Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / api / tests.py @ b66e4833

History | View | Annotate | Download (43.8 kB)

1 47eeffa9 Christos Stavrakakis
# Copyright 2012 GRNET S.A. All rights reserved.
2 c25cc9ec Vangelis Koukis
#
3 adee02b8 Giorgos Verigakis
# Redistribution and use in source and binary forms, with or
4 adee02b8 Giorgos Verigakis
# without modification, are permitted provided that the following
5 adee02b8 Giorgos Verigakis
# conditions are met:
6 c25cc9ec Vangelis Koukis
#
7 adee02b8 Giorgos Verigakis
#   1. Redistributions of source code must retain the above
8 adee02b8 Giorgos Verigakis
#      copyright notice, this list of conditions and the following
9 adee02b8 Giorgos Verigakis
#      disclaimer.
10 c25cc9ec Vangelis Koukis
#
11 adee02b8 Giorgos Verigakis
#   2. Redistributions in binary form must reproduce the above
12 adee02b8 Giorgos Verigakis
#      copyright notice, this list of conditions and the following
13 adee02b8 Giorgos Verigakis
#      disclaimer in the documentation and/or other materials
14 adee02b8 Giorgos Verigakis
#      provided with the distribution.
15 c25cc9ec Vangelis Koukis
#
16 adee02b8 Giorgos Verigakis
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 adee02b8 Giorgos Verigakis
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 adee02b8 Giorgos Verigakis
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 adee02b8 Giorgos Verigakis
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 adee02b8 Giorgos Verigakis
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 adee02b8 Giorgos Verigakis
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 adee02b8 Giorgos Verigakis
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 adee02b8 Giorgos Verigakis
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 adee02b8 Giorgos Verigakis
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 adee02b8 Giorgos Verigakis
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 adee02b8 Giorgos Verigakis
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 adee02b8 Giorgos Verigakis
# POSSIBILITY OF SUCH DAMAGE.
28 c25cc9ec Vangelis Koukis
#
29 adee02b8 Giorgos Verigakis
# The views and conclusions contained in the software and
30 adee02b8 Giorgos Verigakis
# documentation are those of the authors and should not be
31 adee02b8 Giorgos Verigakis
# interpreted as representing official policies, either expressed
32 adee02b8 Giorgos Verigakis
# or implied, of GRNET S.A.
33 894f6b7e Dimitris Moraitis
34 53b1eea6 Giorgos Verigakis
from __future__ import with_statement
35 53b1eea6 Giorgos Verigakis
36 a237869d Faidon Liambotis
from django.utils import simplejson as json
37 894f6b7e Dimitris Moraitis
from django.test import TestCase
38 40777cc8 Giorgos Verigakis
39 47eeffa9 Christos Stavrakakis
from mock import patch, Mock
40 08b079e2 Stavros Sachtouris
from contextlib import contextmanager
41 52194c77 Christos Stavrakakis
from functools import wraps
42 52194c77 Christos Stavrakakis
43 52194c77 Christos Stavrakakis
from synnefo.db.models import *
44 47eeffa9 Christos Stavrakakis
from synnefo.db import models_factory as mfactory
45 52194c77 Christos Stavrakakis
from synnefo.logic.utils import get_rsapi_state
46 47eeffa9 Christos Stavrakakis
47 47eeffa9 Christos Stavrakakis
from synnefo.api import faults
48 47eeffa9 Christos Stavrakakis
49 47eeffa9 Christos Stavrakakis
50 08b079e2 Stavros Sachtouris
@contextmanager
51 08b079e2 Stavros Sachtouris
def astakos_user(user):
52 08b079e2 Stavros Sachtouris
    """
53 08b079e2 Stavros Sachtouris
    Context manager to mock astakos response.
54 08b079e2 Stavros Sachtouris

55 08b079e2 Stavros Sachtouris
    usage:
56 08b079e2 Stavros Sachtouris
    with astakos_user("user@user.com"):
57 47eeffa9 Christos Stavrakakis
        .... make api calls ....
58 08b079e2 Stavros Sachtouris

59 08b079e2 Stavros Sachtouris
    """
60 08b079e2 Stavros Sachtouris
    def dummy_get_user(request, *args, **kwargs):
61 47eeffa9 Christos Stavrakakis
        request.user = {'username': user, 'groups': []}
62 47eeffa9 Christos Stavrakakis
        request.user_uniq = user
63 ce55f211 Kostas Papadimitriou
64 52194c77 Christos Stavrakakis
    with patch('synnefo.api.util.get_user') as m:
65 52194c77 Christos Stavrakakis
        m.side_effect = dummy_get_user
66 52194c77 Christos Stavrakakis
        yield
67 54c30633 Markos Gogoulos
68 668c1361 Markos Gogoulos
69 52194c77 Christos Stavrakakis
class BaseAPITest(TestCase):
70 52194c77 Christos Stavrakakis
    def get(self, url, user='user', *args, **kwargs):
71 47eeffa9 Christos Stavrakakis
        with astakos_user(user):
72 52194c77 Christos Stavrakakis
            response = self.client.get(url, *args, **kwargs)
73 47eeffa9 Christos Stavrakakis
        return response
74 47eeffa9 Christos Stavrakakis
75 47eeffa9 Christos Stavrakakis
    def delete(self, url, user='user'):
76 47eeffa9 Christos Stavrakakis
        with astakos_user(user):
77 47eeffa9 Christos Stavrakakis
            response = self.client.delete(url)
78 47eeffa9 Christos Stavrakakis
        return response
79 47eeffa9 Christos Stavrakakis
80 52194c77 Christos Stavrakakis
    def post(self, url, user='user', params={}, ctype='json', *args, **kwargs):
81 47eeffa9 Christos Stavrakakis
        if ctype == 'json':
82 47eeffa9 Christos Stavrakakis
            content_type = 'application/json'
83 47eeffa9 Christos Stavrakakis
        with astakos_user(user):
84 52194c77 Christos Stavrakakis
            response = self.client.post(url, params, content_type=content_type,
85 52194c77 Christos Stavrakakis
                                        *args, **kwargs)
86 47eeffa9 Christos Stavrakakis
        return response
87 47eeffa9 Christos Stavrakakis
88 52194c77 Christos Stavrakakis
    def put(self, url, user='user', params={}, ctype='json', *args, **kwargs):
89 47eeffa9 Christos Stavrakakis
        if ctype == 'json':
90 47eeffa9 Christos Stavrakakis
            content_type = 'application/json'
91 47eeffa9 Christos Stavrakakis
        with astakos_user(user):
92 52194c77 Christos Stavrakakis
            response = self.client.put(url, params, content_type=content_type,
93 52194c77 Christos Stavrakakis
                    *args, **kwargs)
94 47eeffa9 Christos Stavrakakis
        return response
95 47eeffa9 Christos Stavrakakis
96 47eeffa9 Christos Stavrakakis
    def assertSuccess(self, response):
97 52194c77 Christos Stavrakakis
        self.assertTrue(response.status_code in [200, 203, 204])
98 685ab2b6 Markos Gogoulos
99 47eeffa9 Christos Stavrakakis
    def assertFault(self, response, status_code, name):
100 47eeffa9 Christos Stavrakakis
        self.assertEqual(response.status_code, status_code)
101 47eeffa9 Christos Stavrakakis
        fault = json.loads(response.content)
102 47eeffa9 Christos Stavrakakis
        self.assertEqual(fault.keys(), [name])
103 668c1361 Markos Gogoulos
104 47eeffa9 Christos Stavrakakis
    def assertBadRequest(self, response):
105 47eeffa9 Christos Stavrakakis
        self.assertFault(response, 400, 'badRequest')
106 aa197ee4 Vangelis Koukis
107 47eeffa9 Christos Stavrakakis
    def assertItemNotFound(self, response):
108 47eeffa9 Christos Stavrakakis
        self.assertFault(response, 404, 'itemNotFound')
109 668c1361 Markos Gogoulos
110 aa197ee4 Vangelis Koukis
111 52194c77 Christos Stavrakakis
class FlavorAPITest(BaseAPITest):
112 668c1361 Markos Gogoulos
113 47eeffa9 Christos Stavrakakis
    def setUp(self):
114 47eeffa9 Christos Stavrakakis
        self.flavor1 = mfactory.FlavorFactory()
115 47eeffa9 Christos Stavrakakis
        self.flavor2 = mfactory.FlavorFactory(deleted=True)
116 47eeffa9 Christos Stavrakakis
        self.flavor3 = mfactory.FlavorFactory()
117 668c1361 Markos Gogoulos
118 e646ebe5 Dimitris Moraitis
    def test_flavor_list(self):
119 883de713 Giorgos Verigakis
        """Test if the expected list of flavors is returned by."""
120 47eeffa9 Christos Stavrakakis
        response = self.get('/api/v1.1/flavors')
121 52194c77 Christos Stavrakakis
        self.assertSuccess(response)
122 47eeffa9 Christos Stavrakakis
123 883de713 Giorgos Verigakis
        flavors_from_api = json.loads(response.content)['flavors']['values']
124 47eeffa9 Christos Stavrakakis
        flavors_from_db = Flavor.objects.filter(deleted=False)
125 668c1361 Markos Gogoulos
        self.assertEqual(len(flavors_from_api), len(flavors_from_db))
126 54c30633 Markos Gogoulos
        for flavor_from_api in flavors_from_api:
127 54c30633 Markos Gogoulos
            flavor_from_db = Flavor.objects.get(id=flavor_from_api['id'])
128 54c30633 Markos Gogoulos
            self.assertEqual(flavor_from_api['id'], flavor_from_db.id)
129 54c30633 Markos Gogoulos
            self.assertEqual(flavor_from_api['name'], flavor_from_db.name)
130 668c1361 Markos Gogoulos
131 e646ebe5 Dimitris Moraitis
    def test_flavors_details(self):
132 883de713 Giorgos Verigakis
        """Test if the flavors details are returned."""
133 47eeffa9 Christos Stavrakakis
        response = self.get('/api/v1.1/flavors/detail')
134 52194c77 Christos Stavrakakis
        self.assertSuccess(response)
135 aa197ee4 Vangelis Koukis
136 47eeffa9 Christos Stavrakakis
        flavors_from_db = Flavor.objects.filter(deleted=False)
137 883de713 Giorgos Verigakis
        flavors_from_api = json.loads(response.content)['flavors']['values']
138 e646ebe5 Dimitris Moraitis
139 f3af8b40 Dimitris Moraitis
        # Assert that all flavors in the db appear inthe API call result
140 f3af8b40 Dimitris Moraitis
        for i in range(0, len(flavors_from_db)):
141 f3af8b40 Dimitris Moraitis
            flavor_from_api = flavors_from_api[i]
142 f3af8b40 Dimitris Moraitis
            flavor_from_db = Flavor.objects.get(id=flavors_from_db[i].id)
143 685ab2b6 Markos Gogoulos
            self.assertEqual(flavor_from_api['cpu'], flavor_from_db.cpu)
144 685ab2b6 Markos Gogoulos
            self.assertEqual(flavor_from_api['id'], flavor_from_db.id)
145 685ab2b6 Markos Gogoulos
            self.assertEqual(flavor_from_api['disk'], flavor_from_db.disk)
146 685ab2b6 Markos Gogoulos
            self.assertEqual(flavor_from_api['name'], flavor_from_db.name)
147 685ab2b6 Markos Gogoulos
            self.assertEqual(flavor_from_api['ram'], flavor_from_db.ram)
148 f3af8b40 Dimitris Moraitis
149 e646ebe5 Dimitris Moraitis
        # Assert that all flavors returned by the API also exist in the db
150 54c30633 Markos Gogoulos
        for flavor_from_api in flavors_from_api:
151 54c30633 Markos Gogoulos
            flavor_from_db = Flavor.objects.get(id=flavor_from_api['id'])
152 54c30633 Markos Gogoulos
            self.assertEqual(flavor_from_api['cpu'], flavor_from_db.cpu)
153 54c30633 Markos Gogoulos
            self.assertEqual(flavor_from_api['id'], flavor_from_db.id)
154 54c30633 Markos Gogoulos
            self.assertEqual(flavor_from_api['disk'], flavor_from_db.disk)
155 54c30633 Markos Gogoulos
            self.assertEqual(flavor_from_api['name'], flavor_from_db.name)
156 54c30633 Markos Gogoulos
            self.assertEqual(flavor_from_api['ram'], flavor_from_db.ram)
157 7de0c985 Dimitris Moraitis
158 e646ebe5 Dimitris Moraitis
    def test_flavor_details(self):
159 883de713 Giorgos Verigakis
        """Test if the expected flavor is returned."""
160 47eeffa9 Christos Stavrakakis
        flavor = self.flavor3
161 47eeffa9 Christos Stavrakakis
162 47eeffa9 Christos Stavrakakis
        response = self.get('/api/v1.1/flavors/%d' % flavor.id)
163 52194c77 Christos Stavrakakis
        self.assertSuccess(response)
164 aa197ee4 Vangelis Koukis
165 668c1361 Markos Gogoulos
        flavor_from_api = json.loads(response.content)['flavor']
166 47eeffa9 Christos Stavrakakis
        flavor_from_db = Flavor.objects.get(id=flavor.id)
167 668c1361 Markos Gogoulos
        self.assertEqual(flavor_from_api['cpu'], flavor_from_db.cpu)
168 668c1361 Markos Gogoulos
        self.assertEqual(flavor_from_api['id'], flavor_from_db.id)
169 668c1361 Markos Gogoulos
        self.assertEqual(flavor_from_api['disk'], flavor_from_db.disk)
170 668c1361 Markos Gogoulos
        self.assertEqual(flavor_from_api['name'], flavor_from_db.name)
171 668c1361 Markos Gogoulos
        self.assertEqual(flavor_from_api['ram'], flavor_from_db.ram)
172 668c1361 Markos Gogoulos
173 47eeffa9 Christos Stavrakakis
    def test_deleted_flavor_details(self):
174 47eeffa9 Christos Stavrakakis
        """Test that API returns details for deleted flavors"""
175 47eeffa9 Christos Stavrakakis
        flavor = self.flavor2
176 47eeffa9 Christos Stavrakakis
        response = self.get('/api/v1.1/flavors/%d' % flavor.id)
177 52194c77 Christos Stavrakakis
        self.assertSuccess(response)
178 47eeffa9 Christos Stavrakakis
        flavor_from_api = json.loads(response.content)['flavor']
179 47eeffa9 Christos Stavrakakis
        self.assertEquals(flavor_from_api['name'], flavor.name)
180 47eeffa9 Christos Stavrakakis
181 47eeffa9 Christos Stavrakakis
    def test_deleted_flavors_list(self):
182 47eeffa9 Christos Stavrakakis
        """Test that deleted flavors do not appear to flavors list"""
183 47eeffa9 Christos Stavrakakis
        response = self.get('/api/v1.1/flavors')
184 52194c77 Christos Stavrakakis
        self.assertSuccess(response)
185 47eeffa9 Christos Stavrakakis
        flavors_from_api = json.loads(response.content)['flavors']['values']
186 47eeffa9 Christos Stavrakakis
        self.assertEqual(len(flavors_from_api), 2)
187 47eeffa9 Christos Stavrakakis
188 47eeffa9 Christos Stavrakakis
    def test_deleted_flavors_details(self):
189 47eeffa9 Christos Stavrakakis
        """Test that deleted flavors do not appear to flavors detail list"""
190 47eeffa9 Christos Stavrakakis
        mfactory.FlavorFactory(deleted=True)
191 47eeffa9 Christos Stavrakakis
        response = self.get('/api/v1.1/flavors/detail')
192 52194c77 Christos Stavrakakis
        self.assertSuccess(response)
193 47eeffa9 Christos Stavrakakis
        flavors_from_api = json.loads(response.content)['flavors']['values']
194 47eeffa9 Christos Stavrakakis
        self.assertEqual(len(flavors_from_api), 2)
195 47eeffa9 Christos Stavrakakis
196 e646ebe5 Dimitris Moraitis
    def test_wrong_flavor(self):
197 883de713 Giorgos Verigakis
        """Test 404 result when requesting a flavor that does not exist."""
198 aa197ee4 Vangelis Koukis
199 47eeffa9 Christos Stavrakakis
        response = self.get('/api/v1.1/flavors/%d' % 22)
200 52194c77 Christos Stavrakakis
        self.assertItemNotFound(response)
201 668c1361 Markos Gogoulos
202 aa197ee4 Vangelis Koukis
203 52194c77 Christos Stavrakakis
class ServerAPITest(BaseAPITest):
204 47eeffa9 Christos Stavrakakis
    def setUp(self):
205 47eeffa9 Christos Stavrakakis
        self.user1 = 'user1'
206 47eeffa9 Christos Stavrakakis
        self.user2 = 'user2'
207 47eeffa9 Christos Stavrakakis
        self.vm1 = mfactory.VirtualMachineFactory(userid=self.user1)
208 47eeffa9 Christos Stavrakakis
        self.vm2 = mfactory.VirtualMachineFactory(userid=self.user2)
209 47eeffa9 Christos Stavrakakis
        self.vm3 = mfactory.VirtualMachineFactory(deleted=True,
210 47eeffa9 Christos Stavrakakis
                                                  userid=self.user1)
211 47eeffa9 Christos Stavrakakis
        self.vm4 = mfactory.VirtualMachineFactory(userid=self.user2)
212 47eeffa9 Christos Stavrakakis
213 47eeffa9 Christos Stavrakakis
    def test_server_list_1(self):
214 47eeffa9 Christos Stavrakakis
        """Test if the expected list of servers is returned."""
215 47eeffa9 Christos Stavrakakis
        response = self.get('/api/v1.1/servers')
216 52194c77 Christos Stavrakakis
        self.assertSuccess(response)
217 47eeffa9 Christos Stavrakakis
        servers = json.loads(response.content)['servers']['values']
218 47eeffa9 Christos Stavrakakis
        self.assertEqual(servers, [])
219 668c1361 Markos Gogoulos
220 47eeffa9 Christos Stavrakakis
    def test_server_list_2(self):
221 47eeffa9 Christos Stavrakakis
        """Test if the expected list of servers is returned."""
222 47eeffa9 Christos Stavrakakis
        response = self.get('/api/v1.1/servers', self.user1)
223 52194c77 Christos Stavrakakis
        self.assertSuccess(response)
224 47eeffa9 Christos Stavrakakis
        servers = json.loads(response.content)['servers']['values']
225 47eeffa9 Christos Stavrakakis
        db_server = self.vm1
226 47eeffa9 Christos Stavrakakis
        self.assertEqual(servers, [{'name': db_server.name,
227 47eeffa9 Christos Stavrakakis
                                    'id': db_server.id}])
228 47eeffa9 Christos Stavrakakis
229 47eeffa9 Christos Stavrakakis
    def test_server_list_detail(self):
230 47eeffa9 Christos Stavrakakis
        """Test if the servers list details are returned."""
231 47eeffa9 Christos Stavrakakis
        user = self.user2
232 47eeffa9 Christos Stavrakakis
        user_vms = {self.vm2.id: self.vm2,
233 47eeffa9 Christos Stavrakakis
                    self.vm4.id: self.vm4}
234 47eeffa9 Christos Stavrakakis
235 47eeffa9 Christos Stavrakakis
        response = self.get('/api/v1.1/servers/detail', user)
236 47eeffa9 Christos Stavrakakis
        servers = json.loads(response.content)['servers']['values']
237 47eeffa9 Christos Stavrakakis
        self.assertEqual(len(servers), len(user_vms))
238 47eeffa9 Christos Stavrakakis
        for api_vm in servers:
239 47eeffa9 Christos Stavrakakis
            db_vm = user_vms[api_vm['id']]
240 47eeffa9 Christos Stavrakakis
            self.assertEqual(api_vm['flavorRef'], db_vm.flavor.id)
241 47eeffa9 Christos Stavrakakis
            self.assertEqual(api_vm['hostId'], db_vm.hostid)
242 47eeffa9 Christos Stavrakakis
            self.assertEqual(api_vm['id'], db_vm.id)
243 47eeffa9 Christos Stavrakakis
            self.assertEqual(api_vm['imageRef'], db_vm.imageid)
244 47eeffa9 Christos Stavrakakis
            self.assertEqual(api_vm['name'], db_vm.name)
245 47eeffa9 Christos Stavrakakis
            self.assertEqual(api_vm['status'], get_rsapi_state(db_vm))
246 52194c77 Christos Stavrakakis
            self.assertSuccess(response)
247 47eeffa9 Christos Stavrakakis
248 47eeffa9 Christos Stavrakakis
    def test_server_detail(self):
249 47eeffa9 Christos Stavrakakis
        """Test if a server details are returned."""
250 47eeffa9 Christos Stavrakakis
        db_vm = self.vm2
251 47eeffa9 Christos Stavrakakis
        user = self.vm2.userid
252 b66e4833 Christos Stavrakakis
        net = mfactory.NetworkFactory()
253 b66e4833 Christos Stavrakakis
        nic = mfactory.NetworkInterfaceFactory(machine=self.vm2, network=net)
254 b66e4833 Christos Stavrakakis
255 47eeffa9 Christos Stavrakakis
        db_vm_meta = mfactory.VirtualMachineMetadataFactory(vm=db_vm)
256 47eeffa9 Christos Stavrakakis
257 47eeffa9 Christos Stavrakakis
        response = self.get('/api/v1.1/servers/%d' % db_vm.id, user)
258 47eeffa9 Christos Stavrakakis
        server = json.loads(response.content)['server']
259 47eeffa9 Christos Stavrakakis
260 47eeffa9 Christos Stavrakakis
        self.assertEqual(server['flavorRef'], db_vm.flavor.id)
261 47eeffa9 Christos Stavrakakis
        self.assertEqual(server['hostId'], db_vm.hostid)
262 47eeffa9 Christos Stavrakakis
        self.assertEqual(server['id'], db_vm.id)
263 47eeffa9 Christos Stavrakakis
        self.assertEqual(server['imageRef'], db_vm.imageid)
264 47eeffa9 Christos Stavrakakis
        self.assertEqual(server['name'], db_vm.name)
265 47eeffa9 Christos Stavrakakis
        self.assertEqual(server['status'], get_rsapi_state(db_vm))
266 b66e4833 Christos Stavrakakis
        api_nic = server['attachments']['values'][0]
267 b66e4833 Christos Stavrakakis
        self.assertEqual(api_nic['network_id'], str(net.id))
268 b66e4833 Christos Stavrakakis
        self.assertEqual(api_nic['mac_address'], nic.mac)
269 b66e4833 Christos Stavrakakis
        self.assertEqual(api_nic['firewallProfile'], nic.firewall_profile)
270 b66e4833 Christos Stavrakakis
        self.assertEqual(api_nic['ipv4'], nic.ipv4)
271 b66e4833 Christos Stavrakakis
        self.assertEqual(api_nic['ipv6'], nic.ipv6)
272 b66e4833 Christos Stavrakakis
        self.assertEqual(api_nic['id'], 'nic-%s-%s' % (db_vm.id, nic.index))
273 47eeffa9 Christos Stavrakakis
274 47eeffa9 Christos Stavrakakis
        metadata = server['metadata']['values']
275 47eeffa9 Christos Stavrakakis
        self.assertEqual(len(metadata), 1)
276 47eeffa9 Christos Stavrakakis
        self.assertEqual(metadata[db_vm_meta.meta_key], db_vm_meta.meta_value)
277 52194c77 Christos Stavrakakis
        self.assertSuccess(response)
278 47eeffa9 Christos Stavrakakis
279 47eeffa9 Christos Stavrakakis
    def test_noauthorized(self):
280 47eeffa9 Christos Stavrakakis
        """Test 404 for detail of other user vm"""
281 47eeffa9 Christos Stavrakakis
        db_vm = self.vm2
282 aa197ee4 Vangelis Koukis
283 47eeffa9 Christos Stavrakakis
        response = self.get('/api/v1.1/servers/%d' % db_vm.id, 'wrong_user')
284 52194c77 Christos Stavrakakis
        self.assertItemNotFound(response)
285 73469364 Markos Gogoulos
286 47eeffa9 Christos Stavrakakis
    def test_wrong_server(self):
287 47eeffa9 Christos Stavrakakis
        """Test 404 response if server does not exist."""
288 47eeffa9 Christos Stavrakakis
        response = self.get('/api/v1.1/servers/%d' % 5000)
289 52194c77 Christos Stavrakakis
        self.assertItemNotFound(response)
290 aa197ee4 Vangelis Koukis
291 47eeffa9 Christos Stavrakakis
    def test_create_server_empty(self):
292 47eeffa9 Christos Stavrakakis
        """Test if the create server call returns a 400 badRequest if
293 47eeffa9 Christos Stavrakakis
           no attributes are specified."""
294 aa197ee4 Vangelis Koukis
295 47eeffa9 Christos Stavrakakis
        response = self.post('/api/v1.1/servers', params={})
296 52194c77 Christos Stavrakakis
        self.assertBadRequest(response)
297 a8acbbac Markos Gogoulos
298 b66e4833 Christos Stavrakakis
    def test_rename_server(self):
299 b66e4833 Christos Stavrakakis
        vm = self.vm2
300 b66e4833 Christos Stavrakakis
        request = {'server': {'name': 'new_name'}}
301 b66e4833 Christos Stavrakakis
        response = self.put('/api/v1.1/servers/%d' % vm.id, vm.userid,
302 b66e4833 Christos Stavrakakis
                            json.dumps(request), 'json')
303 b66e4833 Christos Stavrakakis
        self.assertSuccess(response)
304 b66e4833 Christos Stavrakakis
        self.assertEqual(VirtualMachine.objects.get(id=vm.id).name, "new_name")
305 b66e4833 Christos Stavrakakis
306 a8acbbac Markos Gogoulos
307 47eeffa9 Christos Stavrakakis
@patch('synnefo.api.util.get_image')
308 47eeffa9 Christos Stavrakakis
@patch('synnefo.logic.rapi_pool.GanetiRapiClient')
309 52194c77 Christos Stavrakakis
class ServerCreateAPITest(BaseAPITest):
310 47eeffa9 Christos Stavrakakis
    def test_create_server(self, mrapi, mimage):
311 47eeffa9 Christos Stavrakakis
        """Test if the create server call returns the expected response
312 47eeffa9 Christos Stavrakakis
           if a valid request has been speficied."""
313 47eeffa9 Christos Stavrakakis
        mimage.return_value = {'location': 'pithos://foo',
314 47eeffa9 Christos Stavrakakis
                               'disk_format': 'diskdump'}
315 47eeffa9 Christos Stavrakakis
        mrapi().CreateInstance.return_value = 12
316 47eeffa9 Christos Stavrakakis
        flavor = mfactory.FlavorFactory()
317 47eeffa9 Christos Stavrakakis
        # Create public network and backend
318 47eeffa9 Christos Stavrakakis
        network = mfactory.NetworkFactory(public=True)
319 47eeffa9 Christos Stavrakakis
        backend = mfactory.BackendFactory()
320 47eeffa9 Christos Stavrakakis
        mfactory.BackendNetworkFactory(network=network, backend=backend)
321 968b3e04 Giorgos Verigakis
322 47eeffa9 Christos Stavrakakis
        request = {
323 47eeffa9 Christos Stavrakakis
                    "server": {
324 47eeffa9 Christos Stavrakakis
                        "name": "new-server-test",
325 47eeffa9 Christos Stavrakakis
                        "userid": "test_user",
326 47eeffa9 Christos Stavrakakis
                        "imageRef": 1,
327 47eeffa9 Christos Stavrakakis
                        "flavorRef": flavor.id,
328 47eeffa9 Christos Stavrakakis
                        "metadata": {
329 47eeffa9 Christos Stavrakakis
                            "My Server Name": "Apache1"
330 47eeffa9 Christos Stavrakakis
                        },
331 47eeffa9 Christos Stavrakakis
                        "personality": []
332 47eeffa9 Christos Stavrakakis
                    }
333 47eeffa9 Christos Stavrakakis
        }
334 47eeffa9 Christos Stavrakakis
        response = self.post('/api/v1.1/servers', 'test_user',
335 47eeffa9 Christos Stavrakakis
                                 json.dumps(request), 'json')
336 47eeffa9 Christos Stavrakakis
        self.assertEqual(response.status_code, 202)
337 47eeffa9 Christos Stavrakakis
        mrapi().CreateInstance.assert_called_once()
338 c25cc9ec Vangelis Koukis
339 47eeffa9 Christos Stavrakakis
        api_server = json.loads(response.content)['server']
340 47eeffa9 Christos Stavrakakis
        self.assertEqual(api_server['status'], "BUILD")
341 47eeffa9 Christos Stavrakakis
        self.assertEqual(api_server['progress'], 0)
342 47eeffa9 Christos Stavrakakis
        self.assertEqual(api_server['metadata']['values'],
343 47eeffa9 Christos Stavrakakis
                        {"My Server Name":  "Apache1"})
344 47eeffa9 Christos Stavrakakis
        self.assertTrue('adminPass' in api_server)
345 968b3e04 Giorgos Verigakis
346 47eeffa9 Christos Stavrakakis
        db_vm = VirtualMachine.objects.get(userid='test_user')
347 47eeffa9 Christos Stavrakakis
        self.assertEqual(api_server['name'], db_vm.name)
348 47eeffa9 Christos Stavrakakis
        self.assertEqual(api_server['status'], db_vm.operstate)
349 c25cc9ec Vangelis Koukis
350 47eeffa9 Christos Stavrakakis
    def test_create_server_no_flavor(self, mrapi, mimage):
351 47eeffa9 Christos Stavrakakis
        request = {
352 47eeffa9 Christos Stavrakakis
                    "server": {
353 47eeffa9 Christos Stavrakakis
                        "name": "new-server-test",
354 47eeffa9 Christos Stavrakakis
                        "userid": "test_user",
355 47eeffa9 Christos Stavrakakis
                        "imageRef": 1,
356 47eeffa9 Christos Stavrakakis
                        "flavorRef": 42,
357 47eeffa9 Christos Stavrakakis
                        "metadata": {
358 47eeffa9 Christos Stavrakakis
                            "My Server Name": "Apache1"
359 47eeffa9 Christos Stavrakakis
                        },
360 47eeffa9 Christos Stavrakakis
                        "personality": []
361 47eeffa9 Christos Stavrakakis
                    }
362 47eeffa9 Christos Stavrakakis
        }
363 47eeffa9 Christos Stavrakakis
        response = self.post('/api/v1.1/servers', 'test_user',
364 47eeffa9 Christos Stavrakakis
                                 json.dumps(request), 'json')
365 47eeffa9 Christos Stavrakakis
        self.assertItemNotFound(response)
366 c25cc9ec Vangelis Koukis
367 53b1eea6 Giorgos Verigakis
368 47eeffa9 Christos Stavrakakis
@patch('synnefo.logic.rapi_pool.GanetiRapiClient')
369 52194c77 Christos Stavrakakis
class ServerDestroyAPITest(BaseAPITest):
370 47eeffa9 Christos Stavrakakis
    def test_delete_server(self, mrapi):
371 47eeffa9 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
372 47eeffa9 Christos Stavrakakis
        response = self.delete('/api/v1.1/servers/%d' % vm.id, vm.userid)
373 47eeffa9 Christos Stavrakakis
        self.assertEqual(response.status_code, 204)
374 47eeffa9 Christos Stavrakakis
        mrapi().DeleteInstance.assert_called_once()
375 47eeffa9 Christos Stavrakakis
376 47eeffa9 Christos Stavrakakis
    def test_non_existing_delete_server(self, mrapi):
377 47eeffa9 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
378 47eeffa9 Christos Stavrakakis
        response = self.delete('/api/v1.1/servers/%d' % 42, vm.userid)
379 47eeffa9 Christos Stavrakakis
        self.assertItemNotFound(response)
380 b66e4833 Christos Stavrakakis
        self.assertFalse(mrapi.mock_calls)
381 47eeffa9 Christos Stavrakakis
382 47eeffa9 Christos Stavrakakis
383 47eeffa9 Christos Stavrakakis
@patch('synnefo.api.util.get_image')
384 47eeffa9 Christos Stavrakakis
@patch('synnefo.logic.rapi_pool.GanetiRapiClient')
385 52194c77 Christos Stavrakakis
class ServerActionAPITest(BaseAPITest):
386 47eeffa9 Christos Stavrakakis
    def test_actions(self, mrapi, mimage):
387 47eeffa9 Christos Stavrakakis
        actions = ['start', 'shutdown', 'reboot']
388 47eeffa9 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
389 47eeffa9 Christos Stavrakakis
        vm.operstate = "STOPPED"
390 47eeffa9 Christos Stavrakakis
        vm.save()
391 47eeffa9 Christos Stavrakakis
        for action in actions:
392 47eeffa9 Christos Stavrakakis
            val = {'type': 'HARD'} if action == 'reboot' else {}
393 47eeffa9 Christos Stavrakakis
            request = {action: val}
394 47eeffa9 Christos Stavrakakis
            response = self.post('/api/v1.1/servers/%d/action' % vm.id,
395 47eeffa9 Christos Stavrakakis
                                vm.userid, json.dumps(request), 'json')
396 47eeffa9 Christos Stavrakakis
            self.assertEqual(response.status_code, 202)
397 47eeffa9 Christos Stavrakakis
            if action == 'shutdown':
398 47eeffa9 Christos Stavrakakis
                self.assertEqual(VirtualMachine.objects.get(id=vm.id).action,
399 47eeffa9 Christos Stavrakakis
                                 "STOP")
400 47eeffa9 Christos Stavrakakis
            else:
401 47eeffa9 Christos Stavrakakis
                self.assertEqual(VirtualMachine.objects.get(id=vm.id).action,
402 47eeffa9 Christos Stavrakakis
                                 action.upper())
403 47eeffa9 Christos Stavrakakis
404 b66e4833 Christos Stavrakakis
    def test_action_in_building_vm(self, mrapi, mimage):
405 b66e4833 Christos Stavrakakis
        """Test building in progress"""
406 b66e4833 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
407 b66e4833 Christos Stavrakakis
        request = {'start': '{}'}
408 b66e4833 Christos Stavrakakis
        response = self.post('/api/v1.1/servers/%d/action' % vm.id,
409 b66e4833 Christos Stavrakakis
                             vm.userid, json.dumps(request), 'json')
410 b66e4833 Christos Stavrakakis
        self.assertEqual(response.status_code, 409)
411 b66e4833 Christos Stavrakakis
        self.assertFalse(mrapi.mock_calls)
412 b66e4833 Christos Stavrakakis
413 b66e4833 Christos Stavrakakis
    def test_destroy_build_vm(self, mrapi, mimage):
414 b66e4833 Christos Stavrakakis
        """Test building in progress"""
415 b66e4833 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
416 b66e4833 Christos Stavrakakis
        response = self.delete('/api/v1.1/servers/%d' % vm.id,
417 b66e4833 Christos Stavrakakis
                             vm.userid)
418 b66e4833 Christos Stavrakakis
        self.assertSuccess(response)
419 b66e4833 Christos Stavrakakis
        mrapi().RemoveInstance.assert_called_once()
420 b66e4833 Christos Stavrakakis
421 47eeffa9 Christos Stavrakakis
    def test_firewall(self, mrapi, mimage):
422 47eeffa9 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
423 47eeffa9 Christos Stavrakakis
        vm.operstate = "STOPPED"
424 47eeffa9 Christos Stavrakakis
        vm.save()
425 47eeffa9 Christos Stavrakakis
        request = {'firewallProfile': {'profile': 'PROTECTED'}}
426 47eeffa9 Christos Stavrakakis
        response = self.post('/api/v1.1/servers/%d/action' % vm.id,
427 47eeffa9 Christos Stavrakakis
                             vm.userid, json.dumps(request), 'json')
428 47eeffa9 Christos Stavrakakis
        self.assertEqual(response.status_code, 202)
429 47eeffa9 Christos Stavrakakis
        mrapi().ModifyInstance.assert_called_once()
430 968b3e04 Giorgos Verigakis
431 b66e4833 Christos Stavrakakis
    def test_unsupported_firewall(self, mrapi, mimage):
432 b66e4833 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
433 b66e4833 Christos Stavrakakis
        vm.operstate = "STOPPED"
434 b66e4833 Christos Stavrakakis
        vm.save()
435 b66e4833 Christos Stavrakakis
        request = {'firewallProfile': {'profile': 'FOO'}}
436 b66e4833 Christos Stavrakakis
        response = self.post('/api/v1.1/servers/%d/action' % vm.id,
437 b66e4833 Christos Stavrakakis
                             vm.userid, json.dumps(request), 'json')
438 b66e4833 Christos Stavrakakis
        self.assertBadRequest(response)
439 b66e4833 Christos Stavrakakis
        self.assertFalse(mrapi.mock_calls)
440 b66e4833 Christos Stavrakakis
441 c25cc9ec Vangelis Koukis
442 52194c77 Christos Stavrakakis
class ServerMetadataAPITest(BaseAPITest):
443 47eeffa9 Christos Stavrakakis
    def setUp(self):
444 47eeffa9 Christos Stavrakakis
        self.vm = mfactory.VirtualMachineFactory()
445 47eeffa9 Christos Stavrakakis
        self.metadata = mfactory.VirtualMachineMetadataFactory(vm=self.vm)
446 47eeffa9 Christos Stavrakakis
447 47eeffa9 Christos Stavrakakis
    def test_get_metadata(self):
448 47eeffa9 Christos Stavrakakis
        vm = self.vm
449 47eeffa9 Christos Stavrakakis
        create_meta = lambda: mfactory.VirtualMachineMetadataFactory(vm=vm)
450 47eeffa9 Christos Stavrakakis
        metadata = [create_meta(), create_meta(), create_meta()]
451 47eeffa9 Christos Stavrakakis
        response = self.get('/api/v1.1/servers/%d/meta' % vm.id, vm.userid)
452 47eeffa9 Christos Stavrakakis
        self.assertTrue(response.status_code in [200, 203])
453 47eeffa9 Christos Stavrakakis
        api_metadata = json.loads(response.content)['metadata']['values']
454 47eeffa9 Christos Stavrakakis
        self.assertEqual(len(api_metadata), len(metadata) + 1)
455 47eeffa9 Christos Stavrakakis
        for db_m in metadata:
456 47eeffa9 Christos Stavrakakis
            self.assertEqual(api_metadata[db_m.meta_key], db_m.meta_value)
457 47eeffa9 Christos Stavrakakis
458 47eeffa9 Christos Stavrakakis
        request = {'metadata':
459 47eeffa9 Christos Stavrakakis
                        {'foo': 'bar'},
460 47eeffa9 Christos Stavrakakis
                        metadata[0].meta_key: 'bar2'
461 47eeffa9 Christos Stavrakakis
                  }
462 47eeffa9 Christos Stavrakakis
        response = self.post('/api/v1.1/servers/%d/meta' % vm.id, vm.userid,
463 47eeffa9 Christos Stavrakakis
                             json.dumps(request), 'json')
464 47eeffa9 Christos Stavrakakis
        metadata2 = VirtualMachineMetadata.objects.filter(vm=vm)
465 47eeffa9 Christos Stavrakakis
        response = self.get('/api/v1.1/servers/%d/meta' % vm.id, vm.userid)
466 47eeffa9 Christos Stavrakakis
        self.assertTrue(response.status_code in [200, 203])
467 47eeffa9 Christos Stavrakakis
        api_metadata2 = json.loads(response.content)['metadata']['values']
468 47eeffa9 Christos Stavrakakis
        self.assertTrue('foo' in api_metadata2.keys())
469 47eeffa9 Christos Stavrakakis
        self.assertTrue(api_metadata2[metadata[0].meta_key], 'bar2')
470 47eeffa9 Christos Stavrakakis
        self.assertEqual(len(api_metadata2), len(metadata2))
471 47eeffa9 Christos Stavrakakis
        for db_m in metadata2:
472 47eeffa9 Christos Stavrakakis
            self.assertEqual(api_metadata2[db_m.meta_key], db_m.meta_value)
473 47eeffa9 Christos Stavrakakis
474 47eeffa9 Christos Stavrakakis
        # Create new meta
475 47eeffa9 Christos Stavrakakis
        request = {'meta': {'foo2': 'bar2'}}
476 47eeffa9 Christos Stavrakakis
        response = self.put('/api/v1.1/servers/%d/meta/foo2' % vm.id,
477 47eeffa9 Christos Stavrakakis
                            vm.userid, json.dumps(request), 'json')
478 47eeffa9 Christos Stavrakakis
479 47eeffa9 Christos Stavrakakis
        # Get the new meta
480 47eeffa9 Christos Stavrakakis
        response = self.get('/api/v1.1/servers/%d/meta/foo2' % vm.id,
481 47eeffa9 Christos Stavrakakis
                            vm.userid)
482 47eeffa9 Christos Stavrakakis
        meta = json.loads(response.content)['meta']
483 47eeffa9 Christos Stavrakakis
        self.assertEqual(meta['foo2'], 'bar2')
484 47eeffa9 Christos Stavrakakis
485 47eeffa9 Christos Stavrakakis
        # Delete the new meta
486 47eeffa9 Christos Stavrakakis
        response = self.delete('/api/v1.1/servers/%d/meta/foo2' % vm.id,
487 47eeffa9 Christos Stavrakakis
                               vm.userid)
488 47eeffa9 Christos Stavrakakis
        self.assertEqual(response.status_code, 204)
489 968b3e04 Giorgos Verigakis
490 47eeffa9 Christos Stavrakakis
        # Try to get the deleted meta: should raise 404
491 47eeffa9 Christos Stavrakakis
        response = self.get('/api/v1.1/servers/%d/meta/foo2' % vm.id,
492 47eeffa9 Christos Stavrakakis
                            vm.userid)
493 47eeffa9 Christos Stavrakakis
        self.assertEqual(response.status_code, 404)
494 968b3e04 Giorgos Verigakis
495 47eeffa9 Christos Stavrakakis
    def test_invalid_metadata(self):
496 47eeffa9 Christos Stavrakakis
        vm = self.vm
497 47eeffa9 Christos Stavrakakis
        response = self.post('/api/v1.1/servers/%d/meta' % vm.id, vm.userid)
498 47eeffa9 Christos Stavrakakis
        self.assertBadRequest(response)
499 47eeffa9 Christos Stavrakakis
        self.assertEqual(len(vm.metadata.all()), 1)
500 aa197ee4 Vangelis Koukis
501 47eeffa9 Christos Stavrakakis
    def test_invalid_metadata_server(self):
502 47eeffa9 Christos Stavrakakis
        response = self.post('/api/v1.1/servers/42/meta', 'user')
503 47eeffa9 Christos Stavrakakis
        self.assertItemNotFound(response)
504 aa197ee4 Vangelis Koukis
505 47eeffa9 Christos Stavrakakis
    def test_get_meta_invalid_key(self):
506 47eeffa9 Christos Stavrakakis
        vm = self.vm
507 47eeffa9 Christos Stavrakakis
        response = self.get('/api/v1.1/servers/%d/meta/foo2' % vm.id,
508 47eeffa9 Christos Stavrakakis
                            vm.userid)
509 47eeffa9 Christos Stavrakakis
        self.assertItemNotFound(response)
510 53b1eea6 Giorgos Verigakis
511 53b1eea6 Giorgos Verigakis
512 47eeffa9 Christos Stavrakakis
@patch('synnefo.logic.rapi_pool.GanetiRapiClient')
513 52194c77 Christos Stavrakakis
class NetworkAPITest(BaseAPITest):
514 883de713 Giorgos Verigakis
    def setUp(self):
515 47eeffa9 Christos Stavrakakis
        self.mac_prefixes = mfactory.MacPrefixPoolTableFactory()
516 47eeffa9 Christos Stavrakakis
        self.bridges = mfactory.BridgePoolTableFactory()
517 47eeffa9 Christos Stavrakakis
        self.user = 'dummy-user'
518 47eeffa9 Christos Stavrakakis
        self.net1 = mfactory.NetworkFactory(userid=self.user)
519 47eeffa9 Christos Stavrakakis
        self.net2 = mfactory.NetworkFactory(userid=self.user)
520 47eeffa9 Christos Stavrakakis
521 47eeffa9 Christos Stavrakakis
    def assertNetworksEqual(self, db_net, api_net, detail=False):
522 47eeffa9 Christos Stavrakakis
        self.assertEqual(str(db_net.id), api_net["id"])
523 47eeffa9 Christos Stavrakakis
        self.assertEqual(db_net.name, api_net['name'])
524 111f6d5b Giorgos Verigakis
        if detail:
525 47eeffa9 Christos Stavrakakis
            self.assertEqual(db_net.state, api_net['status'])
526 47eeffa9 Christos Stavrakakis
            self.assertEqual(db_net.flavor, api_net['type'])
527 47eeffa9 Christos Stavrakakis
            self.assertEqual(db_net.subnet, api_net['cidr'])
528 47eeffa9 Christos Stavrakakis
            self.assertEqual(db_net.subnet6, api_net['cidr6'])
529 47eeffa9 Christos Stavrakakis
            self.assertEqual(db_net.gateway, api_net['gateway'])
530 47eeffa9 Christos Stavrakakis
            self.assertEqual(db_net.gateway6, api_net['gateway6'])
531 47eeffa9 Christos Stavrakakis
            self.assertEqual(db_net.dhcp, api_net['dhcp'])
532 47eeffa9 Christos Stavrakakis
533 47eeffa9 Christos Stavrakakis
    def test_create_network_1(self, mrapi):
534 47eeffa9 Christos Stavrakakis
        request = {
535 47eeffa9 Christos Stavrakakis
            'network': {'name': 'foo'}
536 47eeffa9 Christos Stavrakakis
            }
537 47eeffa9 Christos Stavrakakis
        response = self.post('/api/v1.1/networks/', 'user1',
538 47eeffa9 Christos Stavrakakis
                             json.dumps(request), 'json')
539 47eeffa9 Christos Stavrakakis
        self.assertEqual(response.status_code, 202)
540 47eeffa9 Christos Stavrakakis
        db_networks = Network.objects.filter(userid='user1')
541 47eeffa9 Christos Stavrakakis
        self.assertEqual(len(db_networks), 1)
542 47eeffa9 Christos Stavrakakis
        db_net = db_networks[0]
543 47eeffa9 Christos Stavrakakis
        api_net = json.loads(response.content)['network']
544 47eeffa9 Christos Stavrakakis
        self.assertNetworksEqual(db_net, api_net)
545 47eeffa9 Christos Stavrakakis
        mrapi.CreateNetwork.assert_called()
546 47eeffa9 Christos Stavrakakis
        mrapi.ConnectNetwork.assert_called()
547 47eeffa9 Christos Stavrakakis
548 47eeffa9 Christos Stavrakakis
    def test_invalid_data_1(self, mrapi):
549 47eeffa9 Christos Stavrakakis
        """Test invalid flavor"""
550 47eeffa9 Christos Stavrakakis
        request = {
551 47eeffa9 Christos Stavrakakis
            'network': {'name': 'foo', 'type': 'LoLo'}
552 47eeffa9 Christos Stavrakakis
            }
553 47eeffa9 Christos Stavrakakis
        response = self.post('/api/v1.1/networks/', 'user1',
554 47eeffa9 Christos Stavrakakis
                             json.dumps(request), 'json')
555 47eeffa9 Christos Stavrakakis
        self.assertBadRequest(response)
556 47eeffa9 Christos Stavrakakis
        self.assertEqual(len(Network.objects.filter(userid='user1')), 0)
557 aa197ee4 Vangelis Koukis
558 47eeffa9 Christos Stavrakakis
    def test_invalid_data_2(self, mrapi):
559 47eeffa9 Christos Stavrakakis
        """Test invalid subnet"""
560 47eeffa9 Christos Stavrakakis
        request = {
561 47eeffa9 Christos Stavrakakis
            'network': {'name': 'foo', 'cidr': '10.0.0.0/8'}
562 47eeffa9 Christos Stavrakakis
            }
563 47eeffa9 Christos Stavrakakis
        response = self.post('/api/v1.1/networks/', 'user1',
564 47eeffa9 Christos Stavrakakis
                             json.dumps(request), 'json')
565 47eeffa9 Christos Stavrakakis
        self.assertFault(response, 413, "overLimit")
566 47eeffa9 Christos Stavrakakis
567 47eeffa9 Christos Stavrakakis
    def test_invalid_data_3(self, mrapi):
568 47eeffa9 Christos Stavrakakis
        """Test unauthorized to create public network"""
569 47eeffa9 Christos Stavrakakis
        request = {
570 47eeffa9 Christos Stavrakakis
                'network': {'name': 'foo', 'public': True}
571 47eeffa9 Christos Stavrakakis
            }
572 47eeffa9 Christos Stavrakakis
        response = self.post('/api/v1.1/networks/', 'user1',
573 47eeffa9 Christos Stavrakakis
                             json.dumps(request), 'json')
574 47eeffa9 Christos Stavrakakis
        self.assertFault(response, 403, "forbidden")
575 47eeffa9 Christos Stavrakakis
576 47eeffa9 Christos Stavrakakis
    def test_list_networks(self, mrapi):
577 47eeffa9 Christos Stavrakakis
        mfactory.NetworkFactory(userid=self.user, deleted=True)
578 47eeffa9 Christos Stavrakakis
        response = self.get('/api/v1.1/networks/', self.user)
579 47eeffa9 Christos Stavrakakis
        self.assertSuccess(response)
580 47eeffa9 Christos Stavrakakis
        db_nets = Network.objects.filter(userid=self.user, deleted=False)
581 47eeffa9 Christos Stavrakakis
        api_nets = json.loads(response.content)["networks"]["values"]
582 47eeffa9 Christos Stavrakakis
        self.assertEqual(len(db_nets), len(api_nets))
583 47eeffa9 Christos Stavrakakis
        for api_net in api_nets:
584 47eeffa9 Christos Stavrakakis
            net_id = api_net['id']
585 47eeffa9 Christos Stavrakakis
            self.assertNetworksEqual(Network.objects.get(id=net_id), api_net)
586 47eeffa9 Christos Stavrakakis
587 47eeffa9 Christos Stavrakakis
    def test_list_networks_detail(self, mrapi):
588 47eeffa9 Christos Stavrakakis
        mfactory.NetworkFactory(userid=self.user, deleted=True)
589 47eeffa9 Christos Stavrakakis
        response = self.get('/api/v1.1/networks/detail', self.user)
590 47eeffa9 Christos Stavrakakis
        self.assertSuccess(response)
591 47eeffa9 Christos Stavrakakis
        db_nets = Network.objects.filter(userid=self.user, deleted=False)
592 47eeffa9 Christos Stavrakakis
        api_nets = json.loads(response.content)["networks"]["values"]
593 47eeffa9 Christos Stavrakakis
        self.assertEqual(len(db_nets), len(api_nets))
594 47eeffa9 Christos Stavrakakis
        for api_net in api_nets:
595 47eeffa9 Christos Stavrakakis
            net_id = api_net['id']
596 47eeffa9 Christos Stavrakakis
            self.assertNetworksEqual(Network.objects.get(id=net_id), api_net,
597 47eeffa9 Christos Stavrakakis
                                     detail=True)
598 47eeffa9 Christos Stavrakakis
599 47eeffa9 Christos Stavrakakis
    def test_network_details_1(self, mrapi):
600 47eeffa9 Christos Stavrakakis
        response = self.get('/api/v1.1/networks/%d' % self.net1.id,
601 47eeffa9 Christos Stavrakakis
                            self.net1.userid)
602 47eeffa9 Christos Stavrakakis
        self.assertSuccess(response)
603 47eeffa9 Christos Stavrakakis
        api_net = json.loads(response.content)["network"]
604 47eeffa9 Christos Stavrakakis
        self.assertNetworksEqual(self.net1, api_net, detail=True)
605 47eeffa9 Christos Stavrakakis
606 47eeffa9 Christos Stavrakakis
    def test_invalid_network(self, mrapi):
607 47eeffa9 Christos Stavrakakis
        response = self.get('/api/v1.1/networks/%d' % 42,
608 47eeffa9 Christos Stavrakakis
                            self.net1.userid)
609 47eeffa9 Christos Stavrakakis
        self.assertItemNotFound(response)
610 47eeffa9 Christos Stavrakakis
611 47eeffa9 Christos Stavrakakis
    def test_rename_network(self, mrapi):
612 47eeffa9 Christos Stavrakakis
        request = {'network': {'name': "new_name"}}
613 47eeffa9 Christos Stavrakakis
        response = self.put('/api/v1.1/networks/%d' % self.net2.id,
614 47eeffa9 Christos Stavrakakis
                            self.net2.userid, json.dumps(request), 'json')
615 13b954b0 Giorgos Verigakis
        self.assertEqual(response.status_code, 204)
616 47eeffa9 Christos Stavrakakis
        self.assertEqual(Network.objects.get(id=self.net2.id).name, "new_name")
617 47eeffa9 Christos Stavrakakis
618 47eeffa9 Christos Stavrakakis
    def test_rename_public_network(self, mrapi):
619 47eeffa9 Christos Stavrakakis
        net = mfactory.NetworkFactory(public=True)
620 47eeffa9 Christos Stavrakakis
        request = {'network': {'name': "new_name"}}
621 47eeffa9 Christos Stavrakakis
        response = self.put('/api/v1.1/networks/%d' % net.id,
622 47eeffa9 Christos Stavrakakis
                            self.net2.userid, json.dumps(request), 'json')
623 47eeffa9 Christos Stavrakakis
        self.assertFault(response, 403, 'forbidden')
624 47eeffa9 Christos Stavrakakis
625 47eeffa9 Christos Stavrakakis
    def test_delete_network(self, mrapi):
626 47eeffa9 Christos Stavrakakis
        response = self.delete('/api/v1.1/networks/%d' % self.net2.id,
627 47eeffa9 Christos Stavrakakis
                                self.net2.userid)
628 13b954b0 Giorgos Verigakis
        self.assertEqual(response.status_code, 204)
629 47eeffa9 Christos Stavrakakis
        net = Network.objects.get(id=self.net2.id, userid=self.net2.userid)
630 47eeffa9 Christos Stavrakakis
        self.assertEqual(net.action, 'DESTROY')
631 47eeffa9 Christos Stavrakakis
        mrapi.DeleteNetwork.assert_called()
632 47eeffa9 Christos Stavrakakis
633 47eeffa9 Christos Stavrakakis
    def test_delete_public_network(self, mrapi):
634 47eeffa9 Christos Stavrakakis
        net = mfactory.NetworkFactory(public=True)
635 47eeffa9 Christos Stavrakakis
        response = self.delete('/api/v1.1/networks/%d' % net.id,
636 47eeffa9 Christos Stavrakakis
                                self.net2.userid)
637 47eeffa9 Christos Stavrakakis
        self.assertFault(response, 403, 'forbidden')
638 b66e4833 Christos Stavrakakis
        self.assertFalse(mrapi.mock_calls)
639 b66e4833 Christos Stavrakakis
640 b66e4833 Christos Stavrakakis
    def test_delete_network_in_use(self, mrapi):
641 b66e4833 Christos Stavrakakis
        net = mfactory.NetworkFactory(deleted=False)
642 b66e4833 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
643 b66e4833 Christos Stavrakakis
        mfactory.NetworkInterfaceFactory(machine=vm, network=net)
644 b66e4833 Christos Stavrakakis
        response = self.delete('/api/v1.1/networks/%d' % net.id,
645 b66e4833 Christos Stavrakakis
                                net.userid)
646 b66e4833 Christos Stavrakakis
        self.assertFault(response, 421, 'networkInUse')
647 b66e4833 Christos Stavrakakis
        self.assertFalse(mrapi.mock_calls)
648 47eeffa9 Christos Stavrakakis
649 47eeffa9 Christos Stavrakakis
    def test_add_nic(self, mrapi):
650 47eeffa9 Christos Stavrakakis
        user = 'userr'
651 47eeffa9 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory(name='yo', userid=user)
652 47eeffa9 Christos Stavrakakis
        net = mfactory.NetworkFactory(state='ACTIVE', userid=user)
653 47eeffa9 Christos Stavrakakis
        request = {'add': {'serverRef': vm.id}}
654 47eeffa9 Christos Stavrakakis
        response = self.post('/api/v1.1/networks/%d/action' % net.id,
655 47eeffa9 Christos Stavrakakis
                             net.userid, json.dumps(request), 'json')
656 13b954b0 Giorgos Verigakis
        self.assertEqual(response.status_code, 202)
657 aa197ee4 Vangelis Koukis
658 b66e4833 Christos Stavrakakis
    def test_add_nic_to_public_network(self, mrapi):
659 b66e4833 Christos Stavrakakis
        user = 'userr'
660 b66e4833 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory(name='yo', userid=user)
661 b66e4833 Christos Stavrakakis
        net = mfactory.NetworkFactory(state='ACTIVE', userid=user, public=True)
662 b66e4833 Christos Stavrakakis
        request = {'add': {'serverRef': vm.id}}
663 b66e4833 Christos Stavrakakis
        response = self.post('/api/v1.1/networks/%d/action' % net.id,
664 b66e4833 Christos Stavrakakis
                             net.userid, json.dumps(request), 'json')
665 b66e4833 Christos Stavrakakis
        self.assertFault(response, 403, 'forbidden')
666 b66e4833 Christos Stavrakakis
667 47eeffa9 Christos Stavrakakis
    def test_add_nic_malformed(self, mrapi):
668 47eeffa9 Christos Stavrakakis
        user = 'userr'
669 47eeffa9 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory(name='yo', userid=user)
670 47eeffa9 Christos Stavrakakis
        net = mfactory.NetworkFactory(state='ACTIVE', userid=user)
671 47eeffa9 Christos Stavrakakis
        request = {'add': {'serveRef': vm.id}}
672 47eeffa9 Christos Stavrakakis
        response = self.post('/api/v1.1/networks/%d/action' % net.id,
673 47eeffa9 Christos Stavrakakis
                             net.userid, json.dumps(request), 'json')
674 47eeffa9 Christos Stavrakakis
        self.assertBadRequest(response)
675 53b1eea6 Giorgos Verigakis
676 b66e4833 Christos Stavrakakis
    def test_add_nic_not_active(self, mrapi):
677 b66e4833 Christos Stavrakakis
        """Test connecting VM to non-active network"""
678 b66e4833 Christos Stavrakakis
        user = 'dummy'
679 b66e4833 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory(name='yo', userid=user)
680 b66e4833 Christos Stavrakakis
        net = mfactory.NetworkFactory(state='PENDING', subnet='10.0.0.0/31',
681 b66e4833 Christos Stavrakakis
                                      userid=user)
682 b66e4833 Christos Stavrakakis
        request = {'add': {'serveRef': vm.id}}
683 b66e4833 Christos Stavrakakis
        response = self.post('/api/v1.1/networks/%d/action' % net.id,
684 b66e4833 Christos Stavrakakis
                             net.userid, json.dumps(request), 'json')
685 b66e4833 Christos Stavrakakis
        # Test that returns BuildInProgress
686 b66e4833 Christos Stavrakakis
        self.assertEqual(response.status_code, 409)
687 b66e4833 Christos Stavrakakis
688 b66e4833 Christos Stavrakakis
    def test_add_nic_full_network(self, mrapi):
689 b66e4833 Christos Stavrakakis
        """Test connecting VM to a full network"""
690 b66e4833 Christos Stavrakakis
        user = 'userr'
691 b66e4833 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory(name='yo', userid=user)
692 b66e4833 Christos Stavrakakis
        net = mfactory.NetworkFactory(state='ACTIVE', subnet='10.0.0.0/30',
693 b66e4833 Christos Stavrakakis
                                      userid=user, dhcp=True)
694 b66e4833 Christos Stavrakakis
        pool = net.get_pool()
695 b66e4833 Christos Stavrakakis
        while not pool.empty():
696 b66e4833 Christos Stavrakakis
            pool.get()
697 b66e4833 Christos Stavrakakis
        pool.save()
698 b66e4833 Christos Stavrakakis
        pool = net.get_pool()
699 b66e4833 Christos Stavrakakis
        self.assertTrue(pool.empty())
700 b66e4833 Christos Stavrakakis
        request = {'add': {'serverRef': vm.id}}
701 b66e4833 Christos Stavrakakis
        response = self.post('/api/v1.1/networks/%d/action' % net.id,
702 b66e4833 Christos Stavrakakis
                             net.userid, json.dumps(request), 'json')
703 b66e4833 Christos Stavrakakis
        # Test that returns OverLimit
704 b66e4833 Christos Stavrakakis
        self.assertEqual(response.status_code, 413)
705 b66e4833 Christos Stavrakakis
706 47eeffa9 Christos Stavrakakis
    def test_remove_nic(self, mrapi):
707 47eeffa9 Christos Stavrakakis
        user = 'userr'
708 47eeffa9 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory(name='yo', userid=user)
709 47eeffa9 Christos Stavrakakis
        net = mfactory.NetworkFactory(state='ACTIVE', userid=user)
710 47eeffa9 Christos Stavrakakis
        nic = mfactory.NetworkInterfaceFactory(machine=vm, network=net)
711 47eeffa9 Christos Stavrakakis
        request = {'remove': {'attachment': 'nic-%s-%s' % (vm.id, nic.index)}}
712 47eeffa9 Christos Stavrakakis
        response = self.post('/api/v1.1/networks/%d/action' % net.id,
713 47eeffa9 Christos Stavrakakis
                             net.userid, json.dumps(request), 'json')
714 47eeffa9 Christos Stavrakakis
        self.assertEqual(response.status_code, 202)
715 47eeffa9 Christos Stavrakakis
        self.assertTrue(NetworkInterface.objects.get(id=nic.id).dirty)
716 47eeffa9 Christos Stavrakakis
        # Remove dirty nic
717 47eeffa9 Christos Stavrakakis
        response = self.post('/api/v1.1/networks/%d/action' % net.id,
718 47eeffa9 Christos Stavrakakis
                             net.userid, json.dumps(request), 'json')
719 47eeffa9 Christos Stavrakakis
        self.assertFault(response, 409, 'buildInProgress')
720 47eeffa9 Christos Stavrakakis
721 47eeffa9 Christos Stavrakakis
    def test_remove_nic_malformed(self, mrapi):
722 47eeffa9 Christos Stavrakakis
        user = 'userr'
723 47eeffa9 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory(name='yo', userid=user)
724 47eeffa9 Christos Stavrakakis
        net = mfactory.NetworkFactory(state='ACTIVE', userid=user)
725 47eeffa9 Christos Stavrakakis
        nic = mfactory.NetworkInterfaceFactory(machine=vm, network=net)
726 47eeffa9 Christos Stavrakakis
        request = {'remove':
727 47eeffa9 Christos Stavrakakis
                    {'att234achment': 'nic-%s-%s' % (vm.id, nic.index)}
728 47eeffa9 Christos Stavrakakis
                  }
729 47eeffa9 Christos Stavrakakis
        response = self.post('/api/v1.1/networks/%d/action' % net.id,
730 47eeffa9 Christos Stavrakakis
                             net.userid, json.dumps(request), 'json')
731 47eeffa9 Christos Stavrakakis
        self.assertBadRequest(response)
732 4cf8adf8 Vangelis Koukis
733 b66e4833 Christos Stavrakakis
    def test_remove_nic_malformed_2(self, mrapi):
734 b66e4833 Christos Stavrakakis
        user = 'userr'
735 b66e4833 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory(name='yo', userid=user)
736 b66e4833 Christos Stavrakakis
        net = mfactory.NetworkFactory(state='ACTIVE', userid=user)
737 b66e4833 Christos Stavrakakis
        request = {'remove':
738 b66e4833 Christos Stavrakakis
                    {'attachment': 'nic-%s' % vm.id}
739 b66e4833 Christos Stavrakakis
                  }
740 b66e4833 Christos Stavrakakis
        response = self.post('/api/v1.1/networks/%d/action' % net.id,
741 b66e4833 Christos Stavrakakis
                             net.userid, json.dumps(request), 'json')
742 b66e4833 Christos Stavrakakis
        self.assertBadRequest(response)
743 b66e4833 Christos Stavrakakis
744 4cf8adf8 Vangelis Koukis
745 52194c77 Christos Stavrakakis
class ServerVNCConsole(BaseAPITest):
746 4cf8adf8 Vangelis Koukis
747 4cf8adf8 Vangelis Koukis
    def test_not_active_server(self):
748 47eeffa9 Christos Stavrakakis
        """Test console req for not ACTIVE server returns badRequest"""
749 47eeffa9 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
750 4cf8adf8 Vangelis Koukis
        data = json.dumps({'console': {'type': 'vnc'}})
751 47eeffa9 Christos Stavrakakis
        response = self.post('/api/v1.1/servers/%d/action' % vm.id,
752 47eeffa9 Christos Stavrakakis
                             vm.userid, data, 'json')
753 4cf8adf8 Vangelis Koukis
        self.assertBadRequest(response)
754 4cf8adf8 Vangelis Koukis
755 4cf8adf8 Vangelis Koukis
    def test_active_server(self):
756 4cf8adf8 Vangelis Koukis
        """Test console req for ACTIVE server"""
757 47eeffa9 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
758 4cf8adf8 Vangelis Koukis
        vm.operstate = 'STARTED'
759 4cf8adf8 Vangelis Koukis
        vm.save()
760 c25cc9ec Vangelis Koukis
761 4cf8adf8 Vangelis Koukis
        data = json.dumps({'console': {'type': 'vnc'}})
762 47eeffa9 Christos Stavrakakis
        response = self.post('/api/v1.1/servers/%d/action' % vm.id,
763 47eeffa9 Christos Stavrakakis
                             vm.userid, data, 'json')
764 4cf8adf8 Vangelis Koukis
        self.assertEqual(response.status_code, 200)
765 4cf8adf8 Vangelis Koukis
        reply = json.loads(response.content)
766 529178b1 Giorgos Verigakis
        self.assertEqual(reply.keys(), ['console'])
767 529178b1 Giorgos Verigakis
        console = reply['console']
768 529178b1 Giorgos Verigakis
        self.assertEqual(console['type'], 'vnc')
769 47eeffa9 Christos Stavrakakis
        self.assertEqual(set(console.keys()),
770 47eeffa9 Christos Stavrakakis
                         set(['type', 'host', 'port', 'password']))
771 47eeffa9 Christos Stavrakakis
772 b66e4833 Christos Stavrakakis
    def test_wrong_console_type(self):
773 b66e4833 Christos Stavrakakis
        """Test console req for ACTIVE server"""
774 b66e4833 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
775 b66e4833 Christos Stavrakakis
        vm.operstate = 'STARTED'
776 b66e4833 Christos Stavrakakis
        vm.save()
777 b66e4833 Christos Stavrakakis
778 b66e4833 Christos Stavrakakis
        data = json.dumps({'console': {'type': 'foo'}})
779 b66e4833 Christos Stavrakakis
        response = self.post('/api/v1.1/servers/%d/action' % vm.id,
780 b66e4833 Christos Stavrakakis
                             vm.userid, data, 'json')
781 b66e4833 Christos Stavrakakis
        self.assertBadRequest(response)
782 47eeffa9 Christos Stavrakakis
783 52194c77 Christos Stavrakakis
def assert_backend_closed(func):
784 52194c77 Christos Stavrakakis
    @wraps(func)
785 52194c77 Christos Stavrakakis
    def wrapper(self, backend):
786 52194c77 Christos Stavrakakis
        result = func(self, backend)
787 52194c77 Christos Stavrakakis
        if backend.called is True:
788 52194c77 Christos Stavrakakis
            backend.return_value.close.assert_called_once_with()
789 52194c77 Christos Stavrakakis
        return result
790 52194c77 Christos Stavrakakis
    return wrapper
791 52194c77 Christos Stavrakakis
792 52194c77 Christos Stavrakakis
793 47eeffa9 Christos Stavrakakis
@patch('synnefo.api.images.ImageBackend')
794 52194c77 Christos Stavrakakis
class ImageAPITest(BaseAPITest):
795 52194c77 Christos Stavrakakis
    @assert_backend_closed
796 47eeffa9 Christos Stavrakakis
    def test_create_image(self, mimage):
797 47eeffa9 Christos Stavrakakis
        """Test that create image is not implemented"""
798 47eeffa9 Christos Stavrakakis
        response = self.post('/api/v1.1/images/', 'user', json.dumps(''),
799 47eeffa9 Christos Stavrakakis
                             'json')
800 47eeffa9 Christos Stavrakakis
        self.assertEqual(response.status_code, 503)
801 47eeffa9 Christos Stavrakakis
802 52194c77 Christos Stavrakakis
    @assert_backend_closed
803 47eeffa9 Christos Stavrakakis
    def test_list_images(self, mimage):
804 47eeffa9 Christos Stavrakakis
        """Test that expected list of images is returned"""
805 47eeffa9 Christos Stavrakakis
        images = [{'id': 1, 'name': 'image-1'},
806 47eeffa9 Christos Stavrakakis
                  {'id': 2, 'name': 'image-2'},
807 47eeffa9 Christos Stavrakakis
                  {'id': 3, 'name': 'image-3'}]
808 47eeffa9 Christos Stavrakakis
        mimage().list.return_value = images
809 47eeffa9 Christos Stavrakakis
        response = self.get('/api/v1.1/images/', 'user')
810 47eeffa9 Christos Stavrakakis
        self.assertSuccess(response)
811 47eeffa9 Christos Stavrakakis
        api_images = json.loads(response.content)['images']['values']
812 47eeffa9 Christos Stavrakakis
        self.assertEqual(images, api_images)
813 47eeffa9 Christos Stavrakakis
814 52194c77 Christos Stavrakakis
    @assert_backend_closed
815 47eeffa9 Christos Stavrakakis
    def test_list_images_detail(self, mimage):
816 47eeffa9 Christos Stavrakakis
        images = [{'id': 1,
817 47eeffa9 Christos Stavrakakis
                   'name': 'image-1',
818 47eeffa9 Christos Stavrakakis
                   'status':'available',
819 47eeffa9 Christos Stavrakakis
                   'created_at': '2012-11-26 11:52:54',
820 47eeffa9 Christos Stavrakakis
                   'updated_at': '2012-12-26 11:52:54',
821 47eeffa9 Christos Stavrakakis
                   'deleted_at': '',
822 47eeffa9 Christos Stavrakakis
                   'properties': {'foo':'bar'}},
823 47eeffa9 Christos Stavrakakis
                  {'id': 2,
824 47eeffa9 Christos Stavrakakis
                   'name': 'image-2',
825 47eeffa9 Christos Stavrakakis
                   'status': 'deleted',
826 47eeffa9 Christos Stavrakakis
                   'created_at': '2012-11-26 11:52:54',
827 47eeffa9 Christos Stavrakakis
                   'updated_at': '2012-12-26 11:52:54',
828 47eeffa9 Christos Stavrakakis
                   'deleted_at': '2012-12-27 11:52:54',
829 47eeffa9 Christos Stavrakakis
                   'properties': ''},
830 47eeffa9 Christos Stavrakakis
                  {'id': 3,
831 47eeffa9 Christos Stavrakakis
                   'name': 'image-3',
832 47eeffa9 Christos Stavrakakis
                   'status': 'available',
833 47eeffa9 Christos Stavrakakis
                   'created_at': '2012-11-26 11:52:54',
834 47eeffa9 Christos Stavrakakis
                   'deleted_at': '',
835 47eeffa9 Christos Stavrakakis
                   'updated_at': '2012-12-26 11:52:54',
836 47eeffa9 Christos Stavrakakis
                   'properties': ''}]
837 47eeffa9 Christos Stavrakakis
        result_images = [
838 47eeffa9 Christos Stavrakakis
                  {'id': 1,
839 47eeffa9 Christos Stavrakakis
                   'name': 'image-1',
840 47eeffa9 Christos Stavrakakis
                   'status':'ACTIVE',
841 47eeffa9 Christos Stavrakakis
                   'progress': 100,
842 47eeffa9 Christos Stavrakakis
                   'created': '2012-11-26T11:52:54+00:00',
843 47eeffa9 Christos Stavrakakis
                   'updated': '2012-12-26T11:52:54+00:00',
844 47eeffa9 Christos Stavrakakis
                   'metadata': {'values': {'foo':'bar'}}},
845 47eeffa9 Christos Stavrakakis
                  {'id': 2,
846 47eeffa9 Christos Stavrakakis
                   'name': 'image-2',
847 47eeffa9 Christos Stavrakakis
                   'status': 'DELETED',
848 47eeffa9 Christos Stavrakakis
                   'progress': 0,
849 47eeffa9 Christos Stavrakakis
                   'created': '2012-11-26T11:52:54+00:00',
850 47eeffa9 Christos Stavrakakis
                   'updated': '2012-12-26T11:52:54+00:00'},
851 47eeffa9 Christos Stavrakakis
                  {'id': 3,
852 47eeffa9 Christos Stavrakakis
                   'name': 'image-3',
853 47eeffa9 Christos Stavrakakis
                   'status': 'ACTIVE',
854 47eeffa9 Christos Stavrakakis
                   'progress': 100,
855 47eeffa9 Christos Stavrakakis
                   'created': '2012-11-26T11:52:54+00:00',
856 47eeffa9 Christos Stavrakakis
                   'updated': '2012-12-26T11:52:54+00:00'}]
857 47eeffa9 Christos Stavrakakis
        mimage().list.return_value = images
858 47eeffa9 Christos Stavrakakis
        response = self.get('/api/v1.1/images/detail', 'user')
859 47eeffa9 Christos Stavrakakis
        self.assertSuccess(response)
860 47eeffa9 Christos Stavrakakis
        api_images = json.loads(response.content)['images']['values']
861 47eeffa9 Christos Stavrakakis
        self.assertEqual(len(result_images), len(api_images))
862 47eeffa9 Christos Stavrakakis
        self.assertEqual(result_images, api_images)
863 47eeffa9 Christos Stavrakakis
864 52194c77 Christos Stavrakakis
    @assert_backend_closed
865 47eeffa9 Christos Stavrakakis
    def test_get_image_details(self, mimage):
866 47eeffa9 Christos Stavrakakis
        image = {'id': 42,
867 47eeffa9 Christos Stavrakakis
                 'name': 'image-1',
868 47eeffa9 Christos Stavrakakis
                 'status': 'available',
869 47eeffa9 Christos Stavrakakis
                 'created_at': '2012-11-26 11:52:54',
870 47eeffa9 Christos Stavrakakis
                 'updated_at': '2012-12-26 11:52:54',
871 47eeffa9 Christos Stavrakakis
                 'deleted_at': '',
872 47eeffa9 Christos Stavrakakis
                 'properties': {'foo': 'bar'}}
873 47eeffa9 Christos Stavrakakis
        result_image = \
874 47eeffa9 Christos Stavrakakis
                  {'id': 42,
875 47eeffa9 Christos Stavrakakis
                   'name': 'image-1',
876 47eeffa9 Christos Stavrakakis
                   'status': 'ACTIVE',
877 47eeffa9 Christos Stavrakakis
                   'progress': 100,
878 47eeffa9 Christos Stavrakakis
                   'created': '2012-11-26T11:52:54+00:00',
879 47eeffa9 Christos Stavrakakis
                   'updated': '2012-12-26T11:52:54+00:00',
880 47eeffa9 Christos Stavrakakis
                   'metadata': {'values': {'foo': 'bar'}}}
881 47eeffa9 Christos Stavrakakis
        with patch('synnefo.api.util.get_image') as m:
882 47eeffa9 Christos Stavrakakis
            m.return_value = image
883 47eeffa9 Christos Stavrakakis
            response = self.get('/api/v1.1/images/42', 'user')
884 47eeffa9 Christos Stavrakakis
        self.assertSuccess(response)
885 47eeffa9 Christos Stavrakakis
        api_image = json.loads(response.content)['image']
886 47eeffa9 Christos Stavrakakis
        self.assertEqual(api_image, result_image)
887 47eeffa9 Christos Stavrakakis
888 52194c77 Christos Stavrakakis
    @assert_backend_closed
889 47eeffa9 Christos Stavrakakis
    def test_invalid_image(self, mimage):
890 47eeffa9 Christos Stavrakakis
        with patch('synnefo.api.util.get_image') as m:
891 47eeffa9 Christos Stavrakakis
            m.side_effect = faults.ItemNotFound('Image not found')
892 47eeffa9 Christos Stavrakakis
            response = self.get('/api/v1.1/images/42', 'user')
893 47eeffa9 Christos Stavrakakis
        self.assertItemNotFound(response)
894 47eeffa9 Christos Stavrakakis
895 47eeffa9 Christos Stavrakakis
    def test_delete_image(self, mimage):
896 47eeffa9 Christos Stavrakakis
        # TODO
897 47eeffa9 Christos Stavrakakis
        pass
898 47eeffa9 Christos Stavrakakis
899 47eeffa9 Christos Stavrakakis
900 52194c77 Christos Stavrakakis
@patch('synnefo.api.util.ImageBackend')
901 52194c77 Christos Stavrakakis
class ImageMetadataAPITest(BaseAPITest):
902 aa519091 Georgios Gousios
    def setUp(self):
903 47eeffa9 Christos Stavrakakis
        self.image = {'id': 42,
904 47eeffa9 Christos Stavrakakis
                 'name': 'image-1',
905 47eeffa9 Christos Stavrakakis
                 'status': 'available',
906 47eeffa9 Christos Stavrakakis
                 'created_at': '2012-11-26 11:52:54',
907 47eeffa9 Christos Stavrakakis
                 'updated_at': '2012-12-26 11:52:54',
908 47eeffa9 Christos Stavrakakis
                 'deleted_at': '',
909 47eeffa9 Christos Stavrakakis
                 'properties': {'foo': 'bar', 'foo2': 'bar2'}}
910 47eeffa9 Christos Stavrakakis
        self.result_image = \
911 47eeffa9 Christos Stavrakakis
                  {'id': 42,
912 47eeffa9 Christos Stavrakakis
                   'name': 'image-1',
913 47eeffa9 Christos Stavrakakis
                   'status': 'ACTIVE',
914 47eeffa9 Christos Stavrakakis
                   'progress': 100,
915 47eeffa9 Christos Stavrakakis
                   'created': '2012-11-26T11:52:54+00:00',
916 47eeffa9 Christos Stavrakakis
                   'updated': '2012-12-26T11:52:54+00:00',
917 47eeffa9 Christos Stavrakakis
                   'metadata': {'values': {'foo': 'bar'}}}
918 aa197ee4 Vangelis Koukis
919 52194c77 Christos Stavrakakis
    @assert_backend_closed
920 52194c77 Christos Stavrakakis
    def test_list_metadata(self, backend):
921 52194c77 Christos Stavrakakis
        backend.return_value.get_image.return_value = self.image
922 52194c77 Christos Stavrakakis
        response = self.get('/api/v1.1/images/42/meta', 'user')
923 47eeffa9 Christos Stavrakakis
        self.assertSuccess(response)
924 47eeffa9 Christos Stavrakakis
        meta = json.loads(response.content)['metadata']['values']
925 47eeffa9 Christos Stavrakakis
        self.assertEqual(meta, self.image['properties'])
926 47eeffa9 Christos Stavrakakis
927 52194c77 Christos Stavrakakis
    @assert_backend_closed
928 52194c77 Christos Stavrakakis
    def test_get_metadata(self, backend):
929 52194c77 Christos Stavrakakis
        backend.return_value.get_image.return_value = self.image
930 52194c77 Christos Stavrakakis
        response = self.get('/api/v1.1/images/42/meta/foo', 'user')
931 47eeffa9 Christos Stavrakakis
        self.assertSuccess(response)
932 47eeffa9 Christos Stavrakakis
        meta = json.loads(response.content)['meta']
933 47eeffa9 Christos Stavrakakis
        self.assertEqual(meta['foo'], 'bar')
934 47eeffa9 Christos Stavrakakis
935 52194c77 Christos Stavrakakis
    @assert_backend_closed
936 52194c77 Christos Stavrakakis
    def test_get_invalid_metadata(self, backend):
937 52194c77 Christos Stavrakakis
        backend.return_value.get_image.return_value = self.image
938 52194c77 Christos Stavrakakis
        response = self.get('/api/v1.1/images/42/meta/not_found', 'user')
939 47eeffa9 Christos Stavrakakis
        self.assertItemNotFound(response)
940 47eeffa9 Christos Stavrakakis
941 52194c77 Christos Stavrakakis
    @assert_backend_closed
942 52194c77 Christos Stavrakakis
    def test_delete_metadata_item(self, backend):
943 52194c77 Christos Stavrakakis
        backend.return_value.get_image.return_value = self.image
944 52194c77 Christos Stavrakakis
        with patch("synnefo.api.images.ImageBackend") as m:
945 52194c77 Christos Stavrakakis
            response = self.delete('/api/v1.1/images/42/meta/foo', 'user')
946 52194c77 Christos Stavrakakis
            self.assertEqual(response.status_code, 204)
947 52194c77 Christos Stavrakakis
            m.return_value.update.assert_called_once_with('42',
948 52194c77 Christos Stavrakakis
                                        {'properties': {'foo2': 'bar2'}})
949 52194c77 Christos Stavrakakis
950 52194c77 Christos Stavrakakis
    @assert_backend_closed
951 52194c77 Christos Stavrakakis
    def test_create_metadata_item(self, backend):
952 52194c77 Christos Stavrakakis
        backend.return_value.get_image.return_value = self.image
953 52194c77 Christos Stavrakakis
        with patch("synnefo.api.images.ImageBackend") as m:
954 47eeffa9 Christos Stavrakakis
                request = {'meta': {'foo3': 'bar3'}}
955 47eeffa9 Christos Stavrakakis
                response = self.put('/api/v1.1/images/42/meta/foo3', 'user',
956 47eeffa9 Christos Stavrakakis
                                    json.dumps(request), 'json')
957 47eeffa9 Christos Stavrakakis
                self.assertEqual(response.status_code, 201)
958 52194c77 Christos Stavrakakis
                m.return_value.update.assert_called_once_with('42',
959 47eeffa9 Christos Stavrakakis
                        {'properties':
960 47eeffa9 Christos Stavrakakis
                            {'foo': 'bar', 'foo2': 'bar2', 'foo3': 'bar3'}})
961 47eeffa9 Christos Stavrakakis
962 52194c77 Christos Stavrakakis
    @assert_backend_closed
963 b66e4833 Christos Stavrakakis
    def test_create_metadata_malformed_1(self, backend):
964 b66e4833 Christos Stavrakakis
        backend.return_value.get_image.return_value = self.image
965 b66e4833 Christos Stavrakakis
        with patch("synnefo.api.images.ImageBackend"):
966 b66e4833 Christos Stavrakakis
                request = {'met': {'foo3': 'bar3'}}
967 b66e4833 Christos Stavrakakis
                response = self.put('/api/v1.1/images/42/meta/foo3', 'user',
968 b66e4833 Christos Stavrakakis
                                    json.dumps(request), 'json')
969 b66e4833 Christos Stavrakakis
                self.assertBadRequest(response)
970 b66e4833 Christos Stavrakakis
971 b66e4833 Christos Stavrakakis
    @assert_backend_closed
972 b66e4833 Christos Stavrakakis
    def test_create_metadata_malformed_2(self, backend):
973 b66e4833 Christos Stavrakakis
        backend.return_value.get_image.return_value = self.image
974 b66e4833 Christos Stavrakakis
        with patch("synnefo.api.images.ImageBackend"):
975 b66e4833 Christos Stavrakakis
                request = {'meta': [('foo3', 'bar3')]}
976 b66e4833 Christos Stavrakakis
                response = self.put('/api/v1.1/images/42/meta/foo3', 'user',
977 b66e4833 Christos Stavrakakis
                                    json.dumps(request), 'json')
978 b66e4833 Christos Stavrakakis
                self.assertBadRequest(response)
979 b66e4833 Christos Stavrakakis
980 b66e4833 Christos Stavrakakis
    @assert_backend_closed
981 b66e4833 Christos Stavrakakis
    def test_create_metadata_malformed_3(self, backend):
982 b66e4833 Christos Stavrakakis
        backend.return_value.get_image.return_value = self.image
983 b66e4833 Christos Stavrakakis
        with patch("synnefo.api.images.ImageBackend"):
984 b66e4833 Christos Stavrakakis
            request = {'met': {'foo3': 'bar3', 'foo4': 'bar4'}}
985 b66e4833 Christos Stavrakakis
            response = self.put('/api/v1.1/images/42/meta/foo3', 'user',
986 b66e4833 Christos Stavrakakis
                                    json.dumps(request), 'json')
987 b66e4833 Christos Stavrakakis
            self.assertBadRequest(response)
988 b66e4833 Christos Stavrakakis
989 b66e4833 Christos Stavrakakis
    @assert_backend_closed
990 b66e4833 Christos Stavrakakis
    def test_create_metadata_malformed_4(self, backend):
991 b66e4833 Christos Stavrakakis
        backend.return_value.get_image.return_value = self.image
992 b66e4833 Christos Stavrakakis
        with patch("synnefo.api.images.ImageBackend"):
993 b66e4833 Christos Stavrakakis
            request = {'met': {'foo3': 'bar3'}}
994 b66e4833 Christos Stavrakakis
            response = self.put('/api/v1.1/images/42/meta/foo4', 'user',
995 b66e4833 Christos Stavrakakis
                                    json.dumps(request), 'json')
996 b66e4833 Christos Stavrakakis
            self.assertBadRequest(response)
997 b66e4833 Christos Stavrakakis
998 b66e4833 Christos Stavrakakis
    @assert_backend_closed
999 52194c77 Christos Stavrakakis
    def test_update_metadata_item(self, backend):
1000 52194c77 Christos Stavrakakis
        backend.return_value.get_image.return_value = self.image
1001 52194c77 Christos Stavrakakis
        with patch("synnefo.api.images.ImageBackend") as m:
1002 47eeffa9 Christos Stavrakakis
                request = {'metadata': {'foo': 'bar_new', 'foo4': 'bar4'}}
1003 47eeffa9 Christos Stavrakakis
                response = self.post('/api/v1.1/images/42/meta', 'user',
1004 47eeffa9 Christos Stavrakakis
                                    json.dumps(request), 'json')
1005 47eeffa9 Christos Stavrakakis
                self.assertEqual(response.status_code, 201)
1006 52194c77 Christos Stavrakakis
                m.return_value.update.assert_called_once_with('42',
1007 52194c77 Christos Stavrakakis
                        {'properties':
1008 52194c77 Christos Stavrakakis
                            {'foo': 'bar_new', 'foo2': 'bar2', 'foo4': 'bar4'}
1009 52194c77 Christos Stavrakakis
                        })
1010 52194c77 Christos Stavrakakis
1011 b66e4833 Christos Stavrakakis
    @assert_backend_closed
1012 b66e4833 Christos Stavrakakis
    def test_update_metadata_malformed(self, backend):
1013 b66e4833 Christos Stavrakakis
        backend.return_value.get_image.return_value = self.image
1014 b66e4833 Christos Stavrakakis
        with patch("synnefo.api.images.ImageBackend"):
1015 b66e4833 Christos Stavrakakis
                request = {'meta': {'foo': 'bar_new', 'foo4': 'bar4'}}
1016 b66e4833 Christos Stavrakakis
                response = self.post('/api/v1.1/images/42/meta', 'user',
1017 b66e4833 Christos Stavrakakis
                                    json.dumps(request), 'json')
1018 b66e4833 Christos Stavrakakis
                self.assertBadRequest(response)
1019 b66e4833 Christos Stavrakakis
1020 52194c77 Christos Stavrakakis
1021 52194c77 Christos Stavrakakis
class APITest(TestCase):
1022 52194c77 Christos Stavrakakis
    def test_api_version(self):
1023 52194c77 Christos Stavrakakis
        """Check API version."""
1024 52194c77 Christos Stavrakakis
        with astakos_user('user'):
1025 52194c77 Christos Stavrakakis
            response = self.client.get('/api/v1.1/')
1026 52194c77 Christos Stavrakakis
        self.assertEqual(response.status_code, 200)
1027 52194c77 Christos Stavrakakis
        api_version = json.loads(response.content)['version']
1028 52194c77 Christos Stavrakakis
        self.assertEqual(api_version['id'], 'v1.1')
1029 52194c77 Christos Stavrakakis
        self.assertEqual(api_version['status'], 'CURRENT')