WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Commit 4d127ea

Browse files
authored
Merge pull request #205 from MalloZup/qa-tests
Qa tests
2 parents 5c1edcf + e90fd31 commit 4d127ea

File tree

14 files changed

+1061
-1
lines changed

14 files changed

+1061
-1
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ http://hawk-ui.github.io
1717
- [Release](doc/release.md)
1818
- [Installation](#installation-and-deployment)
1919
- [Devel notes](#devel)
20+
- [Testing](e2e_test/README.md)
2021

2122
## Build Dependencies
2223

@@ -88,4 +89,3 @@ server instance runs as).
8889
of Pacemaker CLI tools as another user in order to support Pacemaker's
8990
ACL feature. It is used by Hawk when performing various management
9091
tasks.
91-

e2e_test/.dockerignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.git
2+
**/__pycache__
3+
**/*.pyc

e2e_test/.pylintrc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[MESSAGES CONTROL]
2+
disable=missing-docstring,line-too-long,too-many-public-methods,too-many-instance-attributes,too-many-arguments,too-many-statements,too-few-public-methods

e2e_test/.travis.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
language: python
2+
3+
services:
4+
- docker
5+
6+
dist: xenial
7+
8+
python:
9+
- "3.5"
10+
- "3.6"
11+
- "3.7"
12+
- "3.8"
13+
14+
install:
15+
- pip install -r requirements-test.txt
16+
17+
script:
18+
- make test
19+
- make test-docker

e2e_test/AUTHORS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[email protected] @atighineanu
2+
[email protected] @alvarocarvajald
3+
[email protected] @ricardobranco777

e2e_test/Dockerfile

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Defines the tag for OBS and build script builds:
2+
#!BuildTag: hawk_test
3+
# Use the repositories defined in OBS for installing packages
4+
#!UseOBSRepositories
5+
FROM opensuse/tumbleweed
6+
7+
RUN zypper -n install -y --no-recommends \
8+
MozillaFirefox \
9+
MozillaFirefox-branding-upstream \
10+
chromium \
11+
file \
12+
python3 \
13+
python3-paramiko \
14+
python3-PyVirtualDisplay \
15+
python3-selenium \
16+
shadow \
17+
xauth \
18+
xdpyinfo \
19+
xorg-x11-fonts \
20+
xorg-x11-server-Xvfb && \
21+
zypper -n clean -a
22+
23+
RUN zypper -n install -y --no-recommends wget tar gzip
24+
RUN zypper -n clean -a
25+
RUN wget https://github.com/mozilla/geckodriver/releases/download/v0.26.0/geckodriver-v0.26.0-linux64.tar.gz
26+
RUN tar xvf geckodriver-v0.26.0-linux64.tar.gz
27+
RUN mv geckodriver /usr/local/bin
28+
RUN chmod +x /usr/local/bin/*
29+
30+
RUN useradd -l -m -d /test test
31+
32+
COPY *.py /
33+
34+
ENV PYTHONPATH /
35+
ENV PYTHONUNBUFFERED 1
36+
ENV DBUS_SESSION_BUS_ADDRESS /dev/null
37+
38+
WORKDIR /test
39+
40+
USER test
41+
ENTRYPOINT ["/usr/bin/python3", "/hawk_test.py"]

e2e_test/Makefile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
test:
2+
@flake8 --ignore=E501
3+
@pylint --ignored-modules=distutils *.py
4+
5+
test-docker:
6+
@docker build -t hawk_test -f Dockerfile.alpine .
7+
@docker run --rm hawk_test --help

e2e_test/README.md

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# Hawk end to end tests.
2+
3+
This Docker image runs a set of Selenium tests for testing [Hawk](https://github.com/ClusterLabs/hawk/)
4+
5+
The following tests are executed by openQA during ci regularly.
6+
7+
As developer you can execute them manually when you do an update on hawk.
8+
9+
# Pre-requisites:
10+
11+
* docker
12+
* 2 Hawk vms running
13+
(normally it is a cluster)
14+
See https://github.com/SUSE/pacemaker-deploy for deploying hawk
15+
16+
17+
# Quickstart:
18+
19+
1) Create the docker image
20+
`docker build . -t hawk_test `
21+
22+
2) Run the tests with:
23+
``` docker run --ipc=host hawk_test -H 10.162.32.175 -S 10.162.29.122 -t 15 -s linux --xvfb ```
24+
25+
Notes:
26+
- You may want to add `--net=host` if you have problems with DNS resolution.
27+
28+
## Dependencies
29+
30+
- OS packages:
31+
- Xvfb (optional)
32+
- Docker (optional)
33+
- Firefox
34+
- [Geckodriver](https://github.com/mozilla/geckodriver/releases)
35+
- Chromium (optional)
36+
- [Chromedriver](https://chromedriver.chromium.org/downloads) (optional)
37+
- Python 3
38+
- Python packages:
39+
- paramiko
40+
- selenium
41+
- PyVirtualDisplay
42+
43+
## Options
44+
45+
```
46+
-h, --help show this help message and exit
47+
-b {firefox,chrome,chromium}, --browser {firefox,chrome,chromium}
48+
Browser to use in the test
49+
-H HOST, --host HOST Host or IP address where HAWK is running
50+
-S SLAVE, --slave SLAVE
51+
Host or IP address of the slave
52+
-I VIRTUAL_IP, --virtual-ip VIRTUAL_IP
53+
Virtual IP address in CIDR notation
54+
-P PORT, --port PORT TCP port where HAWK is running
55+
-p PREFIX, --prefix PREFIX
56+
Prefix to add to Resources created during the test
57+
-t TEST_VERSION, --test-version TEST_VERSION
58+
Test SLES Version. Ex: 12-SP3, 12-SP4, 15, 15-SP1
59+
-s SECRET, --secret SECRET
60+
root SSH Password of the HAWK node
61+
-r RESULTS, --results RESULTS
62+
Generate hawk_test.results file for use with openQA.
63+
--xvfb Use Xvfb. Headless mode
64+
```
65+
66+
## FAQ
67+
68+
- Why Xvfb?
69+
- The `-headless` in both browsers still have bugs, specially with modal dialogs.
70+
- Having Xvfb prevents it from connecting to our X system.
71+
- Why docker?
72+
- The Docker image packs the necessary dependencies in such a way that fits the compatibility matrix between Python, Selenium, Firefox (and Geckodriver) & Chromium (and Chromedriver).

e2e_test/hawk_test.py

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
#!/usr/bin/python3
2+
# Copyright (C) 2019 SUSE LLC
3+
"""HAWK GUI interface Selenium test: tests hawk GUI with Selenium using firefox or chrome"""
4+
5+
import argparse
6+
import ipaddress
7+
import re
8+
import shutil
9+
import socket
10+
import sys
11+
12+
from pyvirtualdisplay import Display
13+
14+
from hawk_test_driver import HawkTestDriver
15+
from hawk_test_results import ResultSet
16+
from hawk_test_ssh import HawkTestSSH
17+
18+
19+
def hostname(string):
20+
try:
21+
socket.getaddrinfo(string, 1)
22+
return string
23+
except socket.gaierror:
24+
raise argparse.ArgumentTypeError("Unknown host: %s" % string)
25+
26+
27+
def cidr_address(string):
28+
try:
29+
ipaddress.ip_network(string, False)
30+
return string
31+
except ValueError:
32+
raise argparse.ArgumentTypeError("Invalid CIDR address: %s" % string)
33+
34+
35+
def port(string):
36+
if string.isdigit() and 1 <= int(string) <= 65535:
37+
return string
38+
raise argparse.ArgumentTypeError("Invalid port number: %s" % string)
39+
40+
41+
def sles_version(string):
42+
if re.match(r"\d{2}(?:-SP\d)?$", string):
43+
return string
44+
raise argparse.ArgumentTypeError("Invalid SLES version: %s" % string)
45+
46+
47+
def parse_args():
48+
parser = argparse.ArgumentParser(description='HAWK GUI interface Selenium test')
49+
parser.add_argument('-b', '--browser', default='firefox', choices=['firefox', 'chrome', 'chromium'],
50+
help='Browser to use in the test')
51+
parser.add_argument('-H', '--host', default='localhost', type=hostname,
52+
help='Host or IP address where HAWK is running')
53+
parser.add_argument('-S', '--slave', type=hostname,
54+
help='Host or IP address of the slave')
55+
parser.add_argument('-I', '--virtual-ip', type=cidr_address,
56+
help='Virtual IP address in CIDR notation')
57+
parser.add_argument('-P', '--port', default='7630', type=port,
58+
help='TCP port where HAWK is running')
59+
parser.add_argument('-p', '--prefix', default='',
60+
help='Prefix to add to Resources created during the test')
61+
parser.add_argument('-t', '--test-version', required=True, type=sles_version,
62+
help='Test SLES Version. Ex: 12-SP3, 12-SP4, 15, 15-SP1')
63+
parser.add_argument('-s', '--secret',
64+
help='root SSH Password of the HAWK node')
65+
parser.add_argument('-r', '--results',
66+
help='Generate hawk_test.results file')
67+
parser.add_argument('--xvfb', action='store_true',
68+
help='Use Xvfb. Headless mode')
69+
args = parser.parse_args()
70+
return args
71+
72+
73+
def main():
74+
args = parse_args()
75+
76+
if args.prefix and not args.prefix.isalpha():
77+
print("ERROR: Prefix must be alphanumeric", file=sys.stderr)
78+
sys.exit(1)
79+
80+
driver = "geckodriver" if args.browser == "firefox" else "chromedriver"
81+
if shutil.which(driver) is None:
82+
print("ERROR: Please download %s to a directory in PATH" % driver, file=sys.stderr)
83+
sys.exit(1)
84+
85+
if args.xvfb:
86+
global DISPLAY # pylint: disable=global-statement
87+
DISPLAY = Display()
88+
DISPLAY.start()
89+
90+
# Create driver instance
91+
browser = HawkTestDriver(addr=args.host, port=args.port,
92+
browser=args.browser, headless=args.xvfb,
93+
version=args.test_version.lower())
94+
95+
# Initialize results set
96+
results = ResultSet()
97+
98+
# Establish SSH connection to verify status
99+
ssh = HawkTestSSH(args.host, args.secret)
100+
results.add_ssh_tests()
101+
102+
# Resources to create
103+
mycluster = args.prefix + 'Anderes'
104+
myprimitive = args.prefix + 'cool_primitive'
105+
myclone = args.prefix + 'cool_clone'
106+
mygroup = args.prefix + 'cool_group'
107+
108+
# Tests to perform
109+
if args.virtual_ip:
110+
browser.test('test_add_virtual_ip', results, args.virtual_ip)
111+
browser.test('test_remove_virtual_ip', results)
112+
else:
113+
results.set_test_status('test_add_virtual_ip', 'skipped')
114+
results.set_test_status('test_remove_virtual_ip', 'skipped')
115+
browser.test('test_set_stonith_maintenance', results)
116+
ssh.verify_stonith_in_maintenance(results)
117+
browser.test('test_disable_stonith_maintenance', results)
118+
browser.test('test_view_details_first_node', results)
119+
browser.test('test_clear_state_first_node', results)
120+
browser.test('test_set_first_node_maintenance', results)
121+
ssh.verify_node_maintenance(results)
122+
browser.test('test_disable_maintenance_first_node', results)
123+
browser.test('test_add_new_cluster', results, mycluster)
124+
browser.test('test_remove_cluster', results, mycluster)
125+
browser.test('test_click_on_history', results)
126+
browser.test('test_generate_report', results)
127+
browser.test('test_click_on_command_log', results)
128+
browser.test('test_click_on_status', results)
129+
browser.test('test_add_primitive', results, myprimitive)
130+
ssh.verify_primitive(myprimitive, args.test_version, results)
131+
browser.test('test_remove_primitive', results, myprimitive)
132+
ssh.verify_primitive_removed(myprimitive, results)
133+
browser.test('test_add_clone', results, myclone)
134+
browser.test('test_remove_clone', results, myclone)
135+
browser.test('test_add_group', results, mygroup)
136+
browser.test('test_remove_group', results, mygroup)
137+
browser.test('test_click_around_edit_conf', results)
138+
if args.slave:
139+
browser.addr = args.slave
140+
browser.test('test_fencing', results)
141+
else:
142+
results.set_test_status('test_fencing', 'skipped')
143+
144+
# Save results if run with -r or --results
145+
if args.results:
146+
results.logresults(args.results)
147+
148+
return results.get_failed_tests_total()
149+
150+
151+
if __name__ == "__main__":
152+
DISPLAY = None
153+
try:
154+
sys.exit(main())
155+
except KeyboardInterrupt:
156+
if DISPLAY is not None:
157+
DISPLAY.stop()
158+
sys.exit(1)
159+
finally:
160+
if DISPLAY is not None:
161+
DISPLAY.stop()

0 commit comments

Comments
 (0)