From 1d502a0444a9b290d7864f91ea178595d6e5f3c0 Mon Sep 17 00:00:00 2001 From: sgayangi Date: Tue, 12 Mar 2024 14:32:50 +0530 Subject: [PATCH] Add GraphQL invocation test case --- .../ballerina/DeployerClient.bal | 3 - test/cucumber-tests/CRs/artifacts.yaml | 260 ++++++++++++++++++ test/cucumber-tests/scripts/setup-hosts.sh | 1 + .../graphql/graphql_conf_with_sub.apk-conf | 2 +- .../graphql/graphql_conf_without_sub.apk-conf | 2 +- .../test/resources/tests/api/GraphQL.feature | 6 + 6 files changed, 269 insertions(+), 5 deletions(-) diff --git a/runtime/config-deployer-service/ballerina/DeployerClient.bal b/runtime/config-deployer-service/ballerina/DeployerClient.bal index 2841e8431..e5beb5d2d 100644 --- a/runtime/config-deployer-service/ballerina/DeployerClient.bal +++ b/runtime/config-deployer-service/ballerina/DeployerClient.bal @@ -408,9 +408,6 @@ public class DeployerClient { } } } - } else { - log:printError("Error occured while deploying routes"); - return e909022("Error occured while deploying routes", error("Error occured while deploying routes")); } } diff --git a/test/cucumber-tests/CRs/artifacts.yaml b/test/cucumber-tests/CRs/artifacts.yaml index f584f3b59..cf592dad8 100644 --- a/test/cucumber-tests/CRs/artifacts.yaml +++ b/test/cucumber-tests/CRs/artifacts.yaml @@ -894,3 +894,263 @@ metadata: spec: applicationRef: 583e4146-7ef5-11ee-b962-0242ac120003 subscriptionRef: semantic-versioning-subscription +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: graphql-faker-schema + namespace: apk-integration-test +data: + schema.graphql: | + schema { + query: Query + mutation: Mutation + subscription: Subscription + } + + # The query type, represents all of the entry points into our object graph + type Query { + hero(episode: Episode): Character + reviews(episode: Episode!): [Review] + search(text: String): [SearchResult] + character(id: ID!): Character + droid(id: ID!): Droid + human(id: ID!): Human + allHumans(first: Int): [Human] + allDroids(first: Int): [Droid] + allCharacters(first: Int): [Character] + starship(id: ID!): Starship + } + + # The mutation type, represents all updates we can make to our data + type Mutation { + createReview(episode: Episode, review: ReviewInput!): Review + } + + # The subscription type, represents all subscriptions we can make to our data + type Subscription { + reviewAdded(episode: Episode): Review + } + + # The episodes in the Star Wars trilogy + enum Episode { + # Star Wars Episode IV: A New Hope, released in 1977. + NEWHOPE + + # Star Wars Episode V: The Empire Strikes Back, released in 1980. + EMPIRE + + # Star Wars Episode VI: Return of the Jedi, released in 1983. + JEDI + + # Star Wars Episode III: Revenge of the Sith, released in 2005 + SITH + } + + # A character from the Star Wars universe + interface Character { + # The ID of the character + id: ID! + + # The name of the character + name: String! + + # The friends of the character, or an empty list if they have none + friends: [Character] + + # The friends of the character exposed as a connection with edges + friendsConnection(first: Int, after: ID): FriendsConnection! + + # The movies this character appears in + appearsIn: [Episode]! + } + + # Units of height + enum LengthUnit { + # The standard unit around the world + METER + + # Primarily used in the United States + FOOT + } + + # A humanoid creature from the Star Wars universe + type Human implements Character { + # The ID of the human + id: ID! + + # What this human calls themselves + name: String! + + # The home planet of the human, or null if unknown + homePlanet: String + + # Height in the preferred unit, default is meters + height(unit: LengthUnit = METER): Float + + # Mass in kilograms, or null if unknown + mass: Float + + # This human's friends, or an empty list if they have none + friends: [Character] + + # The friends of the human exposed as a connection with edges + friendsConnection(first: Int, after: ID): FriendsConnection! + + # The movies this human appears in + appearsIn: [Episode]! + + # A list of starships this person has piloted, or an empty list if none + starships: [Starship] + } + + # An autonomous mechanical character in the Star Wars universe + type Droid implements Character { + # The ID of the droid + id: ID! + + # What others call this droid + name: String! + + # This droid's friends, or an empty list if they have none + friends: [Character] + + # The friends of the droid exposed as a connection with edges + friendsConnection(first: Int, after: ID): FriendsConnection! + + # The movies this droid appears in + appearsIn: [Episode]! + + # This droid's primary function + primaryFunction: String + } + + # A connection object for a character's friends + type FriendsConnection { + # The total number of friends + totalCount: Int + + # The edges for each of the character's friends. + edges: [FriendsEdge] + + # A list of the friends, as a convenience when edges are not needed. + friends: [Character] + + # Information for paginating this connection + pageInfo: PageInfo! + } + + # An edge object for a character's friends + type FriendsEdge { + # A cursor used for pagination + cursor: ID! + + # The character represented by this friendship edge + node: Character + } + + # Information for paginating this connection + type PageInfo { + startCursor: ID + endCursor: ID + hasNextPage: Boolean! + } + + # Represents a review for a movie + type Review { + # The movie + episode: Episode + + # The number of stars this review gave, 1-5 + stars: Int! + + # Comment about the movie + commentary: String + } + + # The input object sent when someone is creating a new review + input ReviewInput { + # 0-5 stars + stars: Int! + + # Comment about the movie, optional + commentary: String + + # Favorite color, optional + favorite_color: ColorInput + } + + # The input object sent when passing in a color + input ColorInput { + red: Int! + green: Int! + blue: Int! + } + + type Starship { + # The ID of the starship + id: ID! + + # The name of the starship + name: String! + + # Length of the starship, along the longest axis + length(unit: LengthUnit = METER): Float + + coordinates: [[Float!]!] + } + + union SearchResult = Human | Droid | Starship + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: graphql-faker + namespace: apk-integration-test + labels: + app: graphql-faker +spec: + replicas: 1 + selector: + matchLabels: + app: graphql-faker + template: + metadata: + labels: + app: graphql-faker + spec: + containers: + - name: graphql-faker + image: apisguru/graphql-faker + args: ["--open=false", "/etc/graphql-faker/schema.graphql"] + ports: + - containerPort: 9002 + volumeMounts: + - name: schema-volume + mountPath: /etc/graphql-faker + resources: + requests: + memory: "256Mi" + cpu: "250m" + limits: + memory: "512Mi" + cpu: "500m" + volumes: + - name: schema-volume + configMap: + name: graphql-faker-schema +--- +apiVersion: v1 +kind: Service +metadata: + name: graphql-faker-service + namespace: apk-integration-test +spec: + type: LoadBalancer + ports: + - port: 9002 + targetPort: 9002 + protocol: TCP + selector: + app: graphql-faker diff --git a/test/cucumber-tests/scripts/setup-hosts.sh b/test/cucumber-tests/scripts/setup-hosts.sh index 4ebf9f1cd..5fb451248 100644 --- a/test/cucumber-tests/scripts/setup-hosts.sh +++ b/test/cucumber-tests/scripts/setup-hosts.sh @@ -5,6 +5,7 @@ kubectl wait deployment/httpbin -n apk-integration-test --for=condition=availabl kubectl wait deployment/backend-retry-deployment -n apk-integration-test --for=condition=available --timeout=600s kubectl wait deployment/dynamic-backend -n apk-integration-test --for=condition=available --timeout=600s kubectl wait deployment/interceptor-service-deployment -n apk-integration-test --for=condition=available --timeout=600s +kubectl wait deployment/graphql-faker -n apk-integration-test --for=condition=available --timeout=600s kubectl wait --timeout=5m -n apk-integration-test deployment/apk-test-setup-wso2-apk-adapter-deployment --for=condition=Available kubectl wait --timeout=15m -n apk-integration-test deployment/apk-test-setup-wso2-apk-gateway-runtime-deployment --for=condition=Available IP=$(kubectl get svc apk-test-setup-wso2-apk-gateway-service -n apk-integration-test --output jsonpath='{.status.loadBalancer.ingress[0].ip}') diff --git a/test/cucumber-tests/src/test/resources/artifacts/apk-confs/graphql/graphql_conf_with_sub.apk-conf b/test/cucumber-tests/src/test/resources/artifacts/apk-confs/graphql/graphql_conf_with_sub.apk-conf index 622650b75..22f4a9e33 100644 --- a/test/cucumber-tests/src/test/resources/artifacts/apk-confs/graphql/graphql_conf_with_sub.apk-conf +++ b/test/cucumber-tests/src/test/resources/artifacts/apk-confs/graphql/graphql_conf_with_sub.apk-conf @@ -8,7 +8,7 @@ defaultVersion: false subscriptionValidation: false endpointConfigurations: production: - endpoint: "https://run.mocky.io/v3/85516819-1edd-412b-a32b-a9284705a0b4" + endpoint: "http://graphql-faker-service:9002/graphql" operations: - target: "hero" verb: "QUERY" diff --git a/test/cucumber-tests/src/test/resources/artifacts/apk-confs/graphql/graphql_conf_without_sub.apk-conf b/test/cucumber-tests/src/test/resources/artifacts/apk-confs/graphql/graphql_conf_without_sub.apk-conf index 4133b169a..b6b12e423 100644 --- a/test/cucumber-tests/src/test/resources/artifacts/apk-confs/graphql/graphql_conf_without_sub.apk-conf +++ b/test/cucumber-tests/src/test/resources/artifacts/apk-confs/graphql/graphql_conf_without_sub.apk-conf @@ -8,7 +8,7 @@ defaultVersion: false subscriptionValidation: false endpointConfigurations: production: - endpoint: "https://run.mocky.io/v3/85516819-1edd-412b-a32b-a9284705a0b4" + endpoint: "http://graphql-faker-service:9002/graphql" operations: - target: "hero" verb: "QUERY" diff --git a/test/cucumber-tests/src/test/resources/tests/api/GraphQL.feature b/test/cucumber-tests/src/test/resources/tests/api/GraphQL.feature index e92d7aab2..23e7578b2 100644 --- a/test/cucumber-tests/src/test/resources/tests/api/GraphQL.feature +++ b/test/cucumber-tests/src/test/resources/tests/api/GraphQL.feature @@ -12,6 +12,12 @@ Feature: Generating APK conf for GraphQL API And the definition file "artifacts/definitions/graphql_sample_api.graphql" And make the API deployment request Then the response status code should be 200 + Then I set headers + | Authorization | bearer ${accessToken} | + And I send "POST" request to "https://default.gw.wso2.com:9095/graphql/3.14" with body "{\"query\":\"{ allHumans { name } }\"}" + And I eventually receive 200 response code, not accepting + | 429 | + | 500 | Scenario: Deploying APK conf using a valid GraphQL API definition containing a subscription resource Given The system is ready