Merge lp:~free.ekanayaka/landscape-charm/dont-stop-cron into lp:~landscape/landscape-charm/trunk

Proposed by Free Ekanayaka
Status: Merged
Approved by: Free Ekanayaka
Approved revision: 293
Merged at revision: 293
Proposed branch: lp:~free.ekanayaka/landscape-charm/dont-stop-cron
Merge into: lp:~landscape/landscape-charm/trunk
Diff against target: 198 lines (+42/-51)
8 files modified
lib/pause.py (+0/-1)
lib/resume.py (+0/-1)
lib/tests/test_pause.py (+1/-3)
lib/tests/test_resume.py (+1/-3)
tests/basic/test_actions.py (+2/-5)
tests/basic/test_service.py (+2/-20)
tests/helpers.py (+17/-17)
tests/layers.py (+19/-1)
To merge this branch: bzr merge lp:~free.ekanayaka/landscape-charm/dont-stop-cron
Reviewer Review Type Date Requested Status
Björn Tillenius (community) Approve
Geoff Teale (community) Approve
🤖 Landscape Builder test results Approve
Review via email: mp+260553@code.launchpad.net

Commit message

Don't stop/start the cron deamon when pausing/resuming a unit. Also, wait for any running cron job to finish before running cron tests, since otherwise we could get spurious failures due to busy db locks.

Starting from r8826 the 'lsctl stop' command will also set the maintenance flag, so cron scripts won't be triggered when the unit is paused.

Description of the change

Don't stop/start the cron deamon when pausing/resuming a unit. Also, wait for any running cron job to finish before running cron tests, since otherwise we could get spurious failures due to busy db locks.

Starting from r8826 the 'lsctl stop' command will also set the maintenance flag, so cron scripts won't be triggered when the unit is paused.

To post a comment you must log in.
Revision history for this message
Björn Tillenius (bjornt) wrote :

The bug says that we shouldn't stop the cron services and instead prevent them from running. This branch doesn't stop the cron service. What about preventing them from running?

review: Needs Information
Revision history for this message
Free Ekanayaka (free.ekanayaka) wrote :

Sorry, I forgot to mention that "lsctl stop" will now also prevent Landscape cron scripts from running, by creating the maintenance.txt flag file. See:

https://bugs.launchpad.net/landscape-charm/+bug/1457800

Revision history for this message
🤖 Landscape Builder (landscape-builder) wrote :

Command: make ci-test
Result: Success
Revno: 293
Branch: lp:~free.ekanayaka/landscape-charm/dont-stop-cron
Jenkins: https://ci.lscape.net/job/latch-test/1118/

review: Approve (test results)
Revision history for this message
Geoff Teale (tealeg) wrote :

+1

review: Approve
Revision history for this message
Björn Tillenius (bjornt) wrote :

Ok, thanks. +1 then, but please update the MP description, mentioning that the landscape-server was fixed to add the maintenance flag. It'd be good to mention the revision, since we now won't work with older version.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/pause.py'
2--- lib/pause.py 2015-05-07 10:26:45 +0000
3+++ lib/pause.py 2015-05-29 09:28:28 +0000
4@@ -15,4 +15,3 @@
5
6 def _run(self):
7 self._subprocess.check_call((LSCTL, "stop"))
8- self._subprocess.check_call(("service", "cron", "stop"))
9
10=== modified file 'lib/resume.py'
11--- lib/resume.py 2015-05-20 11:21:32 +0000
12+++ lib/resume.py 2015-05-29 09:28:28 +0000
13@@ -15,4 +15,3 @@
14
15 def _run(self):
16 self._subprocess.check_call((LSCTL, "start"))
17- self._subprocess.check_call(("service", "cron", "start"))
18
19=== modified file 'lib/tests/test_pause.py'
20--- lib/tests/test_pause.py 2015-05-26 11:33:50 +0000
21+++ lib/tests/test_pause.py 2015-05-29 09:28:28 +0000
22@@ -20,6 +20,4 @@
23 """
24 self.action()
25 self.assertEqual(
26- [(("/usr/bin/lsctl", "stop"), {}),
27- (("service", "cron", "stop"), {})],
28- self.subprocess.calls)
29+ [(("/usr/bin/lsctl", "stop"), {})], self.subprocess.calls)
30
31=== modified file 'lib/tests/test_resume.py'
32--- lib/tests/test_resume.py 2015-05-26 11:33:50 +0000
33+++ lib/tests/test_resume.py 2015-05-29 09:28:28 +0000
34@@ -22,6 +22,4 @@
35 """
36 self.action()
37 self.assertEqual(
38- [(("/usr/bin/lsctl", "start"), {}),
39- (("service", "cron", "start"), {})],
40- self.subprocess.calls)
41+ [(("/usr/bin/lsctl", "start"), {})], self.subprocess.calls)
42
43=== modified file 'tests/basic/test_actions.py'
44--- tests/basic/test_actions.py 2015-05-22 09:15:39 +0000
45+++ tests/basic/test_actions.py 2015-05-29 09:28:28 +0000
46@@ -18,16 +18,13 @@
47 result = self.environment.pause_landscape()
48 self.assertEqual("completed", result["status"])
49 service_status = self.environment.get_landscape_services_status()
50- # All Landcape services and cron have been stopped
51+ # All Landcape services have been stopped
52 self.assertEqual([], service_status["running"])
53 self.assertTrue(len(service_status["stopped"]) > 0)
54- self.assertFalse(
55- self.environment.is_cron_running("landscape-server/0"))
56
57 result = self.environment.resume_landscape()
58 self.assertEqual("completed", result["status"])
59 service_status = self.environment.get_landscape_services_status()
60- # All Landcape services and cron have been started
61+ # All Landcape services have been started
62 self.assertEqual([], service_status["stopped"])
63 self.assertTrue(len(service_status["running"]) > 0)
64- self.assertTrue(self.environment.is_cron_running("landscape-server/0"))
65
66=== modified file 'tests/basic/test_service.py'
67--- tests/basic/test_service.py 2015-05-22 09:15:39 +0000
68+++ tests/basic/test_service.py 2015-05-29 09:28:28 +0000
69@@ -11,7 +11,7 @@
70 from subprocess import check_output, CalledProcessError, PIPE
71
72 from helpers import IntegrationTest
73-from layers import OneLandscapeUnitLayer
74+from layers import OneLandscapeUnitLayer, OneLandscapeUnitNoCronLayer
75
76
77 class ServiceTest(IntegrationTest):
78@@ -148,18 +148,10 @@
79 the cron daemon will be stopped, so Landscape cron jobs in particular
80 won't be run.
81 """
82- layer = OneLandscapeUnitLayer
83+ layer = OneLandscapeUnitNoCronLayer
84
85 cron_unit = "landscape-server/0"
86
87- @classmethod
88- def setUpClass(cls):
89- cls._stop_cron(cls.cron_unit)
90-
91- @classmethod
92- def tearDownClass(cls):
93- cls._start_cron(cls.cron_unit)
94-
95 def _sanitize_ssh_output(self, output,
96 remove_text=["sudo: unable to resolve",
97 "Warning: Permanently added"]):
98@@ -265,13 +257,3 @@
99 frontend = self.environment.get_haproxy_public_address()
100 self.assertEqual(
101 "https://%s/" % frontend, config["global"]["root-url"])
102-
103- @staticmethod
104- def _stop_cron(unit):
105- cmd = ["juju", "ssh", unit, "sudo", "service", "cron", "stop", "2>&1"]
106- check_output(cmd, stderr=PIPE)
107-
108- @staticmethod
109- def _start_cron(unit):
110- cmd = ["juju", "ssh", unit, "sudo", "service", "cron", "start", "2>&1"]
111- check_output(cmd, stderr=PIPE)
112
113=== modified file 'tests/helpers.py'
114--- tests/helpers.py 2015-05-21 11:02:48 +0000
115+++ tests/helpers.py 2015-05-29 09:28:28 +0000
116@@ -168,13 +168,25 @@
117 action_id = self._do_action("resume", "landscape-server/" + str(unit))
118 return self._fetch_action(action_id)
119
120- def stop_landscape_service(self, service, unit=0):
121- """Stop the given Landscape service on the given unit.
122-
123- The service being stopped will be automatically restarted upon cleanUp.
124+ def wait_landscape_cron_jobs(self, unit=0):
125+ """Wait for running cron jobs to finish on the given Landscape unit."""
126+ unit = self._deployment.sentry.unit["landscape-server/%d" % unit]
127+ output, code = unit.run(
128+ "sudo /opt/canonical/landscape/wait-batch-scripts")
129+ if code != 0:
130+ raise RuntimeError(output)
131+
132+ def stop_landscape_service(self, service, unit=0, restore=True):
133+ """Stop the given service on the given Landscape unit.
134+
135+ @param service: The service to stop.
136+ @param unit: The Landscape unit to act on.
137+ @param restore: Whether the service should be automatically restarted
138+ upon cleanUp.
139 """
140 self._control_landscape_service("stop", service, unit)
141- self._stopped_landscape_services.append((service, unit))
142+ if restore:
143+ self._stopped_landscape_services.append((service, unit))
144
145 def start_landscape_service(self, service, unit=0):
146 """Start the given Landscape service on the given unit."""
147@@ -210,18 +222,6 @@
148 service_status["stopped"].append(service_name)
149 return service_status
150
151- def is_cron_running(self, unit):
152- """Returns whether cron is running on a unit."""
153- unit_sentry = self._deployment.sentry.unit[unit]
154- output, code = unit_sentry.run("service cron status")
155- assert code == 0
156- if "stop/waiting" in output:
157- return False
158- elif "start/running" in output:
159- return True
160- else:
161- raise AssertionError("Malformed status output: " + output)
162-
163 def configure_ssl(self, cert, key):
164 """Start the given Landscape service on the given unit."""
165 self._deployment.configure(
166
167=== modified file 'tests/layers.py'
168--- tests/layers.py 2015-05-13 17:57:51 +0000
169+++ tests/layers.py 2015-05-29 09:28:28 +0000
170@@ -15,10 +15,28 @@
171 cls.environment.setUp()
172
173 @classmethod
174- def tearDown(cls):
175+ def testTearDown(cls):
176 cls.environment.cleanUp()
177
178
179+class OneLandscapeUnitNoCronLayer(OneLandscapeUnitLayer):
180+ """Layer for all tests needing to run with the cron daemon stopped.
181+
182+ The deployment has the same structure as OneLandscapeUnitLayer, the cron
183+ daemon will be stopped. Also, the layer setup waits for any currently
184+ running Landscape cron job to finish.
185+ """
186+
187+ @classmethod
188+ def setUp(cls):
189+ cls.environment.stop_landscape_service("cron", restore=False)
190+ cls.environment.wait_landscape_cron_jobs()
191+
192+ @classmethod
193+ def tearDown(cls):
194+ cls.environment.start_landscape_service("cron")
195+
196+
197 class OneLandscapeUnitCustomSSLCertificateLayer(OneLandscapeUnitLayer):
198 """Layer for all tests needing a deployment with a custom SSL certificate.
199

Subscribers

People subscribed via source and target branches