On 5 May 2016 at 17:21, Michael Wood <[email protected]> wrote:

> 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.
>
> Signed-off-by: Michael Wood <[email protected]>
> ---
>  bitbake/lib/toaster/tests/builds/__init__.py  |   0
>  bitbake/lib/toaster/tests/builds/buildtest.py | 133
> ++++++++++++++++++++++++++
>  2 files changed, 133 insertions(+)
>  create mode 100644 bitbake/lib/toaster/tests/builds/__init__.py
>  create mode 100644 bitbake/lib/toaster/tests/builds/buildtest.py
>
> diff --git a/bitbake/lib/toaster/tests/builds/__init__.py
> b/bitbake/lib/toaster/tests/builds/__init__.py
> new file mode 100644
> index 0000000..e69de29
> diff --git a/bitbake/lib/toaster/tests/builds/buildtest.py
> b/bitbake/lib/toaster/tests/builds/buildtest.py
> new file mode 100644
> index 0000000..6d1037c
> --- /dev/null
> +++ b/bitbake/lib/toaster/tests/builds/buildtest.py
> @@ -0,0 +1,133 @@
> +#! /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 should be set to None here. If not, you get a lot of misleading
errors when the tests fail because toasterconf.json can't be found, like
this:

ERROR: test_custom_packages_generated
(tests.builds.test_core_image_min.BuildCoreImageMinimal)
Test if there is a corresponding generated CustomImagePackage
----------------------------------------------------------------------
Traceback (most recent call last):
  File
"/home/elliot/poky-contrib/bitbake/lib/toaster/tests/builds/test_core_image_min.py",
line 41, in setUp
    self.build("core-image-minimal")
  File
"/home/elliot/poky-contrib/bitbake/lib/toaster/tests/builds/buildtest.py",
line 71, in build
    self.assertIsNotNone(config_file,
UnboundLocalError: local variable 'config_file' referenced before assignment

...rather than the more useful message about setting TOASTER_CONF manually.


> +
> +        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
> --
> 2.7.4
>
> --
> _______________________________________________
> toaster mailing list
> [email protected]
> https://lists.yoctoproject.org/listinfo/toaster
>



-- 
Elliot Smith
Software Engineer
Intel Open Source Technology Centre
-- 
_______________________________________________
toaster mailing list
[email protected]
https://lists.yoctoproject.org/listinfo/toaster

Reply via email to