Merge lp:~simpoir/landscape-charm/juju-deploy-err into lp:~landscape/landscape-charm/trunk

Proposed by Simon Poirier
Status: Merged
Approved by: Simon Poirier
Approved revision: 405
Merged at revision: 405
Proposed branch: lp:~simpoir/landscape-charm/juju-deploy-err
Merge into: lp:~landscape/landscape-charm/trunk
Diff against target: 328 lines (+68/-43)
8 files modified
Makefile (+7/-11)
README.md (+2/-4)
dev/deploy-landscape-client (+3/-3)
dev/deployer (+15/-16)
dev/ubuntu-deps (+4/-4)
lib/tests/test_install.py (+1/-1)
tests/basic/test_service.py (+11/-0)
tests/helpers.py (+25/-4)
To merge this branch: bzr merge lp:~simpoir/landscape-charm/juju-deploy-err
Reviewer Review Type Date Requested Status
Maximiliano Bertacchini Approve
Review via email: mp+406174@code.launchpad.net

Commit message

Replace juju-deployer by plain "juju deploy" in integration tests to allow testing on bionic.

Description of the change

This branch gives some love to charm integration tests.

This should allow integration-tests to run on top of bionic (current release).
(focal won't run yet because there are still bits of python27 in there)
* get rid of juju-deployer, which is most definitely broken/dead
* mild PY3 compat fixes
* some unbroken tests

For testing, it assumes you have a juju model accessible.
So I encourage setting lxd config security.nesting=true if you're already
running this in a container (and you should) and doing a juju bootstrap.

FWIW xenial still deploys and passes tests, though it's not a supported
series for recent landscape release.

To post a comment you must log in.
Revision history for this message
Maximiliano Bertacchini (maxiberta) wrote :

Looks good to me! Locally tested test, test-depends, integration-test, bundles-local-charm, deploy.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'Makefile'
2--- Makefile 2019-05-24 12:41:48 +0000
3+++ Makefile 2021-07-23 23:12:40 +0000
4@@ -1,9 +1,9 @@
5 PYTHON := /usr/bin/env python
6
7 test:
8- trial lib
9+ PYTHONPATH=. trial lib
10 # For now only the install hook runs against python3
11- trial3 lib/tests/test_apt.py lib/tests/test_install.py
12+ PYTHONPATH=. trial3 lib/tests/test_apt.py lib/tests/test_install.py
13
14 ci-test:
15 ./dev/ubuntu-deps
16@@ -15,8 +15,7 @@
17 apache2 postgresql juju-gui haproxy rabbitmq-server nfs
18
19 test-depends: bundles
20- pip install --user bundletester juju-deployer
21- pip3 install --user amulet
22+ PIP_IGNORE_INSTALLED=0 pip3 install --user amulet
23 cd tests && python3 test_helpers.py
24
25 bundles-checkout:
26@@ -31,9 +30,6 @@
27 bundles: bundles-checkout
28 bundles/render-bundles
29
30-bundles-local-branch: bundles-checkout
31- bundles/render-bundles --landscape-branch $(CURDIR)
32-
33 bundles-local-charm: bundles-checkout
34 bundles/render-bundles --landscape-charm $(CURDIR)
35
36@@ -45,19 +41,19 @@
37 fi
38
39 integration-test: test-depends
40- python2 ~/.local/bin/bundletester -v -l DEBUG --skip-implicit -t .
41+ ./tests/01-basic
42
43 # Run integration tests using the LDS package from the lds-trunk PPA
44 integration-test-trunk: secrets
45 LS_CHARM_SOURCE=lds-trunk-ppa $(MAKE) $(subst -trunk,,$@)
46
47-deploy-dense-maas: bundles-local-branch config
48+deploy-dense-maas: bundles-local-charm config
49 ./dev/deployer dense-maas
50
51-deploy-dense-maas-dev: bundles-local-branch config repo-file-trunk
52+deploy-dense-maas-dev: bundles-local-charm config repo-file-trunk
53 ./dev/deployer dense-maas --flags juju-debug
54
55-deploy: bundles-local-branch
56+deploy: bundles-local-charm
57 ./dev/deployer scalable
58
59 repo-file-trunk: secrets config
60
61=== modified file 'README.md'
62--- README.md 2020-02-27 15:39:24 +0000
63+++ README.md 2021-07-23 23:12:40 +0000
64@@ -62,13 +62,11 @@
65 Integration Testing
66 ===================
67
68-This charm makes use of juju-deployer and the charm-tools package to enable end-to-end integration testing. This is how you proceed with running them:
69+This charm had juju-deployer and charm-tools tests. Those being EOL, some integration-test still exist, and can be executed using a "juju deploy" directly. This is how you proceed with running them:
70
71 $ juju bootstrap localhost
72 $ make integration-test
73
74 Or if you want to use the packages from the lds-trunk PPA:
75
76- $ JUJU_MODEL=<model> make integration-test-trunk
77-
78-The JUJU_MODEL environment variable can be omitted if you want to use the current model.
79+ $ make integration-test-trunk
80
81=== modified file 'dev/deploy-landscape-client'
82--- dev/deploy-landscape-client 2015-06-19 09:11:27 +0000
83+++ dev/deploy-landscape-client 2021-07-23 23:12:40 +0000
84@@ -1,12 +1,12 @@
85 #!/usr/bin/python3
86 """
87 This script looks at the current Juju environment and generates a
88-juju-deployer config for landscape-client that is configured to talk to
89+juju bundle for landscape-client that is configured to talk to
90 the deployed landscape-server service. The URLs and SSL certificate are
91 taken from the deployed landscape-server units.
92
93 By default, landscape-client will be deployed, but you can choose to
94-only generate the juju-deployer config and deploy manually:
95+only generate the juju bundle and deploy manually:
96
97 deploy-landscape-client --no-deploy > landscape-client.yaml
98
99@@ -119,7 +119,7 @@
100
101 if args.deploy:
102 print("Deploying landscape-client.", file=stderr)
103- subprocess.check_call(["juju-deployer", "-c", config_path])
104+ subprocess.check_call(["juju deploy", config_path])
105 print("Cleaning up {}".format(tempdir), file=stderr)
106 shutil.rmtree(tempdir)
107
108
109=== modified file 'dev/deployer'
110--- dev/deployer 2016-09-14 16:17:08 +0000
111+++ dev/deployer 2021-07-23 23:12:40 +0000
112@@ -13,10 +13,10 @@
113
114
115 class Deployer(object):
116- """Simple wrapper around juju-deployer.
117+ """Simple wrapper around juju deploy (used to be juju-deployer).
118
119 It creates a temporary directory that will act as local charm repository
120- for juju-deployer so it can deploy the current charm branch as local
121+ for juju deploy so it can deploy the current charm branch as local
122 charm.
123
124 It also overrides the configuration in the stock bundles, accounting for
125@@ -53,7 +53,7 @@
126 @param source_bundle_file: The bundle file to override.
127 """
128 # Will create a config file with option values overridden for use in
129- # the juju deployer commandline to add a custom license-file to the
130+ # the juju deploy commandline to add a custom license-file to the
131 # deployment.
132 local_yaml_file = os.path.join(tmpdir, "99-local.yaml")
133 with open(source_bundle_file, "r") as bundle_content:
134@@ -80,8 +80,8 @@
135
136 def deploy(self, timeout=900):
137 """
138- Use juju-deployer to deploy the target deployment type on current
139- `juju env`.
140+ Use juju deploy to deploy the target deployment type on current
141+ juju model.
142
143 @param timeout: timeout in seconds (int or string is OK)
144 """
145@@ -100,22 +100,21 @@
146 self._stage_deployer_dir(deployer_dir, series)
147 updated_bundle_file = self._create_local_yaml(
148 deployer_dir, original_bundle)
149- # The -w 30 is there to allow things to settle a bit before
150- # issuing a 'juju run' to wait for all the relations to settle.
151- args = ["juju-deployer", "-vdWL", "-w 30"]
152- args.extend(["-c", updated_bundle_file])
153- if timeout is not None:
154- args.extend(["--timeout", str(timeout)])
155+ args = ["juju", "deploy"]
156+ args.append(updated_bundle_file)
157 logging.info("(cwd=%s) RUN: %s" % (deployer_dir, args))
158 subprocess.check_call(args, cwd=deployer_dir)
159 logging.info("Waiting for relations to settle")
160- subprocess.check_output(["juju", "run", "--all", "/bin/true"])
161+ subprocess.check_output([
162+ "juju", "run", "--all", "--timeout={}s".format(timeout),
163+ "/bin/true"])
164 deploy_time = int(round(time.time() - start))
165 logging.info(
166 "Deployment usable after {} seconds".format(deploy_time))
167- haproxy_ip = subprocess.check_output(
168- ["juju-deployer", "-f", "haproxy"])
169- haproxy_ip = haproxy_ip.decode("utf-8").strip()
170+ juju_status = yaml.load(subprocess.check_output([
171+ "juju", "status", "--format=yaml"]))
172+ haproxies = juju_status["applications"]["haproxy"]["units"]
173+ haproxy_ip = list(haproxies.values())[0]["public-address"]
174 logging.info("Landscape URL: https://{}/".format(haproxy_ip))
175 finally:
176 if deployer_dir is not None:
177@@ -138,7 +137,7 @@
178
179
180 def get_parser():
181- parser = ArgumentParser(description="Simple wrapper around juju-deployer")
182+ parser = ArgumentParser(description="Simple wrapper around juju deploy")
183 parser.add_argument(
184 "target", choices=("scalable", "dense", "dense-maas"),
185 help="target deployment type")
186
187=== modified file 'dev/ubuntu-deps'
188--- dev/ubuntu-deps 2019-01-17 14:23:49 +0000
189+++ dev/ubuntu-deps 2021-07-23 23:12:40 +0000
190@@ -5,17 +5,17 @@
191 CODENAME=$(lsb_release -cs)
192
193 # Install add-apt-repository (packaging differs across releases).
194-sudo apt-get -y install python-software-properties
195+sudo apt-get -y install software-properties-common
196
197 # Add the juju stable ppa, install charm-tools (juju-test plugin) and other deps
198 sudo add-apt-repository -y ppa:juju/stable
199 sudo apt-get update
200-sudo apt-get -y install juju-2.0 charm-tools python3 \
201+sudo apt-get -y install juju-2.0 python3 \
202 python3-yaml curl python3-zope.testrunner \
203- python3-amulet python3-fixtures python3-jinja2 python3-fixtures \
204+ python3-fixtures python3-jinja2 python3-fixtures \
205 python3-psutil python3-twisted python3-flake8 \
206 python3-path python3-libcharmstore python3-zope.testrunner python3-six \
207- python-twisted-core
208+ python-twisted-core python3-pip
209
210 sudo apt-get -y install python-fixtures python-six python-yaml dpkg-dev \
211 pbuilder dh-make python-jinja2 python-psutil python-six
212
213=== modified file 'lib/tests/test_install.py'
214--- lib/tests/test_install.py 2019-05-28 20:36:35 +0000
215+++ lib/tests/test_install.py 2021-07-23 23:12:40 +0000
216@@ -53,7 +53,7 @@
217 os.chmod(hook, 0o755)
218 self.hookenv.config()["source"] = "ppa:landscape/14.10"
219 self.assertEqual(1, self.hook())
220- self.assertEqual(
221+ self.assertIn(
222 "Command '%s' returned non-zero exit status 127" % hook,
223 self.hookenv.messages[-1][0])
224
225
226=== modified file 'tests/basic/test_service.py'
227--- tests/basic/test_service.py 2016-09-15 07:38:13 +0000
228+++ tests/basic/test_service.py 2021-07-23 23:12:40 +0000
229@@ -180,6 +180,12 @@
230 def test_update_security_db_cron(self):
231 """Verify that the update_security_db cron job runs without errors."""
232 script = "/opt/canonical/landscape/scripts/update_security_db.sh"
233+ # remove some extra sleep which would make this test timeout
234+ check_output([
235+ "juju", "ssh", self.layer.cron_unit, "sudo", "sed", "-e",
236+ "/^sleep/d", "-i", script
237+ ])
238+
239 output, status = self.environment.run_script_on_cron_unit(
240 script, self.layer)
241 self.assertCronStatus(status, output, "update_security_db_cron")
242@@ -222,6 +228,11 @@
243 "sudo cp {config_dir}/hash-id-databases-sample.conf"
244 " {config_dir}/hash-id-databases.conf".format(
245 config_dir=config_dir))
246+ self.environment.run_command_on_landscape(
247+ "sudo sed -i 's,^url.*,url={url},' "
248+ "{config_dir}/hash-id-databases.conf".format(
249+ config_dir=config_dir,
250+ url="http://ppa.launchpad.net/simpoir/dummy-test-only/ubuntu"))
251
252 script = "/opt/canonical/landscape/scripts/hash_id_databases.sh"
253 output, status = self.environment.run_script_on_cron_unit(
254
255=== modified file 'tests/helpers.py'
256--- tests/helpers.py 2019-01-17 14:23:49 +0000
257+++ tests/helpers.py 2021-07-23 23:12:40 +0000
258@@ -6,6 +6,7 @@
259 import sys
260 import yaml
261 import os
262+import path
263 import subprocess
264 import tempfile
265 import json
266@@ -20,6 +21,8 @@
267 from fixtures import Fixture, TestWithFixtures
268
269 from amulet import Deployment
270+from amulet.helpers import INFRA_FAIL, raise_status
271+from amulet.sentry import SentryError, Talisman
272
273 from zope.testrunner import run
274
275@@ -43,8 +46,10 @@
276 },
277 "haproxy": {},
278 "landscape": {
279- "branch": ".",
280- "memory": "2G"},
281+ "charm": os.getcwd(),
282+ # If you get OOM killed by LXD host (e.g. test_update_security_db_cron)
283+ # the memory quota isn't high enough.
284+ "memory": "4G"},
285 }
286
287
288@@ -77,6 +82,22 @@
289 self._dense_maas = os.environ.get("DENSE_MAAS", "0") == "1"
290 self._tempfile = tempfile
291
292+ def _amulet_setup(self):
293+ """Like Deployement.setup(), without using defunct juju-deployer."""
294+ timeout = 900
295+ with path.tempdir(prefix='amulet-juju-deployer-') as tmpdir:
296+ schema_file = tmpdir / 'deployer-schema.yaml'
297+ schema_file.write_text(yaml.dump(self._get_bundle()))
298+ with self._deployment._deploy_w_timeout(timeout):
299+ self._subprocess.check_call(
300+ ["juju", "deploy", str(schema_file)])
301+ try:
302+ self._deployment.sentry = Talisman(
303+ self._deployment.services, timeout=900,
304+ juju_env=self._deployment.juju_env)
305+ except SentryError as e:
306+ raise_status(INFRA_FAIL, msg=e)
307+
308 def setUp(self):
309 super(EnvironmentFixture, self).setUp()
310 if not self._deployment.deployed:
311@@ -84,7 +105,7 @@
312 self._configure_for_dense_maas()
313 self._deployment.load(self._get_bundle())
314 with self._enable_sample_hashids():
315- self._deployment.setup(timeout=self._timeout)
316+ self._amulet_setup()
317 self._deployment.sentry.wait(self._timeout)
318
319 def get_haproxy_public_address(self, unit=None):
320@@ -178,7 +199,7 @@
321 post_data = ("login.email=%s&login.password=%s&login=Login&"
322 "form-security-token=%s" % (email, password, token))
323 return self.check_url(
324- "/redirect", "<h2>Organisation</h2>", post_data=post_data,
325+ "/redirect", "<h2>Standalone Account</h2>", post_data=post_data,
326 cookie_jar=cookie_file)
327
328 def check_service(self, name, state="up", attempts=2, interval=5):

Subscribers

People subscribed via source and target branches