Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test(load): add k6 load test workflow with example test #1186

Merged
merged 1 commit into from
Jun 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ module.exports = {
'@vue-storefront/eslint-config-vue',
'@vue-storefront/eslint-config-jest',
],
globals: {
"__ENV": "readonly",
},
rules: {
"@typescript-eslint/no-floating-promises": "off",
"jest/expect-expect": [
Expand Down
52 changes: 52 additions & 0 deletions .github/workflows/run-k6-load-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: Run K6 test file
on:
workflow_dispatch:
inputs:
cloud:
description: True = run in K6 cloud; False = run on the test on GitHub Actions agent
required: true
default: false
type: boolean

filename:
description: The K6 test file to run relative to repository root
required: true
default: packages/theme/tests/load/searchProduct.js
type: string

environment:
description: The full URL of the environment on which load tests will be ran
required: true
default: https://demo-magento2-canary.europe-west1.gcp.storefrontcloud.io
type: choice
options:
- https://demo-magento2-canary.europe-west1.gcp.storefrontcloud.io
- https://demo-magento2-dev.europe-west1.gcp.storefrontcloud.io
- https://demo-magento2.europe-west1.gcp.storefrontcloud.cloud
- https://demo-magento2-enterprise.europe-west1.gcp.storefrontcloud.io

flags:
description: Additional argument and flags to provide to the k6 CLI. See https://k6.io/docs/using-k6/options for details.
required: false
default: ''
type: string

jobs:
build:
name: Run k6 cloud test
runs-on: ubuntu-latest
environment: test

steps:
- name: Checkout
uses: actions/checkout@v3

- name: Run k6 cloud test
uses: grafana/k6-action@v0.2.0
with:
cloud: ${{ inputs.cloud }}
token: ${{ secrets.K6_CLOUD_API_TOKEN }}
filename: ${{ inputs.filename }}
flags: ${{ inputs.flags }}
env:
BASE_URL: ${{ inputs.environment }}
6 changes: 3 additions & 3 deletions packages/api-client/src/api/customMutation/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import gql from 'graphql-tag';
import { FetchPolicy, FetchResult } from '@apollo/client/core';
import { DocumentNode } from 'graphql';
import { Context } from '../../types/context';
import getHeaders from '../getHeaders';

Expand All @@ -10,12 +10,12 @@ export default async <MUTATION = any, MUTATION_VARIABLES = any>(
mutationVariables,
fetchPolicy,
}: {
mutation: DocumentNode,
mutation: string,
mutationVariables: MUTATION_VARIABLES,
fetchPolicy?: Extract<FetchPolicy, 'network-only' | 'no-cache'>,
},
): Promise<FetchResult<MUTATION>> => context.client.mutate<MUTATION, MUTATION_VARIABLES>({
mutation,
mutation: gql`${mutation}`,
variables: { ...mutationVariables },
fetchPolicy: fetchPolicy || 'no-cache',
context: {
Expand Down
6 changes: 3 additions & 3 deletions packages/api-client/src/api/customQuery/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import gql from 'graphql-tag';
import { ApolloQueryResult, FetchPolicy } from '@apollo/client/core';
import { DocumentNode } from 'graphql';
import { Context } from '../../types/context';
import getHeaders from '../getHeaders';

Expand All @@ -10,12 +10,12 @@ export default async <QUERY = any, QUERY_VARIABLES = any>(
queryVariables,
fetchPolicy,
}: {
query: DocumentNode,
query: string,
queryVariables?: QUERY_VARIABLES,
fetchPolicy?: FetchPolicy,
},
): Promise<ApolloQueryResult<QUERY>> => context.client.query<QUERY, QUERY_VARIABLES>({
query,
query: gql`${query}`,
variables: { ...queryVariables },
fetchPolicy: fetchPolicy || 'no-cache',
context: {
Expand Down
6 changes: 3 additions & 3 deletions packages/api-client/src/types/API.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ApolloQueryResult, FetchPolicy, FetchResult } from '@apollo/client/core';
import { DocumentNode, ExecutionResult } from 'graphql';
import { ExecutionResult } from 'graphql';
import { CustomQuery } from '@vue-storefront/core';
import {
AddConfigurableProductsToCartInput,
Expand Down Expand Up @@ -279,13 +279,13 @@ export interface MagentoApiMethods {
): Promise<ApolloQueryResult<CustomerOrdersQuery>>;

customQuery<QUERY, QUERY_VARIABLES = any>(params: {
query: DocumentNode,
query: string,
queryVariables?: QUERY_VARIABLES,
fetchPolicy?: FetchPolicy,
}): Promise<ApolloQueryResult<QUERY>>;

customMutation<MUTATION, MUTATION_VARIABLES = any>(params: {
mutation: DocumentNode,
mutation: string,
mutationVariables: MUTATION_VARIABLES,
fetchPolicy?: Extract<FetchPolicy, 'network-only' | 'no-cache'>,
}): Promise<FetchResult<MUTATION>>;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import gql from 'graphql-tag';

export default gql`
export default `
query getStoresAndCurrencies {
availableStores {
store_code
Expand Down
11 changes: 3 additions & 8 deletions packages/theme/composables/useApi/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { useContext } from '@nuxtjs/composition-api';
import type { DocumentNode } from 'graphql';
import { Logger } from '~/helpers/logger';

export type FetchPolicy = 'cache-first' | 'network-only' | 'cache-only' | 'no-cache' | 'standby';
Expand All @@ -19,7 +18,7 @@ export type Error = {
};

export type Request = <DATA, VARIABLES extends Variables = Variables>(
request: DocumentNode,
request: string,
variables?: VARIABLES,
fetchPolicy?: FetchPolicy,
) => Promise<{ data: DATA, errors: Error[] }>;
Expand Down Expand Up @@ -75,10 +74,6 @@ export interface UseApiInterface {
mutate: Request;
}

function getGqlString(doc: DocumentNode) {
return doc.loc && doc.loc.source.body;
}

/**
* Allows executing arbitrary GraphQL queries and mutations.
*
Expand All @@ -93,7 +88,7 @@ export function useApi(): UseApiInterface {
variables,
) => {
const reqID = `id${Math.random().toString(16).slice(2)}`;
Logger.debug(`customQuery/request/${reqID}`, getGqlString(request));
Logger.debug(`customQuery/request/${reqID}`, request);
const { data, errors } = await context.app.$vsf.$magento.api.customQuery({ query: request, queryVariables: variables });
Logger.debug(`customQuery/result/${reqID}`, { data, errors });

Expand All @@ -106,7 +101,7 @@ export function useApi(): UseApiInterface {
variables,
) => {
const reqID = `id${Math.random().toString(16).slice(2)}`;
Logger.debug(`customQuery/request/${reqID}`, getGqlString(request));
Logger.debug(`customQuery/request/${reqID}`, request);
const { data, errors } = await context.app.$vsf.$magento.api.customMutation({ mutation: request, mutationVariables: variables });
Logger.debug(`customQuery/result/${reqID}`, { data, errors });

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import gql from 'graphql-tag';

export default gql`
export default `
query getCategoryContentData($filters: CategoryFilterInput) {
categoryList(filters: $filters) {
uid
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import gql from 'graphql-tag';

export default gql`
export default `
query getProductFiltersByCategory($categoryIdFilter: FilterEqualTypeInput!) {
products(filter: { category_uid: $categoryIdFilter }) {
aggregations {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import gql from 'graphql-tag';

/**
* GraphQL Query that fetches products using received search term and the params
* for filter, sort and pagination.
*/
export default gql`
export default `
query getFacetData($search: String = "", $filter: ProductAttributeFilterInput, $pageSize: Int = 10, $currentPage: Int = 1, $sort: ProductAttributeSortInput) {
products(search: $search, filter: $filter, pageSize: $pageSize, currentPage: $currentPage, sort: $sort) {
items {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import gql from 'graphql-tag';

const fragmentCategory = gql`
const fragmentCategory = `
fragment CategoryFields on CategoryTree {
is_anchor
name
Expand All @@ -13,7 +11,7 @@ const fragmentCategory = gql`
}
`;

export default gql`
export default `
query categoryList {
categories {
items {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import gql from 'graphql-tag';

export default gql`
export default `
query productsList($search: String = "", $filter: ProductAttributeFilterInput, $pageSize: Int = 20, $currentPage: Int = 1, $sort: ProductAttributeSortInput) {
products(search: $search, filter: $filter, pageSize: $pageSize, currentPage: $currentPage, sort: $sort) {
items {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
const fragmentPriceRangeFields = `
fragment PriceRangeFields on PriceRange {
maximum_price {
final_price {
currency
value
}
regular_price {
currency
value
}
}
minimum_price {
final_price {
currency
value
}
regular_price {
currency
value
}
}
}
`;

export default `
query getProductPriceBySku($sku: String) {
products(filter: {sku: {eq: $sku}}) {
items {
price_range {
...PriceRangeFields
}

... on BundleProduct {
items {
position
required
sku
title
type
uid
options {
can_change_quantity
is_default
position
uid
quantity
product {
uid
sku
name
price_range {
maximum_price {
final_price {
currency
value
}
regular_price {
currency
value
}
}
minimum_price {
final_price {
currency
value
}
regular_price {
currency
value
}
}
}
}
}
}
}

... on GroupedProduct {
items {
position
qty
product {
uid
sku
name
stock_status
only_x_left_in_stock
price_range {
maximum_price {
final_price {
currency
value
}
regular_price {
currency
value
}
}
minimum_price {
final_price {
currency
value
}
regular_price {
currency
value
}
}
}
thumbnail {
url
position
disabled
label
}
}
}
}

}
}
}
${fragmentPriceRangeFields}
`;
2 changes: 1 addition & 1 deletion packages/theme/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@
"cookie-universal-nuxt": "^2.1.5",
"deepdash": "^5.3.9",
"express": "4.17.3",
"graphql-tag": "^2.12.6",
"is-https": "^4.0.0",
"isomorphic-dompurify": "^0.18.0",
"lodash.debounce": "^4.0.8",
Expand All @@ -73,6 +72,7 @@
"@types/lodash.debounce": "^4.0.6",
"@types/lodash.merge": "^4.6.7",
"@types/lodash.unescape": "^4.0.7",
"@types/k6": "^0.37.0",
"@vue/test-utils": "^1.3.0",
"babel-core": "7.0.0-bridge.0",
"babel-jest": "^27.4.6",
Expand Down
4 changes: 1 addition & 3 deletions packages/theme/plugins/query/StoreConfig.gql.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import gql from 'graphql-tag';

/** GraphQL Query that fetches store configuration from the API */
export const StoreConfigQuery = gql`
export const StoreConfigQuery = `
query storeConfig {
storeConfig {
store_code,
Expand Down
Loading