diff options
author | Elliot Smith <elliot.smith@intel.com> | 2016-07-13 15:12:53 +0100 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2016-08-11 00:09:27 +0100 |
commit | 36f71db680db36a2378b5c03b70819ecaf5814fa (patch) | |
tree | 882682c4825e2a167e4503ff537f40987978c872 | |
parent | 504a85822e240bef868de54bc55edf265ba87510 (diff) | |
download | poky-36f71db680db36a2378b5c03b70819ecaf5814fa.tar.gz |
bitbake: toaster-tests: add tests for build dashboard menu and summary visibility
Test that the build dashboard only shows a menu and a build
summary area if a build has properly "started" (i.e. has at least
one Variable object associated with it).
[YOCTO #8443]
(Bitbake rev: 9e16f76fb254ae967ded6c21251243b2af9b16b6)
Signed-off-by: Elliot Smith <elliot.smith@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r-- | bitbake/lib/toaster/tests/browser/test_builddashboard_page.py | 127 | ||||
-rw-r--r-- | bitbake/lib/toaster/tests/browser/test_builddashboard_page_artifacts.py | 7 |
2 files changed, 108 insertions, 26 deletions
diff --git a/bitbake/lib/toaster/tests/browser/test_builddashboard_page.py b/bitbake/lib/toaster/tests/browser/test_builddashboard_page.py index 14e77a31d6..f8ccb54528 100644 --- a/bitbake/lib/toaster/tests/browser/test_builddashboard_page.py +++ b/bitbake/lib/toaster/tests/browser/test_builddashboard_page.py | |||
@@ -25,7 +25,7 @@ from django.utils import timezone | |||
25 | from tests.browser.selenium_helpers import SeleniumTestCase | 25 | from tests.browser.selenium_helpers import SeleniumTestCase |
26 | 26 | ||
27 | from orm.models import Project, Release, BitbakeVersion, Build, LogMessage | 27 | from orm.models import Project, Release, BitbakeVersion, Build, LogMessage |
28 | from orm.models import Layer, Layer_Version, Recipe, CustomImageRecipe | 28 | from orm.models import Layer, Layer_Version, Recipe, CustomImageRecipe, Variable |
29 | 29 | ||
30 | class TestBuildDashboardPage(SeleniumTestCase): | 30 | class TestBuildDashboardPage(SeleniumTestCase): |
31 | """ Tests for the build dashboard /build/X """ | 31 | """ Tests for the build dashboard /build/X """ |
@@ -42,15 +42,27 @@ class TestBuildDashboardPage(SeleniumTestCase): | |||
42 | 42 | ||
43 | self.build1 = Build.objects.create(project=project, | 43 | self.build1 = Build.objects.create(project=project, |
44 | started_on=now, | 44 | started_on=now, |
45 | completed_on=now) | 45 | completed_on=now, |
46 | outcome=Build.SUCCEEDED) | ||
46 | 47 | ||
47 | self.build2 = Build.objects.create(project=project, | 48 | self.build2 = Build.objects.create(project=project, |
48 | started_on=now, | 49 | started_on=now, |
49 | completed_on=now) | 50 | completed_on=now, |
51 | outcome=Build.SUCCEEDED) | ||
50 | 52 | ||
51 | self.build3 = Build.objects.create(project=project, | 53 | self.build3 = Build.objects.create(project=project, |
52 | started_on=now, | 54 | started_on=now, |
53 | completed_on=now) | 55 | completed_on=now, |
56 | outcome=Build.FAILED) | ||
57 | |||
58 | # add Variable objects to the successful builds, as this is the criterion | ||
59 | # used to determine whether the left-hand panel should be displayed | ||
60 | Variable.objects.create(build=self.build1, | ||
61 | variable_name='Foo', | ||
62 | variable_value='Bar') | ||
63 | Variable.objects.create(build=self.build2, | ||
64 | variable_name='Foo', | ||
65 | variable_value='Bar') | ||
54 | 66 | ||
55 | # exception | 67 | # exception |
56 | msg1 = 'an exception was thrown' | 68 | msg1 = 'an exception was thrown' |
@@ -68,6 +80,22 @@ class TestBuildDashboardPage(SeleniumTestCase): | |||
68 | message=msg2 | 80 | message=msg2 |
69 | ) | 81 | ) |
70 | 82 | ||
83 | # error on the failed build | ||
84 | msg3 = 'an error occurred' | ||
85 | self.error_message = LogMessage.objects.create( | ||
86 | build=self.build3, | ||
87 | level=LogMessage.ERROR, | ||
88 | message=msg3 | ||
89 | ) | ||
90 | |||
91 | # warning on the failed build | ||
92 | msg4 = 'DANGER WILL ROBINSON' | ||
93 | self.warning_message = LogMessage.objects.create( | ||
94 | build=self.build3, | ||
95 | level=LogMessage.WARNING, | ||
96 | message=msg4 | ||
97 | ) | ||
98 | |||
71 | # recipes related to the build, for testing the edit custom image/new | 99 | # recipes related to the build, for testing the edit custom image/new |
72 | # custom image buttons | 100 | # custom image buttons |
73 | layer = Layer.objects.create(name='alayer') | 101 | layer = Layer.objects.create(name='alayer') |
@@ -151,36 +179,45 @@ class TestBuildDashboardPage(SeleniumTestCase): | |||
151 | self._get_build_dashboard(build) | 179 | self._get_build_dashboard(build) |
152 | return self.find_all('#errors div.alert-danger') | 180 | return self.find_all('#errors div.alert-danger') |
153 | 181 | ||
154 | def _check_for_log_message(self, build, log_message): | 182 | def _check_for_log_message(self, message_elements, log_message): |
155 | """ | 183 | """ |
156 | Check whether the LogMessage instance <log_message> is | 184 | Check that the LogMessage <log_message> has a representation in |
157 | represented as an HTML error in the dashboard page for the Build object | 185 | the HTML elements <message_elements>. |
158 | build | ||
159 | """ | ||
160 | errors = self._get_build_dashboard_errors(build) | ||
161 | self.assertEqual(len(errors), 2) | ||
162 | 186 | ||
187 | message_elements: WebElements representing the log messages shown | ||
188 | in the build dashboard; each should have a <pre> element inside | ||
189 | it with a data-log-message-id attribute | ||
190 | |||
191 | log_message: orm.models.LogMessage instance | ||
192 | """ | ||
163 | expected_text = log_message.message | 193 | expected_text = log_message.message |
164 | expected_id = str(log_message.id) | 194 | expected_pk = str(log_message.pk) |
165 | 195 | ||
166 | found = False | 196 | found = False |
167 | for error in errors: | 197 | for element in message_elements: |
168 | error_text = error.find_element_by_tag_name('pre').text | 198 | log_message_text = element.find_element_by_tag_name('pre').text.strip() |
169 | text_matches = (error_text == expected_text) | 199 | text_matches = (log_message_text == expected_text) |
170 | 200 | ||
171 | error_id = error.get_attribute('data-error') | 201 | log_message_pk = element.get_attribute('data-log-message-id') |
172 | id_matches = (error_id == expected_id) | 202 | id_matches = (log_message_pk == expected_pk) |
173 | 203 | ||
174 | if text_matches and id_matches: | 204 | if text_matches and id_matches: |
175 | found = True | 205 | found = True |
176 | break | 206 | break |
177 | 207 | ||
178 | template_vars = (expected_text, error_text, | 208 | template_vars = (expected_text, expected_pk) |
179 | expected_id, error_id) | 209 | assertion_failed_msg = 'message not found: ' \ |
180 | assertion_error_msg = 'exception not found as error: ' \ | 210 | 'expected text "%s" and ID %s' % template_vars |
181 | 'expected text "%s" and got "%s"; ' \ | 211 | self.assertTrue(found, assertion_failed_msg) |
182 | 'expected ID %s and got %s' % template_vars | 212 | |
183 | self.assertTrue(found, assertion_error_msg) | 213 | def _check_for_error_message(self, build, log_message): |
214 | """ | ||
215 | Check whether the LogMessage instance <log_message> is | ||
216 | represented as an HTML error in the dashboard page for the Build object | ||
217 | build | ||
218 | """ | ||
219 | errors = self._get_build_dashboard_errors(build) | ||
220 | self._check_for_log_message(errors, log_message) | ||
184 | 221 | ||
185 | def _check_labels_in_modal(self, modal, expected): | 222 | def _check_labels_in_modal(self, modal, expected): |
186 | """ | 223 | """ |
@@ -203,14 +240,14 @@ class TestBuildDashboardPage(SeleniumTestCase): | |||
203 | LogMessages with level EXCEPTION should display in the errors | 240 | LogMessages with level EXCEPTION should display in the errors |
204 | section of the page | 241 | section of the page |
205 | """ | 242 | """ |
206 | self._check_for_log_message(self.build1, self.exception_message) | 243 | self._check_for_error_message(self.build1, self.exception_message) |
207 | 244 | ||
208 | def test_criticals_show_as_errors(self): | 245 | def test_criticals_show_as_errors(self): |
209 | """ | 246 | """ |
210 | LogMessages with level CRITICAL should display in the errors | 247 | LogMessages with level CRITICAL should display in the errors |
211 | section of the page | 248 | section of the page |
212 | """ | 249 | """ |
213 | self._check_for_log_message(self.build1, self.critical_message) | 250 | self._check_for_error_message(self.build1, self.critical_message) |
214 | 251 | ||
215 | def test_edit_custom_image_button(self): | 252 | def test_edit_custom_image_button(self): |
216 | """ | 253 | """ |
@@ -268,3 +305,43 @@ class TestBuildDashboardPage(SeleniumTestCase): | |||
268 | self.assertFalse(self.element_exists(selector), | 305 | self.assertFalse(self.element_exists(selector), |
269 | 'new custom image button should not show for builds which ' \ | 306 | 'new custom image button should not show for builds which ' \ |
270 | 'don\'t have any image recipes') | 307 | 'don\'t have any image recipes') |
308 | |||
309 | def test_left_panel(self): | ||
310 | """" | ||
311 | Builds which succeed should have a left panel and a build summary | ||
312 | """ | ||
313 | self._get_build_dashboard(self.build1) | ||
314 | |||
315 | left_panel = self.find_all('#nav') | ||
316 | self.assertEqual(len(left_panel), 1) | ||
317 | |||
318 | build_summary = self.find_all('[data-role="build-summary-heading"]') | ||
319 | self.assertEqual(len(build_summary), 1) | ||
320 | |||
321 | def test_failed_no_left_panel(self): | ||
322 | """ | ||
323 | Builds which fail should have no left panel and no build summary | ||
324 | """ | ||
325 | self._get_build_dashboard(self.build3) | ||
326 | |||
327 | left_panel = self.find_all('#nav') | ||
328 | self.assertEqual(len(left_panel), 0) | ||
329 | |||
330 | build_summary = self.find_all('[data-role="build-summary-heading"]') | ||
331 | self.assertEqual(len(build_summary), 0) | ||
332 | |||
333 | def test_failed_shows_errors_and_warnings(self): | ||
334 | """ | ||
335 | Failed builds should still show error and warning messages | ||
336 | """ | ||
337 | self._get_build_dashboard(self.build3) | ||
338 | |||
339 | errors = self.find_all('#errors div.alert-danger') | ||
340 | self._check_for_log_message(errors, self.error_message) | ||
341 | |||
342 | # expand the warnings area | ||
343 | self.click('#warning-toggle') | ||
344 | self.wait_until_visible('#warnings div.alert-warning') | ||
345 | |||
346 | warnings = self.find_all('#warnings div.alert-warning') | ||
347 | self._check_for_log_message(warnings, self.warning_message) | ||
diff --git a/bitbake/lib/toaster/tests/browser/test_builddashboard_page_artifacts.py b/bitbake/lib/toaster/tests/browser/test_builddashboard_page_artifacts.py index 39b0e207fc..1c627ad498 100644 --- a/bitbake/lib/toaster/tests/browser/test_builddashboard_page_artifacts.py +++ b/bitbake/lib/toaster/tests/browser/test_builddashboard_page_artifacts.py | |||
@@ -26,7 +26,7 @@ from tests.browser.selenium_helpers import SeleniumTestCase | |||
26 | 26 | ||
27 | from orm.models import Project, Release, BitbakeVersion, Build, Target, Package | 27 | from orm.models import Project, Release, BitbakeVersion, Build, Target, Package |
28 | from orm.models import Target_Image_File, TargetSDKFile, TargetKernelFile | 28 | from orm.models import Target_Image_File, TargetSDKFile, TargetKernelFile |
29 | from orm.models import Target_Installed_Package | 29 | from orm.models import Target_Installed_Package, Variable |
30 | 30 | ||
31 | class TestBuildDashboardPageArtifacts(SeleniumTestCase): | 31 | class TestBuildDashboardPageArtifacts(SeleniumTestCase): |
32 | """ Tests for artifacts on the build dashboard /build/X """ | 32 | """ Tests for artifacts on the build dashboard /build/X """ |
@@ -151,6 +151,11 @@ class TestBuildDashboardPageArtifacts(SeleniumTestCase): | |||
151 | started_on=now, completed_on=timezone.now(), | 151 | started_on=now, completed_on=timezone.now(), |
152 | outcome=Build.SUCCEEDED) | 152 | outcome=Build.SUCCEEDED) |
153 | 153 | ||
154 | # add a variable to the build so that it counts as "started" | ||
155 | Variable.objects.create(build=build, | ||
156 | variable_name='Christopher', | ||
157 | variable_value='Lee') | ||
158 | |||
154 | target = Target.objects.create(is_image=True, build=build, | 159 | target = Target.objects.create(is_image=True, build=build, |
155 | task='', target='core-image-minimal', | 160 | task='', target='core-image-minimal', |
156 | license_manifest_path='/home/foo/license.manifest', | 161 | license_manifest_path='/home/foo/license.manifest', |