From ee534b13ffdae963b77131f8d8800c39cc7f6dd6 Mon Sep 17 00:00:00 2001 From: Andrew Sisley Date: Wed, 15 Feb 2023 13:56:46 -0500 Subject: [PATCH] PR FIXUP - Fix subscription tests Sorry about the late change, there was a bug in the subscription mapping from the old system that resulted in these silently passing. It proved inconvienent to fix in the mapping as the old system did not specify the results for the triggering mutations which are required in the new system. I decided it would be better to just convert the existing tests to the new system. --- .../subscription/subscription_test.go | 214 +++++++++++------- tests/integration/subscription/utils.go | 34 ++- tests/integration/test_case.go | 8 +- tests/integration/utils.go | 27 --- tests/integration/utils2.go | 25 +- 5 files changed, 163 insertions(+), 145 deletions(-) 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,