~cloud-init-dev/cloud-init/trunk

« back to all changes in this revision

Viewing changes to tests/unittests/test_datasource/test_maas.py

  • Committer: Scott Moser
  • Date: 2016-08-10 15:06:15 UTC
  • Revision ID: smoser@ubuntu.com-20160810150615-ma2fv107w3suy1ma
README: Mention move of revision control to git.

cloud-init development has moved its revision control to git.
It is available at 
  https://code.launchpad.net/cloud-init

Clone with 
  git clone https://git.launchpad.net/cloud-init
or
  git clone git+ssh://git.launchpad.net/cloud-init

For more information see
  https://git.launchpad.net/cloud-init/tree/HACKING.rst

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
from copy import copy
2
 
import os
3
 
import shutil
4
 
import tempfile
5
 
 
6
 
from cloudinit.sources import DataSourceMAAS
7
 
from cloudinit import url_helper
8
 
from ..helpers import TestCase, populate_dir
9
 
 
10
 
try:
11
 
    from unittest import mock
12
 
except ImportError:
13
 
    import mock
14
 
 
15
 
 
16
 
class TestMAASDataSource(TestCase):
17
 
 
18
 
    def setUp(self):
19
 
        super(TestMAASDataSource, self).setUp()
20
 
        # Make a temp directoy for tests to use.
21
 
        self.tmp = tempfile.mkdtemp()
22
 
        self.addCleanup(shutil.rmtree, self.tmp)
23
 
 
24
 
    def test_seed_dir_valid(self):
25
 
        """Verify a valid seeddir is read as such."""
26
 
 
27
 
        data = {'instance-id': 'i-valid01',
28
 
                'local-hostname': 'valid01-hostname',
29
 
                'user-data': b'valid01-userdata',
30
 
                'public-keys': 'ssh-rsa AAAAB3Nz...aC1yc2E= keyname'}
31
 
 
32
 
        my_d = os.path.join(self.tmp, "valid")
33
 
        populate_dir(my_d, data)
34
 
 
35
 
        (userdata, metadata) = DataSourceMAAS.read_maas_seed_dir(my_d)
36
 
 
37
 
        self.assertEqual(userdata, data['user-data'])
38
 
        for key in ('instance-id', 'local-hostname'):
39
 
            self.assertEqual(data[key], metadata[key])
40
 
 
41
 
        # verify that 'userdata' is not returned as part of the metadata
42
 
        self.assertFalse(('user-data' in metadata))
43
 
 
44
 
    def test_seed_dir_valid_extra(self):
45
 
        """Verify extra files do not affect seed_dir validity."""
46
 
 
47
 
        data = {'instance-id': 'i-valid-extra',
48
 
                'local-hostname': 'valid-extra-hostname',
49
 
                'user-data': b'valid-extra-userdata', 'foo': 'bar'}
50
 
 
51
 
        my_d = os.path.join(self.tmp, "valid_extra")
52
 
        populate_dir(my_d, data)
53
 
 
54
 
        (userdata, metadata) = DataSourceMAAS.read_maas_seed_dir(my_d)
55
 
 
56
 
        self.assertEqual(userdata, data['user-data'])
57
 
        for key in ('instance-id', 'local-hostname'):
58
 
            self.assertEqual(data[key], metadata[key])
59
 
 
60
 
        # additional files should not just appear as keys in metadata atm
61
 
        self.assertFalse(('foo' in metadata))
62
 
 
63
 
    def test_seed_dir_invalid(self):
64
 
        """Verify that invalid seed_dir raises MAASSeedDirMalformed."""
65
 
 
66
 
        valid = {'instance-id': 'i-instanceid',
67
 
                 'local-hostname': 'test-hostname', 'user-data': ''}
68
 
 
69
 
        my_based = os.path.join(self.tmp, "valid_extra")
70
 
 
71
 
        # missing 'userdata' file
72
 
        my_d = "%s-01" % my_based
73
 
        invalid_data = copy(valid)
74
 
        del invalid_data['local-hostname']
75
 
        populate_dir(my_d, invalid_data)
76
 
        self.assertRaises(DataSourceMAAS.MAASSeedDirMalformed,
77
 
                          DataSourceMAAS.read_maas_seed_dir, my_d)
78
 
 
79
 
        # missing 'instance-id'
80
 
        my_d = "%s-02" % my_based
81
 
        invalid_data = copy(valid)
82
 
        del invalid_data['instance-id']
83
 
        populate_dir(my_d, invalid_data)
84
 
        self.assertRaises(DataSourceMAAS.MAASSeedDirMalformed,
85
 
                          DataSourceMAAS.read_maas_seed_dir, my_d)
86
 
 
87
 
    def test_seed_dir_none(self):
88
 
        """Verify that empty seed_dir raises MAASSeedDirNone."""
89
 
 
90
 
        my_d = os.path.join(self.tmp, "valid_empty")
91
 
        self.assertRaises(DataSourceMAAS.MAASSeedDirNone,
92
 
                          DataSourceMAAS.read_maas_seed_dir, my_d)
93
 
 
94
 
    def test_seed_dir_missing(self):
95
 
        """Verify that missing seed_dir raises MAASSeedDirNone."""
96
 
        self.assertRaises(DataSourceMAAS.MAASSeedDirNone,
97
 
                          DataSourceMAAS.read_maas_seed_dir,
98
 
                          os.path.join(self.tmp, "nonexistantdirectory"))
99
 
 
100
 
    def test_seed_url_valid(self):
101
 
        """Verify that valid seed_url is read as such."""
102
 
        valid = {
103
 
            'meta-data/instance-id': 'i-instanceid',
104
 
            'meta-data/local-hostname': 'test-hostname',
105
 
            'meta-data/public-keys': 'test-hostname',
106
 
            'user-data': b'foodata',
107
 
        }
108
 
        valid_order = [
109
 
            'meta-data/local-hostname',
110
 
            'meta-data/instance-id',
111
 
            'meta-data/public-keys',
112
 
            'user-data',
113
 
        ]
114
 
        my_seed = "http://example.com/xmeta"
115
 
        my_ver = "1999-99-99"
116
 
        my_headers = {'header1': 'value1', 'header2': 'value2'}
117
 
 
118
 
        def my_headers_cb(url):
119
 
            return my_headers
120
 
 
121
 
        # Each time url_helper.readurl() is called, something different is
122
 
        # returned based on the canned data above.  We need to build up a list
123
 
        # of side effect return values, which the mock will return.  At the
124
 
        # same time, we'll build up a list of expected call arguments for
125
 
        # asserting after the code under test is run.
126
 
        calls = []
127
 
 
128
 
        def side_effect():
129
 
            for key in valid_order:
130
 
                resp = valid.get(key)
131
 
                url = "%s/%s/%s" % (my_seed, my_ver, key)
132
 
                calls.append(
133
 
                    mock.call(url, headers=None, timeout=mock.ANY,
134
 
                              data=mock.ANY, sec_between=mock.ANY,
135
 
                              ssl_details=mock.ANY, retries=mock.ANY,
136
 
                              headers_cb=my_headers_cb,
137
 
                              exception_cb=mock.ANY))
138
 
                yield url_helper.StringResponse(resp)
139
 
 
140
 
        # Now do the actual call of the code under test.
141
 
        with mock.patch.object(url_helper, 'readurl',
142
 
                               side_effect=side_effect()) as mockobj:
143
 
            userdata, metadata = DataSourceMAAS.read_maas_seed_url(
144
 
                my_seed, version=my_ver)
145
 
 
146
 
            self.assertEqual(b"foodata", userdata)
147
 
            self.assertEqual(metadata['instance-id'],
148
 
                             valid['meta-data/instance-id'])
149
 
            self.assertEqual(metadata['local-hostname'],
150
 
                             valid['meta-data/local-hostname'])
151
 
 
152
 
            mockobj.has_calls(calls)
153
 
 
154
 
    def test_seed_url_invalid(self):
155
 
        """Verify that invalid seed_url raises MAASSeedDirMalformed."""
156
 
        pass
157
 
 
158
 
    def test_seed_url_missing(self):
159
 
        """Verify seed_url with no found entries raises MAASSeedDirNone."""
160
 
        pass
161
 
 
162
 
 
163
 
# vi: ts=4 expandtab