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

H-3166: Mimic Flow behavior in artillery #4771

Merged
merged 3 commits into from
Aug 6, 2024
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
76 changes: 76 additions & 0 deletions patches/@artilleryio+int-commons+2.9.0.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
diff --git a/node_modules/@artilleryio/int-commons/engine_util.js b/node_modules/@artilleryio/int-commons/engine_util.js
index 8e5dc73..31a9a01 100644
--- a/node_modules/@artilleryio/int-commons/engine_util.js
+++ b/node_modules/@artilleryio/int-commons/engine_util.js
@@ -6,7 +6,6 @@

const async = require('async');
const debug = require('debug')('engine_util');
-const deepForEach = require('deep-for-each');
const espree = require('espree');
const L = require('lodash');
const vm = require('vm');
@@ -257,42 +256,36 @@ function template(o, context, inPlace) {
}

// Mutates the object in place
-function templateObjectOrArray(o, context) {
- deepForEach(o, (value, key, subj, path) => {
- const newPath = template(path, context, true);
-
- let newValue;
+function templateObject(o, context) {
+ Object.entries(o).forEach(([key, value]) => {
if (value && value.constructor !== Object && value.constructor !== Array) {
- newValue = template(value, context, true);
+ o[key] = template(o[key], context, true);
} else {
- newValue = value;
- }
-
- debug(
- `path = ${path} ; value = ${JSON.stringify(
- value
- )} (${typeof value}) ; (subj type: ${
- subj.length ? 'list' : 'hash'
- }) ; newValue = ${JSON.stringify(newValue)} ; newPath = ${newPath}`
- );
-
- // If path has changed, we need to unset the original path and
- // explicitly walk down the new subtree from this path:
- if (path !== newPath) {
- L.unset(o, path);
- newValue = template(value, context, true);
+ templateObjectOrArray(value, context);
}
+ });
+}

- if (newPath.endsWith(key)) {
- const keyIndex = newPath.lastIndexOf(key);
- const prefix = newPath.substr(0, keyIndex - 1);
- L.set(o, `${prefix}["${key}"]`, newValue);
+// Mutates the array in place
+function templateArray(o, context) {
+ o.forEach((value, index) => {
+ if (value && value.constructor !== Object && value.constructor !== Array) {
+ o[index] = template(o[index], context, true);
} else {
- L.set(o, newPath, newValue);
+ templateObjectOrArray(value, context);
}
});
}

+// Mutates the object or array in place
+function templateObjectOrArray(o, context) {
+ if (o.constructor === Array) {
+ templateArray(o, context);
+ } else {
+ templateObject(o, context);
+ }
+}
+
function renderVariables(str, vars) {
const RX = /{{{?[\s$\w\.\[\]\'\"-]+}}}?/g;
let rxmatch;
1 change: 0 additions & 1 deletion tests/hash-backend-performance/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@
"@rollup/plugin-commonjs": "26.0.1",
"@rollup/plugin-node-resolve": "15.2.3",
"@rollup/plugin-typescript": "11.1.6",
"@types/artillery": "1.7.4",
"eslint": "8.57.0",
"rimraf": "6.0.1",
"rollup": "4.12.0",
Expand Down
2 changes: 1 addition & 1 deletion tests/hash-backend-performance/rollup.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const OUT_DIR = "dist/esm";

const bundles: RollupOptions[] = [
{
input: "src/main.ts",
input: ["src/main.ts"],
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Accidentally committed this, but it doesn't hurt, either, as it's easier to extend πŸ˜„

output: {
dir: OUT_DIR,
entryFileNames: "[name].mjs",
Expand Down
58 changes: 58 additions & 0 deletions tests/hash-backend-performance/scenarios/flow.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
before:
flow:
- function: login

scenarios:
- name: Mimic a flow run
beforeRequest: refreshSessionToken
flow:
- count: 10
loop:
- post:
name: Create entities
url: /
json:
query: |
mutation createEntity($ownedById: OwnedById!, $entityTypeId: VersionedUrl!, $properties: PropertyObjectWithMetadata!) {
createEntity(ownedById: $ownedById, entityTypeId: $entityTypeId, properties: $properties)
}
variables:
ownedById: "{{ session.ownedById }}"
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not strictly needed but we have it available.

entityTypeId: https://hash.ai/@hash/types/entity-type/usage-record/v/2
properties:
value:
https://hash.ai/@hash/types/property-type/input-unit-count/:
value: 1000
metadata:
dataTypeId: https://blockprotocol.org/@blockprotocol/types/data-type/number/v/1
https://hash.ai/@hash/types/property-type/output-unit-count/:
value: 1000
metadata:
dataTypeId: https://blockprotocol.org/@blockprotocol/types/data-type/number/v/1
expect:
- notHasProperty: errors
- post:
name: Create entities
url: http://127.0.0.1:4000/entities/bulk
Comment on lines +34 to +36
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I kept the graph endpoint to show how this is used

headers:
X-Authenticated-User-Actor-Id: "{{ session.ownedById }}"
json:
- ownedById: "{{ session.ownedById }}"
entityTypeIds:
- https://hash.ai/@hash/types/entity-type/usage-record/v/2
properties:
value:
https://hash.ai/@hash/types/property-type/input-unit-count/:
value: 1000
metadata:
dataTypeId: https://blockprotocol.org/@blockprotocol/types/data-type/number/v/1
https://hash.ai/@hash/types/property-type/output-unit-count/:
value: 1000
metadata:
dataTypeId: https://blockprotocol.org/@blockprotocol/types/data-type/number/v/1
draft: false
relationships:
- relation: setting
subject:
kind: setting
subjectId: administratorFromWeb
82 changes: 41 additions & 41 deletions tests/hash-backend-performance/src/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,63 +7,45 @@ import { extractOwnedByIdFromEntityId } from "@local/hash-subgraph";
import { Configuration, FrontendApi } from "@ory/client";

import { getUserByKratosIdentityId } from "./graph";
import type { BeforeRequest, RequestParams } from "./types";
import type { ActionFn, BeforeRequestFn } from "./types";

const API_ORIGIN = "http://127.0.0.1:5001";

type LoginContext = {
flowId: string;
session: {
token: string;
expiresAt?: string;
expiresAt?: number;
user: SimpleProperties<User["properties"]>;
ownedById: OwnedById;
};
};

const setAuthorizationHeader = (request: RequestParams, token: string) => {
if (!request.headers) {
request.headers = {};
let __oryKratosClient: FrontendApi | undefined;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a naming pattern we use for this? Or is there a better way? Generally I just tried to avoid creating the client multiple times.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd use one underscore (_oryKratosClient) but this is fine

const getOryKratosClient = () => {
if (!__oryKratosClient) {
__oryKratosClient = new FrontendApi(
new Configuration({
basePath: `${API_ORIGIN}/auth`,
baseOptions: {
withCredentials: true,
},
}),
);
}
request.headers.Authorization = `Bearer ${token}`;
};

export const refreshSessionToken: BeforeRequest<LoginContext> = async (
request,
context,
) => {
if (context.vars.session) {
if (context.vars.session.expiresAt) {
if (context.vars.session.expiresAt > new Date().toISOString()) {
setAuthorizationHeader(request, context.vars.session.token);
return;
}
} else {
setAuthorizationHeader(request, context.vars.session.token);
return;
}
}

const oryKratosClient = new FrontendApi(
new Configuration({
basePath: `${API_ORIGIN}/auth`,
baseOptions: {
withCredentials: true,
},
}),
);
return __oryKratosClient;
};

if (!context.vars.flowId) {
const loginFlow = await oryKratosClient
.createNativeLoginFlow()
.then(({ data }) => data);
export const login: ActionFn<LoginContext> = async (context) => {
const oryKratosClient = getOryKratosClient();

context.vars.flowId = loginFlow.id;
}
const loginFlow = await oryKratosClient
.createNativeLoginFlow()
.then(({ data }) => data);

const fullLogin = await oryKratosClient
.updateLoginFlow({
flow: context.vars.flowId,
flow: loginFlow.id,
updateLoginFlowBody: {
method: "password",
password_identifier: "email",
Expand All @@ -86,9 +68,27 @@ export const refreshSessionToken: BeforeRequest<LoginContext> = async (

context.vars.session = {
token: fullLogin.session_token,
expiresAt: fullLogin.session.expires_at,
expiresAt: fullLogin.session.expires_at
? new Date(fullLogin.session.expires_at).valueOf()
: undefined,
user: simplifyProperties(user.properties),
ownedById: extractOwnedByIdFromEntityId(user.entityId),
};
setAuthorizationHeader(request, context.vars.session.token);
};

export const refreshSessionToken: BeforeRequestFn<LoginContext> = async (
request,
context,
events,
) => {
if (
!context.vars.session ||
(context.vars.session.expiresAt &&
context.vars.session.expiresAt < Date.now())
) {
await login(context, events);
}

request.headers ??= {};
request.headers.Authorization = `Bearer ${context.vars.session!.token}`;
};
14 changes: 7 additions & 7 deletions tests/hash-backend-performance/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export interface Context<
scenario: Scenario & ScenarioVariables;
}

export type BeforeRequest<
export type BeforeRequestFn<
Vars extends Record<string, unknown> = Record<string, unknown>,
Scenario extends Record<string, unknown> = Record<string, unknown>,
> = (
Expand All @@ -34,7 +34,7 @@ export type BeforeRequest<
events: events.EventEmitter,
) => Promise<void>;

export type AfterResponse<
export type AfterResponseFn<
Vars extends Record<string, unknown> = Record<string, unknown>,
Scenario extends Record<string, unknown> = Record<string, unknown>,
> = (
Expand All @@ -44,20 +44,20 @@ export type AfterResponse<
events: events.EventEmitter,
) => Promise<void>;

export type Action<
export type ActionFn<
Vars extends Record<string, unknown> = Record<string, unknown>,
Scenario extends Record<string, unknown> = Record<string, unknown>,
> = (
context: Context<Partial<Vars>, Partial<Scenario>>,
events: events.EventEmitter,
) => Promise<void>;

export type BeforeScenario<
export type BeforeScenarioFn<
Vars extends Record<string, unknown> = Record<string, unknown>,
Scenario extends Record<string, unknown> = Record<string, unknown>,
> = Action<Vars, Scenario>;
> = ActionFn<Vars, Scenario>;

export type AfterScenario<
export type AfterScenarioFn<
Vars extends Record<string, unknown> = Record<string, unknown>,
Scenario extends Record<string, unknown> = Record<string, unknown>,
> = Action<Vars, Scenario>;
> = ActionFn<Vars, Scenario>;
9 changes: 0 additions & 9 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -10163,15 +10163,6 @@
resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-4.2.2.tgz#ed4e0ad92306a704f9fb132a0cfcf77486dbe2bc"
integrity "sha1-7U4K2SMGpwT5+xMqDPz3dIbb4rw= sha512-HnYpAE1Y6kRyKM/XkEuiRQhTHvkzMBurTHnpFLYLBGPIylZNPs9jJcuOOYWxPLJCSEtmZT0Y8rHDokKN7rRTig=="

"@types/[email protected]":
version "1.7.4"
resolved "https://registry.yarnpkg.com/@types/artillery/-/artillery-1.7.4.tgz#683140e7a0915a42377fd9ca6473ed09cf516ebb"
integrity sha512-nqT0ixMaWyy8eVyvVLfbea/8q9TRnzO6UlpEVejTTy49YKUaax3KL/Pp/36BFkGL9c0WYc8Ea9Yhy7CahNnQBA==
dependencies:
"@types/node" "*"
"@types/tough-cookie" "*"
got "^11.8.5"

"@types/babel__core@^7.0.0":
version "7.1.20"
resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.20.tgz#e168cdd612c92a2d335029ed62ac94c95b362359"
Expand Down
Loading