mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-10-21 22:04:41 -04:00
move k6 into cdperf
remove k6 from ci
This commit is contained in:
1 parent
f8891bd6e4
commit
4f0d8b5e3c
32 files changed
+4
-18384
No files matched your search
+4
-60
@@ -191,10 +191,9 @@ def main(ctx):
|
||||
|
||||
if ctx.build.event == "cron":
|
||||
pipelines = test_pipelines + [
|
||||
benchmark(ctx),
|
||||
pipelineDependsOn(
|
||||
purgeBuildArtifactCache(ctx, 'ocis-binary-amd64'),
|
||||
testPipelines(ctx) + [benchmark(ctx)]
|
||||
testPipelines(ctx)
|
||||
)
|
||||
]
|
||||
|
||||
@@ -206,21 +205,12 @@ def main(ctx):
|
||||
pipelines = [docs(ctx)]
|
||||
|
||||
else:
|
||||
if '[with-benchmarks]' in (ctx.build.title + ctx.build.message):
|
||||
test_pipelines += [
|
||||
benchmark(ctx),
|
||||
test_pipelines.append(
|
||||
pipelineDependsOn(
|
||||
purgeBuildArtifactCache(ctx, 'ocis-binary-amd64'),
|
||||
testPipelines(ctx) + [benchmark(ctx)]
|
||||
)
|
||||
]
|
||||
else:
|
||||
test_pipelines.append(
|
||||
pipelineDependsOn(
|
||||
purgeBuildArtifactCache(ctx, 'ocis-binary-amd64'),
|
||||
testPipelines(ctx)
|
||||
)
|
||||
testPipelines(ctx)
|
||||
)
|
||||
)
|
||||
|
||||
pipelines = test_pipelines + build_release_pipelines + build_release_helpers
|
||||
|
||||
@@ -535,52 +525,6 @@ def coreApiTests(ctx, part_number = 1, number_of_parts = 1, storage = 'owncloud'
|
||||
'volumes': [pipelineVolumeOC10Tests],
|
||||
}
|
||||
|
||||
def benchmark(ctx):
|
||||
return {
|
||||
'kind': 'pipeline',
|
||||
'type': 'docker',
|
||||
'name': 'benchmark',
|
||||
'failure': 'ignore',
|
||||
'platform': {
|
||||
'os': 'linux',
|
||||
'arch': 'amd64',
|
||||
},
|
||||
'steps':
|
||||
restoreBuildArtifactCache(ctx, 'ocis-binary-amd64', 'ocis/bin/ocis') +
|
||||
ocisServer('ocis') + [
|
||||
{
|
||||
'name': 'build benchmarks',
|
||||
'image': 'node',
|
||||
'pull': 'always',
|
||||
'commands': [
|
||||
'cd tests/k6',
|
||||
'yarn',
|
||||
'yarn build',
|
||||
],
|
||||
},
|
||||
{
|
||||
'name': 'run benchmarks',
|
||||
'image': 'loadimpact/k6',
|
||||
'pull': 'always',
|
||||
'environment': {
|
||||
'OC_HOST': 'https://ocis-server:9200',
|
||||
},
|
||||
'commands': [
|
||||
'cd tests/k6',
|
||||
'for f in ./dist/test-* ; do k6 run "$f" -q; done',
|
||||
],
|
||||
},
|
||||
],
|
||||
'depends_on': getPipelineNames([buildOcisBinaryForTesting(ctx)]),
|
||||
'trigger': {
|
||||
'ref': [
|
||||
'refs/heads/master',
|
||||
'refs/tags/v*',
|
||||
'refs/pull/**',
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
def uiTests(ctx):
|
||||
suiteNames = config['uiTests']['suites'].keys()
|
||||
return [uiTestPipeline(ctx, suiteName) for suiteName in suiteNames]
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"presets": ["@babel/env", "@babel/typescript"],
|
||||
"plugins": [
|
||||
"lodash",
|
||||
"@babel/proposal-class-properties",
|
||||
"@babel/proposal-object-rest-spread"
|
||||
]
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
node_modules
|
||||
dist
|
||||
@@ -1,23 +0,0 @@
|
||||
{
|
||||
"plugins": [
|
||||
"simple-import-sort",
|
||||
"import"
|
||||
],
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2020,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"extends": [
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"prettier/@typescript-eslint",
|
||||
"plugin:prettier/recommended"
|
||||
],
|
||||
"rules": {
|
||||
"simple-import-sort/imports": "error",
|
||||
"simple-import-sort/exports": "error",
|
||||
"import/first": "error",
|
||||
"import/newline-after-import": "error",
|
||||
"import/no-duplicates": "error",
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"semi": true,
|
||||
"trailingComma": "all",
|
||||
"singleQuote": true,
|
||||
"printWidth": 120,
|
||||
"tabWidth": 4
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
## Requirements
|
||||
* [K6](https://k6.io/)
|
||||
* [YARN](https://yarnpkg.com/)
|
||||
* [OCIS](https://github.com/owncloud/ocis)
|
||||
|
||||
## How to build
|
||||
```console
|
||||
$ yarn
|
||||
$ yarn build
|
||||
```
|
||||
|
||||
## How to run
|
||||
```console
|
||||
k6 run ./dist/NAME_OF_TEST.js
|
||||
```
|
||||
|
||||
## Environment variables
|
||||
```console
|
||||
$ OC_LOGIN=USERNAME OC_PASSWORD=PASSWORD k6 run ...
|
||||
$ OC_HOST=URL k6 run ...
|
||||
$ OC_OIDC_HOST=URL k6 run ...
|
||||
$ OC_OIDC_ENABLED=BOOL k6 run ...
|
||||
```
|
||||
Generated
-10320
File diff suppressed because it is too large.
Load diff
@@ -1,53 +0,0 @@
|
||||
{
|
||||
"name": "oc-k6",
|
||||
"version": "1.0.0",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"clean": "rm -rf ./dist",
|
||||
"lint": "eslint './src/**/*.ts' --fix",
|
||||
"build": "rollup -c",
|
||||
"build:w": "rollup -c -w"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.{ts}": [
|
||||
"eslint --fix"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.9.0",
|
||||
"@babel/polyfill": "^7.12.1",
|
||||
"@babel/preset-env": "^7.9.5",
|
||||
"@babel/preset-typescript": "^7.9.0",
|
||||
"@commitlint/cli": "^8.3.5",
|
||||
"@commitlint/config-conventional": "^8.3.4",
|
||||
"@rollup/plugin-commonjs": "^11.1.0",
|
||||
"@rollup/plugin-json": "^4.0.3",
|
||||
"@rollup/plugin-node-resolve": "^7.1.3",
|
||||
"@rollup/pluginutils": "^4.1.0",
|
||||
"@types/k6": "^0.28.2",
|
||||
"@types/lodash": "^4.14.165",
|
||||
"@typescript-eslint/eslint-plugin": "^4.9.0",
|
||||
"@typescript-eslint/parser": "^4.9.0",
|
||||
"babel-plugin-lodash": "^3.3.4",
|
||||
"eslint": "^7.14.0",
|
||||
"eslint-config-prettier": "^6.15.0",
|
||||
"eslint-plugin-import": "^2.22.1",
|
||||
"eslint-plugin-jest": "^23.8.2",
|
||||
"eslint-plugin-prettier": "^3.2.0",
|
||||
"eslint-plugin-simple-import-sort": "^6.0.1",
|
||||
"jest": "^25.4.0",
|
||||
"k6": "^0.0.0",
|
||||
"lint-staged": "^10.1.7",
|
||||
"prettier": "^2.2.1",
|
||||
"prettier-eslint": "^12.0.0",
|
||||
"rollup": "^2.7.2",
|
||||
"rollup-plugin-babel": "^4.4.0",
|
||||
"rollup-plugin-multi-input": "^1.1.1",
|
||||
"rollup-plugin-terser": "^5.3.0",
|
||||
"typescript": "^4.1.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"lodash": "^4.17.20",
|
||||
"query-string": "^6.13.7"
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
import commonjs from '@rollup/plugin-commonjs';
|
||||
import json from '@rollup/plugin-json';
|
||||
import resolve from '@rollup/plugin-node-resolve';
|
||||
import babel from 'rollup-plugin-babel';
|
||||
import { terser } from 'rollup-plugin-terser';
|
||||
import multiInput from 'rollup-plugin-multi-input';
|
||||
import utils from '@rollup/pluginutils';
|
||||
import pkg from './package.json';
|
||||
|
||||
const extensions = ['.js', '.ts'];
|
||||
|
||||
export default [
|
||||
{
|
||||
input: ['src/test/**/*.ts', '!src/test/**/*.lib.ts', '!src/test/**/index.ts', '!src/test/**/_*.ts'],
|
||||
external: utils.createFilter(['k6/**', ...Object.keys(pkg.devDependencies)], null, { resolve: false }),
|
||||
output: [
|
||||
{
|
||||
dir: 'dist',
|
||||
format: 'cjs',
|
||||
exports: 'named',
|
||||
chunkFileNames: '_chunks/[name]-[hash].js',
|
||||
},
|
||||
],
|
||||
plugins: [
|
||||
multiInput({
|
||||
transformOutputPath: (output, input) => `${output.split('/').join('-')}`,
|
||||
}),
|
||||
json(),
|
||||
resolve({
|
||||
extensions,
|
||||
}),
|
||||
commonjs(),
|
||||
babel({
|
||||
extensions,
|
||||
include: ['src/**/*'],
|
||||
}),
|
||||
terser(),
|
||||
],
|
||||
},
|
||||
];
|
||||
@@ -1,53 +0,0 @@
|
||||
import { bytes } from 'k6';
|
||||
import encoding from 'k6/encoding';
|
||||
import http, { RefinedParams, RefinedResponse, RequestBody, ResponseType } from 'k6/http';
|
||||
import { merge } from 'lodash';
|
||||
|
||||
import * as defaults from '../defaults';
|
||||
import * as types from '../types';
|
||||
|
||||
export const buildHeaders = ({ credential }: { credential?: types.Credential }): { [key: string]: string } => {
|
||||
const isOIDCGuard = (credential as types.Token).tokenType !== undefined;
|
||||
const authOIDC = credential as types.Token;
|
||||
const authBasic = credential as types.Account;
|
||||
|
||||
return {
|
||||
...(credential && {
|
||||
Authorization: isOIDCGuard
|
||||
? `${authOIDC.tokenType} ${authOIDC.accessToken}`
|
||||
: `Basic ${encoding.b64encode(`${authBasic.login}:${authBasic.password}`)}`,
|
||||
}),
|
||||
};
|
||||
};
|
||||
|
||||
export const buildURL = ({ path }: { path: string }): string => {
|
||||
return [defaults.ENV.HOST, ...path.split('/').filter(Boolean)].join('/');
|
||||
};
|
||||
|
||||
export const request = ({
|
||||
method,
|
||||
path,
|
||||
body = {},
|
||||
params = {},
|
||||
credential,
|
||||
}: {
|
||||
method: 'PROPFIND' | 'PUT' | 'GET' | 'POST' | 'DELETE' | 'MKCOL';
|
||||
path: string;
|
||||
credential: types.Credential;
|
||||
body?: RequestBody | bytes | null;
|
||||
params?: RefinedParams<ResponseType> | null;
|
||||
}): RefinedResponse<ResponseType> => {
|
||||
return http.request(
|
||||
method,
|
||||
buildURL({ path }),
|
||||
body as never,
|
||||
merge(
|
||||
{
|
||||
headers: {
|
||||
...buildHeaders({ credential }),
|
||||
},
|
||||
},
|
||||
params,
|
||||
),
|
||||
);
|
||||
};
|
||||
@@ -1,112 +0,0 @@
|
||||
import { RefinedResponse, ResponseType } from 'k6/http';
|
||||
|
||||
import * as types from '../types';
|
||||
import * as api from './api';
|
||||
|
||||
export class Upload {
|
||||
public static exec({
|
||||
credential,
|
||||
userName,
|
||||
path = '',
|
||||
asset,
|
||||
tags,
|
||||
}: {
|
||||
credential: types.Credential;
|
||||
userName: string;
|
||||
asset: types.Asset;
|
||||
path?: string;
|
||||
tags?: types.Tags;
|
||||
}): RefinedResponse<ResponseType> {
|
||||
return api.request({
|
||||
method: 'PUT',
|
||||
credential,
|
||||
path: `/remote.php/dav/files/${userName}/${path}/${asset.name}`,
|
||||
params: { tags },
|
||||
body: asset.bytes,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export class Download {
|
||||
public static exec({
|
||||
credential,
|
||||
userName,
|
||||
path,
|
||||
tags,
|
||||
}: {
|
||||
credential: types.Credential;
|
||||
userName: string;
|
||||
path: string;
|
||||
tags?: types.Tags;
|
||||
}): RefinedResponse<ResponseType> {
|
||||
return api.request({
|
||||
method: 'GET',
|
||||
credential,
|
||||
path: `/remote.php/dav/files/${userName}/${path}`,
|
||||
params: { tags },
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export class Delete {
|
||||
public static exec({
|
||||
credential,
|
||||
userName,
|
||||
path,
|
||||
tags,
|
||||
}: {
|
||||
credential: types.Credential;
|
||||
userName: string;
|
||||
path: string;
|
||||
tags?: types.Tags;
|
||||
}): RefinedResponse<ResponseType> {
|
||||
return api.request({
|
||||
method: 'DELETE',
|
||||
credential,
|
||||
path: `/remote.php/dav/files/${userName}/${path}`,
|
||||
params: { tags },
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export class Create {
|
||||
public static exec({
|
||||
credential,
|
||||
userName,
|
||||
path,
|
||||
tags,
|
||||
}: {
|
||||
credential: types.Credential;
|
||||
userName: string;
|
||||
path: string;
|
||||
tags?: types.Tags;
|
||||
}): RefinedResponse<ResponseType> {
|
||||
return api.request({
|
||||
method: 'MKCOL',
|
||||
credential,
|
||||
path: `/remote.php/dav/files/${userName}/${path}`,
|
||||
params: { tags },
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export class Propfind {
|
||||
public static exec({
|
||||
credential,
|
||||
userName,
|
||||
path = '',
|
||||
tags,
|
||||
}: {
|
||||
credential: types.Credential;
|
||||
userName: string;
|
||||
path?: string;
|
||||
tags?: types.Tags;
|
||||
}): RefinedResponse<ResponseType> {
|
||||
return api.request({
|
||||
method: 'PROPFIND',
|
||||
credential,
|
||||
path: `/remote.php/dav/files/${userName}/${path}`,
|
||||
params: { tags },
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
export * as api from './api';
|
||||
export * as dav from './dav';
|
||||
export * as users from './users';
|
||||
@@ -1,47 +0,0 @@
|
||||
import { RefinedResponse, ResponseType } from 'k6/http';
|
||||
|
||||
import * as types from '../types';
|
||||
import * as api from './api';
|
||||
|
||||
export class Create {
|
||||
public static exec({
|
||||
userName,
|
||||
password,
|
||||
email,
|
||||
credential,
|
||||
tags,
|
||||
}: {
|
||||
credential: types.Credential;
|
||||
userName: string;
|
||||
password: string;
|
||||
email: string;
|
||||
tags?: types.Tags;
|
||||
}): RefinedResponse<ResponseType> {
|
||||
return api.request({
|
||||
method: 'POST',
|
||||
credential,
|
||||
path: `/ocs/v1.php/cloud/users`,
|
||||
params: { tags },
|
||||
body: { userid: userName, password, email },
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export class Delete {
|
||||
public static exec({
|
||||
userName,
|
||||
credential,
|
||||
tags,
|
||||
}: {
|
||||
credential: types.Credential;
|
||||
userName: string;
|
||||
tags?: types.Tags;
|
||||
}): RefinedResponse<ResponseType> {
|
||||
return api.request({
|
||||
method: 'DELETE',
|
||||
credential,
|
||||
path: `/ocs/v1.php/cloud/users/${userName}`,
|
||||
params: { tags },
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,156 +0,0 @@
|
||||
import { fail } from 'k6';
|
||||
import http from 'k6/http';
|
||||
import { get } from 'lodash';
|
||||
import queryString from 'query-string';
|
||||
|
||||
import * as defaults from './defaults';
|
||||
import * as types from './types';
|
||||
|
||||
export default class Factory {
|
||||
private provider!: types.AuthProvider;
|
||||
public account!: types.Account;
|
||||
|
||||
constructor(account: types.Account) {
|
||||
this.account = account;
|
||||
|
||||
if (defaults.ENV.OIDC_ENABLED) {
|
||||
this.provider = new OIDCProvider(account);
|
||||
return;
|
||||
}
|
||||
|
||||
this.provider = new AccountProvider(account);
|
||||
}
|
||||
|
||||
public get credential(): types.Credential {
|
||||
return this.provider.credential;
|
||||
}
|
||||
}
|
||||
|
||||
class AccountProvider implements types.AuthProvider {
|
||||
private account: types.Account;
|
||||
|
||||
constructor(account: types.Account) {
|
||||
this.account = account;
|
||||
}
|
||||
|
||||
public get credential(): types.Account {
|
||||
return this.account;
|
||||
}
|
||||
}
|
||||
|
||||
class OIDCProvider implements types.AuthProvider {
|
||||
private account: types.Account;
|
||||
private redirectUri = `${defaults.ENV.OIDC_HOST}/oidc-callback.html`;
|
||||
private logonUri = `${defaults.ENV.OIDC_HOST}/signin/v1/identifier/_/logon`;
|
||||
private tokenUrl = `${defaults.ENV.OIDC_HOST}/konnect/v1/token`;
|
||||
private cache!: {
|
||||
validTo: Date;
|
||||
token: types.Token;
|
||||
};
|
||||
|
||||
constructor(account: types.Account) {
|
||||
this.account = account;
|
||||
}
|
||||
|
||||
public get credential(): types.Token {
|
||||
if (!this.cache || this.cache.validTo <= new Date()) {
|
||||
const continueURI = this.getContinueURI();
|
||||
const code = this.getCode(continueURI);
|
||||
const token = this.getToken(code);
|
||||
|
||||
this.cache = {
|
||||
validTo: ((): Date => {
|
||||
const offset = 5;
|
||||
const d = new Date();
|
||||
|
||||
d.setSeconds(d.getSeconds() + token.expiresIn - offset);
|
||||
|
||||
return d;
|
||||
})(),
|
||||
token,
|
||||
};
|
||||
}
|
||||
|
||||
return this.cache.token;
|
||||
}
|
||||
|
||||
private getContinueURI(): string {
|
||||
const logonResponse = http.post(
|
||||
this.logonUri,
|
||||
JSON.stringify({
|
||||
params: [this.account.login, this.account.password, '1'],
|
||||
hello: {
|
||||
scope: 'openid profile email',
|
||||
client_id: 'web',
|
||||
redirect_uri: this.redirectUri,
|
||||
flow: 'oidc',
|
||||
},
|
||||
state: 'vp42cf',
|
||||
}),
|
||||
{
|
||||
headers: {
|
||||
'Kopano-Konnect-XSRF': '1',
|
||||
Referer: defaults.ENV.OIDC_HOST,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
},
|
||||
);
|
||||
const continueURI = get(logonResponse.json(), 'hello.continue_uri');
|
||||
|
||||
if (logonResponse.status != 200 || !continueURI) {
|
||||
fail(this.logonUri);
|
||||
}
|
||||
|
||||
return continueURI;
|
||||
}
|
||||
|
||||
private getCode(continueURI: string): string {
|
||||
const authorizeUri = `${continueURI}?${queryString.stringify({
|
||||
client_id: 'web',
|
||||
prompt: 'none',
|
||||
redirect_uri: this.redirectUri,
|
||||
response_mode: 'query',
|
||||
response_type: 'code',
|
||||
scope: 'openid profile email',
|
||||
})}`;
|
||||
const authorizeResponse = http.get(authorizeUri, {
|
||||
redirects: 0,
|
||||
});
|
||||
|
||||
const code = get(queryString.parseUrl(authorizeResponse.headers.Location), 'query.code');
|
||||
|
||||
if (authorizeResponse.status != 302 || !code) {
|
||||
fail(continueURI);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
private getToken(code: string): types.Token {
|
||||
const tokenResponse = http.post(this.tokenUrl, {
|
||||
client_id: 'web',
|
||||
code,
|
||||
redirect_uri: this.redirectUri,
|
||||
grant_type: 'authorization_code',
|
||||
});
|
||||
|
||||
const token = {
|
||||
accessToken: get(tokenResponse.json(), 'access_token'),
|
||||
tokenType: get(tokenResponse.json(), 'token_type'),
|
||||
idToken: get(tokenResponse.json(), 'id_token'),
|
||||
expiresIn: get(tokenResponse.json(), 'expires_in'),
|
||||
};
|
||||
|
||||
if (
|
||||
tokenResponse.status != 200 ||
|
||||
!token.accessToken ||
|
||||
!token.tokenType ||
|
||||
!token.idToken ||
|
||||
!token.expiresIn
|
||||
) {
|
||||
fail(this.tokenUrl);
|
||||
}
|
||||
|
||||
return token;
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
import * as types from './types';
|
||||
|
||||
export class ENV {
|
||||
public static readonly HOST = __ENV.OC_HOST || 'https://localhost:9200';
|
||||
public static readonly LOGIN = __ENV.OC_LOGIN;
|
||||
public static readonly PASSWORD = __ENV.OC_PASSWORD;
|
||||
public static readonly OIDC_HOST = __ENV.OC_OIDC_HOST || ENV.HOST;
|
||||
public static readonly OIDC_ENABLED = __ENV.OC_OIDC_ENABLED === 'true' || false;
|
||||
}
|
||||
|
||||
export class ACCOUNTS {
|
||||
public static readonly ADMIN = 'admin';
|
||||
public static readonly EINSTEIN = 'einstein';
|
||||
public static readonly RICHARD = 'richard';
|
||||
public static readonly ALL: { [key: string]: types.Account } = {
|
||||
admin: {
|
||||
login: 'admin',
|
||||
password: 'admin',
|
||||
},
|
||||
einstein: {
|
||||
login: 'einstein',
|
||||
password: 'relativity',
|
||||
},
|
||||
richard: {
|
||||
login: 'richard',
|
||||
password: 'superfluidity',
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
export * as api from './api';
|
||||
export { default as auth } from './auth';
|
||||
export * as defaults from './defaults';
|
||||
export * as playbook from './playbook';
|
||||
export * as types from './types';
|
||||
export * as utils from './utils';
|
||||
@@ -1,178 +0,0 @@
|
||||
import { check } from 'k6';
|
||||
import { RefinedResponse, ResponseType } from 'k6/http';
|
||||
|
||||
import * as api from '../api';
|
||||
import * as types from '../types';
|
||||
import { Play } from './playbook';
|
||||
|
||||
export class Upload extends Play {
|
||||
constructor({ name, metricID = 'default' }: { name?: string; metricID?: string } = {}) {
|
||||
super({ name: name || `oc_${metricID}_play_dav_upload` });
|
||||
}
|
||||
|
||||
public exec({
|
||||
credential,
|
||||
userName,
|
||||
path,
|
||||
asset,
|
||||
tags,
|
||||
}: {
|
||||
credential: types.Credential;
|
||||
path?: string;
|
||||
userName: string;
|
||||
asset: types.Asset;
|
||||
tags?: types.Tags;
|
||||
}): { response: RefinedResponse<ResponseType>; tags: types.Tags } {
|
||||
tags = { ...this.tags, ...tags };
|
||||
|
||||
const response = api.dav.Upload.exec({ credential: credential, asset, userName, tags, path });
|
||||
|
||||
check(
|
||||
response,
|
||||
{
|
||||
'dav upload status is 201': () => response.status === 201,
|
||||
},
|
||||
tags,
|
||||
) || this.metricErrorRate.add(1, tags);
|
||||
|
||||
this.metricTrend.add(response.timings.duration, tags);
|
||||
|
||||
return { response, tags };
|
||||
}
|
||||
}
|
||||
|
||||
export class Delete extends Play {
|
||||
constructor({ name, metricID = 'default' }: { name?: string; metricID?: string } = {}) {
|
||||
super({ name: name || `oc_${metricID}_play_dav_delete` });
|
||||
}
|
||||
|
||||
public exec({
|
||||
credential,
|
||||
userName,
|
||||
path,
|
||||
tags,
|
||||
}: {
|
||||
credential: types.Credential;
|
||||
path: string;
|
||||
userName: string;
|
||||
tags?: types.Tags;
|
||||
}): { response: RefinedResponse<ResponseType>; tags: types.Tags } {
|
||||
tags = { ...this.tags, ...tags };
|
||||
|
||||
const response = api.dav.Delete.exec({ credential: credential, userName, tags, path });
|
||||
|
||||
check(
|
||||
response,
|
||||
{
|
||||
'dav delete status is 204': () => response.status === 204,
|
||||
},
|
||||
tags,
|
||||
) || this.metricErrorRate.add(1, tags);
|
||||
|
||||
this.metricTrend.add(response.timings.duration, tags);
|
||||
|
||||
return { response, tags };
|
||||
}
|
||||
}
|
||||
|
||||
export class Download extends Play {
|
||||
constructor({ name, metricID = 'default' }: { name?: string; metricID?: string } = {}) {
|
||||
super({ name: name || `oc_${metricID}_play_dav_download` });
|
||||
}
|
||||
|
||||
public exec({
|
||||
credential,
|
||||
userName,
|
||||
path,
|
||||
tags,
|
||||
}: {
|
||||
credential: types.Credential;
|
||||
path: string;
|
||||
userName: string;
|
||||
tags?: types.Tags;
|
||||
}): { response: RefinedResponse<ResponseType>; tags: types.Tags } {
|
||||
tags = { ...this.tags, ...tags };
|
||||
|
||||
const response = api.dav.Download.exec({ credential: credential, userName, tags, path });
|
||||
|
||||
check(
|
||||
response,
|
||||
{
|
||||
'dav download status is 200': () => response.status === 200,
|
||||
},
|
||||
tags,
|
||||
) || this.metricErrorRate.add(1, tags);
|
||||
|
||||
this.metricTrend.add(response.timings.duration, tags);
|
||||
|
||||
return { response, tags };
|
||||
}
|
||||
}
|
||||
|
||||
export class Create extends Play {
|
||||
constructor({ name, metricID = 'default' }: { name?: string; metricID?: string } = {}) {
|
||||
super({ name: name || `oc_${metricID}_play_dav_create` });
|
||||
}
|
||||
|
||||
public exec({
|
||||
credential,
|
||||
userName,
|
||||
path,
|
||||
tags,
|
||||
}: {
|
||||
credential: types.Credential;
|
||||
path: string;
|
||||
userName: string;
|
||||
tags?: types.Tags;
|
||||
}): { response: RefinedResponse<ResponseType>; tags: types.Tags } {
|
||||
tags = { ...this.tags, ...tags };
|
||||
|
||||
const response = api.dav.Create.exec({ credential: credential, userName, tags, path });
|
||||
|
||||
check(
|
||||
response,
|
||||
{
|
||||
'dav create status is 201': () => response.status === 201,
|
||||
},
|
||||
tags,
|
||||
) || this.metricErrorRate.add(1, tags);
|
||||
|
||||
this.metricTrend.add(response.timings.duration, tags);
|
||||
|
||||
return { response, tags };
|
||||
}
|
||||
}
|
||||
|
||||
export class Propfind extends Play {
|
||||
constructor({ name, metricID = 'default' }: { name?: string; metricID?: string } = {}) {
|
||||
super({ name: name || `oc_${metricID}_play_dav_propfind` });
|
||||
}
|
||||
|
||||
public exec({
|
||||
credential,
|
||||
userName,
|
||||
path,
|
||||
tags,
|
||||
}: {
|
||||
credential: types.Credential;
|
||||
path?: string;
|
||||
userName: string;
|
||||
tags?: types.Tags;
|
||||
}): { response: RefinedResponse<ResponseType>; tags: types.Tags } {
|
||||
tags = { ...this.tags, ...tags };
|
||||
|
||||
const response = api.dav.Propfind.exec({ credential: credential, userName, tags, path });
|
||||
|
||||
check(
|
||||
response,
|
||||
{
|
||||
'dav propfind status is 207': () => response.status === 207,
|
||||
},
|
||||
tags,
|
||||
) || this.metricErrorRate.add(1, tags);
|
||||
|
||||
this.metricTrend.add(response.timings.duration, tags);
|
||||
|
||||
return { response, tags };
|
||||
}
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
export * as dav from './dav';
|
||||
export * as users from './users';
|
||||
@@ -1,19 +0,0 @@
|
||||
import { Gauge, Trend } from 'k6/metrics';
|
||||
|
||||
export class Play {
|
||||
public readonly name: string;
|
||||
public readonly metricTrendName: string;
|
||||
public readonly metricErrorRateName: string;
|
||||
public readonly metricTrend: Trend;
|
||||
public readonly metricErrorRate: Gauge;
|
||||
protected tags: { [key: string]: string };
|
||||
|
||||
constructor({ name }: { name: string }) {
|
||||
this.name = name;
|
||||
this.metricTrendName = `${this.name}_trend`;
|
||||
this.metricErrorRateName = `${this.name}_error_rate`;
|
||||
this.metricTrend = new Trend(this.metricTrendName, true);
|
||||
this.metricErrorRate = new Gauge(this.metricErrorRateName);
|
||||
this.tags = { play: this.name };
|
||||
}
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
import { check } from 'k6';
|
||||
import { RefinedResponse, ResponseType } from 'k6/http';
|
||||
|
||||
import * as api from '../api';
|
||||
import * as types from '../types';
|
||||
import { Play } from './playbook';
|
||||
|
||||
export class Create extends Play {
|
||||
constructor({ name, metricID = 'default' }: { name?: string; metricID?: string } = {}) {
|
||||
super({ name: name || `oc_${metricID}_play_users_create` });
|
||||
}
|
||||
|
||||
public exec({
|
||||
credential,
|
||||
userName,
|
||||
password,
|
||||
email,
|
||||
tags,
|
||||
}: {
|
||||
credential: types.Credential;
|
||||
userName: string;
|
||||
password: string;
|
||||
email: string;
|
||||
tags?: types.Tags;
|
||||
}): { response: RefinedResponse<ResponseType>; tags: types.Tags } {
|
||||
tags = { ...this.tags, ...tags };
|
||||
|
||||
const response = api.users.Create.exec({ credential: credential, userName, password, tags, email });
|
||||
|
||||
check(
|
||||
response,
|
||||
{
|
||||
'users create status is 200': () => response.status === 200,
|
||||
},
|
||||
tags,
|
||||
) || this.metricErrorRate.add(1, tags);
|
||||
|
||||
this.metricTrend.add(response.timings.duration, tags);
|
||||
|
||||
return { response, tags };
|
||||
}
|
||||
}
|
||||
|
||||
export class Delete extends Play {
|
||||
constructor({ name, metricID = 'default' }: { name?: string; metricID?: string } = {}) {
|
||||
super({ name: name || `oc_${metricID}_play_users_delete` });
|
||||
}
|
||||
|
||||
public exec({
|
||||
credential,
|
||||
userName,
|
||||
tags,
|
||||
}: {
|
||||
credential: types.Credential;
|
||||
userName: string;
|
||||
tags?: types.Tags;
|
||||
}): { response: RefinedResponse<ResponseType>; tags: types.Tags } {
|
||||
tags = { ...this.tags, ...tags };
|
||||
|
||||
const response = api.users.Delete.exec({ credential: credential, userName, tags });
|
||||
|
||||
check(
|
||||
response,
|
||||
{
|
||||
'users delete status is 200': () => response.status === 200,
|
||||
},
|
||||
tags,
|
||||
) || this.metricErrorRate.add(1, tags);
|
||||
|
||||
this.metricTrend.add(response.timings.duration, tags);
|
||||
|
||||
return { response, tags };
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
import { bytes } from 'k6';
|
||||
|
||||
export interface Asset {
|
||||
bytes: bytes;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface Token {
|
||||
accessToken: string;
|
||||
tokenType: string;
|
||||
idToken: string;
|
||||
expiresIn: number;
|
||||
}
|
||||
|
||||
export interface Account {
|
||||
login: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
export type Credential = Token | Account;
|
||||
|
||||
export interface AuthProvider {
|
||||
credential: Credential;
|
||||
}
|
||||
|
||||
export type Tags = { [key: string]: string };
|
||||
|
||||
export declare type AssetUnit = 'KB' | 'MB' | 'GB';
|
||||
@@ -1,61 +0,0 @@
|
||||
import { bytes } from 'k6';
|
||||
import { randomBytes as k6_randomBytes } from 'k6/crypto';
|
||||
|
||||
import * as defaults from './defaults';
|
||||
import * as types from './types';
|
||||
|
||||
export const randomNumber = ({ min, max }: { min: number; max: number }): number => {
|
||||
return Math.random() * (max - min) + min;
|
||||
};
|
||||
|
||||
export const randomString = ({ length = 10 }: { length?: number } = {}): string => {
|
||||
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
|
||||
|
||||
let str = '';
|
||||
for (let i = 0; i < length; i++) {
|
||||
str += chars.charAt(Math.floor(Math.random() * chars.length));
|
||||
}
|
||||
|
||||
return str;
|
||||
};
|
||||
|
||||
export const buildAccount = ({ login = defaults.ACCOUNTS.EINSTEIN }: { login: string }): types.Account => {
|
||||
if (defaults.ENV.LOGIN && defaults.ENV.PASSWORD) {
|
||||
return {
|
||||
login: defaults.ENV.LOGIN,
|
||||
password: defaults.ENV.PASSWORD,
|
||||
};
|
||||
}
|
||||
|
||||
return defaults.ACCOUNTS.ALL[login];
|
||||
};
|
||||
export const buildAsset = ({
|
||||
name = 'dummy.zip',
|
||||
size = 50,
|
||||
unit = 'KB',
|
||||
}: {
|
||||
name?: string;
|
||||
size?: number;
|
||||
unit?: types.AssetUnit;
|
||||
}): types.Asset => {
|
||||
const gen = {
|
||||
KB: (s: number): bytes => {
|
||||
return k6_randomBytes(s * 1024);
|
||||
},
|
||||
MB: (s: number): bytes => {
|
||||
return gen.KB(s * 1024);
|
||||
},
|
||||
GB: (s: number): bytes => {
|
||||
return gen.MB(s * 1024);
|
||||
},
|
||||
};
|
||||
|
||||
const fileBaseName = name.split('/').reverse()[0];
|
||||
const fileName = fileBaseName.split('.')[0];
|
||||
const fileExtension = fileBaseName.split('.').reverse()[0] || 'zip';
|
||||
|
||||
return {
|
||||
name: `${fileName}-${__VU}-${__ITER}-${unit}-${size}-${randomString()}.${fileExtension}`,
|
||||
bytes: gen[unit](size),
|
||||
};
|
||||
};
|
||||
@@ -1,90 +0,0 @@
|
||||
import { Options, Threshold } from 'k6/options';
|
||||
import { times } from 'lodash';
|
||||
|
||||
import { playbook, types, utils } from '../../../../../../lib';
|
||||
|
||||
interface File {
|
||||
size: number;
|
||||
unit: types.AssetUnit;
|
||||
}
|
||||
|
||||
interface Plays {
|
||||
davUpload: playbook.dav.Upload;
|
||||
davPropfind: playbook.dav.Propfind;
|
||||
davCreate: playbook.dav.Create;
|
||||
davDelete: playbook.dav.Delete;
|
||||
}
|
||||
|
||||
export const options = ({ files, plays }: { files: File[]; plays: Plays }): Options => {
|
||||
return {
|
||||
thresholds: files.reduce((acc: { [name: string]: Threshold[] }, c) => {
|
||||
acc[`${plays.davUpload.metricTrendName}{asset:${c.unit + c.size.toString()}}`] = [];
|
||||
acc[`${plays.davCreate.metricTrendName}{asset:${c.unit + c.size.toString()}}`] = [];
|
||||
acc[`${plays.davDelete.metricTrendName}{asset:${c.unit + c.size.toString()}}`] = [];
|
||||
return acc;
|
||||
}, {}),
|
||||
};
|
||||
};
|
||||
|
||||
export default ({
|
||||
files,
|
||||
account,
|
||||
credential,
|
||||
plays,
|
||||
}: {
|
||||
plays: Plays;
|
||||
files: File[];
|
||||
account: types.Account;
|
||||
credential: types.Credential;
|
||||
}): void => {
|
||||
const filesUploaded: { id: string; name: string; folder: string }[] = [];
|
||||
|
||||
files.forEach((f) => {
|
||||
const id = f.unit + f.size.toString();
|
||||
|
||||
const asset = utils.buildAsset({
|
||||
name: `${account.login}-dummy.zip`,
|
||||
unit: f.unit,
|
||||
size: f.size,
|
||||
});
|
||||
|
||||
const folder = times(utils.randomNumber({ min: 1, max: 10 }), () => utils.randomString())
|
||||
.reduce((acc: string[], c) => {
|
||||
acc.push(c);
|
||||
|
||||
plays.davCreate.exec({
|
||||
credential,
|
||||
path: acc.join('/'),
|
||||
userName: account.login,
|
||||
tags: { asset: id },
|
||||
});
|
||||
|
||||
return acc;
|
||||
}, [])
|
||||
.join('/');
|
||||
|
||||
plays.davUpload.exec({
|
||||
credential,
|
||||
asset,
|
||||
path: folder,
|
||||
userName: account.login,
|
||||
tags: { asset: id },
|
||||
});
|
||||
|
||||
filesUploaded.push({ id, name: asset.name, folder });
|
||||
});
|
||||
|
||||
plays.davPropfind.exec({
|
||||
credential,
|
||||
userName: account.login,
|
||||
});
|
||||
|
||||
filesUploaded.forEach((f) => {
|
||||
plays.davDelete.exec({
|
||||
credential,
|
||||
userName: account.login,
|
||||
path: f.folder.split('/')[0],
|
||||
tags: { asset: f.id },
|
||||
});
|
||||
});
|
||||
};
|
||||
@@ -1,27 +0,0 @@
|
||||
import { Options } from 'k6/options';
|
||||
import { times } from 'lodash';
|
||||
|
||||
import { auth, defaults, playbook, types, utils } from '../../../../../../lib';
|
||||
import { default as propfind, options as propfindOptions } from './deep.lib';
|
||||
|
||||
// put 1000 files into nested dirs and run a 'PROPFIND' through API
|
||||
|
||||
const files: {
|
||||
size: number;
|
||||
unit: types.AssetUnit;
|
||||
}[] = times(1000, () => ({ size: 1, unit: 'KB' }));
|
||||
const authFactory = new auth(utils.buildAccount({ login: defaults.ACCOUNTS.EINSTEIN }));
|
||||
const plays = {
|
||||
davUpload: new playbook.dav.Upload(),
|
||||
davCreate: new playbook.dav.Create(),
|
||||
davPropfind: new playbook.dav.Propfind(),
|
||||
davDelete: new playbook.dav.Delete(),
|
||||
};
|
||||
export const options: Options = {
|
||||
insecureSkipTLSVerify: true,
|
||||
iterations: 3,
|
||||
vus: 1,
|
||||
...propfindOptions({ plays, files }),
|
||||
};
|
||||
|
||||
export default (): void => propfind({ files, plays, credential: authFactory.credential, account: authFactory.account });
|
||||
@@ -1,71 +0,0 @@
|
||||
import { Options, Threshold } from 'k6/options';
|
||||
|
||||
import { playbook, types, utils } from '../../../../../../lib';
|
||||
|
||||
interface File {
|
||||
size: number;
|
||||
unit: types.AssetUnit;
|
||||
}
|
||||
|
||||
interface Plays {
|
||||
davUpload: playbook.dav.Upload;
|
||||
davPropfind: playbook.dav.Propfind;
|
||||
davDelete: playbook.dav.Delete;
|
||||
}
|
||||
|
||||
export const options = ({ files, plays }: { files: File[]; plays: Plays }): Options => {
|
||||
return {
|
||||
thresholds: files.reduce((acc: { [name: string]: Threshold[] }, c) => {
|
||||
acc[`${plays.davUpload.metricTrendName}{asset:${c.unit + c.size.toString()}}`] = [];
|
||||
acc[`${plays.davDelete.metricTrendName}{asset:${c.unit + c.size.toString()}}`] = [];
|
||||
return acc;
|
||||
}, {}),
|
||||
};
|
||||
};
|
||||
|
||||
export default ({
|
||||
files,
|
||||
account,
|
||||
credential,
|
||||
plays,
|
||||
}: {
|
||||
plays: Plays;
|
||||
files: File[];
|
||||
account: types.Account;
|
||||
credential: types.Credential;
|
||||
}): void => {
|
||||
const filesUploaded: { id: string; name: string }[] = [];
|
||||
|
||||
files.forEach((f) => {
|
||||
const id = f.unit + f.size.toString();
|
||||
|
||||
const asset = utils.buildAsset({
|
||||
name: `${account.login}-dummy.zip`,
|
||||
unit: f.unit,
|
||||
size: f.size,
|
||||
});
|
||||
|
||||
plays.davUpload.exec({
|
||||
credential,
|
||||
asset,
|
||||
userName: account.login,
|
||||
tags: { asset: id },
|
||||
});
|
||||
|
||||
filesUploaded.push({ id, name: asset.name });
|
||||
});
|
||||
|
||||
plays.davPropfind.exec({
|
||||
credential,
|
||||
userName: account.login,
|
||||
});
|
||||
|
||||
filesUploaded.forEach((f) => {
|
||||
plays.davDelete.exec({
|
||||
credential,
|
||||
userName: account.login,
|
||||
path: f.name,
|
||||
tags: { asset: f.id },
|
||||
});
|
||||
});
|
||||
};
|
||||
@@ -1,26 +0,0 @@
|
||||
import { Options } from 'k6/options';
|
||||
import { times } from 'lodash';
|
||||
|
||||
import { auth, defaults, playbook, types, utils } from '../../../../../../lib';
|
||||
import { default as propfind, options as propfindOptions } from './flat.lib';
|
||||
|
||||
// put 1000 files into one dir and run a 'PROPFIND' through API
|
||||
|
||||
const files: {
|
||||
size: number;
|
||||
unit: types.AssetUnit;
|
||||
}[] = times(1000, () => ({ size: 1, unit: 'KB' }));
|
||||
const authFactory = new auth(utils.buildAccount({ login: defaults.ACCOUNTS.EINSTEIN }));
|
||||
const plays = {
|
||||
davUpload: new playbook.dav.Upload(),
|
||||
davPropfind: new playbook.dav.Propfind(),
|
||||
davDelete: new playbook.dav.Delete(),
|
||||
};
|
||||
export const options: Options = {
|
||||
insecureSkipTLSVerify: true,
|
||||
iterations: 3,
|
||||
vus: 1,
|
||||
...propfindOptions({ plays, files }),
|
||||
};
|
||||
|
||||
export default (): void => propfind({ files, plays, credential: authFactory.credential, account: authFactory.account });
|
||||
@@ -1,33 +0,0 @@
|
||||
import { Options } from 'k6/options';
|
||||
|
||||
import { auth, defaults, playbook, types, utils } from '../../../../../../lib';
|
||||
import { default as upDownDelete, options as upDownDeleteOptions } from './shared.lib';
|
||||
|
||||
// upload, download and delete of many files with several sizes and summary size of 500 MB in one directory
|
||||
|
||||
const files: {
|
||||
size: number;
|
||||
unit: types.AssetUnit;
|
||||
}[] = [
|
||||
{ size: 50, unit: 'KB' },
|
||||
{ size: 500, unit: 'KB' },
|
||||
{ size: 5, unit: 'MB' },
|
||||
{ size: 50, unit: 'MB' },
|
||||
{ size: 500, unit: 'MB' },
|
||||
{ size: 1, unit: 'GB' },
|
||||
];
|
||||
const authFactory = new auth(utils.buildAccount({ login: defaults.ACCOUNTS.EINSTEIN }));
|
||||
const plays = {
|
||||
davUpload: new playbook.dav.Upload(),
|
||||
davDownload: new playbook.dav.Download(),
|
||||
davDelete: new playbook.dav.Delete(),
|
||||
};
|
||||
export const options: Options = {
|
||||
insecureSkipTLSVerify: true,
|
||||
iterations: 3,
|
||||
vus: 1,
|
||||
...upDownDeleteOptions({ plays, files }),
|
||||
};
|
||||
|
||||
export default (): void =>
|
||||
upDownDelete({ files, plays, credential: authFactory.credential, account: authFactory.account });
|
||||
@@ -1,31 +0,0 @@
|
||||
import { Options } from 'k6/options';
|
||||
import { times } from 'lodash';
|
||||
|
||||
import { auth, defaults, playbook, types, utils } from '../../../../../../lib';
|
||||
import { default as upDownDelete, options as upDownDeleteOptions } from './shared.lib';
|
||||
|
||||
// upload, download and delete of many files with several sizes and summary size of 500 MB in one directory
|
||||
|
||||
const files: {
|
||||
size: number;
|
||||
unit: types.AssetUnit;
|
||||
}[] = [
|
||||
...times(100, () => ({ size: 500, unit: 'KB' as types.AssetUnit })),
|
||||
...times(50, () => ({ size: 5, unit: 'MB' as types.AssetUnit })),
|
||||
...times(10, () => ({ size: 25, unit: 'MB' as types.AssetUnit })),
|
||||
];
|
||||
const authFactory = new auth(utils.buildAccount({ login: defaults.ACCOUNTS.EINSTEIN }));
|
||||
const plays = {
|
||||
davUpload: new playbook.dav.Upload(),
|
||||
davDownload: new playbook.dav.Download(),
|
||||
davDelete: new playbook.dav.Delete(),
|
||||
};
|
||||
export const options: Options = {
|
||||
insecureSkipTLSVerify: true,
|
||||
iterations: 3,
|
||||
vus: 1,
|
||||
...upDownDeleteOptions({ plays, files }),
|
||||
};
|
||||
|
||||
export default (): void =>
|
||||
upDownDelete({ files, plays, credential: authFactory.credential, account: authFactory.account });
|
||||
@@ -1,76 +0,0 @@
|
||||
import { Options, Threshold } from 'k6/options';
|
||||
|
||||
import { playbook, types, utils } from '../../../../../../lib';
|
||||
|
||||
interface File {
|
||||
size: number;
|
||||
unit: types.AssetUnit;
|
||||
}
|
||||
|
||||
interface Plays {
|
||||
davUpload: playbook.dav.Upload;
|
||||
davDownload: playbook.dav.Download;
|
||||
davDelete: playbook.dav.Delete;
|
||||
}
|
||||
|
||||
export const options = ({ files, plays }: { files: File[]; plays: Plays }): Options => {
|
||||
return {
|
||||
thresholds: files.reduce((acc: { [name: string]: Threshold[] }, c) => {
|
||||
acc[`${plays.davUpload.metricTrendName}{asset:${c.unit + c.size.toString()}}`] = [];
|
||||
acc[`${plays.davDownload.metricTrendName}{asset:${c.unit + c.size.toString()}}`] = [];
|
||||
acc[`${plays.davDelete.metricTrendName}{asset:${c.unit + c.size.toString()}}`] = [];
|
||||
return acc;
|
||||
}, {}),
|
||||
};
|
||||
};
|
||||
|
||||
export default ({
|
||||
files,
|
||||
account,
|
||||
credential,
|
||||
plays,
|
||||
}: {
|
||||
plays: Plays;
|
||||
files: File[];
|
||||
account: types.Account;
|
||||
credential: types.Credential;
|
||||
}): void => {
|
||||
const filesUploaded: { id: string; name: string }[] = [];
|
||||
|
||||
files.forEach((f) => {
|
||||
const id = f.unit + f.size.toString();
|
||||
|
||||
const asset = utils.buildAsset({
|
||||
name: `${account.login}-dummy.zip`,
|
||||
unit: f.unit,
|
||||
size: f.size,
|
||||
});
|
||||
|
||||
plays.davUpload.exec({
|
||||
credential,
|
||||
asset,
|
||||
userName: account.login,
|
||||
tags: { asset: id },
|
||||
});
|
||||
|
||||
filesUploaded.push({ id, name: asset.name });
|
||||
});
|
||||
|
||||
filesUploaded.forEach((f) => {
|
||||
plays.davDownload.exec({
|
||||
credential,
|
||||
userName: account.login,
|
||||
path: f.name,
|
||||
tags: { asset: f.id },
|
||||
});
|
||||
});
|
||||
|
||||
filesUploaded.forEach((f) => {
|
||||
plays.davDelete.exec({
|
||||
credential,
|
||||
userName: account.login,
|
||||
path: f.name,
|
||||
tags: { asset: f.id },
|
||||
});
|
||||
});
|
||||
};
|
||||
@@ -1,44 +0,0 @@
|
||||
import { Options } from 'k6/options';
|
||||
import { times } from 'lodash';
|
||||
|
||||
import { auth, defaults, playbook, types, utils } from '../../../../../../lib';
|
||||
import { default as upDownDelete, options as upDownDeleteOptions } from './shared.lib';
|
||||
|
||||
// create 10 users. Do the Simple Uploads & downloads with each user in parallel.
|
||||
|
||||
const files: {
|
||||
size: number;
|
||||
unit: types.AssetUnit;
|
||||
}[] = times(10, () => ({ size: 1, unit: 'KB' as types.AssetUnit }));
|
||||
const authFactory = new auth(utils.buildAccount({ login: defaults.ACCOUNTS.ADMIN }));
|
||||
const plays = {
|
||||
davUpload: new playbook.dav.Upload(),
|
||||
davDownload: new playbook.dav.Download(),
|
||||
davDelete: new playbook.dav.Delete(),
|
||||
usersCreate: new playbook.users.Create(),
|
||||
usersDelete: new playbook.users.Delete(),
|
||||
};
|
||||
export const options: Options = {
|
||||
insecureSkipTLSVerify: true,
|
||||
iterations: 10,
|
||||
vus: 10,
|
||||
...upDownDeleteOptions({ plays, files }),
|
||||
};
|
||||
|
||||
export default (): void => {
|
||||
const userName: string = utils.randomString();
|
||||
const password: string = utils.randomString();
|
||||
|
||||
plays.usersCreate.exec({
|
||||
userName,
|
||||
password,
|
||||
email: `${userName}@owncloud.com`,
|
||||
credential: authFactory.credential,
|
||||
});
|
||||
|
||||
const userAuthFactory = new auth({ login: userName, password });
|
||||
|
||||
upDownDelete({ files, plays, credential: userAuthFactory.credential, account: userAuthFactory.account });
|
||||
|
||||
plays.usersDelete.exec({ userName: userName, credential: authFactory.credential });
|
||||
};
|
||||
@@ -1,22 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"moduleResolution": "node",
|
||||
"module": "commonjs",
|
||||
"noEmit": true,
|
||||
"allowJs": true,
|
||||
"removeComments": true,
|
||||
"strict": true,
|
||||
"noImplicitAny": true,
|
||||
"noImplicitThis": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"esModuleInterop": true,
|
||||
"experimentalDecorators": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"skipLibCheck": true
|
||||
}
|
||||
}
|
||||
-6660
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user