Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (45.3 kB)

1 adee02b8 Giorgos Verigakis
# Copyright 2011 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 53b1eea6 Giorgos Verigakis
from collections import defaultdict
37 8b01f7f3 Giorgos Verigakis
from email.utils import parsedate
38 ba6ded2a Giorgos Verigakis
from random import choice, randint, sample
39 8b01f7f3 Giorgos Verigakis
from time import mktime
40 8b01f7f3 Giorgos Verigakis
41 ccd0d474 Giorgos Verigakis
from django.conf import settings
42 a237869d Faidon Liambotis
from django.utils import simplejson as json
43 894f6b7e Dimitris Moraitis
from django.test import TestCase
44 894f6b7e Dimitris Moraitis
from django.test.client import Client
45 883de713 Giorgos Verigakis
46 968b3e04 Giorgos Verigakis
from synnefo.db.models import *
47 40777cc8 Giorgos Verigakis
from synnefo.logic.utils import get_rsapi_state
48 40777cc8 Giorgos Verigakis
49 ce55f211 Kostas Papadimitriou
import mock
50 08b079e2 Stavros Sachtouris
from synnefo.lib import astakos
51 08b079e2 Stavros Sachtouris
52 08b079e2 Stavros Sachtouris
from contextlib import contextmanager
53 08b079e2 Stavros Sachtouris
54 08b079e2 Stavros Sachtouris
# This is a hack to override astakos
55 08b079e2 Stavros Sachtouris
# The global variable ASTAKOS_PATCHED_USER keeps the name of
56 08b079e2 Stavros Sachtouris
# a dummy user that we provide through replacement of the
57 08b079e2 Stavros Sachtouris
# corresponding astakos function with a dummy function.
58 08b079e2 Stavros Sachtouris
ASTAKOS_PATCHED_USER = "user"
59 08b079e2 Stavros Sachtouris
60 08b079e2 Stavros Sachtouris
@contextmanager
61 08b079e2 Stavros Sachtouris
def astakos_user(user):
62 08b079e2 Stavros Sachtouris
    """
63 08b079e2 Stavros Sachtouris
    Context manager to mock astakos response.
64 08b079e2 Stavros Sachtouris

65 08b079e2 Stavros Sachtouris
    usage:
66 08b079e2 Stavros Sachtouris
    with astakos_user("user@user.com"):
67 08b079e2 Stavros Sachtouris
        .... make api calls .... get_user will act as user@user.com requested the api.
68 08b079e2 Stavros Sachtouris

69 08b079e2 Stavros Sachtouris
    """
70 08b079e2 Stavros Sachtouris
    from synnefo.lib import astakos
71 08b079e2 Stavros Sachtouris
    orig_method = astakos.get_user
72 08b079e2 Stavros Sachtouris
    
73 08b079e2 Stavros Sachtouris
    global ASTAKOS_PATCHED_USER
74 08b079e2 Stavros Sachtouris
    ASTAKOS_PATCHED_USER = user
75 08b079e2 Stavros Sachtouris
    def dummy_get_user(request, *args, **kwargs):
76 08b079e2 Stavros Sachtouris
        global ASTAKOS_PATCHED_USER
77 08b079e2 Stavros Sachtouris
        request.user = {'username': ASTAKOS_PATCHED_USER, 'groups': []}
78 08b079e2 Stavros Sachtouris
        request.user_uniq = ASTAKOS_PATCHED_USER
79 08b079e2 Stavros Sachtouris
    astakos.get_user = dummy_get_user
80 08b079e2 Stavros Sachtouris
    yield
81 08b079e2 Stavros Sachtouris
    astakos.get_user = orig_method
82 40777cc8 Giorgos Verigakis
83 40777cc8 Giorgos Verigakis
class AaiClient(Client):
84 40777cc8 Giorgos Verigakis
    def request(self, **request):
85 244c552b Giorgos Verigakis
        request['HTTP_X_AUTH_TOKEN'] = '0000'
86 40777cc8 Giorgos Verigakis
        return super(AaiClient, self).request(**request)
87 894f6b7e Dimitris Moraitis
88 08b079e2 Stavros Sachtouris
class NetworksTest(TestCase):
89 08b079e2 Stavros Sachtouris
    
90 08b079e2 Stavros Sachtouris
    fixtures = ['network_test_data']
91 08b079e2 Stavros Sachtouris
92 08b079e2 Stavros Sachtouris
    def test_attachments_list(self):
93 08b079e2 Stavros Sachtouris
        with astakos_user("admin@adminland.com"):
94 08b079e2 Stavros Sachtouris
            r = self.client.get("/api/v1.1/networks")
95 08b079e2 Stavros Sachtouris
            data = json.loads(r.content)
96 08b079e2 Stavros Sachtouris
            self.assertEqual(data["networks"]["values"][1]["name"], "network4admin")
97 08b079e2 Stavros Sachtouris
            #import pdb; pdb.set_trace()
98 08b079e2 Stavros Sachtouris
            self.assertEqual(len(data["networks"]["values"]), 2)
99 08b079e2 Stavros Sachtouris
        with astakos_user("user1@userland.com"):
100 08b079e2 Stavros Sachtouris
            r = self.client.get("/api/v1.1/networks")
101 08b079e2 Stavros Sachtouris
            data = json.loads(r.content)
102 08b079e2 Stavros Sachtouris
            self.assertEqual(data["networks"]["values"][1]["name"], "network4user1")
103 08b079e2 Stavros Sachtouris
            #import pdb; pdb.set_trace()
104 08b079e2 Stavros Sachtouris
            self.assertEqual(len(data["networks"]["values"]), 2)
105 08b079e2 Stavros Sachtouris
106 08b079e2 Stavros Sachtouris
    def test_create_network(self):
107 08b079e2 Stavros Sachtouris
        with astakos_user("admin@adminland.com"):
108 08b079e2 Stavros Sachtouris
            r = self.client.post("/api/v1.1/networks")
109 08b079e2 Stavros Sachtouris
110 08b079e2 Stavros Sachtouris
class ServersTest(TestCase):
111 08b079e2 Stavros Sachtouris
112 08b079e2 Stavros Sachtouris
    fixtures = ['network_test_data']
113 08b079e2 Stavros Sachtouris
114 08b079e2 Stavros Sachtouris
    def test_attachments_list(self):
115 08b079e2 Stavros Sachtouris
        with astakos_user("admin@adminland.com"):
116 08b079e2 Stavros Sachtouris
            r = self.client.get("/api/v1.1/servers")
117 08b079e2 Stavros Sachtouris
            data = json.loads(r.content)
118 08b079e2 Stavros Sachtouris
            self.assertEqual(data["servers"]["values"][0]["id"], 1001)
119 08b079e2 Stavros Sachtouris
            self.assertEqual(len(data["servers"]["values"]), 1)
120 08b079e2 Stavros Sachtouris
            r = self.client.get("/api/v1.1/servers/1001")
121 08b079e2 Stavros Sachtouris
122 883de713 Giorgos Verigakis
123 ce55f211 Kostas Papadimitriou
class TestQuota(TestCase):
124 ce55f211 Kostas Papadimitriou
125 ce55f211 Kostas Papadimitriou
    fixtures = ['users', 'flavors']
126 ce55f211 Kostas Papadimitriou
    astakos_response_user = 'test'
127 ce55f211 Kostas Papadimitriou
128 ce55f211 Kostas Papadimitriou
    def setUp(self):
129 ce55f211 Kostas Papadimitriou
130 ce55f211 Kostas Papadimitriou
        self.astakos_response_user = 'test'
131 ce55f211 Kostas Papadimitriou
        def get_user_mock(request, *Args, **kwargs):
132 ce55f211 Kostas Papadimitriou
            if request.META.get('HTTP_X_AUTH_TOKEN', None) == '0000':
133 ce55f211 Kostas Papadimitriou
                request.user_uniq = self.astakos_response_user
134 ce55f211 Kostas Papadimitriou
                request.user = {'uniq': self.astakos_response_user}
135 ce55f211 Kostas Papadimitriou
136 ce55f211 Kostas Papadimitriou
        def get_image_mock(request, *Args, **kwargs):
137 ce55f211 Kostas Papadimitriou
            return {'backend_id':'1234', 'location':'pithos://dummyimage',
138 ce55f211 Kostas Papadimitriou
                    'disk_format': 'plain'}
139 ce55f211 Kostas Papadimitriou
140 ce55f211 Kostas Papadimitriou
        self.rapi_patch = mock.patch('synnefo.logic.backend.rapi')
141 ce55f211 Kostas Papadimitriou
        self.rapi_mock = self.rapi_patch.start()
142 ce55f211 Kostas Papadimitriou
143 ce55f211 Kostas Papadimitriou
        self.pithos_patch = mock.patch('synnefo.api.util.get_image')
144 ce55f211 Kostas Papadimitriou
        self.pithos_mock = self.rapi_patch.start()
145 ce55f211 Kostas Papadimitriou
146 ce55f211 Kostas Papadimitriou
        # mock the astakos authentication function
147 ce55f211 Kostas Papadimitriou
        from synnefo.api import util
148 ce55f211 Kostas Papadimitriou
        util.get_user = get_user_mock
149 ce55f211 Kostas Papadimitriou
        util.get_image = get_image_mock
150 ce55f211 Kostas Papadimitriou
151 ce55f211 Kostas Papadimitriou
        settings.SKIP_SSH_VALIDATION = True
152 ce55f211 Kostas Papadimitriou
        self.client = AaiClient()
153 ce55f211 Kostas Papadimitriou
        self.user = 'test'
154 ce55f211 Kostas Papadimitriou
155 ce55f211 Kostas Papadimitriou
    def test_vms_quota(self):
156 ce55f211 Kostas Papadimitriou
        request = {
157 ce55f211 Kostas Papadimitriou
                    "server": {
158 ce55f211 Kostas Papadimitriou
                        "name": "new-server-test",
159 ce55f211 Kostas Papadimitriou
                        "userid": "test",
160 ce55f211 Kostas Papadimitriou
                        "imageRef": 1,
161 ce55f211 Kostas Papadimitriou
                        "flavorRef": 1,
162 ce55f211 Kostas Papadimitriou
                        "metadata": {
163 ce55f211 Kostas Papadimitriou
                            "My Server Name": "Apache1"
164 ce55f211 Kostas Papadimitriou
                        },
165 ce55f211 Kostas Papadimitriou
                        "personality": []
166 ce55f211 Kostas Papadimitriou
                    }
167 ce55f211 Kostas Papadimitriou
        }
168 ce55f211 Kostas Papadimitriou
169 ce55f211 Kostas Papadimitriou
        def create_server(for_user='test'):
170 ce55f211 Kostas Papadimitriou
            self.astakos_response_user = for_user
171 ce55f211 Kostas Papadimitriou
            return self.client.post('/api/v1.1/servers', json.dumps(request),
172 ce55f211 Kostas Papadimitriou
                content_type="application/json")
173 ce55f211 Kostas Papadimitriou
174 ce55f211 Kostas Papadimitriou
        def user_vms_count(user='test'):
175 ce55f211 Kostas Papadimitriou
            return VirtualMachine.objects.filter(userid=user).count()
176 ce55f211 Kostas Papadimitriou
177 ce55f211 Kostas Papadimitriou
        # admin sets max vms per user to 2
178 ce55f211 Kostas Papadimitriou
        settings.MAX_VMS_PER_USER = 2
179 ce55f211 Kostas Papadimitriou
        create_server()
180 ce55f211 Kostas Papadimitriou
        create_server()
181 ce55f211 Kostas Papadimitriou
        self.assertEqual(user_vms_count(), 2)
182 ce55f211 Kostas Papadimitriou
183 ce55f211 Kostas Papadimitriou
        # third creation fails
184 ce55f211 Kostas Papadimitriou
        resp = create_server()
185 ce55f211 Kostas Papadimitriou
        self.assertEqual(resp.status_code, 413)
186 ce55f211 Kostas Papadimitriou
        self.assertEqual(user_vms_count(), 2)
187 ce55f211 Kostas Papadimitriou
188 ce55f211 Kostas Papadimitriou
        # setting changed, no additional servers can get created
189 ce55f211 Kostas Papadimitriou
        settings.MAX_VMS_PER_USER = 1
190 ce55f211 Kostas Papadimitriou
        resp = create_server()
191 ce55f211 Kostas Papadimitriou
        self.assertEqual(resp.status_code, 413)
192 ce55f211 Kostas Papadimitriou
        self.assertEqual(user_vms_count(), 2)
193 ce55f211 Kostas Papadimitriou
194 ce55f211 Kostas Papadimitriou
        # admin wants test user to create 4 vms, now test user can create
195 ce55f211 Kostas Papadimitriou
        # one additional vm, but no more
196 ce55f211 Kostas Papadimitriou
        settings.VMS_USER_QUOTA = {'test':3}
197 ce55f211 Kostas Papadimitriou
        create_server()
198 ce55f211 Kostas Papadimitriou
        self.assertEqual(user_vms_count(), 3)
199 ce55f211 Kostas Papadimitriou
        resp = create_server()
200 ce55f211 Kostas Papadimitriou
        self.assertEqual(resp.status_code, 413)
201 ce55f211 Kostas Papadimitriou
        self.assertEqual(user_vms_count(), 3)
202 ce55f211 Kostas Papadimitriou
        # other users still apply to the global quota
203 ce55f211 Kostas Papadimitriou
        create_server("testuser2")
204 ce55f211 Kostas Papadimitriou
        self.assertEqual(user_vms_count("testuser2"), 1)
205 ce55f211 Kostas Papadimitriou
        resp = create_server("testuser2")
206 ce55f211 Kostas Papadimitriou
        self.assertEqual(resp.status_code, 413)
207 ce55f211 Kostas Papadimitriou
        self.assertEqual(user_vms_count("testuser2"), 1)
208 ce55f211 Kostas Papadimitriou
209 ce55f211 Kostas Papadimitriou
210 ce55f211 Kostas Papadimitriou
    def test_networks_quota(self):
211 ce55f211 Kostas Papadimitriou
212 ce55f211 Kostas Papadimitriou
        def create_network(for_user='test'):
213 ce55f211 Kostas Papadimitriou
            request = json.dumps({'network': {'name': 'user %s network' %
214 ce55f211 Kostas Papadimitriou
                for_user}})
215 ce55f211 Kostas Papadimitriou
            self.astakos_response_user = for_user
216 ce55f211 Kostas Papadimitriou
            return self.client.post('/api/v1.1/networks', request,
217 ce55f211 Kostas Papadimitriou
                content_type="application/json")
218 ce55f211 Kostas Papadimitriou
219 ce55f211 Kostas Papadimitriou
        def user_networks_count(user='test'):
220 ce55f211 Kostas Papadimitriou
            return Network.objects.filter(userid=user).count()
221 ce55f211 Kostas Papadimitriou
222 ce55f211 Kostas Papadimitriou
        settings.MAX_NETWORKS_PER_USER = 1
223 ce55f211 Kostas Papadimitriou
        create_network()
224 ce55f211 Kostas Papadimitriou
        self.assertEqual(user_networks_count(),1)
225 ce55f211 Kostas Papadimitriou
        resp = create_network()
226 ce55f211 Kostas Papadimitriou
        self.assertEqual(resp.status_code, 413)
227 ce55f211 Kostas Papadimitriou
        self.assertEqual(user_networks_count(), 1)
228 ce55f211 Kostas Papadimitriou
229 ce55f211 Kostas Papadimitriou
        settings.NETWORKS_USER_QUOTA = {'test':2}
230 ce55f211 Kostas Papadimitriou
        create_network()
231 ce55f211 Kostas Papadimitriou
        self.assertEqual(user_networks_count(),2)
232 ce55f211 Kostas Papadimitriou
        resp = create_network()
233 ce55f211 Kostas Papadimitriou
        self.assertEqual(resp.status_code, 413)
234 ce55f211 Kostas Papadimitriou
        self.assertEqual(user_networks_count(), 2)
235 ce55f211 Kostas Papadimitriou
236 ce55f211 Kostas Papadimitriou
        create_network("testuser2")
237 ce55f211 Kostas Papadimitriou
        self.assertEqual(user_networks_count("testuser2"),1)
238 ce55f211 Kostas Papadimitriou
        resp = create_network("testuser2")
239 ce55f211 Kostas Papadimitriou
        self.assertEqual(resp.status_code, 413)
240 ce55f211 Kostas Papadimitriou
        self.assertEqual(user_networks_count("testuser2"), 1)
241 ce55f211 Kostas Papadimitriou
242 ce55f211 Kostas Papadimitriou
        settings.GANETI_MAX_LINK_NUMBER = 3
243 ce55f211 Kostas Papadimitriou
        settings.NETWORKS_USER_QUOTA = {'test':10}
244 ce55f211 Kostas Papadimitriou
        resp = create_network()
245 ce55f211 Kostas Papadimitriou
        self.assertEqual(Network.objects.count(), 4)
246 ce55f211 Kostas Papadimitriou
        self.assertEqual('No networks available.' in resp.content, True)
247 ce55f211 Kostas Papadimitriou
        self.assertEqual(user_networks_count(), 2)
248 ce55f211 Kostas Papadimitriou
249 ce55f211 Kostas Papadimitriou
250 ce55f211 Kostas Papadimitriou
251 ce55f211 Kostas Papadimitriou
252 894f6b7e Dimitris Moraitis
class APITestCase(TestCase):
253 53481544 Vangelis Koukis
    fixtures = ['users', 'api_test_data']
254 d2e5f1d1 Markos Gogoulos
    test_server_id = 1001
255 d2e5f1d1 Markos Gogoulos
    test_image_id = 1
256 d2e5f1d1 Markos Gogoulos
    test_flavor_id = 1
257 a8acbbac Markos Gogoulos
    test_group_id = 1
258 d2e5f1d1 Markos Gogoulos
    test_wrong_server_id = 99999999
259 d2e5f1d1 Markos Gogoulos
    test_wrong_image_id = 99999999
260 d2e5f1d1 Markos Gogoulos
    test_wrong_flavor_id = 99999999
261 a8acbbac Markos Gogoulos
    test_wrong_group_id = 99999999
262 d2e5f1d1 Markos Gogoulos
    #make the testing with these id's
263 d2e5f1d1 Markos Gogoulos
264 894f6b7e Dimitris Moraitis
    def setUp(self):
265 40777cc8 Giorgos Verigakis
        self.client = AaiClient()
266 ccd0d474 Giorgos Verigakis
        settings.MAX_VMS_PER_USER = 5
267 c25cc9ec Vangelis Koukis
268 e646ebe5 Dimitris Moraitis
    def test_api_version(self):
269 883de713 Giorgos Verigakis
        """Check API version."""
270 aa197ee4 Vangelis Koukis
271 883de713 Giorgos Verigakis
        response = self.client.get('/api/v1.1/')
272 894f6b7e Dimitris Moraitis
        self.assertEqual(response.status_code, 200)
273 54c30633 Markos Gogoulos
        api_version = json.loads(response.content)['version']
274 883de713 Giorgos Verigakis
        self.assertEqual(api_version['id'], 'v1.1')
275 54c30633 Markos Gogoulos
        self.assertEqual(api_version['status'], 'CURRENT')
276 54c30633 Markos Gogoulos
277 e646ebe5 Dimitris Moraitis
    def test_server_list(self):
278 883de713 Giorgos Verigakis
        """Test if the expected list of servers is returned."""
279 aa197ee4 Vangelis Koukis
280 883de713 Giorgos Verigakis
        response = self.client.get('/api/v1.1/servers')
281 883de713 Giorgos Verigakis
        vms_from_api = json.loads(response.content)['servers']['values']
282 668c1361 Markos Gogoulos
        vms_from_db = VirtualMachine.objects.filter(deleted=False)
283 6781c0d0 Dimitris Moraitis
        self.assertEqual(len(vms_from_api), len(vms_from_db))
284 e646ebe5 Dimitris Moraitis
        self.assertTrue(response.status_code in [200, 203])
285 54c30633 Markos Gogoulos
        for vm_from_api in vms_from_api:
286 54c30633 Markos Gogoulos
            vm_from_db = VirtualMachine.objects.get(id=vm_from_api['id'])
287 54c30633 Markos Gogoulos
            self.assertEqual(vm_from_api['id'], vm_from_db.id)
288 54c30633 Markos Gogoulos
            self.assertEqual(vm_from_api['name'], vm_from_db.name)
289 54c30633 Markos Gogoulos
290 e646ebe5 Dimitris Moraitis
    def test_server_details(self):
291 883de713 Giorgos Verigakis
        """Test if the expected server is returned."""
292 aa197ee4 Vangelis Koukis
293 883de713 Giorgos Verigakis
        response = self.client.get('/api/v1.1/servers/%d' % self.test_server_id)
294 668c1361 Markos Gogoulos
        vm_from_api = json.loads(response.content)['server']
295 d2e5f1d1 Markos Gogoulos
        vm_from_db = VirtualMachine.objects.get(id=self.test_server_id)
296 b335768e Markos Gogoulos
        self.assertEqual(vm_from_api['flavorRef'], vm_from_db.flavor.id)
297 668c1361 Markos Gogoulos
        self.assertEqual(vm_from_api['hostId'], vm_from_db.hostid)
298 668c1361 Markos Gogoulos
        self.assertEqual(vm_from_api['id'], vm_from_db.id)
299 936afb7b Giorgos Verigakis
        self.assertEqual(vm_from_api['imageRef'], vm_from_db.imageid)
300 668c1361 Markos Gogoulos
        self.assertEqual(vm_from_api['name'], vm_from_db.name)
301 40777cc8 Giorgos Verigakis
        self.assertEqual(vm_from_api['status'], get_rsapi_state(vm_from_db))
302 883de713 Giorgos Verigakis
        self.assertTrue(response.status_code in [200, 203])
303 668c1361 Markos Gogoulos
304 e646ebe5 Dimitris Moraitis
    def test_servers_details(self):
305 883de713 Giorgos Verigakis
        """Test if the servers details are returned."""
306 aa197ee4 Vangelis Koukis
307 883de713 Giorgos Verigakis
        response = self.client.get('/api/v1.1/servers/detail')
308 ba15eb15 Vangelis Koukis
309 ba15eb15 Vangelis Koukis
        # Make sure both DB and API responses are sorted by id,
310 ba15eb15 Vangelis Koukis
        # to allow for 1-1 comparisons
311 ba15eb15 Vangelis Koukis
        vms_from_db = VirtualMachine.objects.filter(deleted=False).order_by('id')
312 ba15eb15 Vangelis Koukis
        vms_from_api = json.loads(response.content)['servers']['values']
313 ba15eb15 Vangelis Koukis
        vms_from_api = sorted(vms_from_api, key=lambda vm: vm['id'])
314 ba15eb15 Vangelis Koukis
        self.assertEqual(len(vms_from_db), len(vms_from_api))
315 ba15eb15 Vangelis Koukis
316 54c30633 Markos Gogoulos
        id_list = [vm.id for vm in vms_from_db]
317 685ab2b6 Markos Gogoulos
        number = 0
318 685ab2b6 Markos Gogoulos
        for vm_id in id_list:
319 ba15eb15 Vangelis Koukis
            vm_from_api = vms_from_api[number]
320 685ab2b6 Markos Gogoulos
            vm_from_db = VirtualMachine.objects.get(id=vm_id)
321 b335768e Markos Gogoulos
            self.assertEqual(vm_from_api['flavorRef'], vm_from_db.flavor.id)
322 685ab2b6 Markos Gogoulos
            self.assertEqual(vm_from_api['hostId'], vm_from_db.hostid)
323 685ab2b6 Markos Gogoulos
            self.assertEqual(vm_from_api['id'], vm_from_db.id)
324 936afb7b Giorgos Verigakis
            self.assertEqual(vm_from_api['imageRef'], vm_from_db.imageid)
325 685ab2b6 Markos Gogoulos
            self.assertEqual(vm_from_api['name'], vm_from_db.name)
326 40777cc8 Giorgos Verigakis
            self.assertEqual(vm_from_api['status'], get_rsapi_state(vm_from_db))
327 685ab2b6 Markos Gogoulos
            number += 1
328 54c30633 Markos Gogoulos
        for vm_from_api in vms_from_api:
329 54c30633 Markos Gogoulos
            vm_from_db = VirtualMachine.objects.get(id=vm_from_api['id'])
330 b335768e Markos Gogoulos
            self.assertEqual(vm_from_api['flavorRef'], vm_from_db.flavor.id)
331 54c30633 Markos Gogoulos
            self.assertEqual(vm_from_api['hostId'], vm_from_db.hostid)
332 54c30633 Markos Gogoulos
            self.assertEqual(vm_from_api['id'], vm_from_db.id)
333 936afb7b Giorgos Verigakis
            self.assertEqual(vm_from_api['imageRef'], vm_from_db.imageid)
334 54c30633 Markos Gogoulos
            self.assertEqual(vm_from_api['name'], vm_from_db.name)
335 40777cc8 Giorgos Verigakis
            self.assertEqual(vm_from_api['status'], get_rsapi_state(vm_from_db))
336 c25cc9ec Vangelis Koukis
        self.assertTrue(response.status_code in [200, 203])
337 685ab2b6 Markos Gogoulos
338 e646ebe5 Dimitris Moraitis
    def test_wrong_server(self):
339 883de713 Giorgos Verigakis
        """Test 404 response if server does not exist."""
340 aa197ee4 Vangelis Koukis
341 883de713 Giorgos Verigakis
        response = self.client.get('/api/v1.1/servers/%d' % self.test_wrong_server_id)
342 685ab2b6 Markos Gogoulos
        self.assertEqual(response.status_code, 404)
343 685ab2b6 Markos Gogoulos
344 e646ebe5 Dimitris Moraitis
    def test_create_server_empty(self):
345 883de713 Giorgos Verigakis
        """Test if the create server call returns a 400 badRequest if
346 883de713 Giorgos Verigakis
           no attributes are specified."""
347 aa197ee4 Vangelis Koukis
348 883de713 Giorgos Verigakis
        response = self.client.post('/api/v1.1/servers', {})
349 7de0c985 Dimitris Moraitis
        self.assertEqual(response.status_code, 400)
350 54c30633 Markos Gogoulos
351 e646ebe5 Dimitris Moraitis
    def test_create_server(self):
352 883de713 Giorgos Verigakis
        """Test if the create server call returns the expected response
353 883de713 Giorgos Verigakis
           if a valid request has been speficied."""
354 aa197ee4 Vangelis Koukis
355 7de0c985 Dimitris Moraitis
        request = {
356 285a1fa8 Dimitris Moraitis
                    "server": {
357 e646ebe5 Dimitris Moraitis
                        "name": "new-server-test",
358 244c552b Giorgos Verigakis
                        "userid": "test",
359 e646ebe5 Dimitris Moraitis
                        "imageRef": 1,
360 e646ebe5 Dimitris Moraitis
                        "flavorRef": 1,
361 e646ebe5 Dimitris Moraitis
                        "metadata": {
362 285a1fa8 Dimitris Moraitis
                            "My Server Name": "Apache1"
363 285a1fa8 Dimitris Moraitis
                        },
364 e646ebe5 Dimitris Moraitis
                        "personality": []
365 285a1fa8 Dimitris Moraitis
                    }
366 7de0c985 Dimitris Moraitis
        }
367 883de713 Giorgos Verigakis
        response = self.client.post('/api/v1.1/servers', json.dumps(request),
368 685ab2b6 Markos Gogoulos
                                    content_type='application/json')
369 285a1fa8 Dimitris Moraitis
        self.assertEqual(response.status_code, 202)
370 e646ebe5 Dimitris Moraitis
        #TODO: check response.content
371 e646ebe5 Dimitris Moraitis
        #TODO: check create server with wrong options (eg non existing flavor)
372 668c1361 Markos Gogoulos
373 e646ebe5 Dimitris Moraitis
    def test_server_polling(self):
374 883de713 Giorgos Verigakis
        """Test if the server polling works as expected."""
375 aa197ee4 Vangelis Koukis
376 883de713 Giorgos Verigakis
        response = self.client.get('/api/v1.1/servers/detail')
377 883de713 Giorgos Verigakis
        vms_from_api_initial = json.loads(response.content)['servers']['values']
378 8b01f7f3 Giorgos Verigakis
        ts = mktime(parsedate(response['Date']))
379 8b01f7f3 Giorgos Verigakis
        since = datetime.datetime.fromtimestamp(ts).isoformat() + 'Z'
380 8b01f7f3 Giorgos Verigakis
        response = self.client.get('/api/v1.1/servers/detail?changes-since=%s' % since)
381 34244492 Markos Gogoulos
        self.assertEqual(len(response.content), 0)
382 34244492 Markos Gogoulos
383 34244492 Markos Gogoulos
        #now create a machine. Then check if it is on the list
384 34244492 Markos Gogoulos
        request = {
385 34244492 Markos Gogoulos
                    "server": {
386 e646ebe5 Dimitris Moraitis
                        "name": "new-server-test",
387 e646ebe5 Dimitris Moraitis
                        "imageRef": 1,
388 e646ebe5 Dimitris Moraitis
                        "flavorRef": 1,
389 e646ebe5 Dimitris Moraitis
                        "metadata": {
390 34244492 Markos Gogoulos
                            "My Server Name": "Apache1"
391 34244492 Markos Gogoulos
                        },
392 e646ebe5 Dimitris Moraitis
                        "personality": []
393 34244492 Markos Gogoulos
                    }
394 34244492 Markos Gogoulos
        }
395 aa197ee4 Vangelis Koukis
396 883de713 Giorgos Verigakis
        path = '/api/v1.1/servers'
397 883de713 Giorgos Verigakis
        response = self.client.post(path, json.dumps(request), content_type='application/json')
398 34244492 Markos Gogoulos
        self.assertEqual(response.status_code, 202)
399 34244492 Markos Gogoulos
400 8b01f7f3 Giorgos Verigakis
        response = self.client.get('/api/v1.1/servers/detail?changes-since=%s' % since)
401 7f63ff66 Giorgos Verigakis
        self.assertEqual(response.status_code, 200)
402 009d3bf2 Giorgos Verigakis
        vms_from_api_after = json.loads(response.content)['servers']['values']
403 e646ebe5 Dimitris Moraitis
        #make sure the newly created server is included on the updated list
404 34244492 Markos Gogoulos
        self.assertEqual(len(vms_from_api_after), 1)
405 34244492 Markos Gogoulos
406 e646ebe5 Dimitris Moraitis
    def test_reboot_server(self):
407 883de713 Giorgos Verigakis
        """Test if the specified server is rebooted."""
408 883de713 Giorgos Verigakis
        request = {'reboot': {'type': 'HARD'}}
409 883de713 Giorgos Verigakis
        path = '/api/v1.1/servers/%d/action' % self.test_server_id
410 883de713 Giorgos Verigakis
        response = self.client.post(path, json.dumps(request), content_type='application/json')
411 685ab2b6 Markos Gogoulos
        self.assertEqual(response.status_code, 202)
412 f90c3d8c Vangelis Koukis
        # server id that does not exist
413 883de713 Giorgos Verigakis
        path = '/api/v1.1/servers/%d/action' % self.test_wrong_server_id
414 883de713 Giorgos Verigakis
        response = self.client.post(path, json.dumps(request), content_type='application/json')
415 685ab2b6 Markos Gogoulos
        self.assertEqual(response.status_code, 404)
416 668c1361 Markos Gogoulos
417 e646ebe5 Dimitris Moraitis
    def test_shutdown_server(self):
418 883de713 Giorgos Verigakis
        """Test if the specified server is shutdown."""
419 aa197ee4 Vangelis Koukis
420 883de713 Giorgos Verigakis
        request = {'shutdown': {}}
421 883de713 Giorgos Verigakis
        path = '/api/v1.1/servers/%d/action' % self.test_server_id
422 883de713 Giorgos Verigakis
        response = self.client.post(path, json.dumps(request), content_type='application/json')
423 685ab2b6 Markos Gogoulos
        self.assertEqual(response.status_code, 202)
424 f90c3d8c Vangelis Koukis
        # server id that does not exist
425 883de713 Giorgos Verigakis
        path = '/api/v1.1/servers/%d/action' % self.test_wrong_server_id
426 883de713 Giorgos Verigakis
        response = self.client.post(path, json.dumps(request), content_type='application/json')
427 685ab2b6 Markos Gogoulos
        self.assertEqual(response.status_code, 404)
428 668c1361 Markos Gogoulos
429 e646ebe5 Dimitris Moraitis
    def test_start_server(self):
430 883de713 Giorgos Verigakis
        """Test if the specified server is started."""
431 aa197ee4 Vangelis Koukis
432 883de713 Giorgos Verigakis
        request = {'start': {}}
433 883de713 Giorgos Verigakis
        path = '/api/v1.1/servers/%d/action' % self.test_server_id
434 883de713 Giorgos Verigakis
        response = self.client.post(path, json.dumps(request), content_type='application/json')
435 685ab2b6 Markos Gogoulos
        self.assertEqual(response.status_code, 202)
436 f90c3d8c Vangelis Koukis
        # server id that does not exist
437 883de713 Giorgos Verigakis
        path = '/api/v1.1/servers/%d/action' % self.test_wrong_server_id
438 883de713 Giorgos Verigakis
        response = self.client.post(path, json.dumps(request), content_type='application/json')
439 685ab2b6 Markos Gogoulos
        self.assertEqual(response.status_code, 404)
440 668c1361 Markos Gogoulos
441 e646ebe5 Dimitris Moraitis
    def test_delete_server(self):
442 883de713 Giorgos Verigakis
        """Test if the specified server is deleted."""
443 883de713 Giorgos Verigakis
        response = self.client.delete('/api/v1.1/servers/%d' % self.test_server_id)
444 883de713 Giorgos Verigakis
        self.assertEqual(response.status_code, 204)
445 f90c3d8c Vangelis Koukis
        # server id that does not exist
446 883de713 Giorgos Verigakis
        response = self.client.delete('/api/v1.1/servers/%d' % self.test_wrong_server_id)
447 685ab2b6 Markos Gogoulos
        self.assertEqual(response.status_code, 404)
448 668c1361 Markos Gogoulos
449 e646ebe5 Dimitris Moraitis
    def test_flavor_list(self):
450 883de713 Giorgos Verigakis
        """Test if the expected list of flavors is returned by."""
451 aa197ee4 Vangelis Koukis
452 883de713 Giorgos Verigakis
        response = self.client.get('/api/v1.1/flavors')
453 883de713 Giorgos Verigakis
        flavors_from_api = json.loads(response.content)['flavors']['values']
454 668c1361 Markos Gogoulos
        flavors_from_db = Flavor.objects.all()
455 668c1361 Markos Gogoulos
        self.assertEqual(len(flavors_from_api), len(flavors_from_db))
456 e646ebe5 Dimitris Moraitis
        self.assertTrue(response.status_code in [200, 203])
457 54c30633 Markos Gogoulos
        for flavor_from_api in flavors_from_api:
458 54c30633 Markos Gogoulos
            flavor_from_db = Flavor.objects.get(id=flavor_from_api['id'])
459 54c30633 Markos Gogoulos
            self.assertEqual(flavor_from_api['id'], flavor_from_db.id)
460 54c30633 Markos Gogoulos
            self.assertEqual(flavor_from_api['name'], flavor_from_db.name)
461 668c1361 Markos Gogoulos
462 e646ebe5 Dimitris Moraitis
    def test_flavors_details(self):
463 883de713 Giorgos Verigakis
        """Test if the flavors details are returned."""
464 aa197ee4 Vangelis Koukis
465 883de713 Giorgos Verigakis
        response = self.client.get('/api/v1.1/flavors/detail')
466 f3af8b40 Dimitris Moraitis
        flavors_from_db = Flavor.objects.all()
467 883de713 Giorgos Verigakis
        flavors_from_api = json.loads(response.content)['flavors']['values']
468 e646ebe5 Dimitris Moraitis
469 f3af8b40 Dimitris Moraitis
        # Assert that all flavors in the db appear inthe API call result
470 f3af8b40 Dimitris Moraitis
        for i in range(0, len(flavors_from_db)):
471 f3af8b40 Dimitris Moraitis
            flavor_from_api = flavors_from_api[i]
472 f3af8b40 Dimitris Moraitis
            flavor_from_db = Flavor.objects.get(id=flavors_from_db[i].id)
473 685ab2b6 Markos Gogoulos
            self.assertEqual(flavor_from_api['cpu'], flavor_from_db.cpu)
474 685ab2b6 Markos Gogoulos
            self.assertEqual(flavor_from_api['id'], flavor_from_db.id)
475 685ab2b6 Markos Gogoulos
            self.assertEqual(flavor_from_api['disk'], flavor_from_db.disk)
476 685ab2b6 Markos Gogoulos
            self.assertEqual(flavor_from_api['name'], flavor_from_db.name)
477 685ab2b6 Markos Gogoulos
            self.assertEqual(flavor_from_api['ram'], flavor_from_db.ram)
478 f3af8b40 Dimitris Moraitis
479 e646ebe5 Dimitris Moraitis
        # Assert that all flavors returned by the API also exist in the db
480 54c30633 Markos Gogoulos
        for flavor_from_api in flavors_from_api:
481 54c30633 Markos Gogoulos
            flavor_from_db = Flavor.objects.get(id=flavor_from_api['id'])
482 54c30633 Markos Gogoulos
            self.assertEqual(flavor_from_api['cpu'], flavor_from_db.cpu)
483 54c30633 Markos Gogoulos
            self.assertEqual(flavor_from_api['id'], flavor_from_db.id)
484 54c30633 Markos Gogoulos
            self.assertEqual(flavor_from_api['disk'], flavor_from_db.disk)
485 54c30633 Markos Gogoulos
            self.assertEqual(flavor_from_api['name'], flavor_from_db.name)
486 54c30633 Markos Gogoulos
            self.assertEqual(flavor_from_api['ram'], flavor_from_db.ram)
487 7de0c985 Dimitris Moraitis
488 e646ebe5 Dimitris Moraitis
        # Check if we have the right status_code
489 e646ebe5 Dimitris Moraitis
        self.assertTrue(response.status_code in [200, 203])
490 7de0c985 Dimitris Moraitis
491 e646ebe5 Dimitris Moraitis
    def test_flavor_details(self):
492 883de713 Giorgos Verigakis
        """Test if the expected flavor is returned."""
493 aa197ee4 Vangelis Koukis
494 883de713 Giorgos Verigakis
        response = self.client.get('/api/v1.1/flavors/%d' % self.test_flavor_id)
495 668c1361 Markos Gogoulos
        flavor_from_api = json.loads(response.content)['flavor']
496 d2e5f1d1 Markos Gogoulos
        flavor_from_db = Flavor.objects.get(id=self.test_flavor_id)
497 668c1361 Markos Gogoulos
        self.assertEqual(flavor_from_api['cpu'], flavor_from_db.cpu)
498 668c1361 Markos Gogoulos
        self.assertEqual(flavor_from_api['id'], flavor_from_db.id)
499 668c1361 Markos Gogoulos
        self.assertEqual(flavor_from_api['disk'], flavor_from_db.disk)
500 668c1361 Markos Gogoulos
        self.assertEqual(flavor_from_api['name'], flavor_from_db.name)
501 668c1361 Markos Gogoulos
        self.assertEqual(flavor_from_api['ram'], flavor_from_db.ram)
502 e646ebe5 Dimitris Moraitis
        self.assertTrue(response.status_code in [200, 203])
503 668c1361 Markos Gogoulos
504 e646ebe5 Dimitris Moraitis
    def test_wrong_flavor(self):
505 883de713 Giorgos Verigakis
        """Test 404 result when requesting a flavor that does not exist."""
506 aa197ee4 Vangelis Koukis
507 883de713 Giorgos Verigakis
        response = self.client.get('/api/v1.1/flavors/%d' % self.test_wrong_flavor_id)
508 ffffd5fe Markos Gogoulos
        self.assertTrue(response.status_code in [404, 503])
509 668c1361 Markos Gogoulos
510 e646ebe5 Dimitris Moraitis
    def test_image_list(self):
511 883de713 Giorgos Verigakis
        """Test if the expected list of images is returned by the API."""
512 aa197ee4 Vangelis Koukis
513 883de713 Giorgos Verigakis
        response = self.client.get('/api/v1.1/images')
514 883de713 Giorgos Verigakis
        images_from_api = json.loads(response.content)['images']['values']
515 668c1361 Markos Gogoulos
        images_from_db = Image.objects.all()
516 668c1361 Markos Gogoulos
        self.assertEqual(len(images_from_api), len(images_from_db))
517 e646ebe5 Dimitris Moraitis
        self.assertTrue(response.status_code in [200, 203])
518 54c30633 Markos Gogoulos
        for image_from_api in images_from_api:
519 54c30633 Markos Gogoulos
            image_from_db = Image.objects.get(id=image_from_api['id'])
520 54c30633 Markos Gogoulos
            self.assertEqual(image_from_api['id'], image_from_db.id)
521 54c30633 Markos Gogoulos
            self.assertEqual(image_from_api['name'], image_from_db.name)
522 668c1361 Markos Gogoulos
523 e646ebe5 Dimitris Moraitis
    def test_wrong_image(self):
524 883de713 Giorgos Verigakis
        """Test 404 result if a non existent image is requested."""
525 aa197ee4 Vangelis Koukis
526 883de713 Giorgos Verigakis
        response = self.client.get('/api/v1.1/images/%d' % self.test_wrong_image_id)
527 685ab2b6 Markos Gogoulos
        self.assertEqual(response.status_code, 404)
528 73469364 Markos Gogoulos
529 e646ebe5 Dimitris Moraitis
    def test_server_metadata(self):
530 883de713 Giorgos Verigakis
        """Test server's metadata (add, edit)."""
531 aa197ee4 Vangelis Koukis
532 883de713 Giorgos Verigakis
        key = 'name'
533 883de713 Giorgos Verigakis
        request = {'meta': {key: 'a fancy name'}}
534 aa197ee4 Vangelis Koukis
535 883de713 Giorgos Verigakis
        path = '/api/v1.1/servers/%d/meta/%s' % (self.test_server_id, key)
536 883de713 Giorgos Verigakis
        response = self.client.put(path, json.dumps(request), content_type='application/json')
537 883de713 Giorgos Verigakis
        self.assertEqual(response.status_code, 201)
538 a8acbbac Markos Gogoulos
539 a8acbbac Markos Gogoulos
540 968b3e04 Giorgos Verigakis
def create_flavors(n=1):
541 968b3e04 Giorgos Verigakis
    for i in range(n):
542 968b3e04 Giorgos Verigakis
        Flavor.objects.create(
543 968b3e04 Giorgos Verigakis
            cpu=randint(1, 4),
544 80da6543 Giorgos Verigakis
            ram=randint(1, 8) * 512,
545 80da6543 Giorgos Verigakis
            disk=randint(1, 40))
546 968b3e04 Giorgos Verigakis
547 c25cc9ec Vangelis Koukis
548 968b3e04 Giorgos Verigakis
def create_images(n=1):
549 968b3e04 Giorgos Verigakis
    for i in range(n):
550 968b3e04 Giorgos Verigakis
        Image.objects.create(
551 968b3e04 Giorgos Verigakis
            name='Image %d' % (i + 1),
552 968b3e04 Giorgos Verigakis
            state='ACTIVE',
553 244c552b Giorgos Verigakis
            owner='test')
554 968b3e04 Giorgos Verigakis
555 c25cc9ec Vangelis Koukis
556 53b1eea6 Giorgos Verigakis
def create_image_metadata(n=1):
557 53b1eea6 Giorgos Verigakis
    images = Image.objects.all()
558 53b1eea6 Giorgos Verigakis
    for i in range(n):
559 53b1eea6 Giorgos Verigakis
        ImageMetadata.objects.create(
560 53b1eea6 Giorgos Verigakis
            meta_key='Key%d' % (i + 1),
561 53b1eea6 Giorgos Verigakis
            meta_value='Value %d' % (i + 1),
562 c25cc9ec Vangelis Koukis
            image=choice(images))
563 c25cc9ec Vangelis Koukis
564 53b1eea6 Giorgos Verigakis
565 968b3e04 Giorgos Verigakis
def create_servers(n=1):
566 968b3e04 Giorgos Verigakis
    flavors = Flavor.objects.all()
567 968b3e04 Giorgos Verigakis
    images = Image.objects.all()
568 968b3e04 Giorgos Verigakis
    for i in range(n):
569 968b3e04 Giorgos Verigakis
        VirtualMachine.objects.create(
570 968b3e04 Giorgos Verigakis
            name='Server %d' % (i + 1),
571 244c552b Giorgos Verigakis
            owner='test',
572 936afb7b Giorgos Verigakis
            imageid=choice(images).id,
573 968b3e04 Giorgos Verigakis
            hostid=str(i),
574 968b3e04 Giorgos Verigakis
            flavor=choice(flavors))
575 968b3e04 Giorgos Verigakis
576 c25cc9ec Vangelis Koukis
577 968b3e04 Giorgos Verigakis
def create_server_metadata(n=1):
578 968b3e04 Giorgos Verigakis
    servers = VirtualMachine.objects.all()
579 968b3e04 Giorgos Verigakis
    for i in range(n):
580 968b3e04 Giorgos Verigakis
        VirtualMachineMetadata.objects.create(
581 968b3e04 Giorgos Verigakis
            meta_key='Key%d' % (i + 1),
582 968b3e04 Giorgos Verigakis
            meta_value='Value %d' % (i + 1),
583 c25cc9ec Vangelis Koukis
            vm=choice(servers))
584 968b3e04 Giorgos Verigakis
585 968b3e04 Giorgos Verigakis
586 53b1eea6 Giorgos Verigakis
class AssertInvariant(object):
587 53b1eea6 Giorgos Verigakis
    def __init__(self, callable, *args, **kwargs):
588 53b1eea6 Giorgos Verigakis
        self.callable = callable
589 53b1eea6 Giorgos Verigakis
        self.args = args
590 53b1eea6 Giorgos Verigakis
        self.kwargs = kwargs
591 aa197ee4 Vangelis Koukis
592 53b1eea6 Giorgos Verigakis
    def __enter__(self):
593 53b1eea6 Giorgos Verigakis
        self.value = self.callable(*self.args, **self.kwargs)
594 53b1eea6 Giorgos Verigakis
        return self.value
595 aa197ee4 Vangelis Koukis
596 53b1eea6 Giorgos Verigakis
    def __exit__(self, type, value, tb):
597 53b1eea6 Giorgos Verigakis
        assert self.value == self.callable(*self.args, **self.kwargs)
598 53b1eea6 Giorgos Verigakis
599 53b1eea6 Giorgos Verigakis
600 968b3e04 Giorgos Verigakis
class BaseTestCase(TestCase):
601 968b3e04 Giorgos Verigakis
    FLAVORS = 1
602 968b3e04 Giorgos Verigakis
    IMAGES = 1
603 968b3e04 Giorgos Verigakis
    SERVERS = 1
604 968b3e04 Giorgos Verigakis
    SERVER_METADATA = 0
605 53b1eea6 Giorgos Verigakis
    IMAGE_METADATA = 0
606 53481544 Vangelis Koukis
    fixtures = ['users']
607 aa197ee4 Vangelis Koukis
608 883de713 Giorgos Verigakis
    def setUp(self):
609 40777cc8 Giorgos Verigakis
        self.client = AaiClient()
610 968b3e04 Giorgos Verigakis
        create_flavors(self.FLAVORS)
611 968b3e04 Giorgos Verigakis
        create_images(self.IMAGES)
612 53b1eea6 Giorgos Verigakis
        create_image_metadata(self.IMAGE_METADATA)
613 968b3e04 Giorgos Verigakis
        create_servers(self.SERVERS)
614 968b3e04 Giorgos Verigakis
        create_server_metadata(self.SERVER_METADATA)
615 aa197ee4 Vangelis Koukis
616 968b3e04 Giorgos Verigakis
    def assertFault(self, response, status_code, name):
617 968b3e04 Giorgos Verigakis
        self.assertEqual(response.status_code, status_code)
618 968b3e04 Giorgos Verigakis
        fault = json.loads(response.content)
619 968b3e04 Giorgos Verigakis
        self.assertEqual(fault.keys(), [name])
620 aa197ee4 Vangelis Koukis
621 968b3e04 Giorgos Verigakis
    def assertBadRequest(self, response):
622 968b3e04 Giorgos Verigakis
        self.assertFault(response, 400, 'badRequest')
623 968b3e04 Giorgos Verigakis
624 968b3e04 Giorgos Verigakis
    def assertItemNotFound(self, response):
625 968b3e04 Giorgos Verigakis
        self.assertFault(response, 404, 'itemNotFound')
626 aa197ee4 Vangelis Koukis
627 111f6d5b Giorgos Verigakis
    def list_images(self, detail=False):
628 111f6d5b Giorgos Verigakis
        path = '/api/v1.1/images'
629 111f6d5b Giorgos Verigakis
        if detail:
630 111f6d5b Giorgos Verigakis
            path += '/detail'
631 111f6d5b Giorgos Verigakis
        response = self.client.get(path)
632 111f6d5b Giorgos Verigakis
        self.assertTrue(response.status_code in (200, 203))
633 111f6d5b Giorgos Verigakis
        reply = json.loads(response.content)
634 111f6d5b Giorgos Verigakis
        self.assertEqual(reply.keys(), ['images'])
635 111f6d5b Giorgos Verigakis
        self.assertEqual(reply['images'].keys(), ['values'])
636 111f6d5b Giorgos Verigakis
        return reply['images']['values']
637 aa197ee4 Vangelis Koukis
638 53b1eea6 Giorgos Verigakis
    def list_metadata(self, path):
639 53b1eea6 Giorgos Verigakis
        response = self.client.get(path)
640 968b3e04 Giorgos Verigakis
        self.assertTrue(response.status_code in (200, 203))
641 968b3e04 Giorgos Verigakis
        reply = json.loads(response.content)
642 968b3e04 Giorgos Verigakis
        self.assertEqual(reply.keys(), ['metadata'])
643 968b3e04 Giorgos Verigakis
        self.assertEqual(reply['metadata'].keys(), ['values'])
644 968b3e04 Giorgos Verigakis
        return reply['metadata']['values']
645 aa197ee4 Vangelis Koukis
646 53b1eea6 Giorgos Verigakis
    def list_server_metadata(self, server_id):
647 53b1eea6 Giorgos Verigakis
        path = '/api/v1.1/servers/%d/meta' % server_id
648 53b1eea6 Giorgos Verigakis
        return self.list_metadata(path)
649 aa197ee4 Vangelis Koukis
650 53b1eea6 Giorgos Verigakis
    def list_image_metadata(self, image_id):
651 53b1eea6 Giorgos Verigakis
        path = '/api/v1.1/images/%d/meta' % image_id
652 53b1eea6 Giorgos Verigakis
        return self.list_metadata(path)
653 aa197ee4 Vangelis Koukis
654 53b1eea6 Giorgos Verigakis
    def update_metadata(self, path, metadata):
655 ba6ded2a Giorgos Verigakis
        data = json.dumps({'metadata': metadata})
656 ba6ded2a Giorgos Verigakis
        response = self.client.post(path, data, content_type='application/json')
657 968b3e04 Giorgos Verigakis
        self.assertEqual(response.status_code, 201)
658 968b3e04 Giorgos Verigakis
        reply = json.loads(response.content)
659 968b3e04 Giorgos Verigakis
        self.assertEqual(reply.keys(), ['metadata'])
660 968b3e04 Giorgos Verigakis
        return reply['metadata']
661 aa197ee4 Vangelis Koukis
662 53b1eea6 Giorgos Verigakis
    def update_server_metadata(self, server_id, metadata):
663 53b1eea6 Giorgos Verigakis
        path = '/api/v1.1/servers/%d/meta' % server_id
664 53b1eea6 Giorgos Verigakis
        return self.update_metadata(path, metadata)
665 aa197ee4 Vangelis Koukis
666 53b1eea6 Giorgos Verigakis
    def update_image_metadata(self, image_id, metadata):
667 53b1eea6 Giorgos Verigakis
        path = '/api/v1.1/images/%d/meta' % image_id
668 53b1eea6 Giorgos Verigakis
        return self.update_metadata(path, metadata)
669 aa197ee4 Vangelis Koukis
670 53b1eea6 Giorgos Verigakis
    def create_server_meta(self, server_id, meta):
671 53b1eea6 Giorgos Verigakis
        key = meta.keys()[0]
672 53b1eea6 Giorgos Verigakis
        path = '/api/v1.1/servers/%d/meta/%s' % (server_id, key)
673 53b1eea6 Giorgos Verigakis
        data = json.dumps({'meta': meta})
674 53b1eea6 Giorgos Verigakis
        response = self.client.put(path, data, content_type='application/json')
675 53b1eea6 Giorgos Verigakis
        self.assertEqual(response.status_code, 201)
676 53b1eea6 Giorgos Verigakis
        reply = json.loads(response.content)
677 53b1eea6 Giorgos Verigakis
        self.assertEqual(reply.keys(), ['meta'])
678 53b1eea6 Giorgos Verigakis
        response_meta = reply['meta']
679 53b1eea6 Giorgos Verigakis
        self.assertEqual(response_meta, meta)
680 aa197ee4 Vangelis Koukis
681 53b1eea6 Giorgos Verigakis
    def get_all_server_metadata(self):
682 53b1eea6 Giorgos Verigakis
        metadata = defaultdict(dict)
683 53b1eea6 Giorgos Verigakis
        for m in VirtualMachineMetadata.objects.all():
684 53b1eea6 Giorgos Verigakis
            metadata[m.vm.id][m.meta_key] = m.meta_value
685 53b1eea6 Giorgos Verigakis
        return metadata
686 aa197ee4 Vangelis Koukis
687 53b1eea6 Giorgos Verigakis
    def get_all_image_metadata(self):
688 53b1eea6 Giorgos Verigakis
        metadata = defaultdict(dict)
689 53b1eea6 Giorgos Verigakis
        for m in ImageMetadata.objects.all():
690 53b1eea6 Giorgos Verigakis
            metadata[m.image.id][m.meta_key] = m.meta_value
691 53b1eea6 Giorgos Verigakis
        return metadata
692 aa197ee4 Vangelis Koukis
693 13b954b0 Giorgos Verigakis
    def list_networks(self, detail=False):
694 13b954b0 Giorgos Verigakis
        path = '/api/v1.1/networks'
695 13b954b0 Giorgos Verigakis
        if detail:
696 13b954b0 Giorgos Verigakis
            path += '/detail'
697 13b954b0 Giorgos Verigakis
        response = self.client.get(path)
698 13b954b0 Giorgos Verigakis
        self.assertTrue(response.status_code in (200, 203))
699 13b954b0 Giorgos Verigakis
        reply = json.loads(response.content)
700 13b954b0 Giorgos Verigakis
        self.assertEqual(reply.keys(), ['networks'])
701 13b954b0 Giorgos Verigakis
        self.assertEqual(reply['networks'].keys(), ['values'])
702 13b954b0 Giorgos Verigakis
        return reply['networks']['values']
703 aa197ee4 Vangelis Koukis
704 13b954b0 Giorgos Verigakis
    def create_network(self, name):
705 08b079e2 Stavros Sachtouris
        with astakos_user("admin@adminland.com"):
706 08b079e2 Stavros Sachtouris
            path = '/api/v1.1/networks'
707 08b079e2 Stavros Sachtouris
            data = json.dumps({'network': {'name': name}})
708 08b079e2 Stavros Sachtouris
            response = self.client.post(path, data, content_type='application/json')
709 08b079e2 Stavros Sachtouris
            self.assertEqual(response.status_code, 202)
710 08b079e2 Stavros Sachtouris
            reply = json.loads(response.content)
711 08b079e2 Stavros Sachtouris
            self.assertEqual(reply.keys(), ['network'])
712 08b079e2 Stavros Sachtouris
            return reply
713 aa197ee4 Vangelis Koukis
714 b19653d1 Giorgos Verigakis
    def get_network_details(self, network_id):
715 207b70d5 Giorgos Verigakis
        path = '/api/v1.1/networks/%s' % network_id
716 13b954b0 Giorgos Verigakis
        response = self.client.get(path)
717 13b954b0 Giorgos Verigakis
        self.assertEqual(response.status_code, 200)
718 13b954b0 Giorgos Verigakis
        reply = json.loads(response.content)
719 13b954b0 Giorgos Verigakis
        self.assertEqual(reply.keys(), ['network'])
720 13b954b0 Giorgos Verigakis
        return reply['network']
721 aa197ee4 Vangelis Koukis
722 b19653d1 Giorgos Verigakis
    def update_network_name(self, network_id, new_name):
723 207b70d5 Giorgos Verigakis
        path = '/api/v1.1/networks/%s' % network_id
724 13b954b0 Giorgos Verigakis
        data = json.dumps({'network': {'name': new_name}})
725 13b954b0 Giorgos Verigakis
        response = self.client.put(path, data, content_type='application/json')
726 13b954b0 Giorgos Verigakis
        self.assertEqual(response.status_code, 204)
727 aa197ee4 Vangelis Koukis
728 b19653d1 Giorgos Verigakis
    def delete_network(self, network_id):
729 207b70d5 Giorgos Verigakis
        path = '/api/v1.1/networks/%s' % network_id
730 13b954b0 Giorgos Verigakis
        response = self.client.delete(path)
731 13b954b0 Giorgos Verigakis
        self.assertEqual(response.status_code, 204)
732 aa197ee4 Vangelis Koukis
733 b19653d1 Giorgos Verigakis
    def add_to_network(self, network_id, server_id):
734 207b70d5 Giorgos Verigakis
        path = '/api/v1.1/networks/%s/action' % network_id
735 13b954b0 Giorgos Verigakis
        data = json.dumps({'add': {'serverRef': server_id}})
736 13b954b0 Giorgos Verigakis
        response = self.client.post(path, data, content_type='application/json')
737 13b954b0 Giorgos Verigakis
        self.assertEqual(response.status_code, 202)
738 aa197ee4 Vangelis Koukis
739 b19653d1 Giorgos Verigakis
    def remove_from_network(self, network_id, server_id):
740 207b70d5 Giorgos Verigakis
        path = '/api/v1.1/networks/%s/action' % network_id
741 13b954b0 Giorgos Verigakis
        data = json.dumps({'remove': {'serverRef': server_id}})
742 13b954b0 Giorgos Verigakis
        response = self.client.post(path, data, content_type='application/json')
743 13b954b0 Giorgos Verigakis
        self.assertEqual(response.status_code, 202)
744 13b954b0 Giorgos Verigakis
745 13b954b0 Giorgos Verigakis
746 13b954b0 Giorgos Verigakis
def popdict(l, **kwargs):
747 13b954b0 Giorgos Verigakis
    """Pops a dict from list `l` based on the predicates given as `kwargs`."""
748 aa197ee4 Vangelis Koukis
749 13b954b0 Giorgos Verigakis
    for i in range(len(l)):
750 13b954b0 Giorgos Verigakis
        item = l[i]
751 13b954b0 Giorgos Verigakis
        match = True
752 13b954b0 Giorgos Verigakis
        for key, val in kwargs.items():
753 13b954b0 Giorgos Verigakis
            if item[key] != val:
754 13b954b0 Giorgos Verigakis
                match = False
755 13b954b0 Giorgos Verigakis
                break
756 13b954b0 Giorgos Verigakis
        if match:
757 13b954b0 Giorgos Verigakis
            del l[i]
758 13b954b0 Giorgos Verigakis
            return item
759 13b954b0 Giorgos Verigakis
    return None
760 53b1eea6 Giorgos Verigakis
761 53b1eea6 Giorgos Verigakis
762 111f6d5b Giorgos Verigakis
class ListImages(BaseTestCase):
763 111f6d5b Giorgos Verigakis
    IMAGES = 10
764 aa197ee4 Vangelis Koukis
765 111f6d5b Giorgos Verigakis
    def test_list_images(self):
766 111f6d5b Giorgos Verigakis
        images = self.list_images()
767 111f6d5b Giorgos Verigakis
        keys = set(['id', 'name'])
768 111f6d5b Giorgos Verigakis
        for img in Image.objects.all():
769 13b954b0 Giorgos Verigakis
            image = popdict(images, id=img.id)
770 111f6d5b Giorgos Verigakis
            self.assertTrue(image is not None)
771 111f6d5b Giorgos Verigakis
            self.assertEqual(set(image.keys()), keys)
772 111f6d5b Giorgos Verigakis
            self.assertEqual(image['id'], img.id)
773 111f6d5b Giorgos Verigakis
            self.assertEqual(image['name'], img.name)
774 111f6d5b Giorgos Verigakis
        self.assertEqual(images, [])
775 aa197ee4 Vangelis Koukis
776 111f6d5b Giorgos Verigakis
    def test_list_images_detail(self):
777 111f6d5b Giorgos Verigakis
        images = self.list_images(detail=True)
778 111f6d5b Giorgos Verigakis
        keys = set(['id', 'name', 'updated', 'created', 'status', 'progress'])
779 111f6d5b Giorgos Verigakis
        for img in Image.objects.all():
780 13b954b0 Giorgos Verigakis
            image = popdict(images, id=img.id)
781 111f6d5b Giorgos Verigakis
            self.assertTrue(image is not None)
782 111f6d5b Giorgos Verigakis
            self.assertEqual(set(image.keys()), keys)
783 111f6d5b Giorgos Verigakis
            self.assertEqual(image['id'], img.id)
784 111f6d5b Giorgos Verigakis
            self.assertEqual(image['name'], img.name)
785 111f6d5b Giorgos Verigakis
            self.assertEqual(image['status'], img.state)
786 111f6d5b Giorgos Verigakis
            self.assertEqual(image['progress'], 100 if img.state == 'ACTIVE' else 0)
787 111f6d5b Giorgos Verigakis
        self.assertEqual(images, [])
788 111f6d5b Giorgos Verigakis
789 111f6d5b Giorgos Verigakis
790 53b1eea6 Giorgos Verigakis
class ListServerMetadata(BaseTestCase):
791 53b1eea6 Giorgos Verigakis
    SERVERS = 5
792 53b1eea6 Giorgos Verigakis
    SERVER_METADATA = 100
793 aa197ee4 Vangelis Koukis
794 53b1eea6 Giorgos Verigakis
    def test_list_metadata(self):
795 53b1eea6 Giorgos Verigakis
        with AssertInvariant(self.get_all_server_metadata) as metadata:
796 53b1eea6 Giorgos Verigakis
            for vm in VirtualMachine.objects.all():
797 53b1eea6 Giorgos Verigakis
                response_metadata = self.list_server_metadata(vm.id)
798 53b1eea6 Giorgos Verigakis
                self.assertEqual(response_metadata, metadata[vm.id])
799 aa197ee4 Vangelis Koukis
800 53b1eea6 Giorgos Verigakis
    def test_invalid_server(self):
801 53b1eea6 Giorgos Verigakis
        with AssertInvariant(self.get_all_server_metadata):
802 53b1eea6 Giorgos Verigakis
            response = self.client.get('/api/v1.1/servers/0/meta')
803 53b1eea6 Giorgos Verigakis
            self.assertItemNotFound(response)
804 53b1eea6 Giorgos Verigakis
805 53b1eea6 Giorgos Verigakis
806 53b1eea6 Giorgos Verigakis
class UpdateServerMetadata(BaseTestCase):
807 53b1eea6 Giorgos Verigakis
    SERVER_METADATA = 10
808 aa197ee4 Vangelis Koukis
809 968b3e04 Giorgos Verigakis
    def test_update_metadata(self):
810 53b1eea6 Giorgos Verigakis
        metadata = self.get_all_server_metadata()
811 53b1eea6 Giorgos Verigakis
        server_id = choice(metadata.keys())
812 ba6ded2a Giorgos Verigakis
        new_metadata = {}
813 53b1eea6 Giorgos Verigakis
        for key in sample(metadata[server_id].keys(), 3):
814 ba6ded2a Giorgos Verigakis
            new_metadata[key] = 'New %s value' % key
815 7cc3c7d9 Giorgos Verigakis
        response_metadata = self.update_server_metadata(server_id,
816 7cc3c7d9 Giorgos Verigakis
                                                        new_metadata)
817 53b1eea6 Giorgos Verigakis
        metadata[server_id].update(new_metadata)
818 7cc3c7d9 Giorgos Verigakis
        self.assertEqual(response_metadata, metadata[server_id])
819 53b1eea6 Giorgos Verigakis
        self.assertEqual(metadata, self.get_all_server_metadata())
820 38d247df Kostas Papadimitriou
821 968b3e04 Giorgos Verigakis
    def test_invalid_data(self):
822 53b1eea6 Giorgos Verigakis
        with AssertInvariant(self.get_all_server_metadata) as metadata:
823 53b1eea6 Giorgos Verigakis
            server_id = choice(metadata.keys())
824 53b1eea6 Giorgos Verigakis
            path = '/api/v1.1/servers/%d/meta' % server_id
825 53b1eea6 Giorgos Verigakis
            response = self.client.post(path, 'metadata', content_type='application/json')
826 53b1eea6 Giorgos Verigakis
            self.assertBadRequest(response)
827 aa197ee4 Vangelis Koukis
828 ba6ded2a Giorgos Verigakis
    def test_invalid_server(self):
829 53b1eea6 Giorgos Verigakis
        with AssertInvariant(self.get_all_server_metadata):
830 53b1eea6 Giorgos Verigakis
            path = '/api/v1.1/servers/0/meta'
831 53b1eea6 Giorgos Verigakis
            data = json.dumps({'metadata': {'Key1': 'A Value'}})
832 53b1eea6 Giorgos Verigakis
            response = self.client.post(path, data, content_type='application/json')
833 53b1eea6 Giorgos Verigakis
            self.assertItemNotFound(response)
834 968b3e04 Giorgos Verigakis
835 968b3e04 Giorgos Verigakis
836 968b3e04 Giorgos Verigakis
class GetServerMetadataItem(BaseTestCase):
837 53b1eea6 Giorgos Verigakis
    SERVERS = 5
838 53b1eea6 Giorgos Verigakis
    SERVER_METADATA = 100
839 aa197ee4 Vangelis Koukis
840 968b3e04 Giorgos Verigakis
    def test_get_metadata_item(self):
841 53b1eea6 Giorgos Verigakis
        with AssertInvariant(self.get_all_server_metadata) as metadata:
842 53b1eea6 Giorgos Verigakis
            server_id = choice(metadata.keys())
843 53b1eea6 Giorgos Verigakis
            key = choice(metadata[server_id].keys())
844 53b1eea6 Giorgos Verigakis
            path = '/api/v1.1/servers/%d/meta/%s' % (server_id, key)
845 53b1eea6 Giorgos Verigakis
            response = self.client.get(path)
846 53b1eea6 Giorgos Verigakis
            self.assertTrue(response.status_code in (200, 203))
847 53b1eea6 Giorgos Verigakis
            reply = json.loads(response.content)
848 53b1eea6 Giorgos Verigakis
            self.assertEqual(reply['meta'], {key: metadata[server_id][key]})
849 aa197ee4 Vangelis Koukis
850 ba6ded2a Giorgos Verigakis
    def test_invalid_key(self):
851 53b1eea6 Giorgos Verigakis
        with AssertInvariant(self.get_all_server_metadata) as metadata:
852 53b1eea6 Giorgos Verigakis
            server_id = choice(metadata.keys())
853 53b1eea6 Giorgos Verigakis
            response = self.client.get('/api/v1.1/servers/%d/meta/foo' % server_id)
854 53b1eea6 Giorgos Verigakis
            self.assertItemNotFound(response)
855 aa197ee4 Vangelis Koukis
856 ba6ded2a Giorgos Verigakis
    def test_invalid_server(self):
857 53b1eea6 Giorgos Verigakis
        with AssertInvariant(self.get_all_server_metadata):
858 53b1eea6 Giorgos Verigakis
            response = self.client.get('/api/v1.1/servers/0/meta/foo')
859 53b1eea6 Giorgos Verigakis
            self.assertItemNotFound(response)
860 968b3e04 Giorgos Verigakis
861 968b3e04 Giorgos Verigakis
862 968b3e04 Giorgos Verigakis
class CreateServerMetadataItem(BaseTestCase):
863 ba6ded2a Giorgos Verigakis
    SERVER_METADATA = 10
864 aa197ee4 Vangelis Koukis
865 968b3e04 Giorgos Verigakis
    def test_create_metadata(self):
866 53b1eea6 Giorgos Verigakis
        metadata = self.get_all_server_metadata()
867 53b1eea6 Giorgos Verigakis
        server_id = choice(metadata.keys())
868 ba6ded2a Giorgos Verigakis
        meta = {'Foo': 'Bar'}
869 53b1eea6 Giorgos Verigakis
        self.create_server_meta(server_id, meta)
870 53b1eea6 Giorgos Verigakis
        metadata[server_id].update(meta)
871 53b1eea6 Giorgos Verigakis
        self.assertEqual(metadata, self.get_all_server_metadata())
872 aa197ee4 Vangelis Koukis
873 ba6ded2a Giorgos Verigakis
    def test_update_metadata(self):
874 53b1eea6 Giorgos Verigakis
        metadata = self.get_all_server_metadata()
875 53b1eea6 Giorgos Verigakis
        server_id = choice(metadata.keys())
876 53b1eea6 Giorgos Verigakis
        key = choice(metadata[server_id].keys())
877 ba6ded2a Giorgos Verigakis
        meta = {key: 'New Value'}
878 53b1eea6 Giorgos Verigakis
        self.create_server_meta(server_id, meta)
879 53b1eea6 Giorgos Verigakis
        metadata[server_id].update(meta)
880 53b1eea6 Giorgos Verigakis
        self.assertEqual(metadata, self.get_all_server_metadata())
881 aa197ee4 Vangelis Koukis
882 968b3e04 Giorgos Verigakis
    def test_invalid_server(self):
883 53b1eea6 Giorgos Verigakis
        with AssertInvariant(self.get_all_server_metadata):
884 53b1eea6 Giorgos Verigakis
            path = '/api/v1.1/servers/0/meta/foo'
885 53b1eea6 Giorgos Verigakis
            data = json.dumps({'meta': {'foo': 'bar'}})
886 53b1eea6 Giorgos Verigakis
            response = self.client.put(path, data, content_type='application/json')
887 53b1eea6 Giorgos Verigakis
            self.assertItemNotFound(response)
888 aa197ee4 Vangelis Koukis
889 968b3e04 Giorgos Verigakis
    def test_invalid_key(self):
890 7317d130 Giorgos Verigakis
        with AssertInvariant(self.get_all_server_metadata) as metadata:
891 7317d130 Giorgos Verigakis
            server_id = choice(metadata.keys())
892 7317d130 Giorgos Verigakis
            path = '/api/v1.1/servers/%d/meta/baz' % server_id
893 53b1eea6 Giorgos Verigakis
            data = json.dumps({'meta': {'foo': 'bar'}})
894 53b1eea6 Giorgos Verigakis
            response = self.client.put(path, data, content_type='application/json')
895 53b1eea6 Giorgos Verigakis
            self.assertBadRequest(response)
896 aa197ee4 Vangelis Koukis
897 968b3e04 Giorgos Verigakis
    def test_invalid_data(self):
898 7317d130 Giorgos Verigakis
        with AssertInvariant(self.get_all_server_metadata) as metadata:
899 7317d130 Giorgos Verigakis
            server_id = choice(metadata.keys())
900 7317d130 Giorgos Verigakis
            path = '/api/v1.1/servers/%d/meta/foo' % server_id
901 53b1eea6 Giorgos Verigakis
            response = self.client.put(path, 'meta', content_type='application/json')
902 53b1eea6 Giorgos Verigakis
            self.assertBadRequest(response)
903 968b3e04 Giorgos Verigakis
904 968b3e04 Giorgos Verigakis
905 968b3e04 Giorgos Verigakis
class DeleteServerMetadataItem(BaseTestCase):
906 ba6ded2a Giorgos Verigakis
    SERVER_METADATA = 10
907 aa197ee4 Vangelis Koukis
908 968b3e04 Giorgos Verigakis
    def test_delete_metadata(self):
909 53b1eea6 Giorgos Verigakis
        metadata = self.get_all_server_metadata()
910 53b1eea6 Giorgos Verigakis
        server_id = choice(metadata.keys())
911 53b1eea6 Giorgos Verigakis
        key = choice(metadata[server_id].keys())
912 53b1eea6 Giorgos Verigakis
        path = '/api/v1.1/servers/%d/meta/%s' % (server_id, key)
913 ba6ded2a Giorgos Verigakis
        response = self.client.delete(path)
914 968b3e04 Giorgos Verigakis
        self.assertEqual(response.status_code, 204)
915 53b1eea6 Giorgos Verigakis
        metadata[server_id].pop(key)
916 53b1eea6 Giorgos Verigakis
        self.assertEqual(metadata, self.get_all_server_metadata())
917 aa197ee4 Vangelis Koukis
918 968b3e04 Giorgos Verigakis
    def test_invalid_server(self):
919 53b1eea6 Giorgos Verigakis
        with AssertInvariant(self.get_all_server_metadata):
920 53b1eea6 Giorgos Verigakis
            response = self.client.delete('/api/v1.1/servers/9/meta/Key1')
921 53b1eea6 Giorgos Verigakis
            self.assertItemNotFound(response)
922 aa197ee4 Vangelis Koukis
923 968b3e04 Giorgos Verigakis
    def test_invalid_key(self):
924 53b1eea6 Giorgos Verigakis
        with AssertInvariant(self.get_all_server_metadata) as metadata:
925 53b1eea6 Giorgos Verigakis
            server_id = choice(metadata.keys())
926 53b1eea6 Giorgos Verigakis
            path = '/api/v1.1/servers/%d/meta/foo' % server_id
927 53b1eea6 Giorgos Verigakis
            response = self.client.delete(path)
928 53b1eea6 Giorgos Verigakis
            self.assertItemNotFound(response)
929 53b1eea6 Giorgos Verigakis
930 53b1eea6 Giorgos Verigakis
931 53b1eea6 Giorgos Verigakis
class ListImageMetadata(BaseTestCase):
932 53b1eea6 Giorgos Verigakis
    IMAGES = 5
933 53b1eea6 Giorgos Verigakis
    IMAGE_METADATA = 100
934 53b1eea6 Giorgos Verigakis
935 53b1eea6 Giorgos Verigakis
    def test_list_metadata(self):
936 53b1eea6 Giorgos Verigakis
        with AssertInvariant(self.get_all_image_metadata) as metadata:
937 53b1eea6 Giorgos Verigakis
            for image in Image.objects.all():
938 53b1eea6 Giorgos Verigakis
                response_metadata = self.list_image_metadata(image.id)
939 53b1eea6 Giorgos Verigakis
                self.assertEqual(response_metadata, metadata[image.id])
940 53b1eea6 Giorgos Verigakis
941 53b1eea6 Giorgos Verigakis
    def test_invalid_image(self):
942 53b1eea6 Giorgos Verigakis
        with AssertInvariant(self.get_all_image_metadata):
943 53b1eea6 Giorgos Verigakis
            response = self.client.get('/api/v1.1/images/0/meta')
944 53b1eea6 Giorgos Verigakis
            self.assertItemNotFound(response)
945 53b1eea6 Giorgos Verigakis
946 c25cc9ec Vangelis Koukis
947 53b1eea6 Giorgos Verigakis
class UpdateImageMetadata(BaseTestCase):
948 53b1eea6 Giorgos Verigakis
    IMAGE_METADATA = 10
949 53b1eea6 Giorgos Verigakis
950 53b1eea6 Giorgos Verigakis
    def test_update_metadata(self):
951 53b1eea6 Giorgos Verigakis
        metadata = self.get_all_image_metadata()
952 53b1eea6 Giorgos Verigakis
        image_id = choice(metadata.keys())
953 53b1eea6 Giorgos Verigakis
        new_metadata = {}
954 53b1eea6 Giorgos Verigakis
        for key in sample(metadata[image_id].keys(), 3):
955 53b1eea6 Giorgos Verigakis
            new_metadata[key] = 'New %s value' % key
956 53b1eea6 Giorgos Verigakis
        response_metadata = self.update_image_metadata(image_id, new_metadata)
957 53b1eea6 Giorgos Verigakis
        metadata[image_id].update(new_metadata)
958 7cc3c7d9 Giorgos Verigakis
        self.assertEqual(response_metadata, metadata[image_id])
959 53b1eea6 Giorgos Verigakis
        self.assertEqual(metadata, self.get_all_image_metadata())
960 38d247df Kostas Papadimitriou
961 53b1eea6 Giorgos Verigakis
    def test_invalid_data(self):
962 53b1eea6 Giorgos Verigakis
        with AssertInvariant(self.get_all_image_metadata) as metadata:
963 53b1eea6 Giorgos Verigakis
            image_id = choice(metadata.keys())
964 53b1eea6 Giorgos Verigakis
            path = '/api/v1.1/images/%d/meta' % image_id
965 53b1eea6 Giorgos Verigakis
            response = self.client.post(path, 'metadata', content_type='application/json')
966 53b1eea6 Giorgos Verigakis
            self.assertBadRequest(response)
967 53b1eea6 Giorgos Verigakis
968 53b1eea6 Giorgos Verigakis
    def test_invalid_server(self):
969 53b1eea6 Giorgos Verigakis
        with AssertInvariant(self.get_all_image_metadata):
970 53b1eea6 Giorgos Verigakis
            path = '/api/v1.1/images/0/meta'
971 53b1eea6 Giorgos Verigakis
            data = json.dumps({'metadata': {'Key1': 'A Value'}})
972 53b1eea6 Giorgos Verigakis
            response = self.client.post(path, data, content_type='application/json')
973 53b1eea6 Giorgos Verigakis
            self.assertItemNotFound(response)
974 4cf8adf8 Vangelis Koukis
975 4cf8adf8 Vangelis Koukis
976 4cf8adf8 Vangelis Koukis
class ServerVNCConsole(BaseTestCase):
977 4cf8adf8 Vangelis Koukis
    SERVERS = 1
978 4cf8adf8 Vangelis Koukis
979 4cf8adf8 Vangelis Koukis
    def test_not_active_server(self):
980 4cf8adf8 Vangelis Koukis
        """Test console req for server not in ACTIVE state returns badRequest"""
981 4cf8adf8 Vangelis Koukis
        server_id = choice(VirtualMachine.objects.all()).id
982 4cf8adf8 Vangelis Koukis
        path = '/api/v1.1/servers/%d/action' % server_id
983 4cf8adf8 Vangelis Koukis
        data = json.dumps({'console': {'type': 'vnc'}})
984 4cf8adf8 Vangelis Koukis
        response = self.client.post(path, data, content_type='application/json')
985 4cf8adf8 Vangelis Koukis
        self.assertBadRequest(response)
986 4cf8adf8 Vangelis Koukis
987 4cf8adf8 Vangelis Koukis
    def test_active_server(self):
988 4cf8adf8 Vangelis Koukis
        """Test console req for ACTIVE server"""
989 4cf8adf8 Vangelis Koukis
        server_id = choice(VirtualMachine.objects.all()).id
990 4cf8adf8 Vangelis Koukis
        # FIXME: Start the server properly, instead of tampering with the DB
991 4cf8adf8 Vangelis Koukis
        vm = choice(VirtualMachine.objects.all())
992 4cf8adf8 Vangelis Koukis
        vm.operstate = 'STARTED'
993 4cf8adf8 Vangelis Koukis
        vm.save()
994 4cf8adf8 Vangelis Koukis
        server_id = vm.id
995 c25cc9ec Vangelis Koukis
996 4cf8adf8 Vangelis Koukis
        path = '/api/v1.1/servers/%d/action' % server_id
997 4cf8adf8 Vangelis Koukis
        data = json.dumps({'console': {'type': 'vnc'}})
998 4cf8adf8 Vangelis Koukis
        response = self.client.post(path, data, content_type='application/json')
999 4cf8adf8 Vangelis Koukis
        self.assertEqual(response.status_code, 200)
1000 4cf8adf8 Vangelis Koukis
        reply = json.loads(response.content)
1001 529178b1 Giorgos Verigakis
        self.assertEqual(reply.keys(), ['console'])
1002 529178b1 Giorgos Verigakis
        console = reply['console']
1003 529178b1 Giorgos Verigakis
        self.assertEqual(console['type'], 'vnc')
1004 529178b1 Giorgos Verigakis
        self.assertEqual(set(console.keys()), set(['type', 'host', 'port', 'password']))
1005 1428a464 Georgios Gousios
1006 13b954b0 Giorgos Verigakis
1007 1428a464 Georgios Gousios
class AaiTestCase(TestCase):
1008 53481544 Vangelis Koukis
    fixtures = ['users', 'api_test_data', 'auth_test_data']
1009 1428a464 Georgios Gousios
    apibase = '/api/v1.1'
1010 1428a464 Georgios Gousios
1011 aa519091 Georgios Gousios
    def setUp(self):
1012 aa519091 Georgios Gousios
        self.client = Client()
1013 1428a464 Georgios Gousios
1014 1428a464 Georgios Gousios
    def test_fail_oapi_auth(self):
1015 1428a464 Georgios Gousios
        """ test authentication from not registered user using OpenAPI
1016 1428a464 Georgios Gousios
        """
1017 1428a464 Georgios Gousios
        response = self.client.get(self.apibase + '/servers', {},
1018 1428a464 Georgios Gousios
                                   **{'X-Auth-User': 'notme',
1019 1428a464 Georgios Gousios
                                      'X-Auth-Key': '0xdeadbabe',
1020 c25cc9ec Vangelis Koukis
                                      'TEST-AAI': 'true'})
1021 1428a464 Georgios Gousios
        self.assertEquals(response.status_code, 401)
1022 1428a464 Georgios Gousios
1023 1428a464 Georgios Gousios
    def test_oapi_auth(self):
1024 1428a464 Georgios Gousios
        """authentication with user registration
1025 1428a464 Georgios Gousios
        """
1026 1428a464 Georgios Gousios
        response = self.client.get(self.apibase + '/index.html', {},
1027 1428a464 Georgios Gousios
                                   **{'X-Auth-User': 'testdbuser',
1028 1428a464 Georgios Gousios
                                      'X-Auth-Key': 'test@synnefo.gr',
1029 c25cc9ec Vangelis Koukis
                                      'TEST-AAI': 'true'})
1030 1428a464 Georgios Gousios
        self.assertEquals(response.status_code, 204)
1031 1428a464 Georgios Gousios
        self.assertNotEqual(response['X-Auth-Token'], None)
1032 1428a464 Georgios Gousios
        self.assertEquals(response['X-Server-Management-Url'], '')
1033 1428a464 Georgios Gousios
        self.assertEquals(response['X-Storage-Url'], '')
1034 1428a464 Georgios Gousios
        self.assertEquals(response['X-CDN-Management-Url'], '')
1035 aa519091 Georgios Gousios
1036 aa519091 Georgios Gousios
    def test_unauthorized_call(self):
1037 aa519091 Georgios Gousios
        request = {'reboot': {'type': 'HARD'}}
1038 aa519091 Georgios Gousios
        path = '/api/v1.1/servers/%d/action' % 1
1039 6a0e1a00 Georgios Gousios
        response = self.client.post(path, json.dumps(request),
1040 6a0e1a00 Georgios Gousios
                                    content_type='application/json')
1041 865fd434 Vangelis Koukis
        self.assertEquals(response.status_code, 401)
1042 865fd434 Vangelis Koukis
1043 865fd434 Vangelis Koukis
1044 13b954b0 Giorgos Verigakis
class ListNetworks(BaseTestCase):
1045 13b954b0 Giorgos Verigakis
    SERVERS = 5
1046 aa197ee4 Vangelis Koukis
1047 13b954b0 Giorgos Verigakis
    def setUp(self):
1048 13b954b0 Giorgos Verigakis
        BaseTestCase.setUp(self)
1049 38d247df Kostas Papadimitriou
1050 a3992827 Giorgos Verigakis
        for i in range(5):
1051 a3992827 Giorgos Verigakis
            self.create_network('net%d' % i)
1052 38d247df Kostas Papadimitriou
1053 13b954b0 Giorgos Verigakis
        machines = VirtualMachine.objects.all()
1054 13b954b0 Giorgos Verigakis
        for network in Network.objects.all():
1055 d54cd53a Giorgos Verigakis
            n = randint(0, self.SERVERS - 1)
1056 d44c236b Giorgos Verigakis
            for machine in sample(machines, n):
1057 d44c236b Giorgos Verigakis
                machine.nics.create(network=network)
1058 38d247df Kostas Papadimitriou
1059 13b954b0 Giorgos Verigakis
    def test_list_networks(self):
1060 13b954b0 Giorgos Verigakis
        networks = self.list_networks()
1061 13b954b0 Giorgos Verigakis
        for net in Network.objects.all():
1062 207b70d5 Giorgos Verigakis
            net_id = str(net.id) if not net.public else 'public'
1063 207b70d5 Giorgos Verigakis
            network = popdict(networks, id=net_id)
1064 b19653d1 Giorgos Verigakis
            self.assertEqual(network['name'], net.name)
1065 13b954b0 Giorgos Verigakis
        self.assertEqual(networks, [])
1066 aa197ee4 Vangelis Koukis
1067 13b954b0 Giorgos Verigakis
    def test_list_networks_detail(self):
1068 13b954b0 Giorgos Verigakis
        networks = self.list_networks(detail=True)
1069 13b954b0 Giorgos Verigakis
        for net in Network.objects.all():
1070 207b70d5 Giorgos Verigakis
            net_id = str(net.id) if not net.public else 'public'
1071 207b70d5 Giorgos Verigakis
            network = popdict(networks, id=net_id)
1072 b19653d1 Giorgos Verigakis
            self.assertEqual(network['name'], net.name)
1073 13b954b0 Giorgos Verigakis
            machines = set(vm.id for vm in net.machines.all())
1074 13b954b0 Giorgos Verigakis
            self.assertEqual(set(network['servers']['values']), machines)
1075 13b954b0 Giorgos Verigakis
        self.assertEqual(networks, [])
1076 13b954b0 Giorgos Verigakis
1077 13b954b0 Giorgos Verigakis
1078 13b954b0 Giorgos Verigakis
class CreateNetwork(BaseTestCase):
1079 13b954b0 Giorgos Verigakis
    def test_create_network(self):
1080 d44c236b Giorgos Verigakis
        before = self.list_networks()
1081 13b954b0 Giorgos Verigakis
        self.create_network('net')
1082 d44c236b Giorgos Verigakis
        after = self.list_networks()
1083 d44c236b Giorgos Verigakis
        self.assertEqual(len(after) - len(before), 1)
1084 d44c236b Giorgos Verigakis
        found = False
1085 d44c236b Giorgos Verigakis
        for network in after:
1086 d44c236b Giorgos Verigakis
            if network['name'] == 'net':
1087 d44c236b Giorgos Verigakis
                found = True
1088 d44c236b Giorgos Verigakis
                break
1089 d44c236b Giorgos Verigakis
        self.assertTrue(found)
1090 13b954b0 Giorgos Verigakis
1091 13b954b0 Giorgos Verigakis
1092 13b954b0 Giorgos Verigakis
class GetNetworkDetails(BaseTestCase):
1093 13b954b0 Giorgos Verigakis
    SERVERS = 5
1094 c25cc9ec Vangelis Koukis
1095 13b954b0 Giorgos Verigakis
    def test_get_network_details(self):
1096 64938cb0 Giorgos Verigakis
        name = 'net'
1097 64938cb0 Giorgos Verigakis
        self.create_network(name)
1098 38d247df Kostas Papadimitriou
1099 13b954b0 Giorgos Verigakis
        servers = VirtualMachine.objects.all()
1100 64938cb0 Giorgos Verigakis
        network = Network.objects.all()[1]
1101 aa197ee4 Vangelis Koukis
1102 b19653d1 Giorgos Verigakis
        net = self.get_network_details(network.id)
1103 64938cb0 Giorgos Verigakis
        self.assertEqual(net['name'], name)
1104 13b954b0 Giorgos Verigakis
        self.assertEqual(net['servers']['values'], [])
1105 aa197ee4 Vangelis Koukis
1106 13b954b0 Giorgos Verigakis
        server_id = choice(servers).id
1107 b19653d1 Giorgos Verigakis
        self.add_to_network(network.id, server_id)
1108 b19653d1 Giorgos Verigakis
        net = self.get_network_details(network.id)
1109 b19653d1 Giorgos Verigakis
        self.assertEqual(net['name'], network.name)
1110 13b954b0 Giorgos Verigakis
1111 13b954b0 Giorgos Verigakis
1112 13b954b0 Giorgos Verigakis
class UpdateNetworkName(BaseTestCase):
1113 13b954b0 Giorgos Verigakis
    def test_update_network_name(self):
1114 207b70d5 Giorgos Verigakis
        name = 'net'
1115 207b70d5 Giorgos Verigakis
        self.create_network(name)
1116 13b954b0 Giorgos Verigakis
        networks = self.list_networks(detail=True)
1117 207b70d5 Giorgos Verigakis
        priv = [net for net in networks if net['id'] != 'public']
1118 207b70d5 Giorgos Verigakis
        network = choice(priv)
1119 b19653d1 Giorgos Verigakis
        network_id = network['id']
1120 b19653d1 Giorgos Verigakis
        new_name = network['name'] + '_2'
1121 b19653d1 Giorgos Verigakis
        self.update_network_name(network_id, new_name)
1122 aa197ee4 Vangelis Koukis
1123 13b954b0 Giorgos Verigakis
        network['name'] = new_name
1124 197398e2 Giorgos Verigakis
        del network['updated']
1125 197398e2 Giorgos Verigakis
        net = self.get_network_details(network_id)
1126 197398e2 Giorgos Verigakis
        del net['updated']
1127 197398e2 Giorgos Verigakis
        self.assertEqual(net, network)
1128 13b954b0 Giorgos Verigakis
1129 13b954b0 Giorgos Verigakis
1130 13b954b0 Giorgos Verigakis
class DeleteNetwork(BaseTestCase):
1131 13b954b0 Giorgos Verigakis
    def test_delete_network(self):
1132 64938cb0 Giorgos Verigakis
        for i in range(5):
1133 64938cb0 Giorgos Verigakis
            self.create_network('net%d' % i)
1134 38d247df Kostas Papadimitriou
1135 13b954b0 Giorgos Verigakis
        networks = self.list_networks()
1136 207b70d5 Giorgos Verigakis
        priv = [net for net in networks if net['id'] != 'public']
1137 207b70d5 Giorgos Verigakis
        network = choice(priv)
1138 b19653d1 Giorgos Verigakis
        network_id = network['id']
1139 b19653d1 Giorgos Verigakis
        self.delete_network(network_id)
1140 38d247df Kostas Papadimitriou
1141 d44c236b Giorgos Verigakis
        net = self.get_network_details(network_id)
1142 d44c236b Giorgos Verigakis
        self.assertEqual(net['status'], 'DELETED')
1143 aa197ee4 Vangelis Koukis
1144 207b70d5 Giorgos Verigakis
        priv.remove(network)
1145 207b70d5 Giorgos Verigakis
        networks = self.list_networks()
1146 207b70d5 Giorgos Verigakis
        new_priv = [net for net in networks if net['id'] != 'public']
1147 207b70d5 Giorgos Verigakis
        self.assertEqual(priv, new_priv)
1148 13b954b0 Giorgos Verigakis
1149 13b954b0 Giorgos Verigakis
1150 13b954b0 Giorgos Verigakis
class NetworkActions(BaseTestCase):
1151 13b954b0 Giorgos Verigakis
    SERVERS = 20
1152 aa197ee4 Vangelis Koukis
1153 13b954b0 Giorgos Verigakis
    def test_add_remove_server(self):
1154 64938cb0 Giorgos Verigakis
        self.create_network('net')
1155 38d247df Kostas Papadimitriou
1156 13b954b0 Giorgos Verigakis
        server_ids = [vm.id for vm in VirtualMachine.objects.all()]
1157 64938cb0 Giorgos Verigakis
        network = self.list_networks(detail=True)[1]
1158 b19653d1 Giorgos Verigakis
        network_id = network['id']
1159 aa197ee4 Vangelis Koukis
1160 13b954b0 Giorgos Verigakis
        to_add = set(sample(server_ids, 10))
1161 13b954b0 Giorgos Verigakis
        for server_id in to_add:
1162 b19653d1 Giorgos Verigakis
            self.add_to_network(network_id, server_id)
1163 38d247df Kostas Papadimitriou
1164 13b954b0 Giorgos Verigakis
        to_remove = set(sample(to_add, 5))
1165 13b954b0 Giorgos Verigakis
        for server_id in to_remove:
1166 b19653d1 Giorgos Verigakis
            self.remove_from_network(network_id, server_id)