From 4ebeaf00d97a5b441e2cbf5732ced850b6d224cf Mon Sep 17 00:00:00 2001 From: Bartosz Prusinowski Date: Wed, 14 Feb 2024 08:50:42 +0100 Subject: [PATCH 1/4] chore: Add metadataByCubeIri to every GQL performance test --- .../graphql/DataCubeComponents.js | 8 ++ .../graphql/DataCubeMetadata.js | 8 ++ .../graphql/DataCubeObservations.js | 108 ++++++++++-------- .../graphql/DataCubePreview.js | 8 ++ .../graphql/PossibleFilters.js | 5 +- 5 files changed, 87 insertions(+), 50 deletions(-) diff --git a/k6/performance-tests/graphql/DataCubeComponents.js b/k6/performance-tests/graphql/DataCubeComponents.js index 63ce4cba0..815ce5e57 100644 --- a/k6/performance-tests/graphql/DataCubeComponents.js +++ b/k6/performance-tests/graphql/DataCubeComponents.js @@ -16,9 +16,17 @@ const query = `query DataCubeComponents( ) }`; +const metadataByCubeIri = { + "https://energy.ld.admin.ch/sfoe/bfe_ogd84_einmalverguetung_fuer_photovoltaikanlagen/9": + {}, + "https://environment.ld.admin.ch/foen/nfi/nfi_C-20/cube/2023-3": {}, + "https://energy.ld.admin.ch/elcom/electricityprice": {}, +}; + const env = __ENV.ENV; const cubeIri = __ENV.CUBE_IRI; const cubeLabel = __ENV.CUBE_LABEL; +const metadata = metadataByCubeIri[cubeIri]; const variables = { locale: "en", diff --git a/k6/performance-tests/graphql/DataCubeMetadata.js b/k6/performance-tests/graphql/DataCubeMetadata.js index 5c10525b2..3f04594d8 100644 --- a/k6/performance-tests/graphql/DataCubeMetadata.js +++ b/k6/performance-tests/graphql/DataCubeMetadata.js @@ -16,9 +16,17 @@ const query = `query DataCubeMetadata( ) }`; +const metadataByCubeIri = { + "https://energy.ld.admin.ch/sfoe/bfe_ogd84_einmalverguetung_fuer_photovoltaikanlagen/9": + {}, + "https://environment.ld.admin.ch/foen/nfi/nfi_C-20/cube/2023-3": {}, + "https://energy.ld.admin.ch/elcom/electricityprice": {}, +}; + const env = __ENV.ENV; const cubeIri = __ENV.CUBE_IRI; const cubeLabel = __ENV.CUBE_LABEL; +const metadata = metadataByCubeIri[cubeIri]; const variables = { locale: "en", diff --git a/k6/performance-tests/graphql/DataCubeObservations.js b/k6/performance-tests/graphql/DataCubeObservations.js index a22548a2f..5c6ac109d 100644 --- a/k6/performance-tests/graphql/DataCubeObservations.js +++ b/k6/performance-tests/graphql/DataCubeObservations.js @@ -16,64 +16,75 @@ const query = `query DataCubeObservations( ) }`; -const cubeFilterByCubeIri = { +const metadataByCubeIri = { "https://energy.ld.admin.ch/sfoe/bfe_ogd84_einmalverguetung_fuer_photovoltaikanlagen/9": { - iri: "https://energy.ld.admin.ch/sfoe/bfe_ogd84_einmalverguetung_fuer_photovoltaikanlagen/9", - filters: { - "https://energy.ld.admin.ch/sfoe/bfe_ogd84_einmalverguetung_fuer_photovoltaikanlagen/Kanton": - { - type: "single", - value: "https://ld.admin.ch/canton/1", - }, + cubeFilter: { + iri: "https://energy.ld.admin.ch/sfoe/bfe_ogd84_einmalverguetung_fuer_photovoltaikanlagen/9", + filters: { + "https://energy.ld.admin.ch/sfoe/bfe_ogd84_einmalverguetung_fuer_photovoltaikanlagen/Kanton": + { + type: "single", + value: "https://ld.admin.ch/canton/1", + }, + }, }, }, "https://environment.ld.admin.ch/foen/nfi/nfi_C-20/cube/2023-3": { - iri: "https://environment.ld.admin.ch/foen/nfi/nfi_C-20/cube/2023-3", - filters: { - "https://environment.ld.admin.ch/foen/nfi/unitOfReference": { - type: "single", - value: "https://ld.admin.ch/country/CHE", - }, - "https://environment.ld.admin.ch/foen/nfi/classificationUnit": { - type: "single", - value: - "https://environment.ld.admin.ch/foen/nfi/ClassificationUnit/Total", - }, - "https://environment.ld.admin.ch/foen/nfi/inventory": { - type: "single", - value: "https://environment.ld.admin.ch/foen/nfi/Inventory/150", - }, - "https://environment.ld.admin.ch/foen/nfi/unitOfEvaluation": { - type: "single", - value: "https://environment.ld.admin.ch/foen/nfi/UnitOfEvaluation/2382", - }, - "https://environment.ld.admin.ch/foen/nfi/evaluationType": { - type: "single", - value: "https://environment.ld.admin.ch/foen/nfi/EvaluationType/1", + cubeFilter: { + iri: "https://environment.ld.admin.ch/foen/nfi/nfi_C-20/cube/2023-3", + filters: { + "https://environment.ld.admin.ch/foen/nfi/unitOfReference": { + type: "single", + value: "https://ld.admin.ch/country/CHE", + }, + "https://environment.ld.admin.ch/foen/nfi/classificationUnit": { + type: "single", + value: + "https://environment.ld.admin.ch/foen/nfi/ClassificationUnit/Total", + }, + "https://environment.ld.admin.ch/foen/nfi/inventory": { + type: "single", + value: "https://environment.ld.admin.ch/foen/nfi/Inventory/150", + }, + "https://environment.ld.admin.ch/foen/nfi/unitOfEvaluation": { + type: "single", + value: + "https://environment.ld.admin.ch/foen/nfi/UnitOfEvaluation/2382", + }, + "https://environment.ld.admin.ch/foen/nfi/evaluationType": { + type: "single", + value: "https://environment.ld.admin.ch/foen/nfi/EvaluationType/1", + }, }, }, }, "https://energy.ld.admin.ch/elcom/electricityprice": { - iri: "https://energy.ld.admin.ch/elcom/electricityprice", - filters: { - "https://energy.ld.admin.ch/elcom/electricityprice/dimension/municipality": - { + cubeFilter: { + iri: "https://energy.ld.admin.ch/elcom/electricityprice", + filters: { + "https://energy.ld.admin.ch/elcom/electricityprice/dimension/municipality": + { + type: "single", + value: "https://ld.admin.ch/municipality/1", + }, + "https://energy.ld.admin.ch/elcom/electricityprice/dimension/category": + { + type: "single", + value: + "https://energy.ld.admin.ch/elcom/electricityprice/category/C1", + }, + "https://energy.ld.admin.ch/elcom/electricityprice/dimension/operator": + { + type: "single", + value: + "https://energy.ld.admin.ch/elcom/electricityprice/operator/486", + }, + "https://energy.ld.admin.ch/elcom/electricityprice/dimension/product": { type: "single", - value: "https://ld.admin.ch/municipality/1", + value: + "https://energy.ld.admin.ch/elcom/electricityprice/product/standard", }, - "https://energy.ld.admin.ch/elcom/electricityprice/dimension/category": { - type: "single", - value: "https://energy.ld.admin.ch/elcom/electricityprice/category/C1", - }, - "https://energy.ld.admin.ch/elcom/electricityprice/dimension/operator": { - type: "single", - value: "https://energy.ld.admin.ch/elcom/electricityprice/operator/486", - }, - "https://energy.ld.admin.ch/elcom/electricityprice/dimension/product": { - type: "single", - value: - "https://energy.ld.admin.ch/elcom/electricityprice/product/standard", }, }, }, @@ -82,12 +93,13 @@ const cubeFilterByCubeIri = { const env = __ENV.ENV; const cubeIri = __ENV.CUBE_IRI; const cubeLabel = __ENV.CUBE_LABEL; +const metadata = metadataByCubeIri[cubeIri]; const variables = { locale: "en", sourceType: "sparql", sourceUrl: "https://lindas.admin.ch/query", - cubeFilter: cubeFilterByCubeIri[cubeIri], + cubeFilter: metadata.cubeFilter, }; /** @type {import("k6/options").Options} */ diff --git a/k6/performance-tests/graphql/DataCubePreview.js b/k6/performance-tests/graphql/DataCubePreview.js index cf347c193..55b402558 100644 --- a/k6/performance-tests/graphql/DataCubePreview.js +++ b/k6/performance-tests/graphql/DataCubePreview.js @@ -16,9 +16,17 @@ const query = `query DataCubePreview( ) }`; +const metadataByCubeIri = { + "https://energy.ld.admin.ch/sfoe/bfe_ogd84_einmalverguetung_fuer_photovoltaikanlagen/9": + {}, + "https://environment.ld.admin.ch/foen/nfi/nfi_C-20/cube/2023-3": {}, + "https://energy.ld.admin.ch/elcom/electricityprice": {}, +}; + const env = __ENV.ENV; const cubeIri = __ENV.CUBE_IRI; const cubeLabel = __ENV.CUBE_LABEL; +const metadata = metadataByCubeIri[cubeIri]; const variables = { locale: "en", diff --git a/k6/performance-tests/graphql/PossibleFilters.js b/k6/performance-tests/graphql/PossibleFilters.js index c60797d6f..ac27dd939 100644 --- a/k6/performance-tests/graphql/PossibleFilters.js +++ b/k6/performance-tests/graphql/PossibleFilters.js @@ -20,7 +20,7 @@ const query = `query PossibleFilters( } }`; -const cubeFilterByCubeIri = { +const metadataByCubeIri = { "https://energy.ld.admin.ch/sfoe/bfe_ogd84_einmalverguetung_fuer_photovoltaikanlagen/9": { iri: "https://energy.ld.admin.ch/sfoe/bfe_ogd84_einmalverguetung_fuer_photovoltaikanlagen/9", @@ -86,13 +86,14 @@ const cubeFilterByCubeIri = { const env = __ENV.ENV; const cubeIri = __ENV.CUBE_IRI; const cubeLabel = __ENV.CUBE_LABEL; +const metadata = metadataByCubeIri[cubeIri]; const variables = { iri: cubeIri, locale: "en", sourceType: "sparql", sourceUrl: "https://lindas.admin.ch/query", - filters: cubeFilterByCubeIri[cubeIri], + filters: metadata.filters, }; /** @type {import("k6/options").Options} */ From a54d2766520e6e231ccd9885f9d5b768776ac81c Mon Sep 17 00:00:00 2001 From: Bartosz Prusinowski Date: Wed, 14 Feb 2024 09:17:45 +0100 Subject: [PATCH 2/4] chore: Increase number of performance test iterations to two ...and subsequently change the Grafana charts measure to k6_http_req_duration_avg. This should reduce number of false-positives of going over the threshold. --- k6/performance-tests/graphql/DataCubeComponents.js | 2 +- k6/performance-tests/graphql/DataCubeMetadata.js | 2 +- k6/performance-tests/graphql/DataCubeObservations.js | 2 +- k6/performance-tests/graphql/DataCubePreview.js | 2 +- k6/performance-tests/graphql/PossibleFilters.js | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/k6/performance-tests/graphql/DataCubeComponents.js b/k6/performance-tests/graphql/DataCubeComponents.js index 815ce5e57..1cc84609b 100644 --- a/k6/performance-tests/graphql/DataCubeComponents.js +++ b/k6/performance-tests/graphql/DataCubeComponents.js @@ -39,7 +39,7 @@ const variables = { /** @type {import("k6/options").Options} */ export const options = { - iterations: 1, + iterations: 2, }; const headers = { diff --git a/k6/performance-tests/graphql/DataCubeMetadata.js b/k6/performance-tests/graphql/DataCubeMetadata.js index 3f04594d8..a9b4a9bc5 100644 --- a/k6/performance-tests/graphql/DataCubeMetadata.js +++ b/k6/performance-tests/graphql/DataCubeMetadata.js @@ -39,7 +39,7 @@ const variables = { /** @type {import("k6/options").Options} */ export const options = { - iterations: 1, + iterations: 2, }; const headers = { diff --git a/k6/performance-tests/graphql/DataCubeObservations.js b/k6/performance-tests/graphql/DataCubeObservations.js index 5c6ac109d..f70c28d90 100644 --- a/k6/performance-tests/graphql/DataCubeObservations.js +++ b/k6/performance-tests/graphql/DataCubeObservations.js @@ -104,7 +104,7 @@ const variables = { /** @type {import("k6/options").Options} */ export const options = { - iterations: 1, + iterations: 2, }; const headers = { diff --git a/k6/performance-tests/graphql/DataCubePreview.js b/k6/performance-tests/graphql/DataCubePreview.js index 55b402558..64106c824 100644 --- a/k6/performance-tests/graphql/DataCubePreview.js +++ b/k6/performance-tests/graphql/DataCubePreview.js @@ -40,7 +40,7 @@ const variables = { /** @type {import("k6/options").Options} */ export const options = { - iterations: 1, + iterations: 2, }; const headers = { diff --git a/k6/performance-tests/graphql/PossibleFilters.js b/k6/performance-tests/graphql/PossibleFilters.js index ac27dd939..216764228 100644 --- a/k6/performance-tests/graphql/PossibleFilters.js +++ b/k6/performance-tests/graphql/PossibleFilters.js @@ -98,7 +98,7 @@ const variables = { /** @type {import("k6/options").Options} */ export const options = { - iterations: 1, + iterations: 2, }; const headers = { From 3ee8bc55b0daddcc2aa22a741e3894a8a4bb1fbf Mon Sep 17 00:00:00 2001 From: Bartosz Prusinowski Date: Wed, 14 Feb 2024 11:44:47 +0100 Subject: [PATCH 3/4] chore: Send avg metric to Prometheus --- .github/workflows/performance-tests.yml | 1 + k6/performance-tests/generate-github-action.js | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/performance-tests.yml b/.github/workflows/performance-tests.yml index 0c2d60a3a..2c4652a54 100644 --- a/.github/workflows/performance-tests.yml +++ b/.github/workflows/performance-tests.yml @@ -21,6 +21,7 @@ jobs: -e K6_PROMETHEUS_RW_USERNAME=${{ secrets.K6_PROMETHEUS_RW_USERNAME }} -e K6_PROMETHEUS_RW_PASSWORD=${{ secrets.K6_PROMETHEUS_RW_PASSWORD }} -e K6_PROMETHEUS_RW_SERVER_URL=${{ secrets.K6_PROMETHEUS_RW_SERVER_URL }} + -e K6_PROMETHEUS_RW_TREND_STATS=avg run: | k6 run -o experimental-prometheus-rw --tag testid=DataCubeComponents --env ENV=test --env CUBE_IRI=https://energy.ld.admin.ch/sfoe/bfe_ogd84_einmalverguetung_fuer_photovoltaikanlagen/9 --env CUBE_LABEL=Photovoltaikanlagen/9 - Date: Wed, 14 Feb 2024 16:09:20 +0100 Subject: [PATCH 4/4] chore: Add data correctness checks --- .../graphql/DataCubeComponents.js | 16 +++++++++++++--- .../graphql/DataCubeMetadata.js | 13 ++++++++++--- .../graphql/DataCubeObservations.js | 15 ++++++++++++--- .../graphql/DataCubePreview.js | 18 +++++++++++++++--- .../graphql/PossibleFilters.js | 13 ++++++++++--- 5 files changed, 60 insertions(+), 15 deletions(-) diff --git a/k6/performance-tests/graphql/DataCubeComponents.js b/k6/performance-tests/graphql/DataCubeComponents.js index 1cc84609b..812773524 100644 --- a/k6/performance-tests/graphql/DataCubeComponents.js +++ b/k6/performance-tests/graphql/DataCubeComponents.js @@ -57,7 +57,17 @@ export default function Components() { { headers } ); - if (!check(res, { "Status code must be 200": (res) => res.status == 200 })) { - fail("Status code was *not* 200!"); - } + check(res, { + "Response must have data": (res) => { + const body = res.json(); + return ( + body.data && + body.data.dataCubeComponents && + body.data.dataCubeComponents.dimensions && + body.data.dataCubeComponents.dimensions.length > 0 && + body.data.dataCubeComponents.measures && + body.data.dataCubeComponents.measures.length > 0 + ); + }, + }); } diff --git a/k6/performance-tests/graphql/DataCubeMetadata.js b/k6/performance-tests/graphql/DataCubeMetadata.js index a9b4a9bc5..0c92d5742 100644 --- a/k6/performance-tests/graphql/DataCubeMetadata.js +++ b/k6/performance-tests/graphql/DataCubeMetadata.js @@ -57,7 +57,14 @@ export default function Components() { { headers } ); - if (!check(res, { "Status code must be 200": (res) => res.status == 200 })) { - fail("Status code was *not* 200!"); - } + check(res, { + "Response must have data": (res) => { + const body = res.json(); + return ( + body.data && + body.data.dataCubeMetadata && + body.data.dataCubeMetadata.iri === cubeIri + ); + }, + }); } diff --git a/k6/performance-tests/graphql/DataCubeObservations.js b/k6/performance-tests/graphql/DataCubeObservations.js index f70c28d90..968b2c657 100644 --- a/k6/performance-tests/graphql/DataCubeObservations.js +++ b/k6/performance-tests/graphql/DataCubeObservations.js @@ -122,7 +122,16 @@ export default function Observations() { { headers } ); - if (!check(res, { "Status code must be 200": (res) => res.status == 200 })) { - fail("Status code was *not* 200!"); - } + check(res, { + "Response must have data": (res) => { + const body = res.json(); + return ( + body.data && + body.data.dataCubeObservations && + body.data.dataCubeObservations && + body.data.dataCubeObservations.data.length > 0 && + body.data.dataCubeObservations.sparqlEditorUrl + ); + }, + }); } diff --git a/k6/performance-tests/graphql/DataCubePreview.js b/k6/performance-tests/graphql/DataCubePreview.js index 64106c824..8cbbc8d79 100644 --- a/k6/performance-tests/graphql/DataCubePreview.js +++ b/k6/performance-tests/graphql/DataCubePreview.js @@ -58,7 +58,19 @@ export default function Components() { { headers } ); - if (!check(res, { "Status code must be 200": (res) => res.status == 200 })) { - fail("Status code was *not* 200!"); - } + check(res, { + "Response must have data": (res) => { + const body = res.json(); + return ( + body.data && + body.data.dataCubePreview && + body.data.dataCubePreview.dimensions && + body.data.dataCubePreview.dimensions.length > 0 && + body.data.dataCubePreview.measures && + body.data.dataCubePreview.measures.length > 0 && + body.data.dataCubePreview.observations && + body.data.dataCubePreview.observations.length > 0 + ); + }, + }); } diff --git a/k6/performance-tests/graphql/PossibleFilters.js b/k6/performance-tests/graphql/PossibleFilters.js index 216764228..eb7b7f61a 100644 --- a/k6/performance-tests/graphql/PossibleFilters.js +++ b/k6/performance-tests/graphql/PossibleFilters.js @@ -116,7 +116,14 @@ export default function Observations() { { headers } ); - if (!check(res, { "Status code must be 200": (res) => res.status == 200 })) { - fail("Status code was *not* 200!"); - } + check(res, { + "Response must have data": (res) => { + const body = res.json(); + return ( + body.data && + body.data.possibleFilters && + body.data.possibleFilters.length > 0 + ); + }, + }); }