Merge ~smoser/cloud-init:cleanup/test-more-files-collect into cloud-init:master

Proposed by Scott Moser
Status: Merged
Approved by: Chad Smith
Approved revision: e975f1b176ab722a09abd387bff00efc2c40358c
Merge reported by: Chad Smith
Merged at revision: bc84f5023f795c261e32cf0690b2d29e12cfaedd
Proposed branch: ~smoser/cloud-init:cleanup/test-more-files-collect
Merge into: cloud-init:master
Diff against target: 171 lines (+52/-33)
5 files modified
tests/cloud_tests/collect.py (+7/-0)
tests/cloud_tests/platforms/lxd/instance.py (+19/-24)
tests/cloud_tests/testcases.yaml (+21/-6)
tests/cloud_tests/testcases/base.py (+4/-2)
tests/cloud_tests/verify.py (+1/-1)
Reviewer Review Type Date Requested Status
Chad Smith Approve
Ryan Harper Approve
Server Team CI bot continuous-integration Approve
Review via email: mp+336498@code.launchpad.net

Commit message

tests: Collect script output as binary, collect systemd journal, fix lxd.

This adds collection a gzip compressed systemd journal on systemd systems.
The file can later be reviewed with:
  zcat system.journal.gz > system.journal
  journalctl --file=system.journal [-o short-monotonic ..]

To support this:
  * modify test harness infrastructure to not assume content is utf-8.
  * fix lxd platform to support make '_execute' return bytes rather
    than a string. https://github.com/lxc/pylxd/issues/268

Also switched the base collectors to use /bin/sh as others already did.

Description of the change

see commit message

To post a comment you must log in.
Revision history for this message
Ryan Harper (raharper) wrote :

Add a comment that you switched to using /bin/sh instead of bash in several scripts. Some comments inline.

Revision history for this message
Server Team CI bot (server-team-bot) wrote :

PASSED: Continuous integration, rev:08639703c83e19242059c2d73df373a05e89746a
https://jenkins.ubuntu.com/server/job/cloud-init-ci/720/
Executed test runs:
    SUCCESS: Checkout
    SUCCESS: Unit & Style Tests
    SUCCESS: Ubuntu LTS: Build
    SUCCESS: Ubuntu LTS: Integration
    SUCCESS: MAAS Compatability Testing
    IN_PROGRESS: Declarative: Post Actions

Click here to trigger a rebuild:
https://jenkins.ubuntu.com/server/job/cloud-init-ci/720/rebuild

review: Approve (continuous-integration)
Revision history for this message
Scott Moser (smoser) :
Revision history for this message
Server Team CI bot (server-team-bot) wrote :

PASSED: Continuous integration, rev:b9a418a6795730bb7b88f1273d12ab5cafa29cc6
https://jenkins.ubuntu.com/server/job/cloud-init-ci/724/
Executed test runs:
    SUCCESS: Checkout
    SUCCESS: Unit & Style Tests
    SUCCESS: Ubuntu LTS: Build
    SUCCESS: Ubuntu LTS: Integration
    SUCCESS: MAAS Compatability Testing
    IN_PROGRESS: Declarative: Post Actions

Click here to trigger a rebuild:
https://jenkins.ubuntu.com/server/job/cloud-init-ci/724/rebuild

review: Approve (continuous-integration)
Revision history for this message
Server Team CI bot (server-team-bot) wrote :

PASSED: Continuous integration, rev:4bcbc7bd9dea686a62576b28bc8b854a992c3221
https://jenkins.ubuntu.com/server/job/cloud-init-ci/726/
Executed test runs:
    SUCCESS: Checkout
    SUCCESS: Unit & Style Tests
    SUCCESS: Ubuntu LTS: Build
    SUCCESS: Ubuntu LTS: Integration
    SUCCESS: MAAS Compatability Testing
    IN_PROGRESS: Declarative: Post Actions

Click here to trigger a rebuild:
https://jenkins.ubuntu.com/server/job/cloud-init-ci/726/rebuild

review: Approve (continuous-integration)
Revision history for this message
Server Team CI bot (server-team-bot) wrote :

PASSED: Continuous integration, rev:e975f1b176ab722a09abd387bff00efc2c40358c
https://jenkins.ubuntu.com/server/job/cloud-init-ci/729/
Executed test runs:
    SUCCESS: Checkout
    SUCCESS: Unit & Style Tests
    SUCCESS: Ubuntu LTS: Build
    SUCCESS: Ubuntu LTS: Integration
    SUCCESS: MAAS Compatability Testing
    IN_PROGRESS: Declarative: Post Actions

Click here to trigger a rebuild:
https://jenkins.ubuntu.com/server/job/cloud-init-ci/729/rebuild

review: Approve (continuous-integration)
Revision history for this message
Ryan Harper (raharper) :
review: Approve
Revision history for this message
Chad Smith (chad.smith) wrote :

+1 on this thanks.

review: Approve

There was an error fetching revisions from git servers. Please try again in a few minutes. If the problem persists, contact Launchpad support.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/tests/cloud_tests/collect.py b/tests/cloud_tests/collect.py
2index 33acbb1..5ea88e5 100644
3--- a/tests/cloud_tests/collect.py
4+++ b/tests/cloud_tests/collect.py
5@@ -24,6 +24,13 @@ def collect_script(instance, base_dir, script, script_name):
6 (out, err, exit) = instance.run_script(
7 script.encode(), rcs=False,
8 description='collect: {}'.format(script_name))
9+ if err:
10+ LOG.debug("collect script %s had stderr: %s", script_name, err)
11+ if not isinstance(out, bytes):
12+ raise util.PlatformError(
13+ "Collection of '%s' returned type %s, expected bytes: %s" %
14+ (script_name, type(out), out))
15+
16 c_util.write_file(os.path.join(base_dir, script_name), out)
17
18
19diff --git a/tests/cloud_tests/platforms/lxd/instance.py b/tests/cloud_tests/platforms/lxd/instance.py
20index 0d697c0..d2d2a1f 100644
21--- a/tests/cloud_tests/platforms/lxd/instance.py
22+++ b/tests/cloud_tests/platforms/lxd/instance.py
23@@ -6,6 +6,8 @@ import os
24 import shutil
25 from tempfile import mkdtemp
26
27+from cloudinit.util import subp, ProcessExecutionError
28+
29 from ..instances import Instance
30
31
32@@ -29,6 +31,7 @@ class LXDInstance(Instance):
33 platform, name, properties, config, features)
34 self.tmpd = mkdtemp(prefix="%s-%s" % (type(self).__name__, name))
35 self._setup_console_log()
36+ self.name = name
37
38 @property
39 def pylxd_container(self):
40@@ -55,33 +58,25 @@ class LXDInstance(Instance):
41 if env is None:
42 env = {}
43
44- if stdin is not None:
45- # pylxd does not support input to execute.
46- # https://github.com/lxc/pylxd/issues/244
47- #
48- # The solution here is write a tmp file in the container
49- # and then execute a shell that sets it standard in to
50- # be from that file, removes it, and calls the comand.
51- tmpf = self.tmpfile()
52- self.write_data(tmpf, stdin)
53- ncmd = 'exec <"{tmpf}"; rm -f "{tmpf}"; exec "$@"'
54- command = (['sh', '-c', ncmd.format(tmpf=tmpf), 'stdinhack'] +
55- list(command))
56+ env_args = []
57+ if env:
58+ env_args = ['env'] + ["%s=%s" for k, v in env.items()]
59
60 # ensure instance is running and execute the command
61 self.start()
62- # execute returns a ContainerExecuteResult, named tuple
63- # (exit_code, stdout, stderr)
64- res = self.pylxd_container.execute(command, environment=env)
65-
66- # get out, exit and err from pylxd return
67- if not hasattr(res, 'exit_code'):
68- # pylxd 2.1.3 and earlier only return out and err, no exit
69- raise RuntimeError(
70- "No 'exit_code' in pylxd.container.execute return.\n"
71- "pylxd > 2.2 is required.")
72-
73- return res.stdout, res.stderr, res.exit_code
74+
75+ # Use cmdline client due to https://github.com/lxc/pylxd/issues/268
76+ exit_code = 0
77+ try:
78+ stdout, stderr = subp(
79+ ['lxc', 'exec', self.name, '--'] + env_args + list(command),
80+ data=stdin, decode=False)
81+ except ProcessExecutionError as e:
82+ exit_code = e.exit_code
83+ stdout = e.stdout
84+ stderr = e.stderr
85+
86+ return stdout, stderr, exit_code
87
88 def read_data(self, remote_path, decode=False):
89 """Read data from instance filesystem.
90diff --git a/tests/cloud_tests/testcases.yaml b/tests/cloud_tests/testcases.yaml
91index 7183e01..8e0fb62 100644
92--- a/tests/cloud_tests/testcases.yaml
93+++ b/tests/cloud_tests/testcases.yaml
94@@ -7,22 +7,37 @@ base_test_data:
95 #cloud-config
96 collect_scripts:
97 cloud-init.log: |
98- #!/bin/bash
99+ #!/bin/sh
100 cat /var/log/cloud-init.log
101 cloud-init-output.log: |
102- #!/bin/bash
103+ #!/bin/sh
104 cat /var/log/cloud-init-output.log
105 instance-id: |
106- #!/bin/bash
107+ #!/bin/sh
108 cat /run/cloud-init/.instance-id
109 result.json: |
110- #!/bin/bash
111+ #!/bin/sh
112 cat /run/cloud-init/result.json
113 status.json: |
114- #!/bin/bash
115+ #!/bin/sh
116 cat /run/cloud-init/status.json
117 cloud-init-version: |
118- #!/bin/bash
119+ #!/bin/sh
120 dpkg-query -W -f='${Version}' cloud-init
121+ system.journal.gz: |
122+ #!/bin/sh
123+ [ -d /run/systemd ] || { echo "not systemd."; exit 0; }
124+ fail() { echo "ERROR:" "$@" 1>&2; exit 1; }
125+ journal=""
126+ for d in /run/log/journal /var/log/journal; do
127+ for f in $d/*/system.journal; do
128+ [ -f "$f" ] || continue
129+ [ -z "$journal" ] ||
130+ fail "multiple journal found: $f $journal."
131+ journal="$f"
132+ done
133+ done
134+ [ -f "$journal" ] || fail "no journal file found."
135+ gzip --to-stdout "$journal"
136
137 # vi: ts=4 expandtab
138diff --git a/tests/cloud_tests/testcases/base.py b/tests/cloud_tests/testcases/base.py
139index 1c5b540..20e9595 100644
140--- a/tests/cloud_tests/testcases/base.py
141+++ b/tests/cloud_tests/testcases/base.py
142@@ -30,12 +30,14 @@ class CloudTestCase(unittest.TestCase):
143 raise AssertionError('Key "{}" not in cloud config'.format(name))
144 return self.cloud_config[name]
145
146- def get_data_file(self, name):
147+ def get_data_file(self, name, decode=True):
148 """Get data file failing test if it is not present."""
149 if name not in self.data:
150 raise AssertionError('File "{}" missing from collect data'
151 .format(name))
152- return self.data[name]
153+ if not decode:
154+ return self.data[name]
155+ return self.data[name].decode('utf-8')
156
157 def get_instance_id(self):
158 """Get recorded instance id."""
159diff --git a/tests/cloud_tests/verify.py b/tests/cloud_tests/verify.py
160index fc1efcf..2a9fd52 100644
161--- a/tests/cloud_tests/verify.py
162+++ b/tests/cloud_tests/verify.py
163@@ -29,7 +29,7 @@ def verify_data(base_dir, tests):
164 data = {}
165 test_dir = os.path.join(base_dir, test_name)
166 for script_name in os.listdir(test_dir):
167- with open(os.path.join(test_dir, script_name), 'r') as fp:
168+ with open(os.path.join(test_dir, script_name), 'rb') as fp:
169 data[script_name] = fp.read()
170
171 # get test suite and launch tests

Subscribers

People subscribed via source and target branches