Merge lp:~canonical-platform-qa/snappy-ecosystem-tests/export-staging-variables-ssh into lp:snappy-ecosystem-tests

Proposed by Omer Akram
Status: Superseded
Proposed branch: lp:~canonical-platform-qa/snappy-ecosystem-tests/export-staging-variables-ssh
Merge into: lp:snappy-ecosystem-tests
Diff against target: 1658 lines (+1185/-111)
30 files modified
README.rst (+12/-7)
pylint.cfg (+4/-4)
requirements-unit-tests.txt (+1/-1)
requirements.txt (+2/-1)
run_checks (+2/-2)
run_system_tests (+1/-0)
snappy_ecosystem_tests/configs/ecosystem_tests.cfg (+8/-3)
snappy_ecosystem_tests/environment/__init__.py (+19/-0)
snappy_ecosystem_tests/environment/constants.py (+82/-0)
snappy_ecosystem_tests/environment/data/__init__.py (+19/-0)
snappy_ecosystem_tests/environment/data/snapcraft.py (+21/-0)
snappy_ecosystem_tests/environment/data/snapd.py (+88/-0)
snappy_ecosystem_tests/environment/managers.py (+142/-0)
snappy_ecosystem_tests/environment/setup.py (+46/-0)
snappy_ecosystem_tests/helpers/snapcraft/client.py (+164/-23)
snappy_ecosystem_tests/helpers/snapd/snapd.py (+5/-1)
snappy_ecosystem_tests/helpers/snapd/staging_builder.py (+11/-4)
snappy_ecosystem_tests/helpers/store_apis/rest_apis.py (+51/-6)
snappy_ecosystem_tests/models/__init__.py (+19/-0)
snappy_ecosystem_tests/models/snap.py (+39/-0)
snappy_ecosystem_tests/run.py (+24/-14)
snappy_ecosystem_tests/tests/test_register_snap.py (+116/-0)
snappy_ecosystem_tests/unittests/test_filters.py (+113/-0)
snappy_ecosystem_tests/unittests/test_snapcraft.py (+0/-31)
snappy_ecosystem_tests/utils/commands.py (+31/-0)
snappy_ecosystem_tests/utils/filters.py (+51/-0)
snappy_ecosystem_tests/utils/ssh.py (+7/-2)
snappy_ecosystem_tests/utils/store_versions.py (+74/-0)
snappy_ecosystem_tests/utils/storeconfig.py (+2/-2)
snappy_ecosystem_tests/utils/user.py (+31/-10)
To merge this branch: bzr merge lp:~canonical-platform-qa/snappy-ecosystem-tests/export-staging-variables-ssh
Reviewer Review Type Date Requested Status
platform-qa-bot continuous-integration Approve
Snappy ecosystem tests developer Pending
Review via email: mp+318728@code.launchpad.net

This proposal has been superseded by a proposal from 2017-03-02.

Commit message

Export staging variables over ssh.

Description of the change

Ensure staging environment variables are available over ssh.

To post a comment you must log in.
Revision history for this message
platform-qa-bot (platform-qa-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Omer Akram (om26er) wrote :

By default ssh is secure and does not allow any random environment variable to be exported. So the ssh config within the container also needs to be updated to allow these variables to be exported.

That can be enabled by container setup script. We basically need to append staging environment variable names to AcceptEnv key inside /etc/ssh/sshd_config. OR if we just want to put this variables inside /etc/environment while we setup the container, that would work, though I am not a fan of that.

For testing just update the AcceptEnv line in the container to

AcceptEnv *

Revision history for this message
Omer Akram (om26er) wrote :

(and restart the container)

25. By Omer Akram

merge with trunk

26. By Omer Akram

Finish rebase

27. By Omer Akram

fix

28. By Omer Akram

fix per suggestion

29. By Omer Akram

merge with pre-req

30. By Omer Akram

ignore arguments-differ pylint warning

31. By Omer Akram

merge with trunk

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'README.rst'
2--- README.rst 2017-02-22 17:40:11 +0000
3+++ README.rst 2017-03-02 10:45:12 +0000
4@@ -69,17 +69,22 @@
5 [user]
6 user_email=^USER_NAME^
7 user_password=^USER_PASSWORD^
8-hostname_remote=^SSH_HOSTNAME^
9-username_remote=^SSH_USERNAME^
10-port_remote=^SSH_PORT^
11+snapd_hostname_remote=^SNAPD_SSH_HOSTNAME^
12+snapd_username_remote=^SNAPD_SSH_USERNAME^
13+snapd_port_remote=^SNAPD_SSH_PORT^
14+snapcraft_hostname_remote=^SNAPCRAFT_SSH_HOSTNAME^
15+snapcraft_username_remote=^SNAPCRAFT_SSH_USERNAME^
16+snapcraft_port_remote=^SNAPCRAFT_SSH_PORT^
17
18 option 2 - Set the following environment variables:
19 user_email=^USER_NAME^
20 user_password=^USER_PASSWORD^
21-hostname_remote=^SSH_HOSTNAME^
22-username_remote=^SSH_USERNAME^
23-port_remote=^SSH_PORT^
24-
25+snapd_hostname_remote=^SNAPD_SSH_HOSTNAME^
26+snapd_username_remote=^SNAPD_SSH_USERNAME^
27+snapd_port_remote=^SNAPD_SSH_PORT^
28+snapcraft_hostname_remote=^SNAPCRAFT_SSH_HOSTNAME^
29+snapcraft_username_remote=^SNAPCRAFT_SSH_USERNAME^
30+snapcraft_port_remote=^SNAPCRAFT_SSH_PORT^
31
32 Changing store:
33 ===============
34
35=== modified file 'pylint.cfg'
36--- pylint.cfg 2017-02-21 13:46:08 +0000
37+++ pylint.cfg 2017-03-02 10:45:12 +0000
38@@ -169,10 +169,10 @@
39 inlinevar-name-hint=[A-Za-z_][A-Za-z0-9_]*$
40
41 # Regular expression matching correct function names
42-function-rgx=[a-z_][a-z0-9_]{2,30}$
43+function-rgx=[a-z_][a-z0-9_]{2,40}$
44
45 # Naming hint for function names
46-function-name-hint=[a-z_][a-z0-9_]{2,30}$
47+function-name-hint=[a-z_][a-z0-9_]{2,40}$
48
49 # Regular expression matching correct attribute names
50 attr-rgx=[a-z_][a-z0-9_]{2,30}$
51@@ -181,10 +181,10 @@
52 attr-name-hint=[a-z_][a-z0-9_]{2,30}$
53
54 # Regular expression matching correct method names
55-method-rgx=[a-z_][a-z0-9_]{2,30}$|setUp|tearDown
56+method-rgx=[a-z_][a-z0-9_]{2,30}$|setUp|tearDown|test_*
57
58 # Naming hint for method names
59-method-name-hint=[a-z_][a-z0-9_]{2,30}$|setUp|tearDown
60+method-name-hint=[a-z_][a-z0-9_]{2,30}$|setUp|tearDown|test_*
61
62 # Regular expression matching correct class attribute names
63 class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$
64
65=== modified file 'requirements-unit-tests.txt'
66--- requirements-unit-tests.txt 2017-02-10 18:18:45 +0000
67+++ requirements-unit-tests.txt 2017-03-02 10:45:12 +0000
68@@ -1,1 +1,1 @@
69-unittest2
70+testtools
71
72=== modified file 'requirements.txt'
73--- requirements.txt 2017-02-21 21:07:33 +0000
74+++ requirements.txt 2017-03-02 10:45:12 +0000
75@@ -14,7 +14,8 @@
76 pexpect
77 pymacaroons==0.9.2
78 requests-toolbelt==0.6.0
79-#chromedriver_installer
80 pylxd
81 pyyaml
82+retrying
83 paramiko
84+chromedriver_installer
85
86=== modified file 'run_checks'
87--- run_checks 2017-02-20 13:10:18 +0000
88+++ run_checks 2017-03-02 10:45:12 +0000
89@@ -51,9 +51,9 @@
90
91 if [ "$proxy" ]; then
92 echo "Using proxy: $proxy to install dependencies"
93- pip install --proxy $proxy -r requirements-unit-tests.txt
94+ pip3 install --proxy $proxy -r requirements-unit-tests.txt
95 else
96- pip install -r requirements-unit-tests.txt
97+ pip3 install -r requirements-unit-tests.txt
98 fi
99
100 ve_unit_tests/bin/python3 -m unittest discover snappy_ecosystem_tests.unittests
101
102=== modified file 'run_system_tests'
103--- run_system_tests 2017-02-13 16:00:04 +0000
104+++ run_system_tests 2017-03-02 10:45:12 +0000
105@@ -20,6 +20,7 @@
106
107 . ./mk-venv "$@"
108
109+ve/bin/python3 ./snappy_ecosystem_tests/utils/store_versions.py
110 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
111
112 deactivate
113
114=== modified file 'snappy_ecosystem_tests/configs/ecosystem_tests.cfg'
115--- snappy_ecosystem_tests/configs/ecosystem_tests.cfg 2017-02-10 19:20:45 +0000
116+++ snappy_ecosystem_tests/configs/ecosystem_tests.cfg 2017-03-02 10:45:12 +0000
117@@ -1,7 +1,5 @@
118-[web-ui]
119+[selenium]
120 browser=chrome
121-stage_url=https://myapps.developer.staging.ubuntu.com/
122-production_url=https://myapps.developer.ubuntu.com/
123
124 [store]
125 # store to use in tests. Possible values: staging or production
126@@ -12,9 +10,16 @@
127 upload=https://upload.apps.staging.ubuntu.com/
128 sso=https://login.staging.ubuntu.com/api/v2/
129 search=https://search.apps.staging.ubuntu.com/
130+web=https://myapps.developer.staging.ubuntu.com/
131
132 [production_urls]
133 root_api=https://myapps.developer.ubuntu.com/dev/api/
134 upload=https://upload.apps.ubuntu.com/
135 sso=https://login.ubuntu.com/api/v2/
136 search=https://search.apps.ubuntu.com/
137+web=https://myapps.developer.ubuntu.com/
138+
139+[time_between_registrations]
140+# Time in seconds between each snap registration
141+staging=10
142+production=180
143
144=== added directory 'snappy_ecosystem_tests/environment'
145=== added file 'snappy_ecosystem_tests/environment/__init__.py'
146--- snappy_ecosystem_tests/environment/__init__.py 1970-01-01 00:00:00 +0000
147+++ snappy_ecosystem_tests/environment/__init__.py 2017-03-02 10:45:12 +0000
148@@ -0,0 +1,19 @@
149+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
150+
151+#
152+# Snappy Ecosystem Tests
153+# Copyright (C) 2017 Canonical
154+#
155+# This program is free software: you can redistribute it and/or modify
156+# it under the terms of the GNU General Public License as published by
157+# the Free Software Foundation, either version 3 of the License, or
158+# (at your option) any later version.
159+#
160+# This program is distributed in the hope that it will be useful,
161+# but WITHOUT ANY WARRANTY; without even the implied warranty of
162+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
163+# GNU General Public License for more details.
164+#
165+# You should have received a copy of the GNU General Public License
166+# along with this program. If not, see <http://www.gnu.org/licenses/>.
167+#
168
169=== added file 'snappy_ecosystem_tests/environment/constants.py'
170--- snappy_ecosystem_tests/environment/constants.py 1970-01-01 00:00:00 +0000
171+++ snappy_ecosystem_tests/environment/constants.py 2017-03-02 10:45:12 +0000
172@@ -0,0 +1,82 @@
173+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
174+
175+#
176+# Snappy Ecosystem Tests
177+# Copyright (C) 2017 Canonical
178+#
179+# This program is free software: you can redistribute it and/or modify
180+# it under the terms of the GNU General Public License as published by
181+# the Free Software Foundation, either version 3 of the License, or
182+# (at your option) any later version.
183+#
184+# This program is distributed in the hope that it will be useful,
185+# but WITHOUT ANY WARRANTY; without even the implied warranty of
186+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
187+# GNU General Public License for more details.
188+#
189+# You should have received a copy of the GNU General Public License
190+# along with this program. If not, see <http://www.gnu.org/licenses/>.
191+#
192+
193+"""Constants used accross the environment setup"""
194+
195+SNAPD = 'snapd'
196+SNAPCRAFT = 'snapcraft'
197+
198+DEPENDENCIES = {
199+ SNAPD : [],
200+ SNAPCRAFT : [],
201+ "shared" : ["expect"]
202+}
203+
204+PROFILES = {
205+ "staging":{
206+ SNAPD:{
207+ "channel": "xenial",
208+ "package_name": 'snapd',
209+ "environment_variables": [
210+ {
211+ "name": "UBUNTU_STORE_API_ROOT_URL",
212+ "value": "https://myapps.developer.ubuntu.com/dev/api/"
213+ },
214+ {
215+ "name": "UBUNTU_STORE_UPLOAD_ROOT_URL",
216+ "value": "https://upload.apps.ubuntu.com"
217+ },
218+ {
219+ "name":"UBUNTU_SSO_API_ROOT_URL",
220+ "value":"https://login.ubuntu.com/api/v2/"
221+ },
222+ {
223+ "name":"UBUNTU_STORE_SEARCH_ROOT_URL",
224+ "value":"https://search.apps.ubuntu.com/"
225+ }
226+ ]
227+ },
228+ SNAPCRAFT: {
229+ "channel": "xenial",
230+ "package_name": 'snapcraft',
231+ "environment_variables": [
232+ {
233+ "name": "UBUNTU_STORE_API_ROOT_URL",
234+ "value": "https://myapps.developer.ubuntu.com/dev/api/"
235+ },
236+ {
237+ "name": "UBUNTU_STORE_UPLOAD_ROOT_URL",
238+ "value": "https://upload.apps.ubuntu.com"
239+ },
240+ {
241+ "name":"UBUNTU_SSO_API_ROOT_URL",
242+ "value":"https://login.ubuntu.com/api/v2/"
243+ },
244+ {
245+ "name":"UBUNTU_STORE_SEARCH_ROOT_URL",
246+ "value":"https://search.apps.ubuntu.com/"
247+ }
248+ ]
249+ },
250+ "snapweb":{
251+ "url": "https://myapps.developer.ubuntu.com/"
252+ },
253+ }
254+}
255
256=== added directory 'snappy_ecosystem_tests/environment/data'
257=== added file 'snappy_ecosystem_tests/environment/data/__init__.py'
258--- snappy_ecosystem_tests/environment/data/__init__.py 1970-01-01 00:00:00 +0000
259+++ snappy_ecosystem_tests/environment/data/__init__.py 2017-03-02 10:45:12 +0000
260@@ -0,0 +1,19 @@
261+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
262+
263+#
264+# Snappy Ecosystem Tests
265+# Copyright (C) 2017 Canonical
266+#
267+# This program is free software: you can redistribute it and/or modify
268+# it under the terms of the GNU General Public License as published by
269+# the Free Software Foundation, either version 3 of the License, or
270+# (at your option) any later version.
271+#
272+# This program is distributed in the hope that it will be useful,
273+# but WITHOUT ANY WARRANTY; without even the implied warranty of
274+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
275+# GNU General Public License for more details.
276+#
277+# You should have received a copy of the GNU General Public License
278+# along with this program. If not, see <http://www.gnu.org/licenses/>.
279+#
280
281=== added file 'snappy_ecosystem_tests/environment/data/snapcraft.py'
282--- snappy_ecosystem_tests/environment/data/snapcraft.py 1970-01-01 00:00:00 +0000
283+++ snappy_ecosystem_tests/environment/data/snapcraft.py 2017-03-02 10:45:12 +0000
284@@ -0,0 +1,21 @@
285+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
286+
287+#
288+# Snappy Ecosystem Tests
289+# Copyright (C) 2017 Canonical
290+#
291+# This program is free software: you can redistribute it and/or modify
292+# it under the terms of the GNU General Public License as published by
293+# the Free Software Foundation, either version 3 of the License, or
294+# (at your option) any later version.
295+#
296+# This program is distributed in the hope that it will be useful,
297+# but WITHOUT ANY WARRANTY; without even the implied warranty of
298+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
299+# GNU General Public License for more details.
300+#
301+# You should have received a copy of the GNU General Public License
302+# along with this program. If not, see <http://www.gnu.org/licenses/>.
303+#
304+"""Snapcraft data"""
305+SNAPCRAFT_CONTAINER_NAME = 'snapcraft'
306
307=== added file 'snappy_ecosystem_tests/environment/data/snapd.py'
308--- snappy_ecosystem_tests/environment/data/snapd.py 1970-01-01 00:00:00 +0000
309+++ snappy_ecosystem_tests/environment/data/snapd.py 2017-03-02 10:45:12 +0000
310@@ -0,0 +1,88 @@
311+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
312+
313+#
314+# Snappy Ecosystem Tests
315+# Copyright (C) 2017 Canonical
316+#
317+# This program is free software: you can redistribute it and/or modify
318+# it under the terms of the GNU General Public License as published by
319+# the Free Software Foundation, either version 3 of the License, or
320+# (at your option) any later version.
321+#
322+# This program is distributed in the hope that it will be useful,
323+# but WITHOUT ANY WARRANTY; without even the implied warranty of
324+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
325+# GNU General Public License for more details.
326+#
327+# You should have received a copy of the GNU General Public License
328+# along with this program. If not, see <http://www.gnu.org/licenses/>.
329+#
330+"""snapd data"""
331+SNAPD_CONTAINER_NAME = 'snapd'
332+
333+CONTAINER_HOME = '/root'
334+DIRECTORY_CLONE = '{}/src/github.com/snapcore/snapd'.format(CONTAINER_HOME)
335+DOMAIN_PING = 'ubuntu.com'
336+ENV_STORE_API_ROOT = 'UBUNTU_STORE_API_ROOT_URL'
337+ENV_STORE_SEARCH_ROOT = 'UBUNTU_STORE_SEARCH_ROOT_URL'
338+ENV_STORE_UPLOAD_ROOT = 'UBUNTU_STORE_UPLOAD_ROOT_URL'
339+ENV_SSO_API_ROOT = 'UBUNTU_SSO_API_ROOT_URL'
340+PACKAGES_SNAPD = ['snapd', 'snap-confine', 'ubuntu-core-launcher']
341+COMMAND_REMOVE_SNAPD = 'apt purge -y {}'.format(' '.join(PACKAGES_SNAPD))
342+COMMAND_APT_BUILD_DEP = 'apt build-dep -y ./'
343+COMMAND_APT_INSTALL = 'apt install -y {}'
344+COMMAND_APT_INSTALL_STAGING_DEBS = COMMAND_APT_INSTALL.format(
345+ ' '.join(['../{}*.deb'.format(pkg) for pkg in PACKAGES_SNAPD]))
346+COMMAND_APT_UPDATE = 'apt update'
347+COMMAND_APT_UPGRADE = 'apt dist-upgrade -y'
348+COMMAND_BUILD_SNAPD = 'DEB_BUILD_OPTIONS="nocheck testkeys" ' \
349+ 'dpkg-buildpackage -tc -b'
350+COMMAND_EXPORT_STAGING_STORE_VAR = 'echo SNAPPY_USE_STAGING_STORE=1 >> ' \
351+ '/etc/environment'
352+COMMAND_GET_GOVENDOR = 'go get -v github.com/kardianos/govendor'
353+COMMAND_GIT_CLONE = 'git clone {} {}'
354+COMMAND_GOVENDOR_SYNC = 'govendor sync'
355+REPOSITORY_GIT = 'https://github.com/snapcore/snapd'
356+URL_API_ROOT = 'https://myapps.developer.staging.ubuntu.com/dev/api/'
357+URL_SEARCH_ROOT = 'https://search.apps.staging.ubuntu.com/'
358+URL_UPLOAD_ROOT = 'https://upload.apps.staging.ubuntu.com/'
359+URL_SSO_API_ROOT = 'https://login.staging.ubuntu.com/api/v2/'
360+
361+CONTAINER_SETUP = [
362+ COMMAND_REMOVE_SNAPD,
363+ COMMAND_APT_UPDATE,
364+ # Hold open-iscsi which is causing apt upgrade errors while running
365+ # inside container.
366+ 'apt-mark hold open-iscsi',
367+ COMMAND_APT_UPGRADE,
368+ # Needed for snaps to work inside a lxd container
369+ # ref: https://stgraber.org/2016/12/07/running-snaps-in-lxd-containers/
370+ COMMAND_APT_INSTALL.format('squashfuse'),
371+ COMMAND_GIT_CLONE.format(REPOSITORY_GIT, DIRECTORY_CLONE),
372+ {'command': COMMAND_APT_BUILD_DEP, 'cwd': DIRECTORY_CLONE},
373+ {'command': COMMAND_GET_GOVENDOR, 'cwd': DIRECTORY_CLONE},
374+ {'command': COMMAND_GOVENDOR_SYNC, 'cwd': DIRECTORY_CLONE},
375+ {'command': COMMAND_BUILD_SNAPD, 'cwd': DIRECTORY_CLONE},
376+ COMMAND_EXPORT_STAGING_STORE_VAR,
377+ {'command': COMMAND_APT_INSTALL_STAGING_DEBS, 'cwd': DIRECTORY_CLONE}
378+]
379+
380+CONTAINER_ENV_VARS = {
381+ 'GOPATH': CONTAINER_HOME,
382+ 'SNAPPY_USE_STAGING_STORE': '1',
383+ ENV_STORE_API_ROOT: URL_API_ROOT,
384+ ENV_STORE_SEARCH_ROOT: URL_SEARCH_ROOT,
385+ ENV_STORE_UPLOAD_ROOT: URL_UPLOAD_ROOT,
386+ ENV_SSO_API_ROOT: URL_SSO_API_ROOT,
387+}
388+
389+DEFAULT_CONTAINER_CONFIG = {
390+ "name": "snapd",
391+ "source": {
392+ "type": "image",
393+ "mode": "pull",
394+ "server": "https://cloud-images.ubuntu.com/releases",
395+ "protocol": "simplestreams",
396+ "fingerprint": "16.04"
397+ }
398+}
399
400=== added file 'snappy_ecosystem_tests/environment/managers.py'
401--- snappy_ecosystem_tests/environment/managers.py 1970-01-01 00:00:00 +0000
402+++ snappy_ecosystem_tests/environment/managers.py 2017-03-02 10:45:12 +0000
403@@ -0,0 +1,142 @@
404+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
405+
406+#
407+# Ubuntu System Tests
408+# Copyright (C) 2017 Canonical
409+#
410+# This program is free software: you can redistribute it and/or modify
411+# it under the terms of the GNU General Public License as published by
412+# the Free Software Foundation, either version 3 of the License, or
413+# (at your option) any later version.
414+#
415+# This program is distributed in the hope that it will be useful,
416+# but WITHOUT ANY WARRANTY; without even the implied warranty of
417+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
418+# GNU General Public License for more details.
419+#
420+# You should have received a copy of the GNU General Public License
421+# along with this program. If not, see <http://www.gnu.org/licenses/>.
422+#
423+
424+"""Managers to setup the environment"""
425+
426+import os
427+import shlex
428+from pylxd import Client
429+from pylxd.exceptions import NotFound, LXDAPIException
430+from retrying import retry
431+
432+from snappy_ecosystem_tests.environment import constants
433+from snappy_ecosystem_tests.environment.constants import (
434+ PROFILES, DEPENDENCIES)
435+from snappy_ecosystem_tests.environment.data.snapcraft import (
436+ SNAPCRAFT_CONTAINER_NAME)
437+from snappy_ecosystem_tests.environment.data.snapd import (
438+ DEFAULT_CONTAINER_CONFIG, SNAPD_CONTAINER_NAME)
439+
440+def get_manager(mode):
441+ """Get the manager for the given mode"""
442+ supported_modules = {
443+ "lxd": LxdManager
444+ }
445+ try:
446+ manager = supported_modules[mode]
447+ return manager()
448+ except KeyError:
449+ raise RuntimeError("Mode: {} is not supported".format(mode))
450+
451+
452+class LxdManager:
453+ """Manage lxd containers"""
454+
455+ def __init__(self):
456+ self.client = Client()
457+
458+ def launch(self, container_name, release='16.04'):
459+ """Launch a container"""
460+ try:
461+ container = self.client.containers.get(container_name)
462+ if container.status == "Running":
463+ container.stop(wait=True)
464+ container.delete(wait=True)
465+ except NotFound:
466+ pass
467+ container_config = DEFAULT_CONTAINER_CONFIG.copy()
468+ container_config['source']['alias'] = release
469+ container_config['name'] = container_name
470+ container = self.client.containers.create(container_config, wait=True)
471+ container.start(wait=True)
472+
473+ def execute_command(self, container_name, command):
474+ """execute command"""
475+ container = self.client.containers.get(container_name)
476+ container.execute(command)
477+
478+ def install(self, container_name, packages, channel=None):
479+ """Install a packages"""
480+ container = self.client.containers.get(container_name)
481+ container.execute(shlex.split('apt-get update'))
482+ install_command = 'apt-get install {} -y'.format(packages)
483+ if channel:
484+ install_command += ' -t {}'.format(channel)
485+ container.execute(shlex.split(install_command))
486+
487+ def install_dependencies(self, container_name, container_type):
488+ """Install a dependencies"""
489+ self.install(
490+ container_name,
491+ DEPENDENCIES[container_type] + DEPENDENCIES['shared'])
492+
493+
494+ def configure(self, container_name, container_type, profile):
495+ """Configure a given container"""
496+ container = self.client.containers.get(container_name)
497+ for variable in \
498+ PROFILES[profile][container_type]['environment_variables']:
499+ container.config.update({'environment.{}'.format(
500+ variable['name']): variable['value']})
501+ container.save(wait=True)
502+
503+ @retry(stop_max_attempt_number=5, wait_fixed=3000,
504+ retry_on_exception=lambda exception: isinstance(
505+ exception, LXDAPIException))
506+ def enable_ssh(self, container_name):
507+ """Enable the ssh connection on the container"""
508+ container = self.client.containers.get(container_name)
509+ pub_key = open(
510+ os.path.expanduser('~') + '/.ssh/id_rsa.pub').read().strip('\n')
511+ container.files.put('/home/ubuntu/.ssh/authorized_keys', pub_key)
512+
513+
514+ def setup(self, profile):
515+ """setup the container based on the profile"""
516+ self._setup(SNAPD_CONTAINER_NAME, constants.SNAPD, profile)
517+ self._setup(
518+ SNAPCRAFT_CONTAINER_NAME, constants.SNAPCRAFT, profile)
519+
520+
521+ def _setup(self, container_name, container_type, profile):
522+ """
523+ Launch a container, enable ssh, install dependencies
524+ and setup the needed environment variables
525+ """
526+ self.launch(container_name)
527+ self.enable_ssh(container_name)
528+ self.install(
529+ container_name,
530+ packages=PROFILES[profile][container_type]["package_name"],
531+ channel=PROFILES[profile][container_type]["channel"])
532+ self.install_dependencies(container_name, container_type)
533+ self.configure(container_name, container_type, profile)
534+
535+ def get_ip(self, container_name):
536+ """Gets the ip address for a given container"""
537+ networks = self.client.containers.get(
538+ container_name).state().network['eth0']['addresses']
539+
540+ for network in networks:
541+ if network['address']:
542+ return network['address']
543+ raise RuntimeError(
544+ "The container {} does not have an IPV4 connection".format(
545+ container_name))
546
547=== added file 'snappy_ecosystem_tests/environment/setup.py'
548--- snappy_ecosystem_tests/environment/setup.py 1970-01-01 00:00:00 +0000
549+++ snappy_ecosystem_tests/environment/setup.py 2017-03-02 10:45:12 +0000
550@@ -0,0 +1,46 @@
551+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
552+
553+#
554+# Ubuntu System Tests
555+# Copyright (C) 2017 Canonical
556+#
557+# This program is free software: you can redistribute it and/or modify
558+# it under the terms of the GNU General Public License as published by
559+# the Free Software Foundation, either version 3 of the License, or
560+# (at your option) any later version.
561+#
562+# This program is distributed in the hope that it will be useful,
563+# but WITHOUT ANY WARRANTY; without even the implied warranty of
564+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
565+# GNU General Public License for more details.
566+#
567+# You should have received a copy of the GNU General Public License
568+# along with this program. If not, see <http://www.gnu.org/licenses/>.
569+#
570+
571+"""Standalone script to setup an ecosystem environment"""
572+
573+import argparse
574+
575+import logging
576+
577+from snappy_ecosystem_tests.environment.managers import get_manager
578+
579+logging.basicConfig(level=logging.DEBUG)
580+
581+def main(mode, profile):
582+ """Main script"""
583+ manager = get_manager(mode)
584+ manager.setup(profile)
585+
586+
587+if __name__ == '__main__':
588+ PARSER = argparse.ArgumentParser(description=
589+ 'Setup a snappy ecosystem environment.')
590+ PARSER.add_argument('--mode', default="lxd",
591+ help='lxd')
592+ PARSER.add_argument('--profile', default="staging",
593+ help='Profile to configure the environment')
594+ ARGS = PARSER.parse_args()
595+
596+ main(ARGS.mode, ARGS.profile)
597
598=== modified file 'snappy_ecosystem_tests/helpers/snapcraft/client.py'
599--- snappy_ecosystem_tests/helpers/snapcraft/client.py 2017-02-15 19:35:54 +0000
600+++ snappy_ecosystem_tests/helpers/snapcraft/client.py 2017-03-02 10:45:12 +0000
601@@ -20,14 +20,49 @@
602
603 """Snapcraft client helpers"""
604
605+import logging
606+import subprocess
607+import time
608+
609 import pexpect
610
611-
612-# login credentials exported by shell environment
613+from snappy_ecosystem_tests.models.snap import Snap
614+from snappy_ecosystem_tests.utils import ssh
615+from snappy_ecosystem_tests.utils.commands import build_command
616+from snappy_ecosystem_tests.utils.filters import filter_list
617+from snappy_ecosystem_tests.utils.storeconfig import get_current_store
618+
619+from snappy_ecosystem_tests.commons.config import CONFIG_STACK
620+
621 from snappy_ecosystem_tests.utils import storeconfig
622
623+# login credentials gotten from config file or shell environment
624+from snappy_ecosystem_tests.utils.user import (
625+ get_snapcraft_remote_host_credentials
626+)
627+
628 LOGIN_EMAIL, LOGIN_PASSWORD = storeconfig.get_store_credentials()
629
630+# Commands
631+PATH_SNAPCRAFT = '/usr/bin/snapcraft'
632+COMMANDS_LOGIN = """\
633+/usr/bin/expect \
634+-c 'spawn {snapcraft} login' \
635+-c 'expect Email:' \
636+-c 'send {email}\\r' \
637+-c 'expect Password:' \
638+-c 'send {password}\\r' \
639+-c 'interact'\
640+"""
641+
642+COMMAND_LOGOUT = 'logout'
643+COMMAND_REGISTER = 'register'
644+COMMAND_LIST_REGISTERED = 'list-registered'
645+
646+LOGGER = logging.getLogger(__name__)
647+
648+HOSTNAME, USERNAME, PORT = get_snapcraft_remote_host_credentials()
649+
650
651 class Snapcraft(object):
652 """Contain Snapcraft specific functionality to use via command
653@@ -37,13 +72,37 @@
654 self._login = False
655 self._cleanup()
656
657+ @staticmethod
658+ def _run_snapcraft_command_ssh(command, debug=True):
659+ """
660+ Run snapcraft command via ssh
661+ :param command: the command to be executed.
662+ Can be a single string or a list of strings
663+ :param debug: whether to enable debug mode
664+ :return: the command's output
665+ """
666+ if not command.startswith(PATH_SNAPCRAFT):
667+ command = build_snapcraft_command(command)
668+ if debug:
669+ command += ' -d'
670+ return ssh.run_command(command, hostname=HOSTNAME, username=USERNAME,
671+ port=PORT)
672+
673+ def assert_logged_in(self):
674+ """Assert that an user is logged.
675+ :raise ValueError: in case login is false
676+ """
677+ if self._login is False:
678+ raise ValueError("User is not logged in, "
679+ "please login before using this command")
680+
681 def _cleanup(self):
682 """Perform cleanup actions"""
683 self.logout()
684
685 def logout(self):
686 """logout of snapcraft store session"""
687- child = pexpect.spawn("snapcraft logout")
688+ child = pexpect.spawn(build_snapcraft_command(COMMAND_LOGOUT))
689 err = child.expect('Credentials cleared.')
690 child.terminate(True)
691 child.wait()
692@@ -52,23 +111,105 @@
693
694 self._login = False
695
696- def login(self):
697- """login to store using the credential environment variables"""
698- child = pexpect.spawn("snapcraft login")
699- child.expect('Email: ')
700- child.sendline(LOGIN_EMAIL)
701- child.expect('Password:')
702- child.sendline(LOGIN_PASSWORD)
703- err = child.expect('Login successful')
704- if err is not 0:
705- raise ValueError("Failed to login")
706-
707- self._login = True
708-
709- def list_registered(self):
710- """call snapcraft list-registered command,
711- raise exception if not logged in"""
712- if self._login is False:
713- raise ValueError("User is not logged in, "
714- "please login before using this command")
715- return pexpect.spawnu("snapcraft list-registered").read()
716+ def login(self, email=LOGIN_EMAIL, password=LOGIN_PASSWORD):
717+ """Login to Snapcraft. If email and/or password are not provided,
718+ use the default ones.
719+ :param email: the SSO email
720+ :param password: the email password
721+ """
722+ output = ssh.run_command(
723+ COMMANDS_LOGIN.format(email=email, password=password,
724+ snapcraft=PATH_SNAPCRAFT),
725+ hostname=HOSTNAME, username=USERNAME, port=PORT)
726+ self._login = 'login successful' in output.lower()
727+ return self._login
728+
729+ def list_registered(self, debug=True, raw=False):
730+ """Call snapcraft list-registered command,
731+ raise exception if not logged in
732+ :param debug: whether to enable debug mode
733+ :param raw: whether to return the output as a raw.
734+ If False, return a list of Snap instances
735+ """
736+ self.assert_logged_in()
737+ registered_snaps_output = self._run_snapcraft_command_ssh(
738+ COMMAND_LIST_REGISTERED,
739+ debug=debug)
740+ if raw:
741+ return registered_snaps_output
742+ else:
743+ snaps = registered_snaps_output.splitlines()
744+ # if debug is set, the first 3 lines of output are the API calls
745+ return parse_snaps_raw(snaps if debug is False else snaps[3:])
746+
747+ def filter_snaps(self, **predicates):
748+ """
749+ Return a list of the snaps that match with all the given predicates.
750+ Examples:
751+ filter_snap() --> return all the snaps
752+ filter_snap(name='my_name') --> return the snaps that matches with
753+ name 'my_name'
754+ filter_snap(name='my_name', private=True) --> return the snaps that
755+ matches with name 'my_name' and are private.
756+ filter_snap(price='5') --> return the snaps with price '5'.
757+ :return: A list of snap instances
758+ """
759+ return filter_list(self.list_registered(raw=False), **predicates)
760+
761+ def register(self, snap_name, private=False, wait=True):
762+ """
763+ Register a snap name in the store.
764+ :param snap_name: the snap name to register.
765+ :param private: whether the snap name is private.
766+ :param wait: wheter to wait after registration to hitting the store
767+ restriction on following registrations
768+ :return: True if the snap was registered successfully, False otherwise.
769+ """
770+ self.assert_logged_in()
771+ LOGGER.info('About to register snap: %s', snap_name)
772+ command = build_snapcraft_command(COMMAND_REGISTER, snap_name)
773+ if private:
774+ command += ' --private'
775+ try:
776+ Snapcraft._run_snapcraft_command_ssh(command)
777+ except subprocess.CalledProcessError as _e:
778+ LOGGER.error('Unable to register snap: %s', _e.output)
779+ return False
780+ if wait:
781+ time.sleep(int(CONFIG_STACK.get('time_between_registrations',
782+ get_current_store())))
783+ LOGGER.info('Snap %s registered successfully!!!', snap_name)
784+ return True
785+
786+
787+def build_snapcraft_command(*args, base_command=PATH_SNAPCRAFT):
788+ """
789+ Build a snapcraft command with arguments
790+ :param args: list of arguments for the command
791+ :param base_command: snapcraft executable that is going to be used
792+ :return: the snapcraft command ready to be executed
793+ """
794+ return build_command(base_command, *args)
795+
796+
797+def parse_snaps_raw(raw):
798+ """
799+ Parse snaps raw output to a list of Snaps object
800+ :param raw: the raw that contains the snaps info.
801+ It assumes that the first line is the output Header like:
802+ (Name, Since, Price, etc.) to get the attributes order.
803+ :return: A list of snaps instances
804+ """
805+ attributes_order = {}
806+ for _i, att in enumerate(raw[0].split()):
807+ attributes_order[att.lower()] = _i
808+ snaps = []
809+ for snap_raw in raw[1:]:
810+ attrs = snap_raw.split()
811+ private = attrs[attributes_order.get('visibility')].lower() == 'private'
812+ snaps.append(Snap(name=attrs[attributes_order.get('name')],
813+ since=attrs[attributes_order.get('since')],
814+ private=private,
815+ price=attrs[attributes_order.get('price')],
816+ notes=attrs[attributes_order.get('notes')]))
817+ return snaps
818
819=== modified file 'snappy_ecosystem_tests/helpers/snapd/snapd.py'
820--- snappy_ecosystem_tests/helpers/snapd/snapd.py 2017-02-21 15:17:12 +0000
821+++ snappy_ecosystem_tests/helpers/snapd/snapd.py 2017-03-02 10:45:12 +0000
822@@ -26,6 +26,7 @@
823 import yaml
824
825 from snappy_ecosystem_tests.utils import ssh
826+from snappy_ecosystem_tests.utils.user import get_snapd_remote_host_credentials
827
828 PATH_SNAP = '/usr/bin/snap'
829 COMMAND_DOWNLOAD = 'download {snap} --channel={channel}'
830@@ -47,6 +48,8 @@
831 """
832 LOGGER = logging.getLogger(__name__)
833
834+HOSTNAME, USERNAME, PORT = get_snapd_remote_host_credentials()
835+
836
837 def run_snapd_command_ssh(parameters, cwd=''):
838 """Run snapd command over ssh.
839@@ -59,7 +62,8 @@
840 if cwd:
841 return ssh.run_command(
842 'cd {}; {} {}'.format(cwd, PATH_SNAP, parameters))
843- return ssh.run_command('{} {}'.format(PATH_SNAP, parameters))
844+ return ssh.run_command('{} {}'.format(PATH_SNAP, parameters),
845+ hostname=HOSTNAME, username=USERNAME, port=PORT)
846
847
848 def login(email, password):
849
850=== modified file 'snappy_ecosystem_tests/helpers/snapd/staging_builder.py'
851--- snappy_ecosystem_tests/helpers/snapd/staging_builder.py 2017-02-21 13:46:08 +0000
852+++ snappy_ecosystem_tests/helpers/snapd/staging_builder.py 2017-03-02 10:45:12 +0000
853@@ -24,6 +24,8 @@
854 import sys
855 from time import sleep
856
857+from snappy_ecosystem_tests.environment.data.snapd import (
858+ CONTAINER_HOME, CONTAINER_ENV_VARS, CONTAINER_SETUP)
859 from snappy_ecosystem_tests.utils.lxd import Container, launch_container
860
861 CONTAINER_HOME = '/root'
862@@ -71,15 +73,20 @@
863 COMMAND_EXPORT_STAGING_STORE_VAR,
864 {'command': COMMAND_APT_INSTALL_STAGING_DEBS, 'cwd': DIRECTORY_CLONE}
865 ]
866-
867-CONTAINER_ENV_VARS = {
868- 'GOPATH': CONTAINER_HOME,
869- 'SNAPPY_USE_STAGING_STORE': '1',
870+SNAPCRAFT_STAGING_VARIABLES = {
871 ENV_STORE_API_ROOT: URL_API_ROOT,
872 ENV_STORE_SEARCH_ROOT: URL_SEARCH_ROOT,
873 ENV_STORE_UPLOAD_ROOT: URL_UPLOAD_ROOT,
874 ENV_SSO_API_ROOT: URL_SSO_API_ROOT,
875 }
876+SNAPD_STAGING_VARIABLES = {
877+ 'SNAPPY_USE_STAGING_STORE': '1'
878+}
879+STAGING_VARIABLES = dict(
880+ SNAPCRAFT_STAGING_VARIABLES, **SNAPD_STAGING_VARIABLES)
881+CONTAINER_ENV_VARS = {
882+ 'GOPATH': CONTAINER_HOME,
883+}
884
885 LOGGER = logging.getLogger(__name__)
886
887
888=== modified file 'snappy_ecosystem_tests/helpers/store_apis/rest_apis.py'
889--- snappy_ecosystem_tests/helpers/store_apis/rest_apis.py 2017-02-17 18:41:32 +0000
890+++ snappy_ecosystem_tests/helpers/store_apis/rest_apis.py 2017-03-02 10:45:12 +0000
891@@ -45,6 +45,8 @@
892 from snappy_ecosystem_tests.helpers.snapcraft.options import ProjectOptions
893 from snappy_ecosystem_tests.helpers.store_apis import errors
894 from snappy_ecosystem_tests.helpers.store_apis.upload import upload_files
895+from snappy_ecosystem_tests.models.snap import Snap
896+from snappy_ecosystem_tests.utils.filters import filter_list
897
898 LOGGER = logging.getLogger(__name__)
899
900@@ -193,16 +195,28 @@
901 """Get current account information"""
902 return self._refresh_if_necessary(self.sca.get_account_information)
903
904+ def get_registered_snaps(self, series=constants.DEFAULT_SERIES):
905+ """Get registered snaps for current user.
906+ First refresh macaroon if necessary"""
907+ return self._refresh_if_necessary(self.sca.get_registered_snaps,
908+ series)
909+
910+ def filter_snaps(self, series=constants.DEFAULT_SERIES, **predicates):
911+ """Filter snaps that match with given predicates
912+ First refresh macaroon if necessary"""
913+ return self._refresh_if_necessary(self.sca.filter_snaps,
914+ series=series, **predicates)
915+
916 def register_key(self, account_key_request):
917 """Register a key for the current user"""
918 return self._refresh_if_necessary(
919 self.sca.register_key, account_key_request)
920
921- def register(self, snap_name, is_private=False):
922+ def register(self, snap_name, private=False):
923 """Register a package name for the current user
924 First refresh macaroon if necessary"""
925 return self._refresh_if_necessary(
926- self.sca.register, snap_name, is_private, constants.DEFAULT_SERIES)
927+ self.sca.register, snap_name, private, constants.DEFAULT_SERIES)
928
929 def push_precheck(self, snap_name):
930 """Do a snap push as a pre-check (dry_run: do not actually push)
931@@ -555,6 +569,36 @@
932 else:
933 raise errors.StoreAccountInformationError(response)
934
935+ def get_registered_snaps(self, series=constants.DEFAULT_SERIES):
936+ """
937+ Get the registered snaps for the current user
938+ :param series: get only snaps that match with this series
939+ :return: the list of registered snaps
940+ """
941+ account_info = self.get_account_information()
942+ user_snaps = account_info.get('snaps')
943+ snaps_dict = user_snaps.get(series)
944+ snaps = []
945+ for name, snap_data in snaps_dict.items():
946+ snaps.append(Snap(name=name, **snap_data))
947+ return snaps
948+
949+ def filter_snaps(self, series=constants.DEFAULT_SERIES, **predicates):
950+ """
951+ Return a list of the snaps that match with all the given predicates.
952+ :param: series: only look in the snaps that match with this series
953+ Examples:
954+ filter_snap() --> return all the snaps
955+ filter_snap(name='my_name') --> return the snaps that matches with
956+ name 'my_name'
957+ filter_snap(name='my_name', private=True) --> return the snaps that
958+ matches with name 'my_name' and are private.
959+ filter_snap(price='5') --> return the snaps that with price '5'.
960+ :return: A list of snap instances
961+ """
962+ return filter_list(self.get_registered_snaps(series=series),
963+ **predicates)
964+
965 def register_key(self, account_key_request):
966 """Register a key for a user with the given request
967 :param account_key_request: the key to register
968@@ -568,20 +612,21 @@
969 if not response.ok:
970 raise errors.StoreKeyRegistrationError(response)
971
972- def register(self, snap_name, is_private, series):
973+ def register(self, snap_name, private, series):
974 """Register a snap name in the store
975 :param snap_name: the name to be registered
976- :param is_private: whether the snap name is private or not
977+ :param private: whether the snap name is private or not
978 :param series: the snap's series to be registered
979 """
980 auth = _macaroon_auth(self.conf)
981- data = dict(snap_name=snap_name, is_private=is_private,
982+ data = dict(snap_name=snap_name, is_private=private,
983 series=series)
984 response = self.post(
985 'register-name/', data=json.dumps(data),
986- headers=dict({'Authorization': auth}, **JSON_ACCEPT))
987+ headers=dict({'Authorization': auth}, **JSON_CONTENT_TYPE))
988 if not response.ok:
989 raise errors.StoreRegistrationError(snap_name, response)
990+ return True
991
992 def snap_push_precheck(self, snap_name):
993 """Do a snap push pre-check (dry_run: do not actually push)
994
995=== added directory 'snappy_ecosystem_tests/models'
996=== added file 'snappy_ecosystem_tests/models/__init__.py'
997--- snappy_ecosystem_tests/models/__init__.py 1970-01-01 00:00:00 +0000
998+++ snappy_ecosystem_tests/models/__init__.py 2017-03-02 10:45:12 +0000
999@@ -0,0 +1,19 @@
1000+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
1001+
1002+#
1003+# Snappy Ecosystem Tests
1004+# Copyright (C) 2017 Canonical
1005+#
1006+# This program is free software: you can redistribute it and/or modify
1007+# it under the terms of the GNU General Public License as published by
1008+# the Free Software Foundation, either version 3 of the License, or
1009+# (at your option) any later version.
1010+#
1011+# This program is distributed in the hope that it will be useful,
1012+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1013+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1014+# GNU General Public License for more details.
1015+#
1016+# You should have received a copy of the GNU General Public License
1017+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1018+#
1019
1020=== added file 'snappy_ecosystem_tests/models/snap.py'
1021--- snappy_ecosystem_tests/models/snap.py 1970-01-01 00:00:00 +0000
1022+++ snappy_ecosystem_tests/models/snap.py 2017-03-02 10:45:12 +0000
1023@@ -0,0 +1,39 @@
1024+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
1025+
1026+#
1027+# Snappy Ecosystem Tests
1028+# Copyright (C) 2017 Canonical
1029+#
1030+# This program is free software: you can redistribute it and/or modify
1031+# it under the terms of the GNU General Public License as published by
1032+# the Free Software Foundation, either version 3 of the License, or
1033+# (at your option) any later version.
1034+#
1035+# This program is distributed in the hope that it will be useful,
1036+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1037+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1038+# GNU General Public License for more details.
1039+#
1040+# You should have received a copy of the GNU General Public License
1041+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1042+#
1043+
1044+"""Business model classes for snaps"""
1045+
1046+
1047+class Snap:
1048+ """Represents a snap entity."""
1049+
1050+ def __init__(self, name='', price=None, private=False, since=None,
1051+ _id=None, status=None, notes=None, **kwargs):
1052+ self.name = name
1053+ self.price = price
1054+ self.private = private
1055+ self.since = since
1056+ self._id = _id or kwargs.get('snap-id')
1057+ self.status = status
1058+ self.notes = notes
1059+
1060+ def is_private(self):
1061+ """Return True if the snap is private, False otherwise"""
1062+ return self.private
1063
1064=== modified file 'snappy_ecosystem_tests/run.py'
1065--- snappy_ecosystem_tests/run.py 2017-02-15 19:14:19 +0000
1066+++ snappy_ecosystem_tests/run.py 2017-03-02 10:45:12 +0000
1067@@ -20,28 +20,38 @@
1068
1069 """Entry point to run snappy ecosystem tests"""
1070
1071+import argparse
1072+import os
1073 import re
1074 import sys
1075 import pytest
1076
1077-FILTER_ARGUMENTS = '--proxy'
1078-
1079-
1080-def _filter_arguments():
1081- """Remove from command line arguments all the ones that are in
1082- FILTER_ARGUMENTS list."""
1083- filtered_args = sys.argv[1:]
1084- for i, arg in enumerate(sys.argv[1:]):
1085- if arg in FILTER_ARGUMENTS:
1086- filtered_args.pop(i + 1)
1087- filtered_args.pop(i)
1088- return filtered_args
1089-
1090
1091 def _parse_arguments():
1092 """Parse and filter command line arguments to makethem pytest compatible"""
1093 sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
1094- return _filter_arguments()
1095+ parser = argparse.ArgumentParser(description=
1096+ 'Run snappy ecosystem tests.')
1097+ parser.add_argument('--proxy',
1098+ help='proxy to use for creating the virtual env.',
1099+ required=False)
1100+ parser.add_argument('--target', default="lxd",
1101+ help='Target on which tests will be executed.')
1102+ ecosystem_args, pytest_args = parser.parse_known_args()
1103+ _set_env_variables(ecosystem_args)
1104+ return pytest_args
1105+
1106+
1107+def _set_env_variables(args):
1108+ """
1109+ Set environment variables with ecosystem arguments passed
1110+ in the command line.
1111+ :param args: The arguments to store in env variables
1112+ """
1113+ for arg in vars(args):
1114+ value = getattr(args, arg, None)
1115+ if value:
1116+ os.environ[arg] = value
1117
1118 if __name__ == '__main__':
1119 sys.exit(pytest.main(args=_parse_arguments() + ['-p', 'no:cacheprovider']))
1120
1121=== added file 'snappy_ecosystem_tests/tests/test_register_snap.py'
1122--- snappy_ecosystem_tests/tests/test_register_snap.py 1970-01-01 00:00:00 +0000
1123+++ snappy_ecosystem_tests/tests/test_register_snap.py 2017-03-02 10:45:12 +0000
1124@@ -0,0 +1,116 @@
1125+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
1126+
1127+#
1128+# Snappy Ecosystem Tests
1129+# Copyright (C) 2017 Canonical
1130+#
1131+# This program is free software: you can redistribute it and/or modify
1132+# it under the terms of the GNU General Public License as published by
1133+# the Free Software Foundation, either version 3 of the License, or
1134+# (at your option) any later version.
1135+#
1136+# This program is distributed in the hope that it will be useful,
1137+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1138+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1139+# GNU General Public License for more details.
1140+#
1141+# You should have received a copy of the GNU General Public License
1142+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1143+#
1144+
1145+"""Tests for Registering a snap name in the store"""
1146+
1147+import uuid
1148+
1149+from snappy_ecosystem_tests.helpers.snapcraft.client import Snapcraft
1150+from snappy_ecosystem_tests.helpers.store_apis.rest_apis import Store
1151+from snappy_ecosystem_tests.helpers.test_base import SnappyEcosystemTestCase
1152+from snappy_ecosystem_tests.utils.storeconfig import get_store_credentials
1153+
1154+
1155+class RegisterSnapNameTestCase(SnappyEcosystemTestCase):
1156+
1157+ def setUp(self):
1158+ super().setUp()
1159+ self.store = Store()
1160+ self.snapcraft = Snapcraft()
1161+ self.store.login(*get_store_credentials())
1162+ self.addCleanup(self.store.logout)
1163+ self.snapcraft.login()
1164+ self.addCleanup(self.snapcraft.logout)
1165+
1166+ @staticmethod
1167+ def _get_random_snap_name(prefix='ecosystem-test'):
1168+ """Get a random snap name using uuid
1169+ :param prefix: the string prefix,
1170+ if not provided, use default one.
1171+ """
1172+ return '{}{}'.format(prefix, int(uuid.uuid4()))
1173+
1174+ def test_register_public_snap_name_using_snapcraft(self):
1175+ """Test register a public snap name via snapcraft
1176+ and verify it via REST API"""
1177+ # Register snap via Snapcraft
1178+ snap_name = self._get_random_snap_name()
1179+ self.assertTrue(self.snapcraft.register(snap_name),
1180+ 'Unable to register snap')
1181+
1182+ # Verify the registered snap via REST API
1183+ snaps = self.store.filter_snaps(name=snap_name)
1184+ self.assertEqual(1, len(snaps),
1185+ 'Expected 1 snap with name %s but found %s'
1186+ % (snap_name, len(snaps)))
1187+ snap = snaps[0]
1188+ self.assertEqual(snap_name, snap.name)
1189+ self.assertFalse(snap.is_private())
1190+
1191+ def test_register_private_snap_name_using_snapcraft(self):
1192+ """Test register a private snap name via snapcraft
1193+ and verify it via REST API"""
1194+ # Register snap via Snapcraft
1195+ snap_name = self._get_random_snap_name()
1196+ self.assertTrue(self.snapcraft.register(snap_name, private=True),
1197+ 'Unable to register snap')
1198+
1199+ # Verify the registered snap via REST API
1200+ snaps = self.store.filter_snaps(name=snap_name)
1201+ self.assertEqual(1, len(snaps),
1202+ 'Expected 1 snap with name %s but found %s'
1203+ % (snap_name, len(snaps)))
1204+ snap = snaps[0]
1205+ self.assertEqual(snap_name, snap.name)
1206+ self.assertTrue(snap.is_private())
1207+
1208+ def test_register_public_snap_name_using_api(self):
1209+ """Verify that snapcraft lists a new snap registered via
1210+ RESTful API when using the command snapcraft list-registered"""
1211+ # Register snap via API
1212+ snap_name = self._get_random_snap_name()
1213+ self.assertTrue(self.store.register(snap_name),
1214+ 'Unable to register snap')
1215+
1216+ # Verify the registered snap via Snapcraft
1217+ snaps = self.snapcraft.filter_snaps(name=snap_name)
1218+ self.assertEqual(1, len(snaps),
1219+ 'Expected 1 snap with name %s but found %s'
1220+ % (snap_name, len(snaps)))
1221+ snap = snaps[0]
1222+ self.assertEqual(snap_name, snap.name)
1223+ self.assertFalse(snap.is_private())
1224+
1225+ def test_register_private_snap_name_using_api(self):
1226+ """Verify that snapcraft lists a new private snap registered via
1227+ RESTful API when using the command snapcraft list-registered"""
1228+ # Register snap via API
1229+ snap_name = self._get_random_snap_name()
1230+ self.assertTrue(self.store.register(snap_name, private=True),
1231+ 'Unable to register snap')
1232+
1233+ # Verify the registered snap via Snapcraft
1234+ snaps = self.snapcraft.filter_snaps(name=snap_name)
1235+ self.assertEqual(1, len(snaps),
1236+ 'Expected 1 snap with name %s but found %s'
1237+ % (snap_name, len(snaps)))
1238+ snap = snaps[0]
1239+ self.assertEqual(snap_name, snap.name)
1240+ self.assertTrue(snap.is_private())
1241
1242=== added file 'snappy_ecosystem_tests/unittests/test_filters.py'
1243--- snappy_ecosystem_tests/unittests/test_filters.py 1970-01-01 00:00:00 +0000
1244+++ snappy_ecosystem_tests/unittests/test_filters.py 2017-03-02 10:45:12 +0000
1245@@ -0,0 +1,113 @@
1246+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
1247+
1248+#
1249+# Snappy Ecosystem Tests
1250+# Copyright (C) 2017 Canonical
1251+#
1252+# This program is free software: you can redistribute it and/or modify
1253+# it under the terms of the GNU General Public License as published by
1254+# the Free Software Foundation, either version 3 of the License, or
1255+# (at your option) any later version.
1256+#
1257+# This program is distributed in the hope that it will be useful,
1258+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1259+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1260+# GNU General Public License for more details.
1261+#
1262+# You should have received a copy of the GNU General Public License
1263+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1264+#
1265+
1266+"""Unit tests cases for filter utils"""
1267+
1268+from testtools import (
1269+ TestCase,
1270+ ExpectedException
1271+)
1272+
1273+from snappy_ecosystem_tests.utils.filters import (
1274+ object_filter,
1275+ filter_list
1276+)
1277+
1278+
1279+class DummyObject: # pylint: disable=too-few-public-methods
1280+ """Dummy object to be used in unit tests"""
1281+
1282+ def __init__(self, **kwargs):
1283+ for _k, _v in kwargs.items():
1284+ setattr(self, _k, _v)
1285+
1286+
1287+class FilterTestCase(TestCase):
1288+
1289+ def setUp(self):
1290+ super().setUp()
1291+ self.obj = DummyObject(name='dummy', desc='this is dummy')
1292+ self.obj_2 = DummyObject(name='another-dummy',
1293+ desc='this is another dummy')
1294+ self.objects = [self.obj, self.obj_2]
1295+
1296+ def test_object_filter_with_single_argument(self):
1297+ """Filter successfully passing one argument"""
1298+ objects = list(filter(object_filter(name='dummy'), self.objects))
1299+ self.assertIsNotNone(objects)
1300+ self.assertEqual(len(objects), 1)
1301+ self.assertEqual(objects[0], self.obj)
1302+
1303+ def test_object_filter_with_multiple_arguments(self):
1304+ """Filter successfully passing two arguments"""
1305+ objects = list(filter(object_filter(name='dummy',
1306+ desc='this is dummy'),
1307+ self.objects))
1308+ self.assertIsNotNone(objects)
1309+ self.assertEqual(len(objects), 1)
1310+ self.assertEqual(objects[0], self.obj)
1311+
1312+ def test_object_filter_does_not_match(self):
1313+ """Return empty list when no object match criteria"""
1314+ objects = list(filter(object_filter(name='dummy',
1315+ desc='any desc'),
1316+ self.objects))
1317+ self.assertEqual([], objects)
1318+
1319+ def test_object_filter_return_all(self):
1320+ """Get all objects when no filter is provided"""
1321+ objects = list(filter(object_filter(), self.objects))
1322+ self.assertEqual(len(objects), len(self.objects))
1323+
1324+ def test_object_filter_raises_attribute_error_if_invalid_filter_name(self):
1325+ """Object filter raises AttributeError when invalid filter
1326+ is provided"""
1327+ with ExpectedException(AttributeError):
1328+ list(filter(object_filter(invalid='dummy'), self.objects))
1329+
1330+ def test_filter_list_with_single_argument(self):
1331+ """Filter List successfully passing one argument"""
1332+ objects = filter_list(self.objects, name='dummy')
1333+ self.assertIsNotNone(objects)
1334+ self.assertEqual(len(objects), 1)
1335+ self.assertEqual(objects[0], self.obj)
1336+
1337+ def test_filter_list_with_multiple_arguments(self):
1338+ """Filter List successfully passing multiple argument"""
1339+ objects = filter_list(self.objects, name='another-dummy',
1340+ desc='this is another dummy')
1341+ self.assertIsNotNone(objects)
1342+ self.assertEqual(len(objects), 1)
1343+ self.assertEqual(objects[0], self.obj_2)
1344+
1345+ def test_filter_list_does_not_match(self):
1346+ """Filter List returns empty list when no object match criteria"""
1347+ objects = filter_list(self.objects, desc='desc does not match')
1348+ self.assertEqual([], objects)
1349+
1350+ def test_filter_list_return_all(self):
1351+ """Filter list returns all objects when no filter is provided"""
1352+ objects = filter_list(self.objects)
1353+ self.assertEqual(len(objects), len(self.objects))
1354+
1355+ def test_filter_list_raises_attribute_error_if_invalid_filter_name(self):
1356+ """Filter list raises AttributeError when invalid filter is provided"""
1357+ with ExpectedException(AttributeError):
1358+ filter_list(self.objects, invalid='invalid filter')
1359
1360=== removed file 'snappy_ecosystem_tests/unittests/test_snapcraft.py'
1361--- snappy_ecosystem_tests/unittests/test_snapcraft.py 2017-02-13 16:00:04 +0000
1362+++ snappy_ecosystem_tests/unittests/test_snapcraft.py 1970-01-01 00:00:00 +0000
1363@@ -1,31 +0,0 @@
1364-# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
1365-
1366-#
1367-# Snappy Ecosystem Tests
1368-# Copyright (C) 2017 Canonical
1369-#
1370-# This program is free software: you can redistribute it and/or modify
1371-# it under the terms of the GNU General Public License as published by
1372-# the Free Software Foundation, either version 3 of the License, or
1373-# (at your option) any later version.
1374-#
1375-# This program is distributed in the hope that it will be useful,
1376-# but WITHOUT ANY WARRANTY; without even the implied warranty of
1377-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1378-# GNU General Public License for more details.
1379-#
1380-# You should have received a copy of the GNU General Public License
1381-# along with this program. If not, see <http://www.gnu.org/licenses/>.
1382-#
1383-
1384-"""Unit tests cases for snapcraft"""
1385-
1386-from unittest2 import TestCase
1387-
1388-
1389-class SnapcraftTestCase(TestCase):
1390-
1391- def test_snapcraft_dummy_test(self):
1392- """Dummy test case"""
1393- _a = True
1394- self.assertTrue(_a)
1395
1396=== added file 'snappy_ecosystem_tests/utils/commands.py'
1397--- snappy_ecosystem_tests/utils/commands.py 1970-01-01 00:00:00 +0000
1398+++ snappy_ecosystem_tests/utils/commands.py 2017-03-02 10:45:12 +0000
1399@@ -0,0 +1,31 @@
1400+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
1401+
1402+#
1403+# Snappy Ecosystem Tests
1404+# Copyright (C) 2017 Canonical
1405+#
1406+# This program is free software: you can redistribute it and/or modify
1407+# it under the terms of the GNU General Public License as published by
1408+# the Free Software Foundation, either version 3 of the License, or
1409+# (at your option) any later version.
1410+#
1411+# This program is distributed in the hope that it will be useful,
1412+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1413+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1414+# GNU General Public License for more details.
1415+#
1416+# You should have received a copy of the GNU General Public License
1417+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1418+#
1419+
1420+"""Manage commands to be executed in a shell"""
1421+
1422+
1423+def build_command(command, *args):
1424+ """
1425+ Build a command with arguments
1426+ :param command: the executable that is going to be used
1427+ :param args: list of arguments for the command
1428+ :return: the command ready to be executed
1429+ """
1430+ return'{c} {a}'.format(c=command, a=' '.join(args)).strip()
1431
1432=== added file 'snappy_ecosystem_tests/utils/filters.py'
1433--- snappy_ecosystem_tests/utils/filters.py 1970-01-01 00:00:00 +0000
1434+++ snappy_ecosystem_tests/utils/filters.py 2017-03-02 10:45:12 +0000
1435@@ -0,0 +1,51 @@
1436+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
1437+
1438+#
1439+# Snappy Ecosystem Tests
1440+# Copyright (C) 2017 Canonical
1441+#
1442+# This program is free software: you can redistribute it and/or modify
1443+# it under the terms of the GNU General Public License as published by
1444+# the Free Software Foundation, either version 3 of the License, or
1445+# (at your option) any later version.
1446+#
1447+# This program is distributed in the hope that it will be useful,
1448+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1449+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1450+# GNU General Public License for more details.
1451+#
1452+# You should have received a copy of the GNU General Public License
1453+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1454+#
1455+
1456+"""Filter utils"""
1457+
1458+
1459+def object_filter(**predicates):
1460+ """
1461+ Higher-order function to build and return an object filter function
1462+ :param predicates: key/values that represent
1463+ the conditions to look for in the object instance.
1464+ :return: a function to be used with filter or lambda expressions.
1465+ :raise: AttributeError if any of the attributes provided in predicates
1466+ does not exists
1467+ """
1468+ def wrapped_filter(instance):
1469+ """wrapped function to be returned when calling object_filter"""
1470+ return all(getattr(instance,
1471+ param) == val for param, val in predicates.items())
1472+ return wrapped_filter
1473+
1474+
1475+def filter_list(objects_list, **predicates):
1476+ """
1477+ Filter a list of objects with the given predicates
1478+ :param objects_list: the target list that contains
1479+ the objects to be filtered
1480+ :param predicates: key/values that represent
1481+ the conditions to look for in the object list.
1482+ :return: A list with the objects that match all the predicates
1483+ :raise: AttributeError if any of the attributes provided in predicates
1484+ does not exists
1485+ """
1486+ return list(filter(object_filter(**predicates), objects_list))
1487
1488=== modified file 'snappy_ecosystem_tests/utils/ssh.py'
1489--- snappy_ecosystem_tests/utils/ssh.py 2017-02-22 18:56:04 +0000
1490+++ snappy_ecosystem_tests/utils/ssh.py 2017-03-02 10:45:12 +0000
1491@@ -23,6 +23,8 @@
1492 import paramiko
1493
1494 from snappy_ecosystem_tests.utils.user import get_remote_host_credentials
1495+from snappy_ecosystem_tests.helpers.snapd.staging_builder import (
1496+ STAGING_VARIABLES)
1497
1498
1499 class SSHManager:
1500@@ -83,10 +85,13 @@
1501 :raises ValueError: if command exits with non-zero status.
1502 :return: the stdout of the command.
1503 """
1504- _hostname, _username, _port = get_remote_host_credentials()
1505+ # Take snapd remote credentials as default if they are not provided.
1506+ # Just arbitrary... Could have been other ones.
1507+ _hostname, _username, _port = get_snapd_remote_host_credentials()
1508 ssh = SSHManager.get_instance(
1509 hostname or _hostname, username or _username, port or _port)
1510- _, stdout, stderr = ssh.exec_command(command)
1511+ _, stdout, stderr = ssh.exec_command(
1512+ command, environment=STAGING_VARIABLES)
1513 if stdout.channel.recv_exit_status() != 0:
1514 raise ValueError(stderr.read().decode())
1515 return stdout.read().decode()
1516
1517=== added file 'snappy_ecosystem_tests/utils/store_versions.py'
1518--- snappy_ecosystem_tests/utils/store_versions.py 1970-01-01 00:00:00 +0000
1519+++ snappy_ecosystem_tests/utils/store_versions.py 2017-03-02 10:45:12 +0000
1520@@ -0,0 +1,74 @@
1521+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
1522+
1523+#
1524+# Snappy Ecosystem Tests
1525+# Copyright (C) 2017 Canonical
1526+#
1527+# This program is free software: you can redistribute it and/or modify
1528+# it under the terms of the GNU General Public License as published by
1529+# the Free Software Foundation, either version 3 of the License, or
1530+# (at your option) any later version.
1531+#
1532+# This program is distributed in the hope that it will be useful,
1533+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1534+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1535+# GNU General Public License for more details.
1536+#
1537+# You should have received a copy of the GNU General Public License
1538+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1539+#
1540+
1541+"""Utility for printing Store versions of: CPI, SCA and SSO.
1542+To be called as a standalone script.
1543+"""
1544+
1545+import requests
1546+
1547+DEFAULT_HEADER = "X-BZR-REVISION-NUMBER"
1548+
1549+SERVICES_INFO = dict(
1550+ CPI=('https://search.apps.ubuntu.com/api/v1',
1551+ 'https://search.apps.staging.ubuntu.com/api/v1'),
1552+ SCA=('https://myapps.developer.ubuntu.com/',
1553+ 'https://myapps.developer.staging.ubuntu.com/'),
1554+ SSO=('https://login.ubuntu.com/',
1555+ 'https://login.staging.ubuntu.com/'),
1556+)
1557+
1558+
1559+def get_deployed_revno(service, environment):
1560+ """Get revno from service."""
1561+ prod, stag = SERVICES_INFO[service]
1562+ if environment == 'staging':
1563+ url = stag
1564+ else:
1565+ url = prod
1566+ with requests.Session() as session:
1567+ resp = session.get(url)
1568+ if resp.status_code == 200:
1569+ revno = resp.headers[DEFAULT_HEADER]
1570+ else:
1571+ print("{} 500'ed: {}".format(service, resp.text))
1572+ revno = 0
1573+ return service, environment, revno
1574+
1575+
1576+def print_versions():
1577+ """Print Store components version"""
1578+ coros = []
1579+ for service in SERVICES_INFO:
1580+ coro = get_deployed_revno(service, 'staging')
1581+ coros.append(coro)
1582+ coro = get_deployed_revno(service, 'production')
1583+ coros.append(coro)
1584+
1585+ data = {(service, kind): value for service, kind, value in coros}
1586+ print("#########################-STORE VERSIONS-#########################")
1587+ for service in sorted(SERVICES_INFO):
1588+ print("{}: Staging: {:>5}".format(service,
1589+ data[(service, 'staging')]))
1590+ print("{}: Production: {:>5}".format(service,
1591+ data[(service, 'production')]))
1592+
1593+if __name__ == '__main__':
1594+ print_versions()
1595
1596=== modified file 'snappy_ecosystem_tests/utils/storeconfig.py'
1597--- snappy_ecosystem_tests/utils/storeconfig.py 2017-02-15 19:14:19 +0000
1598+++ snappy_ecosystem_tests/utils/storeconfig.py 2017-03-02 10:45:12 +0000
1599@@ -27,8 +27,8 @@
1600 USER_CONFIG_STACK
1601 )
1602
1603-URL_WEB_STORE_PRODUCTION = CONFIG_STACK.get('web-ui', 'production_url')
1604-URL_WEB_STORE_STAGING = CONFIG_STACK.get('web-ui', 'stage_url')
1605+URL_WEB_STORE_PRODUCTION = CONFIG_STACK.get('production_urls', 'web')
1606+URL_WEB_STORE_STAGING = CONFIG_STACK.get('staging_urls', 'web')
1607
1608
1609 def get_store_credentials():
1610
1611=== modified file 'snappy_ecosystem_tests/utils/user.py'
1612--- snappy_ecosystem_tests/utils/user.py 2017-02-22 15:39:40 +0000
1613+++ snappy_ecosystem_tests/utils/user.py 2017-03-02 10:45:12 +0000
1614@@ -23,13 +23,34 @@
1615 import os
1616
1617 from snappy_ecosystem_tests.commons.config import USER_CONFIG_STACK
1618-
1619-
1620-def get_remote_host_credentials():
1621- """Return credentials for remote machine, to run commands on."""
1622- return (USER_CONFIG_STACK.get('user', 'hostname_remote',
1623- default=os.environ.get('hostname_remote')),
1624- USER_CONFIG_STACK.get('user', 'username_remote',
1625- default=os.environ.get('username_remote')),
1626- USER_CONFIG_STACK.get('user', 'port_remote',
1627- default=os.environ.get('port_remote')))
1628+from snappy_ecosystem_tests.environment.managers import get_manager
1629+
1630+MANAGER = get_manager(os.environ['target'])
1631+
1632+
1633+def get_snapd_remote_host_credentials():
1634+ """Return credentials for snapd remote machine, to run commands on."""
1635+ _ip = MANAGER.get_ip(USER_CONFIG_STACK.get(
1636+ 'user', 'snapd_hostname_remote',
1637+ default=os.environ.get('snapd_hostname_remote')))
1638+ return (_ip,
1639+ USER_CONFIG_STACK.get('user', 'snapd_username_remote',
1640+ default=os.environ.get(
1641+ 'snapd_username_remote')),
1642+ USER_CONFIG_STACK.get('user', 'snapd_port_remote',
1643+ default=os.environ.get(
1644+ 'snapd_port_remote')))
1645+
1646+
1647+def get_snapcraft_remote_host_credentials():
1648+ """Return credentials for snapcraft remote machine, to run commands on."""
1649+ _ip = MANAGER.get_ip(USER_CONFIG_STACK.get(
1650+ 'user', 'snapcraft_hostname_remote',
1651+ default=os.environ.get('snapcraft_snapcraft_remote')))
1652+ return (_ip,
1653+ USER_CONFIG_STACK.get('user', 'snapcraft_username_remote',
1654+ default=os.environ.get(
1655+ 'snapcraft_username_remote')),
1656+ USER_CONFIG_STACK.get('user', 'snapcraft_port_remote',
1657+ default=os.environ.get(
1658+ 'snapcraft_port_remote')))

Subscribers

People subscribed via source and target branches