mirror of https://github.com/rancher/dartboard.git
Merge pull request #43 from git-ival/lastused-tokens-k6
Basic Lastused tokens k6 test
This commit is contained in:
commit
3f2aed0b86
|
|
@ -241,7 +241,7 @@ func K6run(kubeconfig, testPath string, envVars, tags map[string]string, printLo
|
|||
output = os.Stdout
|
||||
}
|
||||
|
||||
err = Exec(kubeconfig, output, "run", "k6", "--image="+k6Image, "--namespace=tester", "--rm", "--stdin", "--restart=Never", "--overrides="+string(overrideJSON))
|
||||
err = Exec(kubeconfig, output, "run", "k6", "--http-debug=full", "--image="+k6Image, "--namespace=tester", "--rm", "--stdin", "--restart=Never", "--overrides="+string(overrideJSON))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import exec from 'k6/execution';
|
|||
import http from 'k6/http';
|
||||
import {Gauge} from 'k6/metrics';
|
||||
import {getCookies, login} from "./rancher_utils.js";
|
||||
import {getPrincipalIds, getCurrentUserPrincipalId, getClusterIds} from "./rancher_users_utils.js"
|
||||
|
||||
// Parameters
|
||||
const projectCount = Number(__ENV.PROJECT_COUNT)
|
||||
|
|
@ -52,47 +53,12 @@ export function setup() {
|
|||
// return data that remains constant throughout the test
|
||||
return {
|
||||
cookies: cookies,
|
||||
principalIds: getPrincipalIds(cookies),
|
||||
myId: getMyId(cookies),
|
||||
clusterIds: getClusterIds(cookies)
|
||||
principalIds: getPrincipalIds(baseUrl, cookies),
|
||||
myId: getCurrentUserPrincipalId(baseUrl, cookies),
|
||||
clusterIds: getClusterIds(baseUrl, cookies)
|
||||
}
|
||||
}
|
||||
|
||||
function getPrincipalIds(cookies) {
|
||||
const response = http.get(
|
||||
`${baseUrl}/v1/management.cattle.io.users`,
|
||||
{cookies: cookies}
|
||||
)
|
||||
if (response.status !== 200) {
|
||||
fail('could not list users')
|
||||
}
|
||||
const users = JSON.parse(response.body).data
|
||||
return users.filter(u => u["username"] != null).map(u => u["principalIds"][0])
|
||||
}
|
||||
|
||||
function getMyId(cookies) {
|
||||
const response = http.get(
|
||||
`${baseUrl}/v3/users?me=true`,
|
||||
{cookies: cookies}
|
||||
)
|
||||
if (response.status !== 200) {
|
||||
fail('could not get my user')
|
||||
}
|
||||
return JSON.parse(response.body).data[0].principalIds[0]
|
||||
}
|
||||
|
||||
function getClusterIds(cookies) {
|
||||
const response = http.get(
|
||||
`${baseUrl}/v1/management.cattle.io.clusters`,
|
||||
{cookies: cookies}
|
||||
)
|
||||
if (response.status !== 200) {
|
||||
fail('could not list clusters')
|
||||
}
|
||||
const clusters = JSON.parse(response.body).data
|
||||
return clusters.map(c => c["id"])
|
||||
}
|
||||
|
||||
function cleanup(cookies) {
|
||||
let res = http.get(`${baseUrl}/v1/management.cattle.io.projects`, {cookies: cookies})
|
||||
check(res, {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
env_file=${1:-"./.env"} # path to the source-able .env file containing relevant variables
|
||||
test_file=${2} # path to the k6 test file to run
|
||||
iters=${3:-1} # the number of iterations of the test to loop through
|
||||
delay=${4:-15} # the delay between iterations, in minutes
|
||||
address=${5:-"localhost:6565"} # the domain:PORT address to the API server https://grafana.com/docs/k6/latest/using-k6/k6-options/reference/#address
|
||||
|
||||
counter=1
|
||||
sleepDuration=$((delay * 60))
|
||||
while [ ${counter} -le "${iters}" ]; do
|
||||
iterStart=$(date -u '+%FT%T%:z')
|
||||
echo "Started iteration at: ${iterStart}"
|
||||
# shellcheck disable=SC1090
|
||||
source "${env_file}" && k6 run -a "${address}" --out json="${test_file%.js*}-output${counter}.json" "${test_file}"
|
||||
kubectl -n cattle-system logs -l status.phase=Running -l app=rancher -c rancher --timestamps --since-time="${iterStart}" --tail=9999999 >"rancher_logs-test_${test_file%.js*}.txt"
|
||||
if [[ ${iters} -ge 2 ]]; then
|
||||
sleep ${sleepDuration}
|
||||
fi
|
||||
counter=$((counter + 1))
|
||||
done
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
import {getCookies, firstLogin, createImportedCluster, logout} from "./rancher_utils.js";
|
||||
|
||||
import {getCookies, createImportedCluster, firstLogin, logout} from "./rancher_utils.js";
|
||||
|
||||
export const options = {
|
||||
insecureSkipTLSVerify: true,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,149 @@
|
|||
import { check, fail, sleep } from 'k6'
|
||||
import http from 'k6/http'
|
||||
|
||||
export function getUserId(baseUrl, cookies) {
|
||||
let response = http.get(`${baseUrl}/v3/users?me=true`, {
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
},
|
||||
cookies: {cookies},
|
||||
})
|
||||
check(response, {
|
||||
'reading user details was successful': (r) => r.status === 200,
|
||||
})
|
||||
if (response.status !== 200) {
|
||||
fail('could not query user details')
|
||||
}
|
||||
|
||||
return JSON.parse(response.body).data[0].id
|
||||
}
|
||||
|
||||
export function getUserPreferences(baseUrl, cookies) {
|
||||
let response = http.get(`${baseUrl}/v1/userpreferences`, {
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
},
|
||||
cookies: {cookies},
|
||||
})
|
||||
check(response, {
|
||||
'preferences can be queried': (r) => r.status === 200,
|
||||
})
|
||||
return JSON.parse(response.body)["data"][0]
|
||||
}
|
||||
|
||||
export function setUserPreferences(baseUrl, cookies, userId, userPreferences) {
|
||||
let response = http.put(
|
||||
`${baseUrl}/v1/userpreferences/${userId}`,
|
||||
JSON.stringify(userPreferences),
|
||||
{
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
cookies: {cookies},
|
||||
}
|
||||
)
|
||||
check(response, {
|
||||
'preferences can be set': (r) => r.status === 200,
|
||||
})
|
||||
return response;
|
||||
}
|
||||
|
||||
export function getPrincipalIds(baseUrl, cookies) {
|
||||
const response = http.get(
|
||||
`${baseUrl}/v1/management.cattle.io.users`,
|
||||
{cookies: cookies}
|
||||
)
|
||||
if (response.status !== 200) {
|
||||
fail('could not list users')
|
||||
}
|
||||
const users = JSON.parse(response.body).data
|
||||
return users.filter(u => u["username"] != null).map(u => u["principalIds"][0])
|
||||
}
|
||||
|
||||
export function getPrincipalById(baseUrl, cookies, id) {
|
||||
const response = http.get(
|
||||
`${baseUrl}/v3/principals/${id}`,
|
||||
{cookies: cookies}
|
||||
)
|
||||
if (response.status !== 200) {
|
||||
fail('could not get principal by ID')
|
||||
}
|
||||
return JSON.parse(response.body).data[0]
|
||||
}
|
||||
|
||||
export function getUsers(baseUrl, params = null) {
|
||||
const response = http.get(`${baseUrl}/v3/users`, params);
|
||||
console.log("GET users status: ", response.status);
|
||||
check(response, {'status is 200': (r) => r.status === 200,}) || fail('could not get list of users');
|
||||
return JSON.parse(response.body)["data"];
|
||||
}
|
||||
|
||||
export function getCurrentUserPrincipal(baseUrl, cookies) {
|
||||
const response = http.get(
|
||||
`${baseUrl}/v3/principals?me=true`,
|
||||
{cookies: cookies}
|
||||
)
|
||||
if (response.status !== 200) {
|
||||
fail('could not get current User\'s Principal')
|
||||
}
|
||||
return JSON.parse(response.body).data[0]
|
||||
}
|
||||
|
||||
export function getCurrentUserId(baseUrl, cookies) {
|
||||
const response = http.get(
|
||||
`${baseUrl}/v3/users?me=true`,
|
||||
{cookies: cookies}
|
||||
)
|
||||
if (response.status !== 200) {
|
||||
fail('could not get my user')
|
||||
}
|
||||
return JSON.parse(response.body).data[0].id
|
||||
}
|
||||
|
||||
export function getCurrentUserPrincipalId(baseUrl, cookies) {
|
||||
const response = http.get(
|
||||
`${baseUrl}/v3/users?me=true`,
|
||||
{cookies: cookies}
|
||||
)
|
||||
if (response.status !== 200) {
|
||||
fail('could not get my user')
|
||||
}
|
||||
return JSON.parse(response.body).data[0].principalIds[0]
|
||||
}
|
||||
|
||||
export function getClusterIds(baseUrl, cookies) {
|
||||
const response = http.get(
|
||||
`${baseUrl}/v1/management.cattle.io.clusters`,
|
||||
{cookies: cookies}
|
||||
)
|
||||
if (response.status !== 200) {
|
||||
fail('could not list clusters')
|
||||
}
|
||||
const clusters = JSON.parse(response.body).data
|
||||
return clusters.map(c => c["id"])
|
||||
}
|
||||
|
||||
export function createUser(baseUrl, params = null, id) {
|
||||
const res = http.post(`${baseUrl}/v3/users`,
|
||||
JSON.stringify({
|
||||
"type": "user",
|
||||
"name": `Dartboard Test User ${id}`,
|
||||
"description": `Dartboard Test User ${id}`,
|
||||
"enabled": true,
|
||||
"mustChangePassword": false,
|
||||
"password": "useruseruser",
|
||||
"username": `user-${id}`
|
||||
}),
|
||||
params
|
||||
)
|
||||
|
||||
sleep(0.1)
|
||||
if (res.status != 201) {
|
||||
console.log("CREATE user failed:\n", JSON.stringify(res, null, 2))
|
||||
}
|
||||
check(res, {
|
||||
'/v3/users returns status 201': (r) => r.status === 201,
|
||||
})
|
||||
return JSON.parse(res.body)
|
||||
}
|
||||
|
|
@ -1,443 +1,419 @@
|
|||
import { check, fail, sleep } from 'k6'
|
||||
import http from 'k6/http'
|
||||
import { getUserId, getUserPreferences, setUserPreferences } from "./rancher_users_utils.js"
|
||||
import encoding from 'k6/encoding';
|
||||
|
||||
|
||||
export function getCookies(baseUrl) {
|
||||
const response = http.get(`${baseUrl}/`)
|
||||
return http.cookieJar().cookiesForURL(response.url)
|
||||
const response = http.get(`${baseUrl}/`)
|
||||
return http.cookieJar().cookiesForURL(response.url)
|
||||
}
|
||||
|
||||
export function login(baseUrl, cookies, username, password) {
|
||||
const response = http.post(
|
||||
`${baseUrl}/v3-public/localProviders/local?action=login`,
|
||||
JSON.stringify({"description": "UI session", "responseType": "cookie", "username":username, "password":password}),
|
||||
{
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
'content-type': 'application/json; charset=UTF-8',
|
||||
},
|
||||
cookies: {cookies},
|
||||
}
|
||||
)
|
||||
|
||||
check(response, {
|
||||
'login works': (r) => r.status === 200 || r.status === 401,
|
||||
})
|
||||
|
||||
return response.status === 200
|
||||
}
|
||||
|
||||
export function timestamp() {
|
||||
return new Date().toISOString()
|
||||
}
|
||||
|
||||
export function getUserId(baseUrl, cookies) {
|
||||
let response = http.get(`${baseUrl}/v3/users?me=true`, {
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
},
|
||||
cookies: {cookies},
|
||||
})
|
||||
check(response, {
|
||||
'reading user details was successful': (r) => r.status === 200,
|
||||
})
|
||||
if (response.status !== 200) {
|
||||
fail('could not query user details')
|
||||
const response = http.post(
|
||||
`${baseUrl}/v3-public/localProviders/local?action=login`,
|
||||
JSON.stringify({ "description": "UI session", "responseType": "cookie", "username": username, "password": password }),
|
||||
{
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
'content-type': 'application/json; charset=UTF-8',
|
||||
},
|
||||
cookies: { cookies },
|
||||
}
|
||||
)
|
||||
console.log("POST login: ", response.status);
|
||||
|
||||
return JSON.parse(response.body).data[0].id
|
||||
}
|
||||
check(response, {
|
||||
'login works': (r) => r.status === 200 || r.status === 401,
|
||||
})
|
||||
|
||||
export function getUserPreferences(baseUrl, cookies) {
|
||||
let response = http.get(`${baseUrl}/v1/userpreferences`, {
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
},
|
||||
cookies: {cookies},
|
||||
})
|
||||
check(response, {
|
||||
'preferences can be queried': (r) => r.status === 200,
|
||||
})
|
||||
return JSON.parse(response.body)["data"][0]
|
||||
}
|
||||
|
||||
export function setUserPreferences(baseUrl, cookies, userId, userPreferences) {
|
||||
let response = http.put(
|
||||
`${baseUrl}/v1/userpreferences/${userId}`,
|
||||
JSON.stringify(userPreferences),
|
||||
{
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
cookies: {cookies},
|
||||
}
|
||||
)
|
||||
check(response, {
|
||||
'preferences can be set': (r) => r.status === 200,
|
||||
})
|
||||
return response;
|
||||
return response.status === 200
|
||||
}
|
||||
|
||||
export function firstLogin(baseUrl, cookies, bootstrapPassword, password) {
|
||||
let response
|
||||
let response
|
||||
|
||||
if (login(baseUrl, cookies, "admin", bootstrapPassword)){
|
||||
response = http.post(
|
||||
`${baseUrl}/v3/users?action=changepassword`,
|
||||
JSON.stringify({"currentPassword":bootstrapPassword, "newPassword":password}),
|
||||
{
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
'content-type': 'application/json; charset=UTF-8',
|
||||
},
|
||||
cookies: {cookies},
|
||||
}
|
||||
)
|
||||
check(response, {
|
||||
'password can be changed': (r) => r.status === 200,
|
||||
})
|
||||
if (response.status !== 200) {
|
||||
fail('first password change was not successful')
|
||||
}
|
||||
}
|
||||
else {
|
||||
console.warn("bootstrap password already changed")
|
||||
if(!login(baseUrl, cookies, "admin", password)) {
|
||||
fail('neither bootstrap nor normal passwords were accepted')
|
||||
}
|
||||
}
|
||||
const userId = getUserId(baseUrl, cookies)
|
||||
const userPreferences = getUserPreferences(baseUrl, cookies);
|
||||
|
||||
userPreferences["data"]["locale"] = "en-us"
|
||||
setUserPreferences(baseUrl, cookies, userId, userPreferences);
|
||||
|
||||
response = http.get(
|
||||
`${baseUrl}/v1/management.cattle.io.settings`,
|
||||
{
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
},
|
||||
cookies: {cookies},
|
||||
}
|
||||
if (login(baseUrl, cookies, "admin", bootstrapPassword)) {
|
||||
response = http.post(
|
||||
`${baseUrl}/v3/users?action=changepassword`,
|
||||
JSON.stringify({ "currentPassword": bootstrapPassword, "newPassword": password }),
|
||||
{
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
'content-type': 'application/json; charset=UTF-8',
|
||||
},
|
||||
cookies: { cookies },
|
||||
}
|
||||
)
|
||||
check(response, {
|
||||
'Settings can be queried': (r) => r.status === 200,
|
||||
'password can be changed': (r) => r.status === 200,
|
||||
})
|
||||
const settings = JSON.parse(response.body)
|
||||
if (response.status !== 200) {
|
||||
fail('first password change was not successful')
|
||||
}
|
||||
}
|
||||
else {
|
||||
console.warn("bootstrap password already changed")
|
||||
if (!login(baseUrl, cookies, "admin", password)) {
|
||||
fail('neither bootstrap nor normal passwords were accepted')
|
||||
}
|
||||
}
|
||||
const userId = getUserId(baseUrl, cookies)
|
||||
const userPreferences = getUserPreferences(baseUrl, cookies);
|
||||
|
||||
const firstLoginSetting = settings.data.filter(d => d.id === "first-login")[0]
|
||||
if (firstLoginSetting === undefined) {
|
||||
response = http.post(
|
||||
`${baseUrl}/v1/management.cattle.io.settings`,
|
||||
JSON.stringify({"type":"management.cattle.io.setting","metadata":{"name":"first-login"},"value":"false"}),
|
||||
{
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
cookies: {cookies},
|
||||
}
|
||||
)
|
||||
check(response, {
|
||||
'First login setting can be set': (r) => r.status === 201,
|
||||
})
|
||||
}
|
||||
else {
|
||||
firstLoginSetting["value"] = "false"
|
||||
response = http.put(
|
||||
`${baseUrl}/v1/management.cattle.io.settings/first-login`,
|
||||
JSON.stringify(firstLoginSetting),
|
||||
{
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
cookies: {cookies},
|
||||
}
|
||||
)
|
||||
check(response, {
|
||||
'First login setting can be changed': (r) => r.status === 200,
|
||||
})
|
||||
}
|
||||
userPreferences["data"]["locale"] = "en-us"
|
||||
setUserPreferences(baseUrl, cookies, userId, userPreferences);
|
||||
|
||||
const eulaSetting = settings.data.filter(d => d.id === "eula-agreed")[0]
|
||||
if (eulaSetting === undefined) {
|
||||
response = http.post(
|
||||
`${baseUrl}/v1/management.cattle.io.settings`,
|
||||
JSON.stringify({"type":"management.cattle.io.setting","metadata":{"name":"eula-agreed"},"value":timestamp(),"default":timestamp()}),
|
||||
{
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
cookies: {cookies},
|
||||
}
|
||||
)
|
||||
check(response, {
|
||||
'EULA setting can be set': (r) => r.status === 201,
|
||||
})
|
||||
}
|
||||
else {
|
||||
eulaSetting["value"] = timestamp()
|
||||
response = http.put(
|
||||
`${baseUrl}/v1/management.cattle.io.settings/eula-agreed`,
|
||||
JSON.stringify(eulaSetting),
|
||||
{
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
cookies: {cookies},
|
||||
}
|
||||
)
|
||||
check(response, {
|
||||
'EULA setting can be changed': (r) => r.status === 200,
|
||||
})
|
||||
response = http.get(
|
||||
`${baseUrl}/v1/management.cattle.io.settings`,
|
||||
{
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
},
|
||||
cookies: { cookies },
|
||||
}
|
||||
)
|
||||
check(response, {
|
||||
'Settings can be queried': (r) => r.status === 200,
|
||||
})
|
||||
const settings = JSON.parse(response.body)
|
||||
|
||||
const telemetrySetting = settings.data.find(d => d.id === "telemetry-opt")
|
||||
if (telemetrySetting === undefined) {
|
||||
response = http.post(
|
||||
`${baseUrl}/v1/management.cattle.io.settings/telemetry-opt`,
|
||||
JSON.stringify({"type":"management.cattle.io.setting","metadata":{"name":"telemetry-opt", "value": "out"}}),
|
||||
{
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
cookies: {cookies},
|
||||
}
|
||||
)
|
||||
check(response, {
|
||||
'telemetry setting can be set': (r) => r.status === 201,
|
||||
})
|
||||
}
|
||||
else {
|
||||
telemetrySetting["value"] = "out"
|
||||
response = http.put(
|
||||
`${baseUrl}/v1/management.cattle.io.settings/telemetry-opt`,
|
||||
JSON.stringify(telemetrySetting),
|
||||
{
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
cookies: {cookies},
|
||||
}
|
||||
)
|
||||
check(response, {
|
||||
'telemetry setting can be changed': (r) => r.status === 200,
|
||||
})
|
||||
}
|
||||
const firstLoginSetting = settings.data.filter(d => d.id === "first-login")[0]
|
||||
if (firstLoginSetting === undefined) {
|
||||
response = http.post(
|
||||
`${baseUrl}/v1/management.cattle.io.settings`,
|
||||
JSON.stringify({ "type": "management.cattle.io.setting", "metadata": { "name": "first-login" }, "value": "false" }),
|
||||
{
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
cookies: { cookies },
|
||||
}
|
||||
)
|
||||
check(response, {
|
||||
'First login setting can be set': (r) => r.status === 201,
|
||||
})
|
||||
}
|
||||
else {
|
||||
firstLoginSetting["value"] = "false"
|
||||
response = http.put(
|
||||
`${baseUrl}/v1/management.cattle.io.settings/first-login`,
|
||||
JSON.stringify(firstLoginSetting),
|
||||
{
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
cookies: { cookies },
|
||||
}
|
||||
)
|
||||
check(response, {
|
||||
'First login setting can be changed': (r) => r.status === 200,
|
||||
})
|
||||
}
|
||||
|
||||
const eulaSetting = settings.data.filter(d => d.id === "eula-agreed")[0]
|
||||
if (eulaSetting === undefined) {
|
||||
response = http.post(
|
||||
`${baseUrl}/v1/management.cattle.io.settings`,
|
||||
JSON.stringify({ "type": "management.cattle.io.setting", "metadata": { "name": "eula-agreed" }, "value": timestamp(), "default": timestamp() }),
|
||||
{
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
cookies: { cookies },
|
||||
}
|
||||
)
|
||||
check(response, {
|
||||
'EULA setting can be set': (r) => r.status === 201,
|
||||
})
|
||||
}
|
||||
else {
|
||||
eulaSetting["value"] = timestamp()
|
||||
response = http.put(
|
||||
`${baseUrl}/v1/management.cattle.io.settings/eula-agreed`,
|
||||
JSON.stringify(eulaSetting),
|
||||
{
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
cookies: { cookies },
|
||||
}
|
||||
)
|
||||
check(response, {
|
||||
'EULA setting can be changed': (r) => r.status === 200,
|
||||
})
|
||||
}
|
||||
|
||||
const telemetrySetting = settings.data.find(d => d.id === "telemetry-opt")
|
||||
if (telemetrySetting === undefined) {
|
||||
response = http.post(
|
||||
`${baseUrl}/v1/management.cattle.io.settings/telemetry-opt`,
|
||||
JSON.stringify({ "type": "management.cattle.io.setting", "metadata": { "name": "telemetry-opt", "value": "out" } }),
|
||||
{
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
cookies: { cookies },
|
||||
}
|
||||
)
|
||||
check(response, {
|
||||
'telemetry setting can be set': (r) => r.status === 201,
|
||||
})
|
||||
}
|
||||
else {
|
||||
telemetrySetting["value"] = "out"
|
||||
response = http.put(
|
||||
`${baseUrl}/v1/management.cattle.io.settings/telemetry-opt`,
|
||||
JSON.stringify(telemetrySetting),
|
||||
{
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
cookies: { cookies },
|
||||
}
|
||||
)
|
||||
check(response, {
|
||||
'telemetry setting can be changed': (r) => r.status === 200,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export function Date(year, month, day) {
|
||||
if (typeof year !== "undefined" &&
|
||||
typeof month !== "undefined" &&
|
||||
typeof day !== "undefined"
|
||||
) return new Date(year, month, day)
|
||||
return new Date()
|
||||
}
|
||||
|
||||
export function timestamp() {
|
||||
return new Date().toISOString()
|
||||
}
|
||||
|
||||
export function addMinutes(date, minutes) {
|
||||
return new Date(date.getTime() + (minutes*60000));
|
||||
}
|
||||
|
||||
export function createImportedCluster(baseUrl, cookies, name) {
|
||||
let response
|
||||
let response
|
||||
|
||||
const userId = getUserId(baseUrl, cookies)
|
||||
const userPreferences = getUserPreferences(baseUrl, cookies);
|
||||
const userId = getUserId(baseUrl, cookies)
|
||||
const userPreferences = getUserPreferences(baseUrl, cookies);
|
||||
|
||||
userPreferences["last-visited"] = "{\"name\":\"c-cluster-product\",\"params\":{\"cluster\":\"_\",\"product\":\"manager\"}}"
|
||||
userPreferences["locale"] = "en-us"
|
||||
userPreferences["seen-whatsnew"] = "\"v2.7.1\""
|
||||
userPreferences["seen-cluster"] = "_"
|
||||
setUserPreferences(baseUrl, cookies, userId, userPreferences)
|
||||
userPreferences["last-visited"] = "{\"name\":\"c-cluster-product\",\"params\":{\"cluster\":\"_\",\"product\":\"manager\"}}"
|
||||
userPreferences["locale"] = "en-us"
|
||||
userPreferences["seen-whatsnew"] = "\"v2.7.1\""
|
||||
userPreferences["seen-cluster"] = "_"
|
||||
setUserPreferences(baseUrl, cookies, userId, userPreferences)
|
||||
|
||||
response = http.get(`${baseUrl}/v1/catalog.cattle.io.clusterrepos`, {
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
},
|
||||
cookies: cookies,
|
||||
})
|
||||
check(response, {
|
||||
'querying clusterrepos works': (r) => r.status === 200,
|
||||
})
|
||||
response = http.get(`${baseUrl}/v1/catalog.cattle.io.clusterrepos`, {
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
},
|
||||
cookies: cookies,
|
||||
})
|
||||
check(response, {
|
||||
'querying clusterrepos works': (r) => r.status === 200,
|
||||
})
|
||||
|
||||
response = http.get(`${baseUrl}/v1/management.cattle.io.kontainerdrivers`, {
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
cookies: cookies,
|
||||
},
|
||||
})
|
||||
check(response, {
|
||||
'querying kontainerdrivers works': (r) => r.status === 200,
|
||||
})
|
||||
response = http.get(`${baseUrl}/v1/management.cattle.io.kontainerdrivers`, {
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
cookies: cookies,
|
||||
},
|
||||
})
|
||||
check(response, {
|
||||
'querying kontainerdrivers works': (r) => r.status === 200,
|
||||
})
|
||||
|
||||
response = http.get(
|
||||
`${baseUrl}/v1/catalog.cattle.io.clusterrepos/rancher-charts?link=index`,
|
||||
{
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
},
|
||||
cookies: cookies,
|
||||
}
|
||||
)
|
||||
check(response, {
|
||||
'querying rancher-charts works': (r) => r.status === 200,
|
||||
})
|
||||
|
||||
response = http.get(
|
||||
`${baseUrl}/v1/catalog.cattle.io.clusterrepos/rancher-partner-charts?link=index`,
|
||||
{
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
},
|
||||
cookies: cookies,
|
||||
}
|
||||
)
|
||||
check(response, {
|
||||
'querying rancher-partners-charts works': (r) => r.status === 200,
|
||||
})
|
||||
|
||||
response = http.get(
|
||||
`${baseUrl}/v1/catalog.cattle.io.clusterrepos/rancher-rke2-charts?link=index`,
|
||||
{
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
},
|
||||
cookies: cookies,
|
||||
}
|
||||
)
|
||||
check(response, {
|
||||
'querying rancher-rke2-charts works': (r) => r.status === 200,
|
||||
})
|
||||
|
||||
response = http.get(`${baseUrl}/v3/clusterroletemplatebindings`, {
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
},
|
||||
cookies: cookies,
|
||||
})
|
||||
check(response, {
|
||||
'querying clusterroletemplatebindings works': (r) => r.status === 200,
|
||||
})
|
||||
|
||||
response = http.get(`${baseUrl}/v1/management.cattle.io.roletemplates`, {
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
},
|
||||
cookies: cookies,
|
||||
})
|
||||
check(response, {
|
||||
'querying roletemplates works': (r) => r.status === 200,
|
||||
})
|
||||
|
||||
response = http.post(
|
||||
`${baseUrl}/v1/provisioning.cattle.io.clusters`,
|
||||
JSON.stringify({"type":"provisioning.cattle.io.cluster","metadata":{"namespace":"fleet-default","name":name},"spec":{}}),
|
||||
{
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
cookies: cookies,
|
||||
}
|
||||
)
|
||||
|
||||
check(response, {
|
||||
'creating an imported cluster works': (r) => r.status === 201 || r.status === 409,
|
||||
})
|
||||
if (response.status === 409) {
|
||||
console.warn(`cluster ${name} already exists`)
|
||||
response = http.get(
|
||||
`${baseUrl}/v1/catalog.cattle.io.clusterrepos/rancher-charts?link=index`,
|
||||
{
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
},
|
||||
cookies: cookies,
|
||||
}
|
||||
)
|
||||
check(response, {
|
||||
'querying rancher-charts works': (r) => r.status === 200,
|
||||
})
|
||||
|
||||
response = http.get(
|
||||
`${baseUrl}/v1/provisioning.cattle.io.clusters/fleet-default/${name}`,
|
||||
{
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
},
|
||||
cookies: cookies,
|
||||
}
|
||||
)
|
||||
check(response, {
|
||||
'querying clusters works': (r) => r.status === 200,
|
||||
})
|
||||
if (!response.status === 200) {
|
||||
fail(`cluster ${name} not found`)
|
||||
response = http.get(
|
||||
`${baseUrl}/v1/catalog.cattle.io.clusterrepos/rancher-partner-charts?link=index`,
|
||||
{
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
},
|
||||
cookies: cookies,
|
||||
}
|
||||
)
|
||||
check(response, {
|
||||
'querying rancher-partners-charts works': (r) => r.status === 200,
|
||||
})
|
||||
|
||||
response = http.get(`${baseUrl}/v1/cluster.x-k8s.io.machinedeployments`, {
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
},
|
||||
cookies: cookies,
|
||||
})
|
||||
check(response, {
|
||||
'querying machinedeployments works': (r) => r.status === 200,
|
||||
})
|
||||
response = http.get(
|
||||
`${baseUrl}/v1/catalog.cattle.io.clusterrepos/rancher-rke2-charts?link=index`,
|
||||
{
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
},
|
||||
cookies: cookies,
|
||||
}
|
||||
)
|
||||
check(response, {
|
||||
'querying rancher-rke2-charts works': (r) => r.status === 200,
|
||||
})
|
||||
|
||||
response = http.get(`${baseUrl}/v1/rke.cattle.io.etcdsnapshots`, {
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
},
|
||||
cookies: cookies,
|
||||
})
|
||||
check(response, {
|
||||
'querying etcdsnapshots works': (r) => r.status === 200,
|
||||
})
|
||||
response = http.get(`${baseUrl}/v3/clusterroletemplatebindings`, {
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
},
|
||||
cookies: cookies,
|
||||
})
|
||||
check(response, {
|
||||
'querying clusterroletemplatebindings works': (r) => r.status === 200,
|
||||
})
|
||||
|
||||
response = http.get(`${baseUrl}/v1/management.cattle.io.nodetemplates`, {
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
},
|
||||
cookies: cookies,
|
||||
})
|
||||
check(response, {
|
||||
'querying nodetemplates works': (r) => r.status === 200,
|
||||
})
|
||||
response = http.get(`${baseUrl}/v1/management.cattle.io.roletemplates`, {
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
},
|
||||
cookies: cookies,
|
||||
})
|
||||
check(response, {
|
||||
'querying roletemplates works': (r) => r.status === 200,
|
||||
})
|
||||
|
||||
response = http.get(`${baseUrl}/v1/management.cattle.io.clustertemplates`, {
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
},
|
||||
cookies: cookies,
|
||||
})
|
||||
check(response, {
|
||||
'querying clustertemplates works': (r) => r.status === 200,
|
||||
})
|
||||
response = http.post(
|
||||
`${baseUrl}/v1/provisioning.cattle.io.clusters`,
|
||||
JSON.stringify({ "type": "provisioning.cattle.io.cluster", "metadata": { "namespace": "fleet-default", "name": name }, "spec": {} }),
|
||||
{
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
cookies: cookies,
|
||||
}
|
||||
)
|
||||
|
||||
response = http.get(
|
||||
`${baseUrl}/v1/management.cattle.io.clustertemplaterevisions`,
|
||||
{
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
},
|
||||
cookies: cookies,
|
||||
}
|
||||
)
|
||||
check(response, {
|
||||
'querying clustertemplaterevisions works': (r) => r.status === 200,
|
||||
})
|
||||
check(response, {
|
||||
'creating an imported cluster works': (r) => r.status === 201 || r.status === 409,
|
||||
})
|
||||
if (response.status === 409) {
|
||||
console.warn(`cluster ${name} already exists`)
|
||||
}
|
||||
|
||||
response = http.get(
|
||||
`${baseUrl}/v1/provisioning.cattle.io.clusters/fleet-default/${name}`,
|
||||
{
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
},
|
||||
cookies: cookies,
|
||||
}
|
||||
)
|
||||
check(response, {
|
||||
'querying clusters works': (r) => r.status === 200,
|
||||
})
|
||||
if (!response.status === 200) {
|
||||
fail(`cluster ${name} not found`)
|
||||
}
|
||||
|
||||
response = http.get(`${baseUrl}/v1/cluster.x-k8s.io.machinedeployments`, {
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
},
|
||||
cookies: cookies,
|
||||
})
|
||||
check(response, {
|
||||
'querying machinedeployments works': (r) => r.status === 200,
|
||||
})
|
||||
|
||||
response = http.get(`${baseUrl}/v1/rke.cattle.io.etcdsnapshots`, {
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
},
|
||||
cookies: cookies,
|
||||
})
|
||||
check(response, {
|
||||
'querying etcdsnapshots works': (r) => r.status === 200,
|
||||
})
|
||||
|
||||
response = http.get(`${baseUrl}/v1/management.cattle.io.nodetemplates`, {
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
},
|
||||
cookies: cookies,
|
||||
})
|
||||
check(response, {
|
||||
'querying nodetemplates works': (r) => r.status === 200,
|
||||
})
|
||||
|
||||
response = http.get(`${baseUrl}/v1/management.cattle.io.clustertemplates`, {
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
},
|
||||
cookies: cookies,
|
||||
})
|
||||
check(response, {
|
||||
'querying clustertemplates works': (r) => r.status === 200,
|
||||
})
|
||||
|
||||
response = http.get(
|
||||
`${baseUrl}/v1/management.cattle.io.clustertemplaterevisions`,
|
||||
{
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
},
|
||||
cookies: cookies,
|
||||
}
|
||||
)
|
||||
check(response, {
|
||||
'querying clustertemplaterevisions works': (r) => r.status === 200,
|
||||
})
|
||||
}
|
||||
|
||||
export function logout(baseUrl, cookies) {
|
||||
const response = http.post(`${baseUrl}/v3/tokens?action=logout`, '{}', {
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
cookies: cookies
|
||||
})
|
||||
const response = http.post(`${baseUrl}/v3/tokens?action=logout`, '{}', {
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
cookies: cookies
|
||||
})
|
||||
|
||||
check(response, {
|
||||
'logging out works': (r) => r.status === 200,
|
||||
})
|
||||
check(response, {
|
||||
'logging out works': (r) => r.status === 200,
|
||||
})
|
||||
}
|
||||
|
||||
export function generateAuthorizationHeader(token) {
|
||||
return {
|
||||
headers: {
|
||||
'Authorization': `Basic ${encoding.b64encode(token)}`,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Retries result-returning function for up to 10 times
|
||||
// until a non-409 status is returned, waiting for up to 1s
|
||||
// between retries
|
||||
export function retryOnConflict(f) {
|
||||
for (let i = 0; i < 9; i++) {
|
||||
const res = f()
|
||||
if (res.status !== 409) {
|
||||
return res
|
||||
}
|
||||
// expected conflict. Sleep a bit and retry
|
||||
sleep(Math.random())
|
||||
for (let i = 0; i < 9; i++) {
|
||||
const res = f()
|
||||
if (res.status !== 409) {
|
||||
return res
|
||||
}
|
||||
// all previous attempts failed, try one last time
|
||||
return f()
|
||||
// expected conflict. Sleep a bit and retry
|
||||
sleep(Math.random())
|
||||
}
|
||||
// all previous attempts failed, try one last time
|
||||
return f()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,202 @@
|
|||
import { check, fail, sleep } from 'k6';
|
||||
import exec from 'k6/execution';
|
||||
import http from 'k6/http';
|
||||
import { getCookies, login, generateAuthorizationHeader, addMinutes } from "./rancher_utils.js";
|
||||
import { getPrincipalIds, getCurrentUserId, getClusterIds, getCurrentUserPrincipal, createUser } from "./rancher_users_utils.js"
|
||||
|
||||
|
||||
// Parameters
|
||||
const tokenCount = Number(__ENV.TOKEN_COUNT)
|
||||
const vus = Number(__ENV.K6_VUS) || 1
|
||||
const perVuIterations = __ENV.PER_VU_ITERATIONS
|
||||
|
||||
|
||||
// Option setting
|
||||
const baseUrl = __ENV.BASE_URL
|
||||
const username = __ENV.USERNAME
|
||||
const password = __ENV.PASSWORD
|
||||
|
||||
// Option setting
|
||||
export const options = {
|
||||
insecureSkipTLSVerify: true,
|
||||
|
||||
setupTimeout: '8h',
|
||||
|
||||
scenarios: {
|
||||
useTokens: {
|
||||
executor: 'shared-iterations',
|
||||
exec: 'useTokens',
|
||||
vus: vus,
|
||||
iterations: perVuIterations,
|
||||
maxDuration: '1h',
|
||||
},
|
||||
},
|
||||
// thresholds: {
|
||||
// checks: ['rate>0.99']
|
||||
// }
|
||||
thresholds: {
|
||||
http_req_failed: ['rate<=0.01'], // http errors should be less than 1%
|
||||
http_req_duration: ['p(99)<=500'], // 95% of requests should be below 500ms
|
||||
checks: ['rate>0.99'], // the rate of successful checks should be higher than 99%
|
||||
}
|
||||
}
|
||||
|
||||
export function setup() {
|
||||
// log in
|
||||
if (!login(baseUrl, {}, username, password)) {
|
||||
fail(`could not login into cluster`)
|
||||
}
|
||||
const cookies = getCookies(baseUrl)
|
||||
|
||||
// delete leftovers, if any
|
||||
cleanup(cookies)
|
||||
|
||||
// return data that remains constant throughout the test
|
||||
let data = {
|
||||
cookies: cookies,
|
||||
principalIds: getPrincipalIds(baseUrl, cookies),
|
||||
myUserId: getCurrentUserId(baseUrl, cookies),
|
||||
myUserPrincipal: getCurrentUserPrincipal(baseUrl, cookies),
|
||||
clusterIds: getClusterIds(baseUrl, cookies),
|
||||
fullTokens: []
|
||||
}
|
||||
let createdTokens = []
|
||||
for (let i = 0; i < tokenCount; i++) {
|
||||
createdTokens.push(createToken(baseUrl, data, i))
|
||||
}
|
||||
|
||||
createdTokens.forEach(r => {
|
||||
data["fullTokens"].push(r)
|
||||
})
|
||||
return data
|
||||
}
|
||||
|
||||
export function daysToMilliseconds(days) {
|
||||
return days * 24 * 60 * 60 * 1000;
|
||||
}
|
||||
|
||||
function createToken(baseUrl, data, idx) {
|
||||
const clusterId = data.clusterIds[idx % data.clusterIds.length]
|
||||
const id = `dartboard-${idx}`
|
||||
const ttl = daysToMilliseconds(90) // Default ttl from UI is 90 days, but the API uses milliseconds
|
||||
|
||||
const body = {
|
||||
// "clusterId": clusterId,
|
||||
// "current": false,
|
||||
"description": `Dartboard test token ${id}`,
|
||||
// "enabled": true,
|
||||
// "expired": false,
|
||||
// "isDerived": true,
|
||||
// "userId": data.myUserId,
|
||||
// "userPrincipal": data.myUserPrincipal.id,
|
||||
"metadata": {},
|
||||
"ttl": ttl,
|
||||
"type": "token",
|
||||
}
|
||||
|
||||
const res = http.post(
|
||||
`${baseUrl}/v3/tokens`,
|
||||
JSON.stringify(body),
|
||||
{ cookies: data.cookies }
|
||||
)
|
||||
|
||||
let token = JSON.parse(res.body)
|
||||
|
||||
check(res, {
|
||||
'POST v3/tokens returns status 201': (r) => r.status === 201,
|
||||
})
|
||||
|
||||
return JSON.parse(res.body)
|
||||
}
|
||||
|
||||
export function deleteTokens(data) {
|
||||
let tokensData = getTokens(baseUrl, data)
|
||||
tokensData.filter(r => ("description" in r) && r["description"].startsWith("Dartboard test")).forEach(r => {
|
||||
let res = http.del(`${baseUrl}/v3/tokens/${r["id"]}`, { cookies: data.cookies })
|
||||
check(res, {
|
||||
'DELETE /v3/tokens returns status 200': (r) => r.status === 200 || r.status === 204,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export function getTokens(data) {
|
||||
let res = http.get(`${baseUrl}/v3/tokens`, { cookies: data.cookies })
|
||||
check(res, {
|
||||
'GET /v3/tokens returns status 200': (r) => r.status === 200 || r.status === 204,
|
||||
})
|
||||
return JSON.parse(res.body)["data"]
|
||||
}
|
||||
|
||||
export function getTokensByClusterID(data, clusterId) {
|
||||
const clusterIdParam = `?clusterId=${clusterId}`
|
||||
const checkString = `GET /v3/tokens${clusterIdParam} returns status 200`
|
||||
let res = http.get(`${baseUrl}/v3/tokens${clusterIdParam}`, { cookies: data.cookies })
|
||||
check(res, {
|
||||
checkString: (r) => r.status === 200 || r.status === 204,
|
||||
})
|
||||
}
|
||||
|
||||
function getUsers(baseUrl, params) {
|
||||
let res = http.get(`${baseUrl}/v3/users`, params);
|
||||
check(res, { 'GET users returns status 200': (r) => r.status === 200, });
|
||||
return res;
|
||||
}
|
||||
|
||||
function useToken(baseUrl, bearerToken) {
|
||||
let params = {
|
||||
insecureSkipTLSVerify: true,
|
||||
...generateAuthorizationHeader(bearerToken)
|
||||
};
|
||||
let res = getUsers(baseUrl, params)
|
||||
check(res, { 'auth with bearer token': (r) => r.status === 200, });
|
||||
return res, params
|
||||
}
|
||||
|
||||
export function useTokens(data) {
|
||||
let tokensData = getTokens(data);
|
||||
let tokens = tokensData.filter(r => ("description" in r) && r["description"].startsWith("Dartboard test"));
|
||||
let lastUsedAtTS = {};
|
||||
// Use the tokens for the first time
|
||||
tokens.forEach(token => {
|
||||
let bearerToken = data["fullTokens"].find(f => token.id == f.id).token;
|
||||
useToken(baseUrl, bearerToken)
|
||||
});
|
||||
tokensData = getTokens(data);
|
||||
tokens = tokensData.filter(r => ("description" in r) && r["description"].startsWith("Dartboard test"));
|
||||
|
||||
// Track lastUsedAtTS for each token
|
||||
tokens.forEach(token => {
|
||||
// Make sure we're storing a valid number
|
||||
const timestamp = Number(token.lastUsedAtTS);
|
||||
if (isNaN(timestamp)) {
|
||||
console.error(`Invalid timestamp for token ${token.id}:`, token.lastUsedAtTS);
|
||||
};
|
||||
lastUsedAtTS[token.id] = timestamp;
|
||||
});
|
||||
|
||||
// Utilize each token and verify that lastUsedAtTS is updated to a newer timestamp
|
||||
tokens.forEach(token => {
|
||||
let bearerToken = data["fullTokens"].find(f => token.id == f.id).token;
|
||||
let _, params = useToken(baseUrl, bearerToken)
|
||||
createUser(baseUrl, params, `${token.id}-${exec.scenario.iterationInTest}`);
|
||||
});
|
||||
|
||||
tokensData = getTokens(data);
|
||||
tokens = tokensData.filter(r => ("description" in r) && r["description"].startsWith("Dartboard test"));
|
||||
check(true, {
|
||||
'all tokens lastUsedAtTS are newer after utilizing them': () =>
|
||||
tokens.every(r => r.lastUsedAtTS > lastUsedAtTS[r.id])
|
||||
});
|
||||
}
|
||||
|
||||
function cleanup(data) {
|
||||
deleteTokens(data);
|
||||
let res = getUsers(baseUrl, { cookies: data.cookies });
|
||||
let users = JSON.parse(res.body)["data"];
|
||||
users.filter(r => r["description"].startsWith("Dartboard Test User ")).forEach(r => {
|
||||
let res = http.del(`${baseUrl}/v3/users/${r["id"]}`, { cookies: data.cookies });
|
||||
check(res, {
|
||||
'DELETE /v3/users returns status 200': (r) => r.status === 200 || r.status === 204,
|
||||
});
|
||||
})
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
terraform {
|
||||
required_version = "1.8.2"
|
||||
required_version = ">= 1.8.1"
|
||||
required_providers {
|
||||
aws = {
|
||||
source = "hashicorp/aws"
|
||||
|
|
|
|||
Loading…
Reference in New Issue