test_most_recent_builds_states.py 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. #! /usr/bin/env python
  2. #
  3. # BitBake Toaster Implementation
  4. #
  5. # SPDX-License-Identifier: GPL-2.0-only
  6. #
  7. # Copyright (C) 2013-2016 Intel Corporation
  8. #
  9. from django.core.urlresolvers import reverse
  10. from django.utils import timezone
  11. from tests.browser.selenium_helpers import SeleniumTestCase
  12. from tests.browser.selenium_helpers_base import Wait
  13. from orm.models import Project, Build, Task, Recipe, Layer, Layer_Version
  14. from bldcontrol.models import BuildRequest
  15. class TestMostRecentBuildsStates(SeleniumTestCase):
  16. """ Test states update correctly in most recent builds area """
  17. def _create_build_request(self):
  18. project = Project.objects.get_or_create_default_project()
  19. now = timezone.now()
  20. build = Build.objects.create(project=project, build_name='fakebuild',
  21. started_on=now, completed_on=now)
  22. return BuildRequest.objects.create(build=build, project=project,
  23. state=BuildRequest.REQ_QUEUED)
  24. def _create_recipe(self):
  25. """ Add a recipe to the database and return it """
  26. layer = Layer.objects.create()
  27. layer_version = Layer_Version.objects.create(layer=layer)
  28. return Recipe.objects.create(name='foo', layer_version=layer_version)
  29. def _check_build_states(self, build_request):
  30. recipes_to_parse = 10
  31. url = reverse('all-builds')
  32. self.get(url)
  33. build = build_request.build
  34. base_selector = '[data-latest-build-result="%s"] ' % build.id
  35. # build queued; check shown as queued
  36. selector = base_selector + '[data-build-state="Queued"]'
  37. element = self.wait_until_visible(selector)
  38. self.assertRegexpMatches(element.get_attribute('innerHTML'),
  39. 'Build queued', 'build should show queued status')
  40. # waiting for recipes to be parsed
  41. build.outcome = Build.IN_PROGRESS
  42. build.recipes_to_parse = recipes_to_parse
  43. build.recipes_parsed = 0
  44. build_request.state = BuildRequest.REQ_INPROGRESS
  45. build_request.save()
  46. self.get(url)
  47. selector = base_selector + '[data-build-state="Parsing"]'
  48. element = self.wait_until_visible(selector)
  49. bar_selector = '#recipes-parsed-percentage-bar-%s' % build.id
  50. bar_element = element.find_element_by_css_selector(bar_selector)
  51. self.assertEqual(bar_element.value_of_css_property('width'), '0px',
  52. 'recipe parse progress should be at 0')
  53. # recipes being parsed; check parse progress
  54. build.recipes_parsed = 5
  55. build.save()
  56. self.get(url)
  57. element = self.wait_until_visible(selector)
  58. bar_element = element.find_element_by_css_selector(bar_selector)
  59. recipe_bar_updated = lambda driver: \
  60. bar_element.get_attribute('style') == 'width: 50%;'
  61. msg = 'recipe parse progress bar should update to 50%'
  62. element = Wait(self.driver).until(recipe_bar_updated, msg)
  63. # all recipes parsed, task started, waiting for first task to finish;
  64. # check status is shown as "Tasks starting..."
  65. build.recipes_parsed = recipes_to_parse
  66. build.save()
  67. recipe = self._create_recipe()
  68. task1 = Task.objects.create(build=build, recipe=recipe,
  69. task_name='Lionel')
  70. task2 = Task.objects.create(build=build, recipe=recipe,
  71. task_name='Jeffries')
  72. self.get(url)
  73. selector = base_selector + '[data-build-state="Starting"]'
  74. element = self.wait_until_visible(selector)
  75. self.assertRegexpMatches(element.get_attribute('innerHTML'),
  76. 'Tasks starting', 'build should show "tasks starting" status')
  77. # first task finished; check tasks progress bar
  78. task1.order = 1
  79. task1.save()
  80. self.get(url)
  81. selector = base_selector + '[data-build-state="In Progress"]'
  82. element = self.wait_until_visible(selector)
  83. bar_selector = '#build-pc-done-bar-%s' % build.id
  84. bar_element = element.find_element_by_css_selector(bar_selector)
  85. task_bar_updated = lambda driver: \
  86. bar_element.get_attribute('style') == 'width: 50%;'
  87. msg = 'tasks progress bar should update to 50%'
  88. element = Wait(self.driver).until(task_bar_updated, msg)
  89. # last task finished; check tasks progress bar updates
  90. task2.order = 2
  91. task2.save()
  92. self.get(url)
  93. element = self.wait_until_visible(selector)
  94. bar_element = element.find_element_by_css_selector(bar_selector)
  95. task_bar_updated = lambda driver: \
  96. bar_element.get_attribute('style') == 'width: 100%;'
  97. msg = 'tasks progress bar should update to 100%'
  98. element = Wait(self.driver).until(task_bar_updated, msg)
  99. def test_states_to_success(self):
  100. """
  101. Test state transitions in the recent builds area for a build which
  102. completes successfully.
  103. """
  104. build_request = self._create_build_request()
  105. self._check_build_states(build_request)
  106. # all tasks complete and build succeeded; check success state shown
  107. build = build_request.build
  108. build.outcome = Build.SUCCEEDED
  109. build.save()
  110. selector = '[data-latest-build-result="%s"] ' \
  111. '[data-build-state="Succeeded"]' % build.id
  112. element = self.wait_until_visible(selector)
  113. def test_states_to_failure(self):
  114. """
  115. Test state transitions in the recent builds area for a build which
  116. completes in a failure.
  117. """
  118. build_request = self._create_build_request()
  119. self._check_build_states(build_request)
  120. # all tasks complete and build succeeded; check fail state shown
  121. build = build_request.build
  122. build.outcome = Build.FAILED
  123. build.save()
  124. selector = '[data-latest-build-result="%s"] ' \
  125. '[data-build-state="Failed"]' % build.id
  126. element = self.wait_until_visible(selector)
  127. def test_states_cancelling(self):
  128. """
  129. Test that most recent build area updates correctly for a build
  130. which is cancelled.
  131. """
  132. url = reverse('all-builds')
  133. build_request = self._create_build_request()
  134. build = build_request.build
  135. # cancel the build
  136. build_request.state = BuildRequest.REQ_CANCELLING
  137. build_request.save()
  138. self.get(url)
  139. # check cancelling state
  140. selector = '[data-latest-build-result="%s"] ' \
  141. '[data-build-state="Cancelling"]' % build.id
  142. element = self.wait_until_visible(selector)
  143. self.assertRegexpMatches(element.get_attribute('innerHTML'),
  144. 'Cancelling the build', 'build should show "cancelling" status')
  145. # check cancelled state
  146. build.outcome = Build.CANCELLED
  147. build.save()
  148. self.get(url)
  149. selector = '[data-latest-build-result="%s"] ' \
  150. '[data-build-state="Cancelled"]' % build.id
  151. element = self.wait_until_visible(selector)
  152. self.assertRegexpMatches(element.get_attribute('innerHTML'),
  153. 'Build cancelled', 'build should show "cancelled" status')