summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--aai-resources/pom.xml29
-rw-r--r--aai-resources/src/main/resources/application.properties10
-rw-r--r--aai-resources/src/test/java/org/onap/aai/it/performance/K6PerformanceTest.java139
-rw-r--r--aai-resources/src/test/resources/k6/test.js66
-rw-r--r--aai-resources/src/test/resources/logback.xml5
5 files changed, 243 insertions, 6 deletions
diff --git a/aai-resources/pom.xml b/aai-resources/pom.xml
index 8ef378c..d50695d 100644
--- a/aai-resources/pom.xml
+++ b/aai-resources/pom.xml
@@ -571,6 +571,10 @@
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</exclusion>
+ <exclusion>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </exclusion>
</exclusions>
</dependency>
<dependency>
@@ -661,13 +665,14 @@
<version>${groovy.version}</version>
</dependency>
<dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-test</artifactId>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-test</artifactId>
<scope>test</scope>
</dependency>
+ <!-- Only used for the WebTestClient -->
<dependency>
<groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-test</artifactId>
+ <artifactId>spring-boot-starter-webflux</artifactId>
<scope>test</scope>
</dependency>
<dependency>
@@ -710,6 +715,24 @@
<scope>test</scope>
</dependency>
<dependency>
+ <groupId>org.testcontainers</groupId>
+ <artifactId>testcontainers</artifactId>
+ <version>1.19.8</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.testcontainers</groupId>
+ <artifactId>junit-jupiter</artifactId>
+ <version>1.19.8</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.testcontainers</groupId>
+ <artifactId>k6</artifactId>
+ <version>1.19.8</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
diff --git a/aai-resources/src/main/resources/application.properties b/aai-resources/src/main/resources/application.properties
index cc0c46a..960db1b 100644
--- a/aai-resources/src/main/resources/application.properties
+++ b/aai-resources/src/main/resources/application.properties
@@ -8,7 +8,7 @@ spring.application.name=aai-resources
spring.jersey.type=filter
spring.main.allow-bean-definition-overriding=true
-spring.sleuth.enabled=true
+spring.sleuth.enabled=false
spring.zipkin.baseUrl=http://jaeger-collector.istio-system:9411
spring.sleuth.messaging.jms.enabled = false
spring.sleuth.trace-id128=true
@@ -43,6 +43,7 @@ server.certs.location=${server.local.startpath}/etc/auth/
server.keystore.name=aai_keystore
server.truststore.name=aai_keystore
server.port=8447
+server.ssl.enabled=false
server.ssl.enabled-protocols=TLSv1.1,TLSv1.2
server.ssl.key-store=${server.certs.location}${server.keystore.name}
server.ssl.key-store-password=password(OBF:1vn21ugu1saj1v9i1v941sar1ugw1vo0)
@@ -60,7 +61,7 @@ jms.bind.address=tcp://localhost:61647
# dmaap.ribbon.listOfServers=localhost:3904
spring.kafka.producer.bootstrap-servers=${BOOTSTRAP_SERVERS}
spring.kafka.producer.properties.security.protocol=SASL_PLAINTEXT
-spring.kafka.producer.properties.sasl.mechanism=SCRAM-SHA-512
+spring.kafka.producer.properties.sasl.mechanism=SCRAM-SHA-512
spring.kafka.producer.key-serializer=org.apache.kafka.common.serialization.StringSerializer
spring.kafka.producer.value-serializer=org.apache.kafka.common.serialization.StringSerializer
spring.kafka.producer.properties.sasl.jaas.config = ${JAAS_CONFIG}
@@ -148,3 +149,8 @@ validation.service.node-types=generic-vnf,lag-interface,l-interface,logical-link
# List of X-FromAppId regexes seperated by comma to ignore the pre validation for
# Note: please don't add any client id here as this is only for testing tools such as robot
validation.service.exclusion-regexes=
+
+BOOTSTRAP_SERVERS=localhost:9092
+JAAS_CONFIG=""
+BUNDLECONFIG_DIR=src/main/resources/
+AJSC_HOME=./
diff --git a/aai-resources/src/test/java/org/onap/aai/it/performance/K6PerformanceTest.java b/aai-resources/src/test/java/org/onap/aai/it/performance/K6PerformanceTest.java
new file mode 100644
index 0000000..8428cb5
--- /dev/null
+++ b/aai-resources/src/test/java/org/onap/aai/it/performance/K6PerformanceTest.java
@@ -0,0 +1,139 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2024 Deutsche Telekom. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.aai.it.performance;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.junit.Assert.assertThat;
+
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
+import org.janusgraph.core.JanusGraph;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.onap.aai.ResourcesApp;
+import org.onap.aai.db.props.AAIProperties;
+import org.onap.aai.dbmap.AAIGraph;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
+import org.springframework.boot.web.server.LocalServerPort;
+import org.testcontainers.containers.output.WaitingConsumer;
+import org.testcontainers.junit.jupiter.Testcontainers;
+import org.testcontainers.k6.K6Container;
+import org.testcontainers.utility.MountableFile;
+
+import lombok.SneakyThrows;
+
+@Testcontainers
+@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
+public class K6PerformanceTest {
+
+ private static final Logger logger = LoggerFactory.getLogger(ResourcesApp.class.getName());
+ private static final long nPservers = 10;
+
+ @LocalServerPort
+ private int port;
+
+
+ private boolean initialized = false;
+
+ @BeforeEach
+ public void setup() {
+ if (!initialized) {
+ initialized = true;
+ AAIGraph.getInstance();
+
+ long startTime = System.currentTimeMillis();
+ logger.info("Creating pserver nodes");
+ loadPerformanceTestData();
+ long endTime = System.currentTimeMillis();
+ logger.info("Created pserver nodes in {} seconds", (endTime - startTime) / 1000);
+ }
+ }
+
+ @AfterAll
+ public static void cleanup() {
+ JanusGraph graph = AAIGraph.getInstance().getGraph();
+ graph.traversal().V().has("aai-node-type", "pserver").drop().iterate();
+ graph.tx().commit();
+ }
+
+ @Test
+ public void k6StandardTest() throws Exception {
+ int testDuration = 5;
+
+ try (
+ K6Container container = new K6Container("grafana/k6:0.49.0")
+ .withNetworkMode("host")
+ .withAccessToHost(true)
+ .withTestScript(MountableFile.forClasspathResource("k6/test.js"))
+ .withScriptVar("API_PORT", String.valueOf(port))
+ .withScriptVar("API_VERSION", "v29")
+ .withScriptVar("DURATION_SECONDS", String.valueOf(testDuration))
+ .withScriptVar("N_PSERVERS", String.valueOf(nPservers))
+ .withCmdOptions("--quiet", "--no-usage-report");) {
+ container.start();
+
+ WaitingConsumer consumer = new WaitingConsumer();
+ container.followOutput(consumer);
+
+ // Wait for test script results to be collected
+ consumer.waitUntil(
+ frame -> {
+ return frame.getUtf8String().contains("iteration_duration");
+ },
+ testDuration + 30,
+ TimeUnit.SECONDS);
+
+ logger.debug(container.getLogs());
+ assertThat(container.getLogs(), containsString("✓ status was 200"));
+ assertThat(container.getLogs(), containsString("✓ returned correct number of results"));
+ assertThat(container.getLogs(), containsString("✓ http_req_duration"));
+ assertThat(container.getLogs(), containsString("✓ http_req_failed"));
+ }
+ }
+
+ @SneakyThrows
+ public static void loadPerformanceTestData() {
+ JanusGraph graph = AAIGraph.getInstance().getGraph();
+ GraphTraversalSource g = graph.traversal();
+ long n = nPservers;
+ for (long i = 0; i < n; i++) {
+ createPServer(g, i);
+ }
+ graph.tx().commit();
+ }
+
+ private static void createPServer(GraphTraversalSource g, long i) {
+ String hostname = "hostname" + i;
+ String uri = "/cloud-infrastructure/pservers/pserver/" + hostname;
+ g.addV()
+ .property("aai-node-type", "pserver")
+ .property("hostname", hostname)
+ .property("resource-version", UUID.randomUUID().toString())
+ .property(AAIProperties.AAI_URI, uri)
+ .next();
+ }
+}
diff --git a/aai-resources/src/test/resources/k6/test.js b/aai-resources/src/test/resources/k6/test.js
new file mode 100644
index 0000000..8e55214
--- /dev/null
+++ b/aai-resources/src/test/resources/k6/test.js
@@ -0,0 +1,66 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2024 Deutsche Telekom. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+import http from "k6/http";
+import { check } from "k6";
+
+export const options = {
+ vus: 3,
+ duration: `${__ENV.DURATION_SECONDS}s`,
+ thresholds: {
+ http_req_failed: ["rate<0.01"], // http errors should be less than 1%
+ http_req_duration: [
+ "p(99)<3000",
+ "p(90)<2000",
+ "avg<1000",
+ "med<1000",
+ "min<1000",
+ ],
+ },
+ insecureSkipTLSVerify: true,
+};
+
+export default function () {
+ const encodedCredentials = 'QUFJOkFBSQ==';
+ const options = {
+ headers: {
+ Accept: "application/json",
+ Authorization: `Basic ${encodedCredentials}`,
+ "X-FromAppId": "k6",
+ "X-TransactionId": "someTransaction",
+ },
+ };
+ const pserverCount = parseInt(`${__ENV.N_PSERVERS}`, 10);
+ const baseUrl = `http://localhost:${__ENV.API_PORT}/aai/${__ENV.API_VERSION}`;
+ const url = `/cloud-infrastructure/pservers`;
+ const res = http.get(baseUrl + url, options);
+
+ if (res.status != 200) {
+ console.error(res);
+ }
+
+ const parsedResponse = JSON.parse(res.body);
+ if (parsedResponse.pserver.length != pserverCount) {
+ console.error(`Expected ${pserverCount} results, got ${parsedResponse.pserver.length}`);
+ }
+ check(res, {
+ "status was 200": (r) => r.status == 200,
+ "returned correct number of results": () => parsedResponse.pserver.length == pserverCount,
+ });
+}
diff --git a/aai-resources/src/test/resources/logback.xml b/aai-resources/src/test/resources/logback.xml
index 7d35439..a550336 100644
--- a/aai-resources/src/test/resources/logback.xml
+++ b/aai-resources/src/test/resources/logback.xml
@@ -142,7 +142,7 @@
<pattern>${transLogPattern}</pattern>
</encoder>
</appender>
-
+
<appender name="asynctranslog" class="ch.qos.logback.classic.AsyncAppender">
<queueSize>${queueSize}</queueSize>
<includeCallerData>true</includeCallerData>
@@ -266,6 +266,9 @@
<appender-ref ref="asyncMETRIC" />
</logger>
+ <logger name="org.testcontainers" level="INFO"/>
+ <logger name="com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.wire" level="OFF"/>
+
<root level="DEBUG">
<appender-ref ref="external" />
<appender-ref ref="STDOUT" />