Skip to content

Commit

Permalink
chore: add e2e tests for database info (#1786)
Browse files Browse the repository at this point in the history
  • Loading branch information
astandrik authored Dec 26, 2024
1 parent 01b8424 commit 7fca7d2
Show file tree
Hide file tree
Showing 3 changed files with 170 additions and 0 deletions.
6 changes: 6 additions & 0 deletions tests/suites/paginatedTable/paginatedTable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -245,3 +245,9 @@ export class ClusterStorageTable extends PaginatedTable {
super(page, '.ydb-cluster');
}
}

export class DiagnosticsNodesTable extends PaginatedTable {
constructor(page: Page) {
super(page, '.kv-tenant-diagnostics__page-wrapper');
}
}
63 changes: 63 additions & 0 deletions tests/suites/tenant/diagnostics/Diagnostics.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import type {Locator, Page} from '@playwright/test';

import {retryAction} from '../../../utils/retryAction';
import {MemoryViewer} from '../../memoryViewer/MemoryViewer';
import {NodesPage} from '../../nodes/NodesPage';
import {StoragePage} from '../../storage/StoragePage';
import {VISIBILITY_TIMEOUT} from '../TenantPage';

export enum DiagnosticsTab {
Expand All @@ -13,6 +16,7 @@ export enum DiagnosticsTab {
Tablets = 'Tablets',
HotKeys = 'Hot keys',
Describe = 'Describe',
Storage = 'Storage',
}

export class Table {
Expand Down Expand Up @@ -114,6 +118,9 @@ export enum QueriesSwitch {

export class Diagnostics {
table: Table;
storage: StoragePage;
nodes: NodesPage;
memoryViewer: MemoryViewer;

private tabs: Locator;
private schemaViewer: Locator;
Expand All @@ -122,8 +129,15 @@ export class Diagnostics {
private primaryKeys: Locator;
private refreshButton: Locator;
private autoRefreshSelect: Locator;
private cpuCard: Locator;
private storageCard: Locator;
private memoryCard: Locator;
private healthcheckCard: Locator;

constructor(page: Page) {
this.storage = new StoragePage(page);
this.nodes = new NodesPage(page);
this.memoryViewer = new MemoryViewer(page);
this.tabs = page.locator('.kv-tenant-diagnostics__tabs');
this.tableControls = page.locator('.ydb-table-with-controls-layout__controls');
this.schemaViewer = page.locator('.schema-viewer');
Expand All @@ -132,6 +146,12 @@ export class Diagnostics {
this.refreshButton = page.locator('button[aria-label="Refresh"]');
this.autoRefreshSelect = page.locator('.g-select');
this.table = new Table(page.locator('.object-general'));

// Info tab cards
this.cpuCard = page.locator('.metrics-cards__tab:has-text("CPU")');
this.storageCard = page.locator('.metrics-cards__tab:has-text("Storage")');
this.memoryCard = page.locator('.metrics-cards__tab:has-text("Memory")');
this.healthcheckCard = page.locator('.metrics-cards__tab:has-text("Healthcheck")');
}

async isSchemaViewerVisible() {
Expand Down Expand Up @@ -184,4 +204,47 @@ export class Diagnostics {
const optionLocator = this.autoRefreshSelect.locator(`text=${option}`);
await optionLocator.click();
}

async areInfoCardsVisible() {
await this.cpuCard.waitFor({state: 'visible', timeout: VISIBILITY_TIMEOUT});
await this.storageCard.waitFor({state: 'visible', timeout: VISIBILITY_TIMEOUT});
await this.memoryCard.waitFor({state: 'visible', timeout: VISIBILITY_TIMEOUT});
await this.healthcheckCard.waitFor({state: 'visible', timeout: VISIBILITY_TIMEOUT});
return true;
}

async getResourceUtilization() {
const cpuSystem = await this.cpuCard
.locator('.ydb-metrics-card__metric:has-text("System") .progress-viewer__text')
.textContent();
const cpuUser = await this.cpuCard
.locator('.ydb-metrics-card__metric:has-text("User") .progress-viewer__text')
.textContent();
const cpuIC = await this.cpuCard
.locator('.ydb-metrics-card__metric:has-text("IC") .progress-viewer__text')
.textContent();
const storage = await this.storageCard
.locator('.ydb-metrics-card__metric:has-text("SSD") .progress-viewer__text')
.textContent();
const memory = await this.memoryCard
.locator('.ydb-metrics-card__metric:has-text("Process") .progress-viewer__text')
.textContent();

return {
cpu: {
system: cpuSystem?.trim() || '',
user: cpuUser?.trim() || '',
ic: cpuIC?.trim() || '',
},
storage: storage?.trim() || '',
memory: memory?.trim() || '',
};
}

async getHealthcheckStatus() {
const statusElement = this.healthcheckCard.locator(
'.healthcheck__self-check-status-indicator',
);
return (await statusElement.textContent())?.trim() || '';
}
}
101 changes: 101 additions & 0 deletions tests/suites/tenant/diagnostics/diagnostics.test.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,114 @@
import {expect, test} from '@playwright/test';

import {dsVslotsSchema, tenantName} from '../../../utils/constants';
import {DiagnosticsNodesTable} from '../../paginatedTable/paginatedTable';
import {NavigationTabs, TenantPage} from '../TenantPage';
import {longRunningQuery} from '../constants';
import {QueryEditor} from '../queryEditor/models/QueryEditor';

import {Diagnostics, DiagnosticsTab, QueriesSwitch} from './Diagnostics';

test.describe('Diagnostics tab', async () => {
test('Info tab shows main page elements', async ({page}) => {
const pageQueryParams = {
schema: tenantName,
database: tenantName,
tenantPage: 'diagnostics',
};
const tenantPage = new TenantPage(page);
await tenantPage.goto(pageQueryParams);

const diagnostics = new Diagnostics(page);
await diagnostics.clickTab(DiagnosticsTab.Info);
await expect(diagnostics.areInfoCardsVisible()).resolves.toBe(true);
});

test('Info tab shows resource utilization', async ({page}) => {
const pageQueryParams = {
schema: tenantName,
database: tenantName,
tenantPage: 'diagnostics',
};
const tenantPage = new TenantPage(page);
await tenantPage.goto(pageQueryParams);

const diagnostics = new Diagnostics(page);
await diagnostics.clickTab(DiagnosticsTab.Info);

const utilization = await diagnostics.getResourceUtilization();
expect(utilization.cpu.system).toMatch(/\d+(\.\d+)? \/ \d+/);
expect(utilization.cpu.user).toMatch(/\d+(\.\d+)? \/ \d+/);
expect(utilization.cpu.ic).toMatch(/\d+(\.\d+)? \/ \d+/);
expect(utilization.storage).toBeTruthy();
expect(utilization.memory).toMatch(/\d+ \/ \d+\s*GB/);
});

test('Info tab shows healthcheck status', async ({page}) => {
const pageQueryParams = {
schema: tenantName,
database: tenantName,
tenantPage: 'diagnostics',
};
const tenantPage = new TenantPage(page);
await tenantPage.goto(pageQueryParams);

const diagnostics = new Diagnostics(page);
await diagnostics.clickTab(DiagnosticsTab.Info);

const status = await diagnostics.getHealthcheckStatus();
expect(status).toBe('GOOD');
});

test('Storage tab shows Groups and Nodes views', async ({page}) => {
const pageQueryParams = {
schema: tenantName,
database: tenantName,
tenantPage: 'diagnostics',
};
const tenantPage = new TenantPage(page);
await tenantPage.goto(pageQueryParams);

const diagnostics = new Diagnostics(page);
await diagnostics.clickTab(DiagnosticsTab.Storage);

// Check Groups view
await diagnostics.storage.selectEntityType('Groups');
await expect(diagnostics.storage.table).toBeVisible();

// Check Nodes view
await diagnostics.storage.selectEntityType('Nodes');
await expect(diagnostics.storage.table).toBeVisible();
});

test('Nodes tab shows nodes table with memory viewer', async ({page}) => {
const pageQueryParams = {
schema: tenantName,
database: tenantName,
tenantPage: 'diagnostics',
};
const tenantPage = new TenantPage(page);
await tenantPage.goto(pageQueryParams);

const diagnostics = new Diagnostics(page);
await diagnostics.clickTab(DiagnosticsTab.Nodes);

// Check nodes table is visible
await expect(diagnostics.nodes.table).toBeVisible();

// Enable Memory column to show memory viewer
const paginatedTable = new DiagnosticsNodesTable(page);
await paginatedTable.waitForTableVisible();
await paginatedTable.waitForTableData();
const controls = paginatedTable.getControls();
await controls.openColumnSetup();
await controls.setColumnChecked('Memory');
await controls.applyColumnVisibility();

// Check memory viewer is present and visible
await diagnostics.memoryViewer.waitForVisible();
await expect(diagnostics.memoryViewer.isVisible()).resolves.toBe(true);
});

test('Primary keys header is visible in Schema tab', async ({page}) => {
const pageQueryParams = {
schema: dsVslotsSchema,
Expand Down

0 comments on commit 7fca7d2

Please sign in to comment.