Merge lp:~raharper/curtin/trunk.vmtest-reuse-output into lp:~curtin-dev/curtin/trunk
- trunk.vmtest-reuse-output
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 500 |
Proposed branch: | lp:~raharper/curtin/trunk.vmtest-reuse-output |
Merge into: | lp:~curtin-dev/curtin/trunk |
Diff against target: |
220 lines (+62/-37) 3 files modified
doc/topics/integration-testing.rst (+9/-0) tests/vmtests/__init__.py (+46/-34) tools/jenkins-runner (+7/-3) |
To merge this branch: | bzr merge lp:~raharper/curtin/trunk.vmtest-reuse-output |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Scott Moser (community) | Approve | ||
Server Team CI bot | continuous-integration | Approve | |
Review via email: mp+318150@code.launchpad.net |
Commit message
Description of the change
Allow re-use of vmtest output
When developing or debugging vmtest unittest failures of collected data
it's useful to skip the install/
unittest against a directory of collected output.
Introduce CURTIN_
stages. If the directory is missing, the test runs as usual.
CURTIN_
tests/
Server Team CI bot (server-team-bot) wrote : | # |
Scott Moser (smoser) wrote : | # |
add documentation of the new environment variable (as you have in the commit message)
the other question is that this change possibly hides failures ...
I'm just reading the diff in line and not thinking too much, but if an error causaed there to be no grub_config or reporting_config, it looks like we'd now just go on, where before we would fail a test.
Ryan Harper (raharper) wrote : | # |
On Thu, Feb 23, 2017 at 2:18 PM, Scott Moser <email address hidden> wrote:
> Review: Needs Fixing
>
> add documentation of the new environment variable (as you have in the
> commit message)
>
ACK
>
> the other question is that this change possibly hides failures ...
> I'm just reading the diff in line and not thinking too much, but if an
> error causaed there to be no grub_config or reporting_config, it looks like
> we'd now just go on, where before we would fail a test.
>
we avoid *rewriting* files if they exist; I don't think that skips any
errors;
The basic concept is, if the tempdir has a cls.__name__ directory, to
rebuild the cls and TempDir paths to files that may get referenced in the
unittests;
however, if we're re-using, we don't want to rewrite the contents a second
time; so all of those checks are if not os.path.
>
> --
> https:/
> reuse-output/
> You are the owner of lp:~raharper/curtin/trunk.vmtest-reuse-output.
>
Scott Moser (smoser) wrote : | # |
On Thu, 23 Feb 2017, Ryan Harper wrote:
> On Thu, Feb 23, 2017 at 2:18 PM, Scott Moser <email address hidden> wrote:
>
> > Review: Needs Fixing
> >
> > add documentation of the new environment variable (as you have in the
> > commit message)
> >
>
> ACK
>
>
> >
> > the other question is that this change possibly hides failures ...
> > I'm just reading the diff in line and not thinking too much, but if an
> > error causaed there to be no grub_config or reporting_config, it looks like
> > we'd now just go on, where before we would fail a test.
> >
>
> we avoid *rewriting* files if they exist; I don't think that skips any
> errors;
>
> The basic concept is, if the tempdir has a cls.__name__ directory, to
> rebuild the cls and TempDir paths to files that may get referenced in the
> unittests;
> however, if we're re-using, we don't want to rewrite the contents a second
> time; so all of those checks are if not os.path.
>
Thats sane then.
As I said, i just looked quick an thought maybe you were just going to
skip over errors.
Server Team CI bot (server-team-bot) wrote : | # |
PASSED: Continuous integration, rev:472
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
Click here to trigger a rebuild:
https:/
Server Team CI bot (server-team-bot) wrote : | # |
PASSED: Continuous integration, rev:472
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
Click here to trigger a rebuild:
https:/
- 473. By Ryan Harper
-
merge from trunk
- 474. By Ryan Harper
-
Do not attempt to re-write launch configs when reusing result data
- 475. By Ryan Harper
-
merge from trunk
Server Team CI bot (server-team-bot) wrote : | # |
PASSED: Continuous integration, rev:475
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
Click here to trigger a rebuild:
https:/
- 476. By Ryan Harper
-
merge from trunk
Server Team CI bot (server-team-bot) wrote : | # |
PASSED: Continuous integration, rev:476
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
Click here to trigger a rebuild:
https:/
- 477. By Ryan Harper
-
merge from trunk
Server Team CI bot (server-team-bot) wrote : | # |
PASSED: Continuous integration, rev:477
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
Click here to trigger a rebuild:
https:/
Scott Moser (smoser) wrote : | # |
Over all this looks really good. I have some minor nits.
I do think we should respect/expect CURTIN_
Ryan Harper (raharper) wrote : | # |
Thanks for the review, I'll clean up the mkdir stuff, make sure to use the environment variable to set cls.restored value instead of just the presence of the tempdir.
- 478. By Ryan Harper
-
merge from trunk
- 479. By Ryan Harper
-
Use environment variable to set restored class attribute
- 480. By Ryan Harper
-
Fix exception message (include the tmpdir value)
- 481. By Ryan Harper
-
Reorder exception message
Server Team CI bot (server-team-bot) wrote : | # |
PASSED: Continuous integration, rev:481
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
Click here to trigger a rebuild:
https:/
Scott Moser (smoser) wrote : | # |
one tiny nit. fix that and i approve.
- 482. By Ryan Harper
-
bool() REUSE_TOPDIR integer
- 483. By Ryan Harper
-
Add documentation of CURTIN_
VMTEST_ REUSE_TOPDIR
Preview Diff
1 | === modified file 'doc/topics/integration-testing.rst' |
2 | --- doc/topics/integration-testing.rst 2017-04-26 16:27:20 +0000 |
3 | +++ doc/topics/integration-testing.rst 2017-05-19 20:26:52 +0000 |
4 | @@ -169,6 +169,15 @@ |
5 | If you set this value, you must ensure that the directory is either |
6 | non-existent or clean. |
7 | |
8 | +- ``CURTIN_VMTEST_REUSE_TOPDIR``: default 0 |
9 | + |
10 | + If this variable is set to 1, then vmtest will detect if the test |
11 | + specified already exists in the configured ``CURTIN_VMTEST_TOPDIR`` |
12 | + location. If present, vmtest will skip executing the install and |
13 | + boot phase of vmtest, and install just execute the unittests |
14 | + specified. This allows developers to re-run unittests on existing |
15 | + data that's already been collected. |
16 | + |
17 | - ``CURTIN_VMTEST_LOG``: default $TMPDIR/vmtest-<timestamp>.log |
18 | |
19 | Vmtest writes extended log information to this file. |
20 | |
21 | === modified file 'tests/vmtests/__init__.py' |
22 | --- tests/vmtests/__init__.py 2017-05-19 15:23:30 +0000 |
23 | +++ tests/vmtests/__init__.py 2017-05-19 20:26:52 +0000 |
24 | @@ -44,6 +44,7 @@ |
25 | OUTPUT_DISK_NAME = 'output_disk.img' |
26 | BOOT_TIMEOUT = int(os.environ.get("CURTIN_VMTEST_BOOT_TIMEOUT", 300)) |
27 | INSTALL_TIMEOUT = int(os.environ.get("CURTIN_VMTEST_INSTALL_TIMEOUT", 3000)) |
28 | +REUSE_TOPDIR = bool(int(os.environ.get("CURTIN_VMTEST_REUSE_TOPDIR", 0))) |
29 | |
30 | _TOPDIR = None |
31 | |
32 | @@ -260,16 +261,9 @@ |
33 | output_disk = None |
34 | |
35 | def __init__(self, name, user_data): |
36 | + self.restored = REUSE_TOPDIR |
37 | # Create tmpdir |
38 | self.tmpdir = os.path.join(_topdir(), name) |
39 | - try: |
40 | - os.mkdir(self.tmpdir) |
41 | - except OSError as e: |
42 | - if e.errno == errno.EEXIST: |
43 | - raise ValueError("name '%s' already exists in %s" % |
44 | - (name, _topdir)) |
45 | - else: |
46 | - raise e |
47 | |
48 | # make subdirs |
49 | self.collect = os.path.join(self.tmpdir, "collect") |
50 | @@ -280,12 +274,25 @@ |
51 | |
52 | self.dirs = (self.collect, self.install, self.boot, self.logs, |
53 | self.disks) |
54 | + |
55 | + self.success_file = os.path.join(self.logs, "success") |
56 | + self.errors_file = os.path.join(self.logs, "errors.json") |
57 | + self.target_disk = os.path.join(self.disks, "install_disk.img") |
58 | + self.seed_disk = os.path.join(self.boot, "seed.img") |
59 | + self.output_disk = os.path.join(self.boot, OUTPUT_DISK_NAME) |
60 | + |
61 | + if self.restored: |
62 | + if os.path.exists(self.tmpdir): |
63 | + logger.info('Reusing existing TempDir: %s', self.tmpdir) |
64 | + return |
65 | + else: |
66 | + raise ValueError("REUSE_TOPDIR set, but TempDir not found:" |
67 | + " %s" % self.tmpdir) |
68 | + |
69 | + os.mkdir(self.tmpdir) |
70 | for d in self.dirs: |
71 | os.mkdir(d) |
72 | |
73 | - self.success_file = os.path.join(self.logs, "success") |
74 | - self.errors_file = os.path.join(self.logs, "errors.json") |
75 | - |
76 | # write cloud-init for installed system |
77 | meta_data_file = os.path.join(self.install, "meta-data") |
78 | with open(meta_data_file, "w") as fp: |
79 | @@ -296,21 +303,18 @@ |
80 | |
81 | # create target disk |
82 | logger.debug('Creating target disk') |
83 | - self.target_disk = os.path.join(self.disks, "install_disk.img") |
84 | subprocess.check_call(["qemu-img", "create", "-f", TARGET_IMAGE_FORMAT, |
85 | self.target_disk, "10G"], |
86 | stdout=DEVNULL, stderr=subprocess.STDOUT) |
87 | |
88 | # create seed.img for installed system's cloud init |
89 | logger.debug('Creating seed disk') |
90 | - self.seed_disk = os.path.join(self.boot, "seed.img") |
91 | subprocess.check_call(["cloud-localds", self.seed_disk, |
92 | user_data_file, meta_data_file], |
93 | stdout=DEVNULL, stderr=subprocess.STDOUT) |
94 | |
95 | # create output disk, mount ro |
96 | logger.debug('Creating output disk') |
97 | - self.output_disk = os.path.join(self.boot, OUTPUT_DISK_NAME) |
98 | subprocess.check_call(["qemu-img", "create", "-f", TARGET_IMAGE_FORMAT, |
99 | self.output_disk, "10M"], |
100 | stdout=DEVNULL, stderr=subprocess.STDOUT) |
101 | @@ -549,7 +553,6 @@ |
102 | cls.boot_log = os.path.join(cls.td.logs, 'boot-serial.log') |
103 | logger.debug('Install console log: {}'.format(cls.install_log)) |
104 | logger.debug('Boot console log: {}'.format(cls.boot_log)) |
105 | - ftypes = cls.get_test_files() |
106 | |
107 | # if interactive, launch qemu without 'background & wait' |
108 | if cls.interactive: |
109 | @@ -569,6 +572,7 @@ |
110 | cmd.extend(["--append=" + cls.extra_kern_args]) |
111 | |
112 | # publish the root tarball |
113 | + ftypes = cls.get_test_files() |
114 | install_src = "PUBURL/" + os.path.basename(ftypes[cls.target_ftype]) |
115 | if cls.target_ftype == 'vmtest.root-tgz': |
116 | cmd.append("--publish=%s" % ftypes['vmtest.root-tgz']) |
117 | @@ -652,10 +656,11 @@ |
118 | # proxy config |
119 | configs = [cls.conf_file] |
120 | cls.proxy = get_apt_proxy() |
121 | - if cls.proxy is not None: |
122 | + if cls.proxy is not None and not cls.td.restored: |
123 | proxy_config = os.path.join(cls.td.install, 'proxy.cfg') |
124 | - with open(proxy_config, "w") as fp: |
125 | - fp.write(json.dumps({'apt_proxy': cls.proxy}) + "\n") |
126 | + if not os.path.exists(proxy_config): |
127 | + with open(proxy_config, "w") as fp: |
128 | + fp.write(json.dumps({'apt_proxy': cls.proxy}) + "\n") |
129 | configs.append(proxy_config) |
130 | |
131 | uefi_flags = [] |
132 | @@ -666,8 +671,9 @@ |
133 | |
134 | # always attempt to update target nvram (via grub) |
135 | grub_config = os.path.join(cls.td.install, 'grub.cfg') |
136 | - with open(grub_config, "w") as fp: |
137 | - fp.write(json.dumps({'grub': {'update_nvram': True}})) |
138 | + if not os.path.exists(grub_config): |
139 | + with open(grub_config, "w") as fp: |
140 | + fp.write(json.dumps({'grub': {'update_nvram': True}})) |
141 | configs.append(grub_config) |
142 | |
143 | if cls.dirty_disks and storage_config: |
144 | @@ -690,20 +696,21 @@ |
145 | reporting_config = os.path.join(cls.td.install, 'reporting.cfg') |
146 | localhost_url = ('http://' + get_lan_ip() + |
147 | ':{:d}/'.format(reporting_logger.port)) |
148 | - with open(reporting_config, 'w') as fp: |
149 | - fp.write(json.dumps({ |
150 | - 'install': { |
151 | - 'log_file': '/tmp/install.log', |
152 | - 'post_files': ['/tmp/install.log'], |
153 | - }, |
154 | - 'reporting': { |
155 | - 'maas': { |
156 | - 'level': 'DEBUG', |
157 | - 'type': 'webhook', |
158 | - 'endpoint': localhost_url, |
159 | - }, |
160 | - }, |
161 | - })) |
162 | + if not os.path.exists(reporting_config) and not cls.td.restored: |
163 | + with open(reporting_config, 'w') as fp: |
164 | + fp.write(json.dumps({ |
165 | + 'install': { |
166 | + 'log_file': '/tmp/install.log', |
167 | + 'post_files': ['/tmp/install.log'], |
168 | + }, |
169 | + 'reporting': { |
170 | + 'maas': { |
171 | + 'level': 'DEBUG', |
172 | + 'type': 'webhook', |
173 | + 'endpoint': localhost_url, |
174 | + }, |
175 | + }, |
176 | + })) |
177 | configs.append(reporting_config) |
178 | |
179 | cmd.extend(uefi_flags + netdevs + disks + |
180 | @@ -713,6 +720,11 @@ |
181 | ["--config=%s" % f for f in configs] + |
182 | [install_src]) |
183 | |
184 | + # don't run the vm stages if we're just re-running testcases on output |
185 | + if cls.td.restored: |
186 | + logger.info('Using existing outputdata, skipping install/boot') |
187 | + return |
188 | + |
189 | # run vm with installer |
190 | lout_path = os.path.join(cls.td.logs, "install-launch.log") |
191 | logger.info('Running curtin installer: {}'.format(cls.install_log)) |
192 | |
193 | === modified file 'tools/jenkins-runner' |
194 | --- tools/jenkins-runner 2017-02-17 21:02:20 +0000 |
195 | +++ tools/jenkins-runner 2017-05-19 20:26:52 +0000 |
196 | @@ -3,6 +3,8 @@ |
197 | topdir="${CURTIN_VMTEST_TOPDIR:-${WORKSPACE:-$PWD}/output}" |
198 | pkeep=${CURTIN_VMTEST_KEEP_DATA_PASS:-logs,collect} |
199 | fkeep=${CURTIN_VMTEST_KEEP_DATA_FAIL:-logs,collect} |
200 | +reuse=${CURTIN_VMTEST_REUSE_TOPDIR:-0} |
201 | +export CURTIN_VMTEST_REUSE_TOPDIR=$reuse |
202 | export CURTIN_VMTEST_IMAGE_SYNC=${CURTIN_VMTEST_IMAGE_SYNC:-0} |
203 | export CURTIN_VMTEST_KEEP_DATA_PASS=$pkeep |
204 | export CURTIN_VMTEST_KEEP_DATA_FAIL=$fkeep |
205 | @@ -13,10 +15,12 @@ |
206 | |
207 | fail() { echo "$@" 1>&2; exit 1; } |
208 | |
209 | -if [ -d "$topdir" ]; then |
210 | - fail "topdir '$topdir' existed." |
211 | +if [ "$reuse" != "1" ]; then |
212 | + if [ -d "$topdir" ]; then |
213 | + fail "topdir '$topdir' existed." |
214 | + fi |
215 | + mkdir -p "$topdir" || fail "failed mkdir $topdir" |
216 | fi |
217 | -mkdir -p "$topdir" || fail "failed mkdir $topdir" |
218 | |
219 | start_s=$(date +%s) |
220 | parallel=${CURTIN_VMTEST_PARALLEL} |
PASSED: Continuous integration, rev:472 /jenkins. ubuntu. com/server/ job/curtin- ci/389/ /jenkins. ubuntu. com/server/ job/curtin- ci/nodes= metal-arm64/ 389 /jenkins. ubuntu. com/server/ job/curtin- ci/nodes= metal-ppc64el/ 389 /jenkins. ubuntu. com/server/ job/curtin- ci/nodes= metal-s390x/ 389 /jenkins. ubuntu. com/server/ job/curtin- ci/nodes= vm-amd64/ 389 /jenkins. ubuntu. com/server/ job/curtin- ci/nodes= vm-i386/ 389
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
Click here to trigger a rebuild: /jenkins. ubuntu. com/server/ job/curtin- ci/389/ rebuild
https:/