diff --git a/tests/integration/subscription/subscription_test.go b/tests/integration/subscription/subscription_test.go index 2a1d26953b..dd8fd66c42 100644 --- a/tests/integration/subscription/subscription_test.go +++ b/tests/integration/subscription/subscription_test.go @@ -17,44 +17,50 @@ import ( ) func TestSubscriptionWithCreateMutations(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Subscription with user creations", - Request: `subscription { + Actions: []any{ + testUtils.SubscriptionRequest{ + Request: `subscription { User { _key name age } }`, - PostSubscriptionRequests: []testUtils.SubscriptionRequest{ - { + Results: []map[string]any{ + { + "_key": "bae-0a24cf29-b2c2-5861-9d00-abd6250c475d", + "age": uint64(27), + "name": "John", + }, + { + "_key": "bae-18def051-7f0f-5dc9-8a69-2a5e423f6b55", + "age": uint64(31), + "name": "Addo", + }, + }, + }, + testUtils.Request{ Request: `mutation { create_User(data: "{\"name\": \"John\",\"age\": 27,\"points\": 42.1,\"verified\": true}") { - _key name - age } }`, Results: []map[string]any{ { - "_key": "bae-0a24cf29-b2c2-5861-9d00-abd6250c475d", - "age": uint64(27), "name": "John", }, }, }, - { + testUtils.Request{ Request: `mutation { create_User(data: "{\"name\": \"Addo\",\"age\": 31,\"points\": 42.1,\"verified\": true}") { - _key name - age } }`, Results: []map[string]any{ { - "_key": "bae-18def051-7f0f-5dc9-8a69-2a5e423f6b55", - "age": uint64(31), "name": "Addo", }, }, @@ -62,32 +68,37 @@ func TestSubscriptionWithCreateMutations(t *testing.T) { }, } - executeTestCase(t, test) + execute(t, test) } func TestSubscriptionWithFilterAndOneCreateMutation(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Subscription with filter and one user creation", - Request: `subscription { + Actions: []any{ + testUtils.SubscriptionRequest{ + Request: `subscription { User(filter: {age: {_lt: 30}}) { _key name age } }`, - PostSubscriptionRequests: []testUtils.SubscriptionRequest{ - { + Results: []map[string]any{ + { + "_key": "bae-0a24cf29-b2c2-5861-9d00-abd6250c475d", + "age": uint64(27), + "name": "John", + }, + }, + }, + testUtils.Request{ Request: `mutation { create_User(data: "{\"name\": \"John\",\"age\": 27,\"points\": 42.1,\"verified\": true}") { - _key name - age } }`, Results: []map[string]any{ { - "_key": "bae-0a24cf29-b2c2-5861-9d00-abd6250c475d", - "age": uint64(27), "name": "John", }, }, @@ -95,113 +106,120 @@ func TestSubscriptionWithFilterAndOneCreateMutation(t *testing.T) { }, } - executeTestCase(t, test) + execute(t, test) } func TestSubscriptionWithFilterAndOneCreateMutationOutsideFilter(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Subscription with filter and one user creation outside of the filter", - Request: `subscription { + Actions: []any{ + testUtils.SubscriptionRequest{ + Request: `subscription { User(filter: {age: {_gt: 30}}) { _key name age } }`, - PostSubscriptionRequests: []testUtils.SubscriptionRequest{ - { + Results: []map[string]any{}, + }, + testUtils.Request{ Request: `mutation { create_User(data: "{\"name\": \"John\",\"age\": 27,\"points\": 42.1,\"verified\": true}") { - _key name - age } }`, - ExpectedTimout: true, + Results: []map[string]any{ + { + "name": "John", + }, + }, }, }, } - executeTestCase(t, test) + execute(t, test) } func TestSubscriptionWithFilterAndCreateMutations(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Subscription with filter and user creation in and outside of the filter", - Request: `subscription { + Actions: []any{ + testUtils.SubscriptionRequest{ + Request: `subscription { User(filter: {age: {_lt: 30}}) { _key name age } }`, - PostSubscriptionRequests: []testUtils.SubscriptionRequest{ - { + Results: []map[string]any{ + { + "_key": "bae-0a24cf29-b2c2-5861-9d00-abd6250c475d", + "age": uint64(27), + "name": "John", + }, + }, + }, + testUtils.Request{ Request: `mutation { create_User(data: "{\"name\": \"John\",\"age\": 27,\"points\": 42.1,\"verified\": true}") { - _key name - age } }`, Results: []map[string]any{ { - "_key": "bae-0a24cf29-b2c2-5861-9d00-abd6250c475d", - "age": uint64(27), "name": "John", }, }, }, - { + testUtils.Request{ Request: `mutation { create_User(data: "{\"name\": \"Addo\",\"age\": 31,\"points\": 42.1,\"verified\": true}") { - _key name - age } }`, - ExpectedTimout: true, + Results: []map[string]any{ + { + "name": "Addo", + }, + }, }, }, } - executeTestCase(t, test) + execute(t, test) } func TestSubscriptionWithUpdateMutations(t *testing.T) { - test := testUtils.RequestTestCase{ - Description: "Subscription with user creations", - Request: `subscription { - User { - _key - name - age - points - } - }`, - Docs: map[int][]string{ - 0: { - `{ + test := testUtils.TestCase{ + Description: "Subscription with user creations and single mutation", + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "John", "age": 27, "verified": true, "points": 42.1 }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Addo", "age": 35, "verified": true, "points": 50 }`, }, - }, - PostSubscriptionRequests: []testUtils.SubscriptionRequest{ - { - Request: `mutation { - update_User(filter: {name: {_eq: "John"}}, data: "{\"points\": 45}") { + testUtils.SubscriptionRequest{ + Request: `subscription { + User { _key name age + points } }`, Results: []map[string]any{ @@ -213,46 +231,53 @@ func TestSubscriptionWithUpdateMutations(t *testing.T) { }, }, }, + testUtils.Request{ + Request: `mutation { + update_User(filter: {name: {_eq: "John"}}, data: "{\"points\": 45}") { + name + } + }`, + Results: []map[string]any{ + { + "name": "John", + }, + }, + }, }, } - executeTestCase(t, test) + execute(t, test) } func TestSubscriptionWithUpdateAllMutations(t *testing.T) { - test := testUtils.RequestTestCase{ - Description: "Subscription with user creations", - Request: `subscription { - User { - _key - name - age - points - } - }`, - Docs: map[int][]string{ - 0: { - `{ + test := testUtils.TestCase{ + Description: "Subscription with user creations and mutations for all", + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "John", "age": 27, "verified": true, "points": 42.1 }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Addo", - "age": 31, + "age": 35, "verified": true, "points": 50 }`, }, - }, - PostSubscriptionRequests: []testUtils.SubscriptionRequest{ - { - Request: `mutation { - update_User(data: "{\"points\": 55}") { + testUtils.SubscriptionRequest{ + Request: `subscription { + User { _key name age + points } }`, Results: []map[string]any{ @@ -263,15 +288,30 @@ func TestSubscriptionWithUpdateAllMutations(t *testing.T) { "points": float64(55), }, { - "_key": "bae-cf723876-5c6a-5dcf-a877-ab288eb30d57", - "age": uint64(31), + "_key": "bae-b04980aa-e290-5a13-b688-07c87d3dfd5d", + "age": uint64(35), "name": "Addo", "points": float64(55), }, }, }, + testUtils.Request{ + Request: `mutation { + update_User(data: "{\"points\": 55}") { + name + } + }`, + Results: []map[string]any{ + { + "name": "John", + }, + { + "name": "Addo", + }, + }, + }, }, } - executeTestCase(t, test) + execute(t, test) } diff --git a/tests/integration/subscription/utils.go b/tests/integration/subscription/utils.go index 68bd6806c1..9c662eb3e9 100644 --- a/tests/integration/subscription/utils.go +++ b/tests/integration/subscription/utils.go @@ -16,15 +16,27 @@ import ( testUtils "github.com/sourcenetwork/defradb/tests/integration" ) -var userSchema = (` - type User { - name: String - age: Int - points: Float - verified: Boolean - } -`) - -func executeTestCase(t *testing.T, test testUtils.RequestTestCase) { - testUtils.ExecuteRequestTestCase(t, userSchema, []string{"User"}, test) +func execute(t *testing.T, test testUtils.TestCase) { + testUtils.ExecuteTestCase( + t, + []string{"User"}, + testUtils.TestCase{ + Description: test.Description, + Actions: append( + []any{ + testUtils.SchemaUpdate{ + Schema: ` + type User { + name: String + age: Int + points: Float + verified: Boolean + } + `, + }, + }, + test.Actions..., + ), + }, + ) } diff --git a/tests/integration/test_case.go b/tests/integration/test_case.go index c9af54f781..b6c589ed36 100644 --- a/tests/integration/test_case.go +++ b/tests/integration/test_case.go @@ -129,18 +129,14 @@ type TransactionCommit struct { ExpectedError string } -// SubscriptionRequest2 represents a subscription request. +// SubscriptionRequest represents a subscription request. // // The subscription will remain active until shortly after all actions have been processed. // The results of the subscription will then be asserted upon. -type SubscriptionRequest2 struct { +type SubscriptionRequest struct { // The subscription request to submit. Request string - // If set to true, the request should yield no results and should instead timeout. - // The timeout duration is that of subscriptionTimeout. - ExpectedTimeout bool - // The expected (data) results yielded through the subscription across its lifetime. Results []map[string]any diff --git a/tests/integration/utils.go b/tests/integration/utils.go index 878ce4b162..d507699721 100644 --- a/tests/integration/utils.go +++ b/tests/integration/utils.go @@ -19,18 +19,6 @@ import ( "github.com/sourcenetwork/defradb/client" ) -// Represents a subscription request. -type SubscriptionRequest struct { - Request string - // The expected (data) results of the issued request. - Results []map[string]any - // The expected error resulting from the issued request. - ExpectedError string - // If set to true, the request should yield no results. - // The timeout is duration is that of subscriptionTimeout (1 second) - ExpectedTimout bool -} - // Represents a request assigned to a particular transaction. type TransactionRequest struct { // Used to identify the transaction for this to run against (allows multiple @@ -48,9 +36,6 @@ type RequestTestCase struct { Description string Request string - // A collection of requests to exucute after the subscriber is listening on the stream - PostSubscriptionRequests []SubscriptionRequest - // A collection of requests that are tied to a specific transaction. // These will be executed before `Request` (if specified), in the order that they are listed here. TransactionalRequests []TransactionRequest @@ -146,18 +131,6 @@ func ExecuteRequestTestCase( ) } - for _, request := range test.PostSubscriptionRequests { - actions = append( - actions, - SubscriptionRequest2{ - ExpectedError: request.ExpectedError, - Request: request.Request, - Results: request.Results, - ExpectedTimeout: request.ExpectedTimout, - }, - ) - } - ExecuteTestCase( t, collectionNames, diff --git a/tests/integration/utils2.go b/tests/integration/utils2.go index 9b2632aaa1..181758ebc0 100644 --- a/tests/integration/utils2.go +++ b/tests/integration/utils2.go @@ -348,7 +348,7 @@ func executeTestCase( return } - case SubscriptionRequest2: + case SubscriptionRequest: var resultsChan subscriptionResult resultsChan, done = executeSubscriptionRequest(ctx, t, allActionsDone, dbi.db, testCase, action) if done { @@ -370,20 +370,25 @@ func executeTestCase( } if len(resultsChans) > 0 { + // Once all other actions have been completed, sleep. + // This is a lazy way to allow the subscription to recieve + // the events generated, and to ensure that no more than are + // expected are recieved. It should probably be done in a better + // way than this at somepoint, but is good enough for now. + time.Sleep(subscriptionTimeout) + // Notify any active subscriptions that all requests have been sent. close(allActionsDone) } + for _, rChans := range resultsChans { select { case subscriptionAssert := <-rChans.subscriptionAssert: // We want to assert back in the main thread so failures get recorded properly subscriptionAssert() - // a safety in case the stream hangs or no results are expected. + // a safety in case the stream hangs - we don't want the tests to run forever. case <-time.After(subscriptionTimeout): - if rChans.expectedTimeout { - continue - } assert.Fail(t, "timeout occured while waiting for data stream", testCase.Description) } } @@ -641,10 +646,9 @@ func executeSubscriptionRequest( allActionsDone chan struct{}, db client.DB, testCase TestCase, - action SubscriptionRequest2, + action SubscriptionRequest, ) (subscriptionResult, bool) { resultChan := subscriptionResult{ - expectedTimeout: action.ExpectedTimeout, subscriptionAssert: make(chan func()), } @@ -667,13 +671,6 @@ func executeSubscriptionRequest( data = append(data, sData...) case <-allActionsDone: - // Once all other actions have been completed, sleep. - // This is a lazy way to allow the subscription to recieve - // the events generated, and to ensure that no more than are - // expected are recieved. It should probably be done in a better - // way than this at somepoint, but is good enough for now. - time.Sleep(subscriptionTimeout) - finalResult := &client.GQLResult{ Data: data, Errors: errs,