Merge lp:~canonical-platform-qa/snappy-ecosystem-tests/adding-test-runner into lp:snappy-ecosystem-tests

Proposed by Heber Parrucci
Status: Merged
Approved by: I Ahmad
Approved revision: 18
Merged at revision: 14
Proposed branch: lp:~canonical-platform-qa/snappy-ecosystem-tests/adding-test-runner
Merge into: lp:snappy-ecosystem-tests
Diff against target: 1367 lines (+856/-144)
29 files modified
README.rst (+76/-24)
mk-venv (+44/-0)
pylint.cfg (+4/-4)
requirements.txt (+13/-2)
run_checks (+1/-1)
run_system_tests (+25/-0)
setup.py (+48/-0)
snappy_ecosystem_tests/commons/__init__.py (+19/-0)
snappy_ecosystem_tests/commons/config.py (+173/-0)
snappy_ecosystem_tests/configs/__init__.py (+19/-0)
snappy_ecosystem_tests/configs/ecosystem_tests.cfg (+20/-0)
snappy_ecosystem_tests/configs/pytest.cfg (+2/-0)
snappy_ecosystem_tests/data/__init__.py (+0/-19)
snappy_ecosystem_tests/helpers/fixture_setup.py (+95/-0)
snappy_ecosystem_tests/helpers/test_base.py (+32/-0)
snappy_ecosystem_tests/helpers/ubuntu_store_tests_base.py (+0/-19)
snappy_ecosystem_tests/helpers/web_test_base.py (+35/-17)
snappy_ecosystem_tests/run.py (+47/-0)
snappy_ecosystem_tests/snapcraft/__init__.py (+19/-0)
snappy_ecosystem_tests/snapcraft/snapcraft.py (+8/-26)
snappy_ecosystem_tests/snapd/__init__.py (+19/-0)
snappy_ecosystem_tests/tests/__init__.py (+0/-19)
snappy_ecosystem_tests/tests/data/entity/entity.json (+6/-0)
snappy_ecosystem_tests/tests/test_store_login.py (+5/-3)
snappy_ecosystem_tests/unittests/test_snapcraft.py (+3/-1)
snappy_ecosystem_tests/utils/json.py (+30/-0)
snappy_ecosystem_tests/utils/singleton.py (+38/-0)
snappy_ecosystem_tests/utils/storeconfig.py (+29/-9)
snappy_ecosystem_tests/utils/test_data.py (+46/-0)
To merge this branch: bzr merge lp:~canonical-platform-qa/snappy-ecosystem-tests/adding-test-runner
Reviewer Review Type Date Requested Status
I Ahmad (community) Approve
platform-qa-bot continuous-integration Approve
Review via email: mp+317132@code.launchpad.net

Commit message

This change includes:

* Adding pytest as a test runner.
* Adding config files
* Adding mechanism to read test data.
* Making pylint more strict: fail when a warning message is returned.

Description of the change

This change includes:

* Adding pytest as a test runner since nose2 has issues when testtools report failures
* Adding config files to store urls, store environment values, etc. And the mechanism to read them.
* Adding mechanism to read test data for users (Can be extended for any entity).
* Making pylint more strict: fail when a warning message is returned.

Can be included in a next iteration:
* Improve selenium config values and page objects.
* read snappy-ecosystem related arguments from commandline.

To post a comment you must log in.
Revision history for this message
platform-qa-bot (platform-qa-bot) wrote :
review: Needs Fixing (continuous-integration)
15. By Heber Parrucci

fixing pylint issues

Revision history for this message
platform-qa-bot (platform-qa-bot) wrote :
review: Approve (continuous-integration)
16. By Heber Parrucci

removing print statement

Revision history for this message
platform-qa-bot (platform-qa-bot) wrote :
review: Approve (continuous-integration)
17. By Heber Parrucci

passing filtered arguments to main without modifying the args command line

Revision history for this message
platform-qa-bot (platform-qa-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
I Ahmad (iahmad) wrote :

I would suggest to not check in the credentials to the public bzr branch as bots can pick it up, this should be concealed using the environment variables or if we can find a way to encrypt them at check in time and decrypt it when these were needed for the setup (like travis)

18. By Heber Parrucci

Addressing review feedback regarding credentials:
Now it is read from a user config file that is outside the repo in the host machine. If that config is not found, then it reads the credentials from env variables.
The idea is to store the config with the credentials in a private repository, and then Jenkins will get it and store in the host machine when running the tests.
The same mechanism is used in ubuntu-system-tests.

Revision history for this message
Heber Parrucci (heber013) wrote :

> I would suggest to not check in the credentials to the public bzr branch as
> bots can pick it up, this should be concealed using the environment variables
> or if we can find a way to encrypt them at check in time and decrypt it when
> these were needed for the setup (like travis)

Thanks for review!

Now credentials are read from a user config file that is outside the repo in the host machine. If that config is not found, then it reads the credentials from env variables.
The idea is to store the config with the credentials in a private repository, and then Jenkins will get it and store in the host machine when running the tests.
The same mechanism is used in ubuntu-system-tests.

Revision history for this message
platform-qa-bot (platform-qa-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
I Ahmad (iahmad) wrote :

LGTM

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== renamed file 'README' => 'README.rst'
2--- README 2017-02-08 14:27:31 +0000
3+++ README.rst 2017-02-15 19:16:15 +0000
4@@ -1,29 +1,81 @@
5-How to setup and execute snappy ecosystem tests
6-===============================================
7-Please make sure you have following dependencies installed
8-1. Python version >= 3.5
9-2. nosetests >= 1.3.7
10-3. xmlrunner >= 1.7.7
11-4. geckodriver webdriver for Firefox >= 0.13.0
12-5. chromedriver webdriver for Chrome >= 2.27
13-
14-Make sure webdrivers are added to $PATH
15-
16-
17-To run the tests checkout the branch follow the below steps
18-===========================================================
19+Snappy Ecosystem Tests
20+######################
21+
22+Automated system tests for snappy ecosystem: snapcraft, store and snapd.
23+
24+
25+To run the tests checkout the branch and follow the below steps
26+===============================================================
27 $ bzr branch lp:snappy-ecosystem-tests
28 $ cd snappy-ecosystem-tests/
29-$ export UBUNTU_STORE_LOGIN_EMAIL=<store account email>
30-$ export UBUNTU_STORE_LOGIN_PASSWORD=<store account password>
31-$ export STAGING=<1 or 0>, To test against staging or production server respectively
32-$ nosetests --with-xunit
33-
34-
35-Running code analysis with pylint
36-=================================
37+$ ./run_system_tests snappy_ecosystem_tests
38+
39+It will create a virtual env with all the dependencies defined in requirements.txt and run all the tests
40+A pytest runner is used: http://docs.pytest.org/en/latest/
41+
42+To run all tests in a python package:
43+$ ./run_system_tests snappy_ecosystem_tests/tests/example_package
44+
45+To run all test in a python module:
46+$ ./run_system_tests snappy_ecosystem_tests/tests/example_package/example_module.py
47+
48+To run all tests in a python class:
49+$ ./run_system_tests snappy_ecosystem_tests/tests/example_package/example_module.py::ExampleClass
50+
51+To run a particular test in a python class:
52+$ ./run_system_tests snappy_ecosystem_tests/tests/example_package/example_module.py::ExampleClass::example_test
53+
54+To run a tests that match with a expression:
55+./run_system_tests -k stringexpr
56+# only run tests with names that match the
57+# "string expression", e.g. "MyClass and not method"
58+# will select TestMyClass.test_something
59+# but not TestMyClass.test_method_simple
60+
61+You can also specify the arguments as python packages separated by dots:
62+$ ./run_system_tests --pyargs tests.example_package.example_module
63+Notice that in this case you skip the root dir snappy_ecosystem_tests and for python modules skip the .py
64+
65+To see all options refer to: http://doc.pytest.org/en/latest/usage.html#specifying-tests-selecting-tests
66+
67+Tests Results
68+=============
69+By default the tests results will be stored in 'snappy-ecosystem-results.xml'
70+
71+Parameters
72+==========
73+If you are behind a proxy you can specify --proxy option
74+All pytest parameters are allowed
75+
76+Config files
77+============
78+You can find configurations files in 'config' folder:
79+
80+ecosystem_tests.cfg stores the snappy ecosystem related config like: APIs urls, Web urls, store to use, etc.
81+You can change this config file location by setting the env variable: XDG_CONFIG_HOME
82+
83+pytest.cfg stores the config related to pytest
84+
85+Changing store:
86+===============
87+You can change the store to use in config file ecosystem_tests.cfg
88+or by setting the env variable TEST_STORE with values: 'staging' or 'production'.
89+It will first try to read the config file, then the env variable and finally
90+if none of them are provided it will take 'staging' as default.
91+
92+
93+Running static code analysis and/or unittest
94+============================================
95 To run static code analysis you can execute from root directory:
96-$ ./run_pylint
97+$ ./run_checks --static
98 It will store the results in pylint-results.txt
99-The config file with all the rules is pylint.cfg
100+The config file with pylint rules is pylint.cfg
101+
102+If you want to run unittests:
103+$ ./run_checks --unit
104+
105+If you want to run both:
106+$ ./run_checks --all
107+
108+If you are behind a proxy you can specify --proxy option
109
110
111=== added file 'mk-venv'
112--- mk-venv 1970-01-01 00:00:00 +0000
113+++ mk-venv 2017-02-15 19:16:15 +0000
114@@ -0,0 +1,44 @@
115+#!/bin/bash
116+
117+#
118+# Snappy Ecosystem Tests
119+# Copyright (C) 2017 Canonical
120+#
121+# This program is free software: you can redistribute it and/or modify
122+# it under the terms of the GNU General Public License as published by
123+# the Free Software Foundation, either version 3 of the License, or
124+# (at your option) any later version.
125+#
126+# This program is distributed in the hope that it will be useful,
127+# but WITHOUT ANY WARRANTY; without even the implied warranty of
128+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
129+# GNU General Public License for more details.
130+#
131+# You should have received a copy of the GNU General Public License
132+# along with this program. If not, see <http://www.gnu.org/licenses/>.
133+#
134+
135+virtualenv --python=python3 ve
136+. ve/bin/activate
137+
138+
139+while [[ $# -gt 1 ]]
140+do
141+
142+key="$1"
143+
144+case $key in
145+ --proxy)
146+ proxy="$2"
147+ shift # past argument
148+ ;;
149+esac
150+shift # past argument or value
151+done
152+
153+if [ "$proxy" ]; then
154+ echo "Using proxy: $proxy to install dependencies"
155+ pip install --proxy $proxy -r requirements.txt
156+else
157+ pip install -r requirements.txt
158+fi
159
160=== modified file 'pylint.cfg'
161--- pylint.cfg 2017-02-10 18:18:45 +0000
162+++ pylint.cfg 2017-02-15 19:16:15 +0000
163@@ -99,7 +99,7 @@
164 [VARIABLES]
165
166 # Tells whether we should check for unused import in __init__ files.
167-init-import=no
168+init-import=yes
169
170 # A regular expression matching the name of dummy variables (i.e. expectedly
171 # not used).
172@@ -222,7 +222,7 @@
173 [FORMAT]
174
175 # Maximum number of characters on a single line.
176-max-line-length=100
177+max-line-length=80
178
179 # Regexp for a line that is allowed to be longer than the limit.
180 ignore-long-lines=^\s*(# )?<?https?://\S+>?$
181@@ -286,7 +286,7 @@
182 [MISCELLANEOUS]
183
184 # List of note tags to take in consideration, separated by a comma.
185-notes=FIXME,XXX,TODO
186+notes=
187
188
189 [TYPECHECK]
190@@ -361,7 +361,7 @@
191 max-attributes=7
192
193 # Minimum number of public methods for a class (see R0903).
194-min-public-methods=2
195+min-public-methods=1
196
197 # Maximum number of public methods for a class (see R0904).
198 max-public-methods=20
199
200=== modified file 'requirements.txt'
201--- requirements.txt 2017-02-10 18:18:45 +0000
202+++ requirements.txt 2017-02-15 19:16:15 +0000
203@@ -1,3 +1,14 @@
204+pytest
205+testtools
206+unittest2
207+testscenarios
208+fixtures
209+selenium
210+configparser==3.5.0
211+progressbar33==2.4
212+requests==2.9.1
213+simplejson==3.8.2
214+pyxdg==0.25
215+jsonschema==2.5.1
216 pexpect
217-selenium
218-unittest2
219+chromedriver_installer
220
221=== modified file 'run_checks'
222--- run_checks 2017-02-10 19:30:21 +0000
223+++ run_checks 2017-02-15 19:16:15 +0000
224@@ -35,7 +35,7 @@
225 ve_pylint/bin/python3 -m pylint snappy_ecosystem_tests --reports=n --rcfile=pylint.cfg > pylint-results.txt
226
227 result=$?
228- if [ $result != 0 ] && [ $result != 4 ]; then
229+ if [ $result != 0 ]; then
230 echo -e -n "${RED}Pylint errors. Check pylint output for more information\n"
231 exit 1;
232 else
233
234=== added file 'run_system_tests'
235--- run_system_tests 1970-01-01 00:00:00 +0000
236+++ run_system_tests 2017-02-15 19:16:15 +0000
237@@ -0,0 +1,25 @@
238+#!/bin/bash
239+
240+#
241+# Snappy Ecosystem Tests
242+# Copyright (C) 2017 Canonical
243+#
244+# This program is free software: you can redistribute it and/or modify
245+# it under the terms of the GNU General Public License as published by
246+# the Free Software Foundation, either version 3 of the License, or
247+# (at your option) any later version.
248+#
249+# This program is distributed in the hope that it will be useful,
250+# but WITHOUT ANY WARRANTY; without even the implied warranty of
251+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
252+# GNU General Public License for more details.
253+#
254+# You should have received a copy of the GNU General Public License
255+# along with this program. If not, see <http://www.gnu.org/licenses/>.
256+#
257+
258+. ./mk-venv "$@"
259+
260+ve/bin/python3 ./snappy_ecosystem_tests/run.py "$@" -c snappy_ecosystem_tests/configs/pytest.cfg --ignore snappy_ecosystem_tests/unittests/ --junitxml snappy-ecosystem-results.xml
261+
262+deactivate
263
264=== added file 'setup.py'
265--- setup.py 1970-01-01 00:00:00 +0000
266+++ setup.py 2017-02-15 19:16:15 +0000
267@@ -0,0 +1,48 @@
268+#!/usr/bin/env python3
269+
270+#
271+# Snappy Ecosystem Tests
272+# Copyright (C) 2017 Canonical
273+#
274+# This program is free software: you can redistribute it and/or modify
275+# it under the terms of the GNU General Public License as published by
276+# the Free Software Foundation, either version 3 of the License, or
277+# (at your option) any later version.
278+#
279+# This program is distributed in the hope that it will be useful,
280+# but WITHOUT ANY WARRANTY; without even the implied warranty of
281+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
282+# GNU General Public License for more details.
283+#
284+# You should have received a copy of the GNU General Public License
285+# along with this program. If not, see <http://www.gnu.org/licenses/>.
286+#
287+
288+import sys
289+from setuptools import find_packages, setup
290+
291+assert sys.version_info >= (3,), 'Python 3 is required'
292+
293+
294+VERSION = '1.0'
295+
296+
297+setup(
298+ name='snappy-ecosystem-tests',
299+ version=VERSION,
300+ description='Automated tests for Snappy Ecosystem.',
301+ author='Canonical Platform QA Team',
302+ author_email='qa-team@lists.canonical.com',
303+ url='https://launchpad.net/~snappy-ecosystem-tests-dev',
304+ license='GPLv3',
305+ packages=find_packages(),
306+ package_data={
307+ 'snappy_ecosystem_tests': ['tests/data/*/*']
308+ },
309+ entry_points={
310+ 'console_scripts': [
311+ 'snappy_ecosystem_tests = snappy_ecosystem_tests.run:main'
312+ ]
313+ },
314+ test_suite='snappy_ecosystem_tests.unittests'
315+)
316
317=== added directory 'snappy_ecosystem_tests/commons'
318=== added file 'snappy_ecosystem_tests/commons/__init__.py'
319--- snappy_ecosystem_tests/commons/__init__.py 1970-01-01 00:00:00 +0000
320+++ snappy_ecosystem_tests/commons/__init__.py 2017-02-15 19:16:15 +0000
321@@ -0,0 +1,19 @@
322+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
323+
324+#
325+# Snappy Ecosystem Tests
326+# Copyright (C) 2017 Canonical
327+#
328+# This program is free software: you can redistribute it and/or modify
329+# it under the terms of the GNU General Public License as published by
330+# the Free Software Foundation, either version 3 of the License, or
331+# (at your option) any later version.
332+#
333+# This program is distributed in the hope that it will be useful,
334+# but WITHOUT ANY WARRANTY; without even the implied warranty of
335+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
336+# GNU General Public License for more details.
337+#
338+# You should have received a copy of the GNU General Public License
339+# along with this program. If not, see <http://www.gnu.org/licenses/>.
340+#
341
342=== added file 'snappy_ecosystem_tests/commons/config.py'
343--- snappy_ecosystem_tests/commons/config.py 1970-01-01 00:00:00 +0000
344+++ snappy_ecosystem_tests/commons/config.py 2017-02-15 19:16:15 +0000
345@@ -0,0 +1,173 @@
346+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
347+
348+#
349+# Snappy Ecosystem Tests
350+# Copyright (C) 2017 Canonical
351+#
352+# This program is free software: you can redistribute it and/or modify
353+# it under the terms of the GNU General Public License as published by
354+# the Free Software Foundation, either version 3 of the License, or
355+# (at your option) any later version.
356+#
357+# This program is distributed in the hope that it will be useful,
358+# but WITHOUT ANY WARRANTY; without even the implied warranty of
359+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
360+# GNU General Public License for more details.
361+#
362+# You should have received a copy of the GNU General Public License
363+# along with this program. If not, see <http://www.gnu.org/licenses/>.
364+#
365+
366+"""Manage tests config files: get existing one, create new one and store it"""
367+
368+import configparser
369+import logging
370+import os
371+
372+LOGGER = logging.getLogger(__name__)
373+
374+DEFAULT_CONF = 'ecosystem_tests.cfg'
375+KEY_DEFAULT = 'default'
376+
377+
378+def get_config_dir():
379+ """Return the path to the tests configuration directory."""
380+ conf_dir = os.environ.get(
381+ 'XDG_CONFIG_HOME', os.path.realpath(__file__ + '/../../configs'))
382+ return conf_dir
383+
384+
385+def get_user_config_dir():
386+ """Return the path to the user configuration directory."""
387+ conf_dir = os.environ.get(
388+ 'XDG_USER_CONFIG_HOME', os.path.expanduser('~/.config'))
389+ return conf_dir
390+
391+
392+def get_config_section():
393+ """Return the name of config section to use."""
394+ return os.environ.get('CONFIG_SECTION', KEY_DEFAULT)
395+
396+
397+def _get_config_stack_from_file(file_path):
398+ """Return config stack from specified file path."""
399+ ecosystem_config = SnappyEcosystemTestsConfig(file_path)
400+ ecosystem_config.read_config_from_file()
401+ return ecosystem_config
402+
403+
404+class ConfigStack:
405+ """Class that represents different config stacks"""
406+
407+ def __init__(self, dir_path=None, file_name=None):
408+ self.__config = self.__create_config_stack(dir_path, file_name)
409+
410+ @property
411+ def config(self):
412+ """Return the current config"""
413+ return self.__get_config()
414+
415+ def set_config(self, dir_path=None, file_name=None):
416+ """Set the current config for the given dirpath and file name.
417+ :param dir_path: the dir in which the config file is located.
418+ If None it takes the default one returned by get_config_dir()
419+ :param file_name: the config file name.
420+ If None it takes the default one stored in DEFAULT_CONF
421+ :return the created config as a dict
422+ """
423+ self.__config = self.__create_config_stack(dir_path, file_name)
424+
425+ def release_config(self):
426+ """Release the current config for those cases that
427+ explicitly want to modify it"""
428+ self.__config = None
429+
430+ def __get_config(self):
431+ """Get current config. Set it in the case is None"""
432+ if self.__config is None:
433+ self.set_config()
434+ return self.__config
435+
436+ @staticmethod
437+ def __create_config_stack(dir_path=None, file_name=None):
438+ """Create the config stack for the given dirpath and file name
439+ :param dir_path: the dir in which the config file is located.
440+ If None it takes the default one returned by get_config_dir()
441+ :param file_name: the config file name.
442+ If None it takes the default one stored in DEFAULT_CONF
443+ :return the created config as a dict
444+ """
445+ full_path = os.path.join(dir_path or get_config_dir(),
446+ file_name or DEFAULT_CONF)
447+ return _get_config_stack_from_file(full_path)
448+
449+
450+class SnappyEcosystemTestsConfig:
451+
452+ """Class to get and save test configuration data."""
453+
454+ def __init__(self, file_name=None):
455+ """
456+ Construct the config and parser object.
457+ :param file_name: Name of config file to load. Default file is used if
458+ value is not specified.
459+ """
460+ user_config_dir = get_config_dir()
461+ if not os.path.exists(user_config_dir):
462+ os.mkdir(user_config_dir)
463+ self.file_path = os.path.join(
464+ user_config_dir, file_name or DEFAULT_CONF)
465+ self.config = configparser.ConfigParser(
466+ allow_no_value=True, empty_lines_in_values=False)
467+
468+ def set(self, section, option_name, value):
469+ """Set a config value for the given section.
470+ :param section: the section of the config in which update
471+ the given value
472+ :param option_name: Name of config option.
473+ :param value: Value to set.
474+ """
475+ self.config[section][option_name] = value
476+ self.save()
477+
478+ def get(self, section, option_name, default=''):
479+ """Get a config value for a given section.
480+ If section and/or value are not found, return default if
481+ provided or raise exception
482+ :param section: the section of the config in which search
483+ for the given value.
484+ :param option_name: Name of config option to get.
485+ :param default: Value to return as default if section and/or
486+ item don't exist.
487+ :return: Config option value if it exists. In case that section
488+ and/or item don't exists,
489+ then return default value if provided, or raise exception"""
490+ try:
491+ return self.config.get(section, option_name)
492+ except(configparser.NoSectionError, configparser.NoOptionError):
493+ if default:
494+ return default
495+ else:
496+ raise
497+
498+ def get_section(self, section):
499+ """
500+ Return a particular section of config
501+ :param section: the section name to retrieve
502+ :return: a Section object
503+ """
504+ return self.config[section]
505+
506+ def save(self):
507+ """Save the config to file path"""
508+ mode = 'r+' if os.path.exists(self.file_path) else 'w'
509+ with open(self.file_path, mode) as _f:
510+ self.config.write(_f)
511+
512+ def read_config_from_file(self):
513+ """Read config from file"""
514+ self.config.read(self.file_path)
515+
516+
517+CONFIG_STACK = ConfigStack().config
518+USER_CONFIG_STACK = ConfigStack(dir_path=get_user_config_dir()).config
519
520=== added directory 'snappy_ecosystem_tests/configs'
521=== added file 'snappy_ecosystem_tests/configs/__init__.py'
522--- snappy_ecosystem_tests/configs/__init__.py 1970-01-01 00:00:00 +0000
523+++ snappy_ecosystem_tests/configs/__init__.py 2017-02-15 19:16:15 +0000
524@@ -0,0 +1,19 @@
525+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
526+
527+#
528+# Snappy Ecosystem Tests
529+# Copyright (C) 2017 Canonical
530+#
531+# This program is free software: you can redistribute it and/or modify
532+# it under the terms of the GNU General Public License as published by
533+# the Free Software Foundation, either version 3 of the License, or
534+# (at your option) any later version.
535+#
536+# This program is distributed in the hope that it will be useful,
537+# but WITHOUT ANY WARRANTY; without even the implied warranty of
538+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
539+# GNU General Public License for more details.
540+#
541+# You should have received a copy of the GNU General Public License
542+# along with this program. If not, see <http://www.gnu.org/licenses/>.
543+#
544
545=== added file 'snappy_ecosystem_tests/configs/ecosystem_tests.cfg'
546--- snappy_ecosystem_tests/configs/ecosystem_tests.cfg 1970-01-01 00:00:00 +0000
547+++ snappy_ecosystem_tests/configs/ecosystem_tests.cfg 2017-02-15 19:16:15 +0000
548@@ -0,0 +1,20 @@
549+[web-ui]
550+browser=chrome
551+stage_url=https://myapps.developer.staging.ubuntu.com/
552+production_url=https://myapps.developer.ubuntu.com/
553+
554+[store]
555+# store to use in tests. Possible values: staging or production
556+environment=staging
557+
558+[staging_urls]
559+root_api=https://myapps.developer.staging.ubuntu.com/dev/api/
560+upload=https://upload.apps.staging.ubuntu.com/
561+sso=https://login.staging.ubuntu.com/api/v2/
562+search=https://search.apps.staging.ubuntu.com/
563+
564+[production_urls]
565+root_api=https://myapps.developer.ubuntu.com/dev/api/
566+upload=https://upload.apps.ubuntu.com/
567+sso=https://login.ubuntu.com/api/v2/
568+search=https://search.apps.ubuntu.com/
569
570=== added file 'snappy_ecosystem_tests/configs/pytest.cfg'
571--- snappy_ecosystem_tests/configs/pytest.cfg 1970-01-01 00:00:00 +0000
572+++ snappy_ecosystem_tests/configs/pytest.cfg 2017-02-15 19:16:15 +0000
573@@ -0,0 +1,2 @@
574+[pytest]
575+
576
577=== removed file 'snappy_ecosystem_tests/data/__init__.py'
578--- snappy_ecosystem_tests/data/__init__.py 2017-02-07 17:41:23 +0000
579+++ snappy_ecosystem_tests/data/__init__.py 1970-01-01 00:00:00 +0000
580@@ -1,19 +0,0 @@
581-# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
582-
583-#
584-# Snappy Ecosystem Tests
585-# Copyright (C) 2017 Canonical
586-#
587-# This program is free software: you can redistribute it and/or modify
588-# it under the terms of the GNU General Public License as published by
589-# the Free Software Foundation, either version 3 of the License, or
590-# (at your option) any later version.
591-#
592-# This program is distributed in the hope that it will be useful,
593-# but WITHOUT ANY WARRANTY; without even the implied warranty of
594-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
595-# GNU General Public License for more details.
596-#
597-# You should have received a copy of the GNU General Public License
598-# along with this program. If not, see <http://www.gnu.org/licenses/>.
599-#
600
601=== added file 'snappy_ecosystem_tests/helpers/fixture_setup.py'
602--- snappy_ecosystem_tests/helpers/fixture_setup.py 1970-01-01 00:00:00 +0000
603+++ snappy_ecosystem_tests/helpers/fixture_setup.py 2017-02-15 19:16:15 +0000
604@@ -0,0 +1,95 @@
605+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
606+
607+#
608+# Snappy Ecosystem Tests
609+# Copyright (C) 2017 Canonical
610+#
611+# This program is free software: you can redistribute it and/or modify
612+# it under the terms of the GNU General Public License as published by
613+# the Free Software Foundation, either version 3 of the License, or
614+# (at your option) any later version.
615+#
616+# This program is distributed in the hope that it will be useful,
617+# but WITHOUT ANY WARRANTY; without even the implied warranty of
618+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
619+# GNU General Public License for more details.
620+#
621+# You should have received a copy of the GNU General Public License
622+# along with this program. If not, see <http://www.gnu.org/licenses/>.
623+#
624+
625+"""Manage general tests fixtures"""
626+
627+import os
628+import fixtures
629+from snappy_ecosystem_tests.commons.config import CONFIG_STACK
630+from snappy_ecosystem_tests.utils.storeconfig import get_current_store
631+
632+
633+class TempCWD(fixtures.TempDir):
634+ """Create a temporary directory an cd into it for the test duration."""
635+
636+ def setUp(self):
637+ """Create a temporary directory an cd into it for the test duration."""
638+ super().setUp()
639+ current_dir = os.getcwd()
640+ self.addCleanup(os.chdir, current_dir)
641+ os.chdir(self.path)
642+
643+
644+class CleanEnvironment(fixtures.Fixture):
645+ """Clean all env variables and restore the original values as
646+ clean up process"""
647+
648+ def setUp(self):
649+ super().setUp()
650+
651+ current_environment = os.environ.copy()
652+ os.environ = {}
653+
654+ self.addCleanup(os.environ.update, current_environment)
655+
656+
657+class SetStoreEnvironmentVariables(fixtures.Fixture):
658+ """Configure the env variables for using staging urls"""
659+
660+ def __init__(self, store):
661+ self.store = store
662+
663+ def setUp(self):
664+ super().setUp()
665+ urls = CONFIG_STACK.get_section('%s_urls' % self.store)
666+
667+ self.useFixture(fixtures.EnvironmentVariable(
668+ 'UBUNTU_STORE_API_ROOT_URL',
669+ urls.get('root_api')))
670+ self.useFixture(fixtures.EnvironmentVariable(
671+ 'UBUNTU_STORE_UPLOAD_ROOT_URL',
672+ urls.get('upload')))
673+ self.useFixture(fixtures.EnvironmentVariable(
674+ 'UBUNTU_SSO_API_ROOT_URL',
675+ urls.get('sso')))
676+ self.useFixture(fixtures.EnvironmentVariable(
677+ 'UBUNTU_STORE_SEARCH_ROOT_URL',
678+ urls.get('search')))
679+
680+
681+class SetTestStore(fixtures.Fixture):
682+ """Configure the env variables for using the corresponding
683+ environment urls"""
684+
685+ def __init__(self):
686+ self.register_delay = -1
687+
688+ def setUp(self):
689+ super().setUp()
690+ test_store = get_current_store()
691+ self.useFixture(SetStoreEnvironmentVariables(test_store))
692+ if test_store == 'staging':
693+ self.register_delay = 10
694+ elif test_store == 'production':
695+ # Use the default server URLs
696+ self.register_delay = 180
697+ else:
698+ raise ValueError(
699+ 'Unknown test store option: {}'.format(test_store))
700
701=== added file 'snappy_ecosystem_tests/helpers/test_base.py'
702--- snappy_ecosystem_tests/helpers/test_base.py 1970-01-01 00:00:00 +0000
703+++ snappy_ecosystem_tests/helpers/test_base.py 2017-02-15 19:16:15 +0000
704@@ -0,0 +1,32 @@
705+# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*-
706+#
707+# Copyright (C) 2017 Canonical Ltd
708+#
709+# This program is free software: you can redistribute it and/or modify
710+# it under the terms of the GNU General Public License version 3 as
711+# published by the Free Software Foundation.
712+#
713+# This program is distributed in the hope that it will be useful,
714+# but WITHOUT ANY WARRANTY; without even the implied warranty of
715+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
716+# GNU General Public License for more details.
717+#
718+# You should have received a copy of the GNU General Public License
719+# along with this program. If not, see <http://www.gnu.org/licenses/>.
720+
721+"""Base Snappy Ecosystem test"""
722+
723+import testscenarios
724+import testtools
725+from snappy_ecosystem_tests.helpers import fixture_setup
726+from snappy_ecosystem_tests.helpers.fixture_setup import SetTestStore
727+
728+
729+class SnappyEcosystemTestCase(testscenarios.WithScenarios, testtools.TestCase):
730+
731+ def setUp(self):
732+ super().setUp()
733+ temp_cwd_fixture = fixture_setup.TempCWD()
734+ self.useFixture(SetTestStore())
735+ self.useFixture(temp_cwd_fixture)
736+ self.path = temp_cwd_fixture.path
737
738=== removed file 'snappy_ecosystem_tests/helpers/ubuntu_store_tests_base.py'
739--- snappy_ecosystem_tests/helpers/ubuntu_store_tests_base.py 2017-02-07 17:41:23 +0000
740+++ snappy_ecosystem_tests/helpers/ubuntu_store_tests_base.py 1970-01-01 00:00:00 +0000
741@@ -1,19 +0,0 @@
742-# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
743-
744-#
745-# Snappy Ecosystem Tests
746-# Copyright (C) 2017 Canonical
747-#
748-# This program is free software: you can redistribute it and/or modify
749-# it under the terms of the GNU General Public License as published by
750-# the Free Software Foundation, either version 3 of the License, or
751-# (at your option) any later version.
752-#
753-# This program is distributed in the hope that it will be useful,
754-# but WITHOUT ANY WARRANTY; without even the implied warranty of
755-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
756-# GNU General Public License for more details.
757-#
758-# You should have received a copy of the GNU General Public License
759-# along with this program. If not, see <http://www.gnu.org/licenses/>.
760-#
761
762=== renamed file 'snappy_ecosystem_tests/helpers/ubuntu_store_web_test_base.py' => 'snappy_ecosystem_tests/helpers/web_test_base.py'
763--- snappy_ecosystem_tests/helpers/ubuntu_store_web_test_base.py 2017-02-07 17:49:25 +0000
764+++ snappy_ecosystem_tests/helpers/web_test_base.py 2017-02-15 19:16:15 +0000
765@@ -19,8 +19,7 @@
766 #
767
768 """Web-Ui related functionality for testing web pages using selenium"""
769-
770-import unittest
771+import logging
772
773 from selenium import webdriver
774 from selenium.webdriver.support.ui import WebDriverWait
775@@ -28,7 +27,10 @@
776 from selenium.common.exceptions import TimeoutException
777 from selenium.webdriver.common.by import By
778
779-from snappy_ecosystem_tests import storeconfig
780+from snappy_ecosystem_tests.utils import storeconfig
781+from snappy_ecosystem_tests.helpers.test_base import SnappyEcosystemTestCase
782+
783+LOGGER = logging.getLogger(__name__)
784
785 LOGIN_EMAIL, LOGIN_PASSWORD = storeconfig.get_store_credentials()
786 STORE_URL = storeconfig.get_store_web_url()
787@@ -37,12 +39,16 @@
788 PAGE_LOAD_TIMEOUT = 30
789
790
791-class UbuntuStoreWebTestsBase(unittest.TestCase):
792+class UbuntuStoreWebTestsBase(SnappyEcosystemTestCase):
793 """Base class to represent a Web-UI test case.
794- Contain basic functionality for locating web elements and interacting with a page
795+ Contain basic functionality for locating web elements and
796+ interacting with a page
797 """
798+
799 def setUp(self):
800- # TODO - add support for multiple type browsers including Chrome, FF and IE
801+ # TODO - add support for multiple type browsers including Chrome,
802+ # FF and IE
803+ super().setUp()
804 options = webdriver.ChromeOptions()
805 options.add_argument("--start-maximized")
806 self.driver = webdriver.Chrome(chrome_options=options)
807@@ -55,7 +61,8 @@
808 element_present = EC.presence_of_element_located(locator)
809 wait.until(element_present)
810 except TimeoutException:
811- print("Timed out waiting for "+locator[1]+" page")
812+ LOGGER.error("Timed out waiting for " + locator[1] + " page")
813+ raise
814
815 def wait_for_page_title(self, title, timeout=PAGE_LOAD_TIMEOUT):
816 """Wait for the target page title for given timeout,
817@@ -65,7 +72,8 @@
818 find_title = EC.title_is(title)
819 wait.until(find_title)
820 except TimeoutException:
821- print("Timed out waiting for "+title + " page")
822+ LOGGER.error("Timed out waiting for " + title + " page")
823+ raise
824
825 def wait_for_visible(self, timeout=PAGE_LOAD_TIMEOUT):
826 # TODO: re-implement to allow any locator as parameter
827@@ -77,7 +85,8 @@
828 (By.XPATH, "/html/body/nav/div/div[1]/span"))
829 wait.until(element_visible)
830 except TimeoutException:
831- print("Timed out waiting for element to be visible")
832+ LOGGER.error("Timed out waiting for element to be visible")
833+ raise
834
835 def wait_for_clickable(self, timeout=PAGE_LOAD_TIMEOUT):
836 # TODO: re-implement to allow any locator as parameter
837@@ -89,10 +98,12 @@
838 (By.XPATH, "/html/body/nav/div/div[1]/span"))
839 wait.until(element_clickable)
840 except TimeoutException:
841- print("Timed out waiting for element to be clickable")
842+ LOGGER.error("Timed out waiting for element to be clickable")
843+ raise
844
845 def login(self):
846- """Login to web interface, following the UI flow which end user would use"""
847+ """Login to web interface, following the UI flow which end user
848+ would use"""
849 driver = self.driver
850 driver.get(STORE_URL)
851
852@@ -111,28 +122,34 @@
853 self.wait_for_page_title("Your packages")
854
855 def logout(self):
856- """Logout of web interface, following the UI flow which end user would use"""
857+ """Logout of web interface, following the UI flow which end
858+ user would use"""
859 driver = self.driver
860 self.wait_for_element((By.CLASS_NAME, "b-dropdown__arrow_light"))
861 #
862- # extremely ugly way to reach the desired element by xpath, a bug will be
863+ # extremely ugly way to reach the desired element by xpath,
864+ # a bug will be
865 # raised to uniquely identify the dropdown arrows
866 self.wait_for_clickable()
867- down_arrow = driver.find_element_by_xpath("/html/body/nav/div/div[1]/span")
868+ down_arrow = driver.find_element_by_xpath(
869+ "/html/body/nav/div/div[1]/span")
870 #
871 # There is a bug with Firefox webdriver when clicking elements,
872 # as sometime click doesn't have any effect, to workaround that
873- # multiple attempts are made. However everything works fine with chrome webdriver.
874+ # multiple attempts are made. However everything works fine with
875+ # chrome webdriver.
876
877 for _ in range(0, 2):
878 wait = WebDriverWait(self.driver, 1)
879 try:
880 down_arrow.click()
881- element_present = EC.presence_of_element_located((By.CLASS_NAME, "b-dropdown_open"))
882+ element_present = EC.presence_of_element_located(
883+ (By.CLASS_NAME, "b-dropdown_open"))
884 wait.until(element_present)
885 break
886 except TimeoutException:
887- print("Failed to open the accounts dropdown menu card, Trying again")
888+ LOGGER.error("Failed to open the accounts dropdown menu card,"
889+ " Trying again")
890
891 self.wait_for_visible()
892 logout_link = driver.find_element_by_link_text("Log out")
893@@ -141,5 +158,6 @@
894 self.wait_for_page_title("Sign in to see your packages")
895
896 def tearDown(self):
897+ super().tearDown()
898 self.driver.close()
899 self.driver.quit()
900
901=== added file 'snappy_ecosystem_tests/run.py'
902--- snappy_ecosystem_tests/run.py 1970-01-01 00:00:00 +0000
903+++ snappy_ecosystem_tests/run.py 2017-02-15 19:16:15 +0000
904@@ -0,0 +1,47 @@
905+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
906+
907+#
908+# Snappy Ecosystem Tests
909+# Copyright (C) 2017 Canonical
910+#
911+# This program is free software: you can redistribute it and/or modify
912+# it under the terms of the GNU General Public License as published by
913+# the Free Software Foundation, either version 3 of the License, or
914+# (at your option) any later version.
915+#
916+# This program is distributed in the hope that it will be useful,
917+# but WITHOUT ANY WARRANTY; without even the implied warranty of
918+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
919+# GNU General Public License for more details.
920+#
921+# You should have received a copy of the GNU General Public License
922+# along with this program. If not, see <http://www.gnu.org/licenses/>.
923+#
924+
925+"""Entry point to run snappy ecosystem tests"""
926+
927+import re
928+import sys
929+import pytest
930+
931+FILTER_ARGUMENTS = '--proxy'
932+
933+
934+def _filter_arguments():
935+ """Remove from command line arguments all the ones that are in
936+ FILTER_ARGUMENTS list."""
937+ filtered_args = sys.argv[1:]
938+ for i, arg in enumerate(sys.argv[1:]):
939+ if arg in FILTER_ARGUMENTS:
940+ filtered_args.pop(i + 1)
941+ filtered_args.pop(i)
942+ return filtered_args
943+
944+
945+def _parse_arguments():
946+ """Parse and filter command line arguments to makethem pytest compatible"""
947+ sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
948+ return _filter_arguments()
949+
950+if __name__ == '__main__':
951+ sys.exit(pytest.main(args=_parse_arguments() + ['-p', 'no:cacheprovider']))
952
953=== added directory 'snappy_ecosystem_tests/snapcraft'
954=== added file 'snappy_ecosystem_tests/snapcraft/__init__.py'
955--- snappy_ecosystem_tests/snapcraft/__init__.py 1970-01-01 00:00:00 +0000
956+++ snappy_ecosystem_tests/snapcraft/__init__.py 2017-02-15 19:16:15 +0000
957@@ -0,0 +1,19 @@
958+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
959+
960+#
961+# Snappy Ecosystem Tests
962+# Copyright (C) 2017 Canonical
963+#
964+# This program is free software: you can redistribute it and/or modify
965+# it under the terms of the GNU General Public License as published by
966+# the Free Software Foundation, either version 3 of the License, or
967+# (at your option) any later version.
968+#
969+# This program is distributed in the hope that it will be useful,
970+# but WITHOUT ANY WARRANTY; without even the implied warranty of
971+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
972+# GNU General Public License for more details.
973+#
974+# You should have received a copy of the GNU General Public License
975+# along with this program. If not, see <http://www.gnu.org/licenses/>.
976+#
977
978=== renamed file 'snappy_ecosystem_tests/utils/snapcraft.py' => 'snappy_ecosystem_tests/snapcraft/snapcraft.py'
979--- snappy_ecosystem_tests/utils/snapcraft.py 2017-02-07 17:49:25 +0000
980+++ snappy_ecosystem_tests/snapcraft/snapcraft.py 2017-02-15 19:16:15 +0000
981@@ -18,43 +18,23 @@
982 # along with this program. If not, see <http://www.gnu.org/licenses/>.
983 #
984
985-"""Snapcraft related helpers to configure the snapcraft environment: staging or production
986-and other specific functions inside Snapcraft class
987-"""
988+"""Snapcraft client helpers"""
989
990-import os
991 import pexpect
992
993
994 # login credentials exported by shell environment
995-from snappy_ecosystem_tests import storeconfig
996+from snappy_ecosystem_tests.utils import storeconfig
997
998 LOGIN_EMAIL, LOGIN_PASSWORD = storeconfig.get_store_credentials()
999
1000
1001-def set_snapcraft_environment():
1002- """set the environment variables for snapcraft communication with store,
1003- this will be staging by default. if STAGING environment variable is
1004- set to 0, then it will be set to production"""
1005- if storeconfig.is_staging():
1006- os.environ["UBUNTU_STORE_SEARCH_ROOT_URL"] = 'https://search.apps.staging.ubuntu.com/'
1007- os.environ["UBUNTU_STORE_UPLOAD_ROOT_URL"] = 'https://upload.apps.staging.ubuntu.com/'
1008- os.environ["UBUNTU_SSO_API_ROOT_URL"] = 'https://login.staging.ubuntu.com/api/v2/'
1009- os.environ["UBUNTU_STORE_API_ROOT_URL"] = \
1010- 'https://myapps.developer.staging.ubuntu.com/dev/api/'
1011- else:
1012- os.environ["UBUNTU_STORE_SEARCH_ROOT_URL"] = 'https://search.apps.ubuntu.com/'
1013- os.environ["UBUNTU_STORE_UPLOAD_ROOT_URL"] = 'https://upload.apps.ubuntu.com/'
1014- os.environ["UBUNTU_SSO_API_ROOT_URL"] = 'https://login.ubuntu.com/api/v2/'
1015- os.environ["UBUNTU_STORE_API_ROOT_URL"] = 'https://myapps.developer.ubuntu.com/dev/api/'
1016-
1017-
1018 class Snapcraft(object):
1019- """Contain Snapcraft specific functionality to use via command line interface"""
1020+ """Contain Snapcraft specific functionality to use via command
1021+ line interface"""
1022 def __init__(self):
1023 """Create new snapcraft instance."""
1024 self._login = False
1025- set_snapcraft_environment()
1026 self._cleanup()
1027
1028 def _cleanup(self):
1029@@ -86,7 +66,9 @@
1030 self._login = True
1031
1032 def list_registered(self):
1033- """call snapcraft list-registered command, raise exception if not logged in"""
1034+ """call snapcraft list-registered command,
1035+ raise exception if not logged in"""
1036 if self._login is False:
1037- raise ValueError("User is not logged in, please login before using this command")
1038+ raise ValueError("User is not logged in, "
1039+ "please login before using this command")
1040 return pexpect.spawnu("snapcraft list-registered").read()
1041
1042=== added directory 'snappy_ecosystem_tests/snapd'
1043=== added file 'snappy_ecosystem_tests/snapd/__init__.py'
1044--- snappy_ecosystem_tests/snapd/__init__.py 1970-01-01 00:00:00 +0000
1045+++ snappy_ecosystem_tests/snapd/__init__.py 2017-02-15 19:16:15 +0000
1046@@ -0,0 +1,19 @@
1047+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
1048+
1049+#
1050+# Snappy Ecosystem Tests
1051+# Copyright (C) 2017 Canonical
1052+#
1053+# This program is free software: you can redistribute it and/or modify
1054+# it under the terms of the GNU General Public License as published by
1055+# the Free Software Foundation, either version 3 of the License, or
1056+# (at your option) any later version.
1057+#
1058+# This program is distributed in the hope that it will be useful,
1059+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1060+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1061+# GNU General Public License for more details.
1062+#
1063+# You should have received a copy of the GNU General Public License
1064+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1065+#
1066
1067=== renamed file 'snappy_ecosystem_tests/utils/snapd.py' => 'snappy_ecosystem_tests/snapd/snapd.py'
1068=== added directory 'snappy_ecosystem_tests/tests'
1069=== removed directory 'snappy_ecosystem_tests/tests'
1070=== added file 'snappy_ecosystem_tests/tests/__init__.py'
1071--- snappy_ecosystem_tests/tests/__init__.py 1970-01-01 00:00:00 +0000
1072+++ snappy_ecosystem_tests/tests/__init__.py 2017-02-15 19:16:15 +0000
1073@@ -0,0 +1,19 @@
1074+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
1075+
1076+#
1077+# Snappy Ecosystem Tests
1078+# Copyright (C) 2017 Canonical
1079+#
1080+# This program is free software: you can redistribute it and/or modify
1081+# it under the terms of the GNU General Public License as published by
1082+# the Free Software Foundation, either version 3 of the License, or
1083+# (at your option) any later version.
1084+#
1085+# This program is distributed in the hope that it will be useful,
1086+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1087+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1088+# GNU General Public License for more details.
1089+#
1090+# You should have received a copy of the GNU General Public License
1091+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1092+#
1093
1094=== removed file 'snappy_ecosystem_tests/tests/__init__.py'
1095--- snappy_ecosystem_tests/tests/__init__.py 2017-02-07 17:49:25 +0000
1096+++ snappy_ecosystem_tests/tests/__init__.py 1970-01-01 00:00:00 +0000
1097@@ -1,19 +0,0 @@
1098-# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
1099-
1100-#
1101-# Snappy Ecosystem Tests
1102-# Copyright (C) 2017 Canonical
1103-#
1104-# This program is free software: you can redistribute it and/or modify
1105-# it under the terms of the GNU General Public License as published by
1106-# the Free Software Foundation, either version 3 of the License, or
1107-# (at your option) any later version.
1108-#
1109-# This program is distributed in the hope that it will be useful,
1110-# but WITHOUT ANY WARRANTY; without even the implied warranty of
1111-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1112-# GNU General Public License for more details.
1113-#
1114-# You should have received a copy of the GNU General Public License
1115-# along with this program. If not, see <http://www.gnu.org/licenses/>.
1116-#
1117
1118=== renamed directory 'snappy_ecosystem_tests/data' => 'snappy_ecosystem_tests/tests/data'
1119=== added directory 'snappy_ecosystem_tests/tests/data/entity'
1120=== added file 'snappy_ecosystem_tests/tests/data/entity/entity.json'
1121--- snappy_ecosystem_tests/tests/data/entity/entity.json 1970-01-01 00:00:00 +0000
1122+++ snappy_ecosystem_tests/tests/data/entity/entity.json 2017-02-15 19:16:15 +0000
1123@@ -0,0 +1,6 @@
1124+{
1125+ "entity": [
1126+ {
1127+ }
1128+ ]
1129+}
1130\ No newline at end of file
1131
1132=== renamed file 'snappy_ecosystem_tests/test_store_login.py' => 'snappy_ecosystem_tests/tests/test_store_login.py'
1133--- snappy_ecosystem_tests/test_store_login.py 2017-02-07 19:44:37 +0000
1134+++ snappy_ecosystem_tests/tests/test_store_login.py 2017-02-15 19:16:15 +0000
1135@@ -20,11 +20,12 @@
1136
1137 """Test for Login to the Store via Web Interface, snapcraft and snapd"""
1138
1139-from snappy_ecosystem_tests.utils.snapcraft import Snapcraft
1140-from snappy_ecosystem_tests.helpers.ubuntu_store_web_test_base import UbuntuStoreWebTestsBase
1141+from snappy_ecosystem_tests.snapcraft.snapcraft import Snapcraft
1142+from snappy_ecosystem_tests.helpers.web_test_base import UbuntuStoreWebTestsBase
1143
1144
1145 class StoreLoginTestCase(UbuntuStoreWebTestsBase):
1146+
1147 def setUp(self):
1148 super().setUp()
1149
1150@@ -40,7 +41,8 @@
1151
1152 self.login()
1153 self.assertEqual(self.driver.title, "Your packages", "Failed to login")
1154- # TODO - fragile as there is no unique way to identify the dropdown arrow
1155+ # TODO - fragile as there is no unique way to identify
1156+ # the dropdown arrow
1157 self.logout()
1158 self.assertEqual(
1159 self.driver.title, "Sign in to see your packages",
1160
1161=== modified file 'snappy_ecosystem_tests/unittests/test_snapcraft.py'
1162--- snappy_ecosystem_tests/unittests/test_snapcraft.py 2017-02-10 20:22:24 +0000
1163+++ snappy_ecosystem_tests/unittests/test_snapcraft.py 2017-02-15 19:16:15 +0000
1164@@ -22,8 +22,10 @@
1165
1166 from unittest2 import TestCase
1167
1168+
1169 class SnapcraftTestCase(TestCase):
1170
1171 def test_snapcraft_dummy_test(self):
1172 """Dummy test case"""
1173- self.assertTrue(True)
1174+ _a = True
1175+ self.assertTrue(_a)
1176
1177=== added file 'snappy_ecosystem_tests/utils/json.py'
1178--- snappy_ecosystem_tests/utils/json.py 1970-01-01 00:00:00 +0000
1179+++ snappy_ecosystem_tests/utils/json.py 2017-02-15 19:16:15 +0000
1180@@ -0,0 +1,30 @@
1181+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
1182+
1183+#
1184+# Snappy Ecosystem Tests
1185+# Copyright (C) 2017 Canonical
1186+#
1187+# This program is free software: you can redistribute it and/or modify
1188+# it under the terms of the GNU General Public License as published by
1189+# the Free Software Foundation, either version 3 of the License, or
1190+# (at your option) any later version.
1191+#
1192+# This program is distributed in the hope that it will be useful,
1193+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1194+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1195+# GNU General Public License for more details.
1196+#
1197+# You should have received a copy of the GNU General Public License
1198+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1199+#
1200+
1201+"""Manage json files"""
1202+
1203+import json
1204+
1205+
1206+def read_json_from_file(file_path):
1207+ """Read a json from the given file path and return it as a dict"""
1208+ with open(file_path) as _f:
1209+ data_json = json.load(_f)
1210+ return data_json
1211
1212=== added file 'snappy_ecosystem_tests/utils/singleton.py'
1213--- snappy_ecosystem_tests/utils/singleton.py 1970-01-01 00:00:00 +0000
1214+++ snappy_ecosystem_tests/utils/singleton.py 2017-02-15 19:16:15 +0000
1215@@ -0,0 +1,38 @@
1216+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
1217+
1218+#
1219+# Snappy Ecosystem Tests
1220+# Copyright (C) 2017 Canonical
1221+#
1222+# This program is free software: you can redistribute it and/or modify
1223+# it under the terms of the GNU General Public License as published by
1224+# the Free Software Foundation, either version 3 of the License, or
1225+# (at your option) any later version.
1226+#
1227+# This program is distributed in the hope that it will be useful,
1228+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1229+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1230+# GNU General Public License for more details.
1231+#
1232+# You should have received a copy of the GNU General Public License
1233+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1234+#
1235+
1236+"""Singleton utils"""
1237+
1238+
1239+class Singleton(type):
1240+ """Class that represents a singleton entity.
1241+ Usage: Specify metaclass=Singleton in those classes you want to be
1242+ Singleton.
1243+ Example: MyClass(metaclass=Singleton).
1244+ And automatically the same instance will be returned when creating
1245+ MyClass objects.
1246+ """
1247+ __instances = {}
1248+
1249+ def __call__(cls, *args, **kwargs):
1250+ if cls not in cls.__instances:
1251+ cls.__instances[cls] = super(Singleton, cls).__call__(
1252+ *args, **kwargs)
1253+ return cls.__instances[cls]
1254
1255=== renamed file 'snappy_ecosystem_tests/storeconfig.py' => 'snappy_ecosystem_tests/utils/storeconfig.py'
1256--- snappy_ecosystem_tests/storeconfig.py 2017-02-07 17:41:23 +0000
1257+++ snappy_ecosystem_tests/utils/storeconfig.py 2017-02-15 19:16:15 +0000
1258@@ -18,25 +18,34 @@
1259 # along with this program. If not, see <http://www.gnu.org/licenses/>.
1260 #
1261
1262-"""Helpers to retrieve store configuration data like: credentials, urls, etc"""
1263+"""Get all the store related data like credentials, urls"""
1264
1265 import os
1266
1267-KEY_ENVIRON_STORE_LOGIN_EMAIL = 'UBUNTU_STORE_LOGIN_EMAIL'
1268-KEY_ENVIRON_STORE_LOGIN_PASSWORD = 'UBUNTU_STORE_LOGIN_PASSWORD'
1269-URL_WEB_STORE_PRODUCTION = 'https://myapps.developer.ubuntu.com/'
1270-URL_WEB_STORE_STAGING = 'https://myapps.developer.staging.ubuntu.com/'
1271+from snappy_ecosystem_tests.commons.config import (
1272+ CONFIG_STACK,
1273+ USER_CONFIG_STACK
1274+)
1275+
1276+URL_WEB_STORE_PRODUCTION = CONFIG_STACK.get('web-ui', 'production_url')
1277+URL_WEB_STORE_STAGING = CONFIG_STACK.get('web-ui', 'stage_url')
1278
1279
1280 def get_store_credentials():
1281- """login credentials exported by shell environment"""
1282- return os.environ['UBUNTU_STORE_LOGIN_EMAIL'], \
1283- os.environ['UBUNTU_STORE_LOGIN_PASSWORD']
1284+ """Get user store credentials.
1285+ It will retrieve the credentials stored in a user config file,
1286+ if the config is not found,
1287+ then it will return the ones provided in environment variables
1288+ """
1289+ return (USER_CONFIG_STACK.get('user', 'user_email',
1290+ default=os.environ.get('user_email')),
1291+ USER_CONFIG_STACK.get('user', 'user_password',
1292+ default=os.environ.get('user_password')))
1293
1294
1295 def is_staging():
1296 """Return False if environment variable PROD is exported"""
1297- return os.environ.get('STAGING', "1") == "1"
1298+ return get_current_store() == 'staging'
1299
1300
1301 def get_store_web_url():
1302@@ -44,3 +53,14 @@
1303 if optional staging argument is false then it will return
1304 production server url """
1305 return URL_WEB_STORE_STAGING if is_staging() else URL_WEB_STORE_PRODUCTION
1306+
1307+
1308+def get_current_store():
1309+ """
1310+ Return the current configured store. It will first read the config value,
1311+ if no config value is set, it will read the env variable TEST_STORE,
1312+ if that env variable is not set, then it returns staging as default
1313+ :return: current configured store environment
1314+ """
1315+ return CONFIG_STACK.get('store', 'environment',
1316+ os.getenv('TEST_STORE', 'staging'))
1317
1318=== added file 'snappy_ecosystem_tests/utils/test_data.py'
1319--- snappy_ecosystem_tests/utils/test_data.py 1970-01-01 00:00:00 +0000
1320+++ snappy_ecosystem_tests/utils/test_data.py 2017-02-15 19:16:15 +0000
1321@@ -0,0 +1,46 @@
1322+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
1323+
1324+#
1325+# Snappy Ecosystem Tests
1326+# Copyright (C) 2017 Canonical
1327+#
1328+# This program is free software: you can redistribute it and/or modify
1329+# it under the terms of the GNU General Public License as published by
1330+# the Free Software Foundation, either version 3 of the License, or
1331+# (at your option) any later version.
1332+#
1333+# This program is distributed in the hope that it will be useful,
1334+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1335+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1336+# GNU General Public License for more details.
1337+#
1338+# You should have received a copy of the GNU General Public License
1339+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1340+#
1341+
1342+"""Parse and get all tests data that will be used during test execution"""
1343+
1344+import os
1345+
1346+from snappy_ecosystem_tests.utils.json import read_json_from_file
1347+
1348+# Test data dirs
1349+DIR_TESTS = os.path.realpath(__file__ + '/../../tests')
1350+DIR_TEST_DATA = os.path.join(DIR_TESTS, 'data')
1351+DIR_TEST_DATA_ENTITY = os.path.join(DIR_TEST_DATA, 'entity')
1352+
1353+# Test data files
1354+ENTITY_FILE = os.path.join(DIR_TEST_DATA_ENTITY, 'entity.json')
1355+
1356+
1357+class EntityStack:
1358+ """Class store an entity that is read as
1359+ test data in json files"""
1360+
1361+ def __init__(self):
1362+ self.__entities = read_json_from_file(ENTITY_FILE)
1363+
1364+ @property
1365+ def entities(self):
1366+ """Get the current entities"""
1367+ return self.__entities

Subscribers

People subscribed via source and target branches