buildtest.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. #! /usr/bin/env python
  2. #
  3. # BitBake Toaster Implementation
  4. #
  5. # Copyright (C) 2016 Intel Corporation
  6. #
  7. # SPDX-License-Identifier: GPL-2.0-only
  8. #
  9. import os
  10. import sys
  11. import time
  12. import unittest
  13. from orm.models import Project, Release, ProjectTarget, Build, ProjectVariable
  14. from bldcontrol.models import BuildEnvironment
  15. from bldcontrol.management.commands.runbuilds import Command\
  16. as RunBuildsCommand
  17. from django.core.management import call_command
  18. import subprocess
  19. import logging
  20. logger = logging.getLogger("toaster")
  21. # We use unittest.TestCase instead of django.test.TestCase because we don't
  22. # want to wrap everything in a database transaction as an external process
  23. # (bitbake needs access to the database)
  24. def load_build_environment():
  25. call_command('loaddata', 'settings.xml', app_label="orm")
  26. call_command('loaddata', 'poky.xml', app_label="orm")
  27. current_builddir = os.environ.get("BUILDDIR")
  28. if current_builddir:
  29. BuildTest.BUILDDIR = current_builddir
  30. else:
  31. # Setup a builddir based on default layout
  32. # bitbake inside openebedded-core
  33. oe_init_build_env_path = os.path.join(
  34. os.path.dirname(os.path.abspath(__file__)),
  35. os.pardir,
  36. os.pardir,
  37. os.pardir,
  38. os.pardir,
  39. os.pardir,
  40. 'oe-init-build-env'
  41. )
  42. if not os.path.exists(oe_init_build_env_path):
  43. raise Exception("We had no BUILDDIR set and couldn't "
  44. "find oe-init-build-env to set this up "
  45. "ourselves please run oe-init-build-env "
  46. "before running these tests")
  47. oe_init_build_env_path = os.path.realpath(oe_init_build_env_path)
  48. cmd = "bash -c 'source oe-init-build-env %s'" % BuildTest.BUILDDIR
  49. p = subprocess.Popen(
  50. cmd,
  51. cwd=os.path.dirname(oe_init_build_env_path),
  52. shell=True,
  53. stdout=subprocess.PIPE,
  54. stderr=subprocess.PIPE)
  55. output, err = p.communicate()
  56. p.wait()
  57. logger.info("oe-init-build-env %s %s" % (output, err))
  58. os.environ['BUILDDIR'] = BuildTest.BUILDDIR
  59. # Setup the path to bitbake we know where to find this
  60. bitbake_path = os.path.join(
  61. os.path.dirname(os.path.abspath(__file__)),
  62. os.pardir,
  63. os.pardir,
  64. os.pardir,
  65. os.pardir,
  66. 'bin',
  67. 'bitbake')
  68. if not os.path.exists(bitbake_path):
  69. raise Exception("Could not find bitbake at the expected path %s"
  70. % bitbake_path)
  71. os.environ['BBBASEDIR'] = bitbake_path
  72. class BuildTest(unittest.TestCase):
  73. PROJECT_NAME = "Testbuild"
  74. BUILDDIR = "/tmp/build/"
  75. def build(self, target):
  76. # So that the buildinfo helper uses the test database'
  77. self.assertEqual(
  78. os.environ.get('DJANGO_SETTINGS_MODULE', ''),
  79. 'toastermain.settings_test',
  80. "Please initialise django with the tests settings: "
  81. "DJANGO_SETTINGS_MODULE='toastermain.settings_test'")
  82. built = self.target_already_built(target)
  83. if built:
  84. return built
  85. load_build_environment()
  86. BuildEnvironment.objects.get_or_create(
  87. betype=BuildEnvironment.TYPE_LOCAL,
  88. sourcedir=BuildTest.BUILDDIR,
  89. builddir=BuildTest.BUILDDIR
  90. )
  91. release = Release.objects.get(name='local')
  92. # Create a project for this build to run in
  93. project = Project.objects.create_project(name=BuildTest.PROJECT_NAME,
  94. release=release)
  95. if os.environ.get("TOASTER_TEST_USE_SSTATE_MIRROR"):
  96. ProjectVariable.objects.get_or_create(
  97. name="SSTATE_MIRRORS",
  98. value="file://.* http://autobuilder.yoctoproject.org/pub/sstate/PATH;downloadfilename=PATH",
  99. project=project)
  100. ProjectTarget.objects.create(project=project,
  101. target=target,
  102. task="")
  103. build_request = project.schedule_build()
  104. # run runbuilds command to dispatch the build
  105. # e.g. manage.py runubilds
  106. RunBuildsCommand().runbuild()
  107. build_pk = build_request.build.pk
  108. while Build.objects.get(pk=build_pk).outcome == Build.IN_PROGRESS:
  109. sys.stdout.write("\rBuilding %s %d%%" %
  110. (target,
  111. build_request.build.completeper()))
  112. sys.stdout.flush()
  113. time.sleep(1)
  114. self.assertEqual(Build.objects.get(pk=build_pk).outcome,
  115. Build.SUCCEEDED,
  116. "Build did not SUCCEEDED")
  117. logger.info("\nBuild finished %s" % build_request.build.outcome)
  118. return build_request.build
  119. def target_already_built(self, target):
  120. """ If the target is already built no need to build it again"""
  121. for build in Build.objects.filter(
  122. project__name=BuildTest.PROJECT_NAME):
  123. targets = build.target_set.values_list('target', flat=True)
  124. if target in targets:
  125. return build
  126. return None