diff --git a/packages/k6-tdk/src/client/resource.ts b/packages/k6-tdk/src/client/resource.ts index e5ce636..fc97885 100644 --- a/packages/k6-tdk/src/client/resource.ts +++ b/packages/k6-tdk/src/client/resource.ts @@ -29,7 +29,7 @@ export class Resource extends EndpointClient { return response } - deleteResource(p: { resourcePath: string, root: string }): RefinedResponse<'none'> { + deleteResource(p: { resourcePath: string, root: string }, v?: {allowStatus?: Array}): RefinedResponse<'none'> { let response: RefinedResponse<'none'> switch (this.platform) { case Platform.ownCloudServer: @@ -43,7 +43,7 @@ export class Resource extends EndpointClient { check({val: response}, { 'client -> resource.deleteResource - status': ({status}) => { - return status === 204 + return [204, ...(v?.allowStatus || [])].includes(status) } }) @@ -97,7 +97,7 @@ export class Resource extends EndpointClient { return response } - uploadResource(p: { resourcePath: string, root: string, resourceBytes: RequestBody }): RefinedResponse<'none'> { + uploadResource(p: { resourcePath: string, root: string, resourceBytes: RequestBody }, v?: {allowStatus?: Array}): RefinedResponse<'none'> { let response: RefinedResponse<'none'> switch (this.platform) { @@ -112,7 +112,7 @@ export class Resource extends EndpointClient { check({val: response}, { 'client -> resource.uploadResource - status': ({status}) => { - return status === 201 + return [201, 204, ...(v?.allowStatus || [])].includes(status) } }) diff --git a/packages/k6-tests/tests/oc/upload-same-file-same-user/default.k6.ts b/packages/k6-tests/tests/oc/upload-same-file-same-user/default.k6.ts new file mode 100644 index 0000000..cfe91ed --- /dev/null +++ b/packages/k6-tests/tests/oc/upload-same-file-same-user/default.k6.ts @@ -0,0 +1,86 @@ +import {ENV, queryJson, store} from '@opencloud-eu/k6-tdk/lib/utils' +import {Options} from 'k6/options' + +import {clientFor} from '@/shortcuts' +import {envValues} from '@/values' +import exec from 'k6/execution' + +/**/ +export const settings = { + ...envValues(), + testFile: ENV('TEST_FILE', 'test-file.txt'), + user: { + login: ENV('USER_LOGIN', 'admin'), + password: ENV('USER_PASSWORD', 'admin') + }, +} + +/**/ +export const options: Options = { + vus: 1, + iterations: 1, + insecureSkipTLSVerify: true +} + + +async function getShared() { + // the test should upload the same file with the same user all the time, + // even across vu's + const user = { + userLogin: settings.user.login, + userPassword: settings.user.password + } + const userStore = store(user.userLogin) + const client = await userStore.setOrGet('client', async () => { + return clientFor(user) + }) + const root = await userStore.setOrGet('root', async () => { + const getMyDrivesResponse = await client.me.getMyDrives({params: {$filter: "driveType eq 'personal'"}}) + const [actorRoot = user.userLogin] = queryJson("$.value[?(@.driveType === 'personal')].id", getMyDrivesResponse?.body) + + return actorRoot + }) + + return {client, root} +} + +async function cleanup() { + const {root, client} = await getShared() + client.resource.deleteResource( + {root, resourcePath: settings.testFile}, + { + allowStatus: [ + 204, + 425, // depending on the load, the resource may still be in post-processing + 404, // depending on the state, the resource may not exist + ] + }, + ) +} + +export async function setup() { + await cleanup() +} + +export default async function actor() { + const {root, client} = await getShared() + + client.resource.uploadResource( + { + root, + resourcePath: settings.testFile, + resourceBytes: `${exec.vu.idInTest}-${exec.scenario.iterationInInstance}` + }, + { + allowStatus: [ + 201, + 204, + 412, // if a file is new, oc does not allow creating revisions before pp is finished + ] + }, + ) +} + +export async function teardown() { + await cleanup() +}