1#! /usr/bin/env python3 2# 3# BitBake Toaster Implementation 4# 5# Copyright (C) 2013-2016 Intel Corporation 6# 7# SPDX-License-Identifier: GPL-2.0-only 8# 9 10import re 11 12from django.urls import reverse 13from django.utils import timezone 14from tests.browser.selenium_helpers import SeleniumTestCase 15 16from orm.models import BitbakeVersion, Release, Project, Build, Target 17 18class TestProjectBuildsPage(SeleniumTestCase): 19 """ Test data at /project/X/builds is displayed correctly """ 20 21 PROJECT_NAME = 'test project' 22 CLI_BUILDS_PROJECT_NAME = 'command line builds' 23 24 def setUp(self): 25 bbv = BitbakeVersion.objects.create(name='bbv1', giturl='/tmp/', 26 branch='master', dirpath='') 27 release = Release.objects.create(name='release1', 28 bitbake_version=bbv) 29 self.project1 = Project.objects.create_project(name=self.PROJECT_NAME, 30 release=release) 31 self.project1.save() 32 33 self.project2 = Project.objects.create_project(name=self.PROJECT_NAME, 34 release=release) 35 self.project2.save() 36 37 self.default_project = Project.objects.create_project( 38 name=self.CLI_BUILDS_PROJECT_NAME, 39 release=release 40 ) 41 self.default_project.is_default = True 42 self.default_project.save() 43 44 # parameters for builds to associate with the projects 45 now = timezone.now() 46 47 self.project1_build_success = { 48 'project': self.project1, 49 'started_on': now, 50 'completed_on': now, 51 'outcome': Build.SUCCEEDED 52 } 53 54 self.project1_build_in_progress = { 55 'project': self.project1, 56 'started_on': now, 57 'completed_on': now, 58 'outcome': Build.IN_PROGRESS 59 } 60 61 self.project2_build_success = { 62 'project': self.project2, 63 'started_on': now, 64 'completed_on': now, 65 'outcome': Build.SUCCEEDED 66 } 67 68 self.project2_build_in_progress = { 69 'project': self.project2, 70 'started_on': now, 71 'completed_on': now, 72 'outcome': Build.IN_PROGRESS 73 } 74 75 def _get_rows_for_project(self, project_id): 76 """ 77 Helper to retrieve HTML rows for a project's builds, 78 as shown in the main table of the page 79 """ 80 url = reverse('projectbuilds', args=(project_id,)) 81 self.get(url) 82 self.wait_until_present('#projectbuildstable tbody tr') 83 return self.find_all('#projectbuildstable tbody tr') 84 85 def test_show_builds_for_project(self): 86 """ Builds for a project should be displayed in the main table """ 87 Build.objects.create(**self.project1_build_success) 88 Build.objects.create(**self.project1_build_success) 89 build_rows = self._get_rows_for_project(self.project1.id) 90 self.assertEqual(len(build_rows), 2) 91 92 def test_show_builds_project_only(self): 93 """ Builds for other projects should be excluded """ 94 Build.objects.create(**self.project1_build_success) 95 Build.objects.create(**self.project1_build_success) 96 Build.objects.create(**self.project1_build_success) 97 98 # shouldn't see these two 99 Build.objects.create(**self.project2_build_success) 100 Build.objects.create(**self.project2_build_in_progress) 101 102 build_rows = self._get_rows_for_project(self.project1.id) 103 self.assertEqual(len(build_rows), 3) 104 105 def test_builds_exclude_in_progress(self): 106 """ "in progress" builds should not be shown in main table """ 107 Build.objects.create(**self.project1_build_success) 108 Build.objects.create(**self.project1_build_success) 109 110 # shouldn't see this one 111 Build.objects.create(**self.project1_build_in_progress) 112 113 # shouldn't see these two either, as they belong to a different project 114 Build.objects.create(**self.project2_build_success) 115 Build.objects.create(**self.project2_build_in_progress) 116 117 build_rows = self._get_rows_for_project(self.project1.id) 118 self.assertEqual(len(build_rows), 2) 119 120 def test_show_tasks_with_suffix(self): 121 """ Task should be shown as suffixes on build names """ 122 build = Build.objects.create(**self.project1_build_success) 123 target = 'bash' 124 task = 'clean' 125 Target.objects.create(build=build, target=target, task=task) 126 127 url = reverse('projectbuilds', args=(self.project1.id,)) 128 self.get(url) 129 self.wait_until_present('td[class="target"]') 130 131 cell = self.find('td[class="target"]') 132 content = cell.get_attribute('innerHTML') 133 expected_text = '%s:%s' % (target, task) 134 135 self.assertTrue(re.search(expected_text, content), 136 '"target" cell should contain text %s' % expected_text) 137 138 def test_cli_builds_hides_tabs(self): 139 """ 140 Display for command line builds should hide tabs 141 """ 142 url = reverse('projectbuilds', args=(self.default_project.id,)) 143 self.get(url) 144 tabs = self.find_all('#project-topbar') 145 self.assertEqual(len(tabs), 0, 146 'should be no top bar shown for command line builds') 147 148 def test_non_cli_builds_has_tabs(self): 149 """ 150 Non-command-line builds projects should show the tabs 151 """ 152 url = reverse('projectbuilds', args=(self.project1.id,)) 153 self.get(url) 154 tabs = self.find_all('#project-topbar') 155 self.assertEqual(len(tabs), 1, 156 'should be a top bar shown for non-command-line builds') 157