1
|
|
|
# |
2
|
|
|
# Copyright (C) 2013 Satoru SATOH <ssato @ redhat.com> |
3
|
|
|
# License: MIT |
4
|
|
|
# |
5
|
|
|
# pylint: disable=missing-docstring, invalid-name, too-many-public-methods |
6
|
|
|
from __future__ import absolute_import |
7
|
|
|
|
8
|
|
|
import os |
9
|
|
|
import os.path |
10
|
|
|
import unittest |
11
|
|
|
|
12
|
|
|
import anyconfig.cli as TT |
13
|
|
|
import anyconfig.api |
14
|
|
|
import anyconfig.template |
15
|
|
|
import anyconfig.tests.common |
16
|
|
|
import anyconfig.tests.api |
17
|
|
|
|
18
|
|
|
from anyconfig.tests.common import CNF_0 |
19
|
|
|
|
20
|
|
|
|
21
|
|
|
CNF_0_PATH = os.path.join(anyconfig.tests.common.selfdir(), "00-cnf.yml") |
22
|
|
|
SCM_0_PATH = os.path.join(anyconfig.tests.common.selfdir(), "00-scm.yml") |
23
|
|
|
CNF_TMPL_0 = anyconfig.tests.api.CNF_TMPL_1 |
24
|
|
|
|
25
|
|
|
|
26
|
|
|
def _run(*args): |
27
|
|
|
TT.main(["dummy", "--silent"] + list(args)) |
28
|
|
|
|
29
|
|
|
|
30
|
|
|
class Test(unittest.TestCase): |
31
|
|
|
|
32
|
|
|
def setUp(self): |
33
|
|
|
self.workdir = anyconfig.tests.common.setup_workdir() |
34
|
|
|
self.script = os.path.join(anyconfig.tests.common.selfdir(), |
35
|
|
|
"..", "cli.py") |
36
|
|
|
|
37
|
|
|
def tearDown(self): |
38
|
|
|
anyconfig.tests.common.cleanup_workdir(self.workdir) |
39
|
|
|
|
40
|
|
|
def _assert_run_and_exit(self, *args): |
41
|
|
|
raised = False |
42
|
|
|
try: |
43
|
|
|
_run(*args) |
44
|
|
|
except SystemExit: |
45
|
|
|
raised = True |
46
|
|
|
|
47
|
|
|
self.assertTrue(raised) |
48
|
|
|
|
49
|
|
|
def run_and_check_exit_code(self, args=None, code=0, _not=False, |
50
|
|
|
exc_cls=SystemExit): |
51
|
|
|
try: |
52
|
|
|
TT.main(["dummy", "--silent"] + ([] if args is None else args)) |
53
|
|
|
except exc_cls as exc: |
54
|
|
|
ecode = getattr(exc, "code", 1) |
55
|
|
|
(self.assertNotEqual if _not else self.assertEqual)(ecode, code) |
56
|
|
|
|
57
|
|
|
def test_10__show_usage(self): |
58
|
|
|
self.run_and_check_exit_code(["--help"]) |
59
|
|
|
|
60
|
|
|
def test_11__wo_args(self): |
61
|
|
|
self.run_and_check_exit_code(_not=True) |
62
|
|
|
|
63
|
|
|
def test_12__wrong_option(self): |
64
|
|
|
self.run_and_check_exit_code(["--wrong-option-xyz"], _not=True) |
65
|
|
|
|
66
|
|
|
def test_20__list(self): |
67
|
|
|
self.run_and_check_exit_code(["--list"]) |
68
|
|
|
|
69
|
|
|
def test_22__list(self): |
70
|
|
|
self.run_and_check_exit_code(["--list"]) |
71
|
|
|
|
72
|
|
|
def test_30_single_input(self): |
|
|
|
|
73
|
|
|
a = dict(name="a", a=1, b=dict(b=[1, 2], c="C")) |
74
|
|
|
|
75
|
|
|
infile = os.path.join(self.workdir, "a.json") |
76
|
|
|
output = os.path.join(self.workdir, "b.json") |
77
|
|
|
|
78
|
|
|
anyconfig.api.dump(a, infile) |
79
|
|
|
self.assertTrue(os.path.exists(infile)) |
80
|
|
|
|
81
|
|
|
TT.main(["dummy", "--silent", "-o", output, infile]) |
82
|
|
|
self.assertTrue(os.path.exists(output)) |
83
|
|
|
|
84
|
|
|
def test_31__single_input_wo_input_type(self): |
85
|
|
|
self._assert_run_and_exit("a.conf") |
86
|
|
|
|
87
|
|
|
def test_32_single_input_w_get_option(self): |
88
|
|
|
d = dict(name="a", a=dict(b=dict(c=[1, 2], d="C"))) |
89
|
|
|
|
90
|
|
|
infile = os.path.join(self.workdir, "a.json") |
91
|
|
|
output = os.path.join(self.workdir, "b.json") |
92
|
|
|
|
93
|
|
|
anyconfig.api.dump(d, infile) |
94
|
|
|
self.assertTrue(os.path.exists(infile)) |
95
|
|
|
|
96
|
|
|
TT.main(["dummy", "--silent", "-o", output, "--get", "a.b", infile]) |
97
|
|
|
self.assertTrue(os.path.exists(output)) |
98
|
|
|
|
99
|
|
|
x = anyconfig.api.load(output) |
100
|
|
|
self.assertEqual(x, d['a']['b']) |
101
|
|
|
|
102
|
|
|
def test_34_single_input_w_set_option(self): |
103
|
|
|
d = dict(name="a", a=dict(b=dict(c=[1, 2], d="C"))) |
104
|
|
|
|
105
|
|
|
infile = os.path.join(self.workdir, "a.json") |
106
|
|
|
output = os.path.join(self.workdir, "b.json") |
107
|
|
|
|
108
|
|
|
anyconfig.api.dump(d, infile) |
109
|
|
|
self.assertTrue(os.path.exists(infile)) |
110
|
|
|
|
111
|
|
|
TT.main(["dummy", "-q", "-o", output, "--set", "a.b.d=E", infile]) |
112
|
|
|
self.assertTrue(os.path.exists(output)) |
113
|
|
|
|
114
|
|
|
ref = d.copy() |
115
|
|
|
ref['a']['b']['d'] = 'E' |
116
|
|
|
|
117
|
|
|
x = anyconfig.api.load(output) |
118
|
|
|
self.assertEqual(x, ref) |
119
|
|
|
|
120
|
|
|
def test_36_single_input__ignore_missing(self): |
121
|
|
|
infile = os.path.join(os.curdir, "conf_file_should_not_exist.json") |
122
|
|
|
assert not os.path.exists(infile) |
123
|
|
|
|
124
|
|
|
self.assertFalse(TT.main(["dummy", "--silent", "-O", "json", |
125
|
|
|
"--ignore-missing", infile])) |
126
|
|
|
|
127
|
|
|
def test_37_single_input_w_schema(self): |
128
|
|
|
(infile, scmfile) = (CNF_0_PATH, SCM_0_PATH) |
129
|
|
|
output = os.path.join(self.workdir, "output.json") |
130
|
|
|
self.run_and_check_exit_code(["--schema", scmfile, "--validate", |
131
|
|
|
infile], 0) |
132
|
|
|
self.run_and_check_exit_code(["--schema", scmfile, "-o", output, |
133
|
|
|
infile], 0) |
134
|
|
|
|
135
|
|
|
infile2 = os.path.join(self.workdir, "input.yml") |
136
|
|
|
cnf = CNF_0.copy() |
137
|
|
|
cnf["a"] = "aaa" # Validation should fail. |
138
|
|
|
anyconfig.api.dump(cnf, infile2) |
139
|
|
|
self.run_and_check_exit_code(["--schema", scmfile, "--validate", |
140
|
|
|
infile2], 1) |
141
|
|
|
|
142
|
|
|
def test_38_single_input__gen_schema_and_validate_with_it(self): |
143
|
|
|
cnf = dict(name="a", a=1, b=dict(b=[1, 2], c="C")) |
144
|
|
|
infile = os.path.join(self.workdir, "cnf.json") |
145
|
|
|
output = os.path.join(self.workdir, "out.yaml") |
146
|
|
|
anyconfig.api.dump(cnf, infile) |
147
|
|
|
|
148
|
|
|
self.run_and_check_exit_code(["--gen-schema", "-o", output, infile], 0) |
149
|
|
|
self.assertTrue(os.path.exists(output)) |
150
|
|
|
self.run_and_check_exit_code(["--schema", output, "--validate", |
151
|
|
|
infile], 0) |
152
|
|
|
|
153
|
|
|
def test_39_single_input_wo_schema(self): |
154
|
|
|
self.run_and_check_exit_code(["--validate", CNF_0_PATH], 1) |
155
|
|
|
|
156
|
|
|
def test_40_multiple_inputs(self): |
157
|
|
|
xs = [dict(a=1, ), |
158
|
|
|
dict(b=dict(b=[1, 2], c="C")), ] |
159
|
|
|
|
160
|
|
|
a = xs[0].copy() |
161
|
|
|
a.update(xs[1]) |
162
|
|
|
|
163
|
|
|
output = os.path.join(self.workdir, "b.json") |
164
|
|
|
|
165
|
|
|
inputs = [] |
166
|
|
|
for i in [0, 1]: |
167
|
|
|
infile = os.path.join(self.workdir, "a%d.json" % i) |
168
|
|
|
inputs.append(infile) |
169
|
|
|
|
170
|
|
|
anyconfig.api.dump(xs[i], infile) |
171
|
|
|
self.assertTrue(os.path.exists(infile)) |
172
|
|
|
|
173
|
|
|
TT.main(["dummy", "--silent", "-o", output] + inputs) |
174
|
|
|
self.assertTrue(os.path.exists(output)) |
175
|
|
|
|
176
|
|
|
def test_50_single_input__w_arg_option(self): |
177
|
|
|
a = dict(name="a", a=1, b=dict(b=[1, 2], c="C"), d=[1, 2]) |
178
|
|
|
|
179
|
|
|
infile = os.path.join(self.workdir, "a.json") |
180
|
|
|
output = os.path.join(self.workdir, "b.json") |
181
|
|
|
|
182
|
|
|
anyconfig.api.dump(a, infile) |
183
|
|
|
self.assertTrue(os.path.exists(infile)) |
184
|
|
|
|
185
|
|
|
TT.main(["dummy", "--silent", "-o", output, "-A", |
186
|
|
|
"a:10;name:x;d:3,4", infile]) |
187
|
|
|
self.assertTrue(os.path.exists(output)) |
188
|
|
|
|
189
|
|
|
x = anyconfig.api.load(output) |
190
|
|
|
|
191
|
|
|
self.assertNotEqual(a["name"], x["name"]) |
192
|
|
|
self.assertNotEqual(a["a"], x["a"]) |
193
|
|
|
self.assertNotEqual(a["d"], x["d"]) |
194
|
|
|
|
195
|
|
|
self.assertEqual(x["name"], 'x') |
196
|
|
|
self.assertEqual(x["a"], 10) |
197
|
|
|
self.assertEqual(x["d"], [3, 4]) |
198
|
|
|
|
199
|
|
|
def test_60_output_wo_output_option_w_otype(self): |
200
|
|
|
a = dict(name="a", a=1, b=dict(b=[1, 2], c="C")) |
201
|
|
|
infile = os.path.join(self.workdir, "a.json") |
202
|
|
|
anyconfig.api.dump(a, infile) |
203
|
|
|
|
204
|
|
|
self.run_and_check_exit_code(["--otype", "json", infile]) |
205
|
|
|
|
206
|
|
|
def test_62_output_wo_output_option_and_otype_w_itype(self): |
207
|
|
|
a = dict(name="a", a=1, b=dict(b=[1, 2], c="C")) |
208
|
|
|
infile = os.path.join(self.workdir, "a.json") |
209
|
|
|
anyconfig.api.dump(a, infile) |
210
|
|
|
|
211
|
|
|
self.run_and_check_exit_code(["--itype", "json", infile]) |
212
|
|
|
|
213
|
|
|
def test_70_multi_inputs__w_template(self): |
214
|
|
|
if not anyconfig.template.SUPPORTED: |
215
|
|
|
return |
216
|
|
|
|
217
|
|
|
a = dict(name="a", a=1, b=dict(b=[1, 2], c="C")) |
218
|
|
|
|
219
|
|
|
inputsdir = os.path.join(self.workdir, "in") |
220
|
|
|
os.makedirs(inputsdir) |
221
|
|
|
|
222
|
|
|
anyconfig.api.dump(a, os.path.join(inputsdir, "a0.yml")) |
223
|
|
|
open(os.path.join(inputsdir, "a1.yml"), 'w').write(CNF_TMPL_0) |
224
|
|
|
output = os.path.join(self.workdir, "b.json") |
225
|
|
|
|
226
|
|
|
TT.main(["dummy", "--silent", "--template", "-o", output, |
227
|
|
|
os.path.join(inputsdir, "*.yml")]) |
228
|
|
|
self.assertTrue(os.path.exists(output)) |
229
|
|
|
|
230
|
|
|
def test_72_single_input__no_template(self): |
|
|
|
|
231
|
|
|
a = dict(name="a", a=1, b=dict(b=[1, 2], c="C")) |
232
|
|
|
|
233
|
|
|
infile = os.path.join(self.workdir, "a.json") |
234
|
|
|
output = os.path.join(self.workdir, "b.json") |
235
|
|
|
|
236
|
|
|
anyconfig.api.dump(a, infile) |
237
|
|
|
self.assertTrue(os.path.exists(infile)) |
238
|
|
|
|
239
|
|
|
TT.main(["dummy", "--silent", "-o", output, infile]) |
240
|
|
|
self.assertTrue(os.path.exists(output)) |
241
|
|
|
|
242
|
|
|
def test_74_multi_inputs__w_template(self): |
243
|
|
|
if not anyconfig.template.SUPPORTED: |
244
|
|
|
return |
245
|
|
|
|
246
|
|
|
curdir = anyconfig.tests.common.selfdir() |
247
|
|
|
|
248
|
|
|
infile = os.path.join(curdir, "*template-c*.yml") |
249
|
|
|
output = os.path.join(self.workdir, "output.yml") |
250
|
|
|
|
251
|
|
|
TT.main(["dummy", "--silent", "--template", "-o", output, infile]) |
252
|
|
|
|
253
|
|
|
def test_80_no_out_dumper(self): |
254
|
|
|
a = dict(name="a", a=1, b=dict(b=[1, 2], c="C"), d=[1, 2]) |
255
|
|
|
infile = os.path.join(self.workdir, "a.json") |
256
|
|
|
anyconfig.api.dump(a, infile) |
257
|
|
|
|
258
|
|
|
exited = False |
259
|
|
|
outfile = os.path.join(self.workdir, "out.conf") |
260
|
|
|
_run("-o", outfile, infile) |
261
|
|
|
self.assertFalse(exited) |
262
|
|
|
|
263
|
|
|
def test_82_no_itype_and_otype(self): |
264
|
|
|
exited = False |
265
|
|
|
outfile = os.path.join(self.workdir, "out.conf") |
266
|
|
|
_run("-o", outfile, "in.conf") |
267
|
|
|
self.assertFalse(exited) |
268
|
|
|
|
269
|
|
|
def test_90_no_inputs__w_env_option(self): |
270
|
|
|
infile = "/dev/null" |
271
|
|
|
output = os.path.join(self.workdir, "out.yml") |
272
|
|
|
|
273
|
|
|
if anyconfig.api.find_loader(infile, "yaml") is None: |
274
|
|
|
return |
275
|
|
|
|
276
|
|
|
TT.main(["dummy", "--silent", "--env", "-o", output, infile]) |
277
|
|
|
data = anyconfig.api.load(output) |
278
|
|
|
|
279
|
|
|
for env_var, env_val in os.environ.items(): |
280
|
|
|
self.assertTrue(env_var in data) |
281
|
|
|
self.assertEqual(env_val, os.environ[env_var]) |
282
|
|
|
|
283
|
|
|
# vim:sw=4:ts=4:et: |
284
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.