diff --git a/ballerina-tests/graphql-advanced-test-suite/Dependencies.toml b/ballerina-tests/graphql-advanced-test-suite/Dependencies.toml index 43be9961f..2ad667110 100644 --- a/ballerina-tests/graphql-advanced-test-suite/Dependencies.toml +++ b/ballerina-tests/graphql-advanced-test-suite/Dependencies.toml @@ -5,7 +5,7 @@ [ballerina] dependencies-toml-version = "2" -distribution-version = "2201.11.0-20241204-121300-fc33b755" +distribution-version = "2201.11.0-20250121-140200-15de3b28" [[package]] org = "ballerina" @@ -130,6 +130,7 @@ dependencies = [ {org = "ballerina", name = "graphql"}, {org = "ballerina", name = "http"}, {org = "ballerina", name = "io"}, + {org = "ballerina", name = "log"}, {org = "ballerina", name = "test"}, {org = "ballerina", name = "websocket"} ] diff --git a/ballerina-tests/graphql-client-test-suite/Dependencies.toml b/ballerina-tests/graphql-client-test-suite/Dependencies.toml index 38f6bfc7b..c08de9c0b 100644 --- a/ballerina-tests/graphql-client-test-suite/Dependencies.toml +++ b/ballerina-tests/graphql-client-test-suite/Dependencies.toml @@ -5,7 +5,7 @@ [ballerina] dependencies-toml-version = "2" -distribution-version = "2201.11.0-20241204-121300-fc33b755" +distribution-version = "2201.11.0-20250121-140200-15de3b28" [[package]] org = "ballerina" @@ -129,6 +129,7 @@ dependencies = [ {org = "ballerina", name = "graphql"}, {org = "ballerina", name = "http"}, {org = "ballerina", name = "io"}, + {org = "ballerina", name = "log"}, {org = "ballerina", name = "test"}, {org = "ballerina", name = "websocket"} ] diff --git a/ballerina-tests/graphql-dataloader-test-suite/Dependencies.toml b/ballerina-tests/graphql-dataloader-test-suite/Dependencies.toml index b192dfb5f..7a1329b9e 100644 --- a/ballerina-tests/graphql-dataloader-test-suite/Dependencies.toml +++ b/ballerina-tests/graphql-dataloader-test-suite/Dependencies.toml @@ -5,7 +5,7 @@ [ballerina] dependencies-toml-version = "2" -distribution-version = "2201.11.0-20241204-121300-fc33b755" +distribution-version = "2201.11.0-20250121-140200-15de3b28" [[package]] org = "ballerina" @@ -131,6 +131,7 @@ dependencies = [ {org = "ballerina", name = "graphql"}, {org = "ballerina", name = "http"}, {org = "ballerina", name = "io"}, + {org = "ballerina", name = "log"}, {org = "ballerina", name = "test"}, {org = "ballerina", name = "websocket"} ] diff --git a/ballerina-tests/graphql-dataloader-test-suite/tests/01_dataloader_tests.bal b/ballerina-tests/graphql-dataloader-test-suite/tests/01_dataloader_tests.bal index 56142cb9a..1d454700f 100644 --- a/ballerina-tests/graphql-dataloader-test-suite/tests/01_dataloader_tests.bal +++ b/ballerina-tests/graphql-dataloader-test-suite/tests/01_dataloader_tests.bal @@ -49,7 +49,8 @@ isolated function testDataLoaderWithDifferentAliasForSameField() returns error? @test:Config { groups: ["subscriptions", "dataloader"], - after: resetDispatchCounters + after: resetDispatchCounters, + enable: false } isolated function testDataLoaderWithSubscription() returns error? { string document = check common:getGraphqlDocumentFromFile("dataloader_with_subscription"); @@ -63,6 +64,7 @@ isolated function testDataLoaderWithSubscription() returns error? { check common:validateNextMessage(wsClient, expectedMsgPayload, id = "1"); } assertDispatchCountForBookLoader(5); + common:closeWebsocketClient(wsClient); } @test:Config { @@ -70,7 +72,8 @@ isolated function testDataLoaderWithSubscription() returns error? { dependsOn: [ testDataLoaderWithQuery, testDataLoaderWithSubscription ], - after: resetDispatchCounters + after: resetDispatchCounters, + enable: false } isolated function testDataLoaderWithMutation() returns error? { graphql:Client graphqlClient = check new ("localhost:9090/dataloader"); diff --git a/ballerina-tests/graphql-interceptor-test-suite/Dependencies.toml b/ballerina-tests/graphql-interceptor-test-suite/Dependencies.toml index 9439e0a72..713be1af0 100644 --- a/ballerina-tests/graphql-interceptor-test-suite/Dependencies.toml +++ b/ballerina-tests/graphql-interceptor-test-suite/Dependencies.toml @@ -5,7 +5,7 @@ [ballerina] dependencies-toml-version = "2" -distribution-version = "2201.11.0-20241204-121300-fc33b755" +distribution-version = "2201.11.0-20250121-140200-15de3b28" [[package]] org = "ballerina" @@ -131,6 +131,7 @@ dependencies = [ {org = "ballerina", name = "graphql"}, {org = "ballerina", name = "http"}, {org = "ballerina", name = "io"}, + {org = "ballerina", name = "log"}, {org = "ballerina", name = "test"}, {org = "ballerina", name = "websocket"} ] diff --git a/ballerina-tests/graphql-security-test-suite/Dependencies.toml b/ballerina-tests/graphql-security-test-suite/Dependencies.toml index 68d3c17e8..12e059057 100644 --- a/ballerina-tests/graphql-security-test-suite/Dependencies.toml +++ b/ballerina-tests/graphql-security-test-suite/Dependencies.toml @@ -5,7 +5,7 @@ [ballerina] dependencies-toml-version = "2" -distribution-version = "2201.11.0-20241204-121300-fc33b755" +distribution-version = "2201.11.0-20250121-140200-15de3b28" [[package]] org = "ballerina" @@ -130,6 +130,7 @@ dependencies = [ {org = "ballerina", name = "graphql"}, {org = "ballerina", name = "http"}, {org = "ballerina", name = "io"}, + {org = "ballerina", name = "log"}, {org = "ballerina", name = "test"}, {org = "ballerina", name = "websocket"} ] diff --git a/ballerina-tests/graphql-service-test-suite/Dependencies.toml b/ballerina-tests/graphql-service-test-suite/Dependencies.toml index 78f9e83ff..03483c1b6 100644 --- a/ballerina-tests/graphql-service-test-suite/Dependencies.toml +++ b/ballerina-tests/graphql-service-test-suite/Dependencies.toml @@ -5,7 +5,7 @@ [ballerina] dependencies-toml-version = "2" -distribution-version = "2201.11.0-20241204-121300-fc33b755" +distribution-version = "2201.11.0-20250121-140200-15de3b28" [[package]] org = "ballerina" @@ -127,6 +127,7 @@ dependencies = [ {org = "ballerina", name = "graphql"}, {org = "ballerina", name = "http"}, {org = "ballerina", name = "io"}, + {org = "ballerina", name = "log"}, {org = "ballerina", name = "test"}, {org = "ballerina", name = "websocket"} ] diff --git a/ballerina-tests/graphql-subgraph-test-suite/Dependencies.toml b/ballerina-tests/graphql-subgraph-test-suite/Dependencies.toml index b61b38ee8..6ab3b738f 100644 --- a/ballerina-tests/graphql-subgraph-test-suite/Dependencies.toml +++ b/ballerina-tests/graphql-subgraph-test-suite/Dependencies.toml @@ -5,7 +5,7 @@ [ballerina] dependencies-toml-version = "2" -distribution-version = "2201.11.0-20241204-121300-fc33b755" +distribution-version = "2201.11.0-20250121-140200-15de3b28" [[package]] org = "ballerina" @@ -122,6 +122,7 @@ dependencies = [ {org = "ballerina", name = "graphql"}, {org = "ballerina", name = "http"}, {org = "ballerina", name = "io"}, + {org = "ballerina", name = "log"}, {org = "ballerina", name = "test"}, {org = "ballerina", name = "websocket"} ] diff --git a/ballerina-tests/graphql-subscription-test-suite/Dependencies.toml b/ballerina-tests/graphql-subscription-test-suite/Dependencies.toml index c0cf5d6e5..ab34e0b35 100644 --- a/ballerina-tests/graphql-subscription-test-suite/Dependencies.toml +++ b/ballerina-tests/graphql-subscription-test-suite/Dependencies.toml @@ -5,7 +5,7 @@ [ballerina] dependencies-toml-version = "2" -distribution-version = "2201.11.0-20241204-121300-fc33b755" +distribution-version = "2201.11.0-20250121-140200-15de3b28" [[package]] org = "ballerina" @@ -142,6 +142,7 @@ dependencies = [ {org = "ballerina", name = "graphql"}, {org = "ballerina", name = "http"}, {org = "ballerina", name = "io"}, + {org = "ballerina", name = "log"}, {org = "ballerina", name = "test"}, {org = "ballerina", name = "websocket"} ] diff --git a/ballerina-tests/graphql-subscription-test-suite/modules/five/tests/01_subscription_five_tests.bal b/ballerina-tests/graphql-subscription-test-suite/modules/five/tests/01_subscription_five_tests.bal index e8b26a43a..daf1aff5f 100644 --- a/ballerina-tests/graphql-subscription-test-suite/modules/five/tests/01_subscription_five_tests.bal +++ b/ballerina-tests/graphql-subscription-test-suite/modules/five/tests/01_subscription_five_tests.bal @@ -26,9 +26,9 @@ function testAttachServiceWithSubscriptionToHttp2BasedListener() returns error? graphql:Error? result = http2BasedListener.attach(subscriptionService); test:assertTrue(result is graphql:Error); graphql:Error err = result; - string expecctedMessage = string `Websocket listener initialization failed due to the incompatibility of ` + + string expectedMessage = string `Websocket listener initialization failed due to the incompatibility of ` + string `provided HTTP(version 2.0) listener`; - test:assertEquals(err.message(), expecctedMessage); + test:assertEquals(err.message(), expectedMessage); } @test:Config { @@ -51,4 +51,6 @@ function testAttachServiceWithSubscriptionToHttp1BasedListener() returns error? check common:validateNextMessage(wsClient1, expectedMsgPayload, id = "1"); check common:validateNextMessage(wsClient2, expectedMsgPayload, id = "2"); } + common:closeWebsocketClient(wsClient1); + common:closeWebsocketClient(wsClient2); } diff --git a/ballerina-tests/graphql-subscription-test-suite/modules/five/tests/02_subscription_with_context.bal b/ballerina-tests/graphql-subscription-test-suite/modules/five/tests/02_subscription_with_context.bal index 76b55fcc6..6cc23543b 100644 --- a/ballerina-tests/graphql-subscription-test-suite/modules/five/tests/02_subscription_with_context.bal +++ b/ballerina-tests/graphql-subscription-test-suite/modules/five/tests/02_subscription_with_context.bal @@ -37,6 +37,7 @@ isolated function testContextWithSubscriptions() returns error? { json expectedMsgPayload = {data: {messages: i}}; check common:validateNextMessage(wsClient, expectedMsgPayload); } + common:closeWebsocketClient(wsClient); } @test:Config { @@ -62,4 +63,5 @@ isolated function testContextWithInvalidScopeInSubscriptions() returns error? { } ]; check common:validateErrorMessage(wsClient, expectedErrorPayload); + common:closeWebsocketClient(wsClient); } diff --git a/ballerina-tests/graphql-subscription-test-suite/modules/five/tests/03_subscription_with_constraint.bal b/ballerina-tests/graphql-subscription-test-suite/modules/five/tests/03_subscription_with_constraint.bal index 752b0a158..e4cb48c8e 100644 --- a/ballerina-tests/graphql-subscription-test-suite/modules/five/tests/03_subscription_with_constraint.bal +++ b/ballerina-tests/graphql-subscription-test-suite/modules/five/tests/03_subscription_with_constraint.bal @@ -30,6 +30,7 @@ isolated function testSubscriptionWithConstraints() returns error? { check common:sendSubscriptionMessage(wsClient, document, operationName = "Sub"); json expectedMsgPayload = check common:getJsonContentFromFile("constraints_with_subscription"); check common:validateErrorMessage(wsClient, expectedMsgPayload); + common:closeWebsocketClient(wsClient); } @test:Config { @@ -50,4 +51,6 @@ isolated function testMultipleSubscriptionClientsWithConstraints() returns error json expectedMsgPayload = check common:getJsonContentFromFile("constraints_with_subscription"); check common:validateErrorMessage(wsClient1, expectedMsgPayload, "1"); check common:validateErrorMessage(wsClient2, expectedMsgPayload, "2"); + common:closeWebsocketClient(wsClient1); + common:closeWebsocketClient(wsClient2); } diff --git a/ballerina-tests/graphql-subscription-test-suite/modules/four/tests/01_subscription_four_tests.bal b/ballerina-tests/graphql-subscription-test-suite/modules/four/tests/01_subscription_four_tests.bal index 64590962d..846f82e3a 100644 --- a/ballerina-tests/graphql-subscription-test-suite/modules/four/tests/01_subscription_four_tests.bal +++ b/ballerina-tests/graphql-subscription-test-suite/modules/four/tests/01_subscription_four_tests.bal @@ -52,6 +52,7 @@ isolated function testSubscriptionMultiplexing() returns error? { json expectedPayload = {'type: common:WS_NEXT, id: subscriptionId, payload: payload}; test:assertEquals(actualPayload, expectedPayload); } + common:closeWebsocketClient(wsClient); } @test:Config { @@ -66,6 +67,7 @@ isolated function testInvalidWebSocketRequestWithEmptyQuery() returns error? { check common:sendSubscriptionMessage(wsClient, document); json expectedMsgPayload = {errors: [{message: "An empty query is found"}]}; check common:validateErrorMessage(wsClient, expectedMsgPayload); + common:closeWebsocketClient(wsClient); } @test:Config { @@ -80,7 +82,8 @@ isolated function testInvalidWebSocketRequestWithInvalidQuery() returns error? { check wsClient->writeMessage({"type": common:WS_SUBSCRIBE, id: "1", payload: payload}); string expectedErrorMsg = "Invalid format: payload does not conform to the format required by the" + " 'graphql-transport-ws' subprotocol: Status code: 1003"; - common:validateConnectionClousureWithError(wsClient, expectedErrorMsg); + common:validateConnectionClosureWithError(wsClient, expectedErrorMsg); + common:closeWebsocketClient(wsClient); } @test:Config { @@ -94,7 +97,8 @@ isolated function testInvalidWebSocketRequestWithoutQuery() returns error? { check wsClient->writeMessage({"type": common:WS_SUBSCRIBE, id: "1", payload: {}}); string expectedErrorMsg = "Invalid format: payload does not conform to the format required by the" + " 'graphql-transport-ws' subprotocol: Status code: 1003"; - common:validateConnectionClousureWithError(wsClient, expectedErrorMsg); + common:validateConnectionClosureWithError(wsClient, expectedErrorMsg); + common:closeWebsocketClient(wsClient); } @test:Config { @@ -110,7 +114,8 @@ isolated function testInvalidVariableInWebSocketPayload() returns error? { check common:sendSubscriptionMessage(wsClient, document, variables = variables); string expectedErrorMsg = "Invalid format: payload does not conform to the format required by the" + " 'graphql-transport-ws' subprotocol: Status code: 1003"; - common:validateConnectionClousureWithError(wsClient, expectedErrorMsg); + common:validateConnectionClosureWithError(wsClient, expectedErrorMsg); + common:closeWebsocketClient(wsClient); } @test:Config { @@ -124,7 +129,8 @@ isolated function testEmptyWebSocketPayload() returns error? { check wsClient->writeMessage(payload); string expectedErrorMsg = "Invalid format: payload does not conform to the format required by the" + " 'graphql-transport-ws' subprotocol: Status code: 1003"; - common:validateConnectionClousureWithError(wsClient, expectedErrorMsg); + common:validateConnectionClosureWithError(wsClient, expectedErrorMsg); + common:closeWebsocketClient(wsClient); } @test:Config { @@ -137,5 +143,6 @@ isolated function testInvalidWebSocketPayload() returns error? { check wsClient->writeMessage(payload); string expectedErrorMsg = "Invalid format: payload does not conform to the format required by the" + " 'graphql-transport-ws' subprotocol: Status code: 1003"; - common:validateConnectionClousureWithError(wsClient, expectedErrorMsg); + common:validateConnectionClosureWithError(wsClient, expectedErrorMsg); + common:closeWebsocketClient(wsClient); } diff --git a/ballerina-tests/graphql-subscription-test-suite/modules/one/tests/01_subscription_tests.bal b/ballerina-tests/graphql-subscription-test-suite/modules/one/tests/01_subscription_tests.bal index 8cf319786..7ca0b940a 100644 --- a/ballerina-tests/graphql-subscription-test-suite/modules/one/tests/01_subscription_tests.bal +++ b/ballerina-tests/graphql-subscription-test-suite/modules/one/tests/01_subscription_tests.bal @@ -33,6 +33,7 @@ isolated function testSubscription() returns error? { check common:validateNextMessage(wsClient, expectedMsgPayload); expectedMsgPayload = {data: {name: "Skyler"}}; check common:validateNextMessage(wsClient, expectedMsgPayload); + common:closeWebsocketClient(wsClient); } @test:Config { @@ -73,6 +74,8 @@ isolated function testSubscriptionsWithMultipleOperations() returns error? { json actualPayload = check common:getJsonPayloadFromService(httpUrl, document, operationName = "getName"); json expectedPayload = {data: {name: "Walter White"}}; common:assertJsonValuesWithOrder(actualPayload, expectedPayload); + common:closeWebsocketClient(wsClient1); + common:closeWebsocketClient(wsClient2); } @test:Config { @@ -90,6 +93,7 @@ isolated function testSubscriptionWithRecords() returns error? { check common:validateNextMessage(wsClient, expectedMsgPayload); expectedMsgPayload = {data: {books: {name: "A Game of Thrones", author: "George R.R. Martin"}}}; check common:validateNextMessage(wsClient, expectedMsgPayload); + common:closeWebsocketClient(wsClient); } @test:Config { @@ -118,6 +122,7 @@ isolated function testSubscriptionWithFragments() returns error? { check common:validateNextMessage(wsClient, expectedMsgPayload); expectedMsgPayload = {data: {students: {id: 2, name: "Mikasa Ackerman"}}}; check common:validateNextMessage(wsClient, expectedMsgPayload); + common:closeWebsocketClient(wsClient); } @test:Config { @@ -135,6 +140,7 @@ isolated function testSubscriptionWithUnionType() returns error? { check common:validateNextMessage(wsClient, expectedMsgPayload); expectedMsgPayload = {data: {multipleValues: {name: "Walter White", subject: "Chemistry"}}}; check common:validateNextMessage(wsClient, expectedMsgPayload); + common:closeWebsocketClient(wsClient); } @test:Config { @@ -153,4 +159,5 @@ isolated function testSubscriptionWithVariables() returns error? { json expectedMsgPayload = {data: {filterValues: i}}; check common:validateNextMessage(wsClient, expectedMsgPayload); } + common:closeWebsocketClient(wsClient); } diff --git a/ballerina-tests/graphql-subscription-test-suite/modules/six/tests/01_subscription_six_tests.bal b/ballerina-tests/graphql-subscription-test-suite/modules/six/tests/01_subscription_six_tests.bal index f4640c93b..7ef646bcf 100644 --- a/ballerina-tests/graphql-subscription-test-suite/modules/six/tests/01_subscription_six_tests.bal +++ b/ballerina-tests/graphql-subscription-test-suite/modules/six/tests/01_subscription_six_tests.bal @@ -21,7 +21,7 @@ import ballerina/websocket; @test:Config { groups: ["subscriptions", "service"] } -isolated function testConnectionClousureWhenPongNotRecived() returns error? { +isolated function testConnectionClosureWhenPongNotReceived() returns error? { string url = "ws://localhost:9091/subscription_interceptor1"; websocket:ClientConfiguration config = {subProtocols: [common:GRAPHQL_TRANSPORT_WS]}; websocket:Client wsClient = check new (url, config); @@ -35,6 +35,7 @@ isolated function testConnectionClousureWhenPongNotRecived() returns error? { } break; } - test:assertTrue(response is error, "Expected connection clousure error"); + test:assertTrue(response is error, "Expected connection closure error"); test:assertEquals((response).message(), "Request timeout: Status code: 4408"); + common:closeWebsocketClient(wsClient); } diff --git a/ballerina-tests/graphql-subscription-test-suite/modules/six/tests/01_subscription_with_interceptors.bal b/ballerina-tests/graphql-subscription-test-suite/modules/six/tests/01_subscription_with_interceptors.bal index f61e6575e..fa32b2770 100644 --- a/ballerina-tests/graphql-subscription-test-suite/modules/six/tests/01_subscription_with_interceptors.bal +++ b/ballerina-tests/graphql-subscription-test-suite/modules/six/tests/01_subscription_with_interceptors.bal @@ -38,6 +38,8 @@ isolated function testInterceptorsWithSubscriptionReturningScalar() returns erro check common:validateNextMessage(wsClient1, expectedMsgPayload, id = "1"); check common:validateNextMessage(wsClient2, expectedMsgPayload, id = "2"); } + common:closeWebsocketClient(wsClient1); + common:closeWebsocketClient(wsClient2); } @test:Config { @@ -60,6 +62,8 @@ isolated function testInterceptorsWithSubscriptionReturningRecord() returns erro check common:sendSubscriptionMessage(wsClient2, document, operationName = "B"); expectedMsgPayload = {data: {newBooks: {name: "A Game of Thrones", author: "George R.R. Martin"}}}; check common:validateNextMessage(wsClient2, expectedMsgPayload); + common:closeWebsocketClient(wsClient1); + common:closeWebsocketClient(wsClient2); } @test:Config { @@ -82,6 +86,8 @@ isolated function testInterceptorsWithSubscriptionAndFragments() returns error? check common:sendSubscriptionMessage(wsClient2, document, operationName = "getNewStudents"); expectedMsgPayload = {data: {newStudents: {id: 4, name: "Ron Weasley"}}}; check common:validateNextMessage(wsClient2, expectedMsgPayload); + common:closeWebsocketClient(wsClient1); + common:closeWebsocketClient(wsClient2); } @test:Config { @@ -125,6 +131,8 @@ isolated function testInterceptorsWithUnionTypeSubscription() returns error? { } }; check common:validateNextMessage(wsClient2, expectedMsgPayload); + common:closeWebsocketClient(wsClient1); + common:closeWebsocketClient(wsClient2); } @test:Config { @@ -147,6 +155,8 @@ isolated function testInterceptorsReturnBeforeResolverWithSubscription() returns check common:validateNextMessage(wsClient1, expectedMsgPayload, id = "1"); check common:validateNextMessage(wsClient2, expectedMsgPayload, id = "2"); } + common:closeWebsocketClient(wsClient1); + common:closeWebsocketClient(wsClient2); } @test:Config { @@ -195,6 +205,8 @@ isolated function testInterceptorsDestructiveModificationWithSubscription() retu check common:validateNextMessage(wsClient1, expectedMsgPayload, id = "1"); check common:validateNextMessage(wsClient2, expectedMsgPayload, id = "2"); } + common:closeWebsocketClient(wsClient1); + common:closeWebsocketClient(wsClient2); } @test:Config { @@ -234,6 +246,9 @@ isolated function testInterceptorsWithSubscribersRunSimultaniously1() returns er } check wait A; check wait B; + common:closeWebsocketClient(wsClient1); + common:closeWebsocketClient(wsClient2); + common:closeWebsocketClient(wsClient3); } @test:Config { @@ -293,4 +308,6 @@ isolated function testInterceptorsWithSubscribersRunSimultaniously2() returns er } check wait A; check wait B; + common:closeWebsocketClient(wsClient1); + common:closeWebsocketClient(wsClient2); } diff --git a/ballerina-tests/graphql-subscription-test-suite/modules/three/tests/01_subscription_three_tests.bal b/ballerina-tests/graphql-subscription-test-suite/modules/three/tests/01_subscription_three_tests.bal index ecade6828..f5c57530e 100644 --- a/ballerina-tests/graphql-subscription-test-suite/modules/three/tests/01_subscription_three_tests.bal +++ b/ballerina-tests/graphql-subscription-test-suite/modules/three/tests/01_subscription_three_tests.bal @@ -48,6 +48,7 @@ function testAlreadyExistingSubscriber() returns error? { } } test:assertEquals((response).message(), expectedErrorMsg); + common:closeWebsocketClient(wsClient); } @test:Config { @@ -60,6 +61,7 @@ isolated function testOnPing() returns error? { check wsClient->writeMessage({'type: common:WS_PING}); json response = check wsClient->readMessage(); test:assertEquals(response.'type, common:WS_PONG); + common:closeWebsocketClient(wsClient); } @test:Config { @@ -71,8 +73,7 @@ isolated function testInvalidSubProtocolInSubscriptions() returns error? { websocket:ClientConfiguration config = {subProtocols: [subProtocol]}; websocket:Client|error wsClient = new (url, config); test:assertTrue(wsClient is websocket:InvalidHandshakeError, "Invalid handshake error expected"); - string expectedErrorMsg = "InvalidHandshakeError: Invalid subprotocol. Actual: null." + - " Expected one of: graphql-invalid-ws"; + string expectedErrorMsg = "InvalidHandshakeError: Invalid subprotocol. Actual: null. Expected one of: graphql-invalid-ws"; test:assertEquals((wsClient).message(), expectedErrorMsg); } @@ -93,6 +94,7 @@ isolated function testErrorsInStreams() returns error? { check common:validateNextMessage(wsClient, expectedMsgPayload); expectedMsgPayload = {data: {evenNumber: 6}}; check common:validateNextMessage(wsClient, expectedMsgPayload); + common:closeWebsocketClient(wsClient); } @test:Config { @@ -118,6 +120,7 @@ isolated function testMultipleSubscriptionUsingSingleClient() returns error? { check common:validateNextMessage(wsClient, expectedMsgPayload, id = "2"); } check common:validateCompleteMessage(wsClient, id = "2"); + common:closeWebsocketClient(wsClient); } @test:Config { @@ -133,7 +136,8 @@ isolated function testSubscriptionWithInvalidPayload() returns error? { string expectedErrorMsg = "Invalid format: payload does not conform to the format required by the" + " 'graphql-transport-ws' subprotocol: Status code: 1003"; - common:validateConnectionClousureWithError(wsClient, expectedErrorMsg); + common:validateConnectionClosureWithError(wsClient, expectedErrorMsg); + common:closeWebsocketClient(wsClient); } @test:Config { @@ -149,6 +153,7 @@ isolated function testResolverReturingStreamOfRecordsWithServiceObjects() return json expectedPayload = {data: {live: {product: {id: "1"}, score: 20}}}; check common:validateNextMessage(wsClient, expectedPayload); + common:closeWebsocketClient(wsClient); } @test:Config { @@ -166,4 +171,5 @@ isolated function testResolverReturingStreamOfRecordsWithMapOfServiceObjects() r check common:validateNextMessage(wsClient, expectedMsgPayload); expectedMsgPayload = {data: {accountUpdates: {details: {name: "James Deen"}}}}; check common:validateNextMessage(wsClient, expectedMsgPayload); + common:closeWebsocketClient(wsClient); } diff --git a/ballerina-tests/graphql-subscription-test-suite/modules/two/tests/01_subscription_two_tests.bal b/ballerina-tests/graphql-subscription-test-suite/modules/two/tests/01_subscription_two_tests.bal index cced36cc2..676e6e35b 100644 --- a/ballerina-tests/graphql-subscription-test-suite/modules/two/tests/01_subscription_two_tests.bal +++ b/ballerina-tests/graphql-subscription-test-suite/modules/two/tests/01_subscription_two_tests.bal @@ -31,6 +31,7 @@ isolated function testSubscriptionWithIntrospectionInFields() returns error? { json expectedMsgPayload = {data: {students: {__typename: "StudentService"}}}; check common:validateNextMessage(wsClient, expectedMsgPayload); + common:closeWebsocketClient(wsClient); } @test:Config { @@ -46,6 +47,7 @@ isolated function testInvalidSubscription() returns error? { json expectedMsgPayload = check common:getJsonContentFromFile("subscription_invalid_field"); check common:validateErrorMessage(wsClient, expectedMsgPayload); + common:closeWebsocketClient(wsClient); } @test:Config { @@ -67,6 +69,7 @@ isolated function testSubscriptionFunctionWithErrors() returns error? { } ]; check common:validateErrorMessage(wsClient, expectedErrorPayload); + common:closeWebsocketClient(wsClient); } @test:Config { @@ -85,6 +88,7 @@ isolated function testSubscriptionWithServiceObjects() returns error? { expectedMsgPayload = {data: {students: {id: 2, name: "Mikasa Ackerman"}}}; check common:validateNextMessage(wsClient, expectedMsgPayload); check common:validateCompleteMessage(wsClient); + common:closeWebsocketClient(wsClient); } @test:Config { @@ -110,6 +114,8 @@ isolated function testSubscriptionWithMultipleClients() returns error? { } check common:validateCompleteMessage(wsClient1, id = "1"); check common:validateCompleteMessage(wsClient2, id = "2"); + common:closeWebsocketClient(wsClient1); + common:closeWebsocketClient(wsClient2); } @test:Config { @@ -121,6 +127,7 @@ isolated function testConnectionInitMessage() returns error? { websocket:Client wsClient = check new (url, config); check common:sendConnectionInitMessage(wsClient); check common:validateConnectionAckMessage(wsClient); + common:closeWebsocketClient(wsClient); } @test:Config { @@ -134,7 +141,8 @@ isolated function testInvalidMultipleConnectionInitMessages() returns error? { check common:sendConnectionInitMessage(wsClient); string expectedErrorMsg = "Too many initialisation requests: Status code: 4429"; - common:validateConnectionClousureWithError(wsClient, expectedErrorMsg); + common:validateConnectionClosureWithError(wsClient, expectedErrorMsg); + common:closeWebsocketClient(wsClient); } @test:Config { @@ -148,5 +156,6 @@ isolated function testUnauthorizedAccess() returns error? { check common:sendSubscriptionMessage(wsClient, document); string expectedErrorMsg = "Unauthorized: Status code: 4401"; - common:validateConnectionClousureWithError(wsClient, expectedErrorMsg); + common:validateConnectionClosureWithError(wsClient, expectedErrorMsg); + common:closeWebsocketClient(wsClient); } diff --git a/ballerina-tests/graphql-test-common/Dependencies.toml b/ballerina-tests/graphql-test-common/Dependencies.toml index b49d9b70f..e33f0bc27 100644 --- a/ballerina-tests/graphql-test-common/Dependencies.toml +++ b/ballerina-tests/graphql-test-common/Dependencies.toml @@ -5,7 +5,7 @@ [ballerina] dependencies-toml-version = "2" -distribution-version = "2201.11.0-20241204-121300-fc33b755" +distribution-version = "2201.11.0-20250121-140200-15de3b28" [[package]] org = "ballerina" @@ -111,6 +111,7 @@ dependencies = [ {org = "ballerina", name = "graphql"}, {org = "ballerina", name = "http"}, {org = "ballerina", name = "io"}, + {org = "ballerina", name = "log"}, {org = "ballerina", name = "test"}, {org = "ballerina", name = "websocket"} ] @@ -275,6 +276,9 @@ dependencies = [ {org = "ballerina", name = "lang.value"}, {org = "ballerina", name = "observe"} ] +modules = [ + {org = "ballerina", packageName = "log", moduleName = "log"} +] [[package]] org = "ballerina" diff --git a/ballerina-tests/graphql-test-common/utils.bal b/ballerina-tests/graphql-test-common/utils.bal index 1cba953d5..708bec983 100644 --- a/ballerina-tests/graphql-test-common/utils.bal +++ b/ballerina-tests/graphql-test-common/utils.bal @@ -18,6 +18,7 @@ import ballerina/file; import ballerina/graphql; import ballerina/http; import ballerina/io; +import ballerina/log; import ballerina/test; import ballerina/websocket; @@ -108,9 +109,11 @@ public isolated function getContentFromByteStream(stream byte return 'string:fromBytes(content); } -public isolated function readMessageExcludingPingMessages(websocket:Client wsClient) returns json|websocket:Error { +public isolated function readMessageExcludingPingMessages(websocket:Client wsClient) returns json|error { json message = null; - while true { + int i = 0; + while i < 10 { + i = i + 1; message = check wsClient->readMessage(); if message == null { continue; @@ -121,6 +124,7 @@ public isolated function readMessageExcludingPingMessages(websocket:Client wsCli } return message; } + return error("No message received"); } public isolated function sendPongMessage(websocket:Client wsClient) returns websocket:Error? { @@ -149,25 +153,25 @@ public isolated function initiateGraphqlWsConnection(websocket:Client wsClient) check validateConnectionAckMessage(wsClient); } -public isolated function validateNextMessage(websocket:Client wsClient, json expectedMsgPayload, string id = "1") returns websocket:Error? { +public isolated function validateNextMessage(websocket:Client wsClient, json expectedMsgPayload, string id = "1") returns error? { json expectedPayload = {'type: WS_NEXT, id, payload: expectedMsgPayload}; json actualPayload = check readMessageExcludingPingMessages(wsClient); assertJsonValuesWithOrder(actualPayload, expectedPayload); } -public isolated function validateErrorMessage(websocket:Client wsClient, json expectedMsgPayload, string id = "1") returns websocket:Error? { +public isolated function validateErrorMessage(websocket:Client wsClient, json expectedMsgPayload, string id = "1") returns error? { json expectedPayload = {'type: WS_ERROR, id, payload: expectedMsgPayload}; json actualPayload = check readMessageExcludingPingMessages(wsClient); assertJsonValuesWithOrder(actualPayload, expectedPayload); } -public isolated function validateCompleteMessage(websocket:Client wsClient, string id = "1") returns websocket:Error? { +public isolated function validateCompleteMessage(websocket:Client wsClient, string id = "1") returns error? { json expectedPayload = {'type: WS_COMPLETE, id}; json actualPayload = check readMessageExcludingPingMessages(wsClient); assertJsonValuesWithOrder(actualPayload, expectedPayload); } -public isolated function validateConnectionClousureWithError(websocket:Client wsClient, string expectedErrorMsg) { +public isolated function validateConnectionClosureWithError(websocket:Client wsClient, string expectedErrorMsg) { json|error response = readMessageExcludingPingMessages(wsClient); if response is error { test:assertEquals(response.message(), expectedErrorMsg); @@ -175,3 +179,15 @@ public isolated function validateConnectionClousureWithError(websocket:Client ws } test:assertFail(string `Unexpected Error found : ${response.toString()}`); } + +public isolated function closeWebsocketClient(websocket:Client wsClient) { + string id = wsClient.getConnectionId(); + error? result = wsClient->writeMessage({'type: WS_COMPLETE, id}); + if result is error { + log:printError("Error occurred while sending the complete message: ", result); + } + result = wsClient->close(timeout = 1); + if result is error { + log:printError("Error occurred while closing the websocket client: ", result); + } +} diff --git a/ballerina/Dependencies.toml b/ballerina/Dependencies.toml index f25a5b667..63527fb52 100644 --- a/ballerina/Dependencies.toml +++ b/ballerina/Dependencies.toml @@ -5,7 +5,7 @@ [ballerina] dependencies-toml-version = "2" -distribution-version = "2201.11.0-20241204-121300-fc33b755" +distribution-version = "2201.11.0-20250121-140200-15de3b28" [[package]] org = "ballerina" diff --git a/ballerina/websocket_utils.bal b/ballerina/websocket_utils.bal index 7c421e9f0..c70c7fe97 100644 --- a/ballerina/websocket_utils.bal +++ b/ballerina/websocket_utils.bal @@ -101,7 +101,7 @@ returns stream|json { } if result !is error { if context.getErrors().length() == 0 { - result = error("Error ocurred in the subscription resolver"); + result = error("Error occurred in the subscription resolver"); } result = (); } @@ -143,10 +143,8 @@ isolated function logError(string message, error cause) { } isolated function writeMessage(websocket:Caller caller, OutboundMessage message) returns websocket:Error? { - lock { - if !caller.isOpen() { - return; - } - check caller->writeMessage(message); + if !caller.isOpen() { + return; } + check caller->writeMessage(message); } diff --git a/examples/simple_github_issue_tracker/Ballerina.toml b/examples/simple_github_issue_tracker/Ballerina.toml index e9c7f98e7..3613b4cbc 100644 --- a/examples/simple_github_issue_tracker/Ballerina.toml +++ b/examples/simple_github_issue_tracker/Ballerina.toml @@ -1,5 +1,5 @@ [package] -org = "ballerina" +org = "wso2" name = "simple_github_issue_tracker" version = "0.1.0" distribution = "2201.6.0" diff --git a/examples/snowtooth/Ballerina.toml b/examples/snowtooth/Ballerina.toml index 9f8dfd376..9ad61271e 100644 --- a/examples/snowtooth/Ballerina.toml +++ b/examples/snowtooth/Ballerina.toml @@ -1,5 +1,5 @@ [package] -org = "graphql" +org = "wso2" name = "snowtooth" version = "0.1.0" diff --git a/examples/starwars/Ballerina.toml b/examples/starwars/Ballerina.toml index fefa56499..c1a331b1c 100644 --- a/examples/starwars/Ballerina.toml +++ b/examples/starwars/Ballerina.toml @@ -1,5 +1,5 @@ [package] -org = "graphql" +org = "wso2" name = "starwars" version = "0.1.0" diff --git a/gradle.properties b/gradle.properties index 619f241eb..f28519099 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,7 +1,7 @@ org.gradle.caching=true group=io.ballerina.stdlib version=1.15.0-SNAPSHOT -ballerinaLangVersion=2201.11.0-20241218-101200-109f6cc7 +ballerinaLangVersion=2201.11.0-20250121-140200-15de3b28 checkstylePluginVersion=10.12.0 spotbugsPluginVersion=6.0.18 @@ -15,35 +15,35 @@ jacocoVersion=0.8.10 # Ballerina Library Dependencies # Level 01 -stdlibIoVersion=1.7.0-20241218-111600-1da6a3f -stdlibTimeVersion=2.6.0-20241218-111600-f57d32a -stdlibUrlVersion=2.5.0-20241218-111600-4f962bc +stdlibIoVersion=1.7.0-20250121-143700-fac534d +stdlibTimeVersion=2.6.0-20250121-143700-96fbd6a +stdlibUrlVersion=2.5.0-20250121-143700-9db47c2 # Level 02 -stdlibConstraintVersion=1.6.0-20241218-112400-cd313f2 -stdlibCryptoVersion=2.8.0-20241218-112400-d6f4922 -stdlibLogVersion=2.11.0-20241218-115100-06c729e -stdlibOsVersion=1.9.0-20241218-112400-c81f077 -stdlibTaskVersion=2.6.0-20241218-112900-84f2aea +stdlibConstraintVersion=1.6.0-20250121-144400-48092bd +stdlibCryptoVersion=2.8.0-20250121-144400-cf0d2db +stdlibLogVersion=2.11.0-20250121-151200-196ede7 +stdlibOsVersion=1.9.0-20250121-144400-3c22e13 +stdlibTaskVersion=2.6.0-20250121-144900-6de8c93 # Level 03 -stdlibCacheVersion=3.9.0-20241218-114600-9f52392 -stdlibFileVersion=1.11.0-20241218-125000-364d941 -stdlibMimeVersion=2.11.0-20241218-125100-e28a03b -stdlibUuidVersion=1.9.0-20241218-124000-a38f1c9 +stdlibCacheVersion=3.9.0-20250121-150600-d24d690 +stdlibFileVersion=1.11.0-20250122-120300-6dd5c6c +stdlibMimeVersion=2.11.0-20250122-120300-9005c8c +stdlibUuidVersion=1.9.0-20250121-171900-df5e661 # Level 04 -stdlibAuthVersion=2.13.0-20241218-124900-9203135 +stdlibAuthVersion=2.13.0-20250122-120100-293d482 stdlibDataJsonDataVersion=1.0.0-20241125-114000-0c2f457 -stdlibJwtVersion=2.14.0-20241218-125000-c952d1e -stdlibOAuth2Version=2.13.0-20241218-125400-c7625c1 +stdlibJwtVersion=2.14.0-20250122-120200-9a7dd9b +stdlibOAuth2Version=2.13.0-20250122-120600-a9c21e1 # Level 05 -stdlibHttpVersion=2.13.0-20241218-142000-8d9c012 +stdlibHttpVersion=2.13.0-20250122-144400-fb78cb1 # Level 06 -stdlibWebsocketVersion=2.13.0-20241218-151900-e2412df +stdlibWebsocketVersion=2.13.0-20250122-154200-e927fbf # Ballerinax Observer -observeVersion=1.4.0-20241218-111700-4d29d40 -observeInternalVersion=1.4.0-20241218-112700-be9da2c +observeVersion=1.4.0-20250121-143800-aa6fa02 +observeInternalVersion=1.4.0-20250121-144700-d59c066