1
1
"""Testing for the OpenStack provider interface"""
2
from twisted.internet.defer import inlineCallbacks
4
from juju import errors
3
5
from juju.lib.testing import TestCase
4
6
from juju.environment.errors import EnvironmentsConfigError
6
from juju.providers.openstack.files import FileStorage
7
from juju.providers.openstack.provider import MachineProvider
10
class ProviderTestCase(TestCase):
7
from juju.machine.constraints import ConstraintSet
9
from juju.providers.openstack import client as _mod_client
10
from juju.providers.openstack.tests import OpenStackTestMixin
13
class ProviderTestMixin(object):
15
from juju.providers.openstack.files import FileStorage as FileStorageClass
16
from juju.providers.openstack.provider import (
17
MachineProvider as ProviderClass)
12
19
environment_name = "testing"
15
"NOVA_URL": "http://environ.invalid",
22
"NOVA_URL": "https://environ.invalid",
16
23
"NOVA_API_KEY": "env-key",
17
24
"EC2_SECRET_KEY": "env-xxxx",
18
25
"NOVA_PROJECT_ID": "env-project",
24
31
"auth-mode": "keypair",
25
32
"access-key": "key",
26
33
"secret-key": "xxxxxxxx",
27
"auth-url": "http://testing.invalid",
34
"auth-url": "https://testing.invalid",
28
35
"project-name": "project",
29
36
"control-bucket": self.environment_name,
39
def get_provider(self, config=None):
41
config = self.get_config()
42
return self.ProviderClass(self.environment_name, config)
44
def get_client(self, provider):
45
client = provider.nova._client
46
self.assertIs(client, provider.swift._client)
50
class ProviderTests(ProviderTestMixin, TestCase):
32
52
def test_empty_config_raises(self):
33
53
"""Passing no config raises an exception about lacking credentials"""
34
54
self.change_environment()
35
55
# XXX: Should this raise EnvironmentsConfigError instead?
36
self.assertRaises(ValueError,
37
MachineProvider, self.environment_name, {})
56
self.assertRaises(ValueError, self.get_provider, {})
39
58
def test_client_params(self):
40
59
"""Config details get passed through to OpenStack client correctly"""
41
config = self.get_config()
42
provider = MachineProvider(self.environment_name, config)
60
provider = self.get_provider()
43
61
creds = provider.credentials
44
62
self.assertEquals("key", creds.access_key)
45
63
self.assertEquals("xxxxxxxx", creds.secret_key)
46
self.assertEquals("http://testing.invalid", creds.url)
64
self.assertEquals("https://testing.invalid", creds.url)
47
65
self.assertEquals("project", creds.project_name)
48
self.assertIs(creds, provider.nova._client.credentials)
49
self.assertIs(creds, provider.swift._client.credentials)
66
self.assertIs(creds, self.get_client(provider).credentials)
51
68
def test_provider_attributes(self):
53
70
The provider environment name and config should be available as
54
71
parameters in the provider.
56
provider = MachineProvider(self.environment_name, self.get_config())
73
provider = self.get_provider()
57
74
self.assertEqual(provider.environment_name, self.environment_name)
58
75
self.assertEqual(provider.config.get("type"), "openstack")
59
76
self.assertEqual(provider.provider_type, "openstack")
61
78
def test_get_file_storage(self):
62
79
"""The file storage is accessible via the machine provider."""
63
provider = MachineProvider(self.environment_name, self.get_config())
80
provider = self.get_provider()
64
81
storage = provider.get_file_storage()
65
self.assertTrue(isinstance(storage, FileStorage))
82
self.assertTrue(isinstance(storage, self.FileStorageClass))
67
84
def test_config_serialization(self):
83
100
Variables from the configuration take precendence over those from
84
101
the environment, when serializing.
86
self.change_environment(**self._test_environ)
87
provider = MachineProvider(self.environment_name, {
103
self.change_environment(**self.test_environ)
104
provider = self.get_provider({
88
105
"auth-mode": "keypair",
89
106
"project-name": "other-project",
90
107
"authorized-keys": "key-data",
109
126
config["authorized-keys"] = "File content"
110
127
config["authorized-keys-path"] = "File path"
111
128
error = self.assertRaises(EnvironmentsConfigError,
112
MachineProvider, self.environment_name, config)
129
self.get_provider, config)
113
130
self.assertEquals(
115
132
"Environment config cannot define both authorized-keys and "
116
133
"authorized-keys-path. Pick one!")
136
class CheckCertsTests(ProviderTestMixin, TestCase):
138
def run_test(self, config_changes, txaws_support=True):
139
log = self.capture_logging("juju")
144
self.patch(_mod_client, "WebVerifyingContextFactory", obj)
145
config = self.get_config()
146
config.update(config_changes)
147
provider = self.get_provider(config)
150
def test_default_true(self):
151
provider, log = self.run_test({})
152
self.assertNotIn("ssl-hostname-verification", provider.config)
153
self.assertEquals(True, provider._check_certs)
154
self.assertEquals(True, self.get_client(provider).check_certs)
155
self.assertEqual("", log.getvalue())
157
def test_false(self):
158
provider, log = self.run_test({"ssl-hostname-verification": False})
159
self.assertEquals(False, provider._check_certs)
160
self.assertEquals(False, self.get_client(provider).check_certs)
161
self.assertIn("Set 'ssl-hostname-verification'", log.getvalue())
164
provider, log = self.run_test({"ssl-hostname-verification": True})
165
self.assertEquals(True, provider._check_certs)
166
self.assertEquals(True, self.get_client(provider).check_certs)
167
self.assertEqual("", log.getvalue())
169
def test_http_auth_url(self):
170
provider, log = self.run_test({
171
"auth-url": "http://testing.invalid",
172
"ssl-hostname-verification": True,
174
self.assertEquals(True, self.get_client(provider).check_certs)
175
self.assertIn("identity service not using secure", log.getvalue())
177
def test_no_txaws_support(self):
178
self.assertRaises(errors.SSLVerificationUnsupported, self.run_test,
179
{"ssl-hostname-verification": True}, txaws_support=False)
182
class GetConstraintSetTests(OpenStackTestMixin, TestCase):
185
def test_get_constraints(self):
186
self.expect_nova_get("flavors",
187
response={'flavors': self.default_flavors})
189
provider = self.get_provider()
190
cs = yield provider.get_constraint_set()
191
self.assertIsInstance(cs, ConstraintSet)
192
cs2 = yield provider.get_constraint_set()
193
self.assertIsInstance(cs2, ConstraintSet)
194
self.assertEqual(cs, cs2)