Merge ~wesley-wiedenmeier/cloud-init:integration-testing-tmpdir into cloud-init:master

Proposed by Wesley Wiedenmeier on 2017-03-20
Status: Merged
Merged at revision: 76d58265e34851b78e952a7f275340863c90a9f5
Proposed branch: ~wesley-wiedenmeier/cloud-init:integration-testing-tmpdir
Merge into: cloud-init:master
Diff against target: 171 lines (+68/-17)
4 files modified
doc/rtd/topics/tests.rst (+13/-1)
tests/cloud_tests/__main__.py (+9/-15)
tests/cloud_tests/args.py (+10/-1)
tests/cloud_tests/util.py (+36/-0)
Reviewer Review Type Date Requested Status
Server Team CI bot continuous-integration Approve on 2017-03-30
cloud-init commiters 2017-03-20 Pending
Review via email: mp+320401@code.launchpad.net

Description of the Change

Integration Testing: improve handling of collected data during run

Previous behavior for run was to collect data into a temporary directory which
was always deleted when tests passed. This adds a command line option
'--preserve-data' that ensures that collected data will be left after tests
run. This also allows the directory to store collected data in during the run
command to be specified using '--data-dir'.

To post a comment you must log in.
Scott Moser (smoser) wrote :

I'm going to mark this 'work in progress'. Josh has integrated this branch and others into his merge proposal at https://code.launchpad.net/~powersj/cloud-init/+git/cloud-init/+merge/324136 . We do plan to pull that all soon.

Thanks for your work, Wesley!

Scott Moser (smoser) wrote :

Hi.
I've marked this 'merged' as I think it is now in trunk under 76d58265e34851b78e952a7f275340863c90a9f5.
If you disagree, please feel free to re-open.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/doc/rtd/topics/tests.rst b/doc/rtd/topics/tests.rst
2index 0663811..7142370 100644
3--- a/doc/rtd/topics/tests.rst
4+++ b/doc/rtd/topics/tests.rst
5@@ -193,7 +193,8 @@ explaining how to run one or the other independently.
6 $ git clone https://git.launchpad.net/cloud-init
7 $ cd cloud-init
8 $ python3 -m tests.cloud_tests run -v -n trusty -n xenial \
9- --deb cloud-init_0.7.8~my_patch_all.deb
10+ --deb cloud-init_0.7.8~my_patch_all.deb --preserve-data
11+ --data-dir /tmp/collection
12
13 The above command will do the following:
14
15@@ -208,8 +209,19 @@ The above command will do the following:
16 * ``--deb cloud-init_0.7.8~patch_all.deb`` use this deb as the version of
17 cloud-init to run with
18
19+* ``--preserve-data`` always preserve collected data, do not remove data after
20+ successful test run
21+
22+* ``--data-dir /tmp/collection`` write collected data into `/tmp/collection`,
23+ rather than using a temporary directory
24+
25 For a more detailed explanation of each option see below.
26
27+.. note::
28+ By default, data collected by the run command will be written into a
29+ temporary directory, to be deleted after a successful. If you would
30+ like to preserve this data, please use the option ``--preserve-data``.
31+
32 Collect
33 -------
34
35diff --git a/tests/cloud_tests/__main__.py b/tests/cloud_tests/__main__.py
36index ef7d187..c0d34d8 100644
37--- a/tests/cloud_tests/__main__.py
38+++ b/tests/cloud_tests/__main__.py
39@@ -2,11 +2,9 @@
40
41 import argparse
42 import logging
43-import shutil
44 import sys
45-import tempfile
46
47-from tests.cloud_tests import (args, collect, manage, verify)
48+from tests.cloud_tests import (args, collect, manage, util, verify)
49 from tests.cloud_tests import LOG
50
51
52@@ -24,23 +22,19 @@ def configure_log(args):
53
54 def run(args):
55 """
56- run full test suite
57+ run test suite
58 """
59 failed = 0
60- args.data_dir = tempfile.mkdtemp(prefix='cloud_test_data_')
61- LOG.debug('using tmpdir %s', args.data_dir)
62- try:
63+ tmpdir = util.TempDir(tmpdir=args.data_dir, preserve=args.preserve_data)
64+
65+ with tmpdir as data_dir:
66+ args.data_dir = data_dir
67 failed += collect.collect(args)
68 failed += verify.verify(args)
69- except Exception:
70- failed += 1
71- raise
72- finally:
73- # TODO: make this configurable via environ or cmdline
74 if failed:
75- LOG.warn('some tests failed, leaving data in %s', args.data_dir)
76- else:
77- shutil.rmtree(args.data_dir)
78+ tmpdir.preserve = True
79+ LOG.warning('some tests failed')
80+
81 return failed
82
83
84diff --git a/tests/cloud_tests/args.py b/tests/cloud_tests/args.py
85index b68cc98..e673277 100644
86--- a/tests/cloud_tests/args.py
87+++ b/tests/cloud_tests/args.py
88@@ -46,6 +46,13 @@ ARG_SETS = {
89 (('-r', '--result'),
90 {'help': 'file to write results to',
91 'action': 'store', 'metavar': 'FILE'}),),
92+ 'RUN_OUTPUT': (
93+ (('-d', '--data-dir'),
94+ {'help': 'directory to store test data in',
95+ 'action': 'store', 'metavar': 'DIR', 'required': False}),
96+ (('--preserve-data',),
97+ {'help': 'do not remove collected data after successful run',
98+ 'action': 'store_true', 'default': False, 'required': False}),),
99 'SETUP': (
100 (('--deb',),
101 {'help': 'install deb', 'metavar': 'FILE', 'action': 'store'}),
102@@ -69,7 +76,8 @@ SUBCMDS = {
103 'collect': ('collect test data',
104 ('COLLECT', 'INTERFACE', 'OUTPUT', 'RESULT', 'SETUP')),
105 'create': ('create new test case', ('CREATE', 'INTERFACE')),
106- 'run': ('run test suite', ('COLLECT', 'INTERFACE', 'RESULT', 'SETUP')),
107+ 'run': ('run test suite',
108+ ('COLLECT', 'INTERFACE', 'RESULT', 'RUN_OUTPUT', 'SETUP')),
109 'verify': ('verify test data', ('INTERFACE', 'OUTPUT', 'RESULT')),
110 }
111
112@@ -215,6 +223,7 @@ NORMALIZERS = {
113 'INTERFACE': _empty_normalizer,
114 'OUTPUT': normalize_output_args,
115 'RESULT': _empty_normalizer,
116+ 'RUN_OUTPUT': _empty_normalizer,
117 'SETUP': normalize_setup_args,
118 }
119
120diff --git a/tests/cloud_tests/util.py b/tests/cloud_tests/util.py
121index 64a8667..006d708 100644
122--- a/tests/cloud_tests/util.py
123+++ b/tests/cloud_tests/util.py
124@@ -3,6 +3,7 @@
125 import glob
126 import os
127 import random
128+import shutil
129 import string
130 import tempfile
131 import yaml
132@@ -160,4 +161,39 @@ def write_file(*args, **kwargs):
133 """
134 c_util.write_file(*args, **kwargs)
135
136+
137+class TempDir(object):
138+ """
139+ temporary directory like tempfile.TemporaryDirectory, but configurable
140+ """
141+
142+ def __init__(self, tmpdir=None, preserve=False, prefix='cloud_test_data_'):
143+ """
144+ tmpdir: directory to use as tempdir
145+ preserve: if true, always preserve data on exit
146+ prefix: prefix to use for tempfile name
147+ """
148+ self.tmpdir = tmpdir
149+ self.preserve = preserve
150+ self.prefix = prefix
151+
152+ def __enter__(self):
153+ """
154+ create tempdir
155+ return_value: tempdir path
156+ """
157+ if not self.tmpdir:
158+ self.tmpdir = tempfile.mkdtemp(prefix=self.prefix)
159+ LOG.debug('using tmpdir: %s', self.tmpdir)
160+ return self.tmpdir
161+
162+ def __exit__(self, etype, value, trace):
163+ """
164+ destroy tempdir if no errors occurred
165+ """
166+ if etype or self.preserve:
167+ LOG.info('leaving data in %s', self.tmpdir)
168+ else:
169+ shutil.rmtree(self.tmpdir)
170+
171 # vi: ts=4 expandtab

Subscribers

People subscribed via source and target branches