Merged in feature/mockserver (pull request #135)
Single Mock Server * mockserver * mockserver * reqs * mockserver * slowrunner * someoptimisedqueries * passedfullsuite * passedfullsuite
This commit is contained in:
@@ -43,7 +43,6 @@ func TestQueryRunner(t *testing.T) {
|
||||
runner := clientsyncrunner.New(&clientsyncrunner.Services{
|
||||
ClientSync: svc,
|
||||
})
|
||||
assert.NotNil(t, runner)
|
||||
|
||||
t.Run("valid", func(t *testing.T) {
|
||||
bod := clientsyncrunner.Body{
|
||||
|
||||
@@ -51,7 +51,6 @@ func TestDocCleanRunner(t *testing.T) {
|
||||
runner := doccleanrunner.New(&doccleanrunner.Services{
|
||||
Clean: documentclean.New(cfg),
|
||||
})
|
||||
assert.NotNil(t, runner)
|
||||
|
||||
t.Run("valid", func(t *testing.T) {
|
||||
bod := doccleanrunner.Body{
|
||||
|
||||
@@ -43,7 +43,6 @@ func TestDocInitRunner(t *testing.T) {
|
||||
runner := docinitrunner.New(&docinitrunner.Services{
|
||||
Document: documentinit.New(cfg),
|
||||
})
|
||||
assert.NotNil(t, runner)
|
||||
|
||||
t.Run("valid", func(t *testing.T) {
|
||||
clientId := "clientid"
|
||||
|
||||
@@ -45,7 +45,6 @@ func TestDocInitRunner(t *testing.T) {
|
||||
Client: client.New(cfg),
|
||||
}),
|
||||
})
|
||||
assert.NotNil(t, runner)
|
||||
|
||||
t.Run("valid", func(t *testing.T) {
|
||||
j := client.Client{
|
||||
|
||||
@@ -58,7 +58,6 @@ func TestDocCleanRunner(t *testing.T) {
|
||||
runner := doctextrunner.New(&doctextrunner.Services{
|
||||
Text: documenttext.New(cfg),
|
||||
})
|
||||
assert.NotNil(t, runner)
|
||||
doc := doctextrunner.Body{
|
||||
DocumentID: uuid.New(),
|
||||
}
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
package queryapi_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
queryapi "queryorchestration/api/queryAPI"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestNewControllers(t *testing.T) {
|
||||
cons := queryapi.NewControllers(&queryapi.Services{})
|
||||
assert.NotNil(t, cons)
|
||||
}
|
||||
@@ -105,7 +105,6 @@ func TestListQueries(t *testing.T) {
|
||||
var res queryapi.ListQueries
|
||||
err = json.Unmarshal(rec.Body.Bytes(), &res)
|
||||
require.NoError(t, err)
|
||||
assert.NotNil(t, res.Queries)
|
||||
assert.ElementsMatch(t, res.Queries, []queryapi.Query{
|
||||
{
|
||||
Id: id,
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
queryapi "queryorchestration/api/queryAPI"
|
||||
"queryorchestration/internal/client"
|
||||
"queryorchestration/internal/database/repository"
|
||||
"queryorchestration/internal/export"
|
||||
"queryorchestration/internal/serviceconfig"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
@@ -27,6 +28,7 @@ func TestGetClientStatus(t *testing.T) {
|
||||
|
||||
cons := queryapi.NewControllers(&queryapi.Services{
|
||||
Client: client.New(cfg),
|
||||
Export: export.New(),
|
||||
})
|
||||
|
||||
e := echo.New()
|
||||
|
||||
@@ -52,7 +52,6 @@ func TestQueryRunner(t *testing.T) {
|
||||
Sync: resultsync.New(cfg),
|
||||
}),
|
||||
})
|
||||
assert.NotNil(t, runner)
|
||||
|
||||
t.Run("valid", func(t *testing.T) {
|
||||
doc := queryrunner.Body{
|
||||
@@ -112,7 +111,7 @@ func TestQueryRunner(t *testing.T) {
|
||||
pool.ExpectExec("name: AddResultDependency :exec").WithArgs(resultId, requiredResultId).
|
||||
WillReturnResult(pgxmock.NewResult("", 1))
|
||||
pool.ExpectCommit()
|
||||
pool.ExpectQuery("name: ListQueryDirectDependentsByDocumentID :many").WithArgs(query.ID, doc.DocumentID).
|
||||
pool.ExpectQuery("name: ListQueryDirectDependentsByDocumentID :many").WithArgs(&query.ID, &doc.DocumentID).
|
||||
WillReturnRows(
|
||||
pgxmock.NewRows([]string{"queryId"}).
|
||||
AddRow(&reqQuery),
|
||||
|
||||
@@ -46,7 +46,6 @@ func TestQueryRunner(t *testing.T) {
|
||||
runner := querysyncrunner.New(&querysyncrunner.Services{
|
||||
QuerySync: svc,
|
||||
})
|
||||
assert.NotNil(t, runner)
|
||||
|
||||
t.Run("valid", func(t *testing.T) {
|
||||
doc := querysyncrunner.Body{
|
||||
|
||||
@@ -43,7 +43,6 @@ func TestQueryRunner(t *testing.T) {
|
||||
runner := queryversionsyncrunner.New(&queryversionsyncrunner.Services{
|
||||
Sync: svc,
|
||||
})
|
||||
assert.NotNil(t, runner)
|
||||
|
||||
t.Run("valid", func(t *testing.T) {
|
||||
doc := queryversionsyncrunner.Body{
|
||||
|
||||
@@ -42,7 +42,6 @@ func TestDocInitRunner(t *testing.T) {
|
||||
runner := New(&Services{
|
||||
documentstore.New(cfg),
|
||||
})
|
||||
assert.NotNil(t, runner)
|
||||
|
||||
t.Run("valid", func(t *testing.T) {
|
||||
clientId := "hi"
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
package client_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"queryorchestration/internal/client"
|
||||
"queryorchestration/internal/database/repository"
|
||||
"queryorchestration/internal/serviceconfig"
|
||||
|
||||
"github.com/pashagolub/pgxmock/v3"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestService(t *testing.T) {
|
||||
pool, err := pgxmock.NewPool()
|
||||
require.NoError(t, err)
|
||||
cfg := &serviceconfig.BaseConfig{}
|
||||
cfg.DBPool = pool
|
||||
cfg.DBQueries = repository.New(pool)
|
||||
|
||||
svc := client.New(cfg)
|
||||
assert.NotNil(t, svc)
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package clientsync
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestService(t *testing.T) {
|
||||
svc := New(nil)
|
||||
assert.NotNil(t, svc)
|
||||
assert.Equal(t, svc.batchSize, int32(100))
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
package clientupdate_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"queryorchestration/internal/client"
|
||||
"queryorchestration/internal/database/repository"
|
||||
"queryorchestration/internal/serviceconfig"
|
||||
|
||||
"github.com/pashagolub/pgxmock/v3"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestService(t *testing.T) {
|
||||
pool, err := pgxmock.NewPool()
|
||||
require.NoError(t, err)
|
||||
cfg := &serviceconfig.BaseConfig{}
|
||||
cfg.DBPool = pool
|
||||
cfg.DBQueries = repository.New(pool)
|
||||
|
||||
svc := client.New(cfg)
|
||||
assert.NotNil(t, svc)
|
||||
}
|
||||
@@ -69,10 +69,15 @@ func TestListQueries(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
v := int32(2)
|
||||
ty := repository.NullQuerytype{
|
||||
Querytype: repository.QuerytypeContextFull,
|
||||
Valid: true,
|
||||
}
|
||||
pool.ExpectQuery("name: ListCollectorQueries :many").WithArgs(clientId).
|
||||
WillReturnRows(
|
||||
pgxmock.NewRows([]string{"clientId", "queryId", "type", "queryVersion", "requiredIds"}).
|
||||
AddRow(clientId, &ogc[0].ID, repository.QuerytypeContextFull, int32(2), nil),
|
||||
AddRow(&clientId, &ogc[0].ID, ty, &v, nil),
|
||||
)
|
||||
|
||||
qs, err := svc.ListQueries(ctx, clientId)
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
package collector_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"queryorchestration/internal/collector"
|
||||
"queryorchestration/internal/database/repository"
|
||||
"queryorchestration/internal/serviceconfig"
|
||||
|
||||
"github.com/pashagolub/pgxmock/v3"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestService(t *testing.T) {
|
||||
pool, err := pgxmock.NewPool()
|
||||
require.NoError(t, err)
|
||||
cfg := &serviceconfig.BaseConfig{}
|
||||
cfg.DBPool = pool
|
||||
cfg.DBQueries = repository.New(pool)
|
||||
|
||||
svc := collector.New(cfg)
|
||||
assert.NotNil(t, svc)
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
package collectorset_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
collectorset "queryorchestration/internal/collector/set"
|
||||
"queryorchestration/internal/database/repository"
|
||||
|
||||
"github.com/pashagolub/pgxmock/v3"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestService(t *testing.T) {
|
||||
pool, err := pgxmock.NewPool()
|
||||
require.NoError(t, err)
|
||||
cfg := &CollectorSetConfig{}
|
||||
cfg.DBPool = pool
|
||||
cfg.DBQueries = repository.New(pool)
|
||||
|
||||
svc := collectorset.New(cfg, &collectorset.Services{})
|
||||
assert.NotNil(t, svc)
|
||||
}
|
||||
@@ -1,12 +1,17 @@
|
||||
CREATE VIEW collectorCurrentActiveVersions as
|
||||
SELECT DISTINCT
|
||||
j.clientId,
|
||||
coalesce(
|
||||
(FIRST_VALUE(v.versionId) OVER (PARTITION BY j.clientId ORDER BY v.id DESC)),
|
||||
0
|
||||
)::int as activeVersion
|
||||
FROM clients as j
|
||||
LEFT JOIN collectorActiveVersions as v on v.clientId = j.clientId;
|
||||
CREATE VIEW collectorCurrentActiveVersions AS
|
||||
SELECT
|
||||
c.clientId,
|
||||
COALESCE(v.versionId, 0)::int AS activeVersion
|
||||
FROM
|
||||
clients c
|
||||
LEFT JOIN (
|
||||
SELECT DISTINCT ON (clientId)
|
||||
clientId,
|
||||
versionId
|
||||
FROM
|
||||
collectorActiveVersions
|
||||
ORDER BY clientId, id DESC
|
||||
) v ON c.clientId = v.clientId;
|
||||
|
||||
CREATE VIEW collectorLatestVersions as
|
||||
SELECT
|
||||
@@ -75,3 +80,44 @@ CREATE VIEW collectorQueryDependencyTree AS
|
||||
FROM collectorQueryDependencyTree as ct
|
||||
JOIN queryCurrentActiveVersions as av on ct.queryId = av.queryId
|
||||
JOIN queries as q on q.queryId = ct.queryId;
|
||||
|
||||
|
||||
CREATE OR REPLACE FUNCTION collectorQueryDependencyTreeByClient(
|
||||
_clientId varchar(255)
|
||||
)
|
||||
RETURNS TABLE (
|
||||
clientId varchar(255),
|
||||
queryId uuid,
|
||||
queryType queryType,
|
||||
queryVersion int,
|
||||
requiredIds uuid[]
|
||||
) AS $$
|
||||
BEGIN
|
||||
RETURN QUERY
|
||||
WITH clientQueries as (
|
||||
SELECT q.clientId, q.queryId
|
||||
FROM currentCollectorQueries as q
|
||||
WHERE q.clientId = _clientId
|
||||
),
|
||||
dependencyTree as (
|
||||
WITH RECURSIVE collectorQueryDependencyTree AS (
|
||||
SELECT cq.clientId, cq.queryId, ri.requiredIds
|
||||
FROM clientQueries as cq
|
||||
JOIN queryCurrentRequiredIdsAGG as ri on cq.queryId = ri.queryId
|
||||
|
||||
UNION ALL
|
||||
|
||||
SELECT acq.clientId, q.queryId, q.requiredIds
|
||||
FROM queryCurrentRequiredIdsAGG as q
|
||||
JOIN collectorQueryDependencyTree as acq on q.queryId = ANY(acq.requiredIds)
|
||||
)
|
||||
SELECT DISTINCT ct.clientId, ct.queryId, q.queryType, av.activeVersion as queryVersion, ct.requiredIds
|
||||
FROM collectorQueryDependencyTree as ct
|
||||
JOIN queryCurrentActiveVersions as av on ct.queryId = av.queryId
|
||||
JOIN queries as q on q.queryId = ct.queryId
|
||||
)
|
||||
SELECT t.clientId, t.queryId, t.queryType, t.queryVersion, t.requiredIds
|
||||
FROM dependencyTree as t
|
||||
WHERE t.clientID is not null;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
@@ -116,8 +116,8 @@ BEGIN
|
||||
),
|
||||
tree as (
|
||||
select q.queryId, q.requiredIds, q.clientId, q.queryVersion
|
||||
from collectorQueryDependencyTree as q
|
||||
join docs as d on q.clientId = d.clientId
|
||||
from docs,
|
||||
LATERAL collectorQueryDependencyTreeByClient(docs.clientId) AS q
|
||||
),
|
||||
query_dependency_tree AS (
|
||||
WITH RECURSIVE query_deps AS (
|
||||
@@ -135,7 +135,6 @@ BEGIN
|
||||
FROM query_deps qd
|
||||
JOIN tree q ON qd.requiredId = q.queryId
|
||||
WHERE array_length(q.requiredIds, 1) > 0
|
||||
|
||||
)
|
||||
SELECT
|
||||
query_deps.queryId,
|
||||
|
||||
@@ -33,7 +33,8 @@ doc_text_entries AS (
|
||||
d.document_id,
|
||||
cte.id AS text_entry_id,
|
||||
d.clean_entry_id,
|
||||
d.clean_fail
|
||||
d.clean_fail,
|
||||
d.client_id
|
||||
FROM
|
||||
doc_clean_entries d
|
||||
LEFT JOIN currentTextEntries cte ON cte.cleanId = d.clean_entry_id
|
||||
@@ -41,16 +42,14 @@ doc_text_entries AS (
|
||||
required_results AS (
|
||||
-- All required document-query-version combinations
|
||||
SELECT
|
||||
d.document_id,
|
||||
dte.document_id,
|
||||
cqdt.queryId,
|
||||
cqdt.queryVersion,
|
||||
dte.text_entry_id
|
||||
FROM
|
||||
doc_clean_entries d
|
||||
JOIN collectorQueryDependencyTree cqdt ON cqdt.clientId = d.client_id
|
||||
JOIN doc_text_entries dte ON dte.document_id = d.document_id
|
||||
and dte.text_entry_id IS NOT NULL
|
||||
where d.clean_fail is null
|
||||
doc_text_entries dte
|
||||
JOIN collectorQueryDependencyTreeByClient($1) cqdt ON cqdt.clientId = dte.client_id
|
||||
where dte.clean_fail is null and dte.text_entry_id IS NOT NULL
|
||||
),
|
||||
existing_results AS (
|
||||
-- Valid results that exist
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
-- name: ListCollectorQueries :many
|
||||
SELECT * FROM collectorQueryDependencyTree WHERE clientId = @clientId;
|
||||
SELECT clientId, queryId, queryType, queryVersion, requiredIds
|
||||
FROM collectorQueryDependencyTreeByClient(@clientId);
|
||||
|
||||
-- name: GetCollectorByClientID :one
|
||||
SELECT * FROM fullActiveCollectors WHERE clientId = @clientId LIMIT 1;
|
||||
|
||||
@@ -75,13 +75,12 @@ SELECT EXISTS (
|
||||
|
||||
-- name: ListQueryDirectDependentsByDocumentID :many
|
||||
WITH doc AS (
|
||||
SELECT id, clientId FROM documents where id = @documentId
|
||||
SELECT clientId FROM documents WHERE id = @documentId
|
||||
)
|
||||
SELECT dt.queryId
|
||||
FROM doc as d
|
||||
JOIN collectorQueryDependencyTree as dt
|
||||
on d.clientId = dt.clientId
|
||||
and @queryId = any(dt.requiredIds);
|
||||
FROM doc,
|
||||
LATERAL collectorQueryDependencyTreeByClient(doc.clientId) AS dt
|
||||
WHERE @queryId = ANY(dt.requiredIds);
|
||||
|
||||
-- name: ListQueryClientIDs :many
|
||||
SELECT clientId FROM collectorQueryDependencyTree WHERE queryId = $1;
|
||||
|
||||
@@ -67,11 +67,19 @@ SELECT r.id, r.value
|
||||
WITH docs as (
|
||||
SELECT id, clientId from documents where id = $1
|
||||
),
|
||||
dependency_tree as (
|
||||
select q.queryId, q.requiredIds, q.clientId, q.queryVersion
|
||||
from docs,
|
||||
LATERAL collectorQueryDependencyTreeByClient(docs.clientId) AS q
|
||||
),
|
||||
text_entries as (
|
||||
select id, documentId from currentTextEntries where documentId = $1
|
||||
),
|
||||
unsyncedQueries AS (
|
||||
SELECT DISTINCT dt.queryId, dt.requiredIds
|
||||
from docs as d
|
||||
JOIN collectorQueryDependencyTree as dt on d.clientId = dt.clientId
|
||||
JOIN currentTextEntries as cte on cte.documentId = d.id
|
||||
JOIN dependency_tree as dt on d.clientId = dt.clientId
|
||||
JOIN text_entries as cte on cte.documentId = d.id
|
||||
LEFT JOIN results as r
|
||||
on r.queryId = dt.queryId
|
||||
and r.queryVersion = dt.queryVersion
|
||||
|
||||
@@ -80,7 +80,8 @@ doc_text_entries AS (
|
||||
d.document_id,
|
||||
cte.id AS text_entry_id,
|
||||
d.clean_entry_id,
|
||||
d.clean_fail
|
||||
d.clean_fail,
|
||||
d.client_id
|
||||
FROM
|
||||
doc_clean_entries d
|
||||
LEFT JOIN currentTextEntries cte ON cte.cleanId = d.clean_entry_id
|
||||
@@ -88,16 +89,14 @@ doc_text_entries AS (
|
||||
required_results AS (
|
||||
-- All required document-query-version combinations
|
||||
SELECT
|
||||
d.document_id,
|
||||
dte.document_id,
|
||||
cqdt.queryId,
|
||||
cqdt.queryVersion,
|
||||
dte.text_entry_id
|
||||
FROM
|
||||
doc_clean_entries d
|
||||
JOIN collectorQueryDependencyTree cqdt ON cqdt.clientId = d.client_id
|
||||
JOIN doc_text_entries dte ON dte.document_id = d.document_id
|
||||
and dte.text_entry_id IS NOT NULL
|
||||
where d.clean_fail is null
|
||||
doc_text_entries dte
|
||||
JOIN collectorQueryDependencyTreeByClient($1) cqdt ON cqdt.clientId = dte.client_id
|
||||
where dte.clean_fail is null and dte.text_entry_id IS NOT NULL
|
||||
),
|
||||
existing_results AS (
|
||||
-- Valid results that exist
|
||||
@@ -178,7 +177,8 @@ SELECT (
|
||||
// d.document_id,
|
||||
// cte.id AS text_entry_id,
|
||||
// d.clean_entry_id,
|
||||
// d.clean_fail
|
||||
// d.clean_fail,
|
||||
// d.client_id
|
||||
// FROM
|
||||
// doc_clean_entries d
|
||||
// LEFT JOIN currentTextEntries cte ON cte.cleanId = d.clean_entry_id
|
||||
@@ -186,16 +186,14 @@ SELECT (
|
||||
// required_results AS (
|
||||
// -- All required document-query-version combinations
|
||||
// SELECT
|
||||
// d.document_id,
|
||||
// dte.document_id,
|
||||
// cqdt.queryId,
|
||||
// cqdt.queryVersion,
|
||||
// dte.text_entry_id
|
||||
// FROM
|
||||
// doc_clean_entries d
|
||||
// JOIN collectorQueryDependencyTree cqdt ON cqdt.clientId = d.client_id
|
||||
// JOIN doc_text_entries dte ON dte.document_id = d.document_id
|
||||
// and dte.text_entry_id IS NOT NULL
|
||||
// where d.clean_fail is null
|
||||
// doc_text_entries dte
|
||||
// JOIN collectorQueryDependencyTreeByClient($1) cqdt ON cqdt.clientId = dte.client_id
|
||||
// where dte.clean_fail is null and dte.text_entry_id IS NOT NULL
|
||||
// ),
|
||||
// existing_results AS (
|
||||
// -- Valid results that exist
|
||||
|
||||
@@ -71,21 +71,31 @@ func (q *Queries) GetCollectorByClientID(ctx context.Context, clientid string) (
|
||||
}
|
||||
|
||||
const listCollectorQueries = `-- name: ListCollectorQueries :many
|
||||
SELECT clientid, queryid, querytype, queryversion, requiredids FROM collectorQueryDependencyTree WHERE clientId = $1
|
||||
SELECT clientId, queryId, queryType, queryVersion, requiredIds
|
||||
FROM collectorQueryDependencyTreeByClient($1)
|
||||
`
|
||||
|
||||
type ListCollectorQueriesRow struct {
|
||||
Clientid *string `db:"clientid"`
|
||||
Queryid *uuid.UUID `db:"queryid"`
|
||||
Querytype NullQuerytype `db:"querytype"`
|
||||
Queryversion *int32 `db:"queryversion"`
|
||||
Requiredids []uuid.UUID `db:"requiredids"`
|
||||
}
|
||||
|
||||
// ListCollectorQueries
|
||||
//
|
||||
// SELECT clientid, queryid, querytype, queryversion, requiredids FROM collectorQueryDependencyTree WHERE clientId = $1
|
||||
func (q *Queries) ListCollectorQueries(ctx context.Context, clientid string) ([]*Collectorquerydependencytree, error) {
|
||||
// SELECT clientId, queryId, queryType, queryVersion, requiredIds
|
||||
// FROM collectorQueryDependencyTreeByClient($1)
|
||||
func (q *Queries) ListCollectorQueries(ctx context.Context, clientid string) ([]*ListCollectorQueriesRow, error) {
|
||||
rows, err := q.db.Query(ctx, listCollectorQueries, clientid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
items := []*Collectorquerydependencytree{}
|
||||
items := []*ListCollectorQueriesRow{}
|
||||
for rows.Next() {
|
||||
var i Collectorquerydependencytree
|
||||
var i ListCollectorQueriesRow
|
||||
if err := rows.Scan(
|
||||
&i.Clientid,
|
||||
&i.Queryid,
|
||||
|
||||
@@ -142,19 +142,27 @@ func TestCollector(t *testing.T) {
|
||||
qs, err := queries.ListCollectorQueries(ctx, clientId)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, qs, 2)
|
||||
assert.ElementsMatch(t, []*repository.Collectorquerydependencytree{
|
||||
jsonV := int32(1)
|
||||
contextV := int32(0)
|
||||
assert.ElementsMatch(t, []*repository.ListCollectorQueriesRow{
|
||||
{
|
||||
Clientid: clientId,
|
||||
Clientid: &clientId,
|
||||
Queryid: &jsonId,
|
||||
Queryversion: 1,
|
||||
Queryversion: &jsonV,
|
||||
Querytype: repository.NullQuerytype{
|
||||
Querytype: repository.QuerytypeJsonExtractor,
|
||||
Valid: true,
|
||||
},
|
||||
Requiredids: []uuid.UUID{contextId},
|
||||
},
|
||||
{
|
||||
Clientid: clientId,
|
||||
Clientid: &clientId,
|
||||
Queryid: &contextId,
|
||||
Queryversion: 0,
|
||||
Queryversion: &contextV,
|
||||
Querytype: repository.NullQuerytype{
|
||||
Querytype: repository.QuerytypeContextFull,
|
||||
Valid: true,
|
||||
},
|
||||
Requiredids: []uuid.UUID{},
|
||||
},
|
||||
}, qs)
|
||||
@@ -212,3 +220,48 @@ func TestCollector(t *testing.T) {
|
||||
Fields: nil,
|
||||
}, coll)
|
||||
}
|
||||
|
||||
func BenchmarkListCollectorQueries(b *testing.B) {
|
||||
ctx := context.Background()
|
||||
|
||||
cfg := &serviceconfig.BaseConfig{}
|
||||
net := test.GetNetwork(b)
|
||||
test.CreateDB(b, cfg, net, &test.CreateDatabaseConfig{})
|
||||
|
||||
queries := cfg.GetDBQueries()
|
||||
|
||||
clientId := "EXAMPLE"
|
||||
err := queries.CreateClient(ctx, &repository.CreateClientParams{
|
||||
Name: "example_client",
|
||||
Clientid: clientId,
|
||||
})
|
||||
require.NoError(b, err)
|
||||
|
||||
b.ResetTimer()
|
||||
|
||||
for b.Loop() {
|
||||
_, _ = queries.ListCollectorQueries(ctx, clientId)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkGetCollectorByClientID(b *testing.B) {
|
||||
ctx := context.Background()
|
||||
|
||||
cfg := &serviceconfig.BaseConfig{}
|
||||
net := test.GetNetwork(b)
|
||||
test.CreateDB(b, cfg, net, &test.CreateDatabaseConfig{})
|
||||
|
||||
queries := cfg.GetDBQueries()
|
||||
|
||||
clientId := "EXAMPLE"
|
||||
err := queries.CreateClient(ctx, &repository.CreateClientParams{
|
||||
Name: "example_client",
|
||||
Clientid: clientId,
|
||||
})
|
||||
require.NoError(b, err)
|
||||
|
||||
b.ResetTimer()
|
||||
for b.Loop() {
|
||||
_, _ = queries.GetCollectorByClientID(ctx, clientId)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -346,30 +346,28 @@ func (q *Queries) ListQueryClientIDs(ctx context.Context, queryid *uuid.UUID) ([
|
||||
|
||||
const listQueryDirectDependentsByDocumentID = `-- name: ListQueryDirectDependentsByDocumentID :many
|
||||
WITH doc AS (
|
||||
SELECT id, clientId FROM documents where id = $2
|
||||
SELECT clientId FROM documents WHERE id = $2
|
||||
)
|
||||
SELECT dt.queryId
|
||||
FROM doc as d
|
||||
JOIN collectorQueryDependencyTree as dt
|
||||
on d.clientId = dt.clientId
|
||||
and $1 = any(dt.requiredIds)
|
||||
FROM doc,
|
||||
LATERAL collectorQueryDependencyTreeByClient(doc.clientId) AS dt
|
||||
WHERE $1 = ANY(dt.requiredIds)
|
||||
`
|
||||
|
||||
type ListQueryDirectDependentsByDocumentIDParams struct {
|
||||
Queryid uuid.UUID `db:"queryid"`
|
||||
Documentid uuid.UUID `db:"documentid"`
|
||||
Queryid *uuid.UUID `db:"queryid"`
|
||||
Documentid *uuid.UUID `db:"documentid"`
|
||||
}
|
||||
|
||||
// ListQueryDirectDependentsByDocumentID
|
||||
//
|
||||
// WITH doc AS (
|
||||
// SELECT id, clientId FROM documents where id = $2
|
||||
// SELECT clientId FROM documents WHERE id = $2
|
||||
// )
|
||||
// SELECT dt.queryId
|
||||
// FROM doc as d
|
||||
// JOIN collectorQueryDependencyTree as dt
|
||||
// on d.clientId = dt.clientId
|
||||
// and $1 = any(dt.requiredIds)
|
||||
// FROM doc,
|
||||
// LATERAL collectorQueryDependencyTreeByClient(doc.clientId) AS dt
|
||||
// WHERE $1 = ANY(dt.requiredIds)
|
||||
func (q *Queries) ListQueryDirectDependentsByDocumentID(ctx context.Context, arg *ListQueryDirectDependentsByDocumentIDParams) ([]*uuid.UUID, error) {
|
||||
rows, err := q.db.Query(ctx, listQueryDirectDependentsByDocumentID, arg.Queryid, arg.Documentid)
|
||||
if err != nil {
|
||||
|
||||
@@ -266,8 +266,8 @@ func TestQueryDependencyTree(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
dependents, err := queries.ListQueryDirectDependentsByDocumentID(ctx, &repository.ListQueryDirectDependentsByDocumentIDParams{
|
||||
Documentid: docID,
|
||||
Queryid: contextQueryID,
|
||||
Documentid: &docID,
|
||||
Queryid: &contextQueryID,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.ElementsMatch(t, []uuid.UUID{}, dependents)
|
||||
@@ -283,8 +283,8 @@ func TestQueryDependencyTree(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
dependents, err = queries.ListQueryDirectDependentsByDocumentID(ctx, &repository.ListQueryDirectDependentsByDocumentIDParams{
|
||||
Documentid: docID,
|
||||
Queryid: jsonQueryID,
|
||||
Documentid: &docID,
|
||||
Queryid: &jsonQueryID,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.ElementsMatch(t, []uuid.UUID{}, dependents)
|
||||
@@ -297,14 +297,14 @@ func TestQueryDependencyTree(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
dependents, err = queries.ListQueryDirectDependentsByDocumentID(ctx, &repository.ListQueryDirectDependentsByDocumentIDParams{
|
||||
Documentid: docID,
|
||||
Queryid: jsonQueryID,
|
||||
Documentid: &docID,
|
||||
Queryid: &jsonQueryID,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.ElementsMatch(t, []uuid.UUID{}, dependents)
|
||||
dependents, err = queries.ListQueryDirectDependentsByDocumentID(ctx, &repository.ListQueryDirectDependentsByDocumentIDParams{
|
||||
Documentid: docID,
|
||||
Queryid: contextQueryID,
|
||||
Documentid: &docID,
|
||||
Queryid: &contextQueryID,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.ElementsMatch(t, []uuid.UUID{}, dependents)
|
||||
@@ -318,14 +318,14 @@ func TestQueryDependencyTree(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
dependents, err = queries.ListQueryDirectDependentsByDocumentID(ctx, &repository.ListQueryDirectDependentsByDocumentIDParams{
|
||||
Documentid: docID,
|
||||
Queryid: jsonQueryID,
|
||||
Documentid: &docID,
|
||||
Queryid: &jsonQueryID,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.ElementsMatch(t, []*uuid.UUID{}, dependents)
|
||||
dependents, err = queries.ListQueryDirectDependentsByDocumentID(ctx, &repository.ListQueryDirectDependentsByDocumentIDParams{
|
||||
Documentid: docID,
|
||||
Queryid: contextQueryID,
|
||||
Documentid: &docID,
|
||||
Queryid: &contextQueryID,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.ElementsMatch(t, []*uuid.UUID{&jsonQueryID}, dependents)
|
||||
@@ -341,14 +341,14 @@ func TestQueryDependencyTree(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
dependents, err = queries.ListQueryDirectDependentsByDocumentID(ctx, &repository.ListQueryDirectDependentsByDocumentIDParams{
|
||||
Documentid: docID,
|
||||
Queryid: jsonQueryID,
|
||||
Documentid: &docID,
|
||||
Queryid: &jsonQueryID,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.ElementsMatch(t, []*uuid.UUID{}, dependents)
|
||||
dependents, err = queries.ListQueryDirectDependentsByDocumentID(ctx, &repository.ListQueryDirectDependentsByDocumentIDParams{
|
||||
Documentid: docID,
|
||||
Queryid: contextQueryID,
|
||||
Documentid: &docID,
|
||||
Queryid: &contextQueryID,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.ElementsMatch(t, []*uuid.UUID{&jsonQueryID}, dependents)
|
||||
@@ -361,20 +361,20 @@ func TestQueryDependencyTree(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
dependents, err = queries.ListQueryDirectDependentsByDocumentID(ctx, &repository.ListQueryDirectDependentsByDocumentIDParams{
|
||||
Documentid: docID,
|
||||
Queryid: secondJsonQueryID,
|
||||
Documentid: &docID,
|
||||
Queryid: &secondJsonQueryID,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.ElementsMatch(t, []*uuid.UUID{}, dependents)
|
||||
dependents, err = queries.ListQueryDirectDependentsByDocumentID(ctx, &repository.ListQueryDirectDependentsByDocumentIDParams{
|
||||
Documentid: docID,
|
||||
Queryid: jsonQueryID,
|
||||
Documentid: &docID,
|
||||
Queryid: &jsonQueryID,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.ElementsMatch(t, []*uuid.UUID{}, dependents)
|
||||
dependents, err = queries.ListQueryDirectDependentsByDocumentID(ctx, &repository.ListQueryDirectDependentsByDocumentIDParams{
|
||||
Documentid: docID,
|
||||
Queryid: contextQueryID,
|
||||
Documentid: &docID,
|
||||
Queryid: &contextQueryID,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.ElementsMatch(t, []*uuid.UUID{&jsonQueryID}, dependents)
|
||||
@@ -388,20 +388,20 @@ func TestQueryDependencyTree(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
dependents, err = queries.ListQueryDirectDependentsByDocumentID(ctx, &repository.ListQueryDirectDependentsByDocumentIDParams{
|
||||
Documentid: docID,
|
||||
Queryid: secondJsonQueryID,
|
||||
Documentid: &docID,
|
||||
Queryid: &secondJsonQueryID,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.ElementsMatch(t, []*uuid.UUID{}, dependents)
|
||||
dependents, err = queries.ListQueryDirectDependentsByDocumentID(ctx, &repository.ListQueryDirectDependentsByDocumentIDParams{
|
||||
Documentid: docID,
|
||||
Queryid: jsonQueryID,
|
||||
Documentid: &docID,
|
||||
Queryid: &jsonQueryID,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.ElementsMatch(t, []*uuid.UUID{&secondJsonQueryID}, dependents)
|
||||
dependents, err = queries.ListQueryDirectDependentsByDocumentID(ctx, &repository.ListQueryDirectDependentsByDocumentIDParams{
|
||||
Documentid: docID,
|
||||
Queryid: contextQueryID,
|
||||
Documentid: &docID,
|
||||
Queryid: &contextQueryID,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.ElementsMatch(t, []*uuid.UUID{&jsonQueryID}, dependents)
|
||||
@@ -590,3 +590,37 @@ func TestListQueryClients(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
assert.ElementsMatch(t, []string{clientOneID}, clients)
|
||||
}
|
||||
|
||||
func BenchmarkListQueryDirectDependentsByDocId(b *testing.B) {
|
||||
ctx := context.Background()
|
||||
|
||||
cfg := &serviceconfig.BaseConfig{}
|
||||
net := test.GetNetwork(b)
|
||||
test.CreateDB(b, cfg, net, &test.CreateDatabaseConfig{})
|
||||
|
||||
queries := cfg.GetDBQueries()
|
||||
|
||||
clientID := "EXAMPLE"
|
||||
err := queries.CreateClient(ctx, &repository.CreateClientParams{
|
||||
Name: "example_client",
|
||||
Clientid: clientID,
|
||||
})
|
||||
require.NoError(b, err)
|
||||
|
||||
docID, err := queries.CreateDocument(ctx, &repository.CreateDocumentParams{
|
||||
Clientid: clientID,
|
||||
Hash: "sample",
|
||||
})
|
||||
require.NoError(b, err)
|
||||
|
||||
contextQueryID, err := queries.CreateQuery(ctx, repository.Querytype(repository.QuerytypeContextFull))
|
||||
require.NoError(b, err)
|
||||
|
||||
b.ResetTimer()
|
||||
for b.Loop() {
|
||||
_, _ = queries.ListQueryDirectDependentsByDocumentID(ctx, &repository.ListQueryDirectDependentsByDocumentIDParams{
|
||||
Documentid: &docID,
|
||||
Queryid: &contextQueryID,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -234,11 +234,19 @@ const listUnsyncedNoDepsQueriesByDocId = `-- name: ListUnsyncedNoDepsQueriesByDo
|
||||
WITH docs as (
|
||||
SELECT id, clientId from documents where id = $1
|
||||
),
|
||||
dependency_tree as (
|
||||
select q.queryId, q.requiredIds, q.clientId, q.queryVersion
|
||||
from docs,
|
||||
LATERAL collectorQueryDependencyTreeByClient(docs.clientId) AS q
|
||||
),
|
||||
text_entries as (
|
||||
select id, documentId from currentTextEntries where documentId = $1
|
||||
),
|
||||
unsyncedQueries AS (
|
||||
SELECT DISTINCT dt.queryId, dt.requiredIds
|
||||
from docs as d
|
||||
JOIN collectorQueryDependencyTree as dt on d.clientId = dt.clientId
|
||||
JOIN currentTextEntries as cte on cte.documentId = d.id
|
||||
JOIN dependency_tree as dt on d.clientId = dt.clientId
|
||||
JOIN text_entries as cte on cte.documentId = d.id
|
||||
LEFT JOIN results as r
|
||||
on r.queryId = dt.queryId
|
||||
and r.queryVersion = dt.queryVersion
|
||||
@@ -256,11 +264,19 @@ SELECT DISTINCT queryId FROM unsyncedQueries as baseuq
|
||||
// WITH docs as (
|
||||
// SELECT id, clientId from documents where id = $1
|
||||
// ),
|
||||
// dependency_tree as (
|
||||
// select q.queryId, q.requiredIds, q.clientId, q.queryVersion
|
||||
// from docs,
|
||||
// LATERAL collectorQueryDependencyTreeByClient(docs.clientId) AS q
|
||||
// ),
|
||||
// text_entries as (
|
||||
// select id, documentId from currentTextEntries where documentId = $1
|
||||
// ),
|
||||
// unsyncedQueries AS (
|
||||
// SELECT DISTINCT dt.queryId, dt.requiredIds
|
||||
// from docs as d
|
||||
// JOIN collectorQueryDependencyTree as dt on d.clientId = dt.clientId
|
||||
// JOIN currentTextEntries as cte on cte.documentId = d.id
|
||||
// JOIN dependency_tree as dt on d.clientId = dt.clientId
|
||||
// JOIN text_entries as cte on cte.documentId = d.id
|
||||
// LEFT JOIN results as r
|
||||
// on r.queryId = dt.queryId
|
||||
// and r.queryVersion = dt.queryVersion
|
||||
|
||||
@@ -2,7 +2,6 @@ package repository_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -128,18 +127,11 @@ type docSyncStateParams struct {
|
||||
}
|
||||
|
||||
func getDocumentSyncState(t testing.TB, ctx context.Context, queries *repository.Queries, params docSyncStateParams) {
|
||||
var wg sync.WaitGroup
|
||||
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
t.Helper()
|
||||
isSynced, err := queries.IsClientSynced(ctx, ¶ms.clientId)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, params.isSynced, isSynced)
|
||||
wg.Done()
|
||||
}()
|
||||
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
doc, err := queries.GetDocumentExternal(ctx, params.documentId)
|
||||
require.NoError(t, err)
|
||||
assert.EqualExportedValues(t, &repository.GetDocumentExternalRow{
|
||||
@@ -148,10 +140,6 @@ func getDocumentSyncState(t testing.TB, ctx context.Context, queries *repository
|
||||
Hash: params.hash,
|
||||
Fields: []byte(params.fields),
|
||||
}, doc)
|
||||
wg.Done()
|
||||
}()
|
||||
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func createQuery(t testing.TB, queries *repository.Queries, queryType repository.Querytype) uuid.UUID {
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
package document_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"queryorchestration/internal/document"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestNewDocumentService(t *testing.T) {
|
||||
svc := document.New(nil)
|
||||
assert.NotNil(t, svc)
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
package export_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"queryorchestration/internal/export"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestNewExportService(t *testing.T) {
|
||||
svc := export.New()
|
||||
assert.NotNil(t, svc)
|
||||
}
|
||||
@@ -65,8 +65,8 @@ func ToDBNullQueryType(t Type) (repository.NullQuerytype, error) {
|
||||
return repository.NullQuerytype{Querytype: dbType, Valid: true}, nil
|
||||
}
|
||||
|
||||
func ParseDBCollectorQuery(q *repository.Collectorquerydependencytree) (*Query, error) {
|
||||
qType, err := ParseDBType(q.Querytype)
|
||||
func ParseDBCollectorQuery(q *repository.ListCollectorQueriesRow) (*Query, error) {
|
||||
qType, err := ParseDBNullType(q.Querytype)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -78,7 +78,7 @@ func ParseDBCollectorQuery(q *repository.Collectorquerydependencytree) (*Query,
|
||||
|
||||
return &Query{
|
||||
ID: *q.Queryid,
|
||||
Version: q.Queryversion,
|
||||
Version: *q.Queryversion,
|
||||
Type: qType,
|
||||
RequiredQueryIDs: reqIds,
|
||||
}, nil
|
||||
|
||||
@@ -12,12 +12,17 @@ import (
|
||||
)
|
||||
|
||||
func TestParseDBCollectorQuery(t *testing.T) {
|
||||
dbResult := repository.Collectorquerydependencytree{
|
||||
Clientid: "hello",
|
||||
id := "hello"
|
||||
version := int32(1)
|
||||
dbResult := repository.ListCollectorQueriesRow{
|
||||
Clientid: &id,
|
||||
Queryid: &uuid.UUID{},
|
||||
Requiredids: []uuid.UUID{},
|
||||
Querytype: repository.NullQuerytype{
|
||||
Querytype: repository.QuerytypeJsonExtractor,
|
||||
Queryversion: 1,
|
||||
Valid: true,
|
||||
},
|
||||
Queryversion: &version,
|
||||
}
|
||||
value, err := resultprocessor.ParseDBCollectorQuery(&dbResult)
|
||||
require.NoError(t, err)
|
||||
@@ -26,7 +31,7 @@ func TestParseDBCollectorQuery(t *testing.T) {
|
||||
assert.Equal(t, int32(1), value.Version)
|
||||
assert.Equal(t, resultprocessor.Type(resultprocessor.TypeJsonExtractor), value.Type)
|
||||
|
||||
dbResult.Querytype = repository.Querytype("")
|
||||
dbResult.Querytype = repository.NullQuerytype{}
|
||||
_, err = resultprocessor.ParseDBCollectorQuery(&dbResult)
|
||||
assert.EqualError(t, err, "invalid database query type")
|
||||
}
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
package result_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"queryorchestration/internal/database/repository"
|
||||
"queryorchestration/internal/query/result"
|
||||
"queryorchestration/internal/serviceconfig"
|
||||
|
||||
"github.com/pashagolub/pgxmock/v3"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestService(t *testing.T) {
|
||||
pool, err := pgxmock.NewPool()
|
||||
require.NoError(t, err)
|
||||
cfg := &serviceconfig.BaseConfig{}
|
||||
cfg.DBPool = pool
|
||||
cfg.DBQueries = repository.New(pool)
|
||||
svc := result.New(cfg, &result.Services{})
|
||||
assert.NotNil(t, svc)
|
||||
}
|
||||
@@ -86,8 +86,8 @@ func (s *Service) storeResult(ctx context.Context, textVersion *repository.Curre
|
||||
|
||||
func (s *Service) informQueryDependents(ctx context.Context, params *Set) error {
|
||||
ids, err := s.cfg.GetDBQueries().ListQueryDirectDependentsByDocumentID(ctx, &repository.ListQueryDirectDependentsByDocumentIDParams{
|
||||
Documentid: params.DocumentID,
|
||||
Queryid: params.QueryID,
|
||||
Documentid: ¶ms.DocumentID,
|
||||
Queryid: ¶ms.QueryID,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -104,7 +104,7 @@ func TestSet(t *testing.T) {
|
||||
pool.ExpectExec("name: AddResultDependency :exec").WithArgs(resultId, requiredResultId).
|
||||
WillReturnResult(pgxmock.NewResult("", 1))
|
||||
pool.ExpectCommit()
|
||||
pool.ExpectQuery("name: ListQueryDirectDependentsByDocumentID :many").WithArgs(params.QueryID, params.DocumentID).
|
||||
pool.ExpectQuery("name: ListQueryDirectDependentsByDocumentID :many").WithArgs(¶ms.QueryID, ¶ms.DocumentID).
|
||||
WillReturnRows(
|
||||
pgxmock.NewRows([]string{"queryId"}).
|
||||
AddRow(&requiredQuery),
|
||||
@@ -159,7 +159,7 @@ func TestInformQueryDependents(t *testing.T) {
|
||||
QueryID: uuid.New(),
|
||||
}
|
||||
|
||||
pool.ExpectQuery("name: ListQueryDirectDependentsByDocumentID :many").WithArgs(params.QueryID, params.DocumentID).
|
||||
pool.ExpectQuery("name: ListQueryDirectDependentsByDocumentID :many").WithArgs(¶ms.QueryID, ¶ms.DocumentID).
|
||||
WillReturnRows(
|
||||
pgxmock.NewRows([]string{"queryId"}).
|
||||
AddRow(&reqOne).
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
package query_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"queryorchestration/internal/database/repository"
|
||||
"queryorchestration/internal/query"
|
||||
"queryorchestration/internal/serviceconfig"
|
||||
|
||||
"github.com/pashagolub/pgxmock/v3"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestService(t *testing.T) {
|
||||
pool, err := pgxmock.NewPool()
|
||||
require.NoError(t, err)
|
||||
cfg := &serviceconfig.BaseConfig{}
|
||||
cfg.DBPool = pool
|
||||
cfg.DBQueries = repository.New(pool)
|
||||
svc := query.New(cfg)
|
||||
assert.NotNil(t, svc)
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
package querytest_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"queryorchestration/internal/database/repository"
|
||||
"queryorchestration/internal/query"
|
||||
"queryorchestration/internal/serviceconfig"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/pashagolub/pgxmock/v3"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestService(t *testing.T) {
|
||||
pool, err := pgxmock.NewPool()
|
||||
require.NoError(t, err)
|
||||
cfg := &serviceconfig.BaseConfig{}
|
||||
cfg.DBPool = pool
|
||||
cfg.DBQueries = repository.New(pool)
|
||||
svc := query.New(cfg)
|
||||
assert.NotNil(t, svc)
|
||||
}
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
"queryorchestration/internal/serviceconfig"
|
||||
|
||||
"github.com/pashagolub/pgxmock/v3"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
@@ -24,7 +23,6 @@ func TestCreatorValidate(t *testing.T) {
|
||||
cfg.DBQueries = repository.New(pool)
|
||||
|
||||
svc := contextfull.NewCreator()
|
||||
assert.NotNil(t, svc)
|
||||
|
||||
entity := &resultprocessor.Create{
|
||||
Type: resultprocessor.TypeContextFull,
|
||||
|
||||
@@ -13,7 +13,6 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/pashagolub/pgxmock/v3"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestUpdatorValidate(t *testing.T) {
|
||||
@@ -26,7 +25,6 @@ func TestUpdatorValidate(t *testing.T) {
|
||||
cfg.DBQueries = repository.New(pool)
|
||||
|
||||
svc := contextfull.NewUpdator()
|
||||
assert.NotNil(t, svc)
|
||||
|
||||
current := &resultprocessor.Query{
|
||||
ID: uuid.New(),
|
||||
|
||||
@@ -12,7 +12,6 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/pashagolub/pgxmock/v3"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestCreatorValidate(t *testing.T) {
|
||||
@@ -25,7 +24,6 @@ func TestCreatorValidate(t *testing.T) {
|
||||
cfg.DBQueries = repository.New(pool)
|
||||
|
||||
svc := jsonextractor.NewCreator()
|
||||
assert.NotNil(t, svc)
|
||||
|
||||
ccfg := "{}"
|
||||
entity := &resultprocessor.Create{
|
||||
|
||||
@@ -11,7 +11,6 @@ import (
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/pashagolub/pgxmock/v3"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
@@ -25,7 +24,6 @@ func TestUpdatorValidate(t *testing.T) {
|
||||
cfg.DBQueries = repository.New(pool)
|
||||
|
||||
svc := jsonextractor.NewUpdator()
|
||||
assert.NotNil(t, svc)
|
||||
|
||||
current := &resultprocessor.Query{
|
||||
ID: uuid.New(),
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
package queryupdate_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"queryorchestration/internal/database/repository"
|
||||
"queryorchestration/internal/query"
|
||||
"queryorchestration/internal/serviceconfig"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/pashagolub/pgxmock/v3"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestService(t *testing.T) {
|
||||
pool, err := pgxmock.NewPool()
|
||||
require.NoError(t, err)
|
||||
cfg := &serviceconfig.BaseConfig{}
|
||||
cfg.DBPool = pool
|
||||
cfg.DBQueries = repository.New(pool)
|
||||
svc := query.New(cfg)
|
||||
assert.NotNil(t, svc)
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package queryversionsync_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"queryorchestration/internal/query"
|
||||
"queryorchestration/internal/serviceconfig"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestService(t *testing.T) {
|
||||
cfg := &serviceconfig.BaseConfig{}
|
||||
svc := query.New(cfg)
|
||||
assert.NotNil(t, svc)
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package runner
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"queryorchestration/internal/serviceconfig"
|
||||
@@ -29,8 +30,18 @@ func TestNewRunner(t *testing.T) {
|
||||
_ = serviceconfig.InitializeConfig(cfg)
|
||||
net := test.GetNetwork(t)
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
a := test.CreateAWSContainer(t, cfg, net)
|
||||
test.SetQueueClient(t, t.Context(), cfg, a.ExternalEndpoint)
|
||||
cfg.QueueURL = test.CreateQueue(t, t.Context(), cfg, "queueName")
|
||||
cfg.SetSQSEndpoint(a.ExternalEndpoint)
|
||||
wg.Done()
|
||||
}()
|
||||
|
||||
wg.Wait()
|
||||
|
||||
test.CreateDB(t, cfg, net, &test.CreateDatabaseConfig{
|
||||
NoMigrations: true,
|
||||
})
|
||||
@@ -38,8 +49,6 @@ func TestNewRunner(t *testing.T) {
|
||||
cfg.ControllerFunc = func() Controller[interface{}] {
|
||||
return runnermock.NewMockController[interface{}](t)
|
||||
}
|
||||
cfg.QueueURL = test.CreateQueue(t, t.Context(), cfg, "queueName")
|
||||
cfg.SetSQSEndpoint(a.ExternalEndpoint)
|
||||
|
||||
srvPtr, err := New(t.Context(), cfg)
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -35,7 +35,7 @@ func TestStopAndWait(t *testing.T) {
|
||||
assert.LessOrEqual(t, 10, cfg.MaxWorkers)
|
||||
assert.NotNil(t, cfg.pool)
|
||||
|
||||
for i := range 1000 {
|
||||
for i := range 2 {
|
||||
index := i
|
||||
cfg.pool.Submit(func() {
|
||||
sl.Info("new thread", "index", index)
|
||||
|
||||
+15
-259
@@ -1,29 +1,18 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"queryorchestration/internal/serviceconfig"
|
||||
"queryorchestration/internal/serviceconfig/objectstore"
|
||||
queryapi "queryorchestration/pkg/queryAPI"
|
||||
|
||||
"github.com/docker/go-connections/nat"
|
||||
"github.com/google/uuid"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/testcontainers/testcontainers-go"
|
||||
"github.com/testcontainers/testcontainers-go/wait"
|
||||
)
|
||||
|
||||
type Network struct {
|
||||
@@ -34,12 +23,13 @@ type Network struct {
|
||||
}
|
||||
|
||||
func CreateFullNetwork(t testing.TB, ctx context.Context, cfg FullDependenciesConfig) (Network, func()) {
|
||||
deps, clean := CreateFullDependencies(t, ctx, cfg)
|
||||
deps := CreateFullDependencies(t, ctx, cfg)
|
||||
|
||||
var wg sync.WaitGroup
|
||||
|
||||
apiContainers := make(map[APIName]*Container, len(apis))
|
||||
apiClean := make([]func(), len(apis))
|
||||
var apiMu sync.Mutex
|
||||
for i, s := range apis {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
@@ -47,7 +37,11 @@ func CreateFullNetwork(t testing.TB, ctx context.Context, cfg FullDependenciesCo
|
||||
API: s,
|
||||
MockHTTP: string(deps.MockServer.Internal),
|
||||
})
|
||||
|
||||
apiMu.Lock()
|
||||
apiContainers[s.Name] = c
|
||||
apiMu.Unlock()
|
||||
|
||||
apiClean[i] = ccleanup
|
||||
wg.Done()
|
||||
}()
|
||||
@@ -55,6 +49,7 @@ func CreateFullNetwork(t testing.TB, ctx context.Context, cfg FullDependenciesCo
|
||||
|
||||
runnerContainers := make(map[RunnerName]*Container, len(runners))
|
||||
runnerClean := make([]func(), len(runners))
|
||||
var runnerMu sync.Mutex
|
||||
for i, r := range runners {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
@@ -63,7 +58,10 @@ func CreateFullNetwork(t testing.TB, ctx context.Context, cfg FullDependenciesCo
|
||||
MockHTTP: string(deps.MockServer.Internal),
|
||||
})
|
||||
|
||||
runnerMu.Lock()
|
||||
runnerContainers[r.Name] = c
|
||||
runnerMu.Unlock()
|
||||
|
||||
runnerClean[i] = ccleanup
|
||||
wg.Done()
|
||||
}()
|
||||
@@ -87,9 +85,6 @@ func CreateFullNetwork(t testing.TB, ctx context.Context, cfg FullDependenciesCo
|
||||
for _, c := range runnerClean {
|
||||
c()
|
||||
}
|
||||
|
||||
clean()
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,14 +101,13 @@ type Dependencies struct {
|
||||
Network string
|
||||
}
|
||||
|
||||
func CreateFullDependencies(t testing.TB, ctx context.Context, cfg FullDependenciesConfig) (Dependencies, func()) {
|
||||
func CreateFullDependencies(t testing.TB, ctx context.Context, cfg FullDependenciesConfig) Dependencies {
|
||||
network := GetNetwork(t)
|
||||
|
||||
deps := Dependencies{
|
||||
Network: network,
|
||||
QueueURLs: map[RunnerName]string{},
|
||||
}
|
||||
cs := map[string]func(){}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
|
||||
@@ -138,9 +132,8 @@ func CreateFullDependencies(t testing.TB, ctx context.Context, cfg FullDependenc
|
||||
wg.Done()
|
||||
}()
|
||||
|
||||
mockServer, cleanMock := CreateMockServer(t, ctx, network)
|
||||
mockServer := CreateMockServer(t, network)
|
||||
deps.MockServer = mockServer
|
||||
cs["mock"] = cleanMock
|
||||
|
||||
CreateDB(t, cfg, network, &CreateDatabaseConfig{
|
||||
NoMigrations: true,
|
||||
@@ -148,11 +141,7 @@ func CreateFullDependencies(t testing.TB, ctx context.Context, cfg FullDependenc
|
||||
|
||||
wg.Wait()
|
||||
|
||||
return deps, func() {
|
||||
for _, c := range cs {
|
||||
c()
|
||||
}
|
||||
}
|
||||
return deps
|
||||
}
|
||||
|
||||
type APINetwork struct {
|
||||
@@ -161,7 +150,7 @@ type APINetwork struct {
|
||||
}
|
||||
|
||||
func CreateAPINetwork(t testing.TB, ctx context.Context, cfg FullDependenciesConfig, api API) (*APINetwork, func()) {
|
||||
deps, depsclean := CreateFullDependencies(t, ctx, cfg)
|
||||
deps := CreateFullDependencies(t, ctx, cfg)
|
||||
|
||||
c, ccleanup := CreateAPI(t, ctx, cfg, deps.Network, &APIConfig{
|
||||
API: api,
|
||||
@@ -171,90 +160,7 @@ func CreateAPINetwork(t testing.TB, ctx context.Context, cfg FullDependenciesCon
|
||||
return &APINetwork{
|
||||
Dependencies: deps,
|
||||
API: c,
|
||||
}, func() {
|
||||
depsclean()
|
||||
ccleanup()
|
||||
}
|
||||
}
|
||||
|
||||
type Address string
|
||||
|
||||
type MockServer struct {
|
||||
Internal Address
|
||||
External Address
|
||||
Container testcontainers.Container
|
||||
Client *http.Client
|
||||
}
|
||||
|
||||
type MockBody any
|
||||
type MockQueries map[string][]string
|
||||
type MockHeaders map[string][]string
|
||||
|
||||
type MockRequest struct {
|
||||
Method string `json:"method"`
|
||||
Path string `json:"path"`
|
||||
Headers MockHeaders `json:"headers"`
|
||||
Body MockBody `json:"body"`
|
||||
Query MockQueries `json:"queryStringParameters"`
|
||||
}
|
||||
|
||||
type MockResponse struct {
|
||||
Code int `json:"statusCode"`
|
||||
Headers MockHeaders `json:"headers"`
|
||||
Body MockBody `json:"body"`
|
||||
}
|
||||
|
||||
type MockExpectation struct {
|
||||
Request MockRequest `json:"httpRequest"`
|
||||
Response MockResponse `json:"httpResponse"`
|
||||
}
|
||||
|
||||
func CreateMockServer(t testing.TB, ctx context.Context, network string) (MockServer, func()) {
|
||||
name := GetAlias(t, "mockserver")
|
||||
port, err := nat.NewPort("tcp", "1080")
|
||||
require.NoError(t, err)
|
||||
|
||||
req := testcontainers.ContainerRequest{
|
||||
Image: "mockserver/mockserver:latest",
|
||||
ExposedPorts: []string{port.Port()},
|
||||
Env: map[string]string{
|
||||
"MOCKSERVER_LOG_LEVEL": "INFO",
|
||||
},
|
||||
WaitingFor: wait.ForAll(
|
||||
wait.ForExposedPort(),
|
||||
wait.ForListeningPort(port),
|
||||
),
|
||||
Networks: []string{network},
|
||||
NetworkAliases: map[string][]string{
|
||||
network: {name},
|
||||
},
|
||||
}
|
||||
|
||||
container, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
|
||||
ContainerRequest: req,
|
||||
Started: true,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
time.Sleep(2 * time.Second)
|
||||
|
||||
host, err := container.Host(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
externalPort, err := container.MappedPort(ctx, port)
|
||||
require.NoError(t, err)
|
||||
|
||||
server := MockServer{
|
||||
Client: &http.Client{},
|
||||
Internal: Address(fmt.Sprintf("http://%s:%d", name, port.Int())),
|
||||
External: Address(fmt.Sprintf("http://%s:%d", host, externalPort.Int())),
|
||||
Container: container,
|
||||
}
|
||||
|
||||
return server, func() {
|
||||
err := container.Terminate(ctx)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
}, ccleanup
|
||||
}
|
||||
|
||||
func GetAlias(t testing.TB, baseName string) string {
|
||||
@@ -266,153 +172,3 @@ func GetAlias(t testing.TB, baseName string) string {
|
||||
name = strings.ReplaceAll(name, "_", "")
|
||||
return name
|
||||
}
|
||||
|
||||
func CreateMockExpectation(t testing.TB, server MockServer, expectation MockExpectation) {
|
||||
jsonData, err := json.Marshal(expectation)
|
||||
require.NoError(t, err)
|
||||
|
||||
url := fmt.Sprintf("%s/mockserver/expectation", server.External)
|
||||
req, err := http.NewRequest("PUT", url, bytes.NewBuffer(jsonData))
|
||||
require.NoError(t, err)
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
|
||||
resp, err := server.Client.Do(req)
|
||||
require.NoError(t, err)
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusCreated && resp.StatusCode != http.StatusOK {
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
t.Fatalf("failed to configure MockServer, status: %d, response: %s", resp.StatusCode, body)
|
||||
}
|
||||
}
|
||||
|
||||
func CreateDetectDocumentTextExpectation(t testing.TB, mockServer MockServer, body string) MockExpectation {
|
||||
childId := uuid.NewString()
|
||||
expectation := MockExpectation{
|
||||
Request: MockRequest{
|
||||
Method: "POST",
|
||||
Path: "/",
|
||||
Headers: MockHeaders{
|
||||
"X-Amz-Target": []string{"Textract.AnalyzeDocument"},
|
||||
},
|
||||
Body: map[string]interface{}{
|
||||
"Document": map[string]interface{}{},
|
||||
"FeatureTypes": []string{"LAYOUT", "SIGNATURES"},
|
||||
},
|
||||
Query: MockQueries{},
|
||||
},
|
||||
Response: MockResponse{
|
||||
Code: 200,
|
||||
Headers: MockHeaders{
|
||||
"Content-Type": {"application/json"},
|
||||
},
|
||||
Body: map[string]interface{}{
|
||||
"Blocks": []map[string]interface{}{
|
||||
{
|
||||
"BlockType": "PAGE",
|
||||
"Relationships": []map[string]interface{}{
|
||||
{
|
||||
"Type": "CHILD",
|
||||
"Ids": []string{
|
||||
childId,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"Id": childId,
|
||||
"Text": body,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
CreateMockExpectation(t, mockServer, expectation)
|
||||
|
||||
return expectation
|
||||
}
|
||||
|
||||
func WaitForMockEndpoint(t testing.TB, server MockServer, request MockRequest) MockRequest {
|
||||
t.Helper()
|
||||
|
||||
verificationRequest := map[string]any{
|
||||
"httpRequest": request,
|
||||
"times": map[string]any{
|
||||
"atLeast": 1,
|
||||
},
|
||||
}
|
||||
|
||||
jsonData, err := json.Marshal(verificationRequest)
|
||||
require.NoError(t, err)
|
||||
|
||||
verifyURL := fmt.Sprintf("%s/mockserver/verify", server.External)
|
||||
|
||||
clientTimeout := 500 * time.Millisecond
|
||||
client := &http.Client{}
|
||||
|
||||
timeout := time.After(60 * time.Second)
|
||||
ticker := time.NewTicker(clientTimeout)
|
||||
defer ticker.Stop()
|
||||
|
||||
slog.Info("Attempting to process request", "body", jsonData)
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-timeout:
|
||||
require.NoError(t, errors.New("Timeout waiting for mock http request to be fulfilled"))
|
||||
case <-ticker.C:
|
||||
req, err := http.NewRequest("PUT", verifyURL, bytes.NewBuffer(jsonData))
|
||||
require.NoError(t, err)
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
|
||||
resp, err := client.Do(req)
|
||||
require.NoError(t, err)
|
||||
|
||||
scanner := bufio.NewScanner(resp.Body)
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
slog.Info(line)
|
||||
}
|
||||
|
||||
if resp.StatusCode == http.StatusAccepted {
|
||||
slog.Info("request found")
|
||||
resp.Body.Close()
|
||||
return retrieveMatchingRequest(t, server, request)
|
||||
}
|
||||
|
||||
resp.Body.Close()
|
||||
slog.Error("no request found")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func retrieveMatchingRequest(t testing.TB, server MockServer, request MockRequest) MockRequest {
|
||||
retrieveURL := fmt.Sprintf("%s/mockserver/retrieve?type=REQUESTS", server.External)
|
||||
|
||||
req, err := http.NewRequest("PUT", retrieveURL, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(req)
|
||||
require.NoError(t, err)
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
require.NoError(t, err)
|
||||
|
||||
var requests []MockRequest
|
||||
err = json.Unmarshal(body, &requests)
|
||||
require.NoError(t, err)
|
||||
|
||||
for i := len(requests) - 1; i >= 0; i-- {
|
||||
attemptRequest := requests[i]
|
||||
|
||||
if attemptRequest.Method == request.Method && attemptRequest.Path == request.Path {
|
||||
return attemptRequest
|
||||
}
|
||||
}
|
||||
|
||||
require.Fail(t, "no request found")
|
||||
return MockRequest{}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,261 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/docker/go-connections/nat"
|
||||
"github.com/google/uuid"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/testcontainers/testcontainers-go"
|
||||
"github.com/testcontainers/testcontainers-go/wait"
|
||||
)
|
||||
|
||||
type Address string
|
||||
|
||||
type MockServer struct {
|
||||
Internal Address
|
||||
External Address
|
||||
Container testcontainers.Container
|
||||
Client *http.Client
|
||||
}
|
||||
|
||||
type MockBody any
|
||||
type MockQueries map[string][]string
|
||||
type MockHeaders map[string][]string
|
||||
|
||||
type MockRequest struct {
|
||||
Method string `json:"method"`
|
||||
Path string `json:"path"`
|
||||
Headers MockHeaders `json:"headers"`
|
||||
Body MockBody `json:"body"`
|
||||
Query MockQueries `json:"queryStringParameters"`
|
||||
}
|
||||
|
||||
type MockResponse struct {
|
||||
Code int `json:"statusCode"`
|
||||
Headers MockHeaders `json:"headers"`
|
||||
Body MockBody `json:"body"`
|
||||
}
|
||||
|
||||
type MockExpectation struct {
|
||||
Request MockRequest `json:"httpRequest"`
|
||||
Response MockResponse `json:"httpResponse"`
|
||||
}
|
||||
|
||||
const (
|
||||
mockServerAlias = "mockserver"
|
||||
mockServerPort = 1080
|
||||
)
|
||||
|
||||
func CreateMockServer(t testing.TB, network string) MockServer {
|
||||
port, err := nat.NewPort("tcp", strconv.Itoa(mockServerPort))
|
||||
require.NoError(t, err)
|
||||
|
||||
req := testcontainers.ContainerRequest{
|
||||
Image: "mockserver/mockserver:latest",
|
||||
Name: "mockserver_test_queryorchestration",
|
||||
ExposedPorts: []string{port.Port()},
|
||||
Env: map[string]string{
|
||||
"MOCKSERVER_LOG_LEVEL": "INFO",
|
||||
"MOCKSERVER_LIVENESS_HTTP_GET_PATH": "/liveness/probe",
|
||||
},
|
||||
WaitingFor: wait.ForAll(
|
||||
wait.ForExposedPort(),
|
||||
wait.ForListeningPort(port),
|
||||
wait.ForHTTP("/liveness/probe").
|
||||
WithPort(port).
|
||||
WithResponseMatcher(func(body io.Reader) bool {
|
||||
return true
|
||||
}).
|
||||
WithStatusCodeMatcher(func(statusCode int) bool {
|
||||
return statusCode == http.StatusOK
|
||||
}),
|
||||
),
|
||||
Networks: []string{network},
|
||||
NetworkAliases: map[string][]string{
|
||||
network: {mockServerAlias},
|
||||
},
|
||||
}
|
||||
|
||||
container, err := testcontainers.GenericContainer(t.Context(), testcontainers.GenericContainerRequest{
|
||||
ContainerRequest: req,
|
||||
Started: true,
|
||||
Reuse: true,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
host, err := container.Host(t.Context())
|
||||
require.NoError(t, err)
|
||||
|
||||
externalPort, err := container.MappedPort(t.Context(), port)
|
||||
require.NoError(t, err)
|
||||
|
||||
server := MockServer{
|
||||
Client: &http.Client{},
|
||||
Internal: Address(fmt.Sprintf("http://%s:%d", mockServerAlias, port.Int())),
|
||||
External: Address(fmt.Sprintf("http://%s:%d", host, externalPort.Int())),
|
||||
Container: container,
|
||||
}
|
||||
|
||||
return server
|
||||
}
|
||||
|
||||
func CreateMockExpectation(t testing.TB, server MockServer, expectation MockExpectation) {
|
||||
jsonData, err := json.Marshal(expectation)
|
||||
require.NoError(t, err)
|
||||
|
||||
url := fmt.Sprintf("%s/mockserver/expectation", server.External)
|
||||
req, err := http.NewRequest("PUT", url, bytes.NewBuffer(jsonData))
|
||||
require.NoError(t, err)
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
|
||||
resp, err := server.Client.Do(req)
|
||||
require.NoError(t, err)
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusCreated && resp.StatusCode != http.StatusOK {
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
t.Fatalf("failed to configure MockServer, status: %d, response: %s", resp.StatusCode, body)
|
||||
}
|
||||
}
|
||||
|
||||
func CreateDetectDocumentTextExpectation(t testing.TB, mockServer MockServer, body string) MockExpectation {
|
||||
childId := uuid.NewString()
|
||||
expectation := MockExpectation{
|
||||
Request: MockRequest{
|
||||
Method: "POST",
|
||||
Path: "/",
|
||||
Headers: MockHeaders{
|
||||
"X-Amz-Target": []string{"Textract.AnalyzeDocument"},
|
||||
},
|
||||
Body: map[string]interface{}{
|
||||
"Document": map[string]interface{}{},
|
||||
"FeatureTypes": []string{"LAYOUT", "SIGNATURES"},
|
||||
},
|
||||
Query: MockQueries{},
|
||||
},
|
||||
Response: MockResponse{
|
||||
Code: 200,
|
||||
Headers: MockHeaders{
|
||||
"Content-Type": {"application/json"},
|
||||
},
|
||||
Body: map[string]interface{}{
|
||||
"Blocks": []map[string]interface{}{
|
||||
{
|
||||
"BlockType": "PAGE",
|
||||
"Relationships": []map[string]interface{}{
|
||||
{
|
||||
"Type": "CHILD",
|
||||
"Ids": []string{
|
||||
childId,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"Id": childId,
|
||||
"Text": body,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
CreateMockExpectation(t, mockServer, expectation)
|
||||
|
||||
return expectation
|
||||
}
|
||||
|
||||
func WaitForMockEndpoint(t testing.TB, server MockServer, request MockRequest) MockRequest {
|
||||
t.Helper()
|
||||
|
||||
verificationRequest := map[string]any{
|
||||
"httpRequest": request,
|
||||
"times": map[string]any{
|
||||
"atLeast": 1,
|
||||
},
|
||||
}
|
||||
|
||||
jsonData, err := json.Marshal(verificationRequest)
|
||||
require.NoError(t, err)
|
||||
|
||||
verifyURL := fmt.Sprintf("%s/mockserver/verify", server.External)
|
||||
|
||||
clientTimeout := 500 * time.Millisecond
|
||||
client := &http.Client{}
|
||||
|
||||
timeout := time.After(60 * time.Second)
|
||||
ticker := time.NewTicker(clientTimeout)
|
||||
defer ticker.Stop()
|
||||
|
||||
slog.Info("Attempting to process request", "body", jsonData)
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-timeout:
|
||||
require.NoError(t, errors.New("Timeout waiting for mock http request to be fulfilled"))
|
||||
case <-ticker.C:
|
||||
req, err := http.NewRequest("PUT", verifyURL, bytes.NewBuffer(jsonData))
|
||||
require.NoError(t, err)
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
|
||||
resp, err := client.Do(req)
|
||||
require.NoError(t, err)
|
||||
|
||||
scanner := bufio.NewScanner(resp.Body)
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
slog.Info(line)
|
||||
}
|
||||
|
||||
if resp.StatusCode == http.StatusAccepted {
|
||||
slog.Info("request found")
|
||||
resp.Body.Close()
|
||||
return retrieveMatchingRequest(t, server, request)
|
||||
}
|
||||
|
||||
resp.Body.Close()
|
||||
slog.Error("no request found")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func retrieveMatchingRequest(t testing.TB, server MockServer, request MockRequest) MockRequest {
|
||||
retrieveURL := fmt.Sprintf("%s/mockserver/retrieve?type=REQUESTS", server.External)
|
||||
|
||||
req, err := http.NewRequest("PUT", retrieveURL, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(req)
|
||||
require.NoError(t, err)
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
require.NoError(t, err)
|
||||
|
||||
var requests []MockRequest
|
||||
err = json.Unmarshal(body, &requests)
|
||||
require.NoError(t, err)
|
||||
|
||||
for i := len(requests) - 1; i >= 0; i-- {
|
||||
attemptRequest := requests[i]
|
||||
|
||||
if attemptRequest.Method == request.Method && attemptRequest.Path == request.Path {
|
||||
return attemptRequest
|
||||
}
|
||||
}
|
||||
|
||||
require.Fail(t, "no request found")
|
||||
return MockRequest{}
|
||||
}
|
||||
@@ -57,8 +57,7 @@ func TestWaitForMockEndpoint(t *testing.T) {
|
||||
}
|
||||
net := GetNetwork(t)
|
||||
|
||||
server, cleanup := CreateMockServer(t, t.Context(), net)
|
||||
defer cleanup()
|
||||
server := CreateMockServer(t, net)
|
||||
|
||||
body := strings.NewReader(`{"team":"hello"}`)
|
||||
req, err := http.NewRequest("GET", string(server.External), body)
|
||||
@@ -33,7 +33,6 @@ func GetNetwork(t testing.TB) string {
|
||||
}
|
||||
|
||||
slog.Info("created network", "name", networkName)
|
||||
|
||||
})
|
||||
|
||||
return networkName
|
||||
|
||||
@@ -16,25 +16,38 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func CreateClientWithSync(t testing.TB, ctx context.Context, client queryapi.ClientWithResponsesInterface) *queryapi.DocClient {
|
||||
func CreateClientWithSync(t testing.TB, client queryapi.ClientWithResponsesInterface) queryapi.ClientID {
|
||||
t.Helper()
|
||||
|
||||
clientCreateRes, err := client.CreateClientWithResponse(ctx, queryapi.ClientCreate{
|
||||
clientCreateRes, err := client.CreateClientWithResponse(t.Context(), queryapi.ClientCreate{
|
||||
Name: "example_name",
|
||||
Id: "ID",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
canSync := true
|
||||
_, err = client.UpdateClientWithResponse(ctx, clientCreateRes.JSON201.Id, queryapi.ClientUpdate{
|
||||
_, err = client.UpdateClientWithResponse(t.Context(), clientCreateRes.JSON201.Id, queryapi.ClientUpdate{
|
||||
CanSync: &canSync,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
clientRes, err := client.GetClientWithResponse(ctx, clientCreateRes.JSON201.Id)
|
||||
require.NoError(t, err)
|
||||
return clientCreateRes.JSON201.Id
|
||||
}
|
||||
|
||||
return clientRes.JSON200
|
||||
func SetQueryForClient(t testing.TB, client queryapi.ClientWithResponsesInterface, clientId queryapi.ClientID, queryId uuid.UUID) {
|
||||
t.Helper()
|
||||
|
||||
newActiveVersion := int32(1)
|
||||
_, err := client.SetCollectorByClientIdWithResponse(t.Context(), clientId, queryapi.CollectorSet{
|
||||
ActiveVersion: &newActiveVersion,
|
||||
Fields: &[]queryapi.CollectorField{
|
||||
{
|
||||
Name: "JSON_QUERY",
|
||||
QueryId: queryId,
|
||||
},
|
||||
},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func WaitForClientStatus(t testing.TB, ctx context.Context, service queryapi.ClientWithResponsesInterface, id string, status queryapi.ClientStatus) {
|
||||
@@ -66,7 +79,7 @@ func WaitForClientStatus(t testing.TB, ctx context.Context, service queryapi.Cli
|
||||
}
|
||||
}
|
||||
|
||||
func CreateDependentQueries(t testing.TB, client *queryapi.ClientWithResponses, clientId string) (uuid.UUID, uuid.UUID) {
|
||||
func CreateDependentQueries(t testing.TB, client *queryapi.ClientWithResponses) (uuid.UUID, uuid.UUID) {
|
||||
contextQueryRes, err := client.CreateQueryWithResponse(t.Context(), queryapi.QueryCreate{
|
||||
Type: queryapi.CONTEXTFULL,
|
||||
})
|
||||
@@ -80,18 +93,6 @@ func CreateDependentQueries(t testing.TB, client *queryapi.ClientWithResponses,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, http.StatusCreated, jsonQueryRes.StatusCode())
|
||||
newActiveVersion := int32(1)
|
||||
collRes, err := client.SetCollectorByClientIdWithResponse(t.Context(), clientId, queryapi.CollectorSet{
|
||||
ActiveVersion: &newActiveVersion,
|
||||
Fields: &[]queryapi.CollectorField{
|
||||
{
|
||||
Name: "JSON_QUERY",
|
||||
QueryId: jsonQueryRes.JSON201.Id,
|
||||
},
|
||||
},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, http.StatusOK, collRes.StatusCode())
|
||||
|
||||
return contextQueryRes.JSON201.Id, jsonQueryRes.JSON201.Id
|
||||
}
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
package queryapitest_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
queryapitest "queryorchestration/internal/test/queryAPI"
|
||||
queryapimock "queryorchestration/mocks/queryapi"
|
||||
queryapi "queryorchestration/pkg/queryAPI"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
)
|
||||
|
||||
func TestCreateClientWithSync(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
svcClient := queryapimock.NewMockClientWithResponsesInterface(t)
|
||||
|
||||
svcClient.EXPECT().CreateClientWithResponse(
|
||||
mock.Anything,
|
||||
mock.MatchedBy(func(create queryapi.ClientCreate) bool {
|
||||
return create.Name == "example_name" && create.Id == "ID"
|
||||
}),
|
||||
mock.Anything,
|
||||
).Return(&queryapi.CreateClientResponse{
|
||||
JSON201: &queryapi.ClientIDBody{
|
||||
Id: "ID",
|
||||
},
|
||||
}, nil)
|
||||
|
||||
svcClient.EXPECT().UpdateClientWithResponse(
|
||||
mock.Anything,
|
||||
mock.MatchedBy(func(id string) bool {
|
||||
return id == "ID"
|
||||
}),
|
||||
mock.MatchedBy(func(create queryapi.ClientUpdate) bool {
|
||||
return *create.CanSync == true
|
||||
}),
|
||||
mock.Anything,
|
||||
).Return(&queryapi.UpdateClientResponse{}, nil)
|
||||
|
||||
svcClient.EXPECT().GetClientWithResponse(
|
||||
mock.Anything,
|
||||
mock.MatchedBy(func(id string) bool {
|
||||
return id == "ID"
|
||||
}),
|
||||
mock.Anything,
|
||||
).Return(&queryapi.GetClientResponse{
|
||||
JSON200: &queryapi.DocClient{
|
||||
Id: "ID",
|
||||
},
|
||||
}, nil)
|
||||
|
||||
client := queryapitest.CreateClientWithSync(t, ctx, svcClient)
|
||||
|
||||
assert.NotNil(t, client)
|
||||
assert.NotNil(t, client)
|
||||
assert.EqualExportedValues(t, queryapi.DocClient{
|
||||
Id: "ID",
|
||||
}, *client)
|
||||
}
|
||||
|
||||
func TestWaitForClientStatus(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
client := queryapimock.NewMockClientWithResponsesInterface(t)
|
||||
|
||||
client.EXPECT().GetStatusByClientIdWithResponse(
|
||||
mock.Anything,
|
||||
mock.MatchedBy(func(id string) bool {
|
||||
return id == "id"
|
||||
}),
|
||||
).Return(&queryapi.GetStatusByClientIdResponse{
|
||||
JSON200: &queryapi.ClientStatusBody{
|
||||
Status: queryapi.INSYNC,
|
||||
},
|
||||
}, nil)
|
||||
|
||||
queryapitest.WaitForClientStatus(t, ctx, client, "id", queryapi.INSYNC)
|
||||
}
|
||||
@@ -66,7 +66,7 @@ tasks:
|
||||
- task: docker:lint
|
||||
- task: openapi:lint
|
||||
- task: compose:lint
|
||||
go:lint: golangci-lint run --fix {{.CLI_ARGS}}
|
||||
go:lint: golangci-lint run {{.CLI_ARGS}}
|
||||
yaml:lint: yamllint . -s {{.CLI_ARGS}}
|
||||
json:lint: jsonlint devbox.json -q -s -i {{.CLI_ARGS}}
|
||||
docs:generate:
|
||||
|
||||
+38
-32
@@ -1,8 +1,8 @@
|
||||
package endtoend_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -25,58 +25,69 @@ type Config struct {
|
||||
}
|
||||
|
||||
func TestProcess(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
cfg := &Config{}
|
||||
|
||||
net, clean := test.CreateFullNetwork(t, ctx, cfg)
|
||||
net, clean := test.CreateFullNetwork(t, t.Context(), cfg)
|
||||
defer clean()
|
||||
|
||||
client := queryapitest.CreateClientWithSync(t, ctx, net.Client)
|
||||
_, jsonId := queryapitest.CreateDependentQueries(t, net.Client, client.Id)
|
||||
|
||||
queryapitest.WaitForClientStatus(t, ctx, net.Client, client.Id, queryapi.INSYNC)
|
||||
|
||||
var wg sync.WaitGroup
|
||||
var clientId queryapi.ClientID
|
||||
var jsonId queryapi.QueryID
|
||||
var textractExpectation test.MockExpectation
|
||||
textractBody := "Hello World"
|
||||
textractExpectation := test.CreateDetectDocumentTextExpectation(
|
||||
wg.Add(3)
|
||||
go func(t testing.TB) {
|
||||
_, jsonId = queryapitest.CreateDependentQueries(t, net.Client)
|
||||
wg.Done()
|
||||
}(t)
|
||||
go func(t testing.TB) {
|
||||
clientId = queryapitest.CreateClientWithSync(t, net.Client)
|
||||
wg.Done()
|
||||
}(t)
|
||||
go func(t testing.TB) {
|
||||
textractExpectation = test.CreateDetectDocumentTextExpectation(
|
||||
t,
|
||||
net.Dependencies.MockServer,
|
||||
textractBody,
|
||||
)
|
||||
wg.Done()
|
||||
}(t)
|
||||
|
||||
wg.Wait()
|
||||
|
||||
queryapitest.SetQueryForClient(t, net.Client, clientId, jsonId)
|
||||
|
||||
part := uint16(0)
|
||||
importKey := objectstore.BucketKey{
|
||||
ClientID: client.Id,
|
||||
ClientID: clientId,
|
||||
EntityID: uuid.New(),
|
||||
Location: objectstore.Import,
|
||||
CreatedAt: time.Now().UTC(),
|
||||
Part: &part,
|
||||
}
|
||||
inputFile := strings.NewReader(pdfHelloWorld)
|
||||
test.PutObject(t, ctx, cfg, test.PutObjectParams{
|
||||
test.PutObject(t, t.Context(), cfg, test.PutObjectParams{
|
||||
File: inputFile,
|
||||
Key: importKey,
|
||||
})
|
||||
|
||||
queryapitest.WaitForClientStatus(t, ctx, net.Client, client.Id, queryapi.NOTSYNCED)
|
||||
|
||||
test.WaitForMockEndpoint(t, net.Dependencies.MockServer, textractExpectation.Request)
|
||||
textKey := objectstore.BucketKey{
|
||||
ClientID: client.Id,
|
||||
ClientID: clientId,
|
||||
EntityID: uuid.New(),
|
||||
Location: objectstore.Text,
|
||||
CreatedAt: time.Now().UTC(),
|
||||
Part: &part,
|
||||
}
|
||||
inputFile = strings.NewReader(textractBody)
|
||||
test.PutObject(t, ctx, cfg, test.PutObjectParams{
|
||||
test.PutObject(t, t.Context(), cfg, test.PutObjectParams{
|
||||
File: inputFile,
|
||||
Key: textKey,
|
||||
})
|
||||
|
||||
queryapitest.WaitForClientStatus(t, ctx, net.Client, client.Id, queryapi.INSYNC)
|
||||
queryapitest.WaitForClientStatus(t, t.Context(), net.Client, clientId, queryapi.INSYNC)
|
||||
|
||||
docs, err := net.Client.ListDocumentsByClientIdWithResponse(ctx, client.Id)
|
||||
docs, err := net.Client.ListDocumentsByClientIdWithResponse(t.Context(), clientId)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, *docs.JSON200, 1)
|
||||
doc := (*docs.JSON200)[0]
|
||||
@@ -84,13 +95,13 @@ func TestProcess(t *testing.T) {
|
||||
expectedDoc := queryapi.Document{
|
||||
Id: doc.Id,
|
||||
Hash: doc.Hash,
|
||||
ClientId: client.Id,
|
||||
ClientId: clientId,
|
||||
Fields: map[string]any{
|
||||
"JSON_QUERY": "valueone",
|
||||
},
|
||||
}
|
||||
|
||||
docRes, err := net.Client.GetDocumentWithResponse(ctx, doc.Id)
|
||||
docRes, err := net.Client.GetDocumentWithResponse(t.Context(), doc.Id)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, docRes)
|
||||
require.NotNil(t, docRes.JSON200)
|
||||
@@ -99,7 +110,7 @@ func TestProcess(t *testing.T) {
|
||||
|
||||
jcfg := `{"path":"keytwo"}`
|
||||
av := int32(2)
|
||||
_, err = net.Client.UpdateQueryWithResponse(ctx, jsonId, queryapi.QueryUpdate{
|
||||
_, err = net.Client.UpdateQueryWithResponse(t.Context(), jsonId, queryapi.QueryUpdate{
|
||||
ActiveVersion: &av,
|
||||
Config: &jcfg,
|
||||
})
|
||||
@@ -108,33 +119,28 @@ func TestProcess(t *testing.T) {
|
||||
"JSON_QUERY": "valuetwo",
|
||||
}
|
||||
|
||||
queryapitest.WaitForClientStatus(t, ctx, net.Client, client.Id, queryapi.NOTSYNCED)
|
||||
queryapitest.WaitForClientStatus(t, ctx, net.Client, client.Id, queryapi.INSYNC)
|
||||
queryapitest.WaitForClientStatus(t, t.Context(), net.Client, clientId, queryapi.NOTSYNCED)
|
||||
queryapitest.WaitForClientStatus(t, t.Context(), net.Client, clientId, queryapi.INSYNC)
|
||||
|
||||
docRes, err = net.Client.GetDocumentWithResponse(ctx, doc.Id)
|
||||
docRes, err = net.Client.GetDocumentWithResponse(t.Context(), doc.Id)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, docRes)
|
||||
require.NotNil(t, docRes.JSON200)
|
||||
assert.EqualExportedValues(t, expectedDoc, *docRes.JSON200)
|
||||
|
||||
testRes, err := net.Client.TestQueryWithResponse(ctx, jsonId, queryapi.QueryTestRequest{
|
||||
testRes, err := net.Client.TestQueryWithResponse(t.Context(), jsonId, queryapi.QueryTestRequest{
|
||||
QueryVersion: 1,
|
||||
DocumentId: doc.Id,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "valueone", testRes.JSON200.Value)
|
||||
testRes, err = net.Client.TestQueryWithResponse(ctx, jsonId, queryapi.QueryTestRequest{
|
||||
|
||||
testRes, err = net.Client.TestQueryWithResponse(t.Context(), jsonId, queryapi.QueryTestRequest{
|
||||
QueryVersion: 2,
|
||||
DocumentId: doc.Id,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "valuetwo", testRes.JSON200.Value)
|
||||
|
||||
docRes, err = net.Client.GetDocumentWithResponse(ctx, doc.Id)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, docRes)
|
||||
require.NotNil(t, docRes.JSON200)
|
||||
assert.EqualExportedValues(t, expectedDoc, *docRes.JSON200)
|
||||
}
|
||||
|
||||
const pdfHelloWorld = `%PDF-1.4
|
||||
|
||||
Reference in New Issue
Block a user