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

Add slow query E2E test #1141

Merged
merged 7 commits into from
Jan 17, 2022
Merged
Show file tree
Hide file tree
Changes from 2 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
15 changes: 9 additions & 6 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
backend_ut:
name: Backend Unit Test
runs-on: ubuntu-latest
timeout-minutes: 10
timeout-minutes: 20
steps:
- name: Checkout code
uses: actions/checkout@v2
Expand Down Expand Up @@ -113,11 +113,8 @@ jobs:
${{ runner.os }}-tiup
- name: Install and run TiUP in the background
run: |
curl --proto '=https' --tlsv1.2 -sSf https://tiup-mirrors.pingcap.com/install.sh | sh
source /home/runner/.profile
tiup update playground
source /home/runner/.profile
tiup playground ${{ matrix.tidb_version }} --tiflash=0 &
chmod u+x scripts/start_tiup.sh
scripts/start_tiup.sh ${{ matrix.tidb_version }}
- name: Build UI
run: |
make ui
Expand Down Expand Up @@ -155,6 +152,12 @@ jobs:
SERVER_URL: http://127.0.0.1:12333/dashboard/
CI: true
FEATURE_VERSION: ${{ matrix.feature_version }}
TIDB_VERSION: ${{ matrix.tidb_version }}
- name: Archive Test Results
if: always()
run: |
cat ui/start_tiup.log
cat ui/wait_tiup.log
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v2
with:
Expand Down
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,10 @@ run:

test_e2e_compat_features:
cd ui &&\
yarn run:e2e-test:compat-features --env FEATURE_VERSION=$(FEATURE_VERSION)
yarn run:e2e-test:compat-features --env FEATURE_VERSION=$(FEATURE_VERSION) TIDB_VERSION=$(TIDB_VERSION)

test_e2e_common_features:
cd ui &&\
yarn run:e2e-test:common-features
yarn run:e2e-test:common-features TIDB_VERSION=$(TIDB_VERSION)

test_e2e: test_e2e_compat_features test_e2e_common_features
28 changes: 28 additions & 0 deletions scripts/start_tiup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/usr/bin/env bash
set -ex
tidb_version=$1
mode=$2

if [ $mode = "restart" ]; then
# get process id
pid=$(ps -ef | grep -v start_tiup | grep tiup | grep -v grep | awk '{print $2}')

for id in $pid
do
# kill tiup-playground
echo "killing $id"
kill -9 $id;
done
else
echo "install tiup"
# Install TiUP
curl --proto '=https' --tlsv1.2 -sSf https://tiup-mirrors.pingcap.com/install.sh | sh
source /home/runner/.profile
tiup update playground
source /home/runner/.profile
fi

# Run Tiup
sleep 3
source /home/runner/.profile
tiup playground ${tidb_version} --tiflash=0 &> start_tiup.log &
shhdgit marked this conversation as resolved.
Show resolved Hide resolved
1 change: 1 addition & 0 deletions ui/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ cypress/screeshots
cypress/integration/1-getting-started
cypress/integration/2-advanced-examples
.nyc_output
*.log

# production
build/
Expand Down
11 changes: 8 additions & 3 deletions ui/cypress.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
{
"defaultCommandTimeout": 60000,
"defaultCommandTimeout": 120000,
"responseTimeout": 60000,
"requestTimeout": 60000,
"screenshotOnRunFailure": false,
"video": false,
"env": {
"FEATURE_VERSION": "6.0.0"
}
"FEATURE_VERSION": "6.0.0",
"TIDB_VERSION": "nightly"
},
"experimentalSessionSupport": true,
"viewportWidth": 1500,
"viewportHeight": 1000
Comment on lines +12 to +13
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

}
3 changes: 2 additions & 1 deletion ui/cypress/fixtures/uri.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"root": "/",
"login": "/signin",
"overview": "/overview"
"overview": "/overview",
"slow_query": "/slow_query"
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,19 @@ describe('Root User Login', () => {

it('root login with correct pwd', function () {
// set password for root
let query = "SET PASSWORD FOR 'root'@'%' = 'root_pwd'"
let password = ''
cy.task('queryDB', { query, password })
let queryData = {
query: 'SET PASSWORD FOR "root"@"%" = "root_pwd"',
}
cy.task('queryDB', { ...queryData })

cy.get('[data-e2e="signin_password_input"]').type('root_pwd{enter}')
cy.url().should('include', `${this.uri.overview}`)

// set empty password for root
query = "SET PASSWORD FOR 'root'@'%' = ''"
password = 'root_pwd'
cy.task('queryDB', { query, password })
queryData = {
query: 'SET PASSWORD FOR "root"@"%" = ""',
password: 'root_pwd',
}
cy.task('queryDB', { ...queryData })
})
})
210 changes: 210 additions & 0 deletions ui/cypress/integration/common-features/slow_query/list_spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
// Copyright 2021 PingCAP, Inc. Licensed under Apache-2.0.
Copy link
Member

@shhdgit shhdgit Jan 17, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about organizing the code by functional modules. So that we can reduce some directory nesting and /__image_snapshots__ that generated by https://github.com/meinaart/cypress-plugin-snapshots can also be organized by functional modules.

Like:

/ui/cypress/integration/slow_query/list.spec.js
/ui/cypress/integration/slow_query/list.compat_spec.js
...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I will update the organization.


import dayjs from 'dayjs'

describe('SlowQuery list page', () => {
before(() => {
cy.fixture('uri.json').then(function (uri) {
this.uri = uri
})
})

beforeEach(function () {
cy.login('root')
cy.visit(this.uri.slow_query)
})

describe('Initialize slow query page', () => {
it('Restart tiup', () => {
cy.exec(
`bash ../scripts/start_tiup.sh ${Cypress.env('TIDB_VERSION')} restart`,
{ log: true }
)
})

it('Wait TiUP Playground', () => {
cy.exec('bash ../scripts/wait_tiup_playground.sh 1 300 &> wait_tiup.log')
})

it('Slow query side bar highlighted', () => {
cy.get('[data-e2e=menu_item_slow_query]').should(
'has.class',
'ant-menu-item-selected'
)
})

it('Has Toolbar', function () {
cy.get('[data-e2e=slow_query_toolbar]').should('be.visible')
})

it('Get slow query bad request', () => {
const staticResponse = {
statusCode: 400,
body: {
code: 'common.bad_request',
error: true,
message: 'common.bad_request',
},
}

// stub out a response body
cy.intercept(
`${Cypress.env('apiUrl')}slow_query/list*`,
staticResponse
).as('slow_query_list')
cy.wait('@slow_query_list').then((res) => {
cy.get('[data-e2e=alert_error_bar] > span:nth-child(2)').should(
'has.text',
staticResponse.body.message
)
})
})
})

describe('Filter slow query list', () => {
it('Run workload', () => {
let queryData = {
query: 'SET tidb_slow_log_threshold = 500',
}
cy.task('queryDB', { ...queryData })

const workloads = [
'SELECT SLEEP(1);',
'SELECT SLEEP(0);',
'SELECT SLEEP(0.8);',
]

workloads.forEach((query) => {
cy.task('queryDB', { query }).as('query')
cy.get('@query')
})
})

describe('Filter slow query by changing time range', () => {
const now = dayjs().unix()
let defaultSlowQueryList
let firstSlowQueryTimeStamp
let firstSec, secondSec, thirdSec

it('Default time range is 30 mins', () => {
cy.get('[data-e2e=selected_timerange]').should(
'has.text',
'Recent 30 min'
)
})

it('Show all slow_query', () => {
const options = {
url: `${Cypress.env('apiUrl')}slow_query/list`,
qs: {
begin_time: now - 1800,
desc: true,
end_time: now + 100,
fields: 'query,timestamp,query_time,memory_max',
limit: 100,
orderBy: 'timestamp',
},
}

cy.request(options).as('slow_query')

cy.get('@slow_query').then((response) => {
defaultSlowQueryList = response.body
if (defaultSlowQueryList.length > 0) {
firstSlowQueryTimeStamp =
defaultSlowQueryList[defaultSlowQueryList.length - 1].timestamp

firstSec = dayjs
.unix(firstSlowQueryTimeStamp)
.format('YYYY-MM-DD HH:mm:ss')
secondSec = dayjs
.unix(firstSlowQueryTimeStamp + 1)
.format('YYYY-MM-DD HH:mm:ss')
thirdSec = dayjs
.unix(firstSlowQueryTimeStamp + 2)
.format('YYYY-MM-DD HH:mm:ss')
}
})
})

describe('Check slow query', () => {
it('Check slow query in the 1st second time range', () => {
cy.get('[data-e2e=timerange-selector]')
.click()
.then(() => {
cy.get('.ant-picker-range').click()
cy.get('.ant-picker-input-active > input').type(
`${firstSec}{leftarrow}{leftarrow}{backspace}{enter}`
)
cy.get('.ant-picker-input-active > input').type(
`${secondSec}{leftarrow}{leftarrow}{backspace}{enter}`
)
cy.get('[data-automation-key=query]')
.should('has.length', 1)
.and('has.text', 'SELECT SLEEP(1);')
})
})

it('Check slow query in the 2nd second time range', () => {
cy.get('[data-e2e=timerange-selector]')
.click()
.then(() => {
cy.get('.ant-picker-range').click()
cy.get('.ant-picker-input-active > input').type(
`${secondSec}{leftarrow}{leftarrow}{backspace}{enter}`
)
cy.get('.ant-picker-input-active > input').type(
`${thirdSec}{leftarrow}{leftarrow}{backspace}{enter}`
)

cy.get('[data-automation-key=query]')
.should('has.length', 1)
.and('has.text', 'SELECT SLEEP(0.8);')
})
})

it('Check slow query in the latest 2 seconds time range', () => {
cy.get('[data-e2e=timerange-selector]')
.click()
.then(() => {
cy.get('.ant-picker-range').click()
cy.get('.ant-picker-input-active > input').type(
`${firstSec}{leftarrow}{leftarrow}{backspace}{enter}`
)
cy.get('.ant-picker-input-active > input').type(
`${thirdSec}{leftarrow}{leftarrow}{backspace}{enter}`
)

cy.get('[data-automation-key=query]').should('has.length', 2)
})
})
})
})

describe('Filter slow query by changing database', () => {
it('No database selected by default', () => {
cy.get('[data-e2e=base_select_input]').should('has.text', '')
})

const options = {
url: `${Cypress.env('apiUrl')}info/databases/`,
}

it('Show all databases', () => {
cy.request(options).as('databases')

cy.get('@databases').then((response) => {
const databaseList = response.body
cy.get('[data-e2e=base_select_input]')
.click()
.then(() => {
cy.get('[data-e2e=multi_select_options_label]').should(
'have.length',
databaseList.length
)
})
})
})
})
})
})
20 changes: 13 additions & 7 deletions ui/cypress/integration/compatibility-features/user_login_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,21 @@ describe('User Login', () => {
if (Cypress.env('FEATURE_VERSION') === '6.0.0') {
// Create user test
before(() => {
let query = "DROP USER IF EXISTS 'test'@'%'"
let password = ''
cy.task('queryDB', { query, password })
let queryData = {
query: 'DROP USER IF EXISTS "test"@"%"',
}
cy.task('queryDB', { ...queryData })

query = "CREATE USER 'test'@'%' IDENTIFIED BY 'test_pwd'"
cy.task('queryDB', { query, password })
queryData = {
query: "CREATE USER 'test'@'%' IDENTIFIED BY 'test_pwd'",
}

query = "GRANT ALL PRIVILEGES ON *.* TO 'test'@'%' WITH GRANT OPTION"
cy.task('queryDB', { query, password })
cy.task('queryDB', { ...queryData })

queryData = {
query: "GRANT ALL PRIVILEGES ON *.* TO 'test'@'%' WITH GRANT OPTION",
}
cy.task('queryDB', { ...queryData })
})

// Run before each test
Expand Down
Loading