Merge lp:~elopio/snappy/15.04-backport-integration into lp:~snappy-dev/snappy/15.04-deprecated

Proposed by Leo Arias
Status: Superseded
Proposed branch: lp:~elopio/snappy/15.04-backport-integration
Merge into: lp:~snappy-dev/snappy/15.04-deprecated
Diff against target: 3484 lines (+2665/-70)
78 files modified
_integration-tests/README.md (+117/-0)
_integration-tests/data/snaps/basic/meta/package.yaml (+4/-0)
_integration-tests/data/snaps/basic/meta/readme.md (+3/-0)
_integration-tests/data/snaps/missing-readme/meta/package.yaml (+4/-0)
_integration-tests/data/snaps/wrong-yaml/meta/package.yaml (+5/-0)
_integration-tests/data/snaps/wrong-yaml/meta/readme.md (+3/-0)
_integration-tests/data/tpl/control (+4/-0)
_integration-tests/main.go (+105/-0)
_integration-tests/reboot-wrapper (+35/-0)
_integration-tests/tests/apt_test.go (+39/-0)
_integration-tests/tests/base_test.go (+29/-0)
_integration-tests/tests/build_test.go (+90/-0)
_integration-tests/tests/failover_rclocal_crash_test.go (+54/-0)
_integration-tests/tests/failover_systemd_loop_test.go (+114/-0)
_integration-tests/tests/failover_test.go (+58/-0)
_integration-tests/tests/failover_zero_size_file_test.go (+258/-0)
_integration-tests/tests/info_test.go (+79/-0)
_integration-tests/tests/installApp_test.go (+128/-0)
_integration-tests/tests/installFramework_test.go (+93/-0)
_integration-tests/tests/list_test.go (+78/-0)
_integration-tests/tests/rollback_test.go (+53/-0)
_integration-tests/tests/search_test.go (+44/-0)
_integration-tests/tests/update_test.go (+51/-0)
_integration-tests/tests/writablePaths_test.go (+106/-0)
_integration-tests/testutils/autopkgtest/autopkgtest.go (+111/-0)
_integration-tests/testutils/autopkgtest/ssh.go (+46/-0)
_integration-tests/testutils/build/build.go (+76/-0)
_integration-tests/testutils/common/common.go (+379/-0)
_integration-tests/testutils/common/common_test.go (+68/-0)
_integration-tests/testutils/config/config.go (+75/-0)
_integration-tests/testutils/config/config_test.go (+121/-0)
_integration-tests/testutils/image/image.go (+86/-0)
_integration-tests/testutils/testutils.go (+61/-0)
clickdeb/deb_test.go (+2/-2)
cmd/snappy/cmd_low_level_unpack_test.go (+1/-1)
cmd/snappy/cmd_set_test.go (+2/-2)
coreconfig/config_test.go (+2/-2)
debian/control (+1/-1)
dependencies.tsv (+1/-1)
helpers/cmp_test.go (+1/-1)
helpers/helpers_test.go (+1/-1)
helpers/touch_test.go (+1/-1)
logger/logger_test.go (+1/-1)
oauth/oauth_test.go (+1/-1)
partition/bootloader_grub_test.go (+1/-1)
partition/bootloader_uboot_test.go (+1/-1)
partition/partition_test.go (+2/-2)
partition/utils_test.go (+1/-1)
policy/policy_test.go (+3/-2)
priv/priv_test.go (+1/-1)
progress/progress_test.go (+2/-2)
release/release_test.go (+2/-2)
run-checks (+19/-3)
snappy/auth_test.go (+13/-13)
snappy/build_test.go (+1/-1)
snappy/click_test.go (+2/-2)
snappy/common_test.go (+3/-2)
snappy/config_test.go (+1/-1)
snappy/datadir_test.go (+1/-1)
snappy/dbus_test.go (+1/-1)
snappy/firstboot_test.go (+1/-1)
snappy/hashes_test.go (+1/-1)
snappy/hwaccess_test.go (+1/-1)
snappy/install_test.go (+1/-1)
snappy/oem_test.go (+1/-1)
snappy/parts_test.go (+1/-1)
snappy/purge_test.go (+1/-1)
snappy/remove_test.go (+1/-1)
snappy/rollback_test.go (+1/-1)
snappy/security_test.go (+1/-1)
snappy/set_test.go (+1/-1)
snappy/snapp_test.go (+1/-1)
snappy/sort_test.go (+1/-1)
snappy/systemimage_native_test.go (+1/-1)
snappy/systemimage_test.go (+2/-2)
snappy/timeout_test.go (+1/-1)
snappy/udev_test.go (+1/-1)
systemd/systemd_test.go (+2/-2)
To merge this branch: bzr merge lp:~elopio/snappy/15.04-backport-integration
Reviewer Review Type Date Requested Status
Federico Gimenez (community) tested Approve
Review via email: mp+266015@code.launchpad.net

This proposal has been superseded by a proposal from 2015-08-02.

Commit message

Backported the integration tests.

To post a comment you must log in.
Revision history for this message
Leo Arias (elopio) wrote :

Work in progress because we want to land this after the current release. But this is working, ready to be tested.

Revision history for this message
Federico Gimenez (fgimenez) wrote :

Thanks for this Leo, leaving my approval here

review: Approve (tested)
Revision history for this message
Federico Gimenez (fgimenez) wrote :

There's a problem with the gocheck dependency, the installed package name doesn't match the import name [1]. We should modify also dependencies.tsv.

Thanks!

[1] http://10.55.61.165:8080/job/snappy-integration-tests-canonistack-1504-edge/14/console

466. By Leo Arias

update runcheck

467. By Leo Arias

Updated from trunk.

468. By Leo Arias

Added the testutils dir.

469. By Leo Arias

Merged with prerequisite.

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added directory '_integration-tests'
2=== added file '_integration-tests/README.md'
3--- _integration-tests/README.md 1970-01-01 00:00:00 +0000
4+++ _integration-tests/README.md 2015-08-02 12:28:18 +0000
5@@ -0,0 +1,117 @@
6+# Integration testing for snappy
7+
8+## Requirements
9+
10+ * autopkgtest (>= 3.15.1)
11+
12+ Get the latest autopkgtest deb from
13+ https://packages.debian.org/sid/all/autopkgtest/download
14+
15+ * Internet access in the test bed.
16+
17+## Setting up the project
18+
19+First you need to set up the GOPATH, get the snappy sources and the
20+dependencies as explained in the `README.md` that is located at the root of the
21+branch.
22+
23+## Testing a virtual machine
24+
25+You can execute the full integration suite in a local virtual machine with:
26+
27+ go run _integration-tests/main.go
28+
29+The test runner will create the snappy images with `ubuntu-device-flash`, so it
30+will ask for your password to run this command with `sudo`.
31+
32+You can also especify more options to customize the image being created, including
33+the release, the channel and the revision to use. This parameters will be passed
34+to `ubuntu-device-flash`:
35+
36+ go run _integration-tests/main.go -release 15.04 -channel stable -revision 3
37+
38+The default values are suited to testing the most recent version, `rolling` for
39+release, `edge` for channel and an empty revision, which picks the latest
40+available.
41+
42+## Testing snappy from a branch
43+
44+With the --snappy-from-branch flag, the snappy CLI command will be compiled
45+from the current branch, copied to the test bed and used during the integration
46+tests:
47+
48+ go run _integration-tests/main.go --snappy-from-branch
49+
50+You can use this flag to test in a remote machine too.
51+
52+## Filtering the tests to run
53+
54+With the --filter flag you can select the tests to run. For instance you can
55+pass MyTestSuite, MyTestSuite.FirstCustomTest or MyTestSuite.*CustomTest:
56+
57+ go run _integration-tests/main.go --filter MyTestSuite.FirstCustomTest
58+
59+## Testing a remote machine
60+
61+You can execute the integration suite in a remote snappy machine with:
62+
63+ go run _integration-tests/main.go --ip {testbed-ip} --port {testbed-port} \
64+ --arch {testbed-arch}
65+
66+The test runner will use `ssh-copy-id` to send your identity file to the
67+testbed, so it will ask for the password of the ubuntu user in the test bed.
68+
69+When running in a remote machine, the test runner assumes the test bed is in
70+the latest rolling edge version, and it will skip all the tests that
71+require a different version. See the following section for instructions for
72+setting up a BeagleBone Black as the test bed.
73+
74+## Testing a BeagleBone Black
75+
76+First flash the latest 15.04 edge version into the sd card
77+(replacing /dev/sdX with the path to your card):
78+
79+ sudo ubuntu-device-flash core 15.04 --channel edge --oem beagleblack \
80+ --developer-mode --enable-ssh -o ubuntu-15.04-edge-armhf-bbb.img
81+
82+ sudo dd if=ubuntu-15.04-edge-armhf-bbb.img of=/dev/sdX bs=32M
83+ sync
84+
85+Then boot the board with the sd card, make sure that it is connected to the
86+same network as the test runner host, and find the {beaglebone-ip}.
87+
88+Run the tests with:
89+
90+ go run _integration-tests/main.go --ip {beaglebone-ip} --arch arm
91+
92+## Testing an update
93+
94+With the --update flag you can flash an old image, update to the latest and
95+then run the whole suite on the updated system. The release, the channel and
96+the revision flags specify the image that will be flashed, and the
97+target-release and target-channel flags specify the values to be used in the
98+update if they are different from the flashed values.
99+
100+For example, to update from 15.04 edge -1 to the latest and then run the
101+integration tests:
102+
103+ go run _integration-tests/main.go --snappy-from-branch \
104+ --release=15.04 --revision=-1 --update
105+
106+To update from 15.04 alpha to 15.04 edge and then run the integration tests:
107+
108+ go run _integration-tests/main.go --snappy-from-branch \
109+ --release=15.04 --channel=alpha \
110+ --update --target-channel=edge
111+
112+## Testing a rollback
113+
114+With the --rollback flag you can flash an old image, update to the latest,
115+rollback again to the old image and then run the whole suite on the rolled
116+back system. You should use the release, channel, revision, target-release and
117+target-channel flags as when testing an update.
118+
119+For example, to test a rollback from latest 15.04 edge to 15.04 edge -1:
120+
121+ go run _integration-tests/main.go \
122+ --release=15.04 --revision=-1 --rollback
123
124=== added directory '_integration-tests/data'
125=== added directory '_integration-tests/data/snaps'
126=== added directory '_integration-tests/data/snaps/basic'
127=== added directory '_integration-tests/data/snaps/basic/meta'
128=== added file '_integration-tests/data/snaps/basic/meta/package.yaml'
129--- _integration-tests/data/snaps/basic/meta/package.yaml 1970-01-01 00:00:00 +0000
130+++ _integration-tests/data/snaps/basic/meta/package.yaml 2015-08-02 12:28:18 +0000
131@@ -0,0 +1,4 @@
132+name: basic
133+version: 1.0
134+vendor: Snappy Developers <snappy-devel@lists.ubuntu.com>
135+icon: meta/snappy64.png
136
137=== added file '_integration-tests/data/snaps/basic/meta/readme.md'
138--- _integration-tests/data/snaps/basic/meta/readme.md 1970-01-01 00:00:00 +0000
139+++ _integration-tests/data/snaps/basic/meta/readme.md 2015-08-02 12:28:18 +0000
140@@ -0,0 +1,3 @@
141+Basic snap
142+
143+A basic buildable snap
144
145=== added file '_integration-tests/data/snaps/basic/meta/snappy64.png'
146Binary files _integration-tests/data/snaps/basic/meta/snappy64.png 1970-01-01 00:00:00 +0000 and _integration-tests/data/snaps/basic/meta/snappy64.png 2015-08-02 12:28:18 +0000 differ
147=== added directory '_integration-tests/data/snaps/missing-readme'
148=== added directory '_integration-tests/data/snaps/missing-readme/meta'
149=== added file '_integration-tests/data/snaps/missing-readme/meta/package.yaml'
150--- _integration-tests/data/snaps/missing-readme/meta/package.yaml 1970-01-01 00:00:00 +0000
151+++ _integration-tests/data/snaps/missing-readme/meta/package.yaml 2015-08-02 12:28:18 +0000
152@@ -0,0 +1,4 @@
153+name: missing-readme
154+version: 1.0
155+vendor: Snappy Developers <snappy-devel@lists.ubuntu.com>
156+icon: meta/snappy64.png
157
158=== added file '_integration-tests/data/snaps/missing-readme/meta/snappy64.png'
159Binary files _integration-tests/data/snaps/missing-readme/meta/snappy64.png 1970-01-01 00:00:00 +0000 and _integration-tests/data/snaps/missing-readme/meta/snappy64.png 2015-08-02 12:28:18 +0000 differ
160=== added directory '_integration-tests/data/snaps/wrong-yaml'
161=== added directory '_integration-tests/data/snaps/wrong-yaml/meta'
162=== added file '_integration-tests/data/snaps/wrong-yaml/meta/package.yaml'
163--- _integration-tests/data/snaps/wrong-yaml/meta/package.yaml 1970-01-01 00:00:00 +0000
164+++ _integration-tests/data/snaps/wrong-yaml/meta/package.yaml 2015-08-02 12:28:18 +0000
165@@ -0,0 +1,5 @@
166+# This is an invalid yaml, there's a missing colon after the 'name' field
167+name wrong-yaml
168+version: 1.0
169+vendor: Snappy Developers <snappy-devel@lists.ubuntu.com>
170+icon: meta/snappy64.png
171
172=== added file '_integration-tests/data/snaps/wrong-yaml/meta/readme.md'
173--- _integration-tests/data/snaps/wrong-yaml/meta/readme.md 1970-01-01 00:00:00 +0000
174+++ _integration-tests/data/snaps/wrong-yaml/meta/readme.md 2015-08-02 12:28:18 +0000
175@@ -0,0 +1,3 @@
176+Wrong metadata snap
177+
178+A snap with an invalid meta/package.yaml
179
180=== added file '_integration-tests/data/snaps/wrong-yaml/meta/snappy64.png'
181Binary files _integration-tests/data/snaps/wrong-yaml/meta/snappy64.png 1970-01-01 00:00:00 +0000 and _integration-tests/data/snaps/wrong-yaml/meta/snappy64.png 2015-08-02 12:28:18 +0000 differ
182=== added directory '_integration-tests/data/tpl'
183=== added file '_integration-tests/data/tpl/control'
184--- _integration-tests/data/tpl/control 1970-01-01 00:00:00 +0000
185+++ _integration-tests/data/tpl/control 2015-08-02 12:28:18 +0000
186@@ -0,0 +1,4 @@
187+{{ $filter := .Filter }}
188+{{ $test := .Test }}
189+Test-Command: ./_integration-tests/reboot-wrapper {{ $test }} {{ if $filter }}-gocheck.f {{ $filter }}{{ end }}
190+Restrictions: allow-stderr
191
192=== added file '_integration-tests/main.go'
193--- _integration-tests/main.go 1970-01-01 00:00:00 +0000
194+++ _integration-tests/main.go 2015-08-02 12:28:18 +0000
195@@ -0,0 +1,105 @@
196+// -*- Mode: Go; indent-tabs-mode: t -*-
197+
198+/*
199+ * Copyright (C) 2015 Canonical Ltd
200+ *
201+ * This program is free software: you can redistribute it and/or modify
202+ * it under the terms of the GNU General Public License version 3 as
203+ * published by the Free Software Foundation.
204+ *
205+ * This program is distributed in the hope that it will be useful,
206+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
207+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
208+ * GNU General Public License for more details.
209+ *
210+ * You should have received a copy of the GNU General Public License
211+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
212+ *
213+ */
214+
215+package main
216+
217+import (
218+ "flag"
219+ "log"
220+ "os"
221+ "path/filepath"
222+ "strconv"
223+
224+ "launchpad.net/snappy/_integration-tests/testutils"
225+ "launchpad.net/snappy/_integration-tests/testutils/autopkgtest"
226+ "launchpad.net/snappy/_integration-tests/testutils/build"
227+ "launchpad.net/snappy/_integration-tests/testutils/config"
228+ "launchpad.net/snappy/_integration-tests/testutils/image"
229+)
230+
231+const (
232+ baseDir = "/tmp/snappy-test"
233+ defaultRelease = "rolling"
234+ defaultChannel = "edge"
235+ defaultSSHPort = 22
236+ dataOutputDir = "_integration-tests/data/output/"
237+)
238+
239+var configFileName = filepath.Join(dataOutputDir, "testconfig.json")
240+
241+func main() {
242+ var (
243+ useSnappyFromBranch = flag.Bool("snappy-from-branch", false,
244+ "If this flag is used, snappy will be compiled from this branch, copied to the testbed and used for the tests. Otherwise, the snappy installed with the image will be used.")
245+ arch = flag.String("arch", "",
246+ "Architecture of the test bed. Defaults to use the same architecture as the host.")
247+ testbedIP = flag.String("ip", "",
248+ "IP of the testbed. If no IP is passed, a virtual machine will be created for the test.")
249+ testbedPort = flag.Int("port", defaultSSHPort,
250+ "SSH port of the testbed. Defaults to use port "+strconv.Itoa(defaultSSHPort))
251+ testFilter = flag.String("filter", "",
252+ "Suites or tests to run, for instance MyTestSuite, MyTestSuite.FirstCustomTest or MyTestSuite.*CustomTest")
253+ imgRelease = flag.String("release", defaultRelease,
254+ "Release of the image to be built, defaults to "+defaultRelease)
255+ imgChannel = flag.String("channel", defaultChannel,
256+ "Channel of the image to be built, defaults to "+defaultChannel)
257+ imgRevision = flag.String("revision", "",
258+ "Revision of the image to be built (can be relative to the latest available revision in the given release and channel as in -1), defaults to the empty string")
259+ update = flag.Bool("update", false,
260+ "If this flag is used, the image will be updated before running the tests.")
261+ targetRelease = flag.String("target-release", "",
262+ "If the update flag is used, the image will be updated to this release before running the tests.")
263+ targetChannel = flag.String("target-channel", "",
264+ "If the update flag is used, the image will be updated to this channel before running the tests.")
265+ rollback = flag.Bool("rollback", false,
266+ "If this flag is used, the image will be updated and then rolled back before running the tests.")
267+ )
268+
269+ flag.Parse()
270+
271+ build.Assets(*useSnappyFromBranch, *arch)
272+
273+ // TODO: generate the files out of the source tree. --elopio - 2015-07-15
274+ testutils.PrepareTargetDir(dataOutputDir)
275+ defer os.RemoveAll(dataOutputDir)
276+
277+ remoteTestbed := *testbedIP != ""
278+
279+ // TODO: pass the config as arguments to the test binaries.
280+ // --elopio - 2015-07-15
281+ cfg := config.NewConfig(
282+ configFileName, *imgRelease, *imgChannel, *targetRelease, *targetChannel,
283+ remoteTestbed, *update, *rollback)
284+ cfg.Write()
285+
286+ rootPath := testutils.RootPath()
287+
288+ test := autopkgtest.NewAutopkgtest(rootPath, baseDir, *testFilter, build.IntegrationTestName)
289+ if !remoteTestbed {
290+ img := image.NewImage(*imgRelease, *imgChannel, *imgRevision, baseDir)
291+
292+ if imagePath, err := img.UdfCreate(); err == nil {
293+ test.AdtRunLocal(imagePath)
294+ } else {
295+ log.Panic(err.Error())
296+ }
297+ } else {
298+ test.AdtRunRemote(*testbedIP, *testbedPort)
299+ }
300+}
301
302=== added file '_integration-tests/reboot-wrapper'
303--- _integration-tests/reboot-wrapper 1970-01-01 00:00:00 +0000
304+++ _integration-tests/reboot-wrapper 2015-08-02 12:28:18 +0000
305@@ -0,0 +1,35 @@
306+#!/bin/sh
307+
308+# Copyright (C) 2015 Canonical Ltd
309+#
310+# This program is free software: you can redistribute it and/or modify
311+# it under the terms of the GNU General Public License version 3 as
312+# published by the Free Software Foundation.
313+#
314+# This program is distributed in the hope that it will be useful,
315+# but WITHOUT ANY WARRANTY; without even the implied warranty of
316+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
317+# GNU General Public License for more details.
318+#
319+# You should have received a copy of the GNU General Public License
320+# along with this program. If not, see <http://www.gnu.org/licenses/>.
321+
322+# This runs the $1 go test binary and reboots if necessary.
323+
324+set -e
325+
326+TEST=$1
327+NEEDS_REBOOT=/tmp/needs-reboot
328+
329+export PATH=$(pwd)/_integration-tests/bin:$PATH
330+
331+# shift to remove the test binary name (first argument) and be able to pass the rest
332+# of them to it
333+shift
334+${TEST} -check.vv -test.outputdir=$ADT_ARTIFACTS-$ADT_REBOOT_MARK "$@"
335+
336+if [ -e ${NEEDS_REBOOT} ]; then
337+ mark=`cat ${NEEDS_REBOOT}`
338+ echo "Rebooting..."
339+ sudo /tmp/autopkgtest-reboot "$mark"
340+fi
341
342=== added directory '_integration-tests/tests'
343=== added file '_integration-tests/tests/apt_test.go'
344--- _integration-tests/tests/apt_test.go 1970-01-01 00:00:00 +0000
345+++ _integration-tests/tests/apt_test.go 2015-08-02 12:28:18 +0000
346@@ -0,0 +1,39 @@
347+// -*- Mode: Go; indent-tabs-mode: t -*-
348+
349+/*
350+ * Copyright (C) 2015 Canonical Ltd
351+ *
352+ * This program is free software: you can redistribute it and/or modify
353+ * it under the terms of the GNU General Public License version 3 as
354+ * published by the Free Software Foundation.
355+ *
356+ * This program is distributed in the hope that it will be useful,
357+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
358+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
359+ * GNU General Public License for more details.
360+ *
361+ * You should have received a copy of the GNU General Public License
362+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
363+ *
364+ */
365+
366+package tests
367+
368+import (
369+ . "launchpad.net/snappy/_integration-tests/testutils/common"
370+
371+ check "gopkg.in/check.v1"
372+)
373+
374+var _ = check.Suite(&aptSuite{})
375+
376+type aptSuite struct {
377+ SnappySuite
378+}
379+
380+func (s *aptSuite) TestAptGetMustPrintError(c *check.C) {
381+ aptOutput := ExecCommand(c, "apt-get", "update")
382+
383+ expected := "Ubuntu Core does not use apt-get, see 'snappy --help'!\n"
384+ c.Assert(aptOutput, check.Equals, expected)
385+}
386
387=== added file '_integration-tests/tests/base_test.go'
388--- _integration-tests/tests/base_test.go 1970-01-01 00:00:00 +0000
389+++ _integration-tests/tests/base_test.go 2015-08-02 12:28:18 +0000
390@@ -0,0 +1,29 @@
391+// -*- Mode: Go; indent-tabs-mode: t -*-
392+
393+/*
394+ * Copyright (C) 2015 Canonical Ltd
395+ *
396+ * This program is free software: you can redistribute it and/or modify
397+ * it under the terms of the GNU General Public License version 3 as
398+ * published by the Free Software Foundation.
399+ *
400+ * This program is distributed in the hope that it will be useful,
401+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
402+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
403+ * GNU General Public License for more details.
404+ *
405+ * You should have received a copy of the GNU General Public License
406+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
407+ *
408+ */
409+
410+package tests
411+
412+import (
413+ "testing"
414+
415+ . "gopkg.in/check.v1"
416+)
417+
418+// Hook up gocheck into the "go test" runner.
419+func Test(t *testing.T) { TestingT(t) }
420
421=== added file '_integration-tests/tests/build_test.go'
422--- _integration-tests/tests/build_test.go 1970-01-01 00:00:00 +0000
423+++ _integration-tests/tests/build_test.go 2015-08-02 12:28:18 +0000
424@@ -0,0 +1,90 @@
425+// -*- Mode: Go; indent-tabs-mode: t -*-
426+
427+/*
428+ * Copyright (C) 2015 Canonical Ltd
429+ *
430+ * This program is free software: you can redistribute it and/or modify
431+ * it under the terms of the GNU General Public License version 3 as
432+ * published by the Free Software Foundation.
433+ *
434+ * This program is distributed in the hope that it will be useful,
435+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
436+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
437+ * GNU General Public License for more details.
438+ *
439+ * You should have received a copy of the GNU General Public License
440+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
441+ *
442+ */
443+
444+package tests
445+
446+import (
447+ "fmt"
448+ "os"
449+ "os/exec"
450+
451+ . "launchpad.net/snappy/_integration-tests/testutils/common"
452+
453+ . "gopkg.in/check.v1"
454+)
455+
456+const (
457+ baseSnapPath = "_integration-tests/data/snaps"
458+ basicSnapName = "basic"
459+ wrongYamlSnapName = "wrong-yaml"
460+ missingReadmeSnapName = "missing-readme"
461+)
462+
463+var _ = Suite(&buildSuite{})
464+
465+type buildSuite struct {
466+ SnappySuite
467+}
468+
469+func buildSnap(c *C, snapPath string) string {
470+ return ExecCommand(c, "snappy", "build", snapPath)
471+}
472+
473+func (s *buildSuite) TestBuildBasicSnapOnSnappy(c *C) {
474+ // build basic snap and check output
475+ snapPath := baseSnapPath + "/" + basicSnapName
476+ buildOutput := buildSnap(c, snapPath)
477+ snapName := basicSnapName + "_1.0_all.snap"
478+ expected := fmt.Sprintf("Generated '%s' snap\n", snapName)
479+ c.Check(buildOutput, Equals, expected)
480+ defer os.Remove(snapPath + "/" + snapName)
481+
482+ // install built snap and check output
483+ installOutput := InstallSnap(c, snapName)
484+ defer RemoveSnap(c, basicSnapName)
485+ expected = "(?ms)" +
486+ "Installing " + snapName + "\n" +
487+ ".*Signature check failed, but installing anyway as requested\n" +
488+ "Name +Date +Version +Developer \n" +
489+ ".*\n" +
490+ basicSnapName + " +.* +.* +sideload \n" +
491+ ".*\n"
492+
493+ c.Check(installOutput, Matches, expected)
494+
495+ // teardown, remove snap file
496+ c.Assert(os.Remove(snapName), IsNil, Commentf("Error removing %s", snapName))
497+}
498+
499+func (s *buildSuite) TestBuildWrongYamlSnapOnSnappy(c *C) {
500+ commonWrongTest(c, wrongYamlSnapName, "(?msi).*Can not parse.*yaml: line 2: mapping values are not allowed in this context.*")
501+}
502+
503+func (s *buildSuite) TestBuildMissingReadmeSnapOnSnappy(c *C) {
504+ commonWrongTest(c, missingReadmeSnapName, ".*readme.md: no such file or directory\n")
505+}
506+
507+func commonWrongTest(c *C, testName, expected string) {
508+ // build wrong snap and check output
509+ cmd := exec.Command("snappy", "build", fmt.Sprintf("%s/%s", baseSnapPath, testName))
510+ echoOutput, err := cmd.CombinedOutput()
511+ c.Assert(err, NotNil, Commentf("%s should not be built", testName))
512+
513+ c.Assert(string(echoOutput), Matches, expected)
514+}
515
516=== added file '_integration-tests/tests/failover_rclocal_crash_test.go'
517--- _integration-tests/tests/failover_rclocal_crash_test.go 1970-01-01 00:00:00 +0000
518+++ _integration-tests/tests/failover_rclocal_crash_test.go 2015-08-02 12:28:18 +0000
519@@ -0,0 +1,54 @@
520+// -*- Mode: Go; indent-tabs-mode: t -*-
521+
522+/*
523+ * Copyright (C) 2015 Canonical Ltd
524+ *
525+ * This program is free software: you can redistribute it and/or modify
526+ * it under the terms of the GNU General Public License version 3 as
527+ * published by the Free Software Foundation.
528+ *
529+ * This program is distributed in the hope that it will be useful,
530+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
531+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
532+ * GNU General Public License for more details.
533+ *
534+ * You should have received a copy of the GNU General Public License
535+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
536+ *
537+ */
538+
539+package tests
540+
541+import (
542+ "fmt"
543+
544+ . "launchpad.net/snappy/_integration-tests/testutils/common"
545+
546+ check "gopkg.in/check.v1"
547+)
548+
549+type rcLocalCrash struct{}
550+
551+func (rcLocalCrash) set(c *check.C) {
552+ MakeWritable(c, BaseAltPartitionPath)
553+ defer MakeReadonly(c, BaseAltPartitionPath)
554+ targetFile := fmt.Sprintf("%s/etc/rc.local", BaseAltPartitionPath)
555+ ExecCommand(c, "sudo", "chmod", "a+xw", targetFile)
556+ ExecCommandToFile(c, targetFile,
557+ "sudo", "echo", "#!bin/sh\nprintf c > /proc/sysrq-trigger")
558+}
559+
560+func (rcLocalCrash) unset(c *check.C) {
561+ MakeWritable(c, BaseAltPartitionPath)
562+ defer MakeReadonly(c, BaseAltPartitionPath)
563+ ExecCommand(c, "sudo", "rm", fmt.Sprintf("%s/etc/rc.local", BaseAltPartitionPath))
564+}
565+
566+/*
567+TODO: uncomment when bug https://bugs.launchpad.net/snappy/+bug/1476129 is fixed
568+(fgimenez 20150728)
569+
570+func (s *failoverSuite) TestRCLocalCrash(c *check.C) {
571+ commonFailoverTest(c, rcLocalCrash{})
572+}
573+*/
574
575=== added file '_integration-tests/tests/failover_systemd_loop_test.go'
576--- _integration-tests/tests/failover_systemd_loop_test.go 1970-01-01 00:00:00 +0000
577+++ _integration-tests/tests/failover_systemd_loop_test.go 2015-08-02 12:28:18 +0000
578@@ -0,0 +1,114 @@
579+// -*- Mode: Go; indent-tabs-mode: t -*-
580+
581+/*
582+ * Copyright (C) 2015 Canonical Ltd
583+ *
584+ * This program is free software: you can redistribute it and/or modify
585+ * it under the terms of the GNU General Public License version 3 as
586+ * published by the Free Software Foundation.
587+ *
588+ * This program is distributed in the hope that it will be useful,
589+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
590+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
591+ * GNU General Public License for more details.
592+ *
593+ * You should have received a copy of the GNU General Public License
594+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
595+ *
596+ */
597+
598+package tests
599+
600+import (
601+ "fmt"
602+
603+ . "launchpad.net/snappy/_integration-tests/testutils/common"
604+
605+ check "gopkg.in/check.v1"
606+)
607+
608+const (
609+ deadlockService = `[Unit]
610+Before=sysinit.target
611+DefaultDependencies=no
612+
613+[Service]
614+Type=oneshot
615+ExecStartPre=-/bin/sh -c "echo 'DEBUG: $(date): deadlocked system' >/dev/console"
616+ExecStartPre=-/bin/sh -c "echo 'DEBUG: $(date): deadlocked system' >/dev/ttyS0"
617+ExecStart=/bin/systemctl start deadlock.service
618+RemainAfterExit=yes
619+
620+[Install]
621+RequiredBy=sysinit.target
622+`
623+ rebootService = `[Unit]
624+DefaultDependencies=no
625+Description=Hack to force reboot if booting did not finish after 20s
626+
627+[Service]
628+Type=oneshot
629+ExecStartPre=/bin/sleep 20
630+ExecStart=-/bin/sh -c 'if ! systemctl is-active default.target; then wall "EMERGENCY REBOOT"; reboot -f; fi'
631+
632+[Install]
633+RequiredBy=sysinit.target
634+`
635+ baseSystemdPath = "/lib/systemd/system"
636+ systemdTargetRequiresDir = "sysinit.target.requires"
637+)
638+
639+type systemdDependencyLoop struct{}
640+
641+func (systemdDependencyLoop) set(c *check.C) {
642+ installService(c, "deadlock", deadlockService, BaseAltPartitionPath)
643+ installService(c, "emerg-reboot", rebootService, BaseAltPartitionPath)
644+}
645+
646+func (systemdDependencyLoop) unset(c *check.C) {
647+ unInstallService(c, "deadlock", BaseAltPartitionPath)
648+ unInstallService(c, "emerg-reboot", BaseAltPartitionPath)
649+}
650+
651+func installService(c *check.C, serviceName, serviceCfg, basePath string) {
652+ MakeWritable(c, basePath)
653+ defer MakeReadonly(c, basePath)
654+
655+ // Create service file
656+ serviceFile := fmt.Sprintf("%s%s/%s.service", basePath, baseSystemdPath, serviceName)
657+ ExecCommand(c, "sudo", "chmod", "a+w", fmt.Sprintf("%s%s", basePath, baseSystemdPath))
658+ ExecCommandToFile(c, serviceFile, "sudo", "echo", serviceCfg)
659+
660+ // Create requires directory
661+ requiresDirPart := fmt.Sprintf("%s/%s", baseSystemdPath, systemdTargetRequiresDir)
662+ requiresDir := fmt.Sprintf("%s%s", basePath, requiresDirPart)
663+ ExecCommand(c, "sudo", "mkdir", "-p", requiresDir)
664+
665+ // Symlink from the requires dir to the service file (with chroot for being
666+ // usable in the other partition)
667+ ExecCommand(c, "sudo", "chroot", basePath, "ln", "-s",
668+ fmt.Sprintf("%s/%s.service", baseSystemdPath, serviceName),
669+ fmt.Sprintf("%s/%s.service", requiresDirPart, serviceName),
670+ )
671+}
672+
673+func unInstallService(c *check.C, serviceName, basePath string) {
674+ MakeWritable(c, basePath)
675+ defer MakeReadonly(c, basePath)
676+
677+ // Disable the service
678+ ExecCommand(c, "sudo", "chroot", basePath,
679+ "systemctl", "disable", fmt.Sprintf("%s.service", serviceName))
680+
681+ // Remove the service file
682+ ExecCommand(c, "sudo", "rm",
683+ fmt.Sprintf("%s%s/%s.service", basePath, baseSystemdPath, serviceName))
684+
685+ // Remove the requires symlink
686+ ExecCommand(c, "sudo", "rm",
687+ fmt.Sprintf("%s%s/%s/%s.service", basePath, baseSystemdPath, systemdTargetRequiresDir, serviceName))
688+}
689+
690+func (s *failoverSuite) TestSystemdDependencyLoop(c *check.C) {
691+ commonFailoverTest(c, systemdDependencyLoop{})
692+}
693
694=== added file '_integration-tests/tests/failover_test.go'
695--- _integration-tests/tests/failover_test.go 1970-01-01 00:00:00 +0000
696+++ _integration-tests/tests/failover_test.go 2015-08-02 12:28:18 +0000
697@@ -0,0 +1,58 @@
698+// -*- Mode: Go; indent-tabs-mode: t -*-
699+
700+/*
701+ * Copyright (C) 2015 Canonical Ltd
702+ *
703+ * This program is free software: you can redistribute it and/or modify
704+ * it under the terms of the GNU General Public License version 3 as
705+ * published by the Free Software Foundation.
706+ *
707+ * This program is distributed in the hope that it will be useful,
708+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
709+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
710+ * GNU General Public License for more details.
711+ *
712+ * You should have received a copy of the GNU General Public License
713+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
714+ *
715+ */
716+
717+package tests
718+
719+import (
720+ check "gopkg.in/check.v1"
721+
722+ . "launchpad.net/snappy/_integration-tests/testutils/common"
723+)
724+
725+var _ = check.Suite(&failoverSuite{})
726+
727+type failoverSuite struct {
728+ SnappySuite
729+}
730+
731+// The types that implement this interface can be used in the test logic
732+type failer interface {
733+ // Sets the failure conditions
734+ set(c *check.C)
735+ // Unsets the failure conditions
736+ unset(c *check.C)
737+}
738+
739+// This is the logic common to all the failover tests. Each of them has define a
740+// type implementing the failer interface and call this function with an instance
741+// of it
742+func commonFailoverTest(c *check.C, f failer) {
743+ currentVersion := GetCurrentUbuntuCoreVersion(c)
744+
745+ if AfterReboot(c) {
746+ RemoveRebootMark(c)
747+ f.unset(c)
748+ c.Assert(GetSavedVersion(c), check.Equals, currentVersion)
749+ } else {
750+ SetSavedVersion(c, currentVersion-1)
751+ CallFakeUpdate(c)
752+ f.set(c)
753+ Reboot(c)
754+ }
755+}
756
757=== added file '_integration-tests/tests/failover_zero_size_file_test.go'
758--- _integration-tests/tests/failover_zero_size_file_test.go 1970-01-01 00:00:00 +0000
759+++ _integration-tests/tests/failover_zero_size_file_test.go 2015-08-02 12:28:18 +0000
760@@ -0,0 +1,258 @@
761+// -*- Mode: Go; indent-tabs-mode: t -*-
762+
763+/*
764+ * Copyright (C) 2015 Canonical Ltd
765+ *
766+ * This program is free software: you can redistribute it and/or modify
767+ * it under the terms of the GNU General Public License version 3 as
768+ * published by the Free Software Foundation.
769+ *
770+ * This program is distributed in the hope that it will be useful,
771+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
772+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
773+ * GNU General Public License for more details.
774+ *
775+ * You should have received a copy of the GNU General Public License
776+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
777+ *
778+ */
779+
780+package tests
781+
782+import (
783+ "bufio"
784+ "fmt"
785+ "os"
786+ "path/filepath"
787+ "strings"
788+
789+ . "launchpad.net/snappy/_integration-tests/testutils/common"
790+
791+ check "gopkg.in/check.v1"
792+)
793+
794+const (
795+ origBootFilenamePattern = "boot/%s%s*"
796+ origSystemdFilenamePattern = "lib/systemd/%s%s"
797+ kernelFilename = "vmlinuz"
798+ initrdFilename = "initrd"
799+ systemdFilename = "systemd"
800+ destFilenamePrefix = "snappy-selftest-"
801+ bootBase = "/boot"
802+ ubootDir = bootBase + "/uboot"
803+ grubDir = bootBase + "/grub"
804+ ubootConfigFile = ubootDir + "/snappy-system.txt"
805+ grubConfigFile = grubDir + "/grubenv"
806+)
807+
808+type zeroSizeKernel struct{}
809+type zeroSizeInitrd struct{}
810+type zeroSizeSystemd struct{}
811+
812+func (zeroSizeKernel) set(c *check.C) {
813+ commonSet(c, BaseAltPartitionPath, origBootFilenamePattern, kernelFilename)
814+}
815+
816+func (zeroSizeKernel) unset(c *check.C) {
817+ commonUnset(c, BaseAltPartitionPath, origBootFilenamePattern, kernelFilename)
818+}
819+
820+func (zeroSizeInitrd) set(c *check.C) {
821+ if classicKernelFiles(c) {
822+ commonSet(c, BaseAltPartitionPath, origBootFilenamePattern, initrdFilename)
823+ } else {
824+ boot := bootSystem(c)
825+ dir := bootDirectory(boot)
826+ bootFileNamePattern := newKernelFilenamePattern(c, boot, true)
827+ commonSet(c, dir, bootFileNamePattern, initrdFilename)
828+ }
829+}
830+
831+func (zeroSizeInitrd) unset(c *check.C) {
832+ if classicKernelFiles(c) {
833+ commonUnset(c, BaseAltPartitionPath, origBootFilenamePattern, initrdFilename)
834+ } else {
835+ boot := bootSystem(c)
836+ dir := bootDirectory(boot)
837+ bootFileNamePattern := newKernelFilenamePattern(c, boot, false)
838+ commonUnset(c, dir, bootFileNamePattern, initrdFilename)
839+ }
840+}
841+
842+func (zeroSizeSystemd) set(c *check.C) {
843+ commonSet(c, BaseAltPartitionPath, origSystemdFilenamePattern, systemdFilename)
844+}
845+
846+func (zeroSizeSystemd) unset(c *check.C) {
847+ commonUnset(c, BaseAltPartitionPath, origSystemdFilenamePattern, systemdFilename)
848+}
849+
850+func commonSet(c *check.C, baseOtherPath, origPattern, filename string) {
851+ filenamePattern := fmt.Sprintf(origPattern, "", filename)
852+ completePattern := filepath.Join(
853+ baseOtherPath,
854+ filenamePattern)
855+ oldFilename := getSingleFilename(c, completePattern)
856+ filenameSuffix := fmt.Sprintf(
857+ strings.Replace(origPattern, "*", "", 1), destFilenamePrefix, filepath.Base(oldFilename))
858+ newFilename := fmt.Sprintf(
859+ "%s/%s", baseOtherPath, filenameSuffix)
860+
861+ renameFile(c, baseOtherPath, oldFilename, newFilename, true)
862+}
863+
864+func commonUnset(c *check.C, baseOtherPath, origPattern, filename string) {
865+ completePattern := filepath.Join(
866+ baseOtherPath,
867+ fmt.Sprintf(origPattern, destFilenamePrefix, filename))
868+ oldFilename := getSingleFilename(c, completePattern)
869+ newFilename := strings.Replace(oldFilename, destFilenamePrefix, "", 1)
870+
871+ renameFile(c, baseOtherPath, oldFilename, newFilename, false)
872+}
873+
874+func renameFile(c *check.C, basePath, oldFilename, newFilename string, keepOld bool) {
875+ // Only need to make writable and revert for BaseAltPartitionPath,
876+ // kernel files' boot directory is writable
877+ if basePath == BaseAltPartitionPath {
878+ MakeWritable(c, basePath)
879+ defer MakeReadonly(c, basePath)
880+ }
881+
882+ ExecCommand(c, "sudo", "mv", oldFilename, newFilename)
883+
884+ if keepOld {
885+ ExecCommand(c, "sudo", "touch", oldFilename)
886+ mode := getFileMode(c, newFilename)
887+ ExecCommand(c, "sudo", "chmod", fmt.Sprintf("%o", mode), oldFilename)
888+ }
889+}
890+
891+func getFileMode(c *check.C, filePath string) os.FileMode {
892+ info, err := os.Stat(filePath)
893+ c.Check(err, check.IsNil, check.Commentf("Error getting Stat of %s", filePath))
894+
895+ return info.Mode()
896+}
897+
898+func getSingleFilename(c *check.C, pattern string) string {
899+ matches, err := filepath.Glob(pattern)
900+
901+ c.Assert(err, check.IsNil, check.Commentf("Error: %v", err))
902+ c.Assert(len(matches), check.Equals, 1,
903+ check.Commentf("%d files matching %s, 1 expected", len(matches), pattern))
904+
905+ return matches[0]
906+}
907+
908+func classicKernelFiles(c *check.C) bool {
909+ initrdClassicFilenamePattern := fmt.Sprintf("/boot/%s*-generic", initrdFilename)
910+ matches, err := filepath.Glob(initrdClassicFilenamePattern)
911+
912+ c.Assert(err, check.IsNil, check.Commentf("Error: %v", err))
913+
914+ return len(matches) == 1
915+}
916+
917+func bootSystem(c *check.C) string {
918+ matches, err := filepath.Glob(bootBase + "/grub")
919+
920+ c.Assert(err, check.IsNil, check.Commentf("Error: %v", err))
921+
922+ if len(matches) == 1 {
923+ return "grub"
924+ }
925+ return "uboot"
926+}
927+
928+func bootDirectory(bootSystem string) string {
929+ if bootSystem == "grub" {
930+ return grubDir
931+ }
932+ return ubootDir
933+}
934+
935+func bootConfigFile(bootSystem string) string {
936+ if bootSystem == "grub" {
937+ return grubConfigFile
938+ }
939+ return ubootConfigFile
940+}
941+
942+func currentPartition(c *check.C, bootSystem string) (partition string) {
943+ bootConfigFile := bootConfigFile(bootSystem)
944+ file, err := os.Open(bootConfigFile)
945+
946+ c.Assert(err, check.IsNil,
947+ check.Commentf("Error reading boot config file %s", bootConfigFile))
948+
949+ defer file.Close()
950+
951+ reader := bufio.NewReader(file)
952+ scanner := bufio.NewScanner(reader)
953+
954+ scanner.Split(bufio.ScanLines)
955+
956+ for scanner.Scan() {
957+ if strings.HasPrefix(scanner.Text(), "snappy_ab") {
958+ fields := strings.Split(scanner.Text(), "=")
959+ if len(fields) > 1 {
960+ if bootSystem == "grub" {
961+ partition = fields[1]
962+ } else {
963+ partition = otherPart(fields[1])
964+ }
965+ }
966+ return
967+ }
968+ }
969+ return
970+}
971+
972+func otherPart(current string) string {
973+ if current == "a" {
974+ return "b"
975+ }
976+ return "a"
977+}
978+
979+// newKernelFilenamePattern returns the filename pattern to modify files
980+// in the partition declared in the boot config file.
981+//
982+// After the update, the config file is already changed to point to the new partition.
983+// If we are on a and update, the config file would point to b
984+// and this function would return "b/%s%s*"
985+// If we are not in an update process (ie. we are unsetting the failover conditions)
986+// we want to change the files in the other partition
987+func newKernelFilenamePattern(c *check.C, bootSystem string, afterUpdate bool) string {
988+ var actualPartition string
989+ partition := currentPartition(c, bootSystem)
990+ if afterUpdate {
991+ actualPartition = partition
992+ } else {
993+ actualPartition = otherPart(partition)
994+ }
995+ return filepath.Join(actualPartition, "%s%s*")
996+}
997+
998+/*
999+TODO: uncomment when bug https://bugs.launchpad.net/snappy/+bug/1467553 is fixed
1000+(fgimenez 20150729)
1001+
1002+func (s *failoverSuite) TestZeroSizeKernel(c *check.C) {
1003+ commonFailoverTest(c, zeroSizeKernel{})
1004+}
1005+*/
1006+
1007+func (s *failoverSuite) TestZeroSizeInitrd(c *check.C) {
1008+ // Skip if on uboot due to https://bugs.launchpad.net/snappy/+bug/1480248
1009+ // (fgimenez 20150731)
1010+ if bootSystem(c) == "uboot" {
1011+ c.Skip("Failover for empty initrd not working in uboot")
1012+ }
1013+ commonFailoverTest(c, zeroSizeInitrd{})
1014+}
1015+
1016+func (s *failoverSuite) TestZeroSizeSystemd(c *check.C) {
1017+ commonFailoverTest(c, zeroSizeSystemd{})
1018+}
1019
1020=== added file '_integration-tests/tests/info_test.go'
1021--- _integration-tests/tests/info_test.go 1970-01-01 00:00:00 +0000
1022+++ _integration-tests/tests/info_test.go 2015-08-02 12:28:18 +0000
1023@@ -0,0 +1,79 @@
1024+// -*- Mode: Go; indent-tabs-mode: t -*-
1025+
1026+/*
1027+ * Copyright (C) 2015 Canonical Ltd
1028+ *
1029+ * This program is free software: you can redistribute it and/or modify
1030+ * it under the terms of the GNU General Public License version 3 as
1031+ * published by the Free Software Foundation.
1032+ *
1033+ * This program is distributed in the hope that it will be useful,
1034+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1035+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1036+ * GNU General Public License for more details.
1037+ *
1038+ * You should have received a copy of the GNU General Public License
1039+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1040+ *
1041+ */
1042+
1043+package tests
1044+
1045+import (
1046+ "fmt"
1047+
1048+ . "launchpad.net/snappy/_integration-tests/testutils/common"
1049+
1050+ check "gopkg.in/check.v1"
1051+)
1052+
1053+var _ = check.Suite(&infoSuite{})
1054+
1055+type infoSuite struct {
1056+ SnappySuite
1057+}
1058+
1059+func (s *infoSuite) TestInfoMustPrintReleaseAndChannel(c *check.C) {
1060+ // skip test when having a remote testbed (we can't know which the
1061+ // release and channels are)
1062+ if Cfg.RemoteTestbed {
1063+ c.Skip(fmt.Sprintf(
1064+ "Skipping %s while testing in remote testbed",
1065+ c.TestName()))
1066+ }
1067+
1068+ infoOutput := ExecCommand(c, "snappy", "info")
1069+
1070+ expected := "(?ms)" +
1071+ fmt.Sprintf("^release: ubuntu-core/%s/%s\n", Cfg.Release, Cfg.Channel) +
1072+ ".*"
1073+
1074+ c.Assert(infoOutput, check.Matches, expected)
1075+}
1076+
1077+func (s *infoSuite) TestInfoMustPrintInstalledApps(c *check.C) {
1078+ InstallSnap(c, "hello-world")
1079+ s.AddCleanup(func() {
1080+ RemoveSnap(c, "hello-world")
1081+ })
1082+ infoOutput := ExecCommand(c, "snappy", "info")
1083+
1084+ expected := "(?ms)" +
1085+ ".*" +
1086+ "^apps: .*hello-world.*\n"
1087+ c.Assert(infoOutput, check.Matches, expected)
1088+}
1089+
1090+func (s *infoSuite) TestInfoMustPrintInstalledFrameworks(c *check.C) {
1091+ InstallSnap(c, "hello-dbus-fwk.canonical")
1092+ s.AddCleanup(func() {
1093+ RemoveSnap(c, "hello-dbus-fwk.canonical")
1094+ })
1095+ infoOutput := ExecCommand(c, "snappy", "info")
1096+
1097+ expected := "(?ms)" +
1098+ ".*" +
1099+ "^frameworks: .*hello-dbus-fwk.*\n" +
1100+ ".*"
1101+ c.Assert(infoOutput, check.Matches, expected)
1102+}
1103
1104=== added file '_integration-tests/tests/installApp_test.go'
1105--- _integration-tests/tests/installApp_test.go 1970-01-01 00:00:00 +0000
1106+++ _integration-tests/tests/installApp_test.go 2015-08-02 12:28:18 +0000
1107@@ -0,0 +1,128 @@
1108+// -*- Mode: Go; indent-tabs-mode: t -*-
1109+
1110+/*
1111+ * Copyright (C) 2015 Canonical Ltd
1112+ *
1113+ * This program is free software: you can redistribute it and/or modify
1114+ * it under the terms of the GNU General Public License version 3 as
1115+ * published by the Free Software Foundation.
1116+ *
1117+ * This program is distributed in the hope that it will be useful,
1118+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1119+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1120+ * GNU General Public License for more details.
1121+ *
1122+ * You should have received a copy of the GNU General Public License
1123+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1124+ *
1125+ */
1126+
1127+package tests
1128+
1129+import (
1130+ "fmt"
1131+ "net/http"
1132+ "os/exec"
1133+ "time"
1134+
1135+ . "launchpad.net/snappy/_integration-tests/testutils/common"
1136+
1137+ check "gopkg.in/check.v1"
1138+)
1139+
1140+var _ = check.Suite(&installAppSuite{})
1141+
1142+type installAppSuite struct {
1143+ SnappySuite
1144+}
1145+
1146+func (s *installAppSuite) TestInstallAppMustPrintPackageInformation(c *check.C) {
1147+ installOutput := InstallSnap(c, "hello-world")
1148+ s.AddCleanup(func() {
1149+ RemoveSnap(c, "hello-world")
1150+ })
1151+
1152+ expected := "(?ms)" +
1153+ "Installing hello-world\n" +
1154+ "Name +Date +Version +Developer \n" +
1155+ ".*" +
1156+ "^hello-world +.* +.* +canonical \n" +
1157+ ".*"
1158+
1159+ c.Assert(installOutput, check.Matches, expected)
1160+}
1161+
1162+func (s *installAppSuite) TestCallBinaryFromInstalledSnap(c *check.C) {
1163+ InstallSnap(c, "hello-world")
1164+ s.AddCleanup(func() {
1165+ RemoveSnap(c, "hello-world")
1166+ })
1167+
1168+ echoOutput := ExecCommand(c, "hello-world.echo")
1169+
1170+ c.Assert(echoOutput, check.Equals, "Hello World!\n")
1171+}
1172+
1173+func (s *installAppSuite) TestCallBinaryWithPermissionDeniedMustPrintError(c *check.C) {
1174+ InstallSnap(c, "hello-world")
1175+ s.AddCleanup(func() {
1176+ RemoveSnap(c, "hello-world")
1177+ })
1178+
1179+ cmd := exec.Command("hello-world.evil")
1180+ echoOutput, err := cmd.CombinedOutput()
1181+ c.Assert(err, check.NotNil, check.Commentf("hello-world.evil did not fail"))
1182+
1183+ expected := "" +
1184+ "Hello Evil World!\n" +
1185+ "This example demonstrates the app confinement\n" +
1186+ "You should see a permission denied error next\n" +
1187+ "/apps/hello-world.canonical/.*/bin/evil: \\d+: " +
1188+ "/apps/hello-world.canonical/.*/bin/evil: " +
1189+ "cannot create /var/tmp/myevil.txt: Permission denied\n"
1190+
1191+ c.Assert(string(echoOutput), check.Matches, expected)
1192+}
1193+
1194+func (s *installAppSuite) TestInfoMustPrintInstalledPackageInformation(c *check.C) {
1195+ InstallSnap(c, "hello-world")
1196+ s.AddCleanup(func() {
1197+ RemoveSnap(c, "hello-world")
1198+ })
1199+
1200+ infoOutput := ExecCommand(c, "snappy", "info")
1201+
1202+ expected := "(?ms).*^apps: hello-world\n"
1203+ c.Assert(infoOutput, check.Matches, expected)
1204+}
1205+
1206+func (s *installAppSuite) TestAppNetworkingServiceMustBeStarted(c *check.C) {
1207+ baseAppName := "xkcd-webserver"
1208+ appName := baseAppName + ".canonical"
1209+ InstallSnap(c, appName)
1210+ s.AddCleanup(func() {
1211+ RemoveSnap(c, appName)
1212+ })
1213+
1214+ appVersion := GetCurrentVersion(c, baseAppName)
1215+ appService := fmt.Sprintf("%s_%s_%s.service", baseAppName, baseAppName, appVersion)
1216+
1217+ err := WaitForActiveService(c, appService)
1218+ c.Assert(err, check.IsNil)
1219+
1220+ time.Sleep(1 * time.Second)
1221+ resp, err := http.Get("http://localhost")
1222+ c.Assert(err, check.IsNil)
1223+ c.Check(resp.Status, check.Equals, "200 OK")
1224+ c.Assert(resp.Proto, check.Equals, "HTTP/1.0")
1225+}
1226+
1227+func (s *installAppSuite) TestInstallUnexistingAppMustPrintError(c *check.C) {
1228+ cmd := exec.Command("sudo", "snappy", "install", "unexisting.canonical")
1229+ output, err := cmd.CombinedOutput()
1230+
1231+ c.Assert(err, check.NotNil)
1232+ c.Assert(string(output), check.Equals,
1233+ "Installing unexisting.canonical\n"+
1234+ "unexisting.canonical failed to install: snappy package not found\n")
1235+}
1236
1237=== added file '_integration-tests/tests/installFramework_test.go'
1238--- _integration-tests/tests/installFramework_test.go 1970-01-01 00:00:00 +0000
1239+++ _integration-tests/tests/installFramework_test.go 2015-08-02 12:28:18 +0000
1240@@ -0,0 +1,93 @@
1241+// -*- Mode: Go; indent-tabs-mode: t -*-
1242+
1243+/*
1244+ * Copyright (C) 2015 Canonical Ltd
1245+ *
1246+ * This program is free software: you can redistribute it and/or modify
1247+ * it under the terms of the GNU General Public License version 3 as
1248+ * published by the Free Software Foundation.
1249+ *
1250+ * This program is distributed in the hope that it will be useful,
1251+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1252+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1253+ * GNU General Public License for more details.
1254+ *
1255+ * You should have received a copy of the GNU General Public License
1256+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1257+ *
1258+ */
1259+
1260+package tests
1261+
1262+import (
1263+ "fmt"
1264+ "regexp"
1265+
1266+ . "launchpad.net/snappy/_integration-tests/testutils/common"
1267+
1268+ check "gopkg.in/check.v1"
1269+)
1270+
1271+var _ = check.Suite(&installFrameworkSuite{})
1272+
1273+type installFrameworkSuite struct {
1274+ SnappySuite
1275+}
1276+
1277+func (s *installFrameworkSuite) TearDownTest(c *check.C) {
1278+ if !NeedsReboot() && CheckRebootMark("") {
1279+ RemoveSnap(c, "docker")
1280+ }
1281+ // run cleanup last
1282+ s.SnappySuite.TearDownTest(c)
1283+}
1284+
1285+func isDockerServiceRunning(c *check.C) bool {
1286+ dockerVersion := GetCurrentVersion(c, "docker")
1287+ dockerService := fmt.Sprintf("docker_docker-daemon_%s.service", dockerVersion)
1288+
1289+ err := WaitForActiveService(c, dockerService)
1290+ c.Assert(err, check.IsNil)
1291+
1292+ statusOutput := ExecCommand(
1293+ c, "systemctl", "status",
1294+ dockerService)
1295+
1296+ expected := "(?ms)" +
1297+ ".* docker_docker-daemon_.*\\.service .*\n" +
1298+ ".*Loaded: loaded .*\n" +
1299+ ".*Active: active \\(running\\) .*\n" +
1300+ ".*"
1301+
1302+ matched, err := regexp.MatchString(expected, statusOutput)
1303+ c.Assert(err, check.IsNil)
1304+ return matched
1305+}
1306+
1307+func (s *installFrameworkSuite) TestInstallFrameworkMustPrintPackageInformation(c *check.C) {
1308+ installOutput := InstallSnap(c, "docker")
1309+
1310+ expected := "(?ms)" +
1311+ "Installing docker\n" +
1312+ "Name +Date +Version +Developer \n" +
1313+ ".*" +
1314+ "^docker +.* +.* +canonical \n" +
1315+ ".*"
1316+
1317+ c.Assert(installOutput, check.Matches, expected)
1318+}
1319+
1320+func (s *installFrameworkSuite) TestInstalledFrameworkServiceMustBeStarted(c *check.C) {
1321+ InstallSnap(c, "docker")
1322+ c.Assert(isDockerServiceRunning(c), check.Equals, true)
1323+}
1324+
1325+func (s *installFrameworkSuite) TestFrameworkServiceMustBeStartedAfterReboot(c *check.C) {
1326+ if BeforeReboot() {
1327+ InstallSnap(c, "docker")
1328+ Reboot(c)
1329+ } else if AfterReboot(c) {
1330+ RemoveRebootMark(c)
1331+ c.Assert(isDockerServiceRunning(c), check.Equals, true)
1332+ }
1333+}
1334
1335=== added file '_integration-tests/tests/list_test.go'
1336--- _integration-tests/tests/list_test.go 1970-01-01 00:00:00 +0000
1337+++ _integration-tests/tests/list_test.go 2015-08-02 12:28:18 +0000
1338@@ -0,0 +1,78 @@
1339+// -*- Mode: Go; indent-tabs-mode: t -*-
1340+
1341+/*
1342+ * Copyright (C) 2015 Canonical Ltd
1343+ *
1344+ * This program is free software: you can redistribute it and/or modify
1345+ * it under the terms of the GNU General Public License version 3 as
1346+ * published by the Free Software Foundation.
1347+ *
1348+ * This program is distributed in the hope that it will be useful,
1349+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1350+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1351+ * GNU General Public License for more details.
1352+ *
1353+ * You should have received a copy of the GNU General Public License
1354+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1355+ *
1356+ */
1357+
1358+package tests
1359+
1360+import (
1361+ "fmt"
1362+ "os"
1363+
1364+ . "launchpad.net/snappy/_integration-tests/testutils/common"
1365+
1366+ "github.com/mvo5/goconfigparser"
1367+ check "gopkg.in/check.v1"
1368+)
1369+
1370+var _ = check.Suite(&listSuite{})
1371+
1372+type listSuite struct {
1373+ SnappySuite
1374+}
1375+
1376+func getVersionFromConfig(c *check.C) string {
1377+ cfg := goconfigparser.New()
1378+ f, err := os.Open("/etc/system-image/channel.ini")
1379+ c.Assert(err, check.IsNil,
1380+ check.Commentf("Error opening the config file: %v:", err))
1381+ defer f.Close()
1382+ err = cfg.Read(f)
1383+ c.Assert(err, check.IsNil,
1384+ check.Commentf("Error parsing the config file: %v", err))
1385+ version, err := cfg.Get("service", "build_number")
1386+ c.Assert(err, check.IsNil,
1387+ check.Commentf("Error getting the build number: %v", err))
1388+ return version
1389+}
1390+
1391+func (s *listSuite) TestListMustPrintCoreVersion(c *check.C) {
1392+ listOutput := ExecCommand(c, "snappy", "list")
1393+
1394+ expected := "(?ms)" +
1395+ "Name +Date +Version +Developer *\n" +
1396+ ".*" +
1397+ fmt.Sprintf("^ubuntu-core +.* +%s +ubuntu *\n", getVersionFromConfig(c)) +
1398+ ".*"
1399+ c.Assert(listOutput, check.Matches, expected)
1400+}
1401+
1402+func (s *listSuite) TestListMustPrintAppVersion(c *check.C) {
1403+ InstallSnap(c, "hello-world")
1404+ s.AddCleanup(func() {
1405+ RemoveSnap(c, "hello-world")
1406+ })
1407+
1408+ listOutput := ExecCommand(c, "snappy", "list")
1409+ expected := "(?ms)" +
1410+ "Name +Date +Version +Developer *\n" +
1411+ ".*" +
1412+ "^hello-world +.* +(\\d+)(\\.\\d+)* +.* +.* *\n" +
1413+ ".*"
1414+
1415+ c.Assert(listOutput, check.Matches, expected)
1416+}
1417
1418=== added file '_integration-tests/tests/rollback_test.go'
1419--- _integration-tests/tests/rollback_test.go 1970-01-01 00:00:00 +0000
1420+++ _integration-tests/tests/rollback_test.go 2015-08-02 12:28:18 +0000
1421@@ -0,0 +1,53 @@
1422+// -*- Mode: Go; indent-tabs-mode: t -*-
1423+
1424+/*
1425+ * Copyright (C) 2015 Canonical Ltd
1426+ *
1427+ * This program is free software: you can redistribute it and/or modify
1428+ * it under the terms of the GNU General Public License version 3 as
1429+ * published by the Free Software Foundation.
1430+ *
1431+ * This program is distributed in the hope that it will be useful,
1432+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1433+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1434+ * GNU General Public License for more details.
1435+ *
1436+ * You should have received a copy of the GNU General Public License
1437+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1438+ *
1439+ */
1440+
1441+package tests
1442+
1443+import (
1444+ "strconv"
1445+
1446+ . "launchpad.net/snappy/_integration-tests/testutils/common"
1447+
1448+ check "gopkg.in/check.v1"
1449+)
1450+
1451+var _ = check.Suite(&rollbackSuite{})
1452+
1453+type rollbackSuite struct {
1454+ SnappySuite
1455+}
1456+
1457+func (s *rollbackSuite) TestRollbackMustRebootToOtherVersion(c *check.C) {
1458+ if BeforeReboot() {
1459+ CallFakeUpdate(c)
1460+ Reboot(c)
1461+ } else if CheckRebootMark(c.TestName()) {
1462+ RemoveRebootMark(c)
1463+ currentVersion := GetCurrentUbuntuCoreVersion(c)
1464+ c.Assert(currentVersion > GetSavedVersion(c), check.Equals, true)
1465+ ExecCommand(c, "sudo", "snappy", "rollback", "ubuntu-core",
1466+ strconv.Itoa(GetSavedVersion(c)))
1467+ SetSavedVersion(c, currentVersion)
1468+ RebootWithMark(c, c.TestName()+"-rollback")
1469+ } else if CheckRebootMark(c.TestName() + "-rollback") {
1470+ RemoveRebootMark(c)
1471+ c.Assert(
1472+ GetCurrentUbuntuCoreVersion(c) < GetSavedVersion(c), check.Equals, true)
1473+ }
1474+}
1475
1476=== added file '_integration-tests/tests/search_test.go'
1477--- _integration-tests/tests/search_test.go 1970-01-01 00:00:00 +0000
1478+++ _integration-tests/tests/search_test.go 2015-08-02 12:28:18 +0000
1479@@ -0,0 +1,44 @@
1480+// -*- Mode: Go; indent-tabs-mode: t -*-
1481+
1482+/*
1483+ * Copyright (C) 2015 Canonical Ltd
1484+ *
1485+ * This program is free software: you can redistribute it and/or modify
1486+ * it under the terms of the GNU General Public License version 3 as
1487+ * published by the Free Software Foundation.
1488+ *
1489+ * This program is distributed in the hope that it will be useful,
1490+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1491+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1492+ * GNU General Public License for more details.
1493+ *
1494+ * You should have received a copy of the GNU General Public License
1495+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1496+ *
1497+ */
1498+
1499+package tests
1500+
1501+import (
1502+ . "launchpad.net/snappy/_integration-tests/testutils/common"
1503+
1504+ . "gopkg.in/check.v1"
1505+)
1506+
1507+var _ = Suite(&searchSuite{})
1508+
1509+type searchSuite struct {
1510+ SnappySuite
1511+}
1512+
1513+func (s *searchSuite) TestSearchFrameworkMustPrintMatch(c *C) {
1514+ searchOutput := ExecCommand(c, "snappy", "search", "hello-dbus-fwk")
1515+
1516+ expected := "(?ms)" +
1517+ "Name +Version +Summary *\n" +
1518+ ".*" +
1519+ "^hello-dbus-fwk +.* +hello-dbus-fwk *\n" +
1520+ ".*"
1521+
1522+ c.Assert(searchOutput, Matches, expected)
1523+}
1524
1525=== added file '_integration-tests/tests/update_test.go'
1526--- _integration-tests/tests/update_test.go 1970-01-01 00:00:00 +0000
1527+++ _integration-tests/tests/update_test.go 2015-08-02 12:28:18 +0000
1528@@ -0,0 +1,51 @@
1529+// -*- Mode: Go; indent-tabs-mode: t -*-
1530+
1531+/*
1532+ * Copyright (C) 2015 Canonical Ltd
1533+ *
1534+ * This program is free software: you can redistribute it and/or modify
1535+ * it under the terms of the GNU General Public License version 3 as
1536+ * published by the Free Software Foundation.
1537+ *
1538+ * This program is distributed in the hope that it will be useful,
1539+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1540+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1541+ * GNU General Public License for more details.
1542+ *
1543+ * You should have received a copy of the GNU General Public License
1544+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1545+ *
1546+ */
1547+
1548+package tests
1549+
1550+import (
1551+ . "launchpad.net/snappy/_integration-tests/testutils/common"
1552+
1553+ check "gopkg.in/check.v1"
1554+)
1555+
1556+var _ = check.Suite(&updateSuite{})
1557+
1558+type updateSuite struct {
1559+ SnappySuite
1560+}
1561+
1562+// Test that the update to the same release and channel must install a newer
1563+// version. If there is no update available, the channel version will be
1564+// modified to fake an update. If there is a version available, the image will
1565+// be up-to-date after running this test.
1566+func (s *updateSuite) TestUpdateToSameReleaseAndChannel(c *check.C) {
1567+ if BeforeReboot() {
1568+ updateOutput := CallFakeUpdate(c)
1569+ expected := "(?ms)" +
1570+ ".*" +
1571+ "^Reboot to use .*ubuntu-core.\n"
1572+ c.Assert(updateOutput, check.Matches, expected)
1573+ Reboot(c)
1574+ } else if AfterReboot(c) {
1575+ RemoveRebootMark(c)
1576+ c.Assert(GetCurrentUbuntuCoreVersion(c) > GetSavedVersion(c),
1577+ check.Equals, true)
1578+ }
1579+}
1580
1581=== added file '_integration-tests/tests/writablePaths_test.go'
1582--- _integration-tests/tests/writablePaths_test.go 1970-01-01 00:00:00 +0000
1583+++ _integration-tests/tests/writablePaths_test.go 2015-08-02 12:28:18 +0000
1584@@ -0,0 +1,106 @@
1585+// -*- Mode: Go; indent-tabs-mode: t -*-
1586+
1587+/*
1588+ * Copyright (C) 2015 Canonical Ltd
1589+ *
1590+ * This program is free software: you can redistribute it and/or modify
1591+ * it under the terms of the GNU General Public License version 3 as
1592+ * published by the Free Software Foundation.
1593+ *
1594+ * This program is distributed in the hope that it will be useful,
1595+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1596+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1597+ * GNU General Public License for more details.
1598+ *
1599+ * You should have received a copy of the GNU General Public License
1600+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1601+ *
1602+ */
1603+
1604+package tests
1605+
1606+import (
1607+ "bufio"
1608+ "fmt"
1609+ "os"
1610+ "os/exec"
1611+ "path/filepath"
1612+ "strings"
1613+
1614+ . "launchpad.net/snappy/_integration-tests/testutils/common"
1615+
1616+ check "gopkg.in/check.v1"
1617+)
1618+
1619+const writablePathsListFile = "/etc/system-image/writable-paths"
1620+
1621+var _ = check.Suite(&writablePathsSuite{})
1622+
1623+type writablePathsSuite struct {
1624+ SnappySuite
1625+}
1626+
1627+var IsWritable check.Checker = &isWritable{}
1628+
1629+type isWritable struct {
1630+}
1631+
1632+func (is *isWritable) Info() *check.CheckerInfo {
1633+ return &check.CheckerInfo{Name: "IsWritable", Params: []string{"path"}}
1634+}
1635+
1636+func (is *isWritable) Check(params []interface{}, names []string) (result bool, error string) {
1637+ if path, ok := params[0].(string); ok {
1638+ filename := filepath.Join(path, "tmpfile")
1639+
1640+ cmd := exec.Command("sudo", "touch", filename)
1641+ rmCmd := exec.Command("sudo", "rm", filename)
1642+ defer rmCmd.Run()
1643+
1644+ if _, err := cmd.CombinedOutput(); err == nil {
1645+ result = true
1646+ } else {
1647+ error = fmt.Sprintf("Error creating file %s", filename)
1648+ }
1649+ } else {
1650+ error = fmt.Sprintf("First param of checker %v is of type %T and it should be a string", params[0], params[0])
1651+ }
1652+ return result, error
1653+}
1654+
1655+func (s *writablePathsSuite) TestWritablePathsAreWritable(c *check.C) {
1656+ for writablePath := range generateWritablePaths(c) {
1657+ c.Logf("Checking if %s is writable", writablePath)
1658+ c.Check(writablePath, IsWritable)
1659+ }
1660+}
1661+
1662+func generateWritablePaths(c *check.C) chan string {
1663+ ch := make(chan string)
1664+
1665+ go func() {
1666+ file, err := os.Open(writablePathsListFile)
1667+
1668+ c.Assert(err, check.IsNil,
1669+ check.Commentf("Error reading writable files list %s", writablePathsListFile))
1670+
1671+ defer file.Close()
1672+
1673+ reader := bufio.NewReader(file)
1674+ scanner := bufio.NewScanner(reader)
1675+
1676+ scanner.Split(bufio.ScanLines)
1677+
1678+ for scanner.Scan() {
1679+ fields := strings.Fields(scanner.Text())
1680+ if len(fields) > 0 && fields[0] != "#" {
1681+ if src, err := os.Stat(fields[0]); err == nil && src.IsDir() {
1682+ ch <- fields[0]
1683+ }
1684+ }
1685+ }
1686+ close(ch)
1687+ }()
1688+
1689+ return ch
1690+}
1691
1692=== added directory '_integration-tests/testutils'
1693=== added directory '_integration-tests/testutils/autopkgtest'
1694=== added file '_integration-tests/testutils/autopkgtest/autopkgtest.go'
1695--- _integration-tests/testutils/autopkgtest/autopkgtest.go 1970-01-01 00:00:00 +0000
1696+++ _integration-tests/testutils/autopkgtest/autopkgtest.go 2015-08-02 12:28:18 +0000
1697@@ -0,0 +1,111 @@
1698+// -*- Mode: Go; indent-tabs-mode: t -*-
1699+
1700+/*
1701+ * Copyright (C) 2015 Canonical Ltd
1702+ *
1703+ * This program is free software: you can redistribute it and/or modify
1704+ * it under the terms of the GNU General Public License version 3 as
1705+ * published by the Free Software Foundation.
1706+ *
1707+ * This program is distributed in the hope that it will be useful,
1708+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1709+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1710+ * GNU General Public License for more details.
1711+ *
1712+ * You should have received a copy of the GNU General Public License
1713+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1714+ *
1715+ */
1716+
1717+package autopkgtest
1718+
1719+import (
1720+ "fmt"
1721+ "os"
1722+ "path/filepath"
1723+ "strconv"
1724+ "text/template"
1725+
1726+ "log"
1727+
1728+ "launchpad.net/snappy/_integration-tests/testutils"
1729+)
1730+
1731+const (
1732+ controlTpl = "_integration-tests/data/tpl/control"
1733+ dataOutputDir = "_integration-tests/data/output/"
1734+)
1735+
1736+var controlFile = filepath.Join(dataOutputDir, "control")
1737+
1738+// Autopkgtest is the type that knows how to call adt-run
1739+type Autopkgtest struct {
1740+ sourceCodePath string // location of the source code on the host
1741+ testArtifactsPath string // location of the test artifacts on the host
1742+ testFilter string
1743+ integrationTestName string
1744+}
1745+
1746+// NewAutopkgtest is the Autopkgtest constructor
1747+func NewAutopkgtest(sourceCodePath, testArtifactsPath, testFilter, integrationTestName string) *Autopkgtest {
1748+ return &Autopkgtest{
1749+ sourceCodePath: sourceCodePath,
1750+ testArtifactsPath: testArtifactsPath,
1751+ testFilter: testFilter,
1752+ integrationTestName: integrationTestName}
1753+}
1754+
1755+// AdtRunLocal starts a kvm running the image passed as argument and runs the
1756+// autopkgtests using it as the testbed.
1757+func (a *Autopkgtest) AdtRunLocal(imgPath string) {
1758+ // Run the tests on the latest rolling edge image.
1759+ a.adtRun(kvmSSHOptions(imgPath))
1760+}
1761+
1762+// AdtRunRemote runs the autopkgtests using a remote machine as the testbed.
1763+func (a *Autopkgtest) AdtRunRemote(testbedIP string, testbedPort int) {
1764+ testutils.ExecCommand("ssh-copy-id", "-p", strconv.Itoa(testbedPort),
1765+ "ubuntu@"+testbedIP)
1766+ a.adtRun(remoteTestbedSSHOptions(testbedIP, testbedPort))
1767+}
1768+
1769+func (a *Autopkgtest) adtRun(testbedOptions []string) {
1770+ a.createControlFile()
1771+
1772+ fmt.Println("Calling adt-run...")
1773+ outputDir := filepath.Join(a.testArtifactsPath, "output")
1774+ testutils.PrepareTargetDir(outputDir)
1775+
1776+ cmd := []string{
1777+ "adt-run", "-B",
1778+ "--setup-commands", "touch /run/autopkgtest_no_reboot.stamp",
1779+ "--override-control", controlFile,
1780+ "--built-tree", a.sourceCodePath,
1781+ "--output-dir", outputDir}
1782+
1783+ testutils.ExecCommand(append(cmd, testbedOptions...)...)
1784+}
1785+
1786+func (a *Autopkgtest) createControlFile() {
1787+ type controlData struct {
1788+ Filter string
1789+ Test string
1790+ }
1791+
1792+ tpl, err := template.ParseFiles(controlTpl)
1793+ if err != nil {
1794+ log.Panicf("Error reading adt-run control template %s", controlTpl)
1795+ }
1796+
1797+ outputFile, err := os.Create(controlFile)
1798+ if err != nil {
1799+ log.Panicf("Error creating control file %s", controlFile)
1800+ }
1801+ defer outputFile.Close()
1802+
1803+ err = tpl.Execute(outputFile,
1804+ controlData{Test: a.integrationTestName, Filter: a.testFilter})
1805+ if err != nil {
1806+ log.Panicf("execution: %s", err)
1807+ }
1808+}
1809
1810=== added file '_integration-tests/testutils/autopkgtest/ssh.go'
1811--- _integration-tests/testutils/autopkgtest/ssh.go 1970-01-01 00:00:00 +0000
1812+++ _integration-tests/testutils/autopkgtest/ssh.go 2015-08-02 12:28:18 +0000
1813@@ -0,0 +1,46 @@
1814+// -*- Mode: Go; indent-tabs-mode: t -*-
1815+
1816+/*
1817+ * Copyright (C) 2015 Canonical Ltd
1818+ *
1819+ * This program is free software: you can redistribute it and/or modify
1820+ * it under the terms of the GNU General Public License version 3 as
1821+ * published by the Free Software Foundation.
1822+ *
1823+ * This program is distributed in the hope that it will be useful,
1824+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1825+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1826+ * GNU General Public License for more details.
1827+ *
1828+ * You should have received a copy of the GNU General Public License
1829+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1830+ *
1831+ */
1832+
1833+package autopkgtest
1834+
1835+import (
1836+ "os"
1837+ "path/filepath"
1838+ "strconv"
1839+)
1840+
1841+var commonSSHOptions = []string{"---", "ssh"}
1842+
1843+func kvmSSHOptions(imagePath string) []string {
1844+ return append(
1845+ commonSSHOptions,
1846+ []string{
1847+ "-s", "/usr/share/autopkgtest/ssh-setup/snappy",
1848+ "--", "-i", imagePath}...)
1849+}
1850+
1851+func remoteTestbedSSHOptions(testbedIP string, testbedPort int) []string {
1852+ options := []string{
1853+ "-H", testbedIP,
1854+ "-p", strconv.Itoa(testbedPort),
1855+ "-l", "ubuntu",
1856+ "-i", filepath.Join(os.Getenv("HOME"), ".ssh", "id_rsa"),
1857+ "--reboot"}
1858+ return append(commonSSHOptions, options...)
1859+}
1860
1861=== added directory '_integration-tests/testutils/build'
1862=== added file '_integration-tests/testutils/build/build.go'
1863--- _integration-tests/testutils/build/build.go 1970-01-01 00:00:00 +0000
1864+++ _integration-tests/testutils/build/build.go 2015-08-02 12:28:18 +0000
1865@@ -0,0 +1,76 @@
1866+// -*- Mode: Go; indent-tabs-mode: t -*-
1867+
1868+/*
1869+ * Copyright (C) 2015 Canonical Ltd
1870+ *
1871+ * This program is free software: you can redistribute it and/or modify
1872+ * it under the terms of the GNU General Public License version 3 as
1873+ * published by the Free Software Foundation.
1874+ *
1875+ * This program is distributed in the hope that it will be useful,
1876+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1877+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1878+ * GNU General Public License for more details.
1879+ *
1880+ * You should have received a copy of the GNU General Public License
1881+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1882+ *
1883+ */
1884+
1885+package build
1886+
1887+import (
1888+ "fmt"
1889+ "os"
1890+
1891+ "launchpad.net/snappy/_integration-tests/testutils"
1892+)
1893+
1894+const (
1895+ // IntegrationTestName is the name of the test binary.
1896+ IntegrationTestName = "integration.test"
1897+ defaultGoArm = "7"
1898+ testsBinDir = "_integration-tests/bin/"
1899+)
1900+
1901+// Assets builds the snappy and integration tests binaries for the target
1902+// architecture.
1903+func Assets(useSnappyFromBranch bool, arch string) {
1904+ testutils.PrepareTargetDir(testsBinDir)
1905+
1906+ if useSnappyFromBranch {
1907+ // FIXME We need to build an image that has the snappy from the branch
1908+ // installed. --elopio - 2015-06-25.
1909+ buildSnappyCLI(arch)
1910+ }
1911+ buildTests(arch)
1912+}
1913+
1914+func buildSnappyCLI(arch string) {
1915+ fmt.Println("Building snappy CLI...")
1916+ // On the root of the project we have a directory called snappy, so we
1917+ // output the binary for the tests in the tests directory.
1918+ goCall(arch, "build", "-o", testsBinDir+"snappy", "./cmd/snappy")
1919+}
1920+
1921+func buildTests(arch string) {
1922+ fmt.Println("Building tests...")
1923+
1924+ goCall(arch, "test", "-c", "./_integration-tests/tests")
1925+ // XXX Go test 1.3 does not have the output flag, so we move the
1926+ // binaries after they are generated.
1927+ os.Rename("tests.test", testsBinDir+IntegrationTestName)
1928+}
1929+
1930+func goCall(arch string, cmds ...string) {
1931+ if arch != "" {
1932+ defer os.Setenv("GOARCH", os.Getenv("GOARCH"))
1933+ os.Setenv("GOARCH", arch)
1934+ if arch == "arm" {
1935+ defer os.Setenv("GOARM", os.Getenv("GOARM"))
1936+ os.Setenv("GOARM", defaultGoArm)
1937+ }
1938+ }
1939+ goCmd := append([]string{"go"}, cmds...)
1940+ testutils.ExecCommand(goCmd...)
1941+}
1942
1943=== added directory '_integration-tests/testutils/common'
1944=== added file '_integration-tests/testutils/common/common.go'
1945--- _integration-tests/testutils/common/common.go 1970-01-01 00:00:00 +0000
1946+++ _integration-tests/testutils/common/common.go 2015-08-02 12:28:18 +0000
1947@@ -0,0 +1,379 @@
1948+// -*- Mode: Go; indent-tabs-mode: t -*-
1949+
1950+/*
1951+ * Copyright (C) 2015 Canonical Ltd
1952+ *
1953+ * This program is free software: you can redistribute it and/or modify
1954+ * it under the terms of the GNU General Public License version 3 as
1955+ * published by the Free Software Foundation.
1956+ *
1957+ * This program is distributed in the hope that it will be useful,
1958+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1959+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1960+ * GNU General Public License for more details.
1961+ *
1962+ * You should have received a copy of the GNU General Public License
1963+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1964+ *
1965+ */
1966+
1967+package common
1968+
1969+import (
1970+ "fmt"
1971+ "io/ioutil"
1972+ "os"
1973+ "os/exec"
1974+ "path/filepath"
1975+ "regexp"
1976+ "strconv"
1977+ "strings"
1978+ "time"
1979+
1980+ check "gopkg.in/check.v1"
1981+
1982+ "launchpad.net/snappy/_integration-tests/testutils/config"
1983+)
1984+
1985+const (
1986+ // BaseAltPartitionPath is the path to the B system partition.
1987+ BaseAltPartitionPath = "/writable/cache/system"
1988+ needsRebootFile = "/tmp/needs-reboot"
1989+ channelCfgFile = "/etc/system-image/channel.ini"
1990+)
1991+
1992+// Cfg is a struct that contains the configuration values passed from the
1993+// host to the testbed.
1994+var Cfg *config.Config
1995+
1996+// SnappySuite is a structure used as a base test suite for all the snappy
1997+// integration tests.
1998+type SnappySuite struct {
1999+ cleanupHandlers []func()
2000+}
2001+
2002+// SetUpSuite disables the snappy autopilot. It will run before all the
2003+// integration suites.
2004+func (s *SnappySuite) SetUpSuite(c *check.C) {
2005+ ExecCommand(c, "sudo", "systemctl", "stop", "snappy-autopilot.timer")
2006+ ExecCommand(c, "sudo", "systemctl", "disable", "snappy-autopilot.timer")
2007+ if !isInRebootProcess() {
2008+ var err error
2009+ Cfg, err = config.ReadConfig(
2010+ "_integration-tests/data/output/testconfig.json")
2011+ c.Assert(err, check.IsNil, check.Commentf("Error reading config: %v", err))
2012+ if Cfg.Update || Cfg.Rollback {
2013+ switchSystemImageConf(c, Cfg.TargetRelease, Cfg.TargetChannel, "0")
2014+ // Always use the installed snappy because we are updating from an old
2015+ // image, so we should not use the snappy from the branch.
2016+ output := ExecCommand(c, "sudo", "/usr/bin/snappy", "update")
2017+ if output != "" {
2018+ RebootWithMark(c, "setupsuite-update")
2019+ }
2020+ }
2021+ } else if CheckRebootMark("setupsuite-update") {
2022+ RemoveRebootMark(c)
2023+ if Cfg.Rollback {
2024+ ExecCommand(c, "sudo", "snappy", "rollback", "ubuntu-core")
2025+ RebootWithMark(c, "setupsuite-rollback")
2026+ }
2027+ } else if CheckRebootMark("setupsuite-rollback") {
2028+ RemoveRebootMark(c)
2029+ }
2030+}
2031+
2032+// SetUpTest handles reboots and stores version information. It will run before
2033+// all the integration tests. Before running a test, it will save the
2034+// ubuntu-core version. If a reboot was requested by a previous test, it
2035+// will skip all the following tests. If the suite is being called after the
2036+// test bed was rebooted, it will resume the test that requested the reboot.
2037+func (s *SnappySuite) SetUpTest(c *check.C) {
2038+ if NeedsReboot() {
2039+ contents, err := ioutil.ReadFile(needsRebootFile)
2040+ c.Assert(err, check.IsNil, check.Commentf("Error reading needs-reboot file %v", err))
2041+ c.Skip(fmt.Sprintf("****** Skipped %s during reboot caused by %s",
2042+ c.TestName(), contents))
2043+ } else {
2044+ if CheckRebootMark("") {
2045+ c.Logf("****** Running %s", c.TestName())
2046+ SetSavedVersion(c, GetCurrentUbuntuCoreVersion(c))
2047+ } else {
2048+ if AfterReboot(c) {
2049+ c.Logf("****** Resuming %s after reboot", c.TestName())
2050+ } else {
2051+ c.Skip(fmt.Sprintf("****** Skipped %s after reboot caused by %s",
2052+ c.TestName(), os.Getenv("ADT_REBOOT_MARK")))
2053+ }
2054+ }
2055+ }
2056+ // clear slice
2057+ s.cleanupHandlers = nil
2058+}
2059+
2060+// TearDownTest cleans up the channel.ini files in case they were changed by
2061+// the test.
2062+// It also runs the cleanup handlers
2063+func (s *SnappySuite) TearDownTest(c *check.C) {
2064+ if !NeedsReboot() && CheckRebootMark("") {
2065+ // Only restore the channel config files if the reboot has been handled.
2066+ m := make(map[string]string)
2067+ m[channelCfgBackupFile()] = "/"
2068+ m[channelCfgOtherBackupFile()] = BaseAltPartitionPath
2069+ for backup, target := range m {
2070+ if _, err := os.Stat(backup); err == nil {
2071+ MakeWritable(c, target)
2072+ defer MakeReadonly(c, target)
2073+ original := filepath.Join(target, channelCfgFile)
2074+ c.Logf("Restoring %s...", original)
2075+ ExecCommand(c, "sudo", "mv", backup, original)
2076+ }
2077+ }
2078+ }
2079+
2080+ // run cleanup handlers and clear the slice
2081+ for _, f := range s.cleanupHandlers {
2082+ f()
2083+ }
2084+ s.cleanupHandlers = nil
2085+}
2086+
2087+// AddCleanup adds a new cleanup function to the test
2088+func (s *SnappySuite) AddCleanup(f func()) {
2089+ s.cleanupHandlers = append(s.cleanupHandlers, f)
2090+}
2091+
2092+func switchSystemImageConf(c *check.C, release, channel, version string) {
2093+ targets := []string{"/", BaseAltPartitionPath}
2094+ for _, target := range targets {
2095+ file := filepath.Join(target, channelCfgFile)
2096+ if _, err := os.Stat(file); err == nil {
2097+ MakeWritable(c, target)
2098+ defer MakeReadonly(c, target)
2099+ replaceSystemImageValues(c, file, release, channel, version)
2100+ }
2101+ }
2102+}
2103+
2104+func replaceSystemImageValues(c *check.C, file, release, channel, version string) {
2105+ c.Log("Switching the system image conf...")
2106+ replaceRegex := map[string]string{
2107+ release: `s#channel: ubuntu-core/.*/\(.*\)#channel: ubuntu-core/%s/\1#`,
2108+ channel: `s#channel: ubuntu-core/\(.*\)/.*#channel: ubuntu-core/\1/%s#`,
2109+ version: `s/build_number: .*/build_number: %s/`,
2110+ }
2111+ for value, regex := range replaceRegex {
2112+ if value != "" {
2113+ ExecCommand(c,
2114+ "sudo", "sed", "-i", fmt.Sprintf(regex, value), file)
2115+ }
2116+ }
2117+ // Leave the new file in the test log.
2118+ ExecCommand(c, "cat", file)
2119+}
2120+
2121+func channelCfgBackupFile() string {
2122+ return filepath.Join(os.Getenv("ADT_ARTIFACTS"), "channel.ini")
2123+}
2124+
2125+func channelCfgOtherBackupFile() string {
2126+ return filepath.Join(os.Getenv("ADT_ARTIFACTS"), "channel.ini.other")
2127+}
2128+
2129+// ExecCommand executes a shell command and returns a string with the output
2130+// of the command. In case of error, it will fail the test.
2131+func ExecCommand(c *check.C, cmds ...string) string {
2132+ fmt.Println(strings.Join(cmds, " "))
2133+ cmd := exec.Command(cmds[0], cmds[1:len(cmds)]...)
2134+ output, err := cmd.CombinedOutput()
2135+ stringOutput := string(output)
2136+ fmt.Print(stringOutput)
2137+ c.Assert(err, check.IsNil, check.Commentf("Error: %v", stringOutput))
2138+ return stringOutput
2139+}
2140+
2141+// ExecCommandToFile executes a shell command and saves the output of the
2142+// command to a file. In case of error, it will fail the test.
2143+func ExecCommandToFile(c *check.C, filename string, cmds ...string) {
2144+ cmd := exec.Command(cmds[0], cmds[1:len(cmds)]...)
2145+ outfile, err := os.Create(filename)
2146+ c.Assert(err, check.IsNil, check.Commentf("Error creating output file %s", filename))
2147+
2148+ defer outfile.Close()
2149+ cmd.Stdout = outfile
2150+
2151+ err = cmd.Run()
2152+ c.Assert(err, check.IsNil, check.Commentf("Error executing command '%v': %v", cmds, err))
2153+}
2154+
2155+// GetCurrentVersion returns the version of the installed and active package.
2156+func GetCurrentVersion(c *check.C, packageName string) string {
2157+ output := ExecCommand(c, "snappy", "list")
2158+ pattern := "(?mU)^" + packageName + " +(.*)$"
2159+ re := regexp.MustCompile(pattern)
2160+ match := re.FindStringSubmatch(string(output))
2161+ c.Assert(match, check.NotNil, check.Commentf("Version not found in %s", output))
2162+
2163+ // match is like "ubuntu-core 2015-06-18 93 ubuntu"
2164+ items := strings.Fields(match[0])
2165+ return items[2]
2166+}
2167+
2168+// GetCurrentUbuntuCoreVersion returns the version number of the installed and
2169+// active ubuntu-core.
2170+func GetCurrentUbuntuCoreVersion(c *check.C) int {
2171+ versionString := GetCurrentVersion(c, "ubuntu-core")
2172+ version, err := strconv.Atoi(versionString)
2173+ c.Assert(err, check.IsNil, check.Commentf("Error converting version to int %v", version))
2174+ return version
2175+}
2176+
2177+// CallFakeUpdate calls snappy update after faking the current version
2178+func CallFakeUpdate(c *check.C) string {
2179+ c.Log("Preparing fake and calling update.")
2180+ fakeAvailableUpdate(c)
2181+ return ExecCommand(c, "sudo", "snappy", "update")
2182+}
2183+
2184+func fakeAvailableUpdate(c *check.C) {
2185+ c.Log("Faking an available update...")
2186+ currentVersion := GetCurrentUbuntuCoreVersion(c)
2187+ switchChannelVersionWithBackup(c, currentVersion-1)
2188+ SetSavedVersion(c, currentVersion-1)
2189+}
2190+
2191+func switchChannelVersionWithBackup(c *check.C, newVersion int) {
2192+ m := make(map[string]string)
2193+ m["/"] = channelCfgBackupFile()
2194+ m[BaseAltPartitionPath] = channelCfgOtherBackupFile()
2195+ for target, backup := range m {
2196+ file := filepath.Join(target, channelCfgFile)
2197+ if _, err := os.Stat(file); err == nil {
2198+ MakeWritable(c, target)
2199+ defer MakeReadonly(c, target)
2200+ // Back up the file. It will be restored during the test tear down.
2201+ ExecCommand(c, "cp", file, backup)
2202+ replaceSystemImageValues(c, file, "", "", strconv.Itoa(newVersion))
2203+ }
2204+ }
2205+}
2206+
2207+// MakeWritable remounts a path with read and write permissions.
2208+func MakeWritable(c *check.C, path string) {
2209+ ExecCommand(c, "sudo", "mount", "-o", "remount,rw", path)
2210+}
2211+
2212+// MakeReadonly remounts a path with only read permissions.
2213+func MakeReadonly(c *check.C, path string) {
2214+ ExecCommand(c, "sudo", "mount", "-o", "remount,ro", path)
2215+}
2216+
2217+// Reboot requests a reboot using the test name as the mark.
2218+func Reboot(c *check.C) {
2219+ RebootWithMark(c, c.TestName())
2220+}
2221+
2222+// RebootWithMark requests a reboot using a specified mark.
2223+func RebootWithMark(c *check.C, mark string) {
2224+ c.Log("Preparing reboot with mark " + mark)
2225+ err := ioutil.WriteFile(needsRebootFile, []byte(mark), 0777)
2226+ c.Assert(err, check.IsNil, check.Commentf("Error writing needs-reboot file: %v", err))
2227+}
2228+
2229+// NeedsReboot returns True if a reboot has been requested by a test.
2230+func NeedsReboot() bool {
2231+ _, err := os.Stat(needsRebootFile)
2232+ return err == nil
2233+}
2234+
2235+// BeforeReboot returns True if the test is running before the test bed has
2236+// been rebooted, or after the test that requested the reboot handled it.
2237+func BeforeReboot() bool {
2238+ return CheckRebootMark("")
2239+}
2240+
2241+// AfterReboot returns True if the test is running after the test bed has been
2242+// rebooted.
2243+func AfterReboot(c *check.C) bool {
2244+ // $ADT_REBOOT_MARK contains the reboot mark, if we have rebooted it'll be the test name
2245+ return strings.HasPrefix(os.Getenv("ADT_REBOOT_MARK"), c.TestName())
2246+}
2247+
2248+// CheckRebootMark returns True if the reboot mark matches the string passed as
2249+// argument.
2250+func CheckRebootMark(mark string) bool {
2251+ return os.Getenv("ADT_REBOOT_MARK") == mark
2252+}
2253+
2254+func isInRebootProcess() bool {
2255+ return !CheckRebootMark("") || NeedsReboot()
2256+}
2257+
2258+// RemoveRebootMark removes the reboot mark to signal that the reboot has been
2259+// handled.
2260+func RemoveRebootMark(c *check.C) {
2261+ os.Setenv("ADT_REBOOT_MARK", "")
2262+}
2263+
2264+// SetSavedVersion saves a version number into a file so it can be used on
2265+// tests after reboots.
2266+func SetSavedVersion(c *check.C, version int) {
2267+ versionFile := getVersionFile()
2268+ err := ioutil.WriteFile(versionFile, []byte(strconv.Itoa(version)), 0777)
2269+ c.Assert(err, check.IsNil, check.Commentf("Error writing version file %s with %s", versionFile, version))
2270+}
2271+
2272+// GetSavedVersion returns the saved version number.
2273+func GetSavedVersion(c *check.C) int {
2274+ versionFile := getVersionFile()
2275+ contents, err := ioutil.ReadFile(versionFile)
2276+ c.Assert(err, check.IsNil, check.Commentf("Error reading version file %s", versionFile))
2277+
2278+ version, err := strconv.Atoi(string(contents))
2279+ c.Assert(err, check.IsNil, check.Commentf("Error converting version %v", contents))
2280+
2281+ return version
2282+}
2283+
2284+func getVersionFile() string {
2285+ return filepath.Join(os.Getenv("ADT_ARTIFACTS"), "version")
2286+}
2287+
2288+// InstallSnap executes the required command to install the specified snap
2289+func InstallSnap(c *check.C, packageName string) string {
2290+ return ExecCommand(c, "sudo", "snappy", "install", packageName, "--allow-unauthenticated")
2291+}
2292+
2293+// RemoveSnap executes the required command to remove the specified snap
2294+func RemoveSnap(c *check.C, packageName string) string {
2295+ return ExecCommand(c, "sudo", "snappy", "remove", packageName)
2296+}
2297+
2298+// WaitForActiveService keeps asking for the active state of the given service until
2299+// it is active or the maximun waiting time expires, in which case an error is returned
2300+func WaitForActiveService(c *check.C, serviceName string) error {
2301+ maxWait := time.Second * 10
2302+ checkInterval := time.Millisecond * 500
2303+
2304+ timer := time.NewTimer(maxWait)
2305+ timeChan := timer.C
2306+
2307+ ticker := time.NewTicker(checkInterval)
2308+ tickChan := ticker.C
2309+
2310+ for {
2311+ select {
2312+ case <-timeChan:
2313+ ticker.Stop()
2314+ journalctlOutput := ExecCommand(c, "sudo", "journalctl", "-u", serviceName)
2315+ return fmt.Errorf("Service %s not active after %s, journalctl output: %s",
2316+ serviceName, maxWait, journalctlOutput)
2317+ case <-tickChan:
2318+ statusOutput := ExecCommand(
2319+ c, "systemctl", "show", "-p", "ActiveState", serviceName)
2320+ if statusOutput == "ActiveState=active\n" {
2321+ timer.Stop()
2322+ return nil
2323+ }
2324+ }
2325+ }
2326+}
2327
2328=== added file '_integration-tests/testutils/common/common_test.go'
2329--- _integration-tests/testutils/common/common_test.go 1970-01-01 00:00:00 +0000
2330+++ _integration-tests/testutils/common/common_test.go 2015-08-02 12:28:18 +0000
2331@@ -0,0 +1,68 @@
2332+// -*- Mode: Go; indent-tabs-mode: t -*-
2333+
2334+/*
2335+ * Copyright (C) 2014-2015 Canonical Ltd
2336+ *
2337+ * This program is free software: you can redistribute it and/or modify
2338+ * it under the terms of the GNU General Public License version 3 as
2339+ * published by the Free Software Foundation.
2340+ *
2341+ * This program is distributed in the hope that it will be useful,
2342+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2343+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2344+ * GNU General Public License for more details.
2345+ *
2346+ * You should have received a copy of the GNU General Public License
2347+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2348+ *
2349+ */
2350+
2351+package common
2352+
2353+import (
2354+ "testing"
2355+
2356+ . "gopkg.in/check.v1"
2357+)
2358+
2359+// Hook up check.v1 into the "go test" runner
2360+func Test(t *testing.T) { TestingT(t) }
2361+
2362+// testing a testsuite - thats so meta
2363+type MetaTestSuite struct {
2364+}
2365+
2366+var _ = Suite(&MetaTestSuite{})
2367+
2368+// test trivial cleanup
2369+func (m *MetaTestSuite) TestCleanupSimple(c *C) {
2370+ canary := "not-called"
2371+ s := SnappySuite{}
2372+
2373+ s.AddCleanup(func() {
2374+ canary = "was-called"
2375+ })
2376+ s.TearDownTest(c)
2377+
2378+ c.Assert(canary, Equals, "was-called")
2379+}
2380+
2381+// a mock method that takes a parameter
2382+func mockCleanupMethodWithParameters(s *string) {
2383+ *s = "was-called"
2384+}
2385+
2386+// test that whle AddCleanup() does not take any parameters itself,
2387+// functions that need parameters can be passed by creating an
2388+// anonymous function as a wrapper
2389+func (m *MetaTestSuite) TestCleanupWithParameters(c *C) {
2390+ canary := "not-called"
2391+ s := SnappySuite{}
2392+
2393+ s.AddCleanup(func() {
2394+ mockCleanupMethodWithParameters(&canary)
2395+ })
2396+ s.TearDownTest(c)
2397+
2398+ c.Assert(canary, Equals, "was-called")
2399+}
2400
2401=== added directory '_integration-tests/testutils/config'
2402=== added file '_integration-tests/testutils/config/config.go'
2403--- _integration-tests/testutils/config/config.go 1970-01-01 00:00:00 +0000
2404+++ _integration-tests/testutils/config/config.go 2015-08-02 12:28:18 +0000
2405@@ -0,0 +1,75 @@
2406+// -*- Mode: Go; indent-tabs-mode: t -*-
2407+
2408+/*
2409+ * Copyright (C) 2015 Canonical Ltd
2410+ *
2411+ * This program is free software: you can redistribute it and/or modify
2412+ * it under the terms of the GNU General Public License version 3 as
2413+ * published by the Free Software Foundation.
2414+ *
2415+ * This program is distributed in the hope that it will be useful,
2416+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2417+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2418+ * GNU General Public License for more details.
2419+ *
2420+ * You should have received a copy of the GNU General Public License
2421+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2422+ *
2423+ */
2424+
2425+package config
2426+
2427+import (
2428+ "encoding/json"
2429+ "fmt"
2430+ "io/ioutil"
2431+ "log"
2432+)
2433+
2434+// Config contains the values to pass to the test bed from the host.
2435+type Config struct {
2436+ FileName string
2437+ Release string
2438+ Channel string
2439+ TargetRelease string
2440+ TargetChannel string
2441+ RemoteTestbed bool
2442+ Update bool
2443+ Rollback bool
2444+}
2445+
2446+// NewConfig is the Config constructor
2447+func NewConfig(fileName, release, channel, targetRelease, targetChannel string, remoteTestbed, update, rollback bool) *Config {
2448+ return &Config{
2449+ FileName: fileName, Release: release, Channel: channel,
2450+ TargetRelease: targetRelease, TargetChannel: targetChannel,
2451+ RemoteTestbed: remoteTestbed, Update: update, Rollback: rollback,
2452+ }
2453+}
2454+
2455+// Write writes the config to a file that will be copied to the test bed.
2456+func (cfg Config) Write() {
2457+ fmt.Println("Writing test config...")
2458+ fmt.Println(cfg)
2459+ encoded, err := json.Marshal(cfg)
2460+ if err != nil {
2461+ log.Panicf("Error encoding the test config: %v", err)
2462+ }
2463+ err = ioutil.WriteFile(cfg.FileName, encoded, 0644)
2464+ if err != nil {
2465+ log.Panicf("Error writing the test config: %v", err)
2466+ }
2467+}
2468+
2469+// ReadConfig the config from a file
2470+func ReadConfig(fileName string) (*Config, error) {
2471+ b, err := ioutil.ReadFile(fileName)
2472+ if err != nil {
2473+ return nil, err
2474+ }
2475+ var decoded Config
2476+ if err = json.Unmarshal(b, &decoded); err != nil {
2477+ return nil, err
2478+ }
2479+ return &decoded, nil
2480+}
2481
2482=== added file '_integration-tests/testutils/config/config.test'
2483Binary files _integration-tests/testutils/config/config.test 1970-01-01 00:00:00 +0000 and _integration-tests/testutils/config/config.test 2015-08-02 12:28:18 +0000 differ
2484=== added file '_integration-tests/testutils/config/config_test.go'
2485--- _integration-tests/testutils/config/config_test.go 1970-01-01 00:00:00 +0000
2486+++ _integration-tests/testutils/config/config_test.go 2015-08-02 12:28:18 +0000
2487@@ -0,0 +1,121 @@
2488+// -*- Mode: Go; indent-tabs-mode: t -*-
2489+
2490+/*
2491+ * Copyright (C) 2014-2015 Canonical Ltd
2492+ *
2493+ * This program is free software: you can redistribute it and/or modify
2494+ * it under the terms of the GNU General Public License version 3 as
2495+ * published by the Free Software Foundation.
2496+ *
2497+ * This program is distributed in the hope that it will be useful,
2498+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2499+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2500+ * GNU General Public License for more details.
2501+ *
2502+ * You should have received a copy of the GNU General Public License
2503+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2504+ *
2505+ */
2506+
2507+package config
2508+
2509+import (
2510+ "fmt"
2511+ "io/ioutil"
2512+ "os"
2513+ "path/filepath"
2514+ "testing"
2515+
2516+ check "gopkg.in/check.v1"
2517+)
2518+
2519+// Hook up check.v1 into the "go test" runner
2520+func Test(t *testing.T) { check.TestingT(t) }
2521+
2522+type ConfigSuite struct{}
2523+
2524+var _ = check.Suite(&ConfigSuite{})
2525+
2526+func testConfigFileName(c *check.C) string {
2527+ tmpDir, err := ioutil.TempDir("", "")
2528+ c.Assert(err, check.IsNil, check.Commentf(
2529+ "Error creating a temporary directory: %v", err))
2530+ return filepath.Join(tmpDir, "test.config")
2531+}
2532+
2533+func testConfigStruct(fileName string) *Config {
2534+ return NewConfig(
2535+ fileName,
2536+ "testrelease", "testchannel", "testtargetrelease", "testtargetchannel",
2537+ true, true, true)
2538+}
2539+func testConfigContents(fileName string) string {
2540+ return `{` +
2541+ fmt.Sprintf(`"FileName":"%s",`, fileName) +
2542+ `"Release":"testrelease",` +
2543+ `"Channel":"testchannel",` +
2544+ `"TargetRelease":"testtargetrelease",` +
2545+ `"TargetChannel":"testtargetchannel",` +
2546+ `"RemoteTestbed":true,` +
2547+ `"Update":true,` +
2548+ `"Rollback":true` +
2549+ `}`
2550+}
2551+
2552+func (s *ConfigSuite) TestWriteConfig(c *check.C) {
2553+ // Do not print to stdout.
2554+ devnull, err := os.Open(os.DevNull)
2555+ c.Assert(err, check.IsNil)
2556+ oldStdout := os.Stdout
2557+ os.Stdout = devnull
2558+ defer func() {
2559+ os.Stdout = oldStdout
2560+ }()
2561+ configFileName := testConfigFileName(c)
2562+
2563+ cfg := testConfigStruct(configFileName)
2564+ cfg.Write()
2565+
2566+ writtenConfig, err := ioutil.ReadFile(configFileName)
2567+ c.Assert(err, check.IsNil, check.Commentf("Error reading config: %v", err))
2568+ c.Assert(string(writtenConfig), check.Equals, testConfigContents(configFileName))
2569+}
2570+
2571+func (s *ConfigSuite) TestReadConfig(c *check.C) {
2572+ configFileName := testConfigFileName(c)
2573+
2574+ configContents := testConfigContents(configFileName)
2575+ ioutil.WriteFile(configFileName, []byte(configContents), 0644)
2576+
2577+ cfg, err := ReadConfig(configFileName)
2578+
2579+ c.Assert(err, check.IsNil, check.Commentf("Error reading config: %v", err))
2580+ c.Assert(cfg, check.DeepEquals, testConfigStruct(configFileName))
2581+}
2582+
2583+func (s *ConfigSuite) TestReadConfigLocalTestBed(c *check.C) {
2584+ configFileName := testConfigFileName(c)
2585+
2586+ configContents := `{` +
2587+ fmt.Sprintf(`"FileName":"%s",`, configFileName) +
2588+ `"Release":"testrelease",` +
2589+ `"Channel":"testchannel",` +
2590+ `"TargetRelease":"testtargetrelease",` +
2591+ `"TargetChannel":"testtargetchannel",` +
2592+ `"RemoteTestbed":false,` +
2593+ `"Update":true,` +
2594+ `"Rollback":true` +
2595+ `}`
2596+
2597+ ioutil.WriteFile(configFileName, []byte(configContents), 0644)
2598+
2599+ cfg, err := ReadConfig(configFileName)
2600+
2601+ testConfigStruct := NewConfig(
2602+ configFileName,
2603+ "testrelease", "testchannel", "testtargetrelease", "testtargetchannel",
2604+ false, true, true)
2605+
2606+ c.Assert(err, check.IsNil, check.Commentf("Error reading config: %v", err))
2607+ c.Assert(cfg, check.DeepEquals, testConfigStruct)
2608+}
2609
2610=== added directory '_integration-tests/testutils/image'
2611=== added file '_integration-tests/testutils/image/image.go'
2612--- _integration-tests/testutils/image/image.go 1970-01-01 00:00:00 +0000
2613+++ _integration-tests/testutils/image/image.go 2015-08-02 12:28:18 +0000
2614@@ -0,0 +1,86 @@
2615+// -*- Mode: Go; indent-tabs-mode: t -*-
2616+
2617+/*
2618+ * Copyright (C) 2015 Canonical Ltd
2619+ *
2620+ * This program is free software: you can redistribute it and/or modify
2621+ * it under the terms of the GNU General Public License version 3 as
2622+ * published by the Free Software Foundation.
2623+ *
2624+ * This program is distributed in the hope that it will be useful,
2625+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2626+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2627+ * GNU General Public License for more details.
2628+ *
2629+ * You should have received a copy of the GNU General Public License
2630+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2631+ *
2632+ */
2633+
2634+package image
2635+
2636+import (
2637+ "fmt"
2638+ "path/filepath"
2639+ "strings"
2640+
2641+ "launchpad.net/snappy/_integration-tests/testutils"
2642+)
2643+
2644+// Image type encapsulates image actions
2645+type Image struct {
2646+ release string
2647+ channel string
2648+ revision string
2649+ baseDir string
2650+}
2651+
2652+// NewImage is the Image constructor
2653+func NewImage(release, channel, revision, baseDir string) *Image {
2654+ return &Image{release: release, channel: channel, revision: revision, baseDir: baseDir}
2655+}
2656+
2657+// UdfCreate forms and executes the UDF command for creating the image
2658+func (img Image) UdfCreate() (string, error) {
2659+ fmt.Println("Creating image...")
2660+
2661+ imageDir := filepath.Join(img.baseDir, "image")
2662+
2663+ testutils.PrepareTargetDir(imageDir)
2664+
2665+ udfCommand := []string{"sudo", "ubuntu-device-flash", "--verbose"}
2666+
2667+ if img.revision != "" {
2668+ udfCommand = append(udfCommand, "--revision", img.revision)
2669+ }
2670+
2671+ imagePath := img.imagePath(imageDir)
2672+
2673+ coreOptions := []string{
2674+ "core", img.release,
2675+ "--output", imagePath,
2676+ "--channel", img.channel,
2677+ "--developer-mode",
2678+ }
2679+
2680+ err := testutils.ExecCommand(append(udfCommand, coreOptions...)...)
2681+
2682+ return imagePath, err
2683+}
2684+
2685+func (img Image) imagePath(imageDir string) string {
2686+ revisionTag := img.revision
2687+ if revisionTag == "" {
2688+ revisionTag = "latest"
2689+ }
2690+
2691+ imageName := strings.Join(
2692+ []string{"snappy", img.release, img.channel, revisionTag}, "-") + ".img"
2693+
2694+ return filepath.Join(imageDir, imageName)
2695+}
2696+
2697+// SetRevision is the setter method for revision
2698+func (img Image) SetRevision(rev string) {
2699+ img.revision = rev
2700+}
2701
2702=== added file '_integration-tests/testutils/testutils.go'
2703--- _integration-tests/testutils/testutils.go 1970-01-01 00:00:00 +0000
2704+++ _integration-tests/testutils/testutils.go 2015-08-02 12:28:18 +0000
2705@@ -0,0 +1,61 @@
2706+// -*- Mode: Go; indent-tabs-mode: t -*-
2707+
2708+/*
2709+ * Copyright (C) 2015 Canonical Ltd
2710+ *
2711+ * This program is free software: you can redistribute it and/or modify
2712+ * it under the terms of the GNU General Public License version 3 as
2713+ * published by the Free Software Foundation.
2714+ *
2715+ * This program is distributed in the hope that it will be useful,
2716+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2717+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2718+ * GNU General Public License for more details.
2719+ *
2720+ * You should have received a copy of the GNU General Public License
2721+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2722+ *
2723+ */
2724+
2725+package testutils
2726+
2727+import (
2728+ "fmt"
2729+ "log"
2730+ "os"
2731+ "os/exec"
2732+ "strings"
2733+)
2734+
2735+// PrepareTargetDir creates the given target directory, removing it previously if it didn't exist
2736+func PrepareTargetDir(targetDir string) {
2737+ if _, err := os.Stat(targetDir); err == nil {
2738+ // dir exists, remove it
2739+ os.RemoveAll(targetDir)
2740+ }
2741+ os.MkdirAll(targetDir, 0777)
2742+}
2743+
2744+// RootPath return the test current working directory.
2745+func RootPath() string {
2746+ dir, err := os.Getwd()
2747+ if err != nil {
2748+ log.Panic(err)
2749+ }
2750+ return dir
2751+}
2752+
2753+// ExecCommand executes the given command and pipes the results to os.Stdout and os.Stderr, returning the resulting error
2754+func ExecCommand(cmds ...string) error {
2755+ fmt.Println(strings.Join(cmds, " "))
2756+
2757+ cmd := exec.Command(cmds[0], cmds[1:]...)
2758+ cmd.Stdout = os.Stdout
2759+ cmd.Stderr = os.Stderr
2760+
2761+ err := cmd.Run()
2762+ if err != nil {
2763+ log.Panicf("Error while running %s: %s\n", cmd.Args, err)
2764+ }
2765+ return err
2766+}
2767
2768=== modified file 'clickdeb/deb_test.go'
2769--- clickdeb/deb_test.go 2015-06-03 19:12:24 +0000
2770+++ clickdeb/deb_test.go 2015-08-02 12:28:18 +0000
2771@@ -27,11 +27,11 @@
2772 "strings"
2773 "testing"
2774
2775- . "launchpad.net/gocheck"
2776+ . "gopkg.in/check.v1"
2777 "launchpad.net/snappy/helpers"
2778 )
2779
2780-// Hook up gocheck into the "go test" runner.
2781+// Hook up check.v1 into the "go test" runner.
2782 func Test(t *testing.T) { TestingT(t) }
2783
2784 type ClickDebTestSuite struct {
2785
2786=== modified file 'cmd/snappy/cmd_low_level_unpack_test.go'
2787--- cmd/snappy/cmd_low_level_unpack_test.go 2015-07-06 18:50:29 +0000
2788+++ cmd/snappy/cmd_low_level_unpack_test.go 2015-08-02 12:28:18 +0000
2789@@ -21,7 +21,7 @@
2790 "os"
2791 "path/filepath"
2792
2793- . "launchpad.net/gocheck"
2794+ . "gopkg.in/check.v1"
2795 )
2796
2797 func makeTempFile(c *C, content string) *os.File {
2798
2799=== modified file 'cmd/snappy/cmd_set_test.go'
2800--- cmd/snappy/cmd_set_test.go 2015-03-26 09:12:58 +0000
2801+++ cmd/snappy/cmd_set_test.go 2015-08-02 12:28:18 +0000
2802@@ -20,10 +20,10 @@
2803 import (
2804 "testing"
2805
2806- . "launchpad.net/gocheck"
2807+ . "gopkg.in/check.v1"
2808 )
2809
2810-// Hook up gocheck into the "go test" runner
2811+// Hook up check.v1 into the "go test" runner
2812 func Test(t *testing.T) { TestingT(t) }
2813
2814 type CmdTestSuite struct {
2815
2816=== modified file 'coreconfig/config_test.go'
2817--- coreconfig/config_test.go 2015-04-14 16:46:57 +0000
2818+++ coreconfig/config_test.go 2015-08-02 12:28:18 +0000
2819@@ -24,10 +24,10 @@
2820 "path/filepath"
2821 "testing"
2822
2823- . "launchpad.net/gocheck"
2824+ . "gopkg.in/check.v1"
2825 )
2826
2827-// Hook up gocheck into the "go test" runner.
2828+// Hook up check.v1 into the "go test" runner.
2829 func Test(t *testing.T) { TestingT(t) }
2830
2831 var (
2832
2833=== modified file 'debian/control'
2834--- debian/control 2015-07-22 06:06:41 +0000
2835+++ debian/control 2015-08-02 12:28:18 +0000
2836@@ -8,10 +8,10 @@
2837 dh-systemd,
2838 fakeroot,
2839 golang-ar-dev,
2840+ golang-check.v1-dev,
2841 golang-go,
2842 golang-go-flags-dev,
2843 golang-go.crypto-dev,
2844- golang-gocheck-dev,
2845 golang-goconfigparser-dev,
2846 golang-juju-loggo-dev,
2847 golang-pb-dev,
2848
2849=== modified file 'dependencies.tsv'
2850--- dependencies.tsv 2015-07-22 12:17:49 +0000
2851+++ dependencies.tsv 2015-08-02 12:28:18 +0000
2852@@ -5,5 +5,5 @@
2853 github.com/juju/loggo git 4c7cbce140ca070eeb59a28f4bf9507e511711f9 2015-02-26T05:51:10Z
2854 github.com/mvo5/goconfigparser git 26426272dda20cc76aa1fa44286dc743d2972fe8 2015-02-12T09:37:50Z
2855 github.com/mvo5/uboot-go git 361f6ebcbb54f389d15dc9faefa000e996ba3e37 2015-07-22T06:53:46Z
2856+gopkg.in/check.v1 git 64131543e7896d5bcc6bd5a76287eb75ea96c673 2014-10-24T13:38:53Z
2857 gopkg.in/yaml.v2 git 49c95bdc21843256fb6c4e0d370a05f24a0bf213 2015-02-24T22:57:58Z
2858-launchpad.net/gocheck bzr gustavo@niemeyer.net-20140225173054-xu9zlkf9kxhvow02 87
2859
2860=== modified file 'helpers/cmp_test.go'
2861--- helpers/cmp_test.go 2015-04-17 06:42:44 +0000
2862+++ helpers/cmp_test.go 2015-08-02 12:28:18 +0000
2863@@ -23,7 +23,7 @@
2864 "path/filepath"
2865 "strings"
2866
2867- . "launchpad.net/gocheck"
2868+ . "gopkg.in/check.v1"
2869 )
2870
2871 func (ts *HTestSuite) TestCmp(c *C) {
2872
2873=== modified file 'helpers/helpers_test.go'
2874--- helpers/helpers_test.go 2015-06-04 15:00:44 +0000
2875+++ helpers/helpers_test.go 2015-08-02 12:28:18 +0000
2876@@ -27,7 +27,7 @@
2877 "path/filepath"
2878 "testing"
2879
2880- . "launchpad.net/gocheck"
2881+ . "gopkg.in/check.v1"
2882 )
2883
2884 func Test(t *testing.T) { TestingT(t) }
2885
2886=== modified file 'helpers/touch_test.go'
2887--- helpers/touch_test.go 2015-04-13 17:00:53 +0000
2888+++ helpers/touch_test.go 2015-08-02 12:28:18 +0000
2889@@ -22,7 +22,7 @@
2890 "path/filepath"
2891 "time"
2892
2893- . "launchpad.net/gocheck"
2894+ . "gopkg.in/check.v1"
2895 )
2896
2897 func (ts *HTestSuite) TestUpdateTimestamp(c *C) {
2898
2899=== modified file 'logger/logger_test.go'
2900--- logger/logger_test.go 2015-03-31 14:12:52 +0000
2901+++ logger/logger_test.go 2015-08-02 12:28:18 +0000
2902@@ -28,7 +28,7 @@
2903 "time"
2904
2905 "github.com/juju/loggo"
2906- . "launchpad.net/gocheck"
2907+ . "gopkg.in/check.v1"
2908 )
2909
2910 func Test(t *testing.T) { TestingT(t) }
2911
2912=== modified file 'oauth/oauth_test.go'
2913--- oauth/oauth_test.go 2015-07-06 18:59:53 +0000
2914+++ oauth/oauth_test.go 2015-08-02 12:28:18 +0000
2915@@ -22,7 +22,7 @@
2916 import (
2917 "testing"
2918
2919- . "launchpad.net/gocheck"
2920+ . "gopkg.in/check.v1"
2921 )
2922
2923 func Test(t *testing.T) { TestingT(t) }
2924
2925=== modified file 'partition/bootloader_grub_test.go'
2926--- partition/bootloader_grub_test.go 2015-04-30 11:28:39 +0000
2927+++ partition/bootloader_grub_test.go 2015-08-02 12:28:18 +0000
2928@@ -22,7 +22,7 @@
2929 "io/ioutil"
2930 "os"
2931
2932- . "launchpad.net/gocheck"
2933+ . "gopkg.in/check.v1"
2934 )
2935
2936 func mockGrubFile(c *C, newPath string, mode os.FileMode) {
2937
2938=== modified file 'partition/bootloader_uboot_test.go'
2939--- partition/bootloader_uboot_test.go 2015-07-23 11:58:40 +0000
2940+++ partition/bootloader_uboot_test.go 2015-08-02 12:28:18 +0000
2941@@ -24,7 +24,7 @@
2942 "strings"
2943 "time"
2944
2945- . "launchpad.net/gocheck"
2946+ . "gopkg.in/check.v1"
2947 "launchpad.net/snappy/helpers"
2948
2949 "github.com/mvo5/uboot-go/uenv"
2950
2951=== modified file 'partition/partition_test.go'
2952--- partition/partition_test.go 2015-07-22 06:06:41 +0000
2953+++ partition/partition_test.go 2015-08-02 12:28:18 +0000
2954@@ -25,10 +25,10 @@
2955 "strings"
2956 "testing"
2957
2958- . "launchpad.net/gocheck"
2959+ . "gopkg.in/check.v1"
2960 )
2961
2962-// Hook up gocheck into the "go test" runner
2963+// Hook up check.v1 into the "go test" runner
2964 func Test(t *testing.T) { TestingT(t) }
2965
2966 // partition specific testsuite
2967
2968=== modified file 'partition/utils_test.go'
2969--- partition/utils_test.go 2015-03-26 09:12:58 +0000
2970+++ partition/utils_test.go 2015-08-02 12:28:18 +0000
2971@@ -18,7 +18,7 @@
2972 package partition
2973
2974 import (
2975- . "launchpad.net/gocheck"
2976+ . "gopkg.in/check.v1"
2977 )
2978
2979 type UtilsTestSuite struct {
2980
2981=== modified file 'policy/policy_test.go'
2982--- policy/policy_test.go 2015-04-17 06:42:44 +0000
2983+++ policy/policy_test.go 2015-08-02 12:28:18 +0000
2984@@ -24,11 +24,12 @@
2985 "path/filepath"
2986 "testing"
2987
2988- . "launchpad.net/gocheck"
2989 "sort"
2990+
2991+ . "gopkg.in/check.v1"
2992 )
2993
2994-// Hook up gocheck into the "go test" runner.
2995+// Hook up check.v1 into the "go test" runner.
2996 func Test(t *testing.T) { TestingT(t) }
2997
2998 type policySuite struct {
2999
3000=== modified file 'priv/priv_test.go'
3001--- priv/priv_test.go 2015-03-26 09:12:58 +0000
3002+++ priv/priv_test.go 2015-08-02 12:28:18 +0000
3003@@ -23,7 +23,7 @@
3004 "path/filepath"
3005 "testing"
3006
3007- . "launchpad.net/gocheck"
3008+ . "gopkg.in/check.v1"
3009 )
3010
3011 func Test(t *testing.T) { TestingT(t) }
3012
3013=== modified file 'progress/progress_test.go'
3014--- progress/progress_test.go 2015-05-29 13:41:55 +0000
3015+++ progress/progress_test.go 2015-08-02 12:28:18 +0000
3016@@ -23,10 +23,10 @@
3017 "os"
3018 "testing"
3019
3020- . "launchpad.net/gocheck"
3021+ . "gopkg.in/check.v1"
3022 )
3023
3024-// Hook up gocheck into the "go test" runner
3025+// Hook up check.v1 into the "go test" runner
3026 func Test(t *testing.T) { TestingT(t) }
3027
3028 type ProgressTestSuite struct {
3029
3030=== modified file 'release/release_test.go'
3031--- release/release_test.go 2015-04-18 19:10:25 +0000
3032+++ release/release_test.go 2015-08-02 12:28:18 +0000
3033@@ -24,10 +24,10 @@
3034 "path/filepath"
3035 "testing"
3036
3037- . "launchpad.net/gocheck"
3038+ . "gopkg.in/check.v1"
3039 )
3040
3041-// Hook up gocheck into the "go test" runner
3042+// Hook up check.v1 into the "go test" runner
3043 func Test(t *testing.T) { TestingT(t) }
3044
3045 type ReleaseTestSuite struct {
3046
3047=== modified file 'run-checks'
3048--- run-checks 2015-03-27 18:35:24 +0000
3049+++ run-checks 2015-08-02 12:28:18 +0000
3050@@ -13,7 +13,7 @@
3051
3052 if [ -n "$fmt" ]; then
3053 echo "Formatting wrong in following files"
3054- echo $fmt
3055+ echo "$fmt"
3056 exit 1
3057 fi
3058
3059@@ -42,14 +42,30 @@
3060 # go vet
3061 echo Running vet
3062 go vet ./...
3063+go vet ./_integration-tests/tests/...
3064+go vet ./_integration-tests/testutils/...
3065
3066 # golint
3067 echo Running lint
3068-lint=$(golint ./...)
3069+lint=$(golint ./... && golint ./_integration-tests/testutils/... && golint ./_integration-tests/tests/...)
3070 if [ -n "$lint" ]; then
3071 echo "Lint complains:"
3072- echo $lint
3073+ echo "$lint"
3074 exit 1
3075 fi
3076
3077+# integration tests
3078+echo Building the integration tests
3079+go build _integration-tests/main.go
3080+
3081+# the rabbit hole
3082+echo Running the tests for the integration testutils
3083+$goctest -v -cover ./_integration-tests/testutils/...
3084+
3085+# integration suite in kvm
3086+if which adt-run >/dev/null 2>&1; then
3087+ echo "Running integration tests on 15.04 edge"
3088+ go run _integration-tests/main.go --snappy-from-branch --release=15.04
3089+fi
3090+
3091 echo "All good, what could possibly go wrong"
3092
3093=== modified file 'snappy/auth_test.go'
3094--- snappy/auth_test.go 2015-07-06 15:35:48 +0000
3095+++ snappy/auth_test.go 2015-08-02 12:28:18 +0000
3096@@ -28,14 +28,14 @@
3097 "launchpad.net/snappy/helpers"
3098 "launchpad.net/snappy/oauth"
3099
3100- . "launchpad.net/gocheck"
3101+ . "gopkg.in/check.v1"
3102 )
3103
3104 const mockStoreInvalidLoginCode = 401
3105 const mockStoreInvalidLogin = `
3106 {
3107- "message": "Provided email/password is not correct.",
3108- "code": "INVALID_CREDENTIALS",
3109+ "message": "Provided email/password is not correct.",
3110+ "code": "INVALID_CREDENTIALS",
3111 "extra": {}
3112 }
3113 `
3114@@ -43,22 +43,22 @@
3115 const mockStoreNeeds2faHTTPCode = 401
3116 const mockStoreNeeds2fa = `
3117 {
3118- "message": "2-factor authentication required.",
3119- "code": "TWOFACTOR_REQUIRED",
3120+ "message": "2-factor authentication required.",
3121+ "code": "TWOFACTOR_REQUIRED",
3122 "extra": {}
3123 }
3124 `
3125
3126 const mockStoreReturnToken = `
3127 {
3128- "openid": "the-open-id-string-that-is-also-the-consumer-key-in-our-store",
3129- "token_name": "some-token-name",
3130- "date_updated": "2015-02-27T15:00:55.062",
3131- "token_key": "the-token-key",
3132- "consumer_secret": "the-consumer-secret",
3133- "href": "/api/v2/tokens/oauth/something",
3134- "date_created": "2015-02-27T14:54:30.863",
3135- "consumer_key": "the-consumer-key",
3136+ "openid": "the-open-id-string-that-is-also-the-consumer-key-in-our-store",
3137+ "token_name": "some-token-name",
3138+ "date_updated": "2015-02-27T15:00:55.062",
3139+ "token_key": "the-token-key",
3140+ "consumer_secret": "the-consumer-secret",
3141+ "href": "/api/v2/tokens/oauth/something",
3142+ "date_created": "2015-02-27T14:54:30.863",
3143+ "consumer_key": "the-consumer-key",
3144 "token_secret": "the-token-secret"
3145 }
3146 `
3147
3148=== modified file 'snappy/build_test.go'
3149--- snappy/build_test.go 2015-05-07 08:28:03 +0000
3150+++ snappy/build_test.go 2015-08-02 12:28:18 +0000
3151@@ -24,7 +24,7 @@
3152 "path/filepath"
3153 "strings"
3154
3155- . "launchpad.net/gocheck"
3156+ . "gopkg.in/check.v1"
3157 )
3158
3159 func makeFakeDuCommand(c *C) string {
3160
3161=== modified file 'snappy/click_test.go'
3162--- snappy/click_test.go 2015-07-06 15:33:44 +0000
3163+++ snappy/click_test.go 2015-08-02 12:28:18 +0000
3164@@ -28,7 +28,7 @@
3165 "strings"
3166
3167 "github.com/mvo5/goconfigparser"
3168- . "launchpad.net/gocheck"
3169+ . "gopkg.in/check.v1"
3170
3171 "launchpad.net/snappy/clickdeb"
3172 "launchpad.net/snappy/helpers"
3173@@ -1118,7 +1118,7 @@
3174 bins := []string{"hello", "goodbye", "missya"}
3175 for i := range verbs {
3176 expected := fmt.Sprintf("Exec%s=/usr/bin/ubuntu-core-launcher hello-app.%s %s_svc1_1.10 %s/bin/%s", verbs[i], testNamespace, helloAppComposedName, baseDirWithoutRootPrefix, bins[i])
3177- c.Check(string(content), Matches, "(?ms).*^"+regexp.QuoteMeta(expected)) // gocheck adds ^ and $ around the regexp provided
3178+ c.Check(string(content), Matches, "(?ms).*^"+regexp.QuoteMeta(expected)) // check.v1 adds ^ and $ around the regexp provided
3179 }
3180 }
3181
3182
3183=== modified file 'snappy/common_test.go'
3184--- snappy/common_test.go 2015-04-30 16:56:15 +0000
3185+++ snappy/common_test.go 2015-08-02 12:28:18 +0000
3186@@ -26,9 +26,10 @@
3187
3188 "launchpad.net/snappy/helpers"
3189
3190+ "strings"
3191+
3192+ . "gopkg.in/check.v1"
3193 "gopkg.in/yaml.v2"
3194- . "launchpad.net/gocheck"
3195- "strings"
3196 )
3197
3198 const (
3199
3200=== modified file 'snappy/config_test.go'
3201--- snappy/config_test.go 2015-04-17 20:32:02 +0000
3202+++ snappy/config_test.go 2015-08-02 12:28:18 +0000
3203@@ -23,7 +23,7 @@
3204 "os"
3205 "path/filepath"
3206
3207- . "launchpad.net/gocheck"
3208+ . "gopkg.in/check.v1"
3209 )
3210
3211 const configPassthroughScript = `#!/bin/sh
3212
3213=== modified file 'snappy/datadir_test.go'
3214--- snappy/datadir_test.go 2015-04-20 13:01:02 +0000
3215+++ snappy/datadir_test.go 2015-08-02 12:28:18 +0000
3216@@ -22,7 +22,7 @@
3217 "path/filepath"
3218 "strings"
3219
3220- . "launchpad.net/gocheck"
3221+ . "gopkg.in/check.v1"
3222 )
3223
3224 type DataDirSuite struct{}
3225
3226=== modified file 'snappy/dbus_test.go'
3227--- snappy/dbus_test.go 2015-04-19 01:24:03 +0000
3228+++ snappy/dbus_test.go 2015-08-02 12:28:18 +0000
3229@@ -1,7 +1,7 @@
3230 package snappy
3231
3232 import (
3233- . "launchpad.net/gocheck"
3234+ . "gopkg.in/check.v1"
3235 )
3236
3237 // systemd's testsuite
3238
3239=== modified file 'snappy/firstboot_test.go'
3240--- snappy/firstboot_test.go 2015-04-14 16:46:57 +0000
3241+++ snappy/firstboot_test.go 2015-08-02 12:28:18 +0000
3242@@ -22,7 +22,7 @@
3243 "os"
3244 "path/filepath"
3245
3246- . "launchpad.net/gocheck"
3247+ . "gopkg.in/check.v1"
3248 )
3249
3250 type fakePart struct {
3251
3252=== modified file 'snappy/hashes_test.go'
3253--- snappy/hashes_test.go 2015-03-31 14:12:52 +0000
3254+++ snappy/hashes_test.go 2015-08-02 12:28:18 +0000
3255@@ -24,7 +24,7 @@
3256
3257 "gopkg.in/yaml.v2"
3258
3259- . "launchpad.net/gocheck"
3260+ . "gopkg.in/check.v1"
3261 )
3262
3263 var fileHashYaml = `name: foo
3264
3265=== modified file 'snappy/hwaccess_test.go'
3266--- snappy/hwaccess_test.go 2015-05-01 12:32:42 +0000
3267+++ snappy/hwaccess_test.go 2015-08-02 12:28:18 +0000
3268@@ -23,7 +23,7 @@
3269
3270 "launchpad.net/snappy/helpers"
3271
3272- . "launchpad.net/gocheck"
3273+ . "gopkg.in/check.v1"
3274 )
3275
3276 func mockRegenerateAppArmorRules() *bool {
3277
3278=== modified file 'snappy/install_test.go'
3279--- snappy/install_test.go 2015-04-17 20:54:23 +0000
3280+++ snappy/install_test.go 2015-08-02 12:28:18 +0000
3281@@ -26,7 +26,7 @@
3282 "os"
3283 "path/filepath"
3284
3285- . "launchpad.net/gocheck"
3286+ . "gopkg.in/check.v1"
3287 "launchpad.net/snappy/helpers"
3288 "launchpad.net/snappy/progress"
3289 )
3290
3291=== modified file 'snappy/oem_test.go'
3292--- snappy/oem_test.go 2015-04-22 12:55:07 +0000
3293+++ snappy/oem_test.go 2015-08-02 12:28:18 +0000
3294@@ -26,7 +26,7 @@
3295
3296 "launchpad.net/snappy/helpers"
3297
3298- . "launchpad.net/gocheck"
3299+ . "gopkg.in/check.v1"
3300 )
3301
3302 type OemSuite struct {
3303
3304=== modified file 'snappy/parts_test.go'
3305--- snappy/parts_test.go 2015-04-21 12:05:22 +0000
3306+++ snappy/parts_test.go 2015-08-02 12:28:18 +0000
3307@@ -22,7 +22,7 @@
3308 "os"
3309 "path/filepath"
3310
3311- . "launchpad.net/gocheck"
3312+ . "gopkg.in/check.v1"
3313
3314 "launchpad.net/snappy/progress"
3315 )
3316
3317=== modified file 'snappy/purge_test.go'
3318--- snappy/purge_test.go 2015-04-20 19:26:04 +0000
3319+++ snappy/purge_test.go 2015-08-02 12:28:18 +0000
3320@@ -23,7 +23,7 @@
3321 "os"
3322 "path/filepath"
3323
3324- . "launchpad.net/gocheck"
3325+ . "gopkg.in/check.v1"
3326
3327 "launchpad.net/snappy/helpers"
3328 "launchpad.net/snappy/systemd"
3329
3330=== modified file 'snappy/remove_test.go'
3331--- snappy/remove_test.go 2015-04-15 13:17:22 +0000
3332+++ snappy/remove_test.go 2015-08-02 12:28:18 +0000
3333@@ -18,7 +18,7 @@
3334 package snappy
3335
3336 import (
3337- . "launchpad.net/gocheck"
3338+ . "gopkg.in/check.v1"
3339 "launchpad.net/snappy/progress"
3340 )
3341
3342
3343=== modified file 'snappy/rollback_test.go'
3344--- snappy/rollback_test.go 2015-04-30 16:56:15 +0000
3345+++ snappy/rollback_test.go 2015-08-02 12:28:18 +0000
3346@@ -18,7 +18,7 @@
3347 package snappy
3348
3349 import (
3350- . "launchpad.net/gocheck"
3351+ . "gopkg.in/check.v1"
3352 )
3353
3354 func (s *SnapTestSuite) TestRollbackWithVersion(c *C) {
3355
3356=== modified file 'snappy/security_test.go'
3357--- snappy/security_test.go 2015-07-06 19:56:46 +0000
3358+++ snappy/security_test.go 2015-08-02 12:28:18 +0000
3359@@ -5,7 +5,7 @@
3360 "os"
3361 "path/filepath"
3362
3363- . "launchpad.net/gocheck"
3364+ . "gopkg.in/check.v1"
3365 )
3366
3367 type SecurityTestSuite struct {
3368
3369=== modified file 'snappy/set_test.go'
3370--- snappy/set_test.go 2015-04-30 16:56:15 +0000
3371+++ snappy/set_test.go 2015-08-02 12:28:18 +0000
3372@@ -22,7 +22,7 @@
3373 "path/filepath"
3374 "strings"
3375
3376- . "launchpad.net/gocheck"
3377+ . "gopkg.in/check.v1"
3378
3379 "launchpad.net/snappy/progress"
3380 )
3381
3382=== modified file 'snappy/snapp_test.go'
3383--- snappy/snapp_test.go 2015-07-07 02:35:22 +0000
3384+++ snappy/snapp_test.go 2015-08-02 12:28:18 +0000
3385@@ -34,7 +34,7 @@
3386 "launchpad.net/snappy/release"
3387 "launchpad.net/snappy/systemd"
3388
3389- . "launchpad.net/gocheck"
3390+ . "gopkg.in/check.v1"
3391 )
3392
3393 type SnapTestSuite struct {
3394
3395=== modified file 'snappy/sort_test.go'
3396--- snappy/sort_test.go 2015-03-26 09:12:58 +0000
3397+++ snappy/sort_test.go 2015-08-02 12:28:18 +0000
3398@@ -20,7 +20,7 @@
3399 import (
3400 "sort"
3401
3402- . "launchpad.net/gocheck"
3403+ . "gopkg.in/check.v1"
3404 )
3405
3406 type SortTestSuite struct {
3407
3408=== modified file 'snappy/systemimage_native_test.go'
3409--- snappy/systemimage_native_test.go 2015-03-26 09:12:58 +0000
3410+++ snappy/systemimage_native_test.go 2015-08-02 12:28:18 +0000
3411@@ -25,7 +25,7 @@
3412 "path/filepath"
3413 "time"
3414
3415- . "launchpad.net/gocheck"
3416+ . "gopkg.in/check.v1"
3417 )
3418
3419 /* acquired via:
3420
3421=== modified file 'snappy/systemimage_test.go'
3422--- snappy/systemimage_test.go 2015-07-15 07:37:44 +0000
3423+++ snappy/systemimage_test.go 2015-08-02 12:28:18 +0000
3424@@ -28,10 +28,10 @@
3425
3426 partition "launchpad.net/snappy/partition"
3427
3428- . "launchpad.net/gocheck"
3429+ . "gopkg.in/check.v1"
3430 )
3431
3432-// Hook up gocheck into the "go test" runner
3433+// Hook up check.v1 into the "go test" runner
3434 func Test(t *testing.T) { TestingT(t) }
3435
3436 type SITestSuite struct {
3437
3438=== modified file 'snappy/timeout_test.go'
3439--- snappy/timeout_test.go 2015-04-13 22:20:58 +0000
3440+++ snappy/timeout_test.go 2015-08-02 12:28:18 +0000
3441@@ -21,7 +21,7 @@
3442 "encoding/json"
3443 "time"
3444
3445- . "launchpad.net/gocheck"
3446+ . "gopkg.in/check.v1"
3447 )
3448
3449 func (s *SnapTestSuite) TestTimeoutMarshal(c *C) {
3450
3451=== modified file 'snappy/udev_test.go'
3452--- snappy/udev_test.go 2015-04-20 12:50:45 +0000
3453+++ snappy/udev_test.go 2015-08-02 12:28:18 +0000
3454@@ -18,7 +18,7 @@
3455 package snappy
3456
3457 import (
3458- . "launchpad.net/gocheck"
3459+ . "gopkg.in/check.v1"
3460 )
3461
3462 func (s *SnapTestSuite) TestGetUdevPartName(c *C) {
3463
3464=== modified file 'systemd/systemd_test.go'
3465--- systemd/systemd_test.go 2015-07-06 15:33:44 +0000
3466+++ systemd/systemd_test.go 2015-08-02 12:28:18 +0000
3467@@ -24,7 +24,7 @@
3468 "testing"
3469 "time"
3470
3471- . "launchpad.net/gocheck"
3472+ . "gopkg.in/check.v1"
3473
3474 "launchpad.net/snappy/helpers"
3475 )
3476@@ -37,7 +37,7 @@
3477 tr.msgs = append(tr.msgs, msg)
3478 }
3479
3480-// Hook up gocheck into the "go test" runner
3481+// Hook up check.v1 into the "go test" runner
3482 func Test(t *testing.T) { TestingT(t) }
3483
3484 // systemd's testsuite

Subscribers

People subscribed via source and target branches

to all changes: