blob: 9f40f978d0007f7bb1202b8cdd215ff52b21ebe5 [file] [log] [blame]
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001#! /usr/bin/env python
Patrick Williamsc0f7c042017-02-23 20:41:17 -06002#
3# BitBake Toaster Implementation
4#
5# Copyright (C) 2016 Intel Corporation
6#
Brad Bishopc342db32019-05-15 21:57:59 -04007# SPDX-License-Identifier: GPL-2.0-only
Patrick Williamsc0f7c042017-02-23 20:41:17 -06008#
Patrick Williamsc0f7c042017-02-23 20:41:17 -06009
10import os
11import sys
12import time
13import unittest
14
Brad Bishop6e60e8b2018-02-01 10:27:11 -050015from orm.models import Project, Release, ProjectTarget, Build, ProjectVariable
Patrick Williamsc0f7c042017-02-23 20:41:17 -060016from bldcontrol.models import BuildEnvironment
17
Patrick Williamsc0f7c042017-02-23 20:41:17 -060018from bldcontrol.management.commands.runbuilds import Command\
19 as RunBuildsCommand
20
Brad Bishop6e60e8b2018-02-01 10:27:11 -050021from django.core.management import call_command
22
Patrick Williamsc0f7c042017-02-23 20:41:17 -060023import subprocess
Brad Bishop6e60e8b2018-02-01 10:27:11 -050024import logging
25
26logger = logging.getLogger("toaster")
Patrick Williamsc0f7c042017-02-23 20:41:17 -060027
28# We use unittest.TestCase instead of django.test.TestCase because we don't
29# want to wrap everything in a database transaction as an external process
30# (bitbake needs access to the database)
31
Brad Bishop6e60e8b2018-02-01 10:27:11 -050032def load_build_environment():
33 call_command('loaddata', 'settings.xml', app_label="orm")
34 call_command('loaddata', 'poky.xml', app_label="orm")
35
36 current_builddir = os.environ.get("BUILDDIR")
37 if current_builddir:
38 BuildTest.BUILDDIR = current_builddir
39 else:
40 # Setup a builddir based on default layout
41 # bitbake inside openebedded-core
42 oe_init_build_env_path = os.path.join(
43 os.path.dirname(os.path.abspath(__file__)),
44 os.pardir,
45 os.pardir,
46 os.pardir,
47 os.pardir,
48 os.pardir,
49 'oe-init-build-env'
50 )
51 if not os.path.exists(oe_init_build_env_path):
52 raise Exception("We had no BUILDDIR set and couldn't "
53 "find oe-init-build-env to set this up "
54 "ourselves please run oe-init-build-env "
55 "before running these tests")
56
57 oe_init_build_env_path = os.path.realpath(oe_init_build_env_path)
58 cmd = "bash -c 'source oe-init-build-env %s'" % BuildTest.BUILDDIR
59 p = subprocess.Popen(
60 cmd,
61 cwd=os.path.dirname(oe_init_build_env_path),
62 shell=True,
63 stdout=subprocess.PIPE,
64 stderr=subprocess.PIPE)
65
66 output, err = p.communicate()
67 p.wait()
68
69 logger.info("oe-init-build-env %s %s" % (output, err))
70
71 os.environ['BUILDDIR'] = BuildTest.BUILDDIR
72
73 # Setup the path to bitbake we know where to find this
74 bitbake_path = os.path.join(
75 os.path.dirname(os.path.abspath(__file__)),
76 os.pardir,
77 os.pardir,
78 os.pardir,
79 os.pardir,
80 'bin',
81 'bitbake')
82 if not os.path.exists(bitbake_path):
83 raise Exception("Could not find bitbake at the expected path %s"
84 % bitbake_path)
85
86 os.environ['BBBASEDIR'] = bitbake_path
Patrick Williamsc0f7c042017-02-23 20:41:17 -060087
88class BuildTest(unittest.TestCase):
89
90 PROJECT_NAME = "Testbuild"
Brad Bishop6e60e8b2018-02-01 10:27:11 -050091 BUILDDIR = "/tmp/build/"
Patrick Williamsc0f7c042017-02-23 20:41:17 -060092
93 def build(self, target):
94 # So that the buildinfo helper uses the test database'
95 self.assertEqual(
96 os.environ.get('DJANGO_SETTINGS_MODULE', ''),
Brad Bishop6e60e8b2018-02-01 10:27:11 -050097 'toastermain.settings_test',
Patrick Williamsc0f7c042017-02-23 20:41:17 -060098 "Please initialise django with the tests settings: "
Brad Bishop6e60e8b2018-02-01 10:27:11 -050099 "DJANGO_SETTINGS_MODULE='toastermain.settings_test'")
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600100
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500101 built = self.target_already_built(target)
102 if built:
103 return built
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600104
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500105 load_build_environment()
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600106
107 BuildEnvironment.objects.get_or_create(
108 betype=BuildEnvironment.TYPE_LOCAL,
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500109 sourcedir=BuildTest.BUILDDIR,
110 builddir=BuildTest.BUILDDIR
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600111 )
112
113 release = Release.objects.get(name='local')
114
115 # Create a project for this build to run in
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500116 project = Project.objects.create_project(name=BuildTest.PROJECT_NAME,
117 release=release)
118
119 if os.environ.get("TOASTER_TEST_USE_SSTATE_MIRROR"):
120 ProjectVariable.objects.get_or_create(
121 name="SSTATE_MIRRORS",
122 value="file://.* http://autobuilder.yoctoproject.org/pub/sstate/PATH;downloadfilename=PATH",
123 project=project)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600124
125 ProjectTarget.objects.create(project=project,
126 target=target,
127 task="")
128 build_request = project.schedule_build()
129
130 # run runbuilds command to dispatch the build
131 # e.g. manage.py runubilds
132 RunBuildsCommand().runbuild()
133
134 build_pk = build_request.build.pk
135 while Build.objects.get(pk=build_pk).outcome == Build.IN_PROGRESS:
136 sys.stdout.write("\rBuilding %s %d%%" %
137 (target,
138 build_request.build.completeper()))
139 sys.stdout.flush()
140 time.sleep(1)
141
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500142 self.assertEqual(Build.objects.get(pk=build_pk).outcome,
143 Build.SUCCEEDED,
144 "Build did not SUCCEEDED")
145
146 logger.info("\nBuild finished %s" % build_request.build.outcome)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600147 return build_request.build
148
149 def target_already_built(self, target):
150 """ If the target is already built no need to build it again"""
151 for build in Build.objects.filter(
152 project__name=BuildTest.PROJECT_NAME):
153 targets = build.target_set.values_list('target', flat=True)
154 if target in targets:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500155 return build
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600156
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500157 return None