summaryrefslogtreecommitdiffstats
path: root/bitbake/lib
diff options
context:
space:
mode:
authorRichard Purdie <richard.purdie@linuxfoundation.org>2024-10-18 22:25:38 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2024-10-24 11:24:03 +0100
commit566c6dca28ea436de791db933f52eba9eef822fb (patch)
tree8137e0b2710331a71ac9d6028554100782675ba7 /bitbake/lib
parent57bdcaf4177320cfc0f00ea49ffc166cbdc44d89 (diff)
downloadpoky-566c6dca28ea436de791db933f52eba9eef822fb.tar.gz
bitbake: toaster/tests/functiona/project_page: Switch to using library create_project function
Switch this test module to use the common project creation code which contains race fixes. That code requires the database access wrapper be dropped and we no longer have ordering constraints. There are two tests that do require database access. Move these to a separate class and allow database access there. Use ordering constraints to allow them to run after the main code. They depend on the project creation from the other class which isn't ideal but good enough for now. (Bitbake rev: e441bfe98ac41d48692ffbaeec90a9c780337fa4) Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake/lib')
-rw-r--r--bitbake/lib/toaster/tests/functional/test_project_page.py118
1 files changed, 42 insertions, 76 deletions
diff --git a/bitbake/lib/toaster/tests/functional/test_project_page.py b/bitbake/lib/toaster/tests/functional/test_project_page.py
index 5d10513d9d..40ef5f486a 100644
--- a/bitbake/lib/toaster/tests/functional/test_project_page.py
+++ b/bitbake/lib/toaster/tests/functional/test_project_page.py
@@ -7,7 +7,6 @@
7# 7#
8 8
9import os 9import os
10import random
11import string 10import string
12from unittest import skip 11from unittest import skip
13import pytest 12import pytest
@@ -22,58 +21,17 @@ from selenium.webdriver.common.by import By
22 21
23from .utils import get_projectId_from_url, wait_until_build, wait_until_build_cancelled 22from .utils import get_projectId_from_url, wait_until_build, wait_until_build_cancelled
24 23
25 24class TestProjectPageBase(SeleniumFunctionalTestCase):
26@pytest.mark.django_db
27@pytest.mark.order("last")
28class TestProjectPage(SeleniumFunctionalTestCase):
29 project_id = None 25 project_id = None
30 PROJECT_NAME = 'TestProjectPage' 26 PROJECT_NAME = 'TestProjectPage'
31 27
32 def _create_project(self, project_name):
33 """ Create/Test new project using:
34 - Project Name: Any string
35 - Release: Any string
36 - Merge Toaster settings: True or False
37 """
38 self.get(reverse('newproject'))
39 self.wait_until_visible('#new-project-name')
40 self.find("#new-project-name").send_keys(project_name)
41 select = Select(self.find("#projectversion"))
42 select.select_by_value('3')
43
44 # check merge toaster settings
45 checkbox = self.find('.checkbox-mergeattr')
46 if not checkbox.is_selected():
47 checkbox.click()
48
49 if self.PROJECT_NAME != 'TestProjectPage':
50 # Reset project name if it's not the default one
51 self.PROJECT_NAME = 'TestProjectPage'
52
53 self.find("#create-project-button").click()
54
55 try:
56 self.wait_until_visible('#hint-error-project-name')
57 url = reverse('project', args=(TestProjectPage.project_id, ))
58 self.get(url)
59 self.wait_until_visible('#config-nav', poll=3)
60 except TimeoutException:
61 self.wait_until_visible('#config-nav', poll=3)
62
63 def _random_string(self, length):
64 return ''.join(
65 random.choice(string.ascii_letters) for _ in range(length)
66 )
67
68 def _navigate_to_project_page(self): 28 def _navigate_to_project_page(self):
69 # Navigate to project page 29 # Navigate to project page
70 if TestProjectPage.project_id is None: 30 if TestProjectPageBase.project_id is None:
71 self._create_project(project_name=self._random_string(10)) 31 TestProjectPageBase.project_id = self.create_new_project(self.PROJECT_NAME, '3', None, True)
72 current_url = self.driver.current_url 32
73 TestProjectPage.project_id = get_projectId_from_url(current_url) 33 url = reverse('project', args=(TestProjectPageBase.project_id,))
74 else: 34 self.get(url)
75 url = reverse('project', args=(TestProjectPage.project_id,))
76 self.get(url)
77 self.wait_until_visible('#config-nav') 35 self.wait_until_visible('#config-nav')
78 36
79 def _get_create_builds(self, **kwargs): 37 def _get_create_builds(self, **kwargs):
@@ -81,14 +39,14 @@ class TestProjectPage(SeleniumFunctionalTestCase):
81 # parameters for builds to associate with the projects 39 # parameters for builds to associate with the projects
82 now = timezone.now() 40 now = timezone.now()
83 self.project1_build_success = { 41 self.project1_build_success = {
84 'project': Project.objects.get(id=TestProjectPage.project_id), 42 'project': Project.objects.get(id=TestProjectPageBase.project_id),
85 'started_on': now, 43 'started_on': now,
86 'completed_on': now, 44 'completed_on': now,
87 'outcome': Build.SUCCEEDED 45 'outcome': Build.SUCCEEDED
88 } 46 }
89 47
90 self.project1_build_failure = { 48 self.project1_build_failure = {
91 'project': Project.objects.get(id=TestProjectPage.project_id), 49 'project': Project.objects.get(id=TestProjectPageBase.project_id),
92 'started_on': now, 50 'started_on': now,
93 'completed_on': now, 51 'completed_on': now,
94 'outcome': Build.FAILED 52 'outcome': Build.FAILED
@@ -222,6 +180,8 @@ class TestProjectPage(SeleniumFunctionalTestCase):
222 rows = self.find_all(f'#{table_selector} tbody tr') 180 rows = self.find_all(f'#{table_selector} tbody tr')
223 self.assertTrue(len(rows) > 0) 181 self.assertTrue(len(rows) > 0)
224 182
183class TestProjectPage(TestProjectPageBase):
184
225 def test_create_project(self): 185 def test_create_project(self):
226 """ Create/Test new project using: 186 """ Create/Test new project using:
227 - Project Name: Any string 187 - Project Name: Any string
@@ -230,26 +190,6 @@ class TestProjectPage(SeleniumFunctionalTestCase):
230 """ 190 """
231 self._create_project(project_name=self.PROJECT_NAME) 191 self._create_project(project_name=self.PROJECT_NAME)
232 192
233 def test_image_recipe_editColumn(self):
234 """ Test the edit column feature in image recipe table on project page """
235 self._get_create_builds(success=10, failure=10)
236
237 url = reverse('projectimagerecipes', args=(TestProjectPage.project_id,))
238 self.get(url)
239 self.wait_until_present('#imagerecipestable tbody tr')
240
241 column_list = [
242 'get_description_or_summary', 'layer_version__get_vcs_reference',
243 'layer_version__layer__name', 'license', 'recipe-file', 'section',
244 'version'
245 ]
246
247 # Check that we can hide the edit column
248 self._mixin_test_table_edit_column(
249 'imagerecipestable',
250 'edit-columns-button',
251 [f'checkbox-{column}' for column in column_list]
252 )
253 193
254 def test_page_header_on_project_page(self): 194 def test_page_header_on_project_page(self):
255 """ Check page header in project page: 195 """ Check page header in project page:
@@ -379,7 +319,7 @@ class TestProjectPage(SeleniumFunctionalTestCase):
379 self.assertEqual(config_tab.get_attribute('class'), 'active') 319 self.assertEqual(config_tab.get_attribute('class'), 'active')
380 self.assertIn('Configuration', str(config_tab.text)) 320 self.assertIn('Configuration', str(config_tab.text))
381 self.assertIn( 321 self.assertIn(
382 f"/toastergui/project/{TestProjectPage.project_id}", str(self.driver.current_url) 322 f"/toastergui/project/{TestProjectPageBase.project_id}", str(self.driver.current_url)
383 ) 323 )
384 324
385 def get_tabs(): 325 def get_tabs():
@@ -402,7 +342,7 @@ class TestProjectPage(SeleniumFunctionalTestCase):
402 check_tab_link( 342 check_tab_link(
403 1, 343 1,
404 'Builds', 344 'Builds',
405 f"/toastergui/project/{TestProjectPage.project_id}/builds" 345 f"/toastergui/project/{TestProjectPageBase.project_id}/builds"
406 ) 346 )
407 347
408 # check "Import layers" tab 348 # check "Import layers" tab
@@ -411,7 +351,7 @@ class TestProjectPage(SeleniumFunctionalTestCase):
411 check_tab_link( 351 check_tab_link(
412 2, 352 2,
413 'Import layer', 353 'Import layer',
414 f"/toastergui/project/{TestProjectPage.project_id}/importlayer" 354 f"/toastergui/project/{TestProjectPageBase.project_id}/importlayer"
415 ) 355 )
416 356
417 # check "New custom image" tab 357 # check "New custom image" tab
@@ -420,7 +360,7 @@ class TestProjectPage(SeleniumFunctionalTestCase):
420 check_tab_link( 360 check_tab_link(
421 3, 361 3,
422 'New custom image', 362 'New custom image',
423 f"/toastergui/project/{TestProjectPage.project_id}/newcustomimage" 363 f"/toastergui/project/{TestProjectPageBase.project_id}/newcustomimage"
424 ) 364 )
425 365
426 # check search box can be use to build recipes 366 # check search box can be use to build recipes
@@ -766,6 +706,10 @@ class TestProjectPage(SeleniumFunctionalTestCase):
766 # Check layer description 706 # Check layer description
767 self.assertIn("Description", section.text) 707 self.assertIn("Description", section.text)
768 708
709@pytest.mark.django_db
710@pytest.mark.order("last")
711class TestProjectPageRecipes(TestProjectPageBase):
712
769 def test_single_recipe_page(self): 713 def test_single_recipe_page(self):
770 """ Test recipe page 714 """ Test recipe page
771 - Check if title is displayed 715 - Check if title is displayed
@@ -777,9 +721,9 @@ class TestProjectPage(SeleniumFunctionalTestCase):
777 # Use a recipe which is likely to exist in the layer index but not enabled 721 # Use a recipe which is likely to exist in the layer index but not enabled
778 # in poky out the box - xen-image-minimal from meta-virtualization 722 # in poky out the box - xen-image-minimal from meta-virtualization
779 self._navigate_to_project_page() 723 self._navigate_to_project_page()
780 prj = Project.objects.get(pk=TestProjectPage.project_id) 724 prj = Project.objects.get(pk=TestProjectPageBase.project_id)
781 recipe_id = prj.get_all_compatible_recipes().get(name="xen-image-minimal").pk 725 recipe_id = prj.get_all_compatible_recipes().get(name="xen-image-minimal").pk
782 url = reverse("recipedetails", args=(TestProjectPage.project_id, recipe_id)) 726 url = reverse("recipedetails", args=(TestProjectPageBase.project_id, recipe_id))
783 self.get(url) 727 self.get(url)
784 self.wait_until_visible('.page-header') 728 self.wait_until_visible('.page-header')
785 # check title is displayed 729 # check title is displayed
@@ -802,3 +746,25 @@ class TestProjectPage(SeleniumFunctionalTestCase):
802 self.assertIn("Approx. packages included", section.text) 746 self.assertIn("Approx. packages included", section.text)
803 self.assertIn("Approx. package size", section.text) 747 self.assertIn("Approx. package size", section.text)
804 self.assertIn("Recipe file", section.text) 748 self.assertIn("Recipe file", section.text)
749
750 def test_image_recipe_editColumn(self):
751 """ Test the edit column feature in image recipe table on project page """
752 self._get_create_builds(success=10, failure=10)
753
754 url = reverse('projectimagerecipes', args=(TestProjectPageBase.project_id,))
755 self.get(url)
756 self.wait_until_present('#imagerecipestable tbody tr')
757
758 column_list = [
759 'get_description_or_summary', 'layer_version__get_vcs_reference',
760 'layer_version__layer__name', 'license', 'recipe-file', 'section',
761 'version'
762 ]
763
764 # Check that we can hide the edit column
765 self._mixin_test_table_edit_column(
766 'imagerecipestable',
767 'edit-columns-button',
768 [f'checkbox-{column}' for column in column_list]
769 )
770