Merge lp:~canonical-platform-qa/snappy-ecosystem-tests/fix-snapd-staging into lp:snappy-ecosystem-tests

Proposed by Omer Akram
Status: Merged
Approved by: Omer Akram
Approved revision: 64
Merged at revision: 41
Proposed branch: lp:~canonical-platform-qa/snappy-ecosystem-tests/fix-snapd-staging
Merge into: lp:snappy-ecosystem-tests
Diff against target: 221 lines (+81/-38)
4 files modified
snappy_ecosystem_tests/environment/constants.py (+36/-11)
snappy_ecosystem_tests/environment/containers/lxd.py (+36/-13)
snappy_ecosystem_tests/environment/managers.py (+6/-3)
snappy_ecosystem_tests/helpers/snapcraft/client.py (+3/-11)
To merge this branch: bzr merge lp:~canonical-platform-qa/snappy-ecosystem-tests/fix-snapd-staging
Reviewer Review Type Date Requested Status
Heber Parrucci (community) Approve
platform-qa-bot continuous-integration Approve
Santiago Baldassin (community) Approve
Review via email: mp+319468@code.launchpad.net

Commit message

Enable snapd staging environment

Description of the change

Enable snapd staging environment.

Note: Currently its downloading from my personal ppa, we will update that soon once we have new PPAs created and get in place a mechanism to upload automatically to ~canonical-platform-qa staging ppas.

To post a comment you must log in.
51. By Omer Akram

merge with trunk

Revision history for this message
platform-qa-bot (platform-qa-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Omer Akram (om26er) wrote :

Note: snapd staging environment does not require those environment variables that I removed. Also to allow for installation from ppa I had to remove "xenial" as default channel.

Also note: the code is now executed inside sh -c because it allows us to run complex commands like one line conditions.

Revision history for this message
platform-qa-bot (platform-qa-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Santiago Baldassin (sbaldassin) wrote :

Code looks good to me

review: Approve
52. By Omer Akram

merge with trunk

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 :

inline diff

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

Added a comment inline.

53. By Omer Akram

merge with trunk

Revision history for this message
platform-qa-bot (platform-qa-bot) wrote :
review: Approve (continuous-integration)
54. By Omer Akram

merge with trunk

55. By Omer Akram

merge with trunk

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 :

One problem with this branch is that its setting permanent environment variables to containers inside /etc/environment. While that is fine for snapd given it reads from there only but for snapcraft we need another solution here.

How about adding methods to Snapcraft and Snapd classes to toggle staging/production/XX urls inside the container. This will also help us to remove the need to pass in environment variables through ssh commands.

56. By Omer Akram

fix staging search url

Revision history for this message
platform-qa-bot (platform-qa-bot) wrote :
review: Approve (continuous-integration)
57. By Omer Akram

Switch store on demand

Revision history for this message
platform-qa-bot (platform-qa-bot) wrote :
review: Needs Fixing (continuous-integration)
58. By Omer Akram

add production urls

Revision history for this message
platform-qa-bot (platform-qa-bot) wrote :
review: Needs Fixing (continuous-integration)
59. By Omer Akram

Make pylint happy by reducing code duplication

60. By Omer Akram

Lets not export environment variables for each ssh command

Revision history for this message
platform-qa-bot (platform-qa-bot) wrote :
review: Approve (continuous-integration)
61. By Omer Akram

remove environment variable whitelist code as that's obsolete with the new approach

62. By Omer Akram

more removal of unneeded code

Revision history for this message
platform-qa-bot (platform-qa-bot) wrote :
review: Approve (continuous-integration)
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 :

Updated this branch to add new methods to Snapcraft and Snapd to dynamically switch the store they are interested in. This also allowed me to remove code that needed to whitelist variable exports over ssh.

So basically a test, self.snapd.switch_store('production') and it will point to production servers, similar snapcraft can do the toggle as well.

One open question: Do we still externally want to decide if a test should be run in production or staging through environment variable ? Or is it fine to give that responsibility to the test. OR do we want both ?

Our base test class could read from an environment variable if it should direct to staging or production for external control.

Thoughts ?

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

> Updated this branch to add new methods to Snapcraft and Snapd to dynamically
> switch the store they are interested in. This also allowed me to remove code
> that needed to whitelist variable exports over ssh.
>
> So basically a test, self.snapd.switch_store('production') and it will point
> to production servers, similar snapcraft can do the toggle as well.
>
> One open question: Do we still externally want to decide if a test should be
> run in production or staging through environment variable ? Or is it fine to
> give that responsibility to the test. OR do we want both ?
>
> Our base test class could read from an environment variable if it should
> direct to staging or production for external control.
>
> Thoughts ?

IMHO we want to point the environment to a given store: prod, staging, etc. But this should be resolved in environment setup. The tests shouldn't know if they are being executed against a particular store. What we might want is pointing different product to different stores, for example:
snapd --> prod
snapcraft --> staging

But this should be resolved in setup time. I think it this dangerous if we give to the tests the capability to switch to another store. Because we will end up not being sure what environment we are actually testing.

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

Comment inline

review: Needs Fixing
Revision history for this message
I Ahmad (iahmad) :
63. By Omer Akram

Add FIXME to replace PPAs with one from team

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 :

replied inline.

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

Heber, added a reply inline.

What this code is doing is, it is setting up staging environment OR production environment based on what parameter was provided to run_setup script. Now we no longer need to pass in environment variables over ssh as they are put inside the container during setup.

The switch_store() methods that I have written allow for dynamic switching by the test code, if this is not what we desire I can remove those functions. But we would lose the flexibility of changing/toggling between staging/production from within our test and the environment we first setup with run_setup is going to be permanent.

I would like to know what others think about that.

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

> Heber, added a reply inline.
>
> What this code is doing is, it is setting up staging environment OR production
> environment based on what parameter was provided to run_setup script. Now we
> no longer need to pass in environment variables over ssh as they are put
> inside the container during setup.
>
> The switch_store() methods that I have written allow for dynamic switching by
> the test code, if this is not what we desire I can remove those functions. But
> we would lose the flexibility of changing/toggling between staging/production
> from within our test and the environment we first setup with run_setup is
> going to be permanent.
>
> I would like to know what others think about that.

The question would be: are there any case in which we will want to switch the store inside a tests execution?
In my opinion the setup prepares the env pointing to one store (or 2 of we want to point snapd and snapcraft to different stores) and this is permanent in all the tests execution, so you know what you are testing. If you dynamically allow the tests to switch the store, you will not be sure if the tests passed for: prod, staging, or whatever env you want to test.

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

We can dynamically switch stores and be *sure* about that in our test code, (ensure it in setUp() lets say). Though if there isn't any use case, removing does make sense.

Revision history for this message
I Ahmad (iahmad) wrote :

I agree with Heber, don't see any use case for current scope of testing. We can always add it if needed in future.

64. By Omer Akram

remove dynamic environment switchers

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 :

Lets land this.

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

Code LGTM and it works properly.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'snappy_ecosystem_tests/environment/constants.py'
2--- snappy_ecosystem_tests/environment/constants.py 2017-03-10 10:18:26 +0000
3+++ snappy_ecosystem_tests/environment/constants.py 2017-03-13 08:59:44 +0000
4@@ -32,18 +32,13 @@
5 PROFILES = {
6 "staging": {
7 SNAPD: {
8- "channel": "xenial",
9+ "channel": "",
10 "package_name": 'snapd',
11 "environment_variables": {
12- "UBUNTU_STORE_API_ROOT_URL":
13- "https://myapps.developer.ubuntu.com/dev/api/",
14- "UBUNTU_STORE_UPLOAD_ROOT_URL":
15- "https://upload.apps.ubuntu.com",
16- "UBUNTU_SSO_API_ROOT_URL":
17- "https://login.ubuntu.com/api/v2/",
18- "UBUNTU_STORE_SEARCH_ROOT_URL":
19- "https://search.apps.ubuntu.com/"
20- }
21+ "SNAPPY_USE_STAGING_STORE": "1"
22+ },
23+ # FIXME: Update ppa to ~canonical-platform-qa team once ready.
24+ "ppas": ["ppa:om26er/snapd-candidate"]
25 },
26 SNAPCRAFT: {
27 "channel": "xenial",
28@@ -57,7 +52,37 @@
29 "https://login.staging.ubuntu.com/api/v2/",
30 "UBUNTU_STORE_SEARCH_ROOT_URL":
31 "https://search.apps.staging.ubuntu.com/"
32- }
33+ },
34+ "ppas": []
35+ },
36+ "snapweb": {
37+ "url": "https://myapps.developer.staging.ubuntu.com/"
38+ },
39+ },
40+ "production": {
41+ SNAPD: {
42+ "channel": "",
43+ "package_name": 'snapd',
44+ "environment_variables": {
45+ "SNAPPY_USE_STAGING_STORE": "0"
46+ },
47+ # FIXME: Update ppa to ~canonical-platform-qa team once ready.
48+ "ppas": ["ppa:om26er/snapd-candidate"]
49+ },
50+ SNAPCRAFT: {
51+ "channel": "xenial",
52+ "package_name": 'snapcraft',
53+ "environment_variables": {
54+ "UBUNTU_STORE_API_ROOT_URL":
55+ "https://myapps.developer.ubuntu.com/dev/api/",
56+ "UBUNTU_STORE_UPLOAD_ROOT_URL":
57+ "https://upload.apps.ubuntu.com/",
58+ "UBUNTU_SSO_API_ROOT_URL":
59+ "https://login.ubuntu.com/api/v2/",
60+ "UBUNTU_STORE_SEARCH_ROOT_URL":
61+ "https://search.apps.ubuntu.com/"
62+ },
63+ "ppas": []
64 },
65 "snapweb": {
66 "url": "https://myapps.developer.ubuntu.com/"
67
68=== modified file 'snappy_ecosystem_tests/environment/containers/lxd.py'
69--- snappy_ecosystem_tests/environment/containers/lxd.py 2017-03-10 09:32:09 +0000
70+++ snappy_ecosystem_tests/environment/containers/lxd.py 2017-03-13 08:59:44 +0000
71@@ -31,9 +31,6 @@
72 from snappy_ecosystem_tests.environment.data.snapd import (
73 DEFAULT_CONTAINER_CONFIG)
74
75-COMMAND_ALLOW_ENV_VARS = 'sed -i \'/^AcceptEnv/ s/$/ {}/\' ' \
76- '/etc/ssh/sshd_config'
77-
78 LOGGER = logging.getLogger(__name__)
79 DOMAIN_PING = 'ubuntu.com'
80
81@@ -73,6 +70,7 @@
82 :return: stdout of the command.
83 :raises ValueError: If command exists with a non-zero code.
84 """
85+ command_string = 'sh -c \'{}\''.format(command_string)
86 response = container.execute(shlex.split(command_string))
87 if response.exit_code == 0:
88 LOGGER.info(response.stdout.strip())
89@@ -86,15 +84,40 @@
90 if not cont.state().status == 'Running':
91 cont.start(wait=True)
92
93- @staticmethod
94- def install(container, packages, channel=None):
95+ def install(self, container, packages, channel=None):
96 """Install packages"""
97- LXDDriver._execute_command(container, 'apt-get update')
98- install_command = 'apt-get install {} -y'.format(
99+ self._execute_command(container, 'apt update')
100+ install_command = 'apt install {} -y --allow-downgrades'.format(
101 ' '.join(packages))
102 if channel:
103 install_command += ' -t {}'.format(channel)
104- LXDDriver._execute_command(container, install_command)
105+ self._execute_command(container, install_command)
106+
107+ def add_ppas(self, container, ppas, pin_priority=1001):
108+ """Add the given PPAs inside the container and set their pin priority.
109+ """
110+ for ppa in ppas:
111+ ppa_name = '-'.join(ppa.split(':')[1].split('/'))
112+ self._execute_command(
113+ container,
114+ 'add-apt-repository {} -y'.format(ppa))
115+ pin_config = '/etc/apt/preferences.d/{}'.format(ppa_name)
116+ self._execute_command(
117+ container,
118+ 'if [ -f {conf_file} ]; then rm {conf_file}; fi'.format(
119+ conf_file=pin_config))
120+ self._execute_command(
121+ container,
122+ 'echo "Package: *" >> {}'.format(pin_config))
123+ self._execute_command(
124+ container,
125+ 'echo "Pin: release o=LP-PPA-{}" >> {}'.format(
126+ ppa_name, pin_config))
127+ self._execute_command(
128+ container,
129+ 'echo "Pin-Priority: {}" >> {}'.format(
130+ pin_priority, pin_config))
131+ self._execute_command(container, 'apt update')
132
133 @staticmethod
134 @retry(stop_max_attempt_number=5, wait_fixed=3000,
135@@ -118,11 +141,11 @@
136 container.name))
137
138 def export_environment_variables(self, container, environment_variables):
139- """Allow export of environment variables over ssh."""
140- self._execute_command(
141- container,
142- COMMAND_ALLOW_ENV_VARS.format(' '.join(environment_variables)))
143- self._execute_command(container, 'service ssh restart')
144+ """Export permanent environment variables inside container."""
145+ for key, value in environment_variables.items():
146+ self._execute_command(
147+ container,
148+ 'echo \'{}={}\' >> /etc/environment'.format(key, value))
149
150 def wait_for_internet(self, container, attempts_count=10,
151 attempt_interval=1, ping_domain=DOMAIN_PING):
152
153=== modified file 'snappy_ecosystem_tests/environment/managers.py'
154--- snappy_ecosystem_tests/environment/managers.py 2017-03-09 10:41:13 +0000
155+++ snappy_ecosystem_tests/environment/managers.py 2017-03-13 08:59:44 +0000
156@@ -44,6 +44,12 @@
157 containers = self.driver.launch(CONTAINERS)
158 for cont in containers:
159 self.driver.wait_for_internet(cont)
160+ self.driver.export_environment_variables(
161+ cont,
162+ PROFILES[profile][cont.name]["environment_variables"])
163+ self.driver.add_ppas(
164+ cont,
165+ PROFILES[profile][cont.name]["ppas"])
166 deps = DEPENDENCIES[cont.name] + DEPENDENCIES["shared"]
167 self.driver.install(cont, packages=deps)
168 self.driver.install(
169@@ -51,6 +57,3 @@
170 packages=[PROFILES[profile][cont.name]["package_name"]],
171 channel=PROFILES[profile][cont.name]["channel"])
172 self.driver.enable_ssh(cont)
173- self.driver.export_environment_variables(
174- cont,
175- PROFILES[profile][cont.name]["environment_variables"].keys())
176
177=== modified file 'snappy_ecosystem_tests/helpers/snapcraft/client.py'
178--- snappy_ecosystem_tests/helpers/snapcraft/client.py 2017-03-10 10:28:15 +0000
179+++ snappy_ecosystem_tests/helpers/snapcraft/client.py 2017-03-13 08:59:44 +0000
180@@ -24,7 +24,6 @@
181 import subprocess
182 import time
183
184-from snappy_ecosystem_tests.environment.constants import PROFILES, SNAPCRAFT
185 from snappy_ecosystem_tests.models.snap import Snap
186 from snappy_ecosystem_tests.utils.commands import build_command
187 from snappy_ecosystem_tests.utils.filters import filter_list
188@@ -88,10 +87,7 @@
189 command = build_snapcraft_command(command)
190 if debug:
191 command += ' -d'
192- return self.ssh.exec_command(
193- command,
194- environment=PROFILES[get_current_store()][SNAPCRAFT]
195- ["environment_variables"])
196+ return self.ssh.exec_command(command)
197
198 def assert_logged_in(self):
199 """Assert that an user is logged.
200@@ -105,9 +101,7 @@
201 """Return bool representing if the user is logged into snapcraft."""
202 try:
203 output = self.ssh.exec_command(
204- 'cat %s' % SNAPCRAFT_CONFIG_FILE_PATH,
205- environment=PROFILES[get_current_store()][SNAPCRAFT]
206- ["environment_variables"])
207+ 'cat %s' % SNAPCRAFT_CONFIG_FILE_PATH)
208 return output is not ''
209 except ValueError:
210 return False
211@@ -131,9 +125,7 @@
212 """
213 self.ssh.exec_command(
214 COMMANDS_LOGIN.format(email=email, password=password,
215- snapcraft=PATH_SNAPCRAFT),
216- environment=PROFILES[get_current_store()][SNAPCRAFT]
217- ["environment_variables"])
218+ snapcraft=PATH_SNAPCRAFT))
219 return self.is_logged_in()
220
221 def list_registered(self, debug=True, raw=False):

Subscribers

People subscribed via source and target branches