Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PMM-12710 api breaking changes #789

Merged
merged 38 commits into from
Sep 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
fb32142
PMM-12710 Update api endpoints
matejkubinec Jun 3, 2024
e304129
PMM-12710 Update inventory & enums
matejkubinec Jun 4, 2024
3d78ad5
Merge branch 'v3' into PMM-12710-API-breaking-changes
yurkovychv Jul 17, 2024
82249f7
PMM-13242 trigger test run
yurkovychv Jul 17, 2024
e9716e2
PMM-13242 test run
yurkovychv Jul 18, 2024
d4ec60d
PMM-13242 update delete location path
yurkovychv Jul 18, 2024
c65e5cf
PMM-13242 change agent status Running
yurkovychv Jul 18, 2024
56fe921
PMM-13242 update pgsm and pgss tests
yurkovychv Jul 18, 2024
83ec056
PMM-13242 fix access control tests
yurkovychv Jul 18, 2024
e9a04ae
PMM-13242 tweak pgsm pgss tests
yurkovychv Jul 18, 2024
ead67af
PMM-13242 update inventory api
yurkovychv Jul 18, 2024
a5edf53
PMM-13242 update inventory api
yurkovychv Jul 18, 2024
87f6971
PMM-13242 update waitForRunningState in inventory api
yurkovychv Jul 19, 2024
6b9ba28
PMM-13242 more updates to inventory and mongo-exporter tests
yurkovychv Jul 23, 2024
49bc822
PMM-13242 update artifacts in workflow
yurkovychv Jul 23, 2024
624d136
PMM-13242 update artifacts in workflow
yurkovychv Jul 24, 2024
93ab63b
Merge branch 'refs/heads/v3' into PMM-12710-API-breaking-changes
yurkovychv Jul 29, 2024
dfe041f
PMM-13267 update tags
yurkovychv Jul 29, 2024
63ff8f8
PMM-13267 pdsm and pgss tests
yurkovychv Jul 29, 2024
ca416d7
PMM-13267 pdsm and pgss tests
yurkovychv Jul 29, 2024
a7fc663
PMM-13267 increase timeout for repl lag
yurkovychv Jul 29, 2024
e9ada78
PMM-13267 pgsm test
yurkovychv Jul 30, 2024
5abc7df
Merge branch 'v3' into PMM-12710-API-breaking-changes
peterSirotnak Sep 20, 2024
d46cb3c
PMM-12710: Fix for PMM-T878 - Verify adding annotation specific dashb…
peterSirotnak Sep 23, 2024
f709c71
PMM-12710: Fix for PMM-T554
peterSirotnak Sep 23, 2024
26df002
PMM-12710: Fix for PMM-T1699
peterSirotnak Sep 23, 2024
36de51a
PMM-12710: Fix for collapsed dashboard panels
peterSirotnak Sep 23, 2024
ae8aa0e
PMM-12710: Fix for collapsed dashboard panels
peterSirotnak Sep 24, 2024
10e888b
PMM-12710: New Dashboards
peterSirotnak Sep 24, 2024
e9c914c
PMM-12710: Fix test T432
peterSirotnak Sep 24, 2024
335ed6c
PMM-12710: Fix test T324
peterSirotnak Sep 24, 2024
3a9286a
PMM-12710: Fix test T1226
peterSirotnak Sep 24, 2024
836b758
PMM-12710: Fix test T1141
peterSirotnak Sep 24, 2024
21d69a8
PMM-12710: Fix tests
peterSirotnak Sep 24, 2024
b3544d6
PMM-12710: Fix tests
peterSirotnak Sep 24, 2024
08734c5
PMM-12710: Fix tests
peterSirotnak Sep 24, 2024
2211da2
PMM-12710: Fix tests
peterSirotnak Sep 25, 2024
a1bd96d
PMM-12710: Fix tests
peterSirotnak Sep 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion playwright-tests/api/helpers/api-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const getConfiguredRestApi = async (): Promise<APIRequestContext> => {
const apiHelper = {
// TODO: remove in favor of xxxPage.network.suppressTour().
confirmTour: async (page: Page) => {
await page.route('**/v1/user', async (route) => {
await page.route('**/v1/users/me', async (route) => {
await route.fulfill({
status: 200,
body: JSON.stringify({
Expand Down Expand Up @@ -75,6 +75,20 @@ const apiHelper = {
return response;
},

/**
* Implements HTTP PUT to PMM Server API
*
* @param path API endpoint path
* @param payload request body {@code Object}
* @return Promise<APIResponse> instance
*/
put: async (path: string, payload: object): Promise<APIResponse> => {
console.log(`PUT: ${path}\nPayload: ${JSON.stringify(payload)}`);
const response = await (await getConfiguredRestApi()).put(path, { data: payload });
expect(response.status(), `Status: ${response.status()} ${response.statusText()}`).toEqual(200);
return response;
},

/**
* Implements HTTP DELETE to PMM Server API
* Request parameters can be configured with original client options.
Expand Down
2 changes: 1 addition & 1 deletion playwright-tests/api/inventory.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ interface NodeDetails {

export const inventoryApi = {
async listNodes(): Promise<ListNodes> {
return await (await apiHelper.post('v1/inventory/Nodes/List', {})).json() as ListNodes;
return await (await apiHelper.get('v1/management/nodes', {})).json() as ListNodes;
},
};
13 changes: 6 additions & 7 deletions playwright-tests/api/management.api.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import apiHelper from '@api/helpers/api-helper';
import { ListRoles, Role } from '@api/api';

const ROLE_CREATE = '/v1/management/Role/Create';
const ROLE_LIST = '/v1/management/Role/List';
const ROLE_DELETE = '/v1/management/Role/Delete';
const PATH = '/v1/accesscontrol/roles';
/**
* v1 API: "management" endpoints requests collection
*/
Expand All @@ -19,22 +17,23 @@ export const managementApi = {
const payload: Role = {
title, description, filter,
};
return (await (await apiHelper.post(ROLE_CREATE, payload)).json()).role_id as number;
return (await (await apiHelper.post(PATH, payload)).json()).role_id as number;
},

listRoles: async (): Promise<ListRoles> => {
return await (await apiHelper.post(ROLE_LIST, {})).json() as ListRoles;
return await (await apiHelper.get(PATH, {})).json() as ListRoles;
},

listServices: async (): Promise<any | undefined> => {
const response = await apiHelper.post('/v1/management/Service/List', {});
const response = await apiHelper.get('/v1/management/services', {});
return response.json();
},

async deleteRole(roleTile: string) {
const searchResult = (await this.listRoles()).roles.find((role: Role) => role.title === roleTile);
if (searchResult) {
await apiHelper.post(ROLE_DELETE, { role_id: searchResult.role_id, replacement_role_id: 1 });
const data = { role_id: searchResult.role_id, replacement_role_id: 1 };
await apiHelper.delete(`${PATH}/${searchResult.role_id}`, { data });
}
},
};
2 changes: 1 addition & 1 deletion playwright-tests/pages/page-components/network-tools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export default class NetworkTools {

// TODO: move it to api calls way
suppressTour = async () => {
await this.page.route('**/v1/user', async (route) => {
await this.page.route('**/v1/users/me', async (route) => {
await route.fulfill({
status: 200,
body: JSON.stringify({
Expand Down
7 changes: 3 additions & 4 deletions playwright-tests/tests/configuration/api/settings.api.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import apiHelper from '@api/helpers/api-helper';
import { APIResponse } from 'playwright-core';

const PATH_GET = 'v1/Settings/Get';
const PATH_CHANGE = 'v1/Settings/Change';
const PATH = 'v1/server/settings';

export interface Settings {
pmm_public_address: string;
Expand All @@ -28,12 +27,12 @@ export const settingsApi = {
* @returns if property found - property value; {@code undefined} otherwise
*/
async getSettingsProperty(name: SettingProperty): Promise<string | undefined> {
const responseBody: SettingObject = await (await apiHelper.post(PATH_GET, {})).json();
const responseBody: SettingObject = await (await apiHelper.post(PATH, {})).json();
console.log(`Response:\n${JSON.stringify(responseBody)}`);
return Object.hasOwn(responseBody.settings, name) ? responseBody.settings[name] as string : undefined;
},

changeSettings: async (settingsData: Settings): Promise<APIResponse> => {
return apiHelper.post(PATH_CHANGE, { data: settingsData });
return apiHelper.put(PATH, { data: settingsData });
},
};
3 changes: 2 additions & 1 deletion tests/DbaaS/verifyDBaaSPXCCluster_test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const assert = require('assert');
const { SERVICE_TYPE } = require('../helper/constants');

const { dbaasAPI, dbaasPage, locationsPage } = inject();
const clusterName = 'minikube';
Expand Down Expand Up @@ -167,7 +168,7 @@ Data(pxcDBClusterDetails).Scenario(

await dbaasPage.dbaasQANCheck(pxc_cluster_name, serviceName, serviceName);
await dbaasPage.pxcClusterMetricCheck(pxc_cluster_name, serviceName, serviceName, haproxyNodeName);
await dbaasPage.dbClusterAgentStatusCheck(pxc_cluster_name, serviceName, 'MYSQL_SERVICE');
await dbaasPage.dbClusterAgentStatusCheck(pxc_cluster_name, serviceName, SERVICE_TYPE.MYSQL);
},
);

Expand Down
2 changes: 1 addition & 1 deletion tests/DbaaS/verifyDbaaSMongoDBCluster_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ Scenario(

// await dbaasPage.psmdbClusterMetricCheck(psmdb_cluster, serviceName, serviceName, replSet);
// await dbaasPage.dbaasQANCheck(psmdb_cluster, serviceName, serviceName);
// await dbaasPage.dbClusterAgentStatusCheck(psmdb_cluster, serviceName, 'MONGODB_SERVICE');
// await dbaasPage.dbClusterAgentStatusCheck(psmdb_cluster, serviceName, SERVICE_TYPE.MONGODB);
// },
// );

Expand Down
2 changes: 1 addition & 1 deletion tests/QAN/api/qanAPI.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ module.exports = {
period_start_to: toTime,
totals: false,
};
const resp = await I.sendPostRequest('v0/qan/ObjectDetails/GetMetrics', data, headers);
const resp = await I.sendPostRequest('/v1/qan:getMetrics', data, headers);

return resp;
},
Expand Down
44 changes: 25 additions & 19 deletions tests/QAN/timerange_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,19 +43,19 @@ Scenario(
async ({
I, adminPage, queryAnalyticsPage,
}) => {
const date = moment().format('YYYY-MM-DD');
const fromString = Date.parse(`${date} 00:00:00`);
const toString = Date.parse(`${date} 23:59:59`);
const currentDate = moment();
const date = currentDate.format('YYYY-MM-DD');

await I.seeInCurrentUrl('from=now-5m&to=now');
await queryAnalyticsPage.data.selectRow(1);
queryAnalyticsPage.data.selectRow(1);
queryAnalyticsPage.waitForLoaded();
await I.seeElement(queryAnalyticsPage.data.root);
await adminPage.setAbsoluteTimeRange(`${date} 00:00:00`, `${date} 23:59:59`);
await I.seeInCurrentUrl(`from=${fromString}&to=${toString}`);
await queryAnalyticsPage.data.selectRow(1);
adminPage.setAbsoluteTimeRange(`${date} 00:00:00`, `${date} 23:59:59`);
queryAnalyticsPage.waitForLoaded();
await I.seeElement(queryAnalyticsPage.data.root);
adminPage.verifySelectedTimeRange(`${date} 00:00:00`, `${date} 23:59:59`);

const url = await I.grabCurrentUrl();

I.assertContain(url.split('from=')[1].replaceAll('%20', ' '), `${currentDate.format('ddd MMM DD YYYY')} 00:00:00`, 'From Date is not correct');
I.assertContain(url.split('to=')[1].replaceAll('%20', ' '), `${currentDate.format('ddd MMM DD YYYY')} 23:59:59`, 'To Date is not correct');
},
);

Expand Down Expand Up @@ -151,19 +151,25 @@ Scenario(
const to = dateTime.format('YYYY-MM-DD HH:mm:ss');
const from = moment(dateTime).subtract(1, 'hours').format('YYYY-MM-DD HH:mm:ss');

await adminPage.setAbsoluteTimeRange(from, to);
adminPage.setAbsoluteTimeRange(from, to);
queryAnalyticsPage.waitForLoaded();
await I.seeInCurrentUrl(`&from=${moment(from).format('ddd%20MMM%20D%20YYYY%20HH:mm:ss')}`);
await I.seeInCurrentUrl(`&to=${moment(to).format('ddd%20MMM%20D%20YYYY%20HH:mm:ss')}`);
I.waitForVisible(queryAnalyticsPage.buttons.copyButton);

const url = await I.grabCurrentUrl();

I.assertContain(url.split('from=')[1].replaceAll('%20', ' '), moment(from).format('ddd MMM DD YYYY HH:mm:ss'), 'Url does not contain selected from date time');
I.assertContain(url.split('to=')[1].replaceAll('%20', ' '), moment(to).format('ddd MMM DD YYYY HH:mm:ss'), 'Url does not contain selected to date time');

I.click(queryAnalyticsPage.buttons.copyButton);
const clipBoardUrl = await I.grabTextFrom(queryAnalyticsPage.elements.clipboardLink);

const url = await I.grabTextFrom(queryAnalyticsPage.elements.clipboardLink);
I.amOnPage(clipBoardUrl);
queryAnalyticsPage.waitForLoaded();
const secondUrl = await I.grabCurrentUrl();

adminPage.verifySelectedTimeRange(from, to);

await I.openNewTab();
await I.amOnPage(url.match(/\bhttps?:\/\/\S+/gi)[0]);
await I.seeInCurrentUrl(`&from=${moment(from).utc().format('ddd%20MMM%20D%20YYYY%20HH:mm:ss')}`);
await I.seeInCurrentUrl(`&to=${moment(to).utc().format('ddd%20MMM%20D%20YYYY%20HH:mm:ss')}`);
I.assertContain(secondUrl.split('from=')[1].replaceAll('%20', ' '), moment(from).utc().format('ddd MMM DD YYYY HH:mm:ss'), 'Second Url does not contain selected from date time');
I.assertContain(secondUrl.split('to=')[1].replaceAll('%20', ' '), moment(to).utc().format('ddd MMM DD YYYY HH:mm:ss'), 'Second Url does not contain selected to date time');
},
);

Expand Down
2 changes: 1 addition & 1 deletion tests/administration/serviceAccounts_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ Scenario('PMM-T1884 Verify disabling service account @service-account', async ({
await serviceAccountsPage.disableServiceAccount(serviceAccountUsername);
await I.wait(10);
const psContainerName = await I.verifyCommand('docker ps | grep ps_pmm | awk \'{print $NF}\'');
const responseDisabled = await I.verifyCommand(`sudo docker exec ${psContainerName} pmm-admin list`, '', 'fail');
const responseDisabled = await I.verifyCommand(`docker exec ${psContainerName} pmm-admin list`, '', 'fail');
const expectedDisabledMessage = 'Unauthorized. Please check username and password.';

I.assertEqual(
Expand Down
21 changes: 11 additions & 10 deletions tests/advisors/pages/api/advisorsAPI.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ module.exports = {
async getSecurityChecksResults() {
const headers = { Authorization: `Basic ${await I.getAuth()}` };

const resp = await I.sendPostRequest('v1/management/SecurityChecks/GetCheckResults', {}, headers);
const resp = await I.sendGetRequest('v1/advisor/checks', headers);

assert.ok(
resp.status === 200,
Expand All @@ -25,7 +25,7 @@ module.exports = {
const headers = { Authorization: `Basic ${await I.getAuth()}` };
const body = checkNamesArray ? { names: checkNamesArray } : {};

const resp = await I.sendPostRequest('v1/management/SecurityChecks/Start', body, headers);
const resp = await I.sendPostRequest('v1/advisors/checks:start', body, headers);

assert.ok(
resp.status === 200,
Expand All @@ -37,7 +37,7 @@ module.exports = {
const headers = { Authorization: `Basic ${await I.getAuth()}` };
const body = { service_id, page_params: { page_size: 25, index: 0 } };

const resp = await I.sendPostRequest('v1/management/SecurityChecks/FailedChecks', body, headers);
const resp = await I.sendPostRequest('v1/advisors/checks/failed', body, headers);

assert.ok(
resp.status === 200,
Expand All @@ -51,6 +51,7 @@ module.exports = {
const headers = { Authorization: `Basic ${await I.getAuth()}` };
const body = { alert_id, silence };

// todo: api-breaking-changes
const resp = await I.sendPostRequest('v1/management/SecurityChecks/ToggleCheckAlert', body, headers);

assert.ok(
Expand Down Expand Up @@ -104,7 +105,7 @@ module.exports = {
}],
};

const resp = await I.sendPostRequest('v1/management/SecurityChecks/Change', body, headers);
const resp = await I.sendPostRequest('v1/advisors/checks:batchChange', body, headers);

assert.ok(
resp.status === 200,
Expand All @@ -121,15 +122,15 @@ module.exports = {
}],
};

const resp = await I.sendPostRequest('v1/management/SecurityChecks/Change', body, headers);
const resp = await I.sendPostRequest('v1/advisors/checks:batchChange', body, headers);

assert.ok(
resp.status === 200,
`Failed to disable Security Check "${checkName}". Response message is "${resp.data.message}"`,
);
},

async changeCheckInterval(checkName, interval = 'FREQUENT') {
async changeCheckInterval(checkName, interval = 'ADVISOR_CHECK_INTERVAL_FREQUENT') {
const headers = { Authorization: `Basic ${await I.getAuth()}` };
const body = {
params: [{
Expand All @@ -138,7 +139,7 @@ module.exports = {
}],
};

const resp = await I.sendPostRequest('v1/management/SecurityChecks/Change', body, headers);
const resp = await I.sendPostRequest('v1/advisors/checks:batchChange', body, headers);

assert.ok(
resp.status === 200,
Expand All @@ -148,7 +149,7 @@ module.exports = {

async getAllChecksList() {
const headers = { Authorization: `Basic ${await I.getAuth()}` };
const resp = await I.sendPostRequest('v1/management/SecurityChecks/List', {}, headers);
const resp = await I.sendGetRequest('v1/advisors/checks', headers);

return resp.data.checks;
},
Expand All @@ -162,8 +163,8 @@ module.exports = {
await I.asyncWaitFor(this.getAllChecksList, 60);
const allChecks = await this.getAllChecksList();

allChecks.forEach(({ name }) => body.params.push({ name, interval: 'STANDARD' }));
const resp = await I.sendPostRequest('v1/management/SecurityChecks/Change', body, headers);
allChecks.forEach(({ name }) => body.params.push({ name, interval: 'ADVISOR_CHECK_INTERVAL_STANDARD' }));
const resp = await I.sendPostRequest('v1/advisors/checks:batchChange', body, headers);

assert.ok(
resp.status === 200,
Expand Down
6 changes: 3 additions & 3 deletions tests/advisors/stt/checksExecution_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ let serviceId;
const intervalsTests = new DataTable(['interval', 'intervalValue']);

// TODO: unskip after https://jira.percona.com/browse/PMM-8051
// intervalsTests.add(['frequent_interval', 'FREQUENT']);
intervalsTests.add(['standard_interval', 'STANDARD']);
// intervalsTests.add(['rare_interval', 'RARE']);
// intervalsTests.add(['frequent_interval', 'ADVISOR_CHECK_INTERVAL_FREQUENT']);
intervalsTests.add(['standard_interval', 'ADVISOR_CHECK_INTERVAL_STANDARD']);
// intervalsTests.add(['rare_interval', 'ADVISOR_CHECK_INTERVAL_RARE']);

const cleanup = async () => {
await settingsAPI.apiEnableSTT();
Expand Down
3 changes: 2 additions & 1 deletion tests/advisors/stt/databaseChecks_test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const assert = require('assert');
const { SERVICE_TYPE } = require('../../helper/constants');

const {
advisorsPage, databaseChecksPage, codeceptjsConfig, psMySql,
Expand Down Expand Up @@ -173,7 +174,7 @@ Scenario.skip(
I.see(psServiceName);
await inventoryAPI.verifyServiceExistsAndHasRunningStatus(
{
serviceType: 'MYSQL_SERVICE',
serviceType: SERVICE_TYPE.MYSQL,
service: 'mysql',
},
psServiceName,
Expand Down
Loading
Loading