1
1
from contextlib import contextmanager
2
2
from copy import deepcopy
3
from StringIO import StringIO
3
4
from textwrap import dedent
4
from StringIO import StringIO
5
from unittest import TestCase
11
from fakejuju import fake_juju_client
12
12
from jujupy import (
18
19
from assess_add_cloud import (
25
30
from tests import FakeHomeTestCase
26
31
from utility import JujuAssertionError
29
class TestCase(FakeHomeTestCase):
31
def make_fake_juju_client(self):
32
env = JujuData('foo', juju_home=self.juju_home)
33
return fake_juju_client(env=env)
36
class TestAssessCloud(TestCase):
34
class TestCloudSpec(TestCase):
36
def test_cloud_spec(self):
38
CloudSpec('label1', 'name1', {'config': '1'}, None, None),
39
cloud_spec('label1', 'name1', {'config': '1'}))
42
class TestXFail(TestCase):
45
spec = CloudSpec('label', 'name', {'config': 'value'}, 'foo', 'bar')
46
fail_spec = xfail(spec, 'baz', 'qux')
47
self.assertEqual(fail_spec, CloudSpec(
48
'label', 'name', {'config': 'value'}, 'qux', 'baz'))
51
class TestAssessCloud(FakeHomeTestCase):
39
54
def cloud_client(self, clouds):
40
client = self.make_fake_juju_client()
55
client = fake_juju_client(juju_home=self.juju_home)
41
56
client.env.load_yaml()
43
58
def dump(cloud_name, cloud):
83
98
"""), stderr.getvalue())
86
def make_long_endpoint(spec, regions=False):
101
def make_long_endpoint(spec, endpoint_validation, regions=False):
87
102
config = deepcopy(spec.config)
88
103
config['endpoint'] = 'A' * 4096
90
105
for region in config['regions'].values():
91
106
region['endpoint'] = 'A' * 4096
92
return CloudSpec('long-endpoint-{}'.format(spec.name), spec.name, config,
96
class TestIterClouds(TestCase):
98
bogus_type = CloudSpec('bogus-type', 'bogus-type', {'type': 'bogus'},
99
exception=TypeNotAccepted)
107
spec = cloud_spec('long-endpoint-{}'.format(spec.name), spec.name, config,
109
if not endpoint_validation:
110
spec = xfail(spec, 1641970, CloudMismatch)
114
class TestIterClouds(FakeHomeTestCase):
116
bogus_type = cloud_spec('bogus-type', 'bogus-type', {'type': 'bogus'},
117
exception=TypeNotAccepted)
101
119
def test_manual(self):
102
cloud = {'type': 'manual', 'endpoint': 'http://example.com'}
103
spec = CloudSpec('foo', 'foo', cloud, exception=None)
121
cloud = {'type': 'manual', 'endpoint': 'http://example.com'}
122
spec = cloud_spec('foo', 'foo', cloud)
123
self.assertItemsEqual([
124
self.bogus_type, xfail(spec, 1649721, InvalidEndpoint),
125
xfail(xfail(cloud_spec('long-name-foo', 'A' * 4096, cloud),
126
1641970, NameMismatch), 1649721, InvalidEndpoint),
127
xfail(xfail(cloud_spec('invalid-name-foo', 'invalid/name', cloud,
128
exception=NameNotAccepted), 1641981, None),
129
1649721, InvalidEndpoint),
130
make_long_endpoint(spec, endpoint_validation=True)],
131
iter_clouds({'foo': cloud}, endpoint_validation=True))
133
def test_manual_no_validation(self):
135
cloud = {'type': 'manual', 'endpoint': 'http://example.com'}
136
spec = cloud_spec('foo', 'foo', cloud)
104
137
self.assertItemsEqual([
105
138
self.bogus_type, spec,
106
CloudSpec('long-name-foo', 'A' * 4096, cloud, exception=None),
107
CloudSpec('invalid-name-foo', 'invalid/name', cloud,
108
exception=NameNotAccepted),
109
make_long_endpoint(spec),
110
], iter_clouds({'foo': cloud}))
139
xfail(cloud_spec('long-name-foo', 'A' * 4096, cloud),
140
1641970, NameMismatch),
141
xfail(cloud_spec('invalid-name-foo', 'invalid/name', cloud,
142
exception=NameNotAccepted), 1641981, None),
143
make_long_endpoint(spec, endpoint_validation=False)],
144
iter_clouds({'foo': cloud}, endpoint_validation=False))
112
146
def test_vsphere(self):
115
149
'endpoint': '1.2.3.4',
116
150
'regions': {'q': {'endpoint': '1.2.3.4'}},
118
spec = CloudSpec('foo', 'foo', cloud, exception=None)
152
spec = cloud_spec('foo', 'foo', cloud, exception=None)
119
153
self.assertItemsEqual([
120
154
self.bogus_type, spec,
121
CloudSpec('invalid-name-foo', 'invalid/name', cloud,
122
exception=NameNotAccepted),
123
CloudSpec('long-name-foo', 'A' * 4096, cloud, exception=None),
124
make_long_endpoint(spec, regions=True),
125
], iter_clouds({'foo': cloud}))
155
xfail(cloud_spec('invalid-name-foo', 'invalid/name', cloud,
156
exception=NameNotAccepted), 1641981, None),
157
xfail(cloud_spec('long-name-foo', 'A' * 4096, cloud,
158
exception=None), 1641970, NameMismatch),
159
xfail(make_long_endpoint(spec, regions=True,
160
endpoint_validation=True),
161
1641970, CloudMismatch),
162
], iter_clouds({'foo': cloud}, endpoint_validation=True))
127
164
def test_maas(self):
130
167
'endpoint': 'http://example.com',
132
spec = CloudSpec('foo', 'foo', cloud, exception=None)
133
self.assertItemsEqual([
134
self.bogus_type, spec,
135
CloudSpec('invalid-name-foo', 'invalid/name', cloud,
136
exception=NameNotAccepted),
137
CloudSpec('long-name-foo', 'A' * 4096, cloud, exception=None),
138
make_long_endpoint(spec),
139
], iter_clouds({'foo': cloud}))
169
spec = cloud_spec('foo', 'foo', cloud, exception=None)
170
self.assertItemsEqual([
171
self.bogus_type, spec,
172
xfail(cloud_spec('invalid-name-foo', 'invalid/name', cloud,
173
exception=NameNotAccepted), 1641981, None),
174
xfail(cloud_spec('long-name-foo', 'A' * 4096, cloud,
175
exception=None), 1641970, NameMismatch),
176
make_long_endpoint(spec, endpoint_validation=True),
177
], iter_clouds({'foo': cloud}, endpoint_validation=True))
179
def test_maas_no_validation(self):
182
'endpoint': 'http://example.com',
184
spec = cloud_spec('foo', 'foo', cloud, exception=None)
185
self.assertItemsEqual([
186
self.bogus_type, spec,
187
xfail(cloud_spec('invalid-name-foo', 'invalid/name', cloud,
188
exception=NameNotAccepted), 1641981, None),
189
xfail(cloud_spec('long-name-foo', 'A' * 4096, cloud,
190
exception=None), 1641970, NameMismatch),
191
make_long_endpoint(spec, endpoint_validation=False),
192
], iter_clouds({'foo': cloud}, endpoint_validation=False))
141
194
def test_openstack(self):
142
195
config = {'type': 'openstack', 'endpoint': 'http://example.com',
143
196
'regions': {'bar': {'endpoint': 'http://baz.example.com'}}}
144
spec = CloudSpec('foo', 'foo', config, exception=None)
145
invalid_name = CloudSpec('invalid-name-foo', 'invalid/name', config,
146
exception=NameNotAccepted)
147
long_name = CloudSpec('long-name-foo', 'A' * 4096, config,
149
long_region = CloudSpec('long-endpoint-foo-bar', 'foo',
150
deepcopy(config), exception=None)
151
long_region.config['regions']['bar']['endpoint'] = 'A' * 4096
152
bogus_auth = CloudSpec('bogus-auth-foo', 'foo',
153
deepcopy(config), exception=AuthNotAccepted)
154
bogus_auth.config['auth-types'] = ['asdf']
155
self.assertItemsEqual([
156
self.bogus_type, spec, invalid_name, long_name, long_region,
157
bogus_auth, make_long_endpoint(spec),
158
], iter_clouds({'foo': config}))
161
class TestAssessAllClouds(TestCase):
197
spec = cloud_spec('foo', 'foo', config, exception=None)
198
invalid_name = xfail(
199
cloud_spec('invalid-name-foo', 'invalid/name', config,
200
exception=NameNotAccepted), 1641981, None)
202
cloud_spec('long-name-foo', 'A' * 4096, config, exception=None),
203
1641970, NameMismatch)
204
long_region = cloud_spec(
205
'long-endpoint-foo-bar', 'foo', deepcopy(config), InvalidEndpoint)
206
long_region.config['regions']['bar']['endpoint'] = 'A' * 4096
207
bogus_auth = cloud_spec('bogus-auth-foo', 'foo',
208
deepcopy(config), exception=AuthNotAccepted)
209
bogus_auth.config['auth-types'] = ['asdf']
210
self.assertItemsEqual([
211
self.bogus_type, spec, invalid_name, long_name, long_region,
213
make_long_endpoint(spec, endpoint_validation=True),
214
], iter_clouds({'foo': config}, endpoint_validation=True))
216
def test_openstack_no_validation(self):
217
config = {'type': 'openstack', 'endpoint': 'http://example.com',
218
'regions': {'bar': {'endpoint': 'http://baz.example.com'}}}
219
spec = cloud_spec('foo', 'foo', config, exception=None)
220
invalid_name = xfail(
221
cloud_spec('invalid-name-foo', 'invalid/name', config,
222
exception=NameNotAccepted), 1641981, None)
224
cloud_spec('long-name-foo', 'A' * 4096, config, exception=None),
225
1641970, NameMismatch)
226
long_region = xfail(cloud_spec(
227
'long-endpoint-foo-bar', 'foo', deepcopy(config),
228
InvalidEndpoint), 1641970, CloudMismatch)
229
long_region.config['regions']['bar']['endpoint'] = 'A' * 4096
230
bogus_auth = cloud_spec('bogus-auth-foo', 'foo',
231
deepcopy(config), exception=AuthNotAccepted)
232
bogus_auth.config['auth-types'] = ['asdf']
233
self.assertItemsEqual([
234
self.bogus_type, spec, invalid_name, long_name, long_region,
236
make_long_endpoint(spec, endpoint_validation=False),
237
], iter_clouds({'foo': config}, endpoint_validation=False))
240
class TestAssessAllClouds(FakeHomeTestCase):
163
242
def test_assess_all_clouds(self):
164
client = self.make_fake_juju_client()
243
client = fake_juju_client(juju_home=self.juju_home)
165
244
clouds = {'a': {'type': 'foo'}, 'b': {'type': 'bar'}}
245
cloud_specs = iter_clouds(clouds, endpoint_validation=True)
166
246
exception = Exception()
167
247
with patch('assess_add_cloud.assess_cloud',
168
248
side_effect=[TypeNotAccepted(), None] + [exception] * 7):
169
249
with patch('sys.stdout'):
170
250
with patch('logging.exception') as exception_mock:
171
succeeded, failed = assess_all_clouds(client, clouds)
251
succeeded, xfail, failed = assess_all_clouds(client,
172
253
self.assertEqual({'bogus-type', 'a'}, succeeded)
173
254
self.assertEqual({
174
255
'b', 'bogus-auth-a', 'bogus-auth-b', 'invalid-name-a',