39
47
request = self.make_request('bundle', remainder='/proof')
40
48
response = self.api_class(request)()
41
49
self.assertEqual(400, response.status_code)
50
results = response.json_body
51
self.assertEqual(0, len(results['warning_messages']))
43
'No deployer file data received.',
44
response.json_body['error_messages'][0])
53
['No deployer file data received.'],
54
results['error_messages'])
46
56
def test_bundle_proof_invalid_deployer_file(self):
47
57
request = self.make_request('bundle', remainder='/proof')
51
61
response = self.api_class(request)()
52
62
self.assertEqual(400, response.status_code)
63
results = response.json_body
64
self.assertEqual(1, len(results['error_messages']))
65
self.assertEqual(0, len(results['warning_messages']))
55
response.json_body['error_messages'][0])
67
'Could not parse', results['error_messages'][0])
57
69
def test_bundle_proof_charm_exists(self):
58
70
deployer_file = load_data_file('sample_bundle/bundles.yaml')
60
72
request = self.make_request('bundle', remainder='/proof')
62
'deployer_file': deployer_file
74
'deployer_file': deployer_file,
65
77
response = self.api_class(request)()
66
78
self.assertEqual(200, response.status_code)
67
79
results = response.json_body
68
80
self.assertEqual(1, len(results['errors']))
81
self.assertEqual(0, len(results['warning_messages']))
69
82
self.assertEqual(4, len(results['errors'][0]['services'].keys()))
100
105
request = self.make_request('bundle', remainder='/proof')
101
106
request.params = {
102
'deployer_file': yaml.dump(bundle_config)
107
'deployer_file': yaml.dump(bundle_config),
104
109
response = self.api_class(request)()
105
110
self.assertEqual(200, response.status_code)
106
111
results = response.json_body
107
112
self.assertEqual(0, len(results['errors']))
108
113
self.assertEqual(1, len(results['services_info'].items()))
109
self.assertEqual(store_url,
114
self.assertEqual(charm.store_url,
110
115
results['services_info']['charm']['store_url'])
112
117
def test_bundle_proof_invalid_config_type(self):
113
# We have to create the charm so that we can verify it exists.
114
_id, charm = factory.makeCharm(
119
# and we'll cheat and just find it straight by the store url.
121
store_url = charm.store_url
118
charm = self.setup_charm()
123
120
bundle_config = {
127
'charm_url': str(store_url),
124
'charm_url': str(charm.store_url),
129
'script-interval': 'invalid'
126
'script-interval': 'invalid',
136
133
request = self.make_request('bundle', remainder='/proof')
137
134
request.params = {
138
'deployer_file': yaml.dump(bundle_config)
135
'deployer_file': yaml.dump(bundle_config),
140
137
response = self.api_class(request)()
141
138
self.assertEqual(200, response.status_code)
142
139
results = response.json_body
143
140
self.assertEqual(1, len(results['errors']))
144
141
self.assertEqual(1, len(results['error_messages']))
142
self.assertEqual(0, len(results['warning_messages']))
146
144
# Note that the View will prefix the error message from the proof with
147
145
# the bundle name to help identify where the error message came from.
148
146
self.assertEqual(
149
'wiki: script-interval is not of type int.',
150
results['error_messages'][0]
147
['wiki/charm: script-interval is not of type int.'],
148
results['error_messages'])
153
150
def test_bundle_proof_supports_multiple_errors(self):
154
_id, charm = factory.makeCharm(
159
# and we'll cheat and just find it straight by the store url.
161
store_url = charm.store_url
151
charm = self.setup_charm()
163
153
bundle_config = {
167
'charm_url': str(store_url),
157
'charm_url': str(charm.store_url),
169
159
'script-interval': 'invalid',
170
160
'no-exist': 'hah invalid',
180
170
request = self.make_request('bundle', remainder='/proof')
181
171
request.params = {
182
'deployer_file': yaml.dump(bundle_config)
172
'deployer_file': yaml.dump(bundle_config),
184
174
response = self.api_class(request)()
185
175
self.assertEqual(200, response.status_code)
186
176
results = response.json_body
187
177
self.assertEqual(1, len(results['errors']))
188
178
self.assertEqual(3, len(results['error_messages']))
179
self.assertEqual(0, len(results['warning_messages']))
190
181
# One message from not finding a charm.
191
182
self.assertEqual(
192
'wiki: Could not find charm for service: fail',
193
results['error_messages'][0]
195
# The other two from checking the config of the other charm.
197
'wiki: script-interval is not of type int.',
198
results['error_messages'][1]
201
'wiki: The charm has no option for: no-exist',
202
results['error_messages'][2]
183
['wiki/fail: Could not find charm for service.',
184
'wiki/charm: script-interval is not of type int.',
185
'wiki/charm: The charm has no option for: no-exist'],
186
results['error_messages'])
205
188
def test_bundle_proof_errors_on_invalid_relations(self):
206
189
# The default charm provides website:https and requires
208
191
one_store_url, two_store_url = self.setup_relatable_charms(
216
'interface': 'memcache'
199
'interface': 'memcache',
219
'interface': 'mongodb'
202
'interface': 'mongodb',
234
- ["wiki:proxy", db]""".format(one_store_url, two_store_url)
207
bundle_base = dedent("""\
217
- ["wiki:proxy", db]""").format(one_store_url, two_store_url)
236
219
request = self.make_request('bundle', remainder='/proof')
237
220
request.params = {
238
'deployer_file': bundle_base
221
'deployer_file': bundle_base,
240
223
response = self.api_class(request)()
241
224
self.assertEqual(200, response.status_code)
225
results = response.json_body
226
self.assertEqual(1, len(results['error_messages']))
227
self.assertEqual(0, len(results['warning_messages']))
243
229
'wiki: Invalid relation requested: proxy',
244
230
response.json_body['error_messages'][0])
257
243
'interface': 'mongodb'
272
- ["wiki:db", "db:proxy"]""".format(one_store_url, two_store_url)
248
bundle_base = dedent("""\
258
- ["wiki:db", "db:proxy"]""").format(
259
one_store_url, two_store_url)
274
261
request = self.make_request('bundle', remainder='/proof')
275
262
request.params = {
276
'deployer_file': bundle_base
263
'deployer_file': bundle_base,
278
265
response = self.api_class(request)()
279
266
self.assertEqual(200, response.status_code)
267
results = response.json_body
268
self.assertEqual(1, len(results['error_messages']))
269
self.assertEqual(0, len(results['warning_messages']))
281
271
'wiki: The requested relation db to proxy is incompatible',
282
272
response.json_body['error_messages'][0])
302
292
""".format(one_store_url, two_store_url))
304
294
request = self.make_request('bundle', remainder='/proof')
306
'deployer_file': bundle_base
295
request.params = {'deployer_file': bundle_base}
308
296
response = self.api_class(request)()
309
297
self.assertEqual(200, response.status_code)
310
error_messages = response.json_body['error_messages']
311
self.assertEqual(1, len(error_messages))
298
results = response.json_body
299
self.assertEqual(1, len(results['error_messages']))
300
self.assertEqual(0, len(results['warning_messages']))
313
302
'wiki: The requested relation db to database is incompatible',
303
results['error_messages'][0])
316
305
'Hint: if order of the relation were reversed it would be valid.',
306
results['error_messages'][0])
319
308
def test_bundle_proof_passes_with_valid_relations(self):
320
309
one_store_url, two_store_url = self.setup_relatable_charms(
312
'interface': 'https',
345
- ["wiki:database", "db:db"]""".format(one_store_url, two_store_url)
324
bundle_base = dedent("""\
334
- ["wiki:database", "db:db"]""").format(
335
one_store_url, two_store_url)
347
337
request = self.make_request('bundle', remainder='/proof')
348
338
request.params = {
349
'deployer_file': bundle_base
339
'deployer_file': bundle_base,
351
341
response = self.api_class(request)()
342
results = response.json_body
343
self.assertEqual(0, len(results['error_messages']))
344
self.assertEqual(0, len(results['warning_messages']))
352
345
self.assertEqual(200, response.status_code)
353
self.assertEqual(0, len(response.json_body['error_messages']))
355
347
def test_bundle_proof_passes_with_valid_vague_as_can_be(self):
356
348
one_store_url, two_store_url = self.setup_relatable_charms(
351
'interface': 'https',
366
358
'interface': 'mongodb'
371
363
bundle_base = dedent("""
381
- ["wiki", "db"]""").format(one_store_url, two_store_url)
373
- ["wiki", "db"]""").format(one_store_url, two_store_url)
383
375
request = self.make_request('bundle', remainder='/proof')
384
376
request.params = {
385
'deployer_file': bundle_base
377
'deployer_file': bundle_base,
387
379
response = self.api_class(request)()
380
results = response.json_body
381
self.assertEqual(0, len(results['error_messages']))
382
self.assertEqual(0, len(results['warning_messages']))
388
383
self.assertEqual(200, response.status_code)
389
self.assertEqual(0, len(response.json_body['error_messages']))
391
385
def test_bundle_proof_errors_with_missing_service(self):
392
386
one_store_url, two_store_url = self.setup_relatable_charms(
389
'interface': 'https',
402
396
'interface': 'mongodb'
407
401
bundle_base = dedent("""
417
- ["wiki", "party"]""").format(one_store_url, two_store_url)
411
- ["wiki", "party"]""").format(one_store_url, two_store_url)
419
413
request = self.make_request('bundle', remainder='/proof')
420
414
request.params = {'deployer_file': bundle_base}
421
415
response = self.api_class(request)()
416
results = response.json_body
417
self.assertEqual(1, len(results['error_messages']))
418
self.assertEqual(0, len(results['warning_messages']))
422
419
self.assertEqual(200, response.status_code)
423
420
self.assertEqual(
424
421
'wiki: Invalid relation to charm: party not found.',
425
response.json_body['error_messages'][0])
422
results['error_messages'][0])
427
424
def test_bundle_proof_with_inheritance(self):
428
425
# Show that inheritance works by relating a charm in wiki-ext to one
458
455
url3 = charm3.store_url
460
457
bundle_base = dedent("""
479
- ["log", "db"]""").format(url1, url2, url3)
481
request = self.make_request('bundle', remainder='/proof')
483
'deployer_file': bundle_base
485
response = self.api_class(request)()
486
self.assertEqual(200, response.status_code)
487
self.assertEqual(0, len(response.json_body['error_messages']))
476
- ["log", "db"]""").format(url1, url2, url3)
478
request = self.make_request('bundle', remainder='/proof')
480
'deployer_file': bundle_base,
482
response = self.api_class(request)()
483
results = response.json_body
484
self.assertEqual(0, len(results['error_messages']))
485
self.assertEqual(0, len(results['warning_messages']))
486
self.assertEqual(200, response.status_code)
488
def test_bundle_proof_invalid_constraints(self):
489
charm = self.setup_charm()
495
'charm_url': str(charm.store_url),
496
'constraints': 'cows=1 cpu-donkeys=4',
502
request = self.make_request('bundle', remainder='/proof')
504
'deployer_file': yaml.dump(bundle_config),
506
response = self.api_class(request)()
507
self.assertEqual(200, response.status_code)
508
results = response.json_body
509
self.assertEqual(1, len(results['errors']))
510
self.assertEqual(1, len(results['error_messages']))
511
self.assertEqual(0, len(results['warning_messages']))
513
['wiki/charm: unsupported constraints: cows, cpu-donkeys'],
514
results['error_messages'])
516
def test_bundle_proof_comma_separated_constraints(self):
517
charm = self.setup_charm()
523
'charm_url': str(charm.store_url),
524
'constraints': 'mem=1G,cpu-cores=4',
530
request = self.make_request('bundle', remainder='/proof')
532
'deployer_file': yaml.dump(bundle_config),
534
response = self.api_class(request)()
535
self.assertEqual(200, response.status_code)
536
results = response.json_body
537
self.assertEqual(1, len(results['errors']))
538
self.assertEqual(0, len(results['error_messages']))
539
self.assertEqual(1, len(results['warning_messages']))
540
expected = ("wiki/charm: The constraints are comma-separated, "
541
"which is deprecated.")
542
self.assertEqual([expected], results['warning_messages'])
544
def test_bundle_proof_multi_error_constraints(self):
545
# If there is a failure due to invalid constraints and comma-separated,
546
# we only report the former.
547
charm = self.setup_charm()
553
'charm_url': str(charm.store_url),
554
'constraints': 'mem=1G,cpu-donkeys=4',
560
request = self.make_request('bundle', remainder='/proof')
562
'deployer_file': yaml.dump(bundle_config),
564
response = self.api_class(request)()
565
self.assertEqual(200, response.status_code)
566
results = response.json_body
568
self.assertEqual(1, len(results['errors']))
569
self.assertEqual(1, len(results['error_messages']))
570
self.assertEqual(0, len(results['warning_messages']))
572
expected = 'wiki/charm: unsupported constraints: cpu-donkeys'
573
self.assertEqual([expected], results['error_messages'])