Statistics
| Branch: | Tag: | Revision:

root / kamaki / clients / image / test.py @ 7b6e977c

History | View | Annotate | Download (10.7 kB)

1 c1004a00 Stavros Sachtouris
# Copyright 2012-2013 GRNET S.A. All rights reserved.
2 c1004a00 Stavros Sachtouris
#
3 c1004a00 Stavros Sachtouris
# Redistribution and use in source and binary forms, with or
4 c1004a00 Stavros Sachtouris
# without modification, are permitted provided that the following
5 c1004a00 Stavros Sachtouris
# conditions are met:
6 c1004a00 Stavros Sachtouris
#
7 c1004a00 Stavros Sachtouris
#   1. Redistributions of source code must retain the above
8 c1004a00 Stavros Sachtouris
#      copyright notice, this list of conditions and the following
9 c1004a00 Stavros Sachtouris
#      disclaimer.
10 c1004a00 Stavros Sachtouris
#
11 c1004a00 Stavros Sachtouris
#   2. Redistributions in binary form must reproduce the above
12 c1004a00 Stavros Sachtouris
#      copyright notice, this list of conditions and the following
13 c1004a00 Stavros Sachtouris
#      disclaimer in the documentation and/or other materials
14 c1004a00 Stavros Sachtouris
#      provided with the distribution.
15 c1004a00 Stavros Sachtouris
#
16 c1004a00 Stavros Sachtouris
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 c1004a00 Stavros Sachtouris
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 c1004a00 Stavros Sachtouris
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 c1004a00 Stavros Sachtouris
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 c1004a00 Stavros Sachtouris
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 c1004a00 Stavros Sachtouris
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 c1004a00 Stavros Sachtouris
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 c1004a00 Stavros Sachtouris
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 c1004a00 Stavros Sachtouris
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 c1004a00 Stavros Sachtouris
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 c1004a00 Stavros Sachtouris
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 c1004a00 Stavros Sachtouris
# POSSIBILITY OF SUCH DAMAGE.
28 c1004a00 Stavros Sachtouris
#
29 c1004a00 Stavros Sachtouris
# The views and conclusions contained in the software and
30 c1004a00 Stavros Sachtouris
# documentation are those of the authors and should not be
31 c1004a00 Stavros Sachtouris
# interpreted as representing official policies, either expressed
32 c1004a00 Stavros Sachtouris
# or implied, of GRNET S.A.
33 c1004a00 Stavros Sachtouris
34 4ba03838 Stavros Sachtouris
from mock import patch, call
35 d86c3c7d Stavros Sachtouris
from unittest import TestCase
36 4ba03838 Stavros Sachtouris
from itertools import product
37 db113224 Stavros Sachtouris
38 7b6e977c Stavros Sachtouris
example_image_headers = {
39 7b6e977c Stavros Sachtouris
    'x-image-meta-id': '3edd4d15-41b4-4a39-9601-015ef56b3bb3',
40 7b6e977c Stavros Sachtouris
    'x-image-meta-checksum': 'df23837c30889252c0aed80b6f770a53a86',
41 7b6e977c Stavros Sachtouris
    'x-image-meta-container-format': 'bare',
42 7b6e977c Stavros Sachtouris
    'x-image-meta-location': 'pithos://a13528163db/con/obj_13.0',
43 7b6e977c Stavros Sachtouris
    'x-image-meta-disk-format': 'diskdump',
44 7b6e977c Stavros Sachtouris
    'x-image-meta-is-public': 'True',
45 7b6e977c Stavros Sachtouris
    'x-image-meta-status': 'available',
46 7b6e977c Stavros Sachtouris
    'x-image-meta-deleted-at': '',
47 7b6e977c Stavros Sachtouris
    'x-image-meta-updated-at': '2013-04-11 15:22:39',
48 7b6e977c Stavros Sachtouris
    'x-image-meta-created-at': '2013-04-11 15:22:37',
49 7b6e977c Stavros Sachtouris
    'x-image-meta-owner': 'a13529bb3c3db',
50 7b6e977c Stavros Sachtouris
    'x-image-meta-size': '1073741824',
51 7b6e977c Stavros Sachtouris
    'x-image-meta-name': 'img_1365686546.0',
52 7b6e977c Stavros Sachtouris
    'extraheaders': 'should be ignored'
53 7b6e977c Stavros Sachtouris
}
54 d86c3c7d Stavros Sachtouris
example_images = [
55 d86c3c7d Stavros Sachtouris
    {
56 d86c3c7d Stavros Sachtouris
        "status": "available",
57 d86c3c7d Stavros Sachtouris
        "name": "Archlinux",
58 d86c3c7d Stavros Sachtouris
        "disk_format": "diskdump",
59 d86c3c7d Stavros Sachtouris
        "container_format": "bare",
60 d86c3c7d Stavros Sachtouris
        "id": "b4713f20-3a41-4eaf-81ae-88698c18b3e8",
61 d86c3c7d Stavros Sachtouris
        "size": 752782848},
62 d86c3c7d Stavros Sachtouris
    {
63 d86c3c7d Stavros Sachtouris
        "status": "available",
64 d86c3c7d Stavros Sachtouris
        "name": "maelstrom",
65 d86c3c7d Stavros Sachtouris
        "disk_format": "diskdump",
66 d86c3c7d Stavros Sachtouris
        "container_format": "bare",
67 d86c3c7d Stavros Sachtouris
        "id": "0fb03e45-7d5a-4515-bd4e-e6bbf6457f06",
68 d86c3c7d Stavros Sachtouris
        "size": 2583195644},
69 d86c3c7d Stavros Sachtouris
    {
70 d86c3c7d Stavros Sachtouris
        "status": "available",
71 d86c3c7d Stavros Sachtouris
        "name": "Gardenia",
72 d86c3c7d Stavros Sachtouris
        "disk_format": "diskdump",
73 d86c3c7d Stavros Sachtouris
        "container_format": "bare",
74 d86c3c7d Stavros Sachtouris
        "id": "5963020b-ab74-4e11-bc59-90c494bbdedb",
75 d86c3c7d Stavros Sachtouris
        "size": 2589802496}]
76 b283ee49 Stavros Sachtouris
imgid = "b4713f20-3a41-4eaf-81ae-88698c18b3e8"
77 e2c53122 Stavros Sachtouris
example_images_detailed = [
78 e2c53122 Stavros Sachtouris
    {
79 e2c53122 Stavros Sachtouris
        "status": "available",
80 e2c53122 Stavros Sachtouris
        "name": "Archlinux",
81 e2c53122 Stavros Sachtouris
        "checksum": "1a126aad07475b43cc1959b446344211be13974",
82 e2c53122 Stavros Sachtouris
        "created_at": "2013-01-28 22:44:54",
83 e2c53122 Stavros Sachtouris
        "disk_format": "diskdump",
84 e2c53122 Stavros Sachtouris
        "updated_at": "2013-01-28 22:44:55",
85 e2c53122 Stavros Sachtouris
        "properties": {
86 e2c53122 Stavros Sachtouris
            "partition_table": "msdos",
87 e2c53122 Stavros Sachtouris
            "osfamily": "linux",
88 e2c53122 Stavros Sachtouris
            "users": "root",
89 e2c53122 Stavros Sachtouris
            "exclude_task_assignhostname": "yes",
90 e2c53122 Stavros Sachtouris
            "os": "archlinux",
91 e2c53122 Stavros Sachtouris
            "root_partition": "1",
92 e2c53122 Stavros Sachtouris
            "description": "Archlinux base install 2012.12.01"},
93 e2c53122 Stavros Sachtouris
        "location": "pithos://us3r-I6E-1d/images/archlinux.12.2012",
94 e2c53122 Stavros Sachtouris
        "container_format": "bare",
95 e2c53122 Stavros Sachtouris
        "owner": "user163@mail.example.com",
96 e2c53122 Stavros Sachtouris
        "is_public": True,
97 e2c53122 Stavros Sachtouris
        "deleted_at": "",
98 e2c53122 Stavros Sachtouris
        "id": "b4713f20-3a41-4eaf-81ae-88698c18b3e8",
99 e2c53122 Stavros Sachtouris
        "size": 752782848},
100 e2c53122 Stavros Sachtouris
    {
101 e2c53122 Stavros Sachtouris
        "status": "available",
102 e2c53122 Stavros Sachtouris
        "name": "maelstrom",
103 e2c53122 Stavros Sachtouris
        "checksum": "b202b8c7030cb22f896c6664ac",
104 e2c53122 Stavros Sachtouris
        "created_at": "2013-02-13 10:07:42",
105 e2c53122 Stavros Sachtouris
        "disk_format": "diskdump",
106 e2c53122 Stavros Sachtouris
        "updated_at": "2013-02-13 10:07:44",
107 e2c53122 Stavros Sachtouris
        "properties": {
108 e2c53122 Stavros Sachtouris
            "partition_table": "msdos",
109 e2c53122 Stavros Sachtouris
            "osfamily": "linux",
110 e2c53122 Stavros Sachtouris
            "description": "Ubuntu 12.04.1 LTS",
111 e2c53122 Stavros Sachtouris
            "os": "ubuntu",
112 e2c53122 Stavros Sachtouris
            "root_partition": "1",
113 e2c53122 Stavros Sachtouris
            "users": "user"},
114 e2c53122 Stavros Sachtouris
        "location": "pithos://us3r-@r3n@-1d/images/mls-201302131203.diskdump",
115 e2c53122 Stavros Sachtouris
        "container_format": "bare",
116 e2c53122 Stavros Sachtouris
        "owner": "user3@mail.example.com",
117 e2c53122 Stavros Sachtouris
        "is_public": True,
118 e2c53122 Stavros Sachtouris
        "deleted_at": "",
119 e2c53122 Stavros Sachtouris
        "id": "0fb03e45-7d5a-4515-bd4e-e6bbf6457f06",
120 e2c53122 Stavros Sachtouris
        "size": 2583195648},
121 e2c53122 Stavros Sachtouris
    {
122 e2c53122 Stavros Sachtouris
        "status": "available",
123 e2c53122 Stavros Sachtouris
        "name": "Gardenia",
124 e2c53122 Stavros Sachtouris
        "checksum": "06d3099815d1f6fada91e80107638b882",
125 e2c53122 Stavros Sachtouris
        "created_at": "2013-02-13 12:35:21",
126 e2c53122 Stavros Sachtouris
        "disk_format": "diskdump",
127 e2c53122 Stavros Sachtouris
        "updated_at": "2013-02-13 12:35:23",
128 e2c53122 Stavros Sachtouris
        "properties": {
129 e2c53122 Stavros Sachtouris
            "partition_table": "msdos",
130 e2c53122 Stavros Sachtouris
            "osfamily": "linux",
131 e2c53122 Stavros Sachtouris
            "description": "Ubuntu 12.04.2 LTS",
132 e2c53122 Stavros Sachtouris
            "os": "ubuntu",
133 e2c53122 Stavros Sachtouris
            "root_partition": "1",
134 e2c53122 Stavros Sachtouris
            "users": "user"},
135 e2c53122 Stavros Sachtouris
        "location": "pithos://us3r-E-1d/images/Gardenia-201302131431.diskdump",
136 e2c53122 Stavros Sachtouris
        "container_format": "bare",
137 e2c53122 Stavros Sachtouris
        "owner": "user3@mail.example.com",
138 e2c53122 Stavros Sachtouris
        "is_public": True,
139 e2c53122 Stavros Sachtouris
        "deleted_at": "",
140 e2c53122 Stavros Sachtouris
        "id": "5963020b-ab74-4e11-bc59-90c494bbdedb",
141 e2c53122 Stavros Sachtouris
        "size": 2589802496}]
142 e2c53122 Stavros Sachtouris
143 fe5173b9 Stavros Sachtouris
144 975270f2 Stavros Sachtouris
class FR(object):
145 975270f2 Stavros Sachtouris
    json = example_images
146 975270f2 Stavros Sachtouris
    headers = {}
147 975270f2 Stavros Sachtouris
    content = json
148 975270f2 Stavros Sachtouris
    status = None
149 975270f2 Stavros Sachtouris
    status_code = 200
150 975270f2 Stavros Sachtouris
151 4ba03838 Stavros Sachtouris
image_pkg = 'kamaki.clients.image.ImageClient'
152 975270f2 Stavros Sachtouris
153 975270f2 Stavros Sachtouris
154 3c50df2e Stavros Sachtouris
class ImageClient(TestCase):
155 d86c3c7d Stavros Sachtouris
156 4ba03838 Stavros Sachtouris
    def assert_dicts_are_equal(self, d1, d2):
157 03493855 Stavros Sachtouris
        for k, v in d1.items():
158 03493855 Stavros Sachtouris
            self.assertTrue(k in d2)
159 03493855 Stavros Sachtouris
            if isinstance(v, dict):
160 4ba03838 Stavros Sachtouris
                self.assert_dicts_are_equal(v, d2[k])
161 03493855 Stavros Sachtouris
            else:
162 03493855 Stavros Sachtouris
                self.assertEqual(unicode(v), unicode(d2[k]))
163 03493855 Stavros Sachtouris
164 c1004a00 Stavros Sachtouris
    def setUp(self):
165 d86c3c7d Stavros Sachtouris
        self.url = 'http://image.example.com'
166 d86c3c7d Stavros Sachtouris
        self.token = 'an1m@g370k3n=='
167 3c50df2e Stavros Sachtouris
        from kamaki.clients import image
168 3c50df2e Stavros Sachtouris
        self.client = image.ImageClient(self.url, self.token)
169 c1004a00 Stavros Sachtouris
170 c1004a00 Stavros Sachtouris
    def tearDown(self):
171 975270f2 Stavros Sachtouris
        FR.json = example_images
172 975270f2 Stavros Sachtouris
        FR.status_code = 200
173 c1004a00 Stavros Sachtouris
174 4ba03838 Stavros Sachtouris
    @patch('%s.get' % image_pkg, return_value=FR())
175 4ba03838 Stavros Sachtouris
    def test_list_public(self, get):
176 4ba03838 Stavros Sachtouris
        a_filter = dict(size_max=42)
177 4ba03838 Stavros Sachtouris
        for args in product((False, True), ({}, a_filter), ('', '-')):
178 4ba03838 Stavros Sachtouris
            (detail, filters, order) = args
179 4ba03838 Stavros Sachtouris
            r = self.client.list_public(*args)
180 4ba03838 Stavros Sachtouris
            filters['sort_dir'] = 'desc' if order.startswith('-') else 'asc'
181 4ba03838 Stavros Sachtouris
            self.assertEqual(get.mock_calls[-1], call(
182 4ba03838 Stavros Sachtouris
                '/images/%s' % ('detail' if detail else ''),
183 4ba03838 Stavros Sachtouris
                async_params=filters, success=200))
184 4ba03838 Stavros Sachtouris
            for i in range(len(r)):
185 4ba03838 Stavros Sachtouris
                self.assert_dicts_are_equal(r[i], example_images[i])
186 d86c3c7d Stavros Sachtouris
187 d55c06f0 Stavros Sachtouris
    @patch('%s.head' % image_pkg, return_value=FR())
188 d55c06f0 Stavros Sachtouris
    def test_get_meta(self, head):
189 e2c53122 Stavros Sachtouris
        img0 = example_images[0]
190 975270f2 Stavros Sachtouris
        FR.json = img0
191 e2c53122 Stavros Sachtouris
        img0_headers = {}
192 e2c53122 Stavros Sachtouris
        for k, v in example_images_detailed[0].items():
193 e2c53122 Stavros Sachtouris
            img0_headers['x-image-meta-%s' % k] = v
194 975270f2 Stavros Sachtouris
        FR.headers = img0_headers
195 975270f2 Stavros Sachtouris
        r = self.client.get_meta(img0['id'])
196 d55c06f0 Stavros Sachtouris
        head.assert_called_once_with('/images/%s' % img0['id'], success=200)
197 975270f2 Stavros Sachtouris
        self.assertEqual(r['id'], img0['id'])
198 4ba03838 Stavros Sachtouris
        self.assert_dicts_are_equal(r, example_images_detailed[0])
199 e2c53122 Stavros Sachtouris
200 f875dd02 Stavros Sachtouris
    @patch('%s.set_header' % image_pkg, return_value=FR())
201 f875dd02 Stavros Sachtouris
    @patch('%s.post' % image_pkg, return_value=FR())
202 f875dd02 Stavros Sachtouris
    def test_register(self, post, SH):
203 fe5173b9 Stavros Sachtouris
        img0 = example_images_detailed[0]
204 7b6e977c Stavros Sachtouris
        FR.headers = example_image_headers
205 fe5173b9 Stavros Sachtouris
        img0_location = img0['location']
206 fe5173b9 Stavros Sachtouris
        img0_name = 'A new img0 name'
207 f875dd02 Stavros Sachtouris
        prfx = 'x-image-meta-'
208 f875dd02 Stavros Sachtouris
        proprfx = 'x-image-meta-property-'
209 f875dd02 Stavros Sachtouris
        keys = [
210 f875dd02 Stavros Sachtouris
            'id', 'store', 'dist_format', 'container_format',
211 f875dd02 Stavros Sachtouris
            'size', 'checksum', 'is_public', 'owner']
212 f875dd02 Stavros Sachtouris
        for args in product(
213 f875dd02 Stavros Sachtouris
                ('v_id', None), ('v_store', None),
214 f875dd02 Stavros Sachtouris
                ('v_dist_format', None), ('v_container_format', None),
215 f875dd02 Stavros Sachtouris
                ('v_size', None), ('v_checksum', None),
216 f875dd02 Stavros Sachtouris
                ('v_is_public', None), ('v_owner', None)):
217 f875dd02 Stavros Sachtouris
            params = dict()
218 f875dd02 Stavros Sachtouris
            async_headers = dict()
219 f875dd02 Stavros Sachtouris
            props = dict()
220 f875dd02 Stavros Sachtouris
            for i, k in enumerate(keys):
221 f875dd02 Stavros Sachtouris
                if args[i]:
222 f875dd02 Stavros Sachtouris
                    params[k] = args[i]
223 f875dd02 Stavros Sachtouris
                    async_headers['%s%s' % (prfx, k)] = args[i]
224 f875dd02 Stavros Sachtouris
                    props['%s%s' % (proprfx, args[i])] = k
225 f875dd02 Stavros Sachtouris
            async_headers.update(props)
226 7b6e977c Stavros Sachtouris
        r = self.client.register(
227 f875dd02 Stavros Sachtouris
            img0_name, img0_location,
228 f875dd02 Stavros Sachtouris
            params=params, properties=props)
229 7b6e977c Stavros Sachtouris
        expectedict = dict(example_image_headers)
230 7b6e977c Stavros Sachtouris
        expectedict.pop('extraheaders')
231 7b6e977c Stavros Sachtouris
        self.assert_dicts_are_equal(expectedict, r)
232 f875dd02 Stavros Sachtouris
        self.assertEqual(
233 f875dd02 Stavros Sachtouris
            post.mock_calls[-1],
234 f875dd02 Stavros Sachtouris
            call('/images/', async_headers=async_headers, success=200))
235 f875dd02 Stavros Sachtouris
        self.assertEqual(SH.mock_calls[-2:], [
236 f875dd02 Stavros Sachtouris
            call('X-Image-Meta-Name', img0_name),
237 f875dd02 Stavros Sachtouris
            call('X-Image-Meta-Location', img0_location)])
238 c1004a00 Stavros Sachtouris
239 80643233 Stavros Sachtouris
    @patch('%s.put' % image_pkg, return_value=FR())
240 80643233 Stavros Sachtouris
    def test_set_members(self, put):
241 03314970 Stavros Sachtouris
        members = ['use3r-1d-0', 'us2r-1d-1', 'us3r-1d-2']
242 b283ee49 Stavros Sachtouris
        self.client.set_members(imgid, members)
243 80643233 Stavros Sachtouris
        put.assert_called_once_with(
244 b283ee49 Stavros Sachtouris
            '/images/%s/members' % imgid,
245 80643233 Stavros Sachtouris
            json=dict(memberships=[dict(member_id=m) for m in members]),
246 80643233 Stavros Sachtouris
            success=204)
247 c1004a00 Stavros Sachtouris
248 b283ee49 Stavros Sachtouris
    @patch('%s.get' % image_pkg, return_value=FR())
249 5a745d8a Stavros Sachtouris
    def test_list_members(self, get):
250 d01f7d92 Stavros Sachtouris
        members = ['use3r-1d-0', 'us2r-1d-1', 'us3r-1d-2']
251 975270f2 Stavros Sachtouris
        FR.json = dict(members=members)
252 5a745d8a Stavros Sachtouris
        r = self.client.list_members(imgid)
253 5a745d8a Stavros Sachtouris
        get.assert_called_once_with('/images/%s/members' % imgid, success=200)
254 975270f2 Stavros Sachtouris
        self.assertEqual(r, members)
255 c1004a00 Stavros Sachtouris
256 d8c7cccc Stavros Sachtouris
    @patch('%s.put' % image_pkg, return_value=FR())
257 d8c7cccc Stavros Sachtouris
    def test_add_member(self, put):
258 04f0c625 Stavros Sachtouris
        new_member = 'us3r-15-n3w'
259 d8c7cccc Stavros Sachtouris
        self.client.add_member(imgid, new_member)
260 d8c7cccc Stavros Sachtouris
        put.assert_called_once_with(
261 d8c7cccc Stavros Sachtouris
            '/images/%s/members/%s' % (imgid, new_member),
262 d8c7cccc Stavros Sachtouris
            success=204)
263 04f0c625 Stavros Sachtouris
264 10e6c39a Stavros Sachtouris
    @patch('%s.delete' % image_pkg, return_value=FR())
265 10e6c39a Stavros Sachtouris
    def test_remove_member(self, delete):
266 e09db3c4 Stavros Sachtouris
        old_member = 'us3r-15-0ld'
267 10e6c39a Stavros Sachtouris
        self.client.remove_member(imgid, old_member)
268 10e6c39a Stavros Sachtouris
        delete.assert_called_once_with(
269 10e6c39a Stavros Sachtouris
            '/images/%s/members/%s' % (imgid, old_member),
270 10e6c39a Stavros Sachtouris
            success=204)
271 c1004a00 Stavros Sachtouris
272 b283ee49 Stavros Sachtouris
    @patch('%s.get' % image_pkg, return_value=FR())
273 b283ee49 Stavros Sachtouris
    def test_list_shared(self, get):
274 975270f2 Stavros Sachtouris
        FR.json = dict(shared_images=example_images)
275 b283ee49 Stavros Sachtouris
        r = self.client.list_shared(imgid)
276 b283ee49 Stavros Sachtouris
        get.assert_called_once_with('/shared-images/%s' % imgid, success=200)
277 975270f2 Stavros Sachtouris
        for i in range(len(r)):
278 4ba03838 Stavros Sachtouris
            self.assert_dicts_are_equal(r[i], example_images[i])
279 85898ca4 Stavros Sachtouris
280 85898ca4 Stavros Sachtouris
if __name__ == '__main__':
281 85898ca4 Stavros Sachtouris
    from sys import argv
282 85898ca4 Stavros Sachtouris
    from kamaki.clients.test import runTestCase
283 3c50df2e Stavros Sachtouris
    runTestCase(ImageClient, 'Plankton Client', argv[1:])