Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / api / test / servers.py @ 07602322

History | View | Annotate | Download (20 kB)

1 039e3e61 Christos Stavrakakis
# Copyright 2012 GRNET S.A. All rights reserved.
2 039e3e61 Christos Stavrakakis
#
3 039e3e61 Christos Stavrakakis
# Redistribution and use in source and binary forms, with or
4 039e3e61 Christos Stavrakakis
# without modification, are permitted provided that the following
5 039e3e61 Christos Stavrakakis
# conditions are met:
6 039e3e61 Christos Stavrakakis
#
7 039e3e61 Christos Stavrakakis
#   1. Redistributions of source code must retain the above
8 039e3e61 Christos Stavrakakis
#      copyright notice, this list of conditions and the following
9 039e3e61 Christos Stavrakakis
#      disclaimer.
10 039e3e61 Christos Stavrakakis
#
11 039e3e61 Christos Stavrakakis
#   2. Redistributions in binary form must reproduce the above
12 039e3e61 Christos Stavrakakis
#      copyright notice, this list of conditions and the following
13 039e3e61 Christos Stavrakakis
#      disclaimer in the documentation and/or other materials
14 039e3e61 Christos Stavrakakis
#      provided with the distribution.
15 039e3e61 Christos Stavrakakis
#
16 039e3e61 Christos Stavrakakis
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 039e3e61 Christos Stavrakakis
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 039e3e61 Christos Stavrakakis
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 039e3e61 Christos Stavrakakis
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 039e3e61 Christos Stavrakakis
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 039e3e61 Christos Stavrakakis
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 039e3e61 Christos Stavrakakis
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 039e3e61 Christos Stavrakakis
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 039e3e61 Christos Stavrakakis
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 039e3e61 Christos Stavrakakis
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 039e3e61 Christos Stavrakakis
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 039e3e61 Christos Stavrakakis
# POSSIBILITY OF SUCH DAMAGE.
28 039e3e61 Christos Stavrakakis
#
29 039e3e61 Christos Stavrakakis
# The views and conclusions contained in the software and
30 039e3e61 Christos Stavrakakis
# documentation are those of the authors and should not be
31 039e3e61 Christos Stavrakakis
# interpreted as representing official policies, either expressed
32 039e3e61 Christos Stavrakakis
# or implied, of GRNET S.A.
33 039e3e61 Christos Stavrakakis
34 039e3e61 Christos Stavrakakis
import json
35 039e3e61 Christos Stavrakakis
36 184a2a8c Christos Stavrakakis
from snf_django.utils.testing import BaseAPITest, mocked_quotaholder
37 039e3e61 Christos Stavrakakis
from synnefo.db.models import VirtualMachine, VirtualMachineMetadata
38 039e3e61 Christos Stavrakakis
from synnefo.db import models_factory as mfactory
39 039e3e61 Christos Stavrakakis
from synnefo.logic.utils import get_rsapi_state
40 a26e5a4d Georgios D. Tsoukalas
from synnefo.cyclades_settings import cyclades_services
41 a26e5a4d Georgios D. Tsoukalas
from synnefo.lib.services import get_service_path
42 a26e5a4d Georgios D. Tsoukalas
from synnefo.lib import join_urls
43 039e3e61 Christos Stavrakakis
44 039e3e61 Christos Stavrakakis
from mock import patch
45 039e3e61 Christos Stavrakakis
46 039e3e61 Christos Stavrakakis
47 a26e5a4d Georgios D. Tsoukalas
class ComputeAPITest(BaseAPITest):
48 a26e5a4d Georgios D. Tsoukalas
    def setUp(self, *args, **kwargs):
49 a26e5a4d Georgios D. Tsoukalas
        super(ComputeAPITest, self).setUp(*args, **kwargs)
50 a26e5a4d Georgios D. Tsoukalas
        self.compute_path = get_service_path(cyclades_services, 'compute',
51 a26e5a4d Georgios D. Tsoukalas
                                             version='v2.0')
52 a26e5a4d Georgios D. Tsoukalas
    def myget(self, path, *args, **kwargs):
53 a26e5a4d Georgios D. Tsoukalas
        path = join_urls(self.compute_path, path)
54 a26e5a4d Georgios D. Tsoukalas
        return self.get(path, *args, **kwargs)
55 a26e5a4d Georgios D. Tsoukalas
56 a26e5a4d Georgios D. Tsoukalas
    def myput(self, path, *args, **kwargs):
57 a26e5a4d Georgios D. Tsoukalas
        path = join_urls(self.compute_path, path)
58 a26e5a4d Georgios D. Tsoukalas
        return self.put(path, *args, **kwargs)
59 a26e5a4d Georgios D. Tsoukalas
60 a26e5a4d Georgios D. Tsoukalas
    def mypost(self, path, *args, **kwargs):
61 a26e5a4d Georgios D. Tsoukalas
        path = join_urls(self.compute_path, path)
62 a26e5a4d Georgios D. Tsoukalas
        return self.post(path, *args, **kwargs)
63 a26e5a4d Georgios D. Tsoukalas
64 a26e5a4d Georgios D. Tsoukalas
    def mydelete(self, path, *args, **kwargs):
65 a26e5a4d Georgios D. Tsoukalas
        path = join_urls(self.compute_path, path)
66 a26e5a4d Georgios D. Tsoukalas
        return self.delete(path, *args, **kwargs)
67 a26e5a4d Georgios D. Tsoukalas
68 a26e5a4d Georgios D. Tsoukalas
69 a26e5a4d Georgios D. Tsoukalas
class ServerAPITest(ComputeAPITest):
70 039e3e61 Christos Stavrakakis
    def setUp(self):
71 039e3e61 Christos Stavrakakis
        self.user1 = 'user1'
72 039e3e61 Christos Stavrakakis
        self.user2 = 'user2'
73 039e3e61 Christos Stavrakakis
        self.vm1 = mfactory.VirtualMachineFactory(userid=self.user1)
74 039e3e61 Christos Stavrakakis
        self.vm2 = mfactory.VirtualMachineFactory(userid=self.user2)
75 039e3e61 Christos Stavrakakis
        self.vm3 = mfactory.VirtualMachineFactory(deleted=True,
76 039e3e61 Christos Stavrakakis
                                                  userid=self.user1)
77 039e3e61 Christos Stavrakakis
        self.vm4 = mfactory.VirtualMachineFactory(userid=self.user2)
78 a26e5a4d Georgios D. Tsoukalas
        super(ServerAPITest, self).setUp()
79 039e3e61 Christos Stavrakakis
80 039e3e61 Christos Stavrakakis
    def test_server_list_1(self):
81 039e3e61 Christos Stavrakakis
        """Test if the expected list of servers is returned."""
82 a26e5a4d Georgios D. Tsoukalas
        response = self.myget('servers')
83 039e3e61 Christos Stavrakakis
        self.assertSuccess(response)
84 2d04422f Christos Stavrakakis
        servers = json.loads(response.content)['servers']
85 039e3e61 Christos Stavrakakis
        self.assertEqual(servers, [])
86 039e3e61 Christos Stavrakakis
87 039e3e61 Christos Stavrakakis
    def test_server_list_2(self):
88 039e3e61 Christos Stavrakakis
        """Test if the expected list of servers is returned."""
89 a26e5a4d Georgios D. Tsoukalas
        response = self.myget('servers', self.user1)
90 039e3e61 Christos Stavrakakis
        self.assertSuccess(response)
91 2d04422f Christos Stavrakakis
        servers = json.loads(response.content)['servers']
92 039e3e61 Christos Stavrakakis
        db_server = self.vm1
93 1b696c26 Christos Stavrakakis
        server = servers[0]
94 1b696c26 Christos Stavrakakis
        self.assertEqual(server["name"], db_server.name)
95 1b696c26 Christos Stavrakakis
        self.assertEqual(server["id"], db_server.id)
96 039e3e61 Christos Stavrakakis
97 039e3e61 Christos Stavrakakis
    def test_server_list_detail(self):
98 039e3e61 Christos Stavrakakis
        """Test if the servers list details are returned."""
99 039e3e61 Christos Stavrakakis
        user = self.user2
100 039e3e61 Christos Stavrakakis
        user_vms = {self.vm2.id: self.vm2,
101 039e3e61 Christos Stavrakakis
                    self.vm4.id: self.vm4}
102 039e3e61 Christos Stavrakakis
103 a26e5a4d Georgios D. Tsoukalas
        response = self.myget('servers/detail', user)
104 2d04422f Christos Stavrakakis
        servers = json.loads(response.content)['servers']
105 039e3e61 Christos Stavrakakis
        self.assertEqual(len(servers), len(user_vms))
106 039e3e61 Christos Stavrakakis
        for api_vm in servers:
107 039e3e61 Christos Stavrakakis
            db_vm = user_vms[api_vm['id']]
108 1b696c26 Christos Stavrakakis
            self.assertEqual(api_vm['flavor']["id"], db_vm.flavor.id)
109 039e3e61 Christos Stavrakakis
            self.assertEqual(api_vm['hostId'], db_vm.hostid)
110 039e3e61 Christos Stavrakakis
            self.assertEqual(api_vm['id'], db_vm.id)
111 1b696c26 Christos Stavrakakis
            self.assertEqual(api_vm['image']["id"], db_vm.imageid)
112 039e3e61 Christos Stavrakakis
            self.assertEqual(api_vm['name'], db_vm.name)
113 039e3e61 Christos Stavrakakis
            self.assertEqual(api_vm['status'], get_rsapi_state(db_vm))
114 039e3e61 Christos Stavrakakis
            self.assertSuccess(response)
115 039e3e61 Christos Stavrakakis
116 039e3e61 Christos Stavrakakis
    def test_server_detail(self):
117 039e3e61 Christos Stavrakakis
        """Test if a server details are returned."""
118 039e3e61 Christos Stavrakakis
        db_vm = self.vm2
119 039e3e61 Christos Stavrakakis
        user = self.vm2.userid
120 039e3e61 Christos Stavrakakis
        net = mfactory.NetworkFactory()
121 1f638a85 Christos Stavrakakis
        nic = mfactory.NetworkInterfaceFactory(machine=self.vm2, network=net,
122 1f638a85 Christos Stavrakakis
                                              ipv6="::babe")
123 039e3e61 Christos Stavrakakis
124 039e3e61 Christos Stavrakakis
        db_vm_meta = mfactory.VirtualMachineMetadataFactory(vm=db_vm)
125 039e3e61 Christos Stavrakakis
126 a26e5a4d Georgios D. Tsoukalas
        response = self.myget('servers/%d' % db_vm.id, user)
127 039e3e61 Christos Stavrakakis
        server = json.loads(response.content)['server']
128 039e3e61 Christos Stavrakakis
129 1b696c26 Christos Stavrakakis
        self.assertEqual(server['flavor']["id"], db_vm.flavor.id)
130 039e3e61 Christos Stavrakakis
        self.assertEqual(server['hostId'], db_vm.hostid)
131 039e3e61 Christos Stavrakakis
        self.assertEqual(server['id'], db_vm.id)
132 1b696c26 Christos Stavrakakis
        self.assertEqual(server['image']["id"], db_vm.imageid)
133 039e3e61 Christos Stavrakakis
        self.assertEqual(server['name'], db_vm.name)
134 039e3e61 Christos Stavrakakis
        self.assertEqual(server['status'], get_rsapi_state(db_vm))
135 2d04422f Christos Stavrakakis
        api_nic = server['attachments'][0]
136 039e3e61 Christos Stavrakakis
        self.assertEqual(api_nic['network_id'], str(net.id))
137 039e3e61 Christos Stavrakakis
        self.assertEqual(api_nic['mac_address'], nic.mac)
138 039e3e61 Christos Stavrakakis
        self.assertEqual(api_nic['firewallProfile'], nic.firewall_profile)
139 039e3e61 Christos Stavrakakis
        self.assertEqual(api_nic['ipv4'], nic.ipv4)
140 039e3e61 Christos Stavrakakis
        self.assertEqual(api_nic['ipv6'], nic.ipv6)
141 039e3e61 Christos Stavrakakis
        self.assertEqual(api_nic['id'], 'nic-%s-%s' % (db_vm.id, nic.index))
142 1f638a85 Christos Stavrakakis
        api_address = server["addresses"]
143 1f638a85 Christos Stavrakakis
        self.assertEqual(api_address[str(net.id)],
144 f8352d29 Christos Stavrakakis
               [{"version": 4, "addr": nic.ipv4, "OS-EXT-IPS:type": "fixed"},
145 f8352d29 Christos Stavrakakis
                {"version": 6, "addr": nic.ipv6, "OS-EXT-IPS:type": "fixed"}])
146 039e3e61 Christos Stavrakakis
147 2d04422f Christos Stavrakakis
        metadata = server['metadata']
148 039e3e61 Christos Stavrakakis
        self.assertEqual(len(metadata), 1)
149 039e3e61 Christos Stavrakakis
        self.assertEqual(metadata[db_vm_meta.meta_key], db_vm_meta.meta_value)
150 039e3e61 Christos Stavrakakis
        self.assertSuccess(response)
151 039e3e61 Christos Stavrakakis
152 939d71dd Christos Stavrakakis
    def test_server_building_nics(self):
153 939d71dd Christos Stavrakakis
        db_vm = self.vm2
154 939d71dd Christos Stavrakakis
        user = self.vm2.userid
155 939d71dd Christos Stavrakakis
        net1 = mfactory.NetworkFactory()
156 939d71dd Christos Stavrakakis
        net2 = mfactory.NetworkFactory()
157 939d71dd Christos Stavrakakis
        net3 = mfactory.NetworkFactory()
158 939d71dd Christos Stavrakakis
        mfactory.NetworkInterfaceFactory(machine=self.vm2, network=net1,
159 939d71dd Christos Stavrakakis
                                         state="BUILDING")
160 939d71dd Christos Stavrakakis
        nic2 = mfactory.NetworkInterfaceFactory(machine=self.vm2, network=net2,
161 939d71dd Christos Stavrakakis
                                                state="ACTIVE")
162 939d71dd Christos Stavrakakis
        mfactory.NetworkInterfaceFactory(machine=self.vm2, network=net3,
163 939d71dd Christos Stavrakakis
                                         state="BUILDING")
164 939d71dd Christos Stavrakakis
165 a26e5a4d Georgios D. Tsoukalas
        response = self.myget('servers/%d' % db_vm.id, user)
166 939d71dd Christos Stavrakakis
        server = json.loads(response.content)['server']
167 2d04422f Christos Stavrakakis
        nics = server["attachments"]
168 939d71dd Christos Stavrakakis
        self.assertEqual(len(nics), 1)
169 939d71dd Christos Stavrakakis
        self.assertEqual(nics[0]["network_id"], str(nic2.network_id))
170 939d71dd Christos Stavrakakis
171 039e3e61 Christos Stavrakakis
    def test_noauthorized(self):
172 039e3e61 Christos Stavrakakis
        """Test 404 for detail of other user vm"""
173 039e3e61 Christos Stavrakakis
        db_vm = self.vm2
174 039e3e61 Christos Stavrakakis
175 a26e5a4d Georgios D. Tsoukalas
        response = self.myget('servers/%d' % db_vm.id, 'wrong_user')
176 039e3e61 Christos Stavrakakis
        self.assertItemNotFound(response)
177 039e3e61 Christos Stavrakakis
178 039e3e61 Christos Stavrakakis
    def test_wrong_server(self):
179 039e3e61 Christos Stavrakakis
        """Test 404 response if server does not exist."""
180 a26e5a4d Georgios D. Tsoukalas
        response = self.myget('servers/%d' % 5000)
181 039e3e61 Christos Stavrakakis
        self.assertItemNotFound(response)
182 039e3e61 Christos Stavrakakis
183 039e3e61 Christos Stavrakakis
    def test_create_server_empty(self):
184 039e3e61 Christos Stavrakakis
        """Test if the create server call returns a 400 badRequest if
185 039e3e61 Christos Stavrakakis
           no attributes are specified."""
186 039e3e61 Christos Stavrakakis
187 a26e5a4d Georgios D. Tsoukalas
        response = self.mypost('servers', params={})
188 039e3e61 Christos Stavrakakis
        self.assertBadRequest(response)
189 039e3e61 Christos Stavrakakis
190 039e3e61 Christos Stavrakakis
    def test_rename_server(self):
191 039e3e61 Christos Stavrakakis
        vm = self.vm2
192 039e3e61 Christos Stavrakakis
        request = {'server': {'name': 'new_name'}}
193 a26e5a4d Georgios D. Tsoukalas
        response = self.myput('servers/%d' % vm.id, vm.userid,
194 a26e5a4d Georgios D. Tsoukalas
                              json.dumps(request), 'json')
195 039e3e61 Christos Stavrakakis
        self.assertSuccess(response)
196 039e3e61 Christos Stavrakakis
        self.assertEqual(VirtualMachine.objects.get(id=vm.id).name, "new_name")
197 039e3e61 Christos Stavrakakis
198 a3accf03 Georgios D. Tsoukalas
    def test_catch_wrong_api_paths(self):
199 a3accf03 Georgios D. Tsoukalas
        response = self.myget('nonexistent')
200 a3accf03 Georgios D. Tsoukalas
        self.assertEqual(response.status_code, 400)
201 a3accf03 Georgios D. Tsoukalas
        try:
202 a3accf03 Georgios D. Tsoukalas
            error = json.loads(response.content)
203 a3accf03 Georgios D. Tsoukalas
        except ValueError:
204 a3accf03 Georgios D. Tsoukalas
            self.assertTrue(False)
205 a3accf03 Georgios D. Tsoukalas
206 16437e4d Kostas Papadimitriou
    def test_method_not_allowed(self, *args):
207 16437e4d Kostas Papadimitriou
        # /servers/ allows only POST, GET
208 16437e4d Kostas Papadimitriou
        response = self.myput('servers', '', '')
209 16437e4d Kostas Papadimitriou
        self.assertMethodNotAllowed(response)
210 16437e4d Kostas Papadimitriou
        response = self.mydelete('servers')
211 16437e4d Kostas Papadimitriou
        self.assertMethodNotAllowed(response)
212 16437e4d Kostas Papadimitriou
213 16437e4d Kostas Papadimitriou
        # /servers/<srvid>/ allows only GET, PUT, DELETE
214 16437e4d Kostas Papadimitriou
        response = self.mypost("servers/42")
215 16437e4d Kostas Papadimitriou
        self.assertMethodNotAllowed(response)
216 16437e4d Kostas Papadimitriou
217 16437e4d Kostas Papadimitriou
        # /imags/<srvid>/metadata/ allows only POST, GET
218 16437e4d Kostas Papadimitriou
        response = self.myput('servers/42/metadata', '', '')
219 16437e4d Kostas Papadimitriou
        self.assertMethodNotAllowed(response)
220 16437e4d Kostas Papadimitriou
        response = self.mydelete('servers/42/metadata')
221 16437e4d Kostas Papadimitriou
        self.assertMethodNotAllowed(response)
222 16437e4d Kostas Papadimitriou
223 16437e4d Kostas Papadimitriou
        # /imags/<srvid>/metadata/ allows only POST, GET
224 16437e4d Kostas Papadimitriou
        response = self.myput('servers/42/metadata', '', '')
225 16437e4d Kostas Papadimitriou
        self.assertMethodNotAllowed(response)
226 16437e4d Kostas Papadimitriou
        response = self.mydelete('servers/42/metadata')
227 16437e4d Kostas Papadimitriou
        self.assertMethodNotAllowed(response)
228 16437e4d Kostas Papadimitriou
229 16437e4d Kostas Papadimitriou
        # /imags/<srvid>/metadata/<key> allows only PUT, GET, DELETE
230 16437e4d Kostas Papadimitriou
        response = self.mypost('servers/42/metadata/foo')
231 16437e4d Kostas Papadimitriou
        self.assertMethodNotAllowed(response)
232 16437e4d Kostas Papadimitriou
233 039e3e61 Christos Stavrakakis
234 039e3e61 Christos Stavrakakis
@patch('synnefo.api.util.get_image')
235 039e3e61 Christos Stavrakakis
@patch('synnefo.logic.rapi_pool.GanetiRapiClient')
236 a26e5a4d Georgios D. Tsoukalas
class ServerCreateAPITest(ComputeAPITest):
237 039e3e61 Christos Stavrakakis
    def test_create_server(self, mrapi, mimage):
238 039e3e61 Christos Stavrakakis
        """Test if the create server call returns the expected response
239 039e3e61 Christos Stavrakakis
           if a valid request has been speficied."""
240 039e3e61 Christos Stavrakakis
        mimage.return_value = {'location': 'pithos://foo',
241 920af09f Christos Stavrakakis
                               'checksum': '1234',
242 bcd80cd9 Christos Stavrakakis
                               "id": 1,
243 bcd80cd9 Christos Stavrakakis
                               "name": "test_image",
244 039e3e61 Christos Stavrakakis
                               'disk_format': 'diskdump'}
245 039e3e61 Christos Stavrakakis
        mrapi().CreateInstance.return_value = 12
246 039e3e61 Christos Stavrakakis
        flavor = mfactory.FlavorFactory()
247 039e3e61 Christos Stavrakakis
        # Create public network and backend
248 039e3e61 Christos Stavrakakis
        network = mfactory.NetworkFactory(public=True)
249 039e3e61 Christos Stavrakakis
        backend = mfactory.BackendFactory()
250 039e3e61 Christos Stavrakakis
        mfactory.BackendNetworkFactory(network=network, backend=backend)
251 039e3e61 Christos Stavrakakis
252 039e3e61 Christos Stavrakakis
        request = {
253 039e3e61 Christos Stavrakakis
                    "server": {
254 039e3e61 Christos Stavrakakis
                        "name": "new-server-test",
255 039e3e61 Christos Stavrakakis
                        "userid": "test_user",
256 039e3e61 Christos Stavrakakis
                        "imageRef": 1,
257 039e3e61 Christos Stavrakakis
                        "flavorRef": flavor.id,
258 039e3e61 Christos Stavrakakis
                        "metadata": {
259 039e3e61 Christos Stavrakakis
                            "My Server Name": "Apache1"
260 039e3e61 Christos Stavrakakis
                        },
261 039e3e61 Christos Stavrakakis
                        "personality": []
262 039e3e61 Christos Stavrakakis
                    }
263 039e3e61 Christos Stavrakakis
        }
264 184a2a8c Christos Stavrakakis
        with mocked_quotaholder():
265 a26e5a4d Georgios D. Tsoukalas
            response = self.mypost('servers', 'test_user',
266 a26e5a4d Georgios D. Tsoukalas
                                   json.dumps(request), 'json')
267 039e3e61 Christos Stavrakakis
        self.assertEqual(response.status_code, 202)
268 039e3e61 Christos Stavrakakis
        mrapi().CreateInstance.assert_called_once()
269 039e3e61 Christos Stavrakakis
270 039e3e61 Christos Stavrakakis
        api_server = json.loads(response.content)['server']
271 039e3e61 Christos Stavrakakis
        self.assertEqual(api_server['status'], "BUILD")
272 039e3e61 Christos Stavrakakis
        self.assertEqual(api_server['progress'], 0)
273 2d04422f Christos Stavrakakis
        self.assertEqual(api_server['metadata'],
274 039e3e61 Christos Stavrakakis
                        {"My Server Name":  "Apache1"})
275 039e3e61 Christos Stavrakakis
        self.assertTrue('adminPass' in api_server)
276 039e3e61 Christos Stavrakakis
277 039e3e61 Christos Stavrakakis
        db_vm = VirtualMachine.objects.get(userid='test_user')
278 039e3e61 Christos Stavrakakis
        self.assertEqual(api_server['name'], db_vm.name)
279 039e3e61 Christos Stavrakakis
        self.assertEqual(api_server['status'], db_vm.operstate)
280 039e3e61 Christos Stavrakakis
281 6dafedf6 Christos Stavrakakis
        # Test drained flag in Network:
282 6dafedf6 Christos Stavrakakis
        network.drained = True
283 6dafedf6 Christos Stavrakakis
        network.save()
284 6dafedf6 Christos Stavrakakis
        with mocked_quotaholder():
285 a26e5a4d Georgios D. Tsoukalas
            response = self.mypost('servers', 'test_user',
286 a26e5a4d Georgios D. Tsoukalas
                                    json.dumps(request), 'json')
287 6dafedf6 Christos Stavrakakis
        self.assertEqual(response.status_code, 503, "serviceUnavailable")
288 6dafedf6 Christos Stavrakakis
289 039e3e61 Christos Stavrakakis
    def test_create_server_no_flavor(self, mrapi, mimage):
290 039e3e61 Christos Stavrakakis
        request = {
291 039e3e61 Christos Stavrakakis
                    "server": {
292 039e3e61 Christos Stavrakakis
                        "name": "new-server-test",
293 039e3e61 Christos Stavrakakis
                        "userid": "test_user",
294 039e3e61 Christos Stavrakakis
                        "imageRef": 1,
295 039e3e61 Christos Stavrakakis
                        "flavorRef": 42,
296 039e3e61 Christos Stavrakakis
                        "metadata": {
297 039e3e61 Christos Stavrakakis
                            "My Server Name": "Apache1"
298 039e3e61 Christos Stavrakakis
                        },
299 039e3e61 Christos Stavrakakis
                        "personality": []
300 039e3e61 Christos Stavrakakis
                    }
301 039e3e61 Christos Stavrakakis
        }
302 a26e5a4d Georgios D. Tsoukalas
        response = self.mypost('servers', 'test_user',
303 a26e5a4d Georgios D. Tsoukalas
                               json.dumps(request), 'json')
304 039e3e61 Christos Stavrakakis
        self.assertItemNotFound(response)
305 039e3e61 Christos Stavrakakis
306 039e3e61 Christos Stavrakakis
307 039e3e61 Christos Stavrakakis
@patch('synnefo.logic.rapi_pool.GanetiRapiClient')
308 a26e5a4d Georgios D. Tsoukalas
class ServerDestroyAPITest(ComputeAPITest):
309 039e3e61 Christos Stavrakakis
    def test_delete_server(self, mrapi):
310 039e3e61 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
311 a26e5a4d Georgios D. Tsoukalas
        response = self.mydelete('servers/%d' % vm.id, vm.userid)
312 039e3e61 Christos Stavrakakis
        self.assertEqual(response.status_code, 204)
313 039e3e61 Christos Stavrakakis
        mrapi().DeleteInstance.assert_called_once()
314 039e3e61 Christos Stavrakakis
315 039e3e61 Christos Stavrakakis
    def test_non_existing_delete_server(self, mrapi):
316 039e3e61 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
317 a26e5a4d Georgios D. Tsoukalas
        response = self.mydelete('servers/%d' % 42, vm.userid)
318 039e3e61 Christos Stavrakakis
        self.assertItemNotFound(response)
319 039e3e61 Christos Stavrakakis
        self.assertFalse(mrapi.mock_calls)
320 039e3e61 Christos Stavrakakis
321 039e3e61 Christos Stavrakakis
322 a26e5a4d Georgios D. Tsoukalas
class ServerMetadataAPITest(ComputeAPITest):
323 039e3e61 Christos Stavrakakis
    def setUp(self):
324 039e3e61 Christos Stavrakakis
        self.vm = mfactory.VirtualMachineFactory()
325 039e3e61 Christos Stavrakakis
        self.metadata = mfactory.VirtualMachineMetadataFactory(vm=self.vm)
326 a26e5a4d Georgios D. Tsoukalas
        super(ServerMetadataAPITest, self).setUp()
327 039e3e61 Christos Stavrakakis
328 039e3e61 Christos Stavrakakis
    def test_get_metadata(self):
329 039e3e61 Christos Stavrakakis
        vm = self.vm
330 039e3e61 Christos Stavrakakis
        create_meta = lambda: mfactory.VirtualMachineMetadataFactory(vm=vm)
331 039e3e61 Christos Stavrakakis
        metadata = [create_meta(), create_meta(), create_meta()]
332 a26e5a4d Georgios D. Tsoukalas
        response = self.myget('servers/%d/metadata' % vm.id, vm.userid)
333 039e3e61 Christos Stavrakakis
        self.assertTrue(response.status_code in [200, 203])
334 2d04422f Christos Stavrakakis
        api_metadata = json.loads(response.content)['metadata']
335 039e3e61 Christos Stavrakakis
        self.assertEqual(len(api_metadata), len(metadata) + 1)
336 039e3e61 Christos Stavrakakis
        for db_m in metadata:
337 039e3e61 Christos Stavrakakis
            self.assertEqual(api_metadata[db_m.meta_key], db_m.meta_value)
338 039e3e61 Christos Stavrakakis
339 039e3e61 Christos Stavrakakis
        request = {'metadata':
340 039e3e61 Christos Stavrakakis
                        {'foo': 'bar'},
341 039e3e61 Christos Stavrakakis
                        metadata[0].meta_key: 'bar2'
342 039e3e61 Christos Stavrakakis
                  }
343 a26e5a4d Georgios D. Tsoukalas
        response = self.mypost('servers/%d/metadata' % vm.id,
344 2d04422f Christos Stavrakakis
                             vm.userid, json.dumps(request), 'json')
345 039e3e61 Christos Stavrakakis
        metadata2 = VirtualMachineMetadata.objects.filter(vm=vm)
346 a26e5a4d Georgios D. Tsoukalas
        response = self.myget('servers/%d/metadata' % vm.id, vm.userid)
347 039e3e61 Christos Stavrakakis
        self.assertTrue(response.status_code in [200, 203])
348 2d04422f Christos Stavrakakis
        api_metadata2 = json.loads(response.content)['metadata']
349 039e3e61 Christos Stavrakakis
        self.assertTrue('foo' in api_metadata2.keys())
350 039e3e61 Christos Stavrakakis
        self.assertTrue(api_metadata2[metadata[0].meta_key], 'bar2')
351 039e3e61 Christos Stavrakakis
        self.assertEqual(len(api_metadata2), len(metadata2))
352 039e3e61 Christos Stavrakakis
        for db_m in metadata2:
353 039e3e61 Christos Stavrakakis
            self.assertEqual(api_metadata2[db_m.meta_key], db_m.meta_value)
354 039e3e61 Christos Stavrakakis
355 039e3e61 Christos Stavrakakis
        # Create new meta
356 039e3e61 Christos Stavrakakis
        request = {'meta': {'foo2': 'bar2'}}
357 a26e5a4d Georgios D. Tsoukalas
        response = self.myput('servers/%d/metadata/foo2' % vm.id,
358 a26e5a4d Georgios D. Tsoukalas
                              vm.userid, json.dumps(request), 'json')
359 039e3e61 Christos Stavrakakis
360 039e3e61 Christos Stavrakakis
        # Get the new meta
361 a26e5a4d Georgios D. Tsoukalas
        response = self.myget('servers/%d/metadata/foo2' % vm.id, vm.userid)
362 039e3e61 Christos Stavrakakis
        meta = json.loads(response.content)['meta']
363 039e3e61 Christos Stavrakakis
        self.assertEqual(meta['foo2'], 'bar2')
364 039e3e61 Christos Stavrakakis
365 039e3e61 Christos Stavrakakis
        # Delete the new meta
366 a26e5a4d Georgios D. Tsoukalas
        response = self.mydelete('servers/%d/metadata/foo2' % vm.id, vm.userid)
367 039e3e61 Christos Stavrakakis
        self.assertEqual(response.status_code, 204)
368 039e3e61 Christos Stavrakakis
369 039e3e61 Christos Stavrakakis
        # Try to get the deleted meta: should raise 404
370 a26e5a4d Georgios D. Tsoukalas
        response = self.myget('servers/%d/metadata/foo2' % vm.id, vm.userid)
371 039e3e61 Christos Stavrakakis
        self.assertEqual(response.status_code, 404)
372 039e3e61 Christos Stavrakakis
373 039e3e61 Christos Stavrakakis
    def test_invalid_metadata(self):
374 039e3e61 Christos Stavrakakis
        vm = self.vm
375 a26e5a4d Georgios D. Tsoukalas
        response = self.mypost('servers/%d/metadata' % vm.id, vm.userid)
376 039e3e61 Christos Stavrakakis
        self.assertBadRequest(response)
377 039e3e61 Christos Stavrakakis
        self.assertEqual(len(vm.metadata.all()), 1)
378 039e3e61 Christos Stavrakakis
379 039e3e61 Christos Stavrakakis
    def test_invalid_metadata_server(self):
380 a26e5a4d Georgios D. Tsoukalas
        response = self.mypost('servers/42/metadata', 'user')
381 039e3e61 Christos Stavrakakis
        self.assertItemNotFound(response)
382 039e3e61 Christos Stavrakakis
383 039e3e61 Christos Stavrakakis
    def test_get_meta_invalid_key(self):
384 039e3e61 Christos Stavrakakis
        vm = self.vm
385 a26e5a4d Georgios D. Tsoukalas
        response = self.myget('servers/%d/metadata/foo2' % vm.id, vm.userid)
386 039e3e61 Christos Stavrakakis
        self.assertItemNotFound(response)
387 039e3e61 Christos Stavrakakis
388 039e3e61 Christos Stavrakakis
389 039e3e61 Christos Stavrakakis
@patch('synnefo.api.util.get_image')
390 039e3e61 Christos Stavrakakis
@patch('synnefo.logic.rapi_pool.GanetiRapiClient')
391 a26e5a4d Georgios D. Tsoukalas
class ServerActionAPITest(ComputeAPITest):
392 039e3e61 Christos Stavrakakis
    def test_actions(self, mrapi, mimage):
393 039e3e61 Christos Stavrakakis
        actions = ['start', 'shutdown', 'reboot']
394 039e3e61 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
395 039e3e61 Christos Stavrakakis
        vm.operstate = "STOPPED"
396 039e3e61 Christos Stavrakakis
        vm.save()
397 039e3e61 Christos Stavrakakis
        for action in actions:
398 039e3e61 Christos Stavrakakis
            val = {'type': 'HARD'} if action == 'reboot' else {}
399 039e3e61 Christos Stavrakakis
            request = {action: val}
400 a26e5a4d Georgios D. Tsoukalas
            response = self.mypost('servers/%d/action' % vm.id,
401 a26e5a4d Georgios D. Tsoukalas
                                   vm.userid, json.dumps(request), 'json')
402 039e3e61 Christos Stavrakakis
            self.assertEqual(response.status_code, 202)
403 039e3e61 Christos Stavrakakis
            if action == 'shutdown':
404 039e3e61 Christos Stavrakakis
                self.assertEqual(VirtualMachine.objects.get(id=vm.id).action,
405 039e3e61 Christos Stavrakakis
                                 "STOP")
406 039e3e61 Christos Stavrakakis
            else:
407 039e3e61 Christos Stavrakakis
                self.assertEqual(VirtualMachine.objects.get(id=vm.id).action,
408 039e3e61 Christos Stavrakakis
                                 action.upper())
409 039e3e61 Christos Stavrakakis
410 039e3e61 Christos Stavrakakis
    def test_action_in_building_vm(self, mrapi, mimage):
411 039e3e61 Christos Stavrakakis
        """Test building in progress"""
412 039e3e61 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
413 039e3e61 Christos Stavrakakis
        request = {'start': '{}'}
414 a26e5a4d Georgios D. Tsoukalas
        response = self.mypost('servers/%d/action' % vm.id,
415 a26e5a4d Georgios D. Tsoukalas
                               vm.userid, json.dumps(request), 'json')
416 039e3e61 Christos Stavrakakis
        self.assertEqual(response.status_code, 409)
417 039e3e61 Christos Stavrakakis
        self.assertFalse(mrapi.mock_calls)
418 039e3e61 Christos Stavrakakis
419 039e3e61 Christos Stavrakakis
    def test_destroy_build_vm(self, mrapi, mimage):
420 039e3e61 Christos Stavrakakis
        """Test building in progress"""
421 039e3e61 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
422 a26e5a4d Georgios D. Tsoukalas
        response = self.mydelete('servers/%d' % vm.id, vm.userid)
423 039e3e61 Christos Stavrakakis
        self.assertSuccess(response)
424 039e3e61 Christos Stavrakakis
        mrapi().RemoveInstance.assert_called_once()
425 039e3e61 Christos Stavrakakis
426 039e3e61 Christos Stavrakakis
    def test_firewall(self, mrapi, mimage):
427 039e3e61 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
428 039e3e61 Christos Stavrakakis
        vm.operstate = "STOPPED"
429 039e3e61 Christos Stavrakakis
        vm.save()
430 039e3e61 Christos Stavrakakis
        request = {'firewallProfile': {'profile': 'PROTECTED'}}
431 a26e5a4d Georgios D. Tsoukalas
        response = self.mypost('servers/%d/action' % vm.id,
432 a26e5a4d Georgios D. Tsoukalas
                               vm.userid, json.dumps(request), 'json')
433 039e3e61 Christos Stavrakakis
        self.assertEqual(response.status_code, 202)
434 039e3e61 Christos Stavrakakis
        mrapi().ModifyInstance.assert_called_once()
435 039e3e61 Christos Stavrakakis
436 039e3e61 Christos Stavrakakis
    def test_unsupported_firewall(self, mrapi, mimage):
437 039e3e61 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
438 039e3e61 Christos Stavrakakis
        vm.operstate = "STOPPED"
439 039e3e61 Christos Stavrakakis
        vm.save()
440 039e3e61 Christos Stavrakakis
        request = {'firewallProfile': {'profile': 'FOO'}}
441 a26e5a4d Georgios D. Tsoukalas
        response = self.mypost('servers/%d/action' % vm.id,
442 a26e5a4d Georgios D. Tsoukalas
                               vm.userid, json.dumps(request), 'json')
443 039e3e61 Christos Stavrakakis
        self.assertBadRequest(response)
444 039e3e61 Christos Stavrakakis
        self.assertFalse(mrapi.mock_calls)
445 039e3e61 Christos Stavrakakis
446 039e3e61 Christos Stavrakakis
447 a26e5a4d Georgios D. Tsoukalas
class ServerVNCConsole(ComputeAPITest):
448 039e3e61 Christos Stavrakakis
    def test_not_active_server(self):
449 039e3e61 Christos Stavrakakis
        """Test console req for not ACTIVE server returns badRequest"""
450 039e3e61 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
451 039e3e61 Christos Stavrakakis
        data = json.dumps({'console': {'type': 'vnc'}})
452 a26e5a4d Georgios D. Tsoukalas
        response = self.mypost('servers/%d/action' % vm.id,
453 a26e5a4d Georgios D. Tsoukalas
                               vm.userid, data, 'json')
454 039e3e61 Christos Stavrakakis
        self.assertBadRequest(response)
455 039e3e61 Christos Stavrakakis
456 039e3e61 Christos Stavrakakis
    def test_active_server(self):
457 039e3e61 Christos Stavrakakis
        """Test console req for ACTIVE server"""
458 039e3e61 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
459 039e3e61 Christos Stavrakakis
        vm.operstate = 'STARTED'
460 039e3e61 Christos Stavrakakis
        vm.save()
461 039e3e61 Christos Stavrakakis
462 039e3e61 Christos Stavrakakis
        data = json.dumps({'console': {'type': 'vnc'}})
463 a26e5a4d Georgios D. Tsoukalas
        response = self.mypost('servers/%d/action' % vm.id,
464 a26e5a4d Georgios D. Tsoukalas
                               vm.userid, data, 'json')
465 039e3e61 Christos Stavrakakis
        self.assertEqual(response.status_code, 200)
466 039e3e61 Christos Stavrakakis
        reply = json.loads(response.content)
467 039e3e61 Christos Stavrakakis
        self.assertEqual(reply.keys(), ['console'])
468 039e3e61 Christos Stavrakakis
        console = reply['console']
469 039e3e61 Christos Stavrakakis
        self.assertEqual(console['type'], 'vnc')
470 039e3e61 Christos Stavrakakis
        self.assertEqual(set(console.keys()),
471 039e3e61 Christos Stavrakakis
                         set(['type', 'host', 'port', 'password']))
472 039e3e61 Christos Stavrakakis
473 039e3e61 Christos Stavrakakis
    def test_wrong_console_type(self):
474 039e3e61 Christos Stavrakakis
        """Test console req for ACTIVE server"""
475 039e3e61 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
476 039e3e61 Christos Stavrakakis
        vm.operstate = 'STARTED'
477 039e3e61 Christos Stavrakakis
        vm.save()
478 039e3e61 Christos Stavrakakis
479 039e3e61 Christos Stavrakakis
        data = json.dumps({'console': {'type': 'foo'}})
480 a26e5a4d Georgios D. Tsoukalas
        response = self.mypost('servers/%d/action' % vm.id,
481 a26e5a4d Georgios D. Tsoukalas
                               vm.userid, data, 'json')
482 039e3e61 Christos Stavrakakis
        self.assertBadRequest(response)