Statistics
| Branch: | Tag: | Revision:

root / kamaki / clients / test / image.py @ 03493855

History | View | Annotate | Download (13.1 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 d86c3c7d Stavros Sachtouris
from mock import patch
35 d86c3c7d Stavros Sachtouris
from unittest import TestCase
36 db113224 Stavros Sachtouris
37 c1004a00 Stavros Sachtouris
from kamaki.clients import ClientError
38 c1004a00 Stavros Sachtouris
39 d86c3c7d Stavros Sachtouris
example_images = [
40 d86c3c7d Stavros Sachtouris
    {
41 d86c3c7d Stavros Sachtouris
        "status": "available",
42 d86c3c7d Stavros Sachtouris
        "name": "Archlinux",
43 d86c3c7d Stavros Sachtouris
        "disk_format": "diskdump",
44 d86c3c7d Stavros Sachtouris
        "container_format": "bare",
45 d86c3c7d Stavros Sachtouris
        "id": "b4713f20-3a41-4eaf-81ae-88698c18b3e8",
46 d86c3c7d Stavros Sachtouris
        "size": 752782848},
47 d86c3c7d Stavros Sachtouris
    {
48 d86c3c7d Stavros Sachtouris
        "status": "available",
49 d86c3c7d Stavros Sachtouris
        "name": "maelstrom",
50 d86c3c7d Stavros Sachtouris
        "disk_format": "diskdump",
51 d86c3c7d Stavros Sachtouris
        "container_format": "bare",
52 d86c3c7d Stavros Sachtouris
        "id": "0fb03e45-7d5a-4515-bd4e-e6bbf6457f06",
53 d86c3c7d Stavros Sachtouris
        "size": 2583195644},
54 d86c3c7d Stavros Sachtouris
    {
55 d86c3c7d Stavros Sachtouris
        "status": "available",
56 d86c3c7d Stavros Sachtouris
        "name": "Gardenia",
57 d86c3c7d Stavros Sachtouris
        "disk_format": "diskdump",
58 d86c3c7d Stavros Sachtouris
        "container_format": "bare",
59 d86c3c7d Stavros Sachtouris
        "id": "5963020b-ab74-4e11-bc59-90c494bbdedb",
60 d86c3c7d Stavros Sachtouris
        "size": 2589802496}]
61 d86c3c7d Stavros Sachtouris
62 e2c53122 Stavros Sachtouris
example_images_detailed = [
63 e2c53122 Stavros Sachtouris
    {
64 e2c53122 Stavros Sachtouris
        "status": "available",
65 e2c53122 Stavros Sachtouris
        "name": "Archlinux",
66 e2c53122 Stavros Sachtouris
        "checksum": "1a126aad07475b43cc1959b446344211be13974",
67 e2c53122 Stavros Sachtouris
        "created_at": "2013-01-28 22:44:54",
68 e2c53122 Stavros Sachtouris
        "disk_format": "diskdump",
69 e2c53122 Stavros Sachtouris
        "updated_at": "2013-01-28 22:44:55",
70 e2c53122 Stavros Sachtouris
        "properties": {
71 e2c53122 Stavros Sachtouris
            "partition_table": "msdos",
72 e2c53122 Stavros Sachtouris
            "osfamily": "linux",
73 e2c53122 Stavros Sachtouris
            "users": "root",
74 e2c53122 Stavros Sachtouris
            "exclude_task_assignhostname": "yes",
75 e2c53122 Stavros Sachtouris
            "os": "archlinux",
76 e2c53122 Stavros Sachtouris
            "root_partition": "1",
77 e2c53122 Stavros Sachtouris
            "description": "Archlinux base install 2012.12.01"},
78 e2c53122 Stavros Sachtouris
        "location": "pithos://us3r-I6E-1d/images/archlinux.12.2012",
79 e2c53122 Stavros Sachtouris
        "container_format": "bare",
80 e2c53122 Stavros Sachtouris
        "owner": "user163@mail.example.com",
81 e2c53122 Stavros Sachtouris
        "is_public": True,
82 e2c53122 Stavros Sachtouris
        "deleted_at": "",
83 e2c53122 Stavros Sachtouris
        "id": "b4713f20-3a41-4eaf-81ae-88698c18b3e8",
84 e2c53122 Stavros Sachtouris
        "size": 752782848},
85 e2c53122 Stavros Sachtouris
    {
86 e2c53122 Stavros Sachtouris
        "status": "available",
87 e2c53122 Stavros Sachtouris
        "name": "maelstrom",
88 e2c53122 Stavros Sachtouris
        "checksum": "b202b8c7030cb22f896c6664ac",
89 e2c53122 Stavros Sachtouris
        "created_at": "2013-02-13 10:07:42",
90 e2c53122 Stavros Sachtouris
        "disk_format": "diskdump",
91 e2c53122 Stavros Sachtouris
        "updated_at": "2013-02-13 10:07:44",
92 e2c53122 Stavros Sachtouris
        "properties": {
93 e2c53122 Stavros Sachtouris
            "partition_table": "msdos",
94 e2c53122 Stavros Sachtouris
            "osfamily": "linux",
95 e2c53122 Stavros Sachtouris
            "description": "Ubuntu 12.04.1 LTS",
96 e2c53122 Stavros Sachtouris
            "os": "ubuntu",
97 e2c53122 Stavros Sachtouris
            "root_partition": "1",
98 e2c53122 Stavros Sachtouris
            "users": "user"},
99 e2c53122 Stavros Sachtouris
        "location": "pithos://us3r-@r3n@-1d/images/mls-201302131203.diskdump",
100 e2c53122 Stavros Sachtouris
        "container_format": "bare",
101 e2c53122 Stavros Sachtouris
        "owner": "user3@mail.example.com",
102 e2c53122 Stavros Sachtouris
        "is_public": True,
103 e2c53122 Stavros Sachtouris
        "deleted_at": "",
104 e2c53122 Stavros Sachtouris
        "id": "0fb03e45-7d5a-4515-bd4e-e6bbf6457f06",
105 e2c53122 Stavros Sachtouris
        "size": 2583195648},
106 e2c53122 Stavros Sachtouris
    {
107 e2c53122 Stavros Sachtouris
        "status": "available",
108 e2c53122 Stavros Sachtouris
        "name": "Gardenia",
109 e2c53122 Stavros Sachtouris
        "checksum": "06d3099815d1f6fada91e80107638b882",
110 e2c53122 Stavros Sachtouris
        "created_at": "2013-02-13 12:35:21",
111 e2c53122 Stavros Sachtouris
        "disk_format": "diskdump",
112 e2c53122 Stavros Sachtouris
        "updated_at": "2013-02-13 12:35:23",
113 e2c53122 Stavros Sachtouris
        "properties": {
114 e2c53122 Stavros Sachtouris
            "partition_table": "msdos",
115 e2c53122 Stavros Sachtouris
            "osfamily": "linux",
116 e2c53122 Stavros Sachtouris
            "description": "Ubuntu 12.04.2 LTS",
117 e2c53122 Stavros Sachtouris
            "os": "ubuntu",
118 e2c53122 Stavros Sachtouris
            "root_partition": "1",
119 e2c53122 Stavros Sachtouris
            "users": "user"},
120 e2c53122 Stavros Sachtouris
        "location": "pithos://us3r-E-1d/images/Gardenia-201302131431.diskdump",
121 e2c53122 Stavros Sachtouris
        "container_format": "bare",
122 e2c53122 Stavros Sachtouris
        "owner": "user3@mail.example.com",
123 e2c53122 Stavros Sachtouris
        "is_public": True,
124 e2c53122 Stavros Sachtouris
        "deleted_at": "",
125 e2c53122 Stavros Sachtouris
        "id": "5963020b-ab74-4e11-bc59-90c494bbdedb",
126 e2c53122 Stavros Sachtouris
        "size": 2589802496}]
127 e2c53122 Stavros Sachtouris
128 fe5173b9 Stavros Sachtouris
129 d86c3c7d Stavros Sachtouris
class Image(TestCase):
130 d86c3c7d Stavros Sachtouris
131 03493855 Stavros Sachtouris
    def assert_dicts_are_deeply_equal(self, d1, d2):
132 03493855 Stavros Sachtouris
        for k, v in d1.items():
133 03493855 Stavros Sachtouris
            self.assertTrue(k in d2)
134 03493855 Stavros Sachtouris
            if isinstance(v, dict):
135 03493855 Stavros Sachtouris
                self.assert_dicts_are_deeply_equal(v, d2[k])
136 03493855 Stavros Sachtouris
            else:
137 03493855 Stavros Sachtouris
                self.assertEqual(unicode(v), unicode(d2[k]))
138 03493855 Stavros Sachtouris
139 d86c3c7d Stavros Sachtouris
    class FR(object):
140 d86c3c7d Stavros Sachtouris
        json = example_images
141 d86c3c7d Stavros Sachtouris
        headers = {}
142 d86c3c7d Stavros Sachtouris
        content = json
143 d86c3c7d Stavros Sachtouris
        status = None
144 d86c3c7d Stavros Sachtouris
        status_code = 200
145 c1004a00 Stavros Sachtouris
146 fe5173b9 Stavros Sachtouris
        def release(self):
147 fe5173b9 Stavros Sachtouris
            pass
148 fe5173b9 Stavros Sachtouris
149 c1004a00 Stavros Sachtouris
    def setUp(self):
150 d86c3c7d Stavros Sachtouris
        self.url = 'http://image.example.com'
151 d86c3c7d Stavros Sachtouris
        self.token = 'an1m@g370k3n=='
152 d86c3c7d Stavros Sachtouris
        from kamaki.clients.image import ImageClient
153 d86c3c7d Stavros Sachtouris
        self.client = ImageClient(self.url, self.token)
154 d86c3c7d Stavros Sachtouris
        from kamaki.clients.connection.kamakicon import KamakiHTTPConnection
155 d86c3c7d Stavros Sachtouris
        self.C = KamakiHTTPConnection
156 c1004a00 Stavros Sachtouris
157 c1004a00 Stavros Sachtouris
    def tearDown(self):
158 d86c3c7d Stavros Sachtouris
        self.FR.json = example_images
159 03314970 Stavros Sachtouris
        self.FR.status_code = 200
160 c1004a00 Stavros Sachtouris
161 c1004a00 Stavros Sachtouris
    def test_list_public(self):
162 d86c3c7d Stavros Sachtouris
        with patch.object(
163 d86c3c7d Stavros Sachtouris
            self.C,
164 d86c3c7d Stavros Sachtouris
            'perform_request',
165 d86c3c7d Stavros Sachtouris
            return_value=self.FR()) as perform_req:
166 d86c3c7d Stavros Sachtouris
            r = self.client.list_public()
167 d86c3c7d Stavros Sachtouris
            self.assertEqual(self.client.http_client.url, self.url)
168 d86c3c7d Stavros Sachtouris
            self.assertEqual(self.client.http_client.path, '/images/')
169 d86c3c7d Stavros Sachtouris
            params = perform_req.call_args[0][3]
170 d86c3c7d Stavros Sachtouris
            self.assertEqual(params['sort_dir'], 'asc')
171 d86c3c7d Stavros Sachtouris
            for i in range(len(r)):
172 d86c3c7d Stavros Sachtouris
                self.assert_dicts_are_deeply_equal(r[i], example_images[i])
173 d86c3c7d Stavros Sachtouris
174 d86c3c7d Stavros Sachtouris
            r = self.client.list_public(order='-')
175 d86c3c7d Stavros Sachtouris
            params = perform_req.call_args[0][3]
176 d86c3c7d Stavros Sachtouris
            self.assertEqual(params['sort_dir'], 'desc')
177 d86c3c7d Stavros Sachtouris
            self.assertEqual(self.client.http_client.url, self.url)
178 d86c3c7d Stavros Sachtouris
            self.assertEqual(self.client.http_client.path, '/images/')
179 d86c3c7d Stavros Sachtouris
180 e2c53122 Stavros Sachtouris
            self.FR.json = example_images_detailed
181 d86c3c7d Stavros Sachtouris
            r = self.client.list_public(detail=True)
182 d86c3c7d Stavros Sachtouris
            self.assertEqual(self.client.http_client.url, self.url)
183 d86c3c7d Stavros Sachtouris
            self.assertEqual(self.client.http_client.path, '/images/detail')
184 e2c53122 Stavros Sachtouris
            for i in range(len(r)):
185 e2c53122 Stavros Sachtouris
                self.assert_dicts_are_deeply_equal(
186 e2c53122 Stavros Sachtouris
                    r[i],
187 e2c53122 Stavros Sachtouris
                    example_images_detailed[i])
188 d86c3c7d Stavros Sachtouris
189 d86c3c7d Stavros Sachtouris
            size_max = 1000000000
190 d86c3c7d Stavros Sachtouris
            r = self.client.list_public(filters=dict(size_max=size_max))
191 d86c3c7d Stavros Sachtouris
            params = perform_req.call_args[0][3]
192 d86c3c7d Stavros Sachtouris
            self.assertEqual(params['size_max'], size_max)
193 d86c3c7d Stavros Sachtouris
            self.assertEqual(self.client.http_client.url, self.url)
194 d86c3c7d Stavros Sachtouris
            self.assertEqual(self.client.http_client.path, '/images/')
195 d86c3c7d Stavros Sachtouris
196 c1004a00 Stavros Sachtouris
    def test_get_meta(self):
197 e2c53122 Stavros Sachtouris
        img0 = example_images[0]
198 e2c53122 Stavros Sachtouris
        self.FR.json = img0
199 e2c53122 Stavros Sachtouris
        img0_headers = {}
200 e2c53122 Stavros Sachtouris
        for k, v in example_images_detailed[0].items():
201 e2c53122 Stavros Sachtouris
            img0_headers['x-image-meta-%s' % k] = v
202 e2c53122 Stavros Sachtouris
        self.FR.headers = img0_headers
203 e2c53122 Stavros Sachtouris
        with patch.object(self.C, 'perform_request', return_value=self.FR()):
204 e2c53122 Stavros Sachtouris
            r = self.client.get_meta(img0['id'])
205 e2c53122 Stavros Sachtouris
            self.assertEqual(self.client.http_client.url, self.url)
206 e2c53122 Stavros Sachtouris
            expected_path = '/images/%s' % img0['id']
207 e2c53122 Stavros Sachtouris
            self.assertEqual(self.client.http_client.path, expected_path)
208 c1004a00 Stavros Sachtouris
209 e2c53122 Stavros Sachtouris
            self.assertEqual(r['id'], img0['id'])
210 e2c53122 Stavros Sachtouris
            self.assert_dicts_are_deeply_equal(r, example_images_detailed[0])
211 e2c53122 Stavros Sachtouris
212 c1004a00 Stavros Sachtouris
    def test_register(self):
213 fe5173b9 Stavros Sachtouris
        img0 = example_images_detailed[0]
214 fe5173b9 Stavros Sachtouris
        img0_location = img0['location']
215 fe5173b9 Stavros Sachtouris
        img0_name = 'A new img0 name'
216 fe5173b9 Stavros Sachtouris
        with patch.object(
217 fe5173b9 Stavros Sachtouris
                self.C,
218 fe5173b9 Stavros Sachtouris
                'perform_request',
219 fe5173b9 Stavros Sachtouris
                return_value=self.FR()) as perform_req:
220 fe5173b9 Stavros Sachtouris
            self.client.register(img0_name, img0_location)
221 fe5173b9 Stavros Sachtouris
            self.assertEqual(self.client.http_client.url, self.url)
222 fe5173b9 Stavros Sachtouris
            self.assertEqual(self.client.http_client.path, '/images/')
223 fe5173b9 Stavros Sachtouris
            (method, data, headers, params) = perform_req.call_args[0]
224 fe5173b9 Stavros Sachtouris
            self.assertEqual(method, 'post')
225 fe5173b9 Stavros Sachtouris
            self.assertTrue(0 == len(params))
226 c1004a00 Stavros Sachtouris
227 fe5173b9 Stavros Sachtouris
            val = 'Some random value'
228 fe5173b9 Stavros Sachtouris
            param_dict = dict(
229 fe5173b9 Stavros Sachtouris
                id=val,
230 fe5173b9 Stavros Sachtouris
                store=val,
231 fe5173b9 Stavros Sachtouris
                disk_format=val,
232 fe5173b9 Stavros Sachtouris
                container_format=val,
233 fe5173b9 Stavros Sachtouris
                size=val,
234 fe5173b9 Stavros Sachtouris
                checksum=val,
235 fe5173b9 Stavros Sachtouris
                is_public=val,
236 fe5173b9 Stavros Sachtouris
                owner=val)
237 fe5173b9 Stavros Sachtouris
            for key in param_dict.keys():
238 fe5173b9 Stavros Sachtouris
                param = {key: val}
239 fe5173b9 Stavros Sachtouris
                self.client.register(img0_name, img0_location, params=param)
240 fe5173b9 Stavros Sachtouris
                (method, data, a_headers, a_params) = perform_req.call_args[0]
241 fe5173b9 Stavros Sachtouris
                key = 'x-image-meta-%s' % key.replace('_', '-')
242 fe5173b9 Stavros Sachtouris
                self.assertEqual(a_headers[key], val)
243 fe5173b9 Stavros Sachtouris
            self.client.register(img0_name, img0_location, params=param_dict)
244 fe5173b9 Stavros Sachtouris
            (method, data, a_headers, a_params) = perform_req.call_args[0]
245 fe5173b9 Stavros Sachtouris
            self.assertEqual(len(param_dict), len(a_headers))
246 fe5173b9 Stavros Sachtouris
            for key, val in param_dict.items():
247 fe5173b9 Stavros Sachtouris
                key = 'x-image-meta-%s' % key.replace('_', '-')
248 fe5173b9 Stavros Sachtouris
                self.assertEqual(a_headers[key], val)
249 c1004a00 Stavros Sachtouris
250 fe5173b9 Stavros Sachtouris
            props = dict(key0='val0', key2='val2', key3='val3')
251 fe5173b9 Stavros Sachtouris
            self.client.register(img0_name, img0_location, properties=props)
252 fe5173b9 Stavros Sachtouris
            (method, data, a_headers, a_params) = perform_req.call_args[0]
253 fe5173b9 Stavros Sachtouris
            for k, v in props.items():
254 fe5173b9 Stavros Sachtouris
                self.assertEquals(a_headers['X-Image-Meta-Property-%s' % k], v)
255 c1004a00 Stavros Sachtouris
256 c1004a00 Stavros Sachtouris
    def test_set_members(self):
257 03314970 Stavros Sachtouris
        img0 = example_images_detailed[0]
258 03314970 Stavros Sachtouris
        members = ['use3r-1d-0', 'us2r-1d-1', 'us3r-1d-2']
259 03314970 Stavros Sachtouris
        with patch.object(
260 03314970 Stavros Sachtouris
                self.C,
261 03314970 Stavros Sachtouris
                'perform_request',
262 03314970 Stavros Sachtouris
                return_value=self.FR()) as perform_req:
263 03314970 Stavros Sachtouris
            self.assertRaises(
264 03314970 Stavros Sachtouris
                ClientError,
265 03314970 Stavros Sachtouris
                self.client.set_members,
266 03314970 Stavros Sachtouris
                img0['id'], members)
267 03314970 Stavros Sachtouris
            self.FR.status_code = 204
268 03314970 Stavros Sachtouris
            self.client.set_members(img0['id'], members)
269 04f0c625 Stavros Sachtouris
            self.assertEqual(self.client.http_client.url, self.url)
270 04f0c625 Stavros Sachtouris
            self.assertEqual(
271 04f0c625 Stavros Sachtouris
                    self.client.http_client.path,
272 04f0c625 Stavros Sachtouris
                '/images/%s/members' % img0['id'])
273 03314970 Stavros Sachtouris
            (method, data, a_headers, a_params) = perform_req.call_args[0]
274 03314970 Stavros Sachtouris
            from json import loads
275 03314970 Stavros Sachtouris
            memberships = loads(data)['memberships']
276 03314970 Stavros Sachtouris
            for membership in memberships:
277 03314970 Stavros Sachtouris
                self.assertTrue(membership['member_id'] in members)
278 c1004a00 Stavros Sachtouris
279 c1004a00 Stavros Sachtouris
    def test_list_members(self):
280 d01f7d92 Stavros Sachtouris
        img0 = example_images_detailed[0]
281 d01f7d92 Stavros Sachtouris
        members = ['use3r-1d-0', 'us2r-1d-1', 'us3r-1d-2']
282 d01f7d92 Stavros Sachtouris
        self.FR.json = dict(members=members)
283 d01f7d92 Stavros Sachtouris
        with patch.object(self.C, 'perform_request', return_value=self.FR()):
284 d01f7d92 Stavros Sachtouris
            r = self.client.list_members(img0['id'])
285 04f0c625 Stavros Sachtouris
            self.assertEqual(self.client.http_client.url, self.url)
286 04f0c625 Stavros Sachtouris
            self.assertEqual(
287 04f0c625 Stavros Sachtouris
                self.client.http_client.path,
288 04f0c625 Stavros Sachtouris
                '/images/%s/members' % img0['id'])
289 d01f7d92 Stavros Sachtouris
            self.assertEqual(r, members)
290 c1004a00 Stavros Sachtouris
291 04f0c625 Stavros Sachtouris
    def test_add_member(self):
292 04f0c625 Stavros Sachtouris
        img0 = example_images_detailed[0]
293 04f0c625 Stavros Sachtouris
        new_member = 'us3r-15-n3w'
294 04f0c625 Stavros Sachtouris
        with patch.object(self.C, 'perform_request', return_value=self.FR()):
295 04f0c625 Stavros Sachtouris
            self.assertRaises(
296 04f0c625 Stavros Sachtouris
                ClientError,
297 e09db3c4 Stavros Sachtouris
                self.client.add_member,
298 04f0c625 Stavros Sachtouris
                img0['id'], new_member)
299 04f0c625 Stavros Sachtouris
            self.FR.status_code = 204
300 04f0c625 Stavros Sachtouris
            self.client.add_member(img0['id'], new_member)
301 04f0c625 Stavros Sachtouris
            self.assertEqual(self.client.http_client.url, self.url)
302 04f0c625 Stavros Sachtouris
            self.assertEqual(
303 04f0c625 Stavros Sachtouris
                self.client.http_client.path,
304 04f0c625 Stavros Sachtouris
                '/images/%s/members/%s' % (img0['id'], new_member))
305 04f0c625 Stavros Sachtouris
306 e09db3c4 Stavros Sachtouris
    def test_remove_member(self):
307 e09db3c4 Stavros Sachtouris
        img0 = example_images_detailed[0]
308 e09db3c4 Stavros Sachtouris
        old_member = 'us3r-15-0ld'
309 e09db3c4 Stavros Sachtouris
        with patch.object(self.C, 'perform_request', return_value=self.FR()):
310 e09db3c4 Stavros Sachtouris
            self.assertRaises(
311 e09db3c4 Stavros Sachtouris
                ClientError,
312 e09db3c4 Stavros Sachtouris
                self.client.remove_member,
313 e09db3c4 Stavros Sachtouris
                img0['id'], old_member)
314 e09db3c4 Stavros Sachtouris
            self.FR.status_code = 204
315 e09db3c4 Stavros Sachtouris
            self.client.remove_member(img0['id'], old_member)
316 e09db3c4 Stavros Sachtouris
            self.assertEqual(self.client.http_client.url, self.url)
317 e09db3c4 Stavros Sachtouris
            self.assertEqual(
318 e09db3c4 Stavros Sachtouris
                self.client.http_client.path,
319 e09db3c4 Stavros Sachtouris
                '/images/%s/members/%s' % (img0['id'], old_member))
320 c1004a00 Stavros Sachtouris
321 c1004a00 Stavros Sachtouris
    def test_list_shared(self):
322 785b478b Stavros Sachtouris
        img0 = example_images_detailed[0]
323 785b478b Stavros Sachtouris
        self.FR.json = dict(shared_images=example_images)
324 785b478b Stavros Sachtouris
        with patch.object(self.C, 'perform_request', return_value=self.FR()):
325 785b478b Stavros Sachtouris
            r = self.client.list_shared(img0['id'])
326 785b478b Stavros Sachtouris
            self.assertEqual(self.client.http_client.url, self.url)
327 785b478b Stavros Sachtouris
            self.assertEqual(
328 785b478b Stavros Sachtouris
                self.client.http_client.path,
329 785b478b Stavros Sachtouris
                '/shared-images/%s' % img0['id'])
330 785b478b Stavros Sachtouris
            for i in range(len(r)):
331 785b478b Stavros Sachtouris
                self.assert_dicts_are_deeply_equal(r[i], example_images[i])