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

[Backport 2.19] [Backport #1689] Onboard query insights dashboards onto functional test repo (#1689) #1692

Merged
merged 1 commit into from
Feb 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
24 changes: 24 additions & 0 deletions .github/workflows/query-insights-dashboards-e2e-workflow.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Query Insights Dashboards Release tests workflow in Bundled OpenSearch Dashboards
on:
pull_request:
branches: [ '**' ]
jobs:
changes:
runs-on: ubuntu-latest
outputs:
tests: ${{ steps.filter.outputs.tests }}
steps:
- uses: dorny/paths-filter@v2
id: filter
with:
filters: |
tests:
- 'cypress/**/query-insights-dashboards/**'

tests:
needs: changes
if: ${{ needs.changes.outputs.tests == 'true' }}
uses: ./.github/workflows/release-e2e-workflow-template.yml
with:
test-name: Query Insights Dashboards
test-command: env CYPRESS_NO_COMMAND_LOG=1 yarn cypress:run-with-security --browser chromium --spec 'cypress/integration/plugins/query-insights-dashboards/*'
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"@timestamp": "2099-11-15T13:12:00",
"message": "this is document 0",
"user": {
"id": "user1",
"name": "John Doe",
"email": "[email protected]",
"roles": ["admin", "editor"]
},
"request": {
"method": "GET",
"url": "/api/v1/resource",
"status": 200,
"response_time_ms": 123,
"headers": {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
"Authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5..."
}
},
"location": {
"ip": "192.168.1.1",
"city": "Seattle",
"region": "Washington",
"country": "US"
},
"application": {
"name": "OpenSearch Dashboard",
"version": "2.8.0",
"environment": "production"
},
"event": {
"id": "event123",
"type": "user_action",
"outcome": "success",
"reason": null
},
"tags": ["login", "dashboard", "analytics"],
"metrics": {
"cpu_usage": 2.4,
"memory_usage": 512,
"disk_space_remaining": 1048576
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import sampleDocument from '../../../fixtures/plugins/query-insights-dashboards/sample_document.json';
import { QUERY_INSIGHTS_METRICS } from '../../../utils/constants';

// Name of the test index used in tests
const indexName = 'sample_index';

/**
Helper function to clean up the environment:
- Deletes the test index.
- Disables the top queries features.
*/
const clearAll = () => {
cy.deleteIndexByName(indexName);
cy.disableTopQueries(QUERY_INSIGHTS_METRICS.LATENCY);
cy.disableTopQueries(QUERY_INSIGHTS_METRICS.CPU);
cy.disableTopQueries(QUERY_INSIGHTS_METRICS.MEMORY);
};

describe('Query Insights Dashboard', () => {
// Setup before each test
beforeEach(() => {
clearAll();
cy.createIndexByName(indexName, sampleDocument);
cy.enableTopQueries(QUERY_INSIGHTS_METRICS.LATENCY);
cy.enableTopQueries(QUERY_INSIGHTS_METRICS.CPU);
cy.enableTopQueries(QUERY_INSIGHTS_METRICS.MEMORY);
cy.searchOnIndex(indexName);
// wait for 1s to avoid same timestamp
cy.wait(1000);
cy.searchOnIndex(indexName);
cy.wait(1000);
cy.searchOnIndex(indexName);
// waiting for the query insights queue to drain
cy.wait(10000);
cy.navigateToOverview();
});

/**
* Validate the main overview page loads correctly
*/
it('should display the main overview page', () => {
cy.get('.euiBasicTable').should('be.visible');
cy.contains('Query insights - Top N queries');
cy.url().should('include', '/queryInsights');

// should display the query table on the overview page
cy.get('.euiBasicTable').should('be.visible');
cy.get('.euiTableHeaderCell').should('have.length.greaterThan', 0);
// should have top n queries displayed on the table
cy.get('.euiTableRow').should('have.length.greaterThan', 0);
});

it('should switch between tabs', () => {
// Click Configuration tab
cy.getElementByText('.euiTab', 'Configuration').click({ force: true });
cy.contains('Query insights - Configuration');
cy.url().should('include', '/configuration');

// Click back to Query Insights tab
cy.getElementByText('.euiTab', 'Top N queries').click({ force: true });
cy.url().should('include', '/queryInsights');
});

it('should filter queries', () => {
cy.get('.euiFieldSearch').should('be.visible');
cy.get('.euiFieldSearch').type('sample_index');
// Add assertions for filtered results
cy.get('.euiTableRow').should('have.length.greaterThan', 0);
});

it('should clear the search input and reset results', () => {
cy.get('.euiFieldSearch').type('random_string');
cy.get('.euiTableRow').should('have.length.greaterThan', 0);
cy.get('.euiFieldSearch').clear();
cy.get('.euiTableRow').should('have.length.greaterThan', 0); // Validate reset
});

it('should display a message when no top queries are found', () => {
clearAll(); // disable top n queries
// waiting for the query insights queue to drain
cy.wait(10000);
cy.reload();
cy.contains('No items found');
});

after(() => clearAll());
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import sampleDocument from '../../../fixtures/plugins/query-insights-dashboards/sample_document.json';
import { QUERY_INSIGHTS_METRICS } from '../../../utils/constants';

const indexName = 'sample_index';

const clearAll = () => {
cy.deleteIndexByName(indexName);
cy.disableTopQueries(QUERY_INSIGHTS_METRICS.LATENCY);
cy.disableTopQueries(QUERY_INSIGHTS_METRICS.CPU);
cy.disableTopQueries(QUERY_INSIGHTS_METRICS.MEMORY);
};

describe('Top Queries Details Page', () => {
beforeEach(() => {
clearAll();
cy.createIndexByName(indexName, sampleDocument);
cy.enableTopQueries(QUERY_INSIGHTS_METRICS.LATENCY);
cy.enableTopQueries(QUERY_INSIGHTS_METRICS.CPU);
cy.enableTopQueries(QUERY_INSIGHTS_METRICS.MEMORY);
cy.searchOnIndex(indexName);
cy.searchOnIndex(indexName);
cy.searchOnIndex(indexName);
// waiting for the query insights queue to drain
cy.wait(10000);
cy.navigateToOverview();
cy.wait(10000);
cy.get('.euiTableRow').first().find('button').first().trigger('mouseover');
cy.wait(1000);
cy.get('.euiTableRow').first().find('button').first().click(); // Navigate to details
cy.wait(1000);
});

it('should display correct details on the query details page', () => {
// cy.get('.euiBasicTable a').first().click(); // Navigate to details
cy.url().should('include', '/query-details');
// Validate the page title
cy.get('h1').contains('Query details').should('be.visible');
// Validate the summary section
cy.get('[data-test-subj="query-details-summary-section"]').should(
'be.visible'
);
// Validate the presence of latency chart
cy.get('[data-test-subj="query-details-latency-chart"]').should(
'be.visible'
);
// Validate the presence of query source details section
cy.get('[data-test-subj="query-details-source-section"]').should(
'be.visible'
);
});

/**
* Validate summary panel has valid labels
*/
it('the summary panel should display correctly', () => {
// Validate all field labels exist
const fieldLabels = [
'Timestamp',
'Latency',
'CPU Time',
'Memory Usage',
'Indices',
'Search Type',
'Coordinator Node ID',
'Total Shards',
];
fieldLabels.forEach((label) => {
cy.get('.euiPanel').contains('h4', label).should('be.visible');
});
});

/**
* Validate each field in the summary panel has valid content
*/
it('should display correct values for all fields in the summary panel', () => {
cy.get('[data-test-subj="query-details-summary-section"]').within(() => {
// Validate Timestamp
cy.contains('h4', 'Timestamp')
.parent()
.next()
.invoke('text')
.should('match', /\w{3} \d{2}, \d{4} @ \d{1,2}:\d{2}:\d{2} [AP]M/);
// Validate Latency
cy.contains('h4', 'Latency')
.parent()
.next()
.invoke('text')
.should('match', /^\d+(\.\d{1,2})? ms$/);
// Validate CPU Time
cy.contains('h4', 'CPU Time')
.parent()
.next()
.invoke('text')
.should('match', /^\d+(\.\d+)? ms$/);
// Validate Memory Usage
cy.contains('h4', 'Memory Usage')
.parent()
.next()
.invoke('text')
.should('match', /^\d+(\.\d+)? B$/);
// Validate Indices
cy.contains('h4', 'Indices')
.parent()
.next()
.invoke('text')
.should('not.be.empty');
// Validate Search Type
cy.contains('h4', 'Search Type')
.parent()
.next()
.invoke('text')
.should('equal', 'query then fetch');
// Validate Coordinator Node ID
cy.contains('h4', 'Coordinator Node ID')
.parent()
.next()
.invoke('text')
.should('not.be.empty');
// Validate Total Shards
cy.contains('h4', 'Total Shards')
.parent()
.next()
.invoke('text')
.then((text) => {
const shardCount = parseInt(text.trim(), 10);
expect(shardCount).to.be.a('number').and.to.be.greaterThan(0);
});
});
});

/**
* Validate the latency chart interaction
*/
it('should render the latency chart and allow interaction', () => {
// Ensure the chart is visible
cy.get('#latency').should('be.visible');
cy.get('.plot-container').should('be.visible');
// Simulate hover over the chart for a data point
cy.get('#latency').trigger('mousemove', { clientX: 100, clientY: 100 });
});

after(() => clearAll());
});
Loading
Loading