aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordanielhanrahan <daniel.hanrahan@est.tech>2024-04-29 16:16:42 +0100
committerdanielhanrahan <daniel.hanrahan@est.tech>2024-05-22 17:09:30 +0100
commitc0b6f3ad5ed529e4f3261cbf6eed44faec3883a4 (patch)
tree5841537492c76fb1ed635177c4c7419435032730
parent6d85c1547fad014fbea44af57440e3de1c3ce9ff (diff)
Add k6 performance tests for NCMP
This commit adds K6 tests for NCMP functionalities: - Registration of 20000 CM-handles - Synchronous single CM-handle passthrough read operation - CM-handle and ID searches for no filter, module, and public property - De-registration of 20000 CM-handles - A mixed load test Also includes a README and shell scripts to run all tests. Issue-ID: CPS-2199 Signed-off-by: danielhanrahan <daniel.hanrahan@est.tech> Change-Id: Ia2e59674057ed28f5f9ceed9465133f7c0ce8318
-rw-r--r--k6-tests/README.md25
-rw-r--r--k6-tests/ncmp/1-create-cmhandles.js56
-rw-r--r--k6-tests/ncmp/10-mixed-load-test.js88
-rw-r--r--k6-tests/ncmp/11-delete-cmhandles.js48
-rw-r--r--k6-tests/ncmp/2-wait-for-cmhandles-to-be-ready.js64
-rw-r--r--k6-tests/ncmp/3-passthrough-read.js51
-rw-r--r--k6-tests/ncmp/4-id-search-no-filter.js35
-rw-r--r--k6-tests/ncmp/5-search-no-filter.js34
-rw-r--r--k6-tests/ncmp/6-id-search-public-property.js42
-rw-r--r--k6-tests/ncmp/7-search-public-property.js42
-rw-r--r--k6-tests/ncmp/8-id-search-module.js42
-rw-r--r--k6-tests/ncmp/9-search-module.js42
-rwxr-xr-xk6-tests/ncmp/run-all-tests.sh44
-rw-r--r--k6-tests/ncmp/search-base.js35
-rw-r--r--k6-tests/ncmp/utils.js41
-rwxr-xr-xk6-tests/run-k6-tests.sh39
-rwxr-xr-xk6-tests/setup.sh22
-rwxr-xr-xk6-tests/teardown.sh31
18 files changed, 781 insertions, 0 deletions
diff --git a/k6-tests/README.md b/k6-tests/README.md
new file mode 100644
index 000000000..e26b18609
--- /dev/null
+++ b/k6-tests/README.md
@@ -0,0 +1,25 @@
+# k6 tests
+
+[k6](https://k6.io/) is used for performance tests.
+k6 tests are written in JavaScript.
+
+## k6 installation
+Follow the instructions in the [k6 installation guide](https://grafana.com/docs/k6/latest/set-up/install-k6/)
+to get started.
+
+## Running the k6 test suites
+Simply run the main script. (The script assumes k6 and docker-compose have been installed).
+```shell
+./run-k6-tests.sh
+```
+
+## Running k6 tests manually
+Before running tests, ensure CPS/NCMP is running:
+```shell
+docker-compose -f docker-compose/docker-compose.yml --profile dmi-stub up
+```
+
+To run an individual test from command line, use
+```shell
+k6 run ncmp/1-create-cmhandles.js
+```
diff --git a/k6-tests/ncmp/1-create-cmhandles.js b/k6-tests/ncmp/1-create-cmhandles.js
new file mode 100644
index 000000000..c32cd2f03
--- /dev/null
+++ b/k6-tests/ncmp/1-create-cmhandles.js
@@ -0,0 +1,56 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2024 Nordix Foundation
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+import http from 'k6/http';
+import exec from 'k6/execution';
+import { check } from 'k6';
+import { NCMP_BASE_URL, DMI_PLUGIN_URL, TOTAL_CM_HANDLES, makeBatchOfCmHandleIds } from './utils.js';
+
+const BATCH_SIZE = 100;
+export const options = {
+ vus: 1,
+ iterations: Math.ceil(TOTAL_CM_HANDLES / BATCH_SIZE),
+ thresholds: {
+ http_req_failed: ['rate == 0'],
+ http_req_duration: ['avg <= 1000'],
+ },
+};
+
+export default function() {
+ const nextBatchOfCmHandleIds = makeBatchOfCmHandleIds(BATCH_SIZE, exec.scenario.iterationInTest);
+ const payload = {
+ "dmiPlugin": DMI_PLUGIN_URL,
+ "createdCmHandles": nextBatchOfCmHandleIds.map(cmHandleId => ({
+ "cmHandle": cmHandleId,
+ "cmHandleProperties": { "neType": "RadioNode" },
+ "publicCmHandleProperties": {
+ "Color": "yellow",
+ "Size": "small",
+ "Shape": "cube"
+ }
+ })),
+ };
+ const response = http.post(NCMP_BASE_URL + '/ncmpInventory/v1/ch', JSON.stringify(payload), {
+ headers: { 'Content-Type': 'application/json' },
+ });
+ check(response, {
+ 'status equals 200': (r) => r.status === 200,
+ });
+}
diff --git a/k6-tests/ncmp/10-mixed-load-test.js b/k6-tests/ncmp/10-mixed-load-test.js
new file mode 100644
index 000000000..d13afa54a
--- /dev/null
+++ b/k6-tests/ncmp/10-mixed-load-test.js
@@ -0,0 +1,88 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2024 Nordix Foundation
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+import http from 'k6/http';
+import { check } from 'k6';
+import { NCMP_BASE_URL, getRandomCmHandleId } from './utils.js'
+import { searchRequest } from './search-base.js';
+
+export const options = {
+ scenarios: {
+ passthrough_read: {
+ executor: 'constant-vus',
+ exec: 'passthrough_read',
+ vus: 10,
+ duration: '1m',
+ },
+ id_search_module: {
+ executor: 'constant-vus',
+ exec: 'id_search_module',
+ vus: 5,
+ duration: '1m',
+ },
+ cm_search_module: {
+ executor: 'constant-vus',
+ exec: 'cm_search_module',
+ vus: 5,
+ duration: '1m',
+ },
+ },
+
+ thresholds: {
+ http_req_failed: ['rate==0'],
+ 'http_req_duration{scenario:passthrough_read}': ['avg <= 2540'], // DMI delay + 40 ms
+ 'http_req_duration{scenario:id_search_module}': ['avg <= 200'],
+ 'http_req_duration{scenario:cm_search_module}': ['avg <= 35_000'],
+ },
+};
+
+export function passthrough_read() {
+ const cmHandleId = getRandomCmHandleId();
+ const datastoreName = 'ncmp-datastore%3Apassthrough-operational';
+ const url = `${NCMP_BASE_URL}/ncmp/v1/ch/${cmHandleId}/data/ds/${datastoreName}?resourceIdentifier=x&include-descendants=true`
+ const response = http.get(url);
+ check(response, {
+ 'status equals 200': (r) => r.status === 200,
+ });
+}
+
+export function id_search_module() {
+ const search_filter = {
+ "cmHandleQueryParameters": [
+ {
+ "conditionName": "hasAllModules",
+ "conditionParameters": [ {"moduleName": "ietf-yang-types-1"} ]
+ }
+ ]
+ };
+ searchRequest('id-searches', JSON.stringify(search_filter));
+}
+
+export function cm_search_module() {
+ const search_filter = {
+ "cmHandleQueryParameters": [
+ {
+ "conditionName": "hasAllModules",
+ "conditionParameters": [ {"moduleName": "ietf-yang-types-1"} ]
+ }
+ ]
+ };
+ searchRequest('searches', JSON.stringify(search_filter));
+}
diff --git a/k6-tests/ncmp/11-delete-cmhandles.js b/k6-tests/ncmp/11-delete-cmhandles.js
new file mode 100644
index 000000000..daced8ddc
--- /dev/null
+++ b/k6-tests/ncmp/11-delete-cmhandles.js
@@ -0,0 +1,48 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2024 Nordix Foundation
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+import http from 'k6/http';
+import exec from 'k6/execution';
+import { check } from 'k6';
+import { NCMP_BASE_URL, TOTAL_CM_HANDLES, makeBatchOfCmHandleIds } from './utils.js';
+
+const BATCH_SIZE = 100;
+export const options = {
+ vus: 1,
+ iterations: Math.ceil(TOTAL_CM_HANDLES / BATCH_SIZE),
+ thresholds: {
+ http_req_failed: ['rate == 0'],
+ http_req_duration: ['avg <= 1000'],
+ },
+};
+
+export default function() {
+ const nextBatchOfCmHandleIds = makeBatchOfCmHandleIds(BATCH_SIZE, exec.scenario.iterationInTest);
+ const payload = {
+ "dmiPlugin": "http://ncmp-dmi-plugin-demo-and-csit-stub:8092",
+ "removedCmHandles": nextBatchOfCmHandleIds,
+ };
+ const response = http.post(NCMP_BASE_URL + '/ncmpInventory/v1/ch', JSON.stringify(payload), {
+ headers: { 'Content-Type': 'application/json' },
+ });
+ check(response, {
+ 'status equals 200': (r) => r.status === 200,
+ });
+}
diff --git a/k6-tests/ncmp/2-wait-for-cmhandles-to-be-ready.js b/k6-tests/ncmp/2-wait-for-cmhandles-to-be-ready.js
new file mode 100644
index 000000000..04a5c21dd
--- /dev/null
+++ b/k6-tests/ncmp/2-wait-for-cmhandles-to-be-ready.js
@@ -0,0 +1,64 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2024 Nordix Foundation
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+import http from 'k6/http';
+import { sleep, fail } from 'k6';
+import { NCMP_BASE_URL, TOTAL_CM_HANDLES } from './utils.js';
+
+export const options = {
+ vus: 1,
+ iterations: 1,
+ thresholds: {
+ http_req_failed: ['rate == 0'],
+ iteration_duration: ['max <= 300_000'], // 5 minutes
+ },
+};
+
+export default function() {
+ waitForCmHandlesToBeReady(TOTAL_CM_HANDLES);
+}
+
+function waitForCmHandlesToBeReady(totalCmHandles) {
+ const timeOutInSeconds = 6 * 60;
+ const pollingIntervalInSeconds = 10;
+ const maxRetries = Math.ceil(timeOutInSeconds / pollingIntervalInSeconds);
+ let cmHandlesReady = 0;
+ for (let currentTry = 0; currentTry <= maxRetries; currentTry++) {
+ sleep(pollingIntervalInSeconds);
+ try {
+ cmHandlesReady = getNumberOfReadyCmHandles();
+ } catch (error) {
+ console.error(`Attempt ${currentTry + 1} - Error fetching CM handles: ${error.message}`);
+ }
+ console.log(`Attempt ${currentTry + 1} - ${cmHandlesReady}/${totalCmHandles} CM handles are READY`);
+ if (cmHandlesReady === totalCmHandles) {
+ console.log(`All ${totalCmHandles} CM handles are READY`);
+ return;
+ }
+ }
+ fail(`Timed out after ${timeoutInSeconds} seconds waiting for ${totalCmHandles} CM handles to be READY`);
+}
+
+function getNumberOfReadyCmHandles() {
+ const endpointUrl = `${NCMP_BASE_URL}/cps/api/v2/dataspaces/NCMP-Admin/anchors/ncmp-dmi-registry/node?xpath=/dmi-registry&descendants=all`;
+ const jsonData = http.get(endpointUrl).json();
+ const cmHandles = jsonData[0]["dmi-reg:dmi-registry"]["cm-handles"];
+ return cmHandles.filter(cmhandle => cmhandle['state']['cm-handle-state'] === 'READY').length;
+}
diff --git a/k6-tests/ncmp/3-passthrough-read.js b/k6-tests/ncmp/3-passthrough-read.js
new file mode 100644
index 000000000..912cee599
--- /dev/null
+++ b/k6-tests/ncmp/3-passthrough-read.js
@@ -0,0 +1,51 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2024 Nordix Foundation
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+import http from 'k6/http';
+import { check } from 'k6';
+import { Trend } from "k6/metrics";
+import { NCMP_BASE_URL, getRandomCmHandleId } from './utils.js'
+
+let ncmpOverheadTrend = new Trend("ncmp_overhead");
+
+export const options = {
+ vus: 12,
+ duration: '30s',
+ thresholds: {
+ http_req_failed: ['rate == 0'],
+ ncmp_overhead: ['avg <= 40'],
+ },
+};
+
+// The function that defines VU logic.
+export default function() {
+ const cmHandleId = getRandomCmHandleId();
+ const datastoreName = 'ncmp-datastore%3Apassthrough-operational';
+ const url = `${NCMP_BASE_URL}/ncmp/v1/ch/${cmHandleId}/data/ds/${datastoreName}?resourceIdentifier=x&include-descendants=true`
+ const response = http.get(url);
+ check(response, {
+ 'status equals 200': (r) => r.status === 200,
+ });
+
+ // Calculate overhead assuming DMI data delay is 2500ms.
+ const dmiDelay = 2500; // This should be same as value DATA_FOR_CM_HANDLE_DELAY_MS in docker-compose.yml
+ const overhead = response.timings.duration - dmiDelay;
+ ncmpOverheadTrend.add(overhead);
+}
diff --git a/k6-tests/ncmp/4-id-search-no-filter.js b/k6-tests/ncmp/4-id-search-no-filter.js
new file mode 100644
index 000000000..774c60942
--- /dev/null
+++ b/k6-tests/ncmp/4-id-search-no-filter.js
@@ -0,0 +1,35 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2024 Nordix Foundation
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+import { searchRequest } from './search-base.js';
+
+export const options = {
+ vus: 5,
+ duration: '60s',
+ thresholds: {
+ http_req_failed: ['rate == 0'],
+ http_req_duration: ['avg <= 800'],
+ },
+};
+
+// The function that defines VU logic.
+export default function() {
+ searchRequest('id-searches', '{}')
+}
diff --git a/k6-tests/ncmp/5-search-no-filter.js b/k6-tests/ncmp/5-search-no-filter.js
new file mode 100644
index 000000000..fa08d0c40
--- /dev/null
+++ b/k6-tests/ncmp/5-search-no-filter.js
@@ -0,0 +1,34 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2024 Nordix Foundation
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+import { searchRequest } from './search-base.js';
+
+export const options = {
+ vus: 5,
+ duration: '60s',
+ thresholds: {
+ http_req_failed: ['rate == 0'],
+ http_req_duration: ['avg <= 35_000'],
+ },
+};
+
+export default function() {
+ searchRequest('searches', '{}')
+}
diff --git a/k6-tests/ncmp/6-id-search-public-property.js b/k6-tests/ncmp/6-id-search-public-property.js
new file mode 100644
index 000000000..e8b584aec
--- /dev/null
+++ b/k6-tests/ncmp/6-id-search-public-property.js
@@ -0,0 +1,42 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2024 Nordix Foundation
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+import { searchRequest } from './search-base.js';
+
+export const options = {
+ vus: 5,
+ duration: '30s',
+ thresholds: {
+ http_req_failed: ['rate == 0'],
+ http_req_duration: ['avg <= 5000'],
+ },
+};
+
+export default function() {
+ const search_filter = {
+ "cmHandleQueryParameters": [
+ {
+ "conditionName": "hasAllProperties",
+ "conditionParameters": [ {"Color": "yellow"}, {"Size": "small"} ]
+ }
+ ]
+ };
+ searchRequest('id-searches', JSON.stringify(search_filter));
+}
diff --git a/k6-tests/ncmp/7-search-public-property.js b/k6-tests/ncmp/7-search-public-property.js
new file mode 100644
index 000000000..3e052dabe
--- /dev/null
+++ b/k6-tests/ncmp/7-search-public-property.js
@@ -0,0 +1,42 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2024 Nordix Foundation
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+import { searchRequest } from './search-base.js';
+
+export const options = {
+ vus: 5,
+ duration: '30s',
+ thresholds: {
+ http_req_failed: ['rate == 0'],
+ http_req_duration: ['avg <= 35_000'],
+ },
+};
+
+export default function() {
+ const search_filter = {
+ "cmHandleQueryParameters": [
+ {
+ "conditionName": "hasAllProperties",
+ "conditionParameters": [ {"Color": "yellow"}, {"Size": "small"} ]
+ }
+ ]
+ };
+ searchRequest('searches', JSON.stringify(search_filter));
+}
diff --git a/k6-tests/ncmp/8-id-search-module.js b/k6-tests/ncmp/8-id-search-module.js
new file mode 100644
index 000000000..e99fbfeb2
--- /dev/null
+++ b/k6-tests/ncmp/8-id-search-module.js
@@ -0,0 +1,42 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2024 Nordix Foundation
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+import { searchRequest } from './search-base.js';
+
+export const options = {
+ vus: 5,
+ duration: '30s',
+ thresholds: {
+ http_req_failed: ['rate == 0'],
+ http_req_duration: ['avg <= 200'],
+ },
+};
+
+export default function() {
+ const search_filter = {
+ "cmHandleQueryParameters": [
+ {
+ "conditionName": "hasAllModules",
+ "conditionParameters": [ {"moduleName": "ietf-yang-types-1"} ]
+ }
+ ]
+ };
+ searchRequest('id-searches', JSON.stringify(search_filter));
+}
diff --git a/k6-tests/ncmp/9-search-module.js b/k6-tests/ncmp/9-search-module.js
new file mode 100644
index 000000000..03eb9a67a
--- /dev/null
+++ b/k6-tests/ncmp/9-search-module.js
@@ -0,0 +1,42 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2024 Nordix Foundation
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+import { searchRequest } from './search-base.js';
+
+export const options = {
+ vus: 5,
+ duration: '60s',
+ thresholds: {
+ http_req_failed: ['rate == 0'],
+ http_req_duration: ['avg <= 35_000'],
+ },
+};
+
+export default function() {
+ const search_filter = {
+ "cmHandleQueryParameters": [
+ {
+ "conditionName": "hasAllModules",
+ "conditionParameters": [ {"moduleName": "ietf-yang-types-1"} ]
+ }
+ ]
+ };
+ searchRequest('searches', JSON.stringify(search_filter));
+}
diff --git a/k6-tests/ncmp/run-all-tests.sh b/k6-tests/ncmp/run-all-tests.sh
new file mode 100755
index 000000000..f75cf2f70
--- /dev/null
+++ b/k6-tests/ncmp/run-all-tests.sh
@@ -0,0 +1,44 @@
+#!/bin/bash
+#
+# Copyright 2024 Nordix Foundation.
+#
+# 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.
+#
+
+ALL_TEST_SCRIPTS=( \
+1-create-cmhandles.js \
+2-wait-for-cmhandles-to-be-ready.js \
+3-passthrough-read.js \
+4-id-search-no-filter.js \
+5-search-no-filter.js \
+6-id-search-public-property.js \
+7-search-public-property.js \
+8-id-search-module.js \
+9-search-module.js \
+10-mixed-load-test.js \
+11-delete-cmhandles.js \
+)
+
+pushd "$(dirname "$0")" || exit 1
+
+number_of_failures=0
+for test_script in "${ALL_TEST_SCRIPTS[@]}"; do
+ echo "k6 run $test_script"
+ k6 --quiet run "$test_script" || ((number_of_failures++))
+ echo
+done
+
+popd || exit 1
+
+echo "NCMP TEST FAILURES: $number_of_failures"
+exit $number_of_failures
diff --git a/k6-tests/ncmp/search-base.js b/k6-tests/ncmp/search-base.js
new file mode 100644
index 000000000..9c1b247a9
--- /dev/null
+++ b/k6-tests/ncmp/search-base.js
@@ -0,0 +1,35 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2024 Nordix Foundation
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+import http from 'k6/http';
+import { check } from 'k6';
+import { NCMP_BASE_URL, TOTAL_CM_HANDLES } from './utils.js';
+
+export function searchRequest(searchType, searchFilter) {
+ const response = http.post(NCMP_BASE_URL + '/ncmp/v1/ch/' + searchType, searchFilter, {
+ headers: { 'Content-Type': 'application/json' },
+ });
+ check(response, {
+ 'status equals 200': (r) => r.status === 200,
+ });
+ check(JSON.parse(response.body), {
+ 'returned list has expected CM-handles': (arr) => arr.length === TOTAL_CM_HANDLES,
+ });
+}
diff --git a/k6-tests/ncmp/utils.js b/k6-tests/ncmp/utils.js
new file mode 100644
index 000000000..3b61b217e
--- /dev/null
+++ b/k6-tests/ncmp/utils.js
@@ -0,0 +1,41 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2024 Nordix Foundation
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+export const NCMP_BASE_URL = 'http://localhost:8883';
+export const DMI_PLUGIN_URL = 'http://ncmp-dmi-plugin-demo-and-csit-stub:8092';
+export const TOTAL_CM_HANDLES = 20000
+
+/*
+ * Makes a batch of CM-handle IDs.
+ * Given a batchSize=100 and batchNumber=2, it will generate ['ch-201', 'ch-202' ... 'ch-300']
+ */
+export function makeBatchOfCmHandleIds(batchSize, batchNumber) {
+ const batchOfIds = [];
+ const startIndex = 1 + batchNumber * batchSize;
+ for (let i = 0; i < batchSize; i++) {
+ let cmHandleId = 'ch-' + (startIndex + i);
+ batchOfIds.push(cmHandleId);
+ }
+ return batchOfIds;
+}
+
+export function getRandomCmHandleId() {
+ return 'ch-' + (Math.floor(Math.random() * TOTAL_CM_HANDLES) + 1);
+}
diff --git a/k6-tests/run-k6-tests.sh b/k6-tests/run-k6-tests.sh
new file mode 100755
index 000000000..9b8747b1f
--- /dev/null
+++ b/k6-tests/run-k6-tests.sh
@@ -0,0 +1,39 @@
+#!/bin/bash
+#
+# Copyright 2024 Nordix Foundation.
+#
+# 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.
+#
+
+set -o errexit # Exit on most errors
+set -o nounset # Disallow expansion of unset variables
+set -o pipefail # Use last non-zero exit code in a pipeline
+#set -o xtrace # Uncomment for debugging
+
+on_exit() {
+ rc=$?
+ ./teardown.sh
+ popd
+ echo "TEST FAILURES: $rc"
+ exit $rc
+}
+trap on_exit EXIT
+
+pushd "$(dirname "$0")" || exit 1
+
+./setup.sh
+./ncmp/run-all-tests.sh
+NCMP_RESULT=$?
+
+# Note that the final steps are done in on_exit function after this exit!
+exit $NCMP_RESULT
diff --git a/k6-tests/setup.sh b/k6-tests/setup.sh
new file mode 100755
index 000000000..4805e2ea4
--- /dev/null
+++ b/k6-tests/setup.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+#
+# Copyright 2024 Nordix Foundation.
+#
+# 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.
+#
+
+docker-compose -f ../docker-compose/docker-compose.yml --profile dmi-stub up -d
+
+echo "Waiting for CPS to start..."
+READY_MESSAGE='Processing module sync fetched 0 advised cm handles from DB'
+docker logs cps-and-ncmp -f | grep -m 1 "$READY_MESSAGE" >/dev/null || true
diff --git a/k6-tests/teardown.sh b/k6-tests/teardown.sh
new file mode 100755
index 000000000..87cca7252
--- /dev/null
+++ b/k6-tests/teardown.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+#
+# Copyright 2024 Nordix Foundation.
+#
+# 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.
+#
+
+echo '================================== docker info =========================='
+docker ps -a
+
+echo '================================== CPS-NCMP Logs ========================'
+docker logs cps-and-ncmp
+
+echo 'Stopping, Removing all running containers...'
+docker stop $(docker ps -aq) && docker rm $(docker ps -aq)
+
+echo 'Removing Volumes...'
+docker volume prune -f
+
+echo 'Removing Networks...'
+docker network prune -f