integration-tests

command
v0.0.0-...-921daf7 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 18, 2016 License: GPL-3.0 Imports: 10 Imported by: 0

README

Integration testing for snappy

The integration tests for snappy are written using gocheck and executed with adt-run through ssh.

The integration-tests/main.go file takes care of executing the tests. By default, it will also provision a snappy virtual machine with ssh enabled, and it will pass the IP of this testbed to adt-run. If you want to provision the testbed on your own or need to run the tests in a remote machine already provisioned, you can specify the IP address and port as explained in the Testing a remote machine section.

Running the tests

Requirements
Setting up the project

First you need to set up the GOPATH, get the snappy sources and the dependencies as explained in the README.md that is located at the root of the branch.

Testing a virtual machine

You can execute the full integration suite in a local virtual machine with:

go run integration-tests/main.go

The test runner will create the snappy images with ubuntu-device-flash, so it will ask for your password to run this command with sudo.

You can also especify more options to customize the image being created, including the release, the channel and the revision to use. This parameters will be passed to ubuntu-device-flash:

go run integration-tests/main.go -release 15.04 -channel stable -revision 3

The default values are suited to testing the most recent version, rolling for release, edge for channel and an empty revision, which picks the latest available.

Testing snappy from a branch

With the --snappy-from-branch flag, the snappy CLI command will be compiled from the current branch, copied to the test bed and used during the integration tests:

go run integration-tests/main.go --snappy-from-branch

You can use this flag to test in a remote machine too.

Filtering the tests to run

With the --filter flag you can select the tests to run. For instance you can pass MyTestSuite, MyTestSuite.FirstCustomTest or MyTestSuite.*CustomTest:

go run integration-tests/main.go --filter MyTestSuite.FirstCustomTest
Testing a remote machine

You can execute the integration suite in a remote snappy machine with:

go run integration-tests/main.go --ip {testbed-ip} --port {testbed-port} \
--arch {testbed-arch}

When running in a remote machine, the test runner assumes the test bed is in the latest rolling edge version, and it will skip all the tests that require a different version. See the following section for instructions for setting up a BeagleBone Black as the test bed.

Testing a BeagleBone Black

First flash the latest rolling edge version into the sd card (replacing /dev/sdX with the path to your card):

sudo ubuntu-device-flash core rolling --channel edge --gadget beagleblack \
--developer-mode --enable-ssh -o ubuntu-rolling-edge-armhf-bbb.img

sudo dd if=ubuntu-rolling-edge-armhf-bbb.img of=/dev/sdX bs=32M
sync

Then boot the board with the sd card, make sure that it is connected to the same network as the test runner host, and find the {beaglebone-ip}.

Run the tests with:

go run integration-tests/main.go --ip {beaglebone-ip} --arch arm
Testing an update

With the --update flag you can flash an old image, update to the latest and then run the whole suite on the updated system. The release, the channel and the revision flags specify the image that will be flashed. There must be an update available for the flashed image.

For example, to update from rolling edge -1 to the latest and then run the integration tests:

go run integration-tests/main.go --snappy-from-branch \
--revision=-1 --update
Testing a rollback

With the --rollback flag you can flash an old image, update to the latest, rollback again to the old image and then run the whole suite on the rolled back system. You should use the release, channel and revision flags as when testing an update.

For example, to test a rollback from latest rolling edge to rolling edge -1:

go run integration-tests/main.go \
--revision=-1 --rollback

Writing a new test

To write a new test, create a file named {something}_test.go in the integration-tests/tests directory. Replace {something} with a useful identifier of what you want to test.

On this file make sure to use the build tag:

// +build !excludeintegration

We use this tag to exclude the integration tests from the unit test runs.

The test suite must extend the common integration suite:

var _ = check.Suite(&somethingSuite{})

type somethingSuite struct {
    common.SnappySuite
}

If for some reason you need to do something on the set up or tear down of the test, always call the methods of the common suite:

func (s *somethingSuite) SetUpTest(c *check.C) {
    s.SnappySuite.SetUpTest(c)
    ...
}

func (s *somethingSuite) TearDownTest(c *check.C) {
    ...
    s.SnappySuite.TearDownTest(c)
}
Tests with reboots

adt-run supports reboots during tests. A test can request a reboot specifying a mark to identify it; adt-run backs up all the test files and the results so far, reboots the test bed, restores the files and results and reruns the test. So a test that requires a reboot is run twice. The test needs to check the reboot mark to know if it must run the steps that go before the reboot, or the steps that go after the reboot.

We write the integration tests in Go and compile a binary for the whole suite. The downside of this is that the whole suite is run before a reboot, and then it is run again after the reboot. We rely on the order of the suite between reboots being always the same, and use the adt reboot mark to identify which test requested the reboot. With this we can know which tests already ran, which is the test that needs to be resumed after the reboot, and which tests are still pending to run. We then use subunit to merge the results of all the executions of the suite.

All of this is implemented in the SetUpTest method of the common Suite, so as long as you are not overwriting it or you are calling it from the overwritten methods (as explained in a previous section), the suite should properly handle the reboots.

In order to tell your test to run a different set of steps before and after the reboot, write it like this:

func (s *somethingSuite) TestSomething(c *check.C) {
    if common.BeforeReboot() {
        ...
        common.Reboot(c)
    } else if common.AfterReboot(c) {
        common.RemoveRebootMark(c)
        ...
    }
}

Always make sure that your test is removing the mark once it handled the reboot.

Some test beds don't support reboots, so the tests that require a reboot must use the build tag:

// +build !excludeintegration,!excludereboots

This allows to exclude the tests that require a reboot by passing excludereboots to the test-build-tags flag:

go run integration-tests/main.go -test-build-tags=excludereboots
Excluding flaky tests on low-performance systems

We have found that some tests give random results on low-performance systems. You can exclude these tests by passing lowperformance to the test-build-tags flag:

go run integration-tests/main.go -test-build-tags=lowperformance

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
cli
tpl

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL