-
Notifications
You must be signed in to change notification settings - Fork 622
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
Testing infra for metalkubed #1886
Conversation
Hi @ukalifon. Thanks for your PR. I'm waiting for a openshift member to verify that this patch is reasonable to test. If it is, they should reply with Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
/ok-to-test |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should remove uses of xpath and avoid complicated, fragile selectors. Add data-test-id
attributes where needed to simplify the tests.
/retest |
2a13aec
to
e7d846d
Compare
/test ci/prow/e2e-aws |
import { execSync } from 'child_process'; | ||
import { logIn } from './utils/utils'; | ||
|
||
describe('Authentication', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm unclear why we need a special login scenario for kubevirt. Can you elaborate?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@spadgett We had to add special login because the login page was different in web-ui and openshift/console at certain point in the past, so login scenario from console didn't work.
Although this is not an issue now, I don't see why plugin related test suites should be running whole console login scenario.
I would prefer having some prerequisite that handles the login quickly rather than executing the whole console login scenario that is executed as a part of different suite anyway.
await browser.get(appHost); | ||
if (process.env.BRIDGE_BASE_ADDRESS !== undefined) { | ||
await logIn(); | ||
execSync(`oc login -u ${process.env.BRIDGE_AUTH_USERNAME} -p ${process.env.BRIDGE_AUTH_PASSWORD} --config=${process.env.KUBECONFIG}`); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
config=${process.env.KUBECONFIG}
should be unnecessary. oc
will already read the env var.
export const WIZARD_TABLE_FIRST_ROW = 1; | ||
|
||
// Tab names | ||
export const TABS = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would use Object.freeze
on all of these to avoid accidentally mutating them in the tests
NICS: 'Network Interfaces', | ||
}; | ||
|
||
// Network tab columns in VM Wizard |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be much better to include data-test-id
in the columns so we don't need to hard-code each index. It makes the test more robust when things change.
|
||
// TIMEOUTS | ||
const SEC = 1000; | ||
export const CLONE_VM_TIMEOUT = 300 * SEC; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would put SECONDS
in each of these names to make it obvious what the unit is where it's used.
export const CLONE_VM_TIMEOUT = 300 * SEC; | |
export const CLONE_VM_TIMEOUT_SECONDS = 300 * SEC; |
}; | ||
|
||
// eslint-disable-next-line eqeqeq | ||
export const resolveTimeout = (timeout, defaultTimeout) => timeout != undefined ? timeout : defaultTimeout; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't protractor use the default timeout already if none is specified? I'm unclear why this is needed at all.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@spadgett This was not intended to use protractor default value as default.
Use case: consider an action that usually takes certain amount of time (starting cirros VM for example), but sometimes we want to start Windows or CentOS VM, which takes more time. So start action has defined default timeout (different from the protractor default) for starting a VM and for special cases a different timeout can be passed to the method.
beforeAll(async() => { | ||
await browser.get(`${appHost}/dashboards`); | ||
await dashboardView.isLoaded(); | ||
browser.sleep(10000); // the counters on the page start updating late... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
arbitrary sleeps are not good. we should wait until the data appears
const output = execSync('oc get nodes', { encoding: 'utf-8' }); | ||
const lines = output.split('\n'); | ||
lines.forEach(function(line) { | ||
if (line.indexOf(' Ready ') > 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Better to use -o json
and check the JSON values
const lines = output.split('\n').slice(1); // slice(1) to ignore the 1st line of output | ||
lines.forEach(function(line) { | ||
if (line.trim().length > 1) { | ||
if (line.indexOf(' OK ') > 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment here. Please use -o json
* await dashboardView.sysEventTime(0).getText() | ||
*/ | ||
export function sysEventTime(rowNumber) { | ||
return element(by.xpath(`(//div[@class="co-sysevent__header"])[${rowNumber + 1}]/small`)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
avoid xpath, here and below. add data-test-id
if needed
e7d846d
to
d8b0101
Compare
d8b0101
to
b5430ca
Compare
import { appHost } from '../../protractor.conf'; | ||
import * as dashboardView from '../../views/metalkube/dashboards.view'; | ||
|
||
async function compareCounters(elem, expectedValue) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe just compareCounter
since it only takes one element.
b5430ca
to
50607a5
Compare
await browser.get(`${appHost}/dashboards`); | ||
await dashboardView.isLoaded(); | ||
// wait until the counters in the inventory card show up | ||
while (!(dashboardView.inventoryNodesUpCounter.isPresent() || dashboardView.inventoryNodesDownCounter.isPresent()) || |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The negations are quite hard to read. Are we waiting for all the counters to be present?
I think ExpectedConditions is the way to go
await browser.wait(
until.and(
dashboardView.inventoryNodesUpCounter.isPresent(),
dashboardView.inventoryNodesDownCounter.isPresent(),
dashboardView.inventoryHostsUpCounter.isPresent(),
dashboardView.inventoryHostsDownCounter.isPresent(),
), 15000 // the timeout that we're willing to wait for all these elements
);
be8d78e
to
2e47a2c
Compare
2e47a2c
to
aee82a4
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any dashboard specific tests suite already? It seems that the scenario which you're introducing could be split into a dashboard suite and metal3-plugin suite. metal3-plugin suite should hold tests which are specific to the baremetal environment.
@@ -113,6 +113,7 @@ export const config: Config = { | |||
return new Promise((resolve) => htmlReporter.afterLaunch(resolve.bind(this, exitCode))); | |||
}, | |||
suites: { | |||
baremetalSmokeTests: ['tests/metalkube/dashboard.scenario.ts'], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To follow the convention which kubevirt-plugin set it would be good to call this metal3-plugin
and colocate the metal3-plugin tests into the plugin - move the test modules into frontend/packages/metal3-plugin/integration-tests
and reference them here as
metal3-plugin: ['../packages/metal3-plugin/integration-tests/tests/dashboard.scenario.ts'],
aee82a4
to
04357dc
Compare
04357dc
to
0bb41be
Compare
@@ -102,7 +111,14 @@ const InventoryItem: React.FC<InventoryItemProps> = React.memo( | |||
</AccordionItem> | |||
</Accordion> | |||
) : ( | |||
<<<<<<< HEAD |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rebase leftover
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
<ClusterInventoryItem | ||
model={PersistentVolumeClaimModel} | ||
mapper={getPVCStatusGroups} | ||
useAbbr | ||
/> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one should not have been removed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It wasn't. it's down below at line 142
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was wrong, fixed it.
0bb41be
to
d6450fe
Compare
@@ -102,7 +111,10 @@ const InventoryItem: React.FC<InventoryItemProps> = React.memo( | |||
</AccordionItem> | |||
</Accordion> | |||
) : ( | |||
<div className="co-inventory-card__item"> | |||
<div | |||
className="co-inventory-card__item co-inventory-card__item--border" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The second class should not be there
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not? I didn't add it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This diff clearly shows you did :) It is a result of an incorrect rebase. The co-inventory-card__item--border
class was recently removed by another patch and when you rebased, it is being unintentionally added back.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed. Thanks
d6450fe
to
97d84f6
Compare
<ClusterInventoryItem | ||
model={PersistentVolumeClaimModel} | ||
mapper={getPVCStatusGroups} | ||
useAbbr | ||
/> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To preserve the order of the ClusterInventoryItems, this should go after StorageClassModel ClusterInventoryItem. Also data-test-id
prop should get added to this item as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
c17a5dd
to
2657874
Compare
This needs to get updated to conform to #2051 |
This is the basic Protractor (Selenium) infrastructure to test the dashboards. Included is also a small test to read some of the counters in the dashboards page, and compare them to what we get from the CLI. This PR includes PRs 2287 and 2288 from Dan Trainor, who added custom data-test-id attributes on the elements inthe dashboards, to support the automation so it will be easier to find the elements. Also huge thanks to Honza Pokorny, Jason Rist and Jiri Tomasek who helped with the code and with rebases. Basic steps to run the tests: yarn install yarn webdriver-update export BRIDGE_BASE_ADDRESS='https://*.*.*.redhat.com' export BRIDGE_AUTH_USERNAME=kubeadmin export BRIDGE_AUTH_PASSWORD=22Z.... oc login -s *.*.*.redhat.com:6443 -u kubeadmin -p 22ZW.... export KUBECONFIG=/home/ukalifon/.kube/config export NO_HEADLESS=true # optional - if you want to see the browser yarn run test-suite --suite baremetalSmokeTests --params.openshift true
2657874
to
7a7209d
Compare
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: ukalifon The full list of commands accepted by this bot can be found here.
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
Issues go stale after 90d of inactivity. Mark the issue as fresh by commenting If this issue is safe to close now please do so with /lifecycle stale |
@ukalifon: The following tests failed, say
Full PR test history. Your PR dashboard. Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here. |
This is the basic Protractor (Selenium) infrastructure we use to test
the baremetal features in the web-ui fork. It is dependent on some
kubevirt code which is shared among the infrastructures, so those deps
are part of this PR as well.
The actual test is in tests/metalkube/dashboard.scenario.ts and it only
reads some of the counters in the dashboards page, and compares them to
what we get from the CLI.
The test might currently fail because not all functionality from the
web-ui has been merged into console yet (it's a long WIP). The test
should pass when the merge is done, as you can see when running the
test against a web-ui instance:
yarn install
yarn webdriver-update
export BRIDGE_BASE_ADDRESS='https://...redhat.com'
export BRIDGE_AUTH_USERNAME=kubeadmin
export BRIDGE_AUTH_PASSWORD=22Z....
oc login -s ...redhat.com:6443 -u kubeadmin -p 22ZW....
export KUBECONFIG=/home/ukalifon/.kube/config
yarn run test-suite --suite baremetalSmokeTests --params.openshift true