Merge lp:~rvb/maas/safeguard-migrations into lp:~maas-committers/maas/trunk
- safeguard-migrations
- Merge into trunk
Status: | Rejected |
---|---|
Rejected by: | MAAS Lander |
Proposed branch: | lp:~rvb/maas/safeguard-migrations |
Merge into: | lp:~maas-committers/maas/trunk |
Diff against target: |
185 lines (+95/-2) 5 files modified
src/maasserver/tests/models.py (+2/-1) src/maasserver/tests/test_migrations.py (+29/-0) src/maastesting/tests/test_utils.py (+19/-1) src/maastesting/utils.py (+15/-0) src/metadataserver/tests/test_migrations.py (+30/-0) |
To merge this branch: | bzr merge lp:~rvb/maas/safeguard-migrations |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Gavin Panella (community) | Approve | ||
Review via email: mp+253934@code.launchpad.net |
Commit message
Add tests to make sure the migrations and the models are in sync.
Description of the change
This is to avoid having broken migrations landed (see https:/
There is a little bit of repetition here (it was tempting to add scenarios to avoid the duplication) but I thought it was better to have two tests, one for each application.
Raphaël Badin (rvb) wrote : | # |
Thanks for the review!
MAAS Lander (maas-lander) wrote : | # |
The attempt to merge lp:~rvb/maas/safeguard-migrations into lp:maas failed. Below is the output from the failed tests.
Ign http://
Get:1 http://
Get:2 http://
Ign http://
Ign http://
Hit http://
Get:3 http://
Hit http://
Get:4 http://
Get:5 http://
Get:6 http://
Get:7 http://
Hit http://
Hit http://
Hit http://
Hit http://
Hit http://
Hit http://
Get:8 http://
Get:9 http://
Hit http://
Hit http://
Get:10 http://
Get:11 http://
Get:12 http://
Hit http://
Hit http://
Ign http://
Ign http://
Fetched 1,601 kB in 3s (501 kB/s)
Reading package lists...
sudo DEBIAN_
--
Gavin Panella (allenap) : | # |
MAAS Lander (maas-lander) wrote : | # |
The attempt to merge lp:~rvb/maas/safeguard-migrations into lp:maas failed. Below is the output from the failed tests.
Ign http://
Get:1 http://
Get:2 http://
Ign http://
Ign http://
Hit http://
Get:3 http://
Hit http://
Get:4 http://
Get:5 http://
Hit http://
Get:6 http://
Get:7 http://
Hit http://
Hit http://
Hit http://
Hit http://
Hit http://
Get:8 http://
Get:9 http://
Hit http://
Hit http://
Get:10 http://
Get:11 http://
Get:12 http://
Hit http://
Hit http://
Ign http://
Ign http://
Fetched 1,606 kB in 3s (495 kB/s)
Reading package lists...
sudo DEBIAN_
--
MAAS Lander (maas-lander) wrote : | # |
The attempt to merge lp:~rvb/maas/safeguard-migrations into lp:maas failed. Below is the output from the failed tests.
Ign http://
Hit http://
Hit http://
Ign http://
Ign http://
Hit http://
Hit http://
Hit http://
Hit http://
Hit http://
Hit http://
Hit http://
Hit http://
Hit http://
Hit http://
Hit http://
Hit http://
Hit http://
Hit http://
Hit http://
Hit http://
Hit http://
Hit http://
Hit http://
Hit http://
Hit http://
Hit http://
Ign http://
Ign http://
Reading package lists...
sudo DEBIAN_
--
MAAS Lander (maas-lander) wrote : | # |
The attempt to merge lp:~rvb/maas/safeguard-migrations into lp:maas failed. Below is the output from the failed tests.
Ign http://
Get:1 http://
Ign http://
Get:2 http://
Ign http://
Hit http://
Get:3 http://
Hit http://
Get:4 http://
Get:5 http://
Get:6 http://
Hit http://
Get:7 http://
Hit http://
Hit http://
Hit http://
Hit http://
Get:8 http://
Hit http://
Get:9 http://
Hit http://
Hit http://
Get:10 http://
Get:11 http://
Get:12 http://
Hit http://
Hit http://
Ign http://
Ign http://
Fetched 1,608 kB in 3s (484 kB/s)
Reading package lists...
sudo DEBIAN_
--
MAAS Lander (maas-lander) wrote : | # |
The attempt to merge lp:~rvb/maas/safeguard-migrations into lp:maas failed. Below is the output from the failed tests.
Ign http://
Get:1 http://
Get:2 http://
Ign http://
Ign http://
Hit http://
Get:3 http://
Hit http://
Get:4 http://
Get:5 http://
Get:6 http://
Hit http://
Get:7 http://
Get:8 http://
Hit http://
Hit http://
Hit http://
Hit http://
Hit http://
Hit http://
Hit http://
Get:9 http://
Get:10 http://
Get:11 http://
Get:12 http://
Hit http://
Hit http://
Ign http://
Ign http://
Fetched 1,608 kB in 3s (522 kB/s)
Reading package lists...
sudo DEBIAN_
--
Raphaël Badin (rvb) wrote : | # |
For the curious: I don't want to spend time investigating what the failure is right now since we only have one week before the release and this is just a nice to have. I'll get it fixed and landed after the release.
MAAS Lander (maas-lander) wrote : | # |
Transitioned to Git.
lp:maas has now moved from Bzr to Git.
Please propose your branches with Launchpad using Git.
git clone https:/
Unmerged revisions
- 3701. By Raphaël Badin
-
Fix lint.
- 3700. By Raphaël Badin
-
Merge trunk.
- 3699. By Raphaël Badin
-
Fix lint.
- 3698. By Raphaël Badin
-
Fix test model.
- 3697. By Raphaël Badin
-
Review fixes.
- 3696. By Raphaël Badin
-
Add test to make sure the migrations and the models are in sync.
Preview Diff
1 | === modified file 'src/maasserver/tests/models.py' | |||
2 | --- src/maasserver/tests/models.py 2015-03-25 15:33:23 +0000 | |||
3 | +++ src/maasserver/tests/models.py 2015-03-27 10:06:20 +0000 | |||
4 | @@ -66,7 +66,8 @@ | |||
5 | 66 | class TimestampedModelTestModel(TimestampedModel): | 66 | class TimestampedModelTestModel(TimestampedModel): |
6 | 67 | # This model inherits from TimestampedModel so it will have a 'created' | 67 | # This model inherits from TimestampedModel so it will have a 'created' |
7 | 68 | # field and an 'updated' field. | 68 | # field and an 'updated' field. |
9 | 69 | pass | 69 | class Meta: |
10 | 70 | db_table = "testtimestampmodel" | ||
11 | 70 | 71 | ||
12 | 71 | 72 | ||
13 | 72 | class FieldChangeTestModel(Model): | 73 | class FieldChangeTestModel(Model): |
14 | 73 | 74 | ||
15 | === modified file 'src/maasserver/tests/test_migrations.py' | |||
16 | --- src/maasserver/tests/test_migrations.py 2014-08-20 00:42:35 +0000 | |||
17 | +++ src/maasserver/tests/test_migrations.py 2015-03-27 10:06:20 +0000 | |||
18 | @@ -18,8 +18,14 @@ | |||
19 | 18 | __metaclass__ = type | 18 | __metaclass__ = type |
20 | 19 | __all__ = [] | 19 | __all__ = [] |
21 | 20 | 20 | ||
22 | 21 | from django.core.management import call_command | ||
23 | 21 | from maasserver.testing.db_migrations import detect_sequence_clashes | 22 | from maasserver.testing.db_migrations import detect_sequence_clashes |
24 | 22 | from maastesting.testcase import MAASTestCase | 23 | from maastesting.testcase import MAASTestCase |
25 | 24 | from maastesting.utils import capture_std_out_err | ||
26 | 25 | from testtools.content import ( | ||
27 | 26 | Content, | ||
28 | 27 | UTF8_TEXT, | ||
29 | 28 | ) | ||
30 | 23 | 29 | ||
31 | 24 | 30 | ||
32 | 25 | EXISTING_DUPES = [ | 31 | EXISTING_DUPES = [ |
33 | @@ -42,3 +48,26 @@ | |||
34 | 42 | self.assertEqual( | 48 | self.assertEqual( |
35 | 43 | EXISTING_DUPES, | 49 | EXISTING_DUPES, |
36 | 44 | detect_sequence_clashes('maasserver')) | 50 | detect_sequence_clashes('maasserver')) |
37 | 51 | |||
38 | 52 | def test_all_model_changes_in_migrations(self): | ||
39 | 53 | # Make sure all the model changes have been transformed into | ||
40 | 54 | # migrations. | ||
41 | 55 | try: | ||
42 | 56 | with capture_std_out_err() as (stdoutIO, stderrIO): | ||
43 | 57 | call_command( | ||
44 | 58 | "schemamigration", "maasserver", | ||
45 | 59 | "generated_migration", auto=True, stdout=True) | ||
46 | 60 | except SystemExit, e: | ||
47 | 61 | if e.code == 1: | ||
48 | 62 | # No migration can be generated because the models haven't | ||
49 | 63 | # changed: exit silently. | ||
50 | 64 | return | ||
51 | 65 | raise | ||
52 | 66 | else: | ||
53 | 67 | self.addDetail( | ||
54 | 68 | "schemamigration stderr", | ||
55 | 69 | Content(UTF8_TEXT, lambda: stderrIO.getvalue())) | ||
56 | 70 | self.addDetail( | ||
57 | 71 | "schemamigration stdout", | ||
58 | 72 | Content(UTF8_TEXT, lambda: stdoutIO.getvalue())) | ||
59 | 73 | self.fail("Migrations are not in sync with the models!") | ||
60 | 45 | 74 | ||
61 | === modified file 'src/maastesting/tests/test_utils.py' | |||
62 | --- src/maastesting/tests/test_utils.py 2013-10-07 09:12:40 +0000 | |||
63 | +++ src/maastesting/tests/test_utils.py 2015-03-27 10:06:20 +0000 | |||
64 | @@ -14,8 +14,14 @@ | |||
65 | 14 | __metaclass__ = type | 14 | __metaclass__ = type |
66 | 15 | __all__ = [] | 15 | __all__ = [] |
67 | 16 | 16 | ||
68 | 17 | import sys | ||
69 | 18 | |||
70 | 19 | from maastesting.factory import factory | ||
71 | 17 | from maastesting.testcase import MAASTestCase | 20 | from maastesting.testcase import MAASTestCase |
73 | 18 | from maastesting.utils import extract_word_list | 21 | from maastesting.utils import ( |
74 | 22 | capture_std_out_err, | ||
75 | 23 | extract_word_list, | ||
76 | 24 | ) | ||
77 | 19 | 25 | ||
78 | 20 | 26 | ||
79 | 21 | class TestFunctions(MAASTestCase): | 27 | class TestFunctions(MAASTestCase): |
80 | @@ -34,3 +40,15 @@ | |||
81 | 34 | for string in expected | 40 | for string in expected |
82 | 35 | } | 41 | } |
83 | 36 | self.assertEqual(expected, observed) | 42 | self.assertEqual(expected, observed) |
84 | 43 | |||
85 | 44 | |||
86 | 45 | class TestCaptureStdOutErr(MAASTestCase): | ||
87 | 46 | |||
88 | 47 | def test_captures_std_out_err(self): | ||
89 | 48 | stdout = factory.make_name('stdout') | ||
90 | 49 | stderr = factory.make_name('stderr') | ||
91 | 50 | with capture_std_out_err() as (stdoutIO, stderrIO): | ||
92 | 51 | sys.stdout.write(stdout) | ||
93 | 52 | sys.stderr.write(stderr) | ||
94 | 53 | self.assertEqual(stdout, stdoutIO.getvalue()) | ||
95 | 54 | self.assertEqual(stderr, stderrIO.getvalue()) | ||
96 | 37 | 55 | ||
97 | === modified file 'src/maastesting/utils.py' | |||
98 | --- src/maastesting/utils.py 2015-03-25 15:33:23 +0000 | |||
99 | +++ src/maastesting/utils.py 2015-03-27 10:06:20 +0000 | |||
100 | @@ -15,6 +15,7 @@ | |||
101 | 15 | __all__ = [ | 15 | __all__ = [ |
102 | 16 | "age_file", | 16 | "age_file", |
103 | 17 | "content_from_file", | 17 | "content_from_file", |
104 | 18 | "capture_std_out_err", | ||
105 | 18 | "extract_word_list", | 19 | "extract_word_list", |
106 | 19 | "get_write_time", | 20 | "get_write_time", |
107 | 20 | "FakeRandInt", | 21 | "FakeRandInt", |
108 | @@ -24,6 +25,8 @@ | |||
109 | 24 | ] | 25 | ] |
110 | 25 | 26 | ||
111 | 26 | import codecs | 27 | import codecs |
112 | 28 | from contextlib import contextmanager | ||
113 | 29 | from cStringIO import StringIO | ||
114 | 27 | import os | 30 | import os |
115 | 28 | import re | 31 | import re |
116 | 29 | import signal | 32 | import signal |
117 | @@ -33,6 +36,7 @@ | |||
118 | 33 | ) | 36 | ) |
119 | 34 | from traceback import print_exc | 37 | from traceback import print_exc |
120 | 35 | 38 | ||
121 | 39 | from mock import patch | ||
122 | 36 | import subunit | 40 | import subunit |
123 | 37 | from testtools.content import Content | 41 | from testtools.content import Content |
124 | 38 | from testtools.content_type import UTF8_TEXT | 42 | from testtools.content_type import UTF8_TEXT |
125 | @@ -153,3 +157,14 @@ | |||
126 | 153 | if self.maximum is not None: | 157 | if self.maximum is not None: |
127 | 154 | maximum = min(maximum, self.maximum) | 158 | maximum = min(maximum, self.maximum) |
128 | 155 | return self.real_randint(minimum, maximum) | 159 | return self.real_randint(minimum, maximum) |
129 | 160 | |||
130 | 161 | |||
131 | 162 | @contextmanager | ||
132 | 163 | def capture_std_out_err(): | ||
133 | 164 | """A context manager that captures stdout and stderr.""" | ||
134 | 165 | stdout = StringIO() | ||
135 | 166 | stderr = StringIO() | ||
136 | 167 | |||
137 | 168 | with patch('sys.stdout', stdout): | ||
138 | 169 | with patch('sys.stderr', stderr): | ||
139 | 170 | yield stdout, stderr | ||
140 | 156 | 171 | ||
141 | === modified file 'src/metadataserver/tests/test_migrations.py' | |||
142 | --- src/metadataserver/tests/test_migrations.py 2013-10-07 09:12:40 +0000 | |||
143 | +++ src/metadataserver/tests/test_migrations.py 2015-03-27 10:06:20 +0000 | |||
144 | @@ -18,11 +18,41 @@ | |||
145 | 18 | __metaclass__ = type | 18 | __metaclass__ = type |
146 | 19 | __all__ = [] | 19 | __all__ = [] |
147 | 20 | 20 | ||
148 | 21 | |||
149 | 22 | from django.core.management import call_command | ||
150 | 21 | from maasserver.testing.db_migrations import detect_sequence_clashes | 23 | from maasserver.testing.db_migrations import detect_sequence_clashes |
151 | 22 | from maastesting.testcase import MAASTestCase | 24 | from maastesting.testcase import MAASTestCase |
152 | 25 | from maastesting.utils import capture_std_out_err | ||
153 | 26 | from testtools.content import ( | ||
154 | 27 | Content, | ||
155 | 28 | UTF8_TEXT, | ||
156 | 29 | ) | ||
157 | 23 | 30 | ||
158 | 24 | 31 | ||
159 | 25 | class TestMigrations(MAASTestCase): | 32 | class TestMigrations(MAASTestCase): |
160 | 26 | 33 | ||
161 | 27 | def test_migrations_have_unique_numbers(self): | 34 | def test_migrations_have_unique_numbers(self): |
162 | 28 | self.assertEqual([], detect_sequence_clashes('metadataserver')) | 35 | self.assertEqual([], detect_sequence_clashes('metadataserver')) |
163 | 36 | |||
164 | 37 | def test_all_model_changes_in_migrations(self): | ||
165 | 38 | # Make sure all the model changes have been transformed into | ||
166 | 39 | # migrations. | ||
167 | 40 | try: | ||
168 | 41 | with capture_std_out_err() as (stdoutIO, stderrIO): | ||
169 | 42 | call_command( | ||
170 | 43 | "schemamigration", "metadataserver", | ||
171 | 44 | "generated_migration", auto=True, stdout=True) | ||
172 | 45 | except SystemExit, e: | ||
173 | 46 | if e.code == 1: | ||
174 | 47 | # No migration can be generated because the models haven't | ||
175 | 48 | # changed: exit silently. | ||
176 | 49 | return | ||
177 | 50 | raise | ||
178 | 51 | else: | ||
179 | 52 | self.addDetail( | ||
180 | 53 | "schemamigration stderr", | ||
181 | 54 | Content(UTF8_TEXT, lambda: stderrIO.getvalue())) | ||
182 | 55 | self.addDetail( | ||
183 | 56 | "schemamigration stdout", | ||
184 | 57 | Content(UTF8_TEXT, lambda: stdoutIO.getvalue())) | ||
185 | 58 | self.fail("Migrations are not in sync with the models!") |
Looks good, I like it!