summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/toaster
diff options
context:
space:
mode:
authorElliot Smith <elliot.smith@intel.com>2016-07-12 15:54:56 -0700
committerRichard Purdie <richard.purdie@linuxfoundation.org>2016-07-19 08:56:52 +0100
commitdb5426b0794c65f69efe34273fe98823e2a655d7 (patch)
tree5e1714e35a3f292aab922c3e927ebe1a183d0e18 /bitbake/lib/toaster
parent9475a684c4baa45ba7bdc6ac7a122c122ed17ed9 (diff)
downloadpoky-db5426b0794c65f69efe34273fe98823e2a655d7.tar.gz
bitbake: toaster-tests: add tests for build artifact display on build dashboard
Add tests for display of image, kernel and SDK artifacts on the build dashboard, checking that the "Images" option in the left-hand menu and the "Build artifacts" section display correctly for different types of build. Also add metadata to elements on the build dashboard so it's clearer what they represent, and to assist in finding them in the tests. Add a method to the test helper to make it more convenient to check whether a single element matching a selector exists. [YOCTO #8556] [YOCTO #8563] [YOCTO #9500] (Bitbake rev: 644a888ce5a2141f2e6e1c22430e196b65cb1313) Signed-off-by: Elliot Smith <elliot.smith@intel.com> Signed-off-by: bavery <brian.avery@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake/lib/toaster')
-rw-r--r--bitbake/lib/toaster/tests/browser/selenium_helpers.py7
-rw-r--r--bitbake/lib/toaster/tests/browser/test_builddashboard_page_artifacts.py177
-rw-r--r--bitbake/lib/toaster/toastergui/templates/basebuildpage.html2
-rw-r--r--bitbake/lib/toaster/toastergui/templates/builddashboard.html12
4 files changed, 191 insertions, 7 deletions
diff --git a/bitbake/lib/toaster/tests/browser/selenium_helpers.py b/bitbake/lib/toaster/tests/browser/selenium_helpers.py
index 54db2e8cf2..be1f037825 100644
--- a/bitbake/lib/toaster/tests/browser/selenium_helpers.py
+++ b/bitbake/lib/toaster/tests/browser/selenium_helpers.py
@@ -158,6 +158,13 @@ class SeleniumTestCase(StaticLiveServerTestCase):
158 """ Find all elements matching CSS selector """ 158 """ Find all elements matching CSS selector """
159 return self.driver.find_elements_by_css_selector(selector) 159 return self.driver.find_elements_by_css_selector(selector)
160 160
161 def element_exists(self, selector):
162 """
163 Return True if one element matching selector exists,
164 False otherwise
165 """
166 return len(self.find_all(selector)) == 1
167
161 def focused_element(self): 168 def focused_element(self):
162 """ Return the element which currently has focus on the page """ 169 """ Return the element which currently has focus on the page """
163 return self.driver.switch_to.active_element 170 return self.driver.switch_to.active_element
diff --git a/bitbake/lib/toaster/tests/browser/test_builddashboard_page_artifacts.py b/bitbake/lib/toaster/tests/browser/test_builddashboard_page_artifacts.py
new file mode 100644
index 0000000000..18e4475711
--- /dev/null
+++ b/bitbake/lib/toaster/tests/browser/test_builddashboard_page_artifacts.py
@@ -0,0 +1,177 @@
1#! /usr/bin/env python
2# ex:ts=4:sw=4:sts=4:et
3# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
4#
5# BitBake Toaster Implementation
6#
7# Copyright (C) 2013-2016 Intel Corporation
8#
9# This program is free software; you can redistribute it and/or modify
10# it under the terms of the GNU General Public License version 2 as
11# published by the Free Software Foundation.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License along
19# with this program; if not, write to the Free Software Foundation, Inc.,
20# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21
22from django.core.urlresolvers import reverse
23from django.utils import timezone
24
25from tests.browser.selenium_helpers import SeleniumTestCase
26
27from orm.models import Project, Release, BitbakeVersion, Build, Target
28from orm.models import Target_Image_File, TargetSDKFile, TargetKernelFile
29
30class TestBuildDashboardPageArtifacts(SeleniumTestCase):
31 """ Tests for artifacts on the build dashboard /build/X """
32
33 def setUp(self):
34 bbv = BitbakeVersion.objects.create(name='bbv1', giturl='/tmp/',
35 branch='master', dirpath="")
36 release = Release.objects.create(name='release1',
37 bitbake_version=bbv)
38 self.project = Project.objects.create_project(name='test project',
39 release=release)
40
41 def _get_build_dashboard(self, build):
42 """
43 Navigate to the build dashboard for build
44 """
45 url = reverse('builddashboard', args=(build.id,))
46 self.get(url)
47
48 def _has_build_artifacts_heading(self):
49 """
50 Check whether the "Build artifacts" heading is visible (True if it
51 is, False otherwise).
52 """
53 return self.element_exists('[data-heading="build-artifacts"]')
54
55 def _has_images_menu_option(self):
56 """
57 Try to get the "Images" list element from the left-hand menu in the
58 build dashboard, and return True if it is present, False otherwise.
59 """
60 return self.element_exists('li.nav-header[data-menu-heading="images"]')
61
62 def test_no_artifacts(self):
63 """
64 If a build produced no artifacts, the artifacts heading and images
65 menu option shouldn't show.
66 """
67 now = timezone.now()
68 build = Build.objects.create(project=self.project,
69 started_on=now, completed_on=now, outcome=Build.SUCCEEDED)
70
71 Target.objects.create(is_image=False, build=build, task='',
72 target='mpfr-native')
73
74 self._get_build_dashboard(build)
75
76 # check build artifacts heading
77 msg = 'Build artifacts heading should not be displayed for non-image' \
78 'builds'
79 self.assertFalse(self._has_build_artifacts_heading(), msg)
80
81 # check "Images" option in left-hand menu (should not be there)
82 msg = 'Images option should not be shown in left-hand menu'
83 self.assertFalse(self._has_images_menu_option(), msg)
84
85 def test_sdk_artifacts(self):
86 """
87 If a build produced SDK artifacts, they should be shown, but the section
88 for image files and the images menu option should be hidden.
89 """
90 now = timezone.now()
91 build = Build.objects.create(project=self.project,
92 started_on=now, completed_on=timezone.now(),
93 outcome=Build.SUCCEEDED)
94
95 target = Target.objects.create(is_image=True, build=build,
96 task='populate_sdk', target='core-image-minimal')
97
98 sdk_file1 = TargetSDKFile.objects.create(target=target,
99 file_size=100000,
100 file_name='/home/foo/core-image-minimal.toolchain.sh')
101
102 sdk_file2 = TargetSDKFile.objects.create(target=target,
103 file_size=120000,
104 file_name='/home/foo/x86_64.toolchain.sh')
105
106 self._get_build_dashboard(build)
107
108 # check build artifacts heading
109 msg = 'Build artifacts heading should be displayed for SDK ' \
110 'builds which generate artifacts'
111 self.assertTrue(self._has_build_artifacts_heading(), msg)
112
113 # check "Images" option in left-hand menu (should not be there)
114 msg = 'Images option should not be shown in left-hand menu for ' \
115 'builds which didn\'t generate an image file'
116 self.assertFalse(self._has_images_menu_option(), msg)
117
118 # check links to SDK artifacts
119 sdk_artifact_links = self.find_all('[data-links="sdk-artifacts"] li')
120 self.assertEqual(len(sdk_artifact_links), 2,
121 'should be links to 2 SDK artifacts')
122
123 def test_image_artifacts(self):
124 """
125 If a build produced image files, kernel artifacts, and manifests,
126 they should all be shown, as well as the image link in the left-hand
127 menu.
128 """
129 now = timezone.now()
130 build = Build.objects.create(project=self.project,
131 started_on=now, completed_on=timezone.now(),
132 outcome=Build.SUCCEEDED)
133
134 target = Target.objects.create(is_image=True, build=build,
135 task='', target='core-image-minimal',
136 license_manifest_path='/home/foo/license.manifest',
137 package_manifest_path='/home/foo/package.manifest')
138
139 image_file = Target_Image_File.objects.create(target=target,
140 file_name='/home/foo/core-image-minimal.ext4', file_size=9000)
141
142 kernel_file1 = TargetKernelFile.objects.create(target=target,
143 file_name='/home/foo/bzImage', file_size=2000)
144
145 kernel_file2 = TargetKernelFile.objects.create(target=target,
146 file_name='/home/foo/bzImage', file_size=2000)
147
148 self._get_build_dashboard(build)
149
150 # check build artifacts heading
151 msg = 'Build artifacts heading should be displayed for image ' \
152 'builds'
153 self.assertTrue(self._has_build_artifacts_heading(), msg)
154
155 # check "Images" option in left-hand menu (should be there)
156 msg = 'Images option should be shown in left-hand menu for image builds'
157 self.assertTrue(self._has_images_menu_option(), msg)
158
159 # check link to image file
160 selector = '[data-links="image-artifacts"] li'
161 self.assertTrue(self.element_exists(selector),
162 'should be a link to the image file (selector %s)' % selector)
163
164 # check links to kernel artifacts
165 kernel_artifact_links = \
166 self.find_all('[data-links="kernel-artifacts"] li')
167 self.assertEqual(len(kernel_artifact_links), 2,
168 'should be links to 2 kernel artifacts')
169
170 # check manifest links
171 selector = 'a[data-link="license-manifest"]'
172 self.assertTrue(self.element_exists(selector),
173 'should be a link to the license manifest (selector %s)' % selector)
174
175 selector = 'a[data-link="package-manifest"]'
176 self.assertTrue(self.element_exists(selector),
177 'should be a link to the package manifest (selector %s)' % selector)
diff --git a/bitbake/lib/toaster/toastergui/templates/basebuildpage.html b/bitbake/lib/toaster/toastergui/templates/basebuildpage.html
index eb709bbd43..44749bf49a 100644
--- a/bitbake/lib/toaster/toastergui/templates/basebuildpage.html
+++ b/bitbake/lib/toaster/toastergui/templates/basebuildpage.html
@@ -63,7 +63,7 @@
63 <a href="{% url 'builddashboard' build.pk %}">Build summary</a> 63 <a href="{% url 'builddashboard' build.pk %}">Build summary</a>
64 </li> 64 </li>
65 {% if build.has_images and build.outcome == build.SUCCEEDED %} 65 {% if build.has_images and build.outcome == build.SUCCEEDED %}
66 <li class="nav-header">Images</li> 66 <li class="nav-header" data-menu-heading="images">Images</li>
67 {% block nav-target %} 67 {% block nav-target %}
68 {% for t in build.get_sorted_target_list %} 68 {% for t in build.get_sorted_target_list %}
69 {% if t.has_images %} 69 {% if t.has_images %}
diff --git a/bitbake/lib/toaster/toastergui/templates/builddashboard.html b/bitbake/lib/toaster/toastergui/templates/builddashboard.html
index 36c28b7d6a..bc41e23622 100644
--- a/bitbake/lib/toaster/toastergui/templates/builddashboard.html
+++ b/bitbake/lib/toaster/toastergui/templates/builddashboard.html
@@ -70,7 +70,7 @@
70{%if build.outcome == build.SUCCEEDED%} 70{%if build.outcome == build.SUCCEEDED%}
71<!-- built images --> 71<!-- built images -->
72 {% if hasArtifacts %} 72 {% if hasArtifacts %}
73 <h2>Build artifacts</h2> 73 <h2 data-heading="build-artifacts">Build artifacts</h2>
74 {% for target in targets %} 74 {% for target in targets %}
75 {% if target.target.is_image %} 75 {% if target.target.is_image %}
76 <div class="well well-transparent dashboard-section" data-artifacts-for-target="{{target.target.pk}}"> 76 <div class="well well-transparent dashboard-section" data-artifacts-for-target="{{target.target.pk}}">
@@ -88,12 +88,12 @@
88 </dt> 88 </dt>
89 89
90 <dd> 90 <dd>
91 <a href="{% url 'build_artifact' build.pk 'licensemanifest' target.target.pk %}">License manifest</a> 91 <a data-link="license-manifest" href="{% url 'build_artifact' build.pk 'licensemanifest' target.target.pk %}">License manifest</a>
92 </dd> 92 </dd>
93 93
94 {% if target.target.package_manifest_path %} 94 {% if target.target.package_manifest_path %}
95 <dd> 95 <dd>
96 <a href="{% url 'build_artifact' build.pk 'packagemanifest' target.target.pk %}">Package manifest</a> 96 <a data-link="package-manifest" href="{% url 'build_artifact' build.pk 'packagemanifest' target.target.pk %}">Package manifest</a>
97 </dd> 97 </dd>
98 {% endif %} 98 {% endif %}
99 </dl> 99 </dl>
@@ -104,7 +104,7 @@
104 Image files 104 Image files
105 </dt> 105 </dt>
106 <dd> 106 <dd>
107 <ul class="list-unstyled"> 107 <ul class="list-unstyled" data-links="image-artifacts">
108 {% for i in target.imageFiles|dictsort:"suffix" %} 108 {% for i in target.imageFiles|dictsort:"suffix" %}
109 <li> 109 <li>
110 <a href="{% url 'build_artifact' build.pk 'imagefile' i.id %}"> 110 <a href="{% url 'build_artifact' build.pk 'imagefile' i.id %}">
@@ -119,7 +119,7 @@
119 Kernel artifacts 119 Kernel artifacts
120 </dt> 120 </dt>
121 <dd> 121 <dd>
122 <ul class="list-unstyled"> 122 <ul class="list-unstyled" data-links="kernel-artifacts">
123 {% for artifact in target.target_kernel_artifacts|dictsort:"basename" %} 123 {% for artifact in target.target_kernel_artifacts|dictsort:"basename" %}
124 <li> 124 <li>
125 <a href="{% url 'build_artifact' build.id 'targetkernelartifact' artifact.id %}">{{artifact.basename}}</a> 125 <a href="{% url 'build_artifact' build.id 'targetkernelartifact' artifact.id %}">{{artifact.basename}}</a>
@@ -136,7 +136,7 @@
136 SDK artifacts 136 SDK artifacts
137 </dt> 137 </dt>
138 <dd> 138 <dd>
139 <ul class="list-unstyled"> 139 <ul class="list-unstyled" data-links="sdk-artifacts">
140 {% for artifact in target.target_sdk_artifacts|dictsort:"basename" %} 140 {% for artifact in target.target_sdk_artifacts|dictsort:"basename" %}
141 <li> 141 <li>
142 <a href="{% url 'build_artifact' build.id 'targetsdkartifact' artifact.id %}">{{artifact.basename}}</a> 142 <a href="{% url 'build_artifact' build.id 'targetsdkartifact' artifact.id %}">{{artifact.basename}}</a>