From c76ce23c07d1ca43ce0c4f45beb7b47285beb3f0 Mon Sep 17 00:00:00 2001 From: Oksana Grishchenko <91597950+oksana-grishchenko@users.noreply.github.com> Date: Fri, 9 Feb 2024 13:24:54 +0200 Subject: [PATCH 1/2] Update api/validation.go Co-authored-by: Diogo Recharte --- api/validation.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/validation.go b/api/validation.go index fb804204..e7e38d71 100644 --- a/api/validation.go +++ b/api/validation.go @@ -83,8 +83,8 @@ var ( errDataSourceNoPath = errors.New("'path' should be specified in .Spec.DataSource.BackupSource") errIncorrectDataSourceStruct = errors.New("incorrect data source struct") errUnsupportedPitrType = errors.New("the given point-in-time recovery type is not supported") - errTooManyPGSchedules = fmt.Errorf("only %d schedules are allowed", pgReposLimit) - errTooManyPGStorages = fmt.Errorf("only %d different storages are allowed to use for a postgres cluster", pgReposLimit) + errTooManyPGSchedules = fmt.Errorf("only %d schedules are allowed in a PostgreSQL cluster", pgReposLimit) + errTooManyPGStorages = fmt.Errorf("only %d different storages are allowed in a PostgreSQL cluster", pgReposLimit) //nolint:gochecknoglobals operatorEngine = map[everestv1alpha1.EngineType]string{ From d656d3c1a5ada5efcf500d4dca24a204decf276f Mon Sep 17 00:00:00 2001 From: Oksana Grishchenko <91597950+oksana-grishchenko@users.noreply.github.com> Date: Sat, 10 Feb 2024 01:43:07 +0200 Subject: [PATCH 2/2] EVEREST-107 update api-tests for multinamespace (#431) --- .github/workflows/ci.yml | 16 - api-tests/tests/auth.spec.ts | 6 +- api-tests/tests/backup-storages.spec.ts | 513 +++++++++--------- .../tests/database-cluster-backups.spec.ts | 21 +- .../tests/database-cluster-restores.spec.ts | 31 +- api-tests/tests/database-cluster.spec.ts | 64 +-- api-tests/tests/database-engines.spec.ts | 17 +- api-tests/tests/helpers.ts | 40 +- api-tests/tests/kubernetes.spec.ts | 38 +- api-tests/tests/monitoring-instances.spec.ts | 51 +- api-tests/tests/pg-clusters.spec.ts | 53 +- api-tests/tests/psmdb-clusters.spec.ts | 69 +-- api-tests/tests/pxc-clusters.spec.ts | 57 +- api-tests/tests/version.spec.ts | 3 +- api/everest_test.go | 8 +- api/monitoring_instance.go | 2 +- 16 files changed, 489 insertions(+), 500 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 15bd6367..692193ba 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -366,22 +366,6 @@ jobs: # API_TOKEN is used later by "make test" echo "API_TOKEN=$(./bin/everest token reset --json | jq .token -r)" >> $GITHUB_ENV - - name: Provision monitoring - shell: bash - continue-on-error: true - run: | - cd percona-everest-cli - - while true; do kubectl port-forward -n everest-system deployment/percona-everest 8080:8080; done & - - sleep 2 - - ./bin/everest monitoring enable \ - --everest-url http://127.0.0.1:8080 \ - --everest-token $API_TOKEN \ - --instance-name pmm-local \ - --skip-wizard - - name: Patch Everest Deployment to use the PR image run: | diff --git a/api-tests/tests/auth.spec.ts b/api-tests/tests/auth.spec.ts index c618d154..73f77374 100644 --- a/api-tests/tests/auth.spec.ts +++ b/api-tests/tests/auth.spec.ts @@ -13,6 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. import { expect, test } from '@fixtures' +import {checkError} from "@tests/tests/helpers"; test('auth header fails with invalid token', async ({ request }) => { const version = await request.get('/v1/version', { @@ -30,7 +31,8 @@ test('auth header is preferred over cookie', async ({ browser }) => { const request = ctx.request const version = await request.get('/v1/version') - expect(version.ok()).toBeTruthy() + await checkError(version) + }) test.describe('no authorization header', () => { @@ -67,6 +69,6 @@ test.describe('no authorization header', () => { const request = ctx.request const version = await request.get('/v1/version') - expect(version.ok()).toBeTruthy() + await checkError(version) }) }) diff --git a/api-tests/tests/backup-storages.spec.ts b/api-tests/tests/backup-storages.spec.ts index d1df5bfe..d1efa6f2 100644 --- a/api-tests/tests/backup-storages.spec.ts +++ b/api-tests/tests/backup-storages.spec.ts @@ -12,294 +12,303 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. -import { expect, test } from '@fixtures' - -test('add/list/get/delete s3 backup storage success', async ({ request }) => { - const payload = { - type: 's3', - name: 'backup-storage-1', - url: 'http://custom-url', - description: 'Dev storage', - bucketName: 'percona-test-backup-storage', - region: 'us-east-2', - accessKey: 'sdfs', - secretKey: 'sdfsdfsd', - } - - const response = await request.post('/v1/backup-storages', { - data: payload, - }) - - // create - expect(response.ok()).toBeTruthy() - const created = await response.json() - - const name = created.name - - expect(created.name).toBe(payload.name) - expect(created.url).toBe(payload.url) - expect(created.bucketName).toBe(payload.bucketName) - expect(created.region).toBe(payload.region) - expect(created.type).toBe(payload.type) - expect(created.description).toBe(payload.description) - - // list - const listResponse = await request.get('/v1/backup-storages') - - expect(listResponse.ok()).toBeTruthy() - const list = await listResponse.json() - - expect(list.length).toBeGreaterThan(0) - - // get - const one = await request.get(`/v1/backup-storages/${name}`) - - expect(one.ok()).toBeTruthy() - expect((await one.json()).name).toBe(payload.name) - - // update - const updatePayload = { - description: 'some description', - bucketName: 'percona-test-backup-storage1', - accessKey: 'otherAccessKey', - secretKey: 'otherSecret', - } - const updated = await request.patch(`/v1/backup-storages/${name}`, { - data: updatePayload, - }) - - expect(updated.ok()).toBeTruthy() - const result = await updated.json() - - expect(result.bucketName).toBe(updatePayload.bucketName) - expect(result.region).toBe(created.region) - expect(result.type).toBe(created.type) - expect(result.description).toBe(updatePayload.description) - - // backup storage already exists - const createAgain = await request.post('/v1/backup-storages', { - data: payload, - }) - - expect(createAgain.status()).toBe(409) - - // delete - const deleted = await request.delete(`/v1/backup-storages/${name}`) - - expect(deleted.ok()).toBeTruthy() -}) +import {expect, test} from '@fixtures' +import {checkError, testsNs, testPrefix} from './helpers' -test('add/list/get/delete azure backup storage success', async ({ request }) => { - const payload = { - type: 'azure', - name: 'backup-storage-azure', - description: 'Dev storage', - bucketName: 'percona-test-backup-storage', - accessKey: 'sdfs', - secretKey: 'sdfsdfsd', - } +test('add/list/get/delete s3 backup storage success', async ({request}) => { + const payload = { + type: 's3', + name: `${testPrefix}-backup-storage`, + url: 'http://custom-url', + description: 'Dev storage', + bucketName: 'percona-test-backup-storage', + region: 'us-east-2', + accessKey: 'sdfs', + secretKey: 'sdfsdfsd', + targetNamespaces: [testsNs] + } - const response = await request.post('/v1/backup-storages', { - data: payload, - }) + const response = await request.post(`/v1/backup-storages`, { + data: payload, + }) - // create - expect(response.ok()).toBeTruthy() - const created = await response.json() + // create + await checkError(response) + const created = await response.json() - const name = created.name + const name = created.name - expect(created.name).toBe(payload.name) - expect(created.bucketName).toBe(payload.bucketName) - expect(created.type).toBe(payload.type) - expect(created.description).toBe(payload.description) + expect(created.name).toBe(payload.name) + expect(created.url).toBe(payload.url) + expect(created.bucketName).toBe(payload.bucketName) + expect(created.region).toBe(payload.region) + expect(created.type).toBe(payload.type) + expect(created.description).toBe(payload.description) - // list - const listResponse = await request.get('/v1/backup-storages') + // list + const listResponse = await request.get(`/v1/backup-storages`) - expect(listResponse.ok()).toBeTruthy() - const list = await listResponse.json() + await checkError(listResponse) + const list = await listResponse.json() - expect(list.length).toBeGreaterThan(0) + expect(list.length).toBeGreaterThan(0) - // get - const one = await request.get(`/v1/backup-storages/${name}`) + // get + const one = await request.get(`/v1/backup-storages/${name}`) - expect(one.ok()).toBeTruthy() - expect((await one.json()).name).toBe(payload.name) + await checkError(one) + expect((await one.json()).name).toBe(payload.name) - // update - const updatePayload = { - description: 'some description', - bucketName: 'percona-test-backup-storage1', - } - const updated = await request.patch(`/v1/backup-storages/${name}`, { - data: updatePayload, - }) + // update + const updatePayload = { + description: 'some description', + bucketName: 'percona-test-backup-storage1', + accessKey: 'otherAccessKey', + secretKey: 'otherSecret', + targetNamespaces: [testsNs] + } + const updated = await request.patch(`/v1/backup-storages/${name}`, { + data: updatePayload, + }) - expect(updated.ok()).toBeTruthy() - const result = await updated.json() + await checkError(updated) + const result = await updated.json() - expect(result.bucketName).toBe(updatePayload.bucketName) - expect(result.region).toBe(created.region) - expect(result.type).toBe(created.type) - expect(result.description).toBe(updatePayload.description) + expect(result.bucketName).toBe(updatePayload.bucketName) + expect(result.region).toBe(created.region) + expect(result.type).toBe(created.type) + expect(result.description).toBe(updatePayload.description) - // backup storage already exists - const createAgain = await request.post('/v1/backup-storages', { - data: payload, - }) + // backup storage already exists + const createAgain = await request.post(`/v1/backup-storages`, { + data: payload, + }) - expect(createAgain.status()).toBe(409) + expect(createAgain.status()).toBe(409) - // delete - const deleted = await request.delete(`/v1/backup-storages/${name}`) + // delete + const deleted = await request.delete(`/v1/backup-storages/${name}`) - expect(deleted.ok()).toBeTruthy() + await checkError(deleted) }) -test('create backup storage failures', async ({ request }) => { - const testCases = [ - { - payload: {}, - errorText: 'property \"name\" is missing', - }, - { - payload: { - type: 's3', - name: 'backup-storage', - bucketName: 'percona-test-backup-storage', - region: 'us-east-2', - accessKey: 'ssdssd', - }, - errorText: 'property \"secretKey\" is missing', - }, - { - payload: { - type: 's3', - name: 'Backup Name', +test('add/list/get/delete azure backup storage success', async ({request}) => { + const payload = { + type: 'azure', + name: 'backup-storage-azure', + description: 'Dev storage', bucketName: 'percona-test-backup-storage', - region: 'us-east-2', - accessKey: 'ssdssd', - secretKey: 'ssdssdssdssd', - }, - errorText: '\'name\' is not RFC 1035 compatible', - }, - { - payload: { - type: 's3', - name: 'backup', - bucketName: 'percona-test-backup-storage', - url: 'not-valid-url', - region: 'us-east-2', - accessKey: 'ssdssd', - secretKey: 'ssdssdssdssd', - }, - errorText: '\'url\' is an invalid URL', - }, - { - payload: { - type: 's3', - name: 'missing-region', - bucketName: 'invalid', - accessKey: 'ssdssd', - secretKey: 'ssdssdssdssd', - }, - errorText: 'Region is required', - }, - { - payload: { - type: 'gcs', - name: 'invalid', - region: 'us-east-2', - bucketName: 'invalid', - accessKey: 'ssdssd', - secretKey: 'ssdssdssdssd', - }, - errorText: '"/type": value is not one of the allowed values', - }, - ] - - for (const testCase of testCases) { - const response = await request.post('/v1/backup-storages', { - data: testCase.payload, + accessKey: 'sdfs', + secretKey: 'sdfsdfsd', + targetNamespaces: [testsNs] + } + + const response = await request.post(`/v1/backup-storages`, { + data: payload, }) - expect(response.status()).toBe(400) - expect((await response.json()).message).toMatch(testCase.errorText) - } -}) + // create + await checkError(response) + const created = await response.json() -test('update backup storage failures', async ({ request }) => { - const createPayload = { - type: 's3', - name: 'backup-storage-2', - bucketName: 'percona-test-backup-storage', - region: 'us-east-2', - accessKey: 'sdfsdfs', - secretKey: 'lkdfslsldfka', - } - const response = await request.post('/v1/backup-storages', { - data: createPayload, - }) - - expect(response.ok()).toBeTruthy() - const created = await response.json() - - const name = created.name - - const testCases = [ - { - payload: { - url: '-asldf;asdfk;sadf', - }, - errorText: '\'url\' is an invalid URL', - }, - { - payload: { - bucket: '-asldf;asdfk;sadf', - }, - errorText: 'request body has an error: doesn\'t match schema #/components/schemas/UpdateBackupStorageParams: property \"bucket\" is unsupported', - }, - ] - - for (const testCase of testCases) { - const response = await request.patch(`/v1/backup-storages/${name}`, { - data: testCase.payload, + const name = created.name + + expect(created.name).toBe(payload.name) + expect(created.bucketName).toBe(payload.bucketName) + expect(created.type).toBe(payload.type) + expect(created.description).toBe(payload.description) + + // list + const listResponse = await request.get(`/v1/backup-storages`) + + await checkError(listResponse) + const list = await listResponse.json() + + expect(list.length).toBeGreaterThan(0) + + // get + const one = await request.get(`/v1/backup-storages/${name}`) + + await checkError(one) + expect((await one.json()).name).toBe(payload.name) + + // update + const updatePayload = { + description: 'some description', + bucketName: 'percona-test-backup-storage1', + } + const updated = await request.patch(`/v1/backup-storages/${name}`, { + data: updatePayload, }) - expect((await response.json()).message).toMatch(testCase.errorText) - expect(response.status()).toBe(400) - } + await checkError(updated) + const result = await updated.json() - const deleted = await request.delete(`/v1/backup-storages/${name}`) + expect(result.bucketName).toBe(updatePayload.bucketName) + expect(result.region).toBe(created.region) + expect(result.type).toBe(created.type) + expect(result.description).toBe(updatePayload.description) - expect(deleted.ok()).toBeTruthy() + // backup storage already exists + const createAgain = await request.post(`/v1/backup-storages`, { + data: payload, + }) + + expect(createAgain.status()).toBe(409) + + // delete + const deleted = await request.delete(`/v1/backup-storages/${name}`) + + await checkError(deleted) }) -test('update: backup storage not found', async ({ request }) => { - const name = 'some-storage' +test('create backup storage failures', async ({request}) => { + const testCases = [ + { + payload: {}, + errorText: 'property \"name\" is missing', + }, + { + payload: { + type: 's3', + name: 'backup-storage', + bucketName: 'percona-test-backup-storage', + region: 'us-east-2', + accessKey: 'ssdssd', + }, + errorText: 'property \"secretKey\" is missing', + }, + { + payload: { + type: 's3', + name: 'Backup Name', + bucketName: 'percona-test-backup-storage', + region: 'us-east-2', + accessKey: 'ssdssd', + secretKey: 'ssdssdssdssd', + targetNamespaces: [testsNs] + }, + errorText: '\'name\' is not RFC 1035 compatible', + }, + { + payload: { + type: 's3', + name: 'backup', + bucketName: 'percona-test-backup-storage', + url: 'not-valid-url', + region: 'us-east-2', + accessKey: 'ssdssd', + secretKey: 'ssdssdssdssd', + targetNamespaces: [testsNs] + }, + errorText: '\'url\' is an invalid URL', + }, + { + payload: { + type: 's3', + name: 'missing-region', + bucketName: 'invalid', + accessKey: 'ssdssd', + secretKey: 'ssdssdssdssd', + targetNamespaces: [testsNs] + }, + errorText: 'Region is required', + }, + { + payload: { + type: 'gcs', + name: 'invalid', + region: 'us-east-2', + bucketName: 'invalid', + accessKey: 'ssdssd', + secretKey: 'ssdssdssdssd', + targetNamespaces: [testsNs] + }, + errorText: '"/type": value is not one of the allowed values', + }, + ] + + for (const testCase of testCases) { + const response = await request.post(`/v1/backup-storages`, { + data: testCase.payload, + }) + + expect(response.status()).toBe(400) + expect((await response.json()).message).toMatch(testCase.errorText) + } +}) - const response = await request.patch(`/v1/backup-storages/${name}`, { - data: { - bucketName: 's3', - }, - }) +test('update backup storage failures', async ({request}) => { + const createPayload = { + type: 's3', + name: 'backup-storage-2', + bucketName: 'percona-test-backup-storage', + region: 'us-east-2', + accessKey: 'sdfsdfs', + secretKey: 'lkdfslsldfka', + targetNamespaces: [testsNs] + } + const response = await request.post(`/v1/backup-storages`, { + data: createPayload, + }) + + await checkError(response) + const created = await response.json() + + const name = created.name + + const testCases = [ + { + payload: { + url: '-asldf;asdfk;sadf', + }, + errorText: '\'url\' is an invalid URL', + }, + { + payload: { + bucket: '-asldf;asdfk;sadf', + }, + errorText: 'request body has an error: doesn\'t match schema #/components/schemas/UpdateBackupStorageParams: property \"bucket\" is unsupported', + }, + ] + + for (const testCase of testCases) { + const response = await request.patch(`/v1/backup-storages/${name}`, { + data: testCase.payload, + }) + + expect((await response.json()).message).toMatch(testCase.errorText) + expect(response.status()).toBe(400) + } + + const deleted = await request.delete(`/v1/backup-storages/${name}`) + + await checkError(deleted) +}) + +test('update: backup storage not found', async ({request}) => { + const name = 'some-storage' + + const response = await request.patch(`/v1/backup-storages/${name}`, { + data: { + bucketName: 's3', + }, + }) - expect(response.status()).toBe(404) + expect(response.status()).toBe(404) }) -test('delete: backup storage not found', async ({ request }) => { - const name = 'backup-storage' +test('delete: backup storage not found', async ({request}) => { + const name = 'backup-storage' - const response = await request.delete(`/v1/backup-storages/${name}`) + const response = await request.delete(`/v1/backup-storages/${name}`) - expect(response.status()).toBe(404) + expect(response.status()).toBe(404) }) -test('get: backup storage not found', async ({ request }) => { - const name = 'backup-storage' - const response = await request.get(`/v1/backup-storages/${name}`) +test('get: backup storage not found', async ({request}) => { + const name = 'backup-storage' + const response = await request.get(`/v1/backup-storages/${name}`) - expect(response.status()).toBe(404) + expect(response.status()).toBe(404) }) diff --git a/api-tests/tests/database-cluster-backups.spec.ts b/api-tests/tests/database-cluster-backups.spec.ts index 34f2e3cd..2066aafc 100644 --- a/api-tests/tests/database-cluster-backups.spec.ts +++ b/api-tests/tests/database-cluster-backups.spec.ts @@ -14,6 +14,7 @@ // limitations under the License. import { expect, test } from '@playwright/test' import * as th from './helpers' +import {checkError, testsNs} from "./helpers"; test('create/delete database cluster backups', async ({ request }) => { const bsName = th.suffixedName('storage') @@ -36,13 +37,13 @@ test('create/delete database cluster backups', async ({ request }) => { }, } - let response = await request.post(`/v1/database-cluster-backups`, { + let response = await request.post(`/v1/namespaces/${testsNs}/database-cluster-backups`, { data: payload, }) - expect(response.ok()).toBeTruthy() + await checkError(response) - response = await request.get(`/v1/database-cluster-backups/${backupName}`) + response = await request.get(`/v1/namespaces/${testsNs}/database-cluster-backups/${backupName}`) const result = await response.json() expect(result.spec).toMatchObject(payload.spec) @@ -70,7 +71,7 @@ test('dbcluster not found', async ({ request }) => { }, } - const response = await request.post(`/v1/database-cluster-backups`, { + const response = await request.post(`/v1/namespaces/${testsNs}/database-cluster-backups`, { data: payload, }) @@ -142,27 +143,27 @@ test('list backups', async ({ request, page }) => { ] for (const payload of payloads) { - const response = await request.post(`/v1/database-cluster-backups`, { + const response = await request.post(`/v1/namespaces/${testsNs}/database-cluster-backups`, { data: payload, }) - expect(response.ok()).toBeTruthy() + await checkError(response) } await page.waitForTimeout(1000) - let response = await request.get(`/v1/database-clusters/${clusterName1}/backups`) + let response = await request.get(`/v1/namespaces/${testsNs}/database-clusters/${clusterName1}/backups`) let result = await response.json() expect(result.items).toHaveLength(2) - response = await request.get(`/v1/database-clusters/${clusterName2}/backups`) + response = await request.get(`/v1/namespaces/${testsNs}/database-clusters/${clusterName2}/backups`) result = await response.json() expect(result.items).toHaveLength(2) for (const payload of payloads) { - await request.delete(`/v1/database-cluster-backups/${payload.metadata.name}`) - response = await request.get(`/v1/database-cluster-backups/${payload.metadata.name}`) + await request.delete(`/v1/namespaces/${testsNs}/database-cluster-backups/${payload.metadata.name}`) + response = await request.get(`/v1/namespaces/${testsNs}/database-cluster-backups/${payload.metadata.name}`) expect(response.status()).toBe(404) } diff --git a/api-tests/tests/database-cluster-restores.spec.ts b/api-tests/tests/database-cluster-restores.spec.ts index ac2cb254..a74c6c53 100644 --- a/api-tests/tests/database-cluster-restores.spec.ts +++ b/api-tests/tests/database-cluster-restores.spec.ts @@ -14,6 +14,7 @@ // limitations under the License. import { expect, test } from '@playwright/test' import * as th from './helpers' +import {checkError, testsNs} from "./helpers"; test('create/update/delete database cluster restore', async ({ request }) => { @@ -43,37 +44,37 @@ test('create/update/delete database cluster restore', async ({ request }) => { }, } - let response = await request.post(`/v1/database-cluster-restores`, { + let response = await request.post(`/v1/namespaces/${testsNs}/database-cluster-restores`, { data: payloadRestore, }) - expect(response.ok()).toBeTruthy() + await checkError(response) const restore = await response.json() expect(restore.spec).toMatchObject(payloadRestore.spec) // update restore restore.spec.dbClusterName = clName2 - response = await request.put(`/v1/database-cluster-restores/${restoreName}`, { + response = await request.put(`/v1/namespaces/${testsNs}/database-cluster-restores/${restoreName}`, { data: restore, }) - expect(response.ok()).toBeTruthy() + await checkError(response) const result = await response.json() expect(result.spec).toMatchObject(restore.spec) // update restore with not existing dbClusterName restore.spec.dbClusterName = 'not-existing-cluster' - response = await request.put(`/v1/database-cluster-restores/${restoreName}`, { + response = await request.put(`/v1/namespaces/${testsNs}/database-cluster-restores/${restoreName}`, { data: restore, }) expect(response.status()).toBe(400) expect(await response.text()).toContain('{"message":"Database cluster not-existing-cluster does not exist"}') // delete restore - await request.delete(`/v1/database-cluster-restores/${restoreName}`) + await request.delete(`/v1/namespaces/${testsNs}/database-cluster-restores/${restoreName}`) // check it couldn't be found anymore - response = await request.get(`/v1/database-cluster-restores/${restoreName}`) + response = await request.get(`/v1/namespaces/${testsNs}/database-cluster-restores/${restoreName}`) expect(response.status()).toBe(404) await th.deleteDBCluster(request, clName) @@ -140,30 +141,30 @@ test('list restores', async ({ request, page }) => { ] for (const payload of payloads) { - const response = await request.post(`/v1/database-cluster-restores`, { + const response = await request.post(`/v1/namespaces/${testsNs}/database-cluster-restores`, { data: payload, }) - expect(response.ok()).toBeTruthy() + await checkError(response) } await page.waitForTimeout(6000) // check if the restores are available when being requested via database-clusters/{cluster-name}/restores path - let response = await request.get(`/v1/database-clusters/${clName1}/restores`) + let response = await request.get(`/v1/namespaces/${testsNs}/database-clusters/${clName1}/restores`) let result = await response.json() expect(result.items).toHaveLength(2) - response = await request.get(`/v1/database-clusters/${clName2}/restores`) + response = await request.get(`/v1/namespaces/${testsNs}/database-clusters/${clName2}/restores`) result = await response.json() expect(result.items).toHaveLength(1) // delete the created restores for (const payload of payloads) { - await request.delete(`/v1/database-cluster-restores/${payload.metadata.name}`) - response = await request.get(`/v1/database-cluster-restores/${payload.metadata.name}`) + await request.delete(`/v1/namespaces/${testsNs}/database-cluster-restores/${payload.metadata.name}`) + response = await request.get(`/v1/namespaces/${testsNs}/database-cluster-restores/${payload.metadata.name}`) expect(response.status()).toBe(404) } @@ -198,7 +199,7 @@ test('create restore: validation errors', async ({ request, page }) => { }, } - let response = await request.post(`/v1/database-cluster-restores`, { + let response = await request.post(`/v1/namespaces/${testsNs}/database-cluster-restores`, { data: payloadRestore, }) @@ -214,7 +215,7 @@ test('create restore: validation errors', async ({ request, page }) => { }, } - response = await request.post(`/v1/database-cluster-restores`, { + response = await request.post(`/v1/namespaces/${testsNs}/database-cluster-restores`, { data: payloadEmptySpec, }) expect(response.status()).toBe(400) diff --git a/api-tests/tests/database-cluster.spec.ts b/api-tests/tests/database-cluster.spec.ts index bb7c0109..2e628343 100644 --- a/api-tests/tests/database-cluster.spec.ts +++ b/api-tests/tests/database-cluster.spec.ts @@ -13,11 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. import { expect, test } from '@fixtures' +import {checkError, testsNs, testPrefix} from "@tests/tests/helpers"; // testPrefix is used to differentiate between several workers // running this test to avoid conflicts in instance names -const testPrefix = `${(Math.random() + 1).toString(36).substring(10)}` - const monitoringConfigName1 = `a${testPrefix}-1` const monitoringConfigName2 = `b${testPrefix}-2` @@ -28,6 +27,7 @@ test.beforeAll(async ({ request }) => { type: 'pmm', name: monitoringConfigName1, url: 'http://monitoring', + targetNamespaces: [testsNs], pmm: { apiKey: '123', }, @@ -36,20 +36,20 @@ test.beforeAll(async ({ request }) => { // Monitoring configs let res = await request.post('/v1/monitoring-instances', { data: miData }) - expect(res.ok()).toBeTruthy() + await checkError(res) miData.name = monitoringConfigName2 res = await request.post('/v1/monitoring-instances', { data: miData }) - expect(res.ok()).toBeTruthy() + await checkError(res) }) test.afterAll(async ({ request }) => { let res = await request.delete(`/v1/monitoring-instances/${monitoringConfigName1}`) - expect(res.ok()).toBeTruthy() + await checkError(res) res = await request.delete(`/v1/monitoring-instances/${monitoringConfigName2}`) - expect(res.ok()).toBeTruthy() + await checkError(res) }) test('create db cluster with monitoring config', async ({ request }) => { @@ -85,15 +85,15 @@ test('create db cluster with monitoring config', async ({ request }) => { }, } - const postReq = await request.post(`/v1/database-clusters`, { data }) + const postReq = await request.post(`/v1/namespaces/${testsNs}/database-clusters`, { data }) - expect(postReq.ok()).toBeTruthy() + await checkError(postReq) try { await expect(async () => { - const pgCluster = await request.get(`/v1/database-clusters/${clusterName}`) + const pgCluster = await request.get(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`) - expect(pgCluster.ok()).toBeTruthy() + await checkError(pgCluster) const res = (await pgCluster.json()) expect(res?.status?.size).toBeGreaterThanOrEqual(1) @@ -102,7 +102,7 @@ test('create db cluster with monitoring config', async ({ request }) => { timeout: 60 * 1000, }) } finally { - await request.delete(`/v1/database-clusters/${clusterName}`) + await request.delete(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`) } }) @@ -139,17 +139,17 @@ test('update db cluster with a new monitoring config', async ({ request }) => { }, } - const postReq = await request.post(`/v1/database-clusters`, { data }) + const postReq = await request.post(`/v1/namespaces/${testsNs}/database-clusters`, { data }) - expect(postReq.ok()).toBeTruthy() + await checkError(postReq) try { let res await expect(async () => { - const req = await request.get(`/v1/database-clusters/${clusterName}`) + const req = await request.get(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`) - expect(req.ok()).toBeTruthy() + await checkError(req) res = (await req.json()) expect(res?.status?.size).toBeGreaterThanOrEqual(1) }).toPass({ @@ -164,13 +164,13 @@ test('update db cluster with a new monitoring config', async ({ request }) => { putData.metadata = res.metadata putData.spec.monitoring.monitoringConfigName = monitoringConfigName2 - const putReq = await request.put(`/v1/database-clusters/${clusterName}`, { data: putData }) + const putReq = await request.put(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`, { data: putData }) - expect(putReq.ok()).toBeTruthy() + await checkError(putReq) res = (await putReq.json()) expect(res?.spec?.monitoring?.monitoringConfigName).toBe(monitoringConfigName2) } finally { - await request.delete(`/v1/database-clusters/${clusterName}`) + await request.delete(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`) } }) @@ -204,17 +204,17 @@ test('update db cluster without monitoring config with a new monitoring config', }, } - const postReq = await request.post(`/v1/database-clusters`, { data }) + const postReq = await request.post(`/v1/namespaces/${testsNs}/database-clusters`, { data }) - expect(postReq.ok()).toBeTruthy() + await checkError(postReq) try { let res await expect(async () => { - const req = await request.get(`/v1/database-clusters/${clusterName}`) + const req = await request.get(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`) - expect(req.ok()).toBeTruthy() + await checkError(req) res = (await req.json()) expect(res?.status?.size).toBeGreaterThanOrEqual(1) }).toPass({ @@ -229,13 +229,13 @@ test('update db cluster without monitoring config with a new monitoring config', putData.metadata = res.metadata; (putData.spec as any).monitoring = { monitoringConfigName: monitoringConfigName2 } - const putReq = await request.put(`/v1/database-clusters/${clusterName}`, { data: putData }) + const putReq = await request.put(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`, { data: putData }) - expect(putReq.ok()).toBeTruthy() + await checkError(putReq) res = (await putReq.json()) expect(res?.spec?.monitoring?.monitoringConfigName).toBe(monitoringConfigName2) } finally { - await request.delete(`/v1/database-clusters/${clusterName}`) + await request.delete(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`) } }) @@ -272,17 +272,17 @@ test('update db cluster monitoring config with an empty monitoring config', asyn }, } - const postReq = await request.post(`/v1/database-clusters`, { data }) + const postReq = await request.post(`/v1/namespaces/${testsNs}/database-clusters`, { data }) - expect(postReq.ok()).toBeTruthy() + await checkError(postReq) try { let res await expect(async () => { - const req = await request.get(`/v1/database-clusters/${clusterName}`) + const req = await request.get(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`) - expect(req.ok()).toBeTruthy() + await checkError(req) res = (await req.json()) expect(res?.status?.size).toBeGreaterThanOrEqual(1) }).toPass({ @@ -295,12 +295,12 @@ test('update db cluster monitoring config with an empty monitoring config', asyn putData.metadata = res.metadata; (putData.spec.monitoring as any) = {} - const putReq = await request.put(`/v1/database-clusters/${clusterName}`, { data: putData }) + const putReq = await request.put(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`, { data: putData }) - expect(putReq.ok()).toBeTruthy() + await checkError(putReq) res = (await putReq.json()) expect(res?.spec?.monitoring?.monitoringConfigName).toBeFalsy() } finally { - await request.delete(`/v1/database-clusters/${clusterName}`) + await request.delete(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`) } }) diff --git a/api-tests/tests/database-engines.spec.ts b/api-tests/tests/database-engines.spec.ts index e3669606..7bedca54 100644 --- a/api-tests/tests/database-engines.spec.ts +++ b/api-tests/tests/database-engines.spec.ts @@ -13,11 +13,12 @@ // See the License for the specific language governing permissions and // limitations under the License. import { test, expect } from '@fixtures' +import {checkError, testsNs} from "@tests/tests/helpers"; test('check operators are installed', async ({ request }) => { - const enginesList = await request.get(`/v1/database-engines`) + const enginesList = await request.get(`/v1/namespaces/${testsNs}/database-engines`) - expect(enginesList.ok()).toBeTruthy() + await checkError(enginesList) const engines = (await enginesList.json()).items @@ -34,9 +35,9 @@ test('check operators are installed', async ({ request }) => { test('get/edit database engine versions', async ({ request }) => { - let engineResponse = await request.get(`/v1/database-engines/percona-server-mongodb-operator`) + let engineResponse = await request.get(`/v1/namespaces/${testsNs}/database-engines/percona-server-mongodb-operator`) - expect(engineResponse.ok()).toBeTruthy() + await checkError(engineResponse) const engineData = await engineResponse.json() const availableVersions = engineData.status.availableVersions @@ -49,14 +50,14 @@ test('get/edit database engine versions', async ({ request }) => { delete engineData.status engineData.spec.allowedVersions = allowedVersions - const updateResponse = await request.put(`/v1/database-engines/percona-server-mongodb-operator`, { + const updateResponse = await request.put(`/v1/namespaces/${testsNs}/database-engines/percona-server-mongodb-operator`, { data: engineData, }) - expect(updateResponse.ok()).toBeTruthy() + await checkError(updateResponse) - engineResponse = await request.get(`/v1/database-engines/percona-server-mongodb-operator`) - expect(engineResponse.ok()).toBeTruthy() + engineResponse = await request.get(`/v1/namespaces/${testsNs}/database-engines/percona-server-mongodb-operator`) + await checkError(engineResponse) expect((await engineResponse.json()).spec.allowedVersions).toEqual(allowedVersions) }) diff --git a/api-tests/tests/helpers.ts b/api-tests/tests/helpers.ts index ca9b7072..50b63ab0 100644 --- a/api-tests/tests/helpers.ts +++ b/api-tests/tests/helpers.ts @@ -2,12 +2,21 @@ import { expect, test } from '@playwright/test' // testPrefix is used to differentiate between several workers // running this test to avoid conflicts in instance names -const testSuffix = () => `${(Math.random() + 1).toString(36).substring(10)}` +export const testPrefix = `t${(Math.random() + 1).toString(36).substring(10)}` export const suffixedName = (name) => { - return `${name}-${testSuffix()}` + return `${name}-${testPrefix}` } +export const checkError = async response => { + if (!response.ok()) { + console.log(`${response.url()}: `, await response.json()); + } + expect(response.ok()).toBeTruthy() +} + +export const testsNs = 'everest' + export const createDBCluster = async (request, name) => { const data = { apiVersion: 'everest.percona.com/v1alpha1', @@ -37,15 +46,15 @@ export const createDBCluster = async (request, name) => { }, } - const postReq = await request.post(`/v1/database-clusters`, { data }) + const postReq = await request.post(`/v1/namespaces/${testsNs}/database-clusters`, { data }) - expect(postReq.ok()).toBeTruthy() + await checkError(postReq) } export const deleteDBCluster = async (request, name) => { - const res = await request.delete(`/v1/database-clusters/${name}`) + const res = await request.delete(`/v1/namespaces/${testsNs}/database-clusters/${name}`) - expect(res.ok()).toBeTruthy() + await checkError(res) } export const createBackupStorage = async (request, name) => { @@ -58,17 +67,18 @@ export const createBackupStorage = async (request, name) => { region: 'us-east-2', accessKey: 'sdfs', secretKey: 'sdfsdfsd', + targetNamespaces: [testsNs], } - const response = await request.post('/v1/backup-storages', { data: storagePayload }) + const response = await request.post(`/v1/backup-storages`, { data: storagePayload }) - expect(response.ok()).toBeTruthy() + await checkError(response) } export const deleteBackupStorage = async (request, name) => { const res = await request.delete(`/v1/backup-storages/${name}`) - expect(res.ok()).toBeTruthy() + await checkError(res) } export const createBackup = async (request, clusterName, backupName, storageName) => { @@ -84,21 +94,21 @@ export const createBackup = async (request, clusterName, backupName, storageNam }, } - const responseBackup = await request.post(`/v1/database-cluster-backups`, { + const responseBackup = await request.post(`/v1/namespaces/${testsNs}/database-cluster-backups`, { data: payloadBackup, }) - expect(responseBackup.ok()).toBeTruthy() + await checkError(responseBackup) } export const deleteBackup = async (request, backupName) => { - const res = await request.delete(`/v1/database-cluster-backups/${backupName}`) + const res = await request.delete(`/v1/namespaces/${testsNs}/database-cluster-backups/${backupName}`) - expect(res.ok()).toBeTruthy() + await checkError(res) } export const deleteRestore = async (request, restoreName) => { - const res = await request.delete(`/v1/database-cluster-restores/${restoreName}`) + const res = await request.delete(`/v1/namespaces/${testsNs}/database-cluster-restores/${restoreName}`) - expect(res.ok()).toBeTruthy() + await checkError(res) } diff --git a/api-tests/tests/kubernetes.spec.ts b/api-tests/tests/kubernetes.spec.ts index fa00ae51..3cc217c8 100644 --- a/api-tests/tests/kubernetes.spec.ts +++ b/api-tests/tests/kubernetes.spec.ts @@ -13,16 +13,17 @@ // See the License for the specific language governing permissions and // limitations under the License. import { test, expect } from '@fixtures' +import {checkError, testsNs} from "@tests/tests/helpers"; // testPrefix is used to differentiate between several workers // running this test to avoid conflicts in instance names -const testPrefix = `${(Math.random() + 1).toString(36).substring(10)}` +const testPrefix = `t${(Math.random() + 1).toString(36).substring(10)}` test('get resource usage', async ({ request }) => { const r = await request.get(`/v1/resources`) const resources = await r.json() - expect(r.ok()).toBeTruthy() + await checkError(r) expect(resources).toBeTruthy() @@ -30,42 +31,11 @@ test('get resource usage', async ({ request }) => { expect(resources?.available).toBeTruthy() }) -test('enable/disable cluster-monitoring', async ({ request }) => { - const data = { - type: 'pmm', - name: `${testPrefix}-monit`, - url: 'http://monitoring', - pmm: { - apiKey: '123', - }, - } - - const response = await request.post('/v1/monitoring-instances', { data }) - - expect(response.ok()).toBeTruthy() - const created = await response.json() - - const rEnable = await request.post(`/v1/cluster-monitoring`, { - data: { - enable: true, - monitoringInstanceName: created.name, - }, - }) - - expect(rEnable.ok()).toBeTruthy() - - const rDisable = await request.post(`/v1/cluster-monitoring`, { - data: { enable: false }, - }) - - expect(rDisable.ok()).toBeTruthy() -}) - test('get cluster info', async ({ request }) => { const r = await request.get(`/v1/cluster-info`) const info = await r.json() - expect(r.ok()).toBeTruthy() + await checkError(r) expect(info).toBeTruthy() diff --git a/api-tests/tests/monitoring-instances.spec.ts b/api-tests/tests/monitoring-instances.spec.ts index 99b6b652..00adde3a 100644 --- a/api-tests/tests/monitoring-instances.spec.ts +++ b/api-tests/tests/monitoring-instances.spec.ts @@ -15,10 +15,11 @@ import http from 'http' import { expect, test } from '@fixtures' import { APIRequestContext } from '@playwright/test' +import {checkError, testsNs} from "@tests/tests/helpers"; // testPrefix is used to differentiate between several workers // running this test to avoid conflicts in instance names -const testPrefix = `${(Math.random() + 1).toString(36).substring(10)}` +const testPrefix = `t${(Math.random() + 1).toString(36).substring(10)}` test.afterEach(async ({ request }, testInfo) => { const result = await request.get('/v1/monitoring-instances') @@ -38,6 +39,7 @@ test('create monitoring instance with api key', async ({ request }) => { type: 'pmm', name: `${testPrefix}-key`, url: 'http://monitoring', + targetNamespaces: [testsNs], pmm: { apiKey: '123', }, @@ -45,7 +47,7 @@ test('create monitoring instance with api key', async ({ request }) => { const response = await request.post('/v1/monitoring-instances', { data }) - expect(response.ok()).toBeTruthy() + await checkError(response) const created = await response.json() expect(created.name).toBe(data.name) @@ -58,6 +60,7 @@ test('create monitoring instance with user/password', async ({ request }) => { type: 'pmm', name: `${testPrefix}-pass`, url: 'http://127.0.0.1:8888', + targetNamespaces: [testsNs], pmm: { user: 'admin', password: 'admin', @@ -66,7 +69,7 @@ test('create monitoring instance with user/password', async ({ request }) => { const response = await request.post('/v1/monitoring-instances', { data }) - expect(response.ok()).toBeTruthy() + await checkError(response) const created = await response.json() expect(created.name).toBe(data.name) @@ -79,6 +82,7 @@ test('create monitoring instance missing pmm', async ({ request }) => { type: 'pmm', name: 'monitoring-fail', url: 'http://monitoring-instance', + targetNamespaces: [testsNs], } const response = await request.post('/v1/monitoring-instances', { data }) @@ -91,6 +95,7 @@ test('create monitoring instance missing pmm credentials', async ({ request }) = type: 'pmm', name: 'monitoring-fail', url: 'http://monitoring-instance', + targetNamespaces: [testsNs], pmm: {}, } @@ -106,7 +111,7 @@ test('list monitoring instances', async ({ request }) => { const response = await request.get('/v1/monitoring-instances') - expect(response.ok()).toBeTruthy() + await checkError(response) const list = await response.json() expect(list.filter((i) => i.name.startsWith(`${namePrefix}${testPrefix}`)).length).toBe(3) @@ -119,47 +124,47 @@ test('get monitoring instance', async ({ request }) => { const response = await request.get(`/v1/monitoring-instances/${name}`) - expect(response.ok()).toBeTruthy() + await checkError(response) const i = await response.json() expect(i.name).toBe(name) }) test('delete monitoring instance', async ({ request }) => { - const namePrefix = 'delete-' + const namePrefix = 'del-' const names = await createInstances(request, namePrefix) const name = names[1] let response = await request.get('/v1/monitoring-instances') - expect(response.ok()).toBeTruthy() + await checkError(response) let list = await response.json() expect(list.filter((i) => i.name.startsWith(`${namePrefix}${testPrefix}`)).length).toBe(3) response = await request.delete(`/v1/monitoring-instances/${name}`) - expect(response.ok()).toBeTruthy() + await checkError(response) response = await request.get('/v1/monitoring-instances') - expect(response.ok()).toBeTruthy() + await checkError(response) list = await response.json() expect(list.filter((i) => i.name.startsWith(`${namePrefix}${testPrefix}`)).length).toBe(2) }) test('patch monitoring instance', async ({ request }) => { - const names = await createInstances(request, 'patch-monitoring-') + const names = await createInstances(request, 'patch-monit-') const name = names[1] const response = await request.get(`/v1/monitoring-instances/${name}`) - expect(response.ok()).toBeTruthy() + await checkError(response) const created = await response.json() const patchData = { url: 'http://monitoring' } const updated = await request.patch(`/v1/monitoring-instances/${name}`, { data: patchData }) - expect(updated.ok()).toBeTruthy() + await checkError(updated) const getJson = await updated.json() expect(getJson.url).toBe(patchData.url) @@ -167,12 +172,12 @@ test('patch monitoring instance', async ({ request }) => { }) test('patch monitoring instance secret key changes', async ({ request }) => { - const names = await createInstances(request, 'patch-monitoring-') + const names = await createInstances(request, 'patch-monit-') const name = names[1] const response = await request.get(`/v1/monitoring-instances/${name}`) - expect(response.ok()).toBeTruthy() + await checkError(response) const created = await response.json() const patchData = { @@ -183,19 +188,19 @@ test('patch monitoring instance secret key changes', async ({ request }) => { } const updated = await request.patch(`/v1/monitoring-instances/${name}`, { data: patchData }) - expect(updated.ok()).toBeTruthy() + await checkError(updated) const getJson = await updated.json() expect(getJson.url).toBe(patchData.url) }) test('patch monitoring instance type updates properly', async ({ request }) => { - const names = await createInstances(request, 'patch-monitoring-') + const names = await createInstances(request, 'patch-monit-') const name = names[1] const response = await request.get(`/v1/monitoring-instances/${name}`) - expect(response.ok()).toBeTruthy() + await checkError(response) const patchData = { type: 'pmm', @@ -205,17 +210,17 @@ test('patch monitoring instance type updates properly', async ({ request }) => { } const updated = await request.patch(`/v1/monitoring-instances/${name}`, { data: patchData }) - expect(updated.ok()).toBeTruthy() + await checkError(updated) const getJson = await updated.json() }) test('patch monitoring instance type fails on missing key', async ({ request }) => { - const names = await createInstances(request, 'patch-monitoring-') + const names = await createInstances(request, 'patch-monit-') const name = names[1] const response = await request.get(`/v1/monitoring-instances/${name}`) - expect(response.ok()).toBeTruthy() + await checkError(response) const patchData = { type: 'pmm', @@ -239,13 +244,14 @@ test('update monitoring instances failures', async ({ request }) => { type: 'pmm', name: `${testPrefix}-fail`, url: 'http://monitoring', + targetNamespaces: [testsNs], pmm: { apiKey: '123', }, } const response = await request.post('/v1/monitoring-instances', { data }) - expect(response.ok()).toBeTruthy() + await checkError(response) const created = await response.json() const name = created.name @@ -295,6 +301,7 @@ async function createInstances(request: APIRequestContext, namePrefix: string, c type: 'pmm', name: '', url: 'http://monitoring-instance', + targetNamespaces: [testsNs], pmm: { apiKey: '123', }, @@ -307,7 +314,7 @@ async function createInstances(request: APIRequestContext, namePrefix: string, c res.push(data.name) const response = await request.post('/v1/monitoring-instances', { data }) - expect(response.ok()).toBeTruthy() + await checkError(response) } return res diff --git a/api-tests/tests/pg-clusters.spec.ts b/api-tests/tests/pg-clusters.spec.ts index b0c000b0..3137cbbf 100644 --- a/api-tests/tests/pg-clusters.spec.ts +++ b/api-tests/tests/pg-clusters.spec.ts @@ -13,11 +13,12 @@ // See the License for the specific language governing permissions and // limitations under the License. import { test, expect } from '@fixtures' +import {checkError, testsNs} from "@tests/tests/helpers"; let recommendedVersion test.beforeAll(async ({ request }) => { - const engineResponse = await request.get(`/v1/database-engines/percona-postgresql-operator`) + const engineResponse = await request.get(`/v1/namespaces/${testsNs}/database-engines/percona-postgresql-operator`) const availableVersions = (await engineResponse.json()).status.availableVersions.engine for (const k in availableVersions) { @@ -60,15 +61,15 @@ test('create/edit/delete single node pg cluster', async ({ request, page }) => { }, } - await request.post(`/v1/database-clusters`, { + await request.post(`/v1/namespaces/${testsNs}/database-clusters`, { data: pgPayload, }) for (let i = 0; i < 15; i++) { await page.waitForTimeout(1000) - const pgCluster = await request.get(`/v1/database-clusters/${clusterName}`) + const pgCluster = await request.get(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`) - expect(pgCluster.ok()).toBeTruthy() + await checkError(pgCluster) const result = (await pgCluster.json()) @@ -93,21 +94,21 @@ test('create/edit/delete single node pg cluster', async ({ request, page }) => { // Update PG cluster - const updatedPGCluster = await request.put(`/v1/database-clusters/${clusterName}`, { + const updatedPGCluster = await request.put(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`, { data: pgPayload, }) - expect(updatedPGCluster.ok()).toBeTruthy() + await checkError(updatedPGCluster) - let pgCluster = await request.get(`/v1/database-clusters/${clusterName}`) + let pgCluster = await request.get(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`) - expect(pgCluster.ok()).toBeTruthy() + await checkError(pgCluster) expect((await updatedPGCluster.json()).spec.clusterSize).toBe(pgPayload.spec.clusterSize) - await request.delete(`/v1/database-clusters/${clusterName}`) + await request.delete(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`) - pgCluster = await request.get(`/v1/database-clusters/${clusterName}`) + pgCluster = await request.get(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`) expect(pgCluster.status()).toBe(404) }) @@ -142,15 +143,15 @@ test('expose pg cluster after creation', async ({ request, page }) => { }, } - await request.post(`/v1/database-clusters`, { + await request.post(`/v1/namespaces/${testsNs}/database-clusters`, { data: pgPayload, }) for (let i = 0; i < 15; i++) { await page.waitForTimeout(1000) - const pgCluster = await request.get(`/v1/database-clusters/${clusterName}`) + const pgCluster = await request.get(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`) - expect(pgCluster.ok()).toBeTruthy() + await checkError(pgCluster) const result = (await pgCluster.json()) @@ -171,21 +172,21 @@ test('expose pg cluster after creation', async ({ request, page }) => { // Update PG cluster - const updatedPGCluster = await request.put(`/v1/database-clusters/${clusterName}`, { + const updatedPGCluster = await request.put(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`, { data: pgPayload, }) - expect(updatedPGCluster.ok()).toBeTruthy() + await checkError(updatedPGCluster) - let pgCluster = await request.get(`/v1/database-clusters/${clusterName}`) + let pgCluster = await request.get(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`) - expect(pgCluster.ok()).toBeTruthy() + await checkError(pgCluster) expect((await updatedPGCluster.json()).spec.proxy.expose.type).toBe('external') - await request.delete(`/v1/database-clusters/${clusterName}`) + await request.delete(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`) - pgCluster = await request.get(`/v1/database-clusters/${clusterName}`) + pgCluster = await request.get(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`) expect(pgCluster.status()).toBe(404) }) @@ -220,15 +221,15 @@ test('expose pg cluster on EKS to the public internet and scale up', async ({ re }, } - await request.post(`/v1/database-clusters`, { + await request.post(`/v1/namespaces/${testsNs}/database-clusters`, { data: pgPayload, }) for (let i = 0; i < 15; i++) { await page.waitForTimeout(2000) - const pgCluster = await request.get(`/v1/database-clusters/${clusterName}`) + const pgCluster = await request.get(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`) - expect(pgCluster.ok()).toBeTruthy() + await checkError(pgCluster) const result = (await pgCluster.json()) @@ -249,16 +250,16 @@ test('expose pg cluster on EKS to the public internet and scale up', async ({ re // Update PG cluster - const updatedPGCluster = await request.put(`/v1/database-clusters/${clusterName}`, { + const updatedPGCluster = await request.put(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`, { data: pgPayload, }) - expect(updatedPGCluster.ok()).toBeTruthy() + await checkError(updatedPGCluster) - await request.delete(`/v1/database-clusters/${clusterName}`) + await request.delete(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`) await page.waitForTimeout(1000) - const pgCluster = await request.get(`/v1/database-clusters/${clusterName}`) + const pgCluster = await request.get(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`) expect(pgCluster.status()).toBe(404) }) diff --git a/api-tests/tests/psmdb-clusters.spec.ts b/api-tests/tests/psmdb-clusters.spec.ts index 1c56eeae..b483dfb8 100644 --- a/api-tests/tests/psmdb-clusters.spec.ts +++ b/api-tests/tests/psmdb-clusters.spec.ts @@ -13,10 +13,11 @@ // See the License for the specific language governing permissions and // limitations under the License. import { test, expect } from '@fixtures' +import {checkError, testsNs} from "@tests/tests/helpers"; test.beforeAll(async ({ request }) => { - const engineResponse = await request.get(`/v1/database-engines/percona-server-mongodb-operator`) + const engineResponse = await request.get(`/v1/namespaces/${testsNs}/database-engines/percona-server-mongodb-operator`) const availableVersions = (await engineResponse.json()).status.availableVersions.engine }) @@ -50,15 +51,15 @@ test('create/edit/delete single node psmdb cluster', async ({ request, page }) = }, } - await request.post(`/v1/database-clusters`, { + await request.post(`/v1/namespaces/${testsNs}/database-clusters`, { data: psmdbPayload, }) for (let i = 0; i < 15; i++) { await page.waitForTimeout(1000) - const psmdbCluster = await request.get(`/v1/database-clusters/${clusterName}`) + const psmdbCluster = await request.get(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`) - expect(psmdbCluster.ok()).toBeTruthy() + await checkError(psmdbCluster) const result = (await psmdbCluster.json()) @@ -74,9 +75,9 @@ test('create/edit/delete single node psmdb cluster', async ({ request, page }) = psmdbPayload.spec.engine.config = 'operationProfiling:\nmode: slowOp' - let psmdbCluster = await request.get(`/v1/database-clusters/${clusterName}`) + let psmdbCluster = await request.get(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`) - expect(psmdbCluster.ok()).toBeTruthy() + await checkError(psmdbCluster) const result = (await psmdbCluster.json()) psmdbPayload.spec = result.spec @@ -84,21 +85,21 @@ test('create/edit/delete single node psmdb cluster', async ({ request, page }) = // Update PSMDB cluster - const updatedPSMDBCluster = await request.put(`/v1/database-clusters/${clusterName}`, { + const updatedPSMDBCluster = await request.put(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`, { data: psmdbPayload, }) - expect(updatedPSMDBCluster.ok()).toBeTruthy() + await checkError(updatedPSMDBCluster) - psmdbCluster = await request.get(`/v1/database-clusters/${clusterName}`) + psmdbCluster = await request.get(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`) - expect(psmdbCluster.ok()).toBeTruthy() + await checkError(psmdbCluster) expect((await updatedPSMDBCluster.json()).spec.engine.config).toBe(psmdbPayload.spec.engine.config) - await request.delete(`/v1/database-clusters/${clusterName}`) + await request.delete(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`) - psmdbCluster = await request.get(`/v1/database-clusters/${clusterName}`) + psmdbCluster = await request.get(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`) expect(psmdbCluster.status()).toBe(404) }) @@ -132,16 +133,16 @@ test('expose psmdb cluster after creation', async ({ request, page }) => { }, } - await request.post(`/v1/database-clusters`, { + await request.post(`/v1/namespaces/${testsNs}/database-clusters`, { data: psmdbPayload, }) for (let i = 0; i < 15; i++) { await page.waitForTimeout(1000) - const psmdbCluster = await request.get(`/v1/database-clusters/${clusterName}`) + const psmdbCluster = await request.get(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`) - expect(psmdbCluster.ok()).toBeTruthy() + await checkError(psmdbCluster) const result = (await psmdbCluster.json()) @@ -156,9 +157,9 @@ test('expose psmdb cluster after creation', async ({ request, page }) => { break } - let psmdbCluster = await request.get(`/v1/database-clusters/${clusterName}`) + let psmdbCluster = await request.get(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`) - expect(psmdbCluster.ok()).toBeTruthy() + await checkError(psmdbCluster) const result = (await psmdbCluster.json()) psmdbPayload.spec = result.spec @@ -167,22 +168,22 @@ test('expose psmdb cluster after creation', async ({ request, page }) => { // Update PSMDB cluster - const updatedPSMDBCluster = await request.put(`/v1/database-clusters/${clusterName}`, { + const updatedPSMDBCluster = await request.put(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`, { data: psmdbPayload, }) - expect(updatedPSMDBCluster.ok()).toBeTruthy() + await checkError(updatedPSMDBCluster) await page.waitForTimeout(1000) - psmdbCluster = await request.get(`/v1/database-clusters/${clusterName}`) + psmdbCluster = await request.get(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`) - expect(psmdbCluster.ok()).toBeTruthy() + await checkError(psmdbCluster) expect((await updatedPSMDBCluster.json()).spec.proxy.expose.type).toBe('external') - await request.delete(`/v1/database-clusters/${clusterName}`) + await request.delete(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`) - psmdbCluster = await request.get(`/v1/database-clusters/${clusterName}`) + psmdbCluster = await request.get(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`) expect(psmdbCluster.status()).toBe(404) }) @@ -216,15 +217,15 @@ test('expose psmdb cluster on EKS to the public internet and scale up', async ({ }, } - await request.post(`/v1/database-clusters`, { + await request.post(`/v1/namespaces/${testsNs}/database-clusters`, { data: psmdbPayload, }) for (let i = 0; i < 15; i++) { await page.waitForTimeout(2000) - const psmdbCluster = await request.get(`/v1/database-clusters/${clusterName}`) + const psmdbCluster = await request.get(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`) - expect(psmdbCluster.ok()).toBeTruthy() + await checkError(psmdbCluster) const result = (await psmdbCluster.json()) @@ -239,9 +240,9 @@ test('expose psmdb cluster on EKS to the public internet and scale up', async ({ } psmdbPayload.spec.engine.replicas = 5 - let psmdbCluster = await request.get(`/v1/database-clusters/${clusterName}`) + let psmdbCluster = await request.get(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`) - expect(psmdbCluster.ok()).toBeTruthy() + await checkError(psmdbCluster) const result = (await psmdbCluster.json()) psmdbPayload.spec = result.spec @@ -249,19 +250,19 @@ test('expose psmdb cluster on EKS to the public internet and scale up', async ({ // Update PSMDB cluster - const updatedPSMDBCluster = await request.put(`/v1/database-clusters/${clusterName}`, { + const updatedPSMDBCluster = await request.put(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`, { data: psmdbPayload, }) - expect(updatedPSMDBCluster.ok()).toBeTruthy() + await checkError(updatedPSMDBCluster) - psmdbCluster = await request.get(`/v1/database-clusters/${clusterName}`) + psmdbCluster = await request.get(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`) - expect(psmdbCluster.ok()).toBeTruthy() + await checkError(psmdbCluster) - await request.delete(`/v1/database-clusters/${clusterName}`) + await request.delete(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`) await page.waitForTimeout(1000) - psmdbCluster = await request.get(`/v1/database-clusters/${clusterName}`) + psmdbCluster = await request.get(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`) expect(psmdbCluster.status()).toBe(404) }) diff --git a/api-tests/tests/pxc-clusters.spec.ts b/api-tests/tests/pxc-clusters.spec.ts index d8143779..39beaf78 100644 --- a/api-tests/tests/pxc-clusters.spec.ts +++ b/api-tests/tests/pxc-clusters.spec.ts @@ -13,11 +13,12 @@ // See the License for the specific language governing permissions and // limitations under the License. import { test, expect } from '@fixtures' +import {checkError, testsNs} from "@tests/tests/helpers"; let recommendedVersion test.beforeAll(async ({ request }) => { - const engineResponse = await request.get(`/v1/database-engines/percona-xtradb-cluster-operator`) + const engineResponse = await request.get(`/v1/namespaces/${testsNs}/database-engines/percona-xtradb-cluster-operator`) const availableVersions = (await engineResponse.json()).status.availableVersions.engine for (const k in availableVersions) { @@ -64,15 +65,15 @@ test('create/edit/delete pxc single node cluster', async ({ request, page }) => }, } - await request.post(`/v1/database-clusters`, { + await request.post(`/v1/namespaces/${testsNs}/database-clusters`, { data: pxcPayload, }) for (let i = 0; i < 15; i++) { await page.waitForTimeout(1000) - const pxcCluster = await request.get(`/v1/database-clusters/${clusterName}`) + const pxcCluster = await request.get(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`) - expect(pxcCluster.ok()).toBeTruthy() + await checkError(pxcCluster) const result = (await pxcCluster.json()) @@ -96,8 +97,8 @@ test('create/edit/delete pxc single node cluster', async ({ request, page }) => pxcPayload.spec.engine.config = '[mysqld]\nwsrep_provider_options="debug=1;gcache.size=1G"\n' // check that the /pitr endpoint returns OK and an empty object since pitr is not enabled - const pitrResponse = await request.get(`/v1/database-clusters/${clusterName}/pitr`) - expect(pitrResponse.ok()).toBeTruthy() + const pitrResponse = await request.get(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}/pitr`) + await checkError(pitrResponse) const pitrInfo = (await pitrResponse.json()) expect(pitrInfo.latestBackupName).toBe(undefined) expect(pitrInfo.earliestDate).toBe(undefined) @@ -105,21 +106,21 @@ test('create/edit/delete pxc single node cluster', async ({ request, page }) => // Update PXC cluster - const updatedPXCCluster = await request.put(`/v1/database-clusters/${clusterName}`, { + const updatedPXCCluster = await request.put(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`, { data: pxcPayload, }) - expect(updatedPXCCluster.ok()).toBeTruthy() + await checkError(updatedPXCCluster) - let pxcCluster = await request.get(`/v1/database-clusters/${clusterName}`) + let pxcCluster = await request.get(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`) - expect(pxcCluster.ok()).toBeTruthy() + await checkError(pxcCluster) expect((await updatedPXCCluster.json()).spec.databaseConfig).toBe(pxcPayload.spec.databaseConfig) - await request.delete(`/v1/database-clusters/${clusterName}`) + await request.delete(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`) - pxcCluster = await request.get(`/v1/database-clusters/${clusterName}`) + pxcCluster = await request.get(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`) expect(pxcCluster.status()).toBe(404) }) @@ -154,15 +155,15 @@ test('expose pxc cluster after creation', async ({ request, page }) => { }, } - await request.post(`/v1/database-clusters`, { + await request.post(`/v1/namespaces/${testsNs}/database-clusters`, { data: pxcPayload, }) for (let i = 0; i < 15; i++) { await page.waitForTimeout(1000) - const pxcCluster = await request.get(`/v1/database-clusters/${clusterName}`) + const pxcCluster = await request.get(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`) - expect(pxcCluster.ok()).toBeTruthy() + await checkError(pxcCluster) const result = (await pxcCluster.json()) @@ -183,21 +184,21 @@ test('expose pxc cluster after creation', async ({ request, page }) => { // Update PXC cluster - const updatedPXCCluster = await request.put(`/v1/database-clusters/${clusterName}`, { + const updatedPXCCluster = await request.put(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`, { data: pxcPayload, }) - expect(updatedPXCCluster.ok()).toBeTruthy() + await checkError(updatedPXCCluster) - let pxcCluster = await request.get(`/v1/database-clusters/${clusterName}`) + let pxcCluster = await request.get(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`) - expect(pxcCluster.ok()).toBeTruthy() + await checkError(pxcCluster) expect((await updatedPXCCluster.json()).spec.proxy.expose.type).toBe('external') - await request.delete(`/v1/database-clusters/${clusterName}`) + await request.delete(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`) - pxcCluster = await request.get(`/v1/database-clusters/${clusterName}`) + pxcCluster = await request.get(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`) expect(pxcCluster.status()).toBe(404) }) @@ -233,15 +234,15 @@ test('expose pxc cluster on EKS to the public internet and scale up', async ({ r }, } - await request.post(`/v1/database-clusters`, { + await request.post(`/v1/namespaces/${testsNs}/database-clusters`, { data: pxcPayload, }) for (let i = 0; i < 15; i++) { await page.waitForTimeout(10000) - const pxcCluster = await request.get(`/v1/database-clusters/${clusterName}`) + const pxcCluster = await request.get(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`) - expect(pxcCluster.ok()).toBeTruthy() + await checkError(pxcCluster) const result = (await pxcCluster.json()) @@ -262,16 +263,16 @@ test('expose pxc cluster on EKS to the public internet and scale up', async ({ r // Update PXC cluster - const updatedPXCCluster = await request.put(`/v1/database-clusters/${clusterName}`, { + const updatedPXCCluster = await request.put(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`, { data: pxcPayload, }) - expect(updatedPXCCluster.ok()).toBeTruthy() + await checkError(updatedPXCCluster) - await request.delete(`/v1/database-clusters/${clusterName}`) + await request.delete(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`) await page.waitForTimeout(1000) - const pxcCluster = await request.get(`/v1/database-clusters/${clusterName}`) + const pxcCluster = await request.get(`/v1/namespaces/${testsNs}/database-clusters/${clusterName}`) expect(pxcCluster.status()).toBe(404) }) diff --git a/api-tests/tests/version.spec.ts b/api-tests/tests/version.spec.ts index b0ad9941..f21b7af9 100644 --- a/api-tests/tests/version.spec.ts +++ b/api-tests/tests/version.spec.ts @@ -13,11 +13,12 @@ // See the License for the specific language governing permissions and // limitations under the License. import { expect, test } from '@fixtures' +import {checkError} from "@tests/tests/helpers"; test('version endpoint', async ({ request, cli }) => { const version = await request.get('/v1/version') - expect(version.ok()).toBeTruthy() + await checkError(version) const versionJSON = await version.json() diff --git a/api/everest_test.go b/api/everest_test.go index 3dd88152..b7e2263c 100644 --- a/api/everest_test.go +++ b/api/everest_test.go @@ -31,25 +31,25 @@ func TestBuildProxiedUrl(t *testing.T) { cases := []tCase{ { - url: "/v1/database-clusters", + url: "/v1/namespaces/some-ns/database-clusters", kind: "databaseclusters", name: "", expected: "/apis/everest.percona.com/v1alpha1/namespaces/everest/databaseclusters", }, { - url: "/v1/database-clusters/snake_case_name", + url: "/v1/namespaces/some-ns/database-clusters/snake_case_name", kind: "databaseclusters", name: "snake_case_name", expected: "/apis/everest.percona.com/v1alpha1/namespaces/everest/databaseclusters/snake_case_name", }, { - url: "/v1/database-clusters/kebab-case-name", + url: "/v1/namespaces/some-ns/database-clusters/kebab-case-name", kind: "databaseclusters", name: "kebab-case-name", expected: "/apis/everest.percona.com/v1alpha1/namespaces/everest/databaseclusters/kebab-case-name", }, { - url: "/v1/database-cluster-restores/kebab-case-name", + url: "/v1/namespaces/some-ns/database-cluster-restores/kebab-case-name", kind: "databaseclusterrestores", name: "kebab-case-name", expected: "/apis/everest.percona.com/v1alpha1/namespaces/everest/databaseclusterrestores/kebab-case-name", diff --git a/api/monitoring_instance.go b/api/monitoring_instance.go index 07ffa34a..a3071266 100644 --- a/api/monitoring_instance.go +++ b/api/monitoring_instance.go @@ -33,7 +33,7 @@ import ( const ( // MonitoringNamespace is the namespace where monitoring configs are created. - MonitoringNamespace = "percona-everest-monitoring" + MonitoringNamespace = "everest-monitoring" ) // CreateMonitoringInstance creates a new monitoring instance.