blob: 872bbd3775107d5d64f6d9f1fe91f8aaab984217 [file] [log] [blame]
#! /usr/bin/env python3
#
# BitBake Toaster Implementation
#
# Copyright (C) 2016 Intel Corporation
#
# SPDX-License-Identifier: GPL-2.0-only
#
import os
import sys
import time
import unittest
from orm.models import Project, Release, ProjectTarget, Build, ProjectVariable
from bldcontrol.models import BuildEnvironment
from bldcontrol.management.commands.runbuilds import Command\
as RunBuildsCommand
from django.core.management import call_command
import subprocess
import logging
logger = logging.getLogger("toaster")
# We use unittest.TestCase instead of django.test.TestCase because we don't
# want to wrap everything in a database transaction as an external process
# (bitbake needs access to the database)
def load_build_environment():
call_command('loaddata', 'settings.xml', app_label="orm")
call_command('loaddata', 'poky.xml', app_label="orm")
current_builddir = os.environ.get("BUILDDIR")
if current_builddir:
BuildTest.BUILDDIR = current_builddir
else:
# Setup a builddir based on default layout
# bitbake inside openebedded-core
oe_init_build_env_path = os.path.join(
os.path.dirname(os.path.abspath(__file__)),
os.pardir,
os.pardir,
os.pardir,
os.pardir,
os.pardir,
'oe-init-build-env'
)
if not os.path.exists(oe_init_build_env_path):
raise Exception("We had no BUILDDIR set and couldn't "
"find oe-init-build-env to set this up "
"ourselves please run oe-init-build-env "
"before running these tests")
oe_init_build_env_path = os.path.realpath(oe_init_build_env_path)
cmd = "bash -c 'source oe-init-build-env %s'" % BuildTest.BUILDDIR
p = subprocess.Popen(
cmd,
cwd=os.path.dirname(oe_init_build_env_path),
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
output, err = p.communicate()
p.wait()
logger.info("oe-init-build-env %s %s" % (output, err))
os.environ['BUILDDIR'] = BuildTest.BUILDDIR
# Setup the path to bitbake we know where to find this
bitbake_path = os.path.join(
os.path.dirname(os.path.abspath(__file__)),
os.pardir,
os.pardir,
os.pardir,
os.pardir,
'bin',
'bitbake')
if not os.path.exists(bitbake_path):
raise Exception("Could not find bitbake at the expected path %s"
% bitbake_path)
os.environ['BBBASEDIR'] = bitbake_path
class BuildTest(unittest.TestCase):
PROJECT_NAME = "Testbuild"
BUILDDIR = "/tmp/build/"
def build(self, target):
# So that the buildinfo helper uses the test database'
self.assertEqual(
os.environ.get('DJANGO_SETTINGS_MODULE', ''),
'toastermain.settings_test',
"Please initialise django with the tests settings: "
"DJANGO_SETTINGS_MODULE='toastermain.settings_test'")
built = self.target_already_built(target)
if built:
return built
load_build_environment()
BuildEnvironment.objects.get_or_create(
betype=BuildEnvironment.TYPE_LOCAL,
sourcedir=BuildTest.BUILDDIR,
builddir=BuildTest.BUILDDIR
)
release = Release.objects.get(name='local')
# Create a project for this build to run in
project = Project.objects.create_project(name=BuildTest.PROJECT_NAME,
release=release)
if os.environ.get("TOASTER_TEST_USE_SSTATE_MIRROR"):
ProjectVariable.objects.get_or_create(
name="SSTATE_MIRRORS",
value="file://.* http://autobuilder.yoctoproject.org/pub/sstate/PATH;downloadfilename=PATH",
project=project)
ProjectTarget.objects.create(project=project,
target=target,
task="")
build_request = project.schedule_build()
# run runbuilds command to dispatch the build
# e.g. manage.py runubilds
RunBuildsCommand().runbuild()
build_pk = build_request.build.pk
while Build.objects.get(pk=build_pk).outcome == Build.IN_PROGRESS:
sys.stdout.write("\rBuilding %s %d%%" %
(target,
build_request.build.completeper()))
sys.stdout.flush()
time.sleep(1)
self.assertEqual(Build.objects.get(pk=build_pk).outcome,
Build.SUCCEEDED,
"Build did not SUCCEEDED")
logger.info("\nBuild finished %s" % build_request.build.outcome)
return build_request.build
def target_already_built(self, target):
""" If the target is already built no need to build it again"""
for build in Build.objects.filter(
project__name=BuildTest.PROJECT_NAME):
targets = build.target_set.values_list('target', flat=True)
if target in targets:
return build
return None