Skip to content

Commit

Permalink
Adding agent integration tests for the remaining functionalities with…
Browse files Browse the repository at this point in the history
… modified helm-chart and workflow
  • Loading branch information
O-sura committed Apr 26, 2024
1 parent 9e25255 commit 4c68be1
Show file tree
Hide file tree
Showing 58 changed files with 4,527 additions and 830 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/agent-integration-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,9 @@ jobs:
if: github.event_name == 'pull_request_target' && contains(github.event.label.name, 'trigger-action')
shell: sh
run: |
helm repo add wso2apim https://github.com/wso2/helm-apim/releases/download/cp-4.3.0-rc
helm repo add wso2apim https://github.com/wso2/helm-apim/releases/download/cp-4.3.0
helm repo update
helm install apim wso2apim/wso2am-cp --version 4.3.0-rc -f https://raw.githubusercontent.com/wso2/apk/main/helm-charts/samples/apim/cp/amd-values.yaml -n apk --debug --wait --timeout 5m0s
helm install apim wso2apim/wso2am-cp --version 4.3.0 -f https://raw.githubusercontent.com/wso2/apk/main/helm-charts/samples/apim/cp/values.yaml -n apk --debug --wait --timeout 5m0s
kubectl get pods -n apk
kubectl get svc -n apk
- name: Helm release deploy APK DP
Expand Down Expand Up @@ -132,4 +132,4 @@ jobs:
uses: malinthaprasan/action-surefire-report@v1
with:
report_paths: 'apk-agent-repo/test/postman-tests/build/*.xml'
fail_on_test_failures: true
fail_on_test_failures: true
2 changes: 1 addition & 1 deletion test/apim-apk-agent-test/agent-helm-chart/Chart.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ dependencies:
repository: https://charts.jetstack.io
version: v1.10.1
digest: sha256:d1377472dfb3a62dccc58dd12757d029afa304c1f2ded3f5cc3052b308fb8c00
generated: "2024-04-03T21:00:00.612083+05:30"
generated: "2024-04-05T14:59:18.259209+05:30"
2 changes: 1 addition & 1 deletion test/apim-apk-agent-test/agent-helm-chart/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ apiVersion: v2
name: apim-apk-agent
description: A Helm chart for deploying apim-apk-agent
type: application
version: 1.1.0-beta
version: 1.1.0
appVersion: "1.16.0"
dependencies:
- name: cert-manager
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ spec:
app.kubernetes.io/app: "apim-apk-agent"
app.kubernetes.io/name: {{ .Chart.Name }}
app.kubernetes.io/instance: {{ .Release.Name }}
annotations:
checksum/config: {{ include (print $.Template.BasePath "/log-conf.yaml") . | sha256sum }}
spec:
serviceAccountName: wso2agent-platform
containers:
Expand Down Expand Up @@ -82,6 +84,13 @@ spec:
initialDelaySeconds: 20
periodSeconds: 20
failureThreshold: 5
resources:
requests:
memory: {{ .Values.resources.requests.memory | default "128Mi" }}
cpu: {{ .Values.resources.requests.cpu | default "100m" }}
limits:
memory: {{ .Values.resources.limits.memory | default "256Mi" }}
cpu: {{ .Values.resources.limits.cpu | default "200m" }}
volumes:
- name: log-conf-volume
configMap:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

{{- if .Values.serviceAccount.enableServiceAccountCreation }}
apiVersion: v1
kind: Secret
metadata:
name: agent-account-secret-token
namespace: {{ .Release.Namespace }}
annotations:
kubernetes.io/service-account.name: wso2agent-platform
type: kubernetes.io/service-account-token
kubernetes.io/service-account.name: {{ .Values.serviceAccount.serviceAccountName | default "wso2agent-platform" }}
type: kubernetes.io/service-account-token
{{- end}}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

{{- if .Values.serviceAccount.enableServiceAccountCreation }}
apiVersion: rbac.authorization.k8s.io/v1
# This cluster role binding allows anyone in the "manager" group to read secrets in any namespace.
kind: ClusterRoleBinding
Expand All @@ -22,10 +22,11 @@ metadata:
namespace: {{ .Release.Namespace }}
roleRef:
kind: ClusterRole
name: wso2agent-role
name: {{ .Values.serviceAccount.roleName | default "wso2agent-role" }}
apiGroup: rbac.authorization.k8s.io
subjects:
# You can specify more than one "subject"
- kind: ServiceAccount
name: wso2agent-platform
namespace: {{ .Release.Namespace }}
name: {{ .Values.serviceAccount.serviceAccountName | default "wso2agent-platform" }}
namespace: {{ .Release.Namespace }}
{{- end }}
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@
# specific language governing permissions and limitations
# under the License.

{{- if .Values.serviceAccount.enableServiceAccountCreation }}
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: wso2agent-role
name: {{ .Values.serviceAccount.roleName | default "wso2agent-role" }}
rules:
- apiGroups: [""]
resources: ["services","configmaps","secrets"]
Expand Down Expand Up @@ -120,4 +121,5 @@ rules:
verbs: ["update"]
- apiGroups: ["dp.wso2.com"]
resources: ["gqlroutes/status"]
verbs: ["get","patch","update"]
verbs: ["get","patch","update"]
{{- end }}
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@
# specific language governing permissions and limitations
# under the License.

{{- if .Values.serviceAccount.enableServiceAccountCreation }}
apiVersion: v1
kind: ServiceAccount
metadata:
name: wso2agent-platform
namespace: {{ .Release.Namespace }}
name: {{ .Values.serviceAccount.serviceAccountName | default "wso2agent-platform" }}
namespace: {{ .Release.Namespace }}
{{- end -}}
17 changes: 14 additions & 3 deletions test/apim-apk-agent-test/agent-helm-chart/values.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com) All Rights Reserved.
# Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com) All Rights Reserved.
#
# WSO2 LLC. licenses this file to you under the Apache License,
# Version 2.0 (the "License"); you may not use this file except
Expand All @@ -21,7 +21,13 @@ image:
pullPolicy: Always
service:
name: apim-apk-agent-service
resources: {}
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "200m"
controlPlane:
enabled: true
serviceURL: https://apim-wso2am-cp-1-service.apk.svc.cluster.local:9443/
Expand All @@ -40,4 +46,9 @@ metrics:
agent:
mode: CPtoDP
certmanager:
enabled: true
enabled: false
serviceAccount:
enableServiceAccountCreation: true
enableClusterRoleCreation: true
serviceAccountName: wso2agent-platform
roleName: wso2agent-role
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@
import org.wso2.apk.integration.utils.clients.SimpleHTTPClient;
import java.nio.file.Files;
import java.nio.charset.StandardCharsets;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.net.URI;
Expand All @@ -56,6 +57,7 @@ public class APIDeploymentSteps {
private final SharedContext sharedContext;
private File payloadFile;
private File definitionFile;
private File certificateFile;

private String OASURL;

Expand Down Expand Up @@ -265,6 +267,8 @@ public void make_subscription_request() throws Exception {

sharedContext.setResponse(response);
sharedContext.setResponseBody(SimpleHTTPClient.responseEntityBodyToString(sharedContext.getResponse()));
sharedContext.setSubscriptionID(Utils.extractKeys(sharedContext.getResponseBody(), "subscriptionId"));
logger.info("Extracted subscription ID: " + sharedContext.getSubscriptionID());
Thread.sleep(3000);
}

Expand Down Expand Up @@ -312,6 +316,7 @@ public void make_access_token_generation_request(String type) throws Exception {
sharedContext.setResponse(response);
sharedContext.setResponseBody(SimpleHTTPClient.responseEntityBodyToString(sharedContext.getResponse()));
sharedContext.setApiAccessToken(Utils.extractKeys(sharedContext.getResponseBody(), "accessToken"));
sharedContext.addStoreValue("accessToken",sharedContext.getApiAccessToken());
logger.info("Access Token: " + sharedContext.getApiAccessToken());
Thread.sleep(3000);
}
Expand Down Expand Up @@ -342,6 +347,7 @@ public void make_access_token_generation_request_without_scopes() throws Excepti
sharedContext.setResponse(response);
sharedContext.setResponseBody(SimpleHTTPClient.responseEntityBodyToString(sharedContext.getResponse()));
sharedContext.setApiAccessToken(Utils.extractKeys(sharedContext.getResponseBody(), "accessToken"));
sharedContext.addStoreValue("accessToken",sharedContext.getApiAccessToken());
logger.info("Access Token without scopes: " + sharedContext.getApiAccessToken());
Thread.sleep(3000);
}
Expand Down Expand Up @@ -449,12 +455,24 @@ public void iHaveValidGraphQLDefinition() throws Exception {
headers.put(Constants.REQUEST_HEADERS.HOST, Constants.DEFAULT_APIM_HOST);

HttpEntity multipartEntity = builder.build();


// Convert the multipart form entity to a string representation
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
multipartEntity.writeTo(outputStream);
String multipartForm = new String(outputStream.toByteArray(), StandardCharsets.UTF_8);

// Log the multipart form
logger.info("Multipart Form Data:\n{}"+ multipartForm);
logger.info("Validator URL: " + Utils.getGQLSchemaValidatorURL());
logger.info("Publisher Token: " + sharedContext.getPublisherAccessToken());

HttpResponse response = sharedContext.getHttpClient().doPostWithMultipart(Utils.getGQLSchemaValidatorURL(),
multipartEntity, headers);

sharedContext.setResponse(response);
logger.info("Full Res:" + response);
sharedContext.setResponseBody(SimpleHTTPClient.responseEntityBodyToString(sharedContext.getResponse()));
logger.info("GQL validation res: "+ sharedContext.getResponseBody());
sharedContext.setAPIDefinitionValidStatus(Utils.extractValidStatus(sharedContext.getResponseBody()));
Thread.sleep(3000);
}
Expand Down Expand Up @@ -484,7 +502,7 @@ public void make_import_gqlapi_creation_request() throws Exception {
Thread.sleep(3000);
}

@Then("I update the GQL API settings")
@Then("I update the API settings")
public void make_update_gql_request() throws Exception {
String fileContent = new String(Files.readAllBytes(payloadFile.toPath()), StandardCharsets.UTF_8);
Map<String, String> headers = new HashMap<>();
Expand Down Expand Up @@ -579,17 +597,91 @@ public void create_new_version_of_the_api(String newVersion, String isDefaultVer

@Then("I set new API throttling policy allowing {string} requests per every {string} minute")
public void add_new_custom_throttling_policy(String requestCount, String unitTime) throws Exception {
// {"policyName":"TestRatelimit","description":"Test descroption","conditionalGroups":[],"defaultLimit":{"requestCount":{"timeUnit":"min","unitTime":"1","requestCount":"3"},"type":"REQUESTCOUNTLIMIT","bandwidth":null}}
String payload = "{\"policyName\":\"TestRatelimit\",\"description\":\"Test descroption\",\"conditionalGroups\":[],\"defaultLimit\":{\"requestCount\":{\"timeUnit\":\"min\",\"unitTime\":"+ unitTime + ",\"requestCount\":" + requestCount + "},\"type\":\"REQUESTCOUNTLIMIT\",\"bandwidth\":null}}";

Map<String, String> headers = new HashMap<>();
headers.put(Constants.REQUEST_HEADERS.AUTHORIZATION, "Bearer " + sharedContext.getAdminAccessToken());
headers.put(Constants.REQUEST_HEADERS.HOST, Constants.DEFAULT_API_HOST);
//https://am.wso2.com/api/am/admin/v4/throttling/policies/advanced
// https:// + DEFAULT_API_HOST + "/" + DEFAULT_ADMINPORTAL + "throttling/policies/advanced"
HttpResponse httpResponse = sharedContext.getHttpClient().doPost(Utils.getAPIThrottlingConfigEndpoint(), headers, payload, Constants.CONTENT_TYPES.APPLICATION_JSON);

sharedContext.setResponse(httpResponse);
sharedContext.setResponseBody(SimpleHTTPClient.responseEntityBodyToString(sharedContext.getResponse()));
sharedContext.setPolicyID(Utils.extractKeys(sharedContext.getResponseBody(), "policyId"));
Thread.sleep(3000);
}

@Then("I send the subcription blocking request")
public void send_subscription_blocking() throws Exception {
Map<String, String> headers = new HashMap<>();
headers.put(Constants.REQUEST_HEADERS.AUTHORIZATION, "Bearer " + sharedContext.getPublisherAccessToken());
headers.put(Constants.REQUEST_HEADERS.HOST, Constants.DEFAULT_API_HOST);
HttpResponse httpResponse = sharedContext.getHttpClient().doPost(Utils.getSubscriptionBlockingURL(sharedContext.getSubscriptionID()), headers, "", Constants.CONTENT_TYPES.APPLICATION_JSON);
sharedContext.setResponse(httpResponse);
sharedContext.setResponseBody(SimpleHTTPClient.responseEntityBodyToString(sharedContext.getResponse()));
Thread.sleep(3000);
}

@Then("I make an internal key generation request")
public void generate_internal_key() throws Exception {
Map<String, String> headers = new HashMap<>();
headers.put(Constants.REQUEST_HEADERS.AUTHORIZATION, "Bearer " + sharedContext.getPublisherAccessToken());
headers.put(Constants.REQUEST_HEADERS.HOST, Constants.DEFAULT_API_HOST);

HttpResponse httpResponse = sharedContext.getHttpClient().doPost(Utils.getInternalKeyGenerationEndpoint(sharedContext.getApiUUID()), headers, "", Constants.CONTENT_TYPES.APPLICATION_JSON);

sharedContext.setResponse(httpResponse);
sharedContext.setResponseBody(SimpleHTTPClient.responseEntityBodyToString(sharedContext.getResponse()));
sharedContext.setAPIInternalKey(Utils.extractKeys(sharedContext.getResponseBody(), "apikey"));
sharedContext.addStoreValue("internalKey",Utils.extractKeys(sharedContext.getResponseBody(), "apikey"));
logger.info("Internal Key: " + sharedContext.getAPIInternalKey());
Thread.sleep(3000);
}

@Then("I have a client certificate {string}")
public void get_valid_client_cert_for_mtls(String clientCertificatePath) throws Exception {
URL url = Resources.getResource("artifacts/certificates/" + clientCertificatePath);

certificateFile = new File(url.getPath());
String clientCertificate = Resources.toString(url, StandardCharsets.UTF_8);
sharedContext.addStoreValue("clientCertificate", clientCertificate);

}

@When("I update the API with mtls certificate data with the alias {string}")
public void update_api_with_mtls_cert_data(String alias) throws Exception {

MultipartEntityBuilder builder = MultipartEntityBuilder.create()
.setMode(HttpMultipartMode.BROWSER_COMPATIBLE)
.addBinaryBody("certificate", certificateFile, ContentType.create("application/x-x509-ca-cert"), "tls.crt")
.addTextBody("alias", alias, ContentType.TEXT_PLAIN)
.addTextBody("tier", "", ContentType.TEXT_PLAIN);

Map<String, String> headers = new HashMap<>();
headers.put(Constants.REQUEST_HEADERS.AUTHORIZATION, "Bearer " + sharedContext.getPublisherAccessToken());
headers.put(Constants.REQUEST_HEADERS.HOST, Constants.DEFAULT_API_HOST);

HttpEntity multipartEntity = builder.build();

HttpResponse response = sharedContext.getHttpClient().doPostWithMultipart(Utils.getClientCertUpdateEndpoint(sharedContext.getApiUUID()),
multipartEntity, headers);

sharedContext.setResponse(response);
sharedContext.setResponseBody(SimpleHTTPClient.responseEntityBodyToString(sharedContext.getResponse()));
Thread.sleep(3000);
}

@Then("I delete the created API throttling policy")
public void delete_throtlling_policy() throws Exception {
Map<String, String> headers = new HashMap<>();
headers.put(Constants.REQUEST_HEADERS.AUTHORIZATION, "Bearer " + sharedContext.getAdminAccessToken());
headers.put(Constants.REQUEST_HEADERS.HOST, Constants.DEFAULT_API_HOST);

logger.info("PolicyID to be deleted: " + sharedContext.getPolicyID());
String URI = Utils.getAPIThrottlingConfigEndpoint() + "/" + sharedContext.getPolicyID();
HttpResponse httpResponse = sharedContext.getHttpClient().doDelete(URI, headers);
sharedContext.setResponse(httpResponse);
sharedContext.setResponseBody(SimpleHTTPClient.responseEntityBodyToString(sharedContext.getResponse()));
Thread.sleep(3000);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,6 @@ public void theResponseStatusCodeShouldBe(int expectedStatusCode) throws IOExcep

@Then("I send {string} request to {string} with body {string}")
public void sendHttpRequest(String httpMethod, String url, String body) throws IOException {
sharedContext.addHeader("Authorization", "Bearer " + sharedContext.getApiAccessToken());
body = Utils.resolveVariables(body, sharedContext.getValueStore());
if (sharedContext.getResponse() instanceof CloseableHttpResponse) {
((CloseableHttpResponse) sharedContext.getResponse()).close();
Expand Down Expand Up @@ -185,6 +184,11 @@ public void setHeaders(DataTable dataTable) {
}
}

@Then("I remove the header {string}")
public void removeHeader(String key) {
sharedContext.removeHeader(key);
}

@Then("the response headers should contain")
public void theResponseHeadersShouldContain(DataTable dataTable) {
List<List<String>> rows = dataTable.asLists(String.class);
Expand Down Expand Up @@ -351,7 +355,7 @@ public void iHaveValidPublisherAccessToken() throws Exception {
headers.put(Constants.REQUEST_HEADERS.HOST, Constants.DEFAULT_IDP_HOST);
headers.put(Constants.REQUEST_HEADERS.AUTHORIZATION, basicAuthHeader);

HttpResponse httpResponse = httpClient.doPost(Utils.getTokenEndpointURL(), headers, "grant_type=password&username=admin&password=admin&scope=apim:api_view apim:api_create apim:api_publish apim:api_delete apim:api_manage apim:api_import_export",
HttpResponse httpResponse = httpClient.doPost(Utils.getTokenEndpointURL(), headers, "grant_type=password&username=admin&password=admin&scope=apim:api_view apim:api_create apim:api_publish apim:api_delete apim:api_manage apim:api_import_export apim:subscription_manage apim:client_certificates_add apim:client_certificates_update",
Constants.CONTENT_TYPES.APPLICATION_X_WWW_FORM_URLENCODED);
logger.info("Response: " + httpResponse);
sharedContext.setPublisherAccessToken(Utils.extractToken(httpResponse));
Expand Down Expand Up @@ -427,4 +431,10 @@ public void theResponseShouldBeGivenAs() throws IOException {
// sharedContext.setAccessToken(Utils.extractToken(httpResponse));
// sharedContext.addStoreValue(Constants.ACCESS_TOKEN, sharedContext.getAccessToken());
// }

@Then("I set {string} as the new access token")
public void set_invalid_access_token(String newToken) throws Exception {
sharedContext.setApiAccessToken(newToken);
sharedContext.addStoreValue("accessToken",sharedContext.getApiAccessToken());
}
}
Loading

0 comments on commit 4c68be1

Please sign in to comment.