mirror of
https://git.yoctoproject.org/poky
synced 2026-05-30 00:20:08 +00:00
bitbake: toaster: tests Add a BuildTest helper class
Add a helper class for running build tests. Subclass this and call the build method to get setup for running tests on the resulting data from a build. (Bitbake rev: d1882371cae6b9a8296ea739e6e46ca6a6dc9da8) Signed-off-by: Michael Wood <michael.g.wood@intel.com> Signed-off-by: Elliot Smith <elliot.smith@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
committed by
Richard Purdie
parent
5ce1adb177
commit
085688c8ed
@@ -0,0 +1,14 @@
|
|||||||
|
# Running build tests
|
||||||
|
|
||||||
|
These tests are to test the running of builds and the data produced by the builds.
|
||||||
|
Your oe build environment must be sourced/initialised for these tests to run.
|
||||||
|
|
||||||
|
The simplest way to run the tests are the following commands:
|
||||||
|
|
||||||
|
$ . oe-init-build-env
|
||||||
|
$ cd lib/toaster/ # path my vary but this is into toaster's directory
|
||||||
|
$ DJANGO_SETTINGS_MODULE='toastermain.settings-test' ./manage.py test tests.builds
|
||||||
|
|
||||||
|
Optional environment variables:
|
||||||
|
- TOASTER_DIR (where toaster keeps it's artifacts)
|
||||||
|
- TOASTER_CONF a path to the toasterconf.json file. This will need to be set if you don't execute the tests from toaster's own directory.
|
||||||
@@ -0,0 +1,134 @@
|
|||||||
|
#! /usr/bin/env python
|
||||||
|
# ex:ts=4:sw=4:sts=4:et
|
||||||
|
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
|
||||||
|
#
|
||||||
|
# BitBake Toaster Implementation
|
||||||
|
#
|
||||||
|
# Copyright (C) 2016 Intel Corporation
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License version 2 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along
|
||||||
|
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
from orm.models import Project, Release, ProjectTarget, Build
|
||||||
|
from bldcontrol.models import BuildEnvironment
|
||||||
|
|
||||||
|
from bldcontrol.management.commands.loadconf import Command\
|
||||||
|
as LoadConfigCommand
|
||||||
|
|
||||||
|
from bldcontrol.management.commands.runbuilds import Command\
|
||||||
|
as RunBuildsCommand
|
||||||
|
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
# 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)
|
||||||
|
|
||||||
|
|
||||||
|
class BuildTest(unittest.TestCase):
|
||||||
|
|
||||||
|
PROJECT_NAME = "Testbuild"
|
||||||
|
|
||||||
|
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'")
|
||||||
|
|
||||||
|
if self.target_already_built(target):
|
||||||
|
return
|
||||||
|
|
||||||
|
# Take a guess at the location of the toasterconf
|
||||||
|
poky_toaster_conf = '../../../meta-poky/conf/toasterconf.json'
|
||||||
|
oe_toaster_conf = '../../../meta/conf/toasterconf.json'
|
||||||
|
env_toaster_conf = os.environ.get('TOASTER_CONF')
|
||||||
|
|
||||||
|
config_file = None
|
||||||
|
if env_toaster_conf:
|
||||||
|
config_file = env_toaster_conf
|
||||||
|
else:
|
||||||
|
if os.path.exists(poky_toaster_conf):
|
||||||
|
config_file = poky_toaster_conf
|
||||||
|
elif os.path.exists(oe_toaster_conf):
|
||||||
|
config_file = oe_toaster_conf
|
||||||
|
|
||||||
|
self.assertIsNotNone(config_file,
|
||||||
|
"Default locations for toasterconf not found"
|
||||||
|
"please set $TOASTER_CONF manually")
|
||||||
|
|
||||||
|
# Setup the release information and default layers
|
||||||
|
print("\nImporting file: %s" % config_file)
|
||||||
|
os.environ['TOASTER_CONF'] = config_file
|
||||||
|
LoadConfigCommand()._import_layer_config(config_file)
|
||||||
|
|
||||||
|
os.environ['TOASTER_DIR'] = \
|
||||||
|
os.path.abspath(os.environ['BUILDDIR'] + "/../")
|
||||||
|
|
||||||
|
os.environ['BBBASEDIR'] = \
|
||||||
|
subprocess.check_output('which bitbake', shell=True)
|
||||||
|
|
||||||
|
BuildEnvironment.objects.get_or_create(
|
||||||
|
betype=BuildEnvironment.TYPE_LOCAL,
|
||||||
|
sourcedir=os.environ['TOASTER_DIR'],
|
||||||
|
builddir=os.environ['BUILDDIR']
|
||||||
|
)
|
||||||
|
|
||||||
|
release = Release.objects.get(name='local')
|
||||||
|
|
||||||
|
# Create a project for this build to run in
|
||||||
|
try:
|
||||||
|
project = Project.objects.get(name=BuildTest.PROJECT_NAME)
|
||||||
|
except Project.DoesNotExist:
|
||||||
|
project = Project.objects.create_project(
|
||||||
|
name=BuildTest.PROJECT_NAME,
|
||||||
|
release=release
|
||||||
|
)
|
||||||
|
|
||||||
|
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.assertNotEqual(build_request.build.outcome,
|
||||||
|
Build.SUCCEEDED, "Build did not SUCCEEDED")
|
||||||
|
print("\nBuild finished")
|
||||||
|
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 True
|
||||||
|
|
||||||
|
return False
|
||||||
Reference in New Issue
Block a user