Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / helpdesk / tests.py @ e892db2d

History | View | Annotate | Download (11.5 kB)

1 c4d1f3b7 Kostas Papadimitriou
# Copyright 2011 GRNET S.A. All rights reserved.
2 c4d1f3b7 Kostas Papadimitriou
#
3 c4d1f3b7 Kostas Papadimitriou
# Redistribution and use in source and binary forms, with or
4 c4d1f3b7 Kostas Papadimitriou
# without modification, are permitted provided that the following
5 c4d1f3b7 Kostas Papadimitriou
# conditions are met:
6 c4d1f3b7 Kostas Papadimitriou
#
7 c4d1f3b7 Kostas Papadimitriou
#   1. Redistributions of source code must retain the above
8 c4d1f3b7 Kostas Papadimitriou
#      copyright notice, this list of conditions and the following
9 c4d1f3b7 Kostas Papadimitriou
#      disclaimer.
10 c4d1f3b7 Kostas Papadimitriou
#
11 c4d1f3b7 Kostas Papadimitriou
#   2. Redistributions in binary form must reproduce the above
12 c4d1f3b7 Kostas Papadimitriou
#      copyright notice, this list of conditions and the following
13 c4d1f3b7 Kostas Papadimitriou
#      disclaimer in the documentation and/or other materials
14 c4d1f3b7 Kostas Papadimitriou
#      provided with the distribution.
15 c4d1f3b7 Kostas Papadimitriou
#
16 c4d1f3b7 Kostas Papadimitriou
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 c4d1f3b7 Kostas Papadimitriou
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 c4d1f3b7 Kostas Papadimitriou
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 c4d1f3b7 Kostas Papadimitriou
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 c4d1f3b7 Kostas Papadimitriou
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 c4d1f3b7 Kostas Papadimitriou
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 c4d1f3b7 Kostas Papadimitriou
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 c4d1f3b7 Kostas Papadimitriou
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 c4d1f3b7 Kostas Papadimitriou
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 c4d1f3b7 Kostas Papadimitriou
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 c4d1f3b7 Kostas Papadimitriou
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 c4d1f3b7 Kostas Papadimitriou
# POSSIBILITY OF SUCH DAMAGE.
28 c4d1f3b7 Kostas Papadimitriou
#
29 c4d1f3b7 Kostas Papadimitriou
# The views and conclusions contained in the software and
30 c4d1f3b7 Kostas Papadimitriou
# documentation are those of the authors and should not be
31 c4d1f3b7 Kostas Papadimitriou
# interpreted as representing official policies, either expressed
32 c4d1f3b7 Kostas Papadimitriou
# or implied, of GRNET S.A.
33 c4d1f3b7 Kostas Papadimitriou
#
34 c4d1f3b7 Kostas Papadimitriou
35 cc5c8608 Kostas Papadimitriou
import mock
36 cc5c8608 Kostas Papadimitriou
37 c4d1f3b7 Kostas Papadimitriou
from django.test import TestCase, Client
38 c4d1f3b7 Kostas Papadimitriou
from django.conf import settings
39 c4d1f3b7 Kostas Papadimitriou
from django.core.urlresolvers import reverse
40 c4d1f3b7 Kostas Papadimitriou
41 d59d86d4 Kostas Papadimitriou
42 505a121e Kostas Papadimitriou
USER1 = "5edcb5aa-1111-4146-a8ed-2b6287824353"
43 505a121e Kostas Papadimitriou
USER2 = "5edcb5aa-2222-4146-a8ed-2b6287824353"
44 505a121e Kostas Papadimitriou
45 505a121e Kostas Papadimitriou
USERS_UUIDS = {}
46 505a121e Kostas Papadimitriou
USERS_UUIDS[USER1] = {'displayname': 'testuser@test.com'}
47 505a121e Kostas Papadimitriou
USERS_UUIDS[USER2] = {'displayname': 'testuser2@test.com'}
48 505a121e Kostas Papadimitriou
49 505a121e Kostas Papadimitriou
USERS_DISPLAYNAMES = dict(map(lambda k: (k[1]['displayname'], {'uuid': k[0]}),
50 505a121e Kostas Papadimitriou
                          USERS_UUIDS.iteritems()))
51 505a121e Kostas Papadimitriou
52 cc5c8608 Kostas Papadimitriou
from synnefo.db import models_factory as mfactory
53 cc5c8608 Kostas Papadimitriou
54 468ba00b Ilias Tsitsimpis
55 468ba00b Ilias Tsitsimpis
class AstakosClientMock():
56 468ba00b Ilias Tsitsimpis
    def __init__(*args, **kwargs):
57 468ba00b Ilias Tsitsimpis
        pass
58 468ba00b Ilias Tsitsimpis
59 468ba00b Ilias Tsitsimpis
    def get_username(self, token, uuid):
60 468ba00b Ilias Tsitsimpis
        try:
61 468ba00b Ilias Tsitsimpis
            return USERS_UUIDS.get(uuid)['displayname']
62 468ba00b Ilias Tsitsimpis
        except TypeError:
63 468ba00b Ilias Tsitsimpis
            return None
64 468ba00b Ilias Tsitsimpis
65 468ba00b Ilias Tsitsimpis
    def get_uuid(self, token, display_name):
66 468ba00b Ilias Tsitsimpis
        try:
67 468ba00b Ilias Tsitsimpis
            return USERS_DISPLAYNAMES.get(display_name)['uuid']
68 468ba00b Ilias Tsitsimpis
        except TypeError:
69 468ba00b Ilias Tsitsimpis
            return None
70 468ba00b Ilias Tsitsimpis
71 468ba00b Ilias Tsitsimpis
72 505a121e Kostas Papadimitriou
class AuthClient(Client):
73 c4d1f3b7 Kostas Papadimitriou
74 c4d1f3b7 Kostas Papadimitriou
    def request(self, **request):
75 c4d1f3b7 Kostas Papadimitriou
        token = request.pop('user_token', '0000')
76 c4d1f3b7 Kostas Papadimitriou
        if token:
77 c4d1f3b7 Kostas Papadimitriou
            request['HTTP_X_AUTH_TOKEN'] = token
78 505a121e Kostas Papadimitriou
        return super(AuthClient, self).request(**request)
79 505a121e Kostas Papadimitriou
80 c4d1f3b7 Kostas Papadimitriou
81 e892db2d Christos Stavrakakis
def get_user_mock(request, *args, **kwargs):
82 e892db2d Christos Stavrakakis
    request.user_uniq = None
83 e892db2d Christos Stavrakakis
    request.user = None
84 e892db2d Christos Stavrakakis
    if request.META.get('HTTP_X_AUTH_TOKEN', None) == '0000':
85 e892db2d Christos Stavrakakis
        request.user_uniq = 'test'
86 e892db2d Christos Stavrakakis
        request.user = {'uniq': 'test', 'auth_token': '0000'}
87 e892db2d Christos Stavrakakis
    if request.META.get('HTTP_X_AUTH_TOKEN', None) == '0001':
88 e892db2d Christos Stavrakakis
        request.user_uniq = 'test'
89 e892db2d Christos Stavrakakis
        request.user = {'uniq': 'test', 'groups': ['default',
90 e892db2d Christos Stavrakakis
                                                   'helpdesk'],
91 e892db2d Christos Stavrakakis
                        'auth_token': '0001'}
92 e892db2d Christos Stavrakakis
93 e892db2d Christos Stavrakakis
94 e892db2d Christos Stavrakakis
@mock.patch("astakosclient.AstakosClient", new=AstakosClientMock)
95 e892db2d Christos Stavrakakis
@mock.patch("snf_django.lib.astakos.get_user", new=get_user_mock)
96 c4d1f3b7 Kostas Papadimitriou
class HelpdeskTests(TestCase):
97 c4d1f3b7 Kostas Papadimitriou
    """
98 c4d1f3b7 Kostas Papadimitriou
    Helpdesk tests. Test correctness of permissions and returned data.
99 c4d1f3b7 Kostas Papadimitriou
    """
100 c4d1f3b7 Kostas Papadimitriou
101 c4d1f3b7 Kostas Papadimitriou
    fixtures = ['helpdesk_test']
102 c4d1f3b7 Kostas Papadimitriou
103 c4d1f3b7 Kostas Papadimitriou
    def setUp(self):
104 c4d1f3b7 Kostas Papadimitriou
        settings.SKIP_SSH_VALIDATION = True
105 9fd36718 Kostas Papadimitriou
        settings.HELPDESK_ENABLED = True
106 505a121e Kostas Papadimitriou
        self.client = AuthClient()
107 c4d1f3b7 Kostas Papadimitriou
108 9fd36718 Kostas Papadimitriou
    def test_enabled_setting(self):
109 9fd36718 Kostas Papadimitriou
        settings.HELPDESK_ENABLED = False
110 9fd36718 Kostas Papadimitriou
111 9fd36718 Kostas Papadimitriou
        # helpdesk is disabled
112 9fd36718 Kostas Papadimitriou
        r = self.client.get(reverse('helpdesk-index'), user_token="0001")
113 9fd36718 Kostas Papadimitriou
        self.assertEqual(r.status_code, 404)
114 505a121e Kostas Papadimitriou
        r = self.client.get(reverse('helpdesk-details',
115 505a121e Kostas Papadimitriou
                                    args=['testuser@test.com']),
116 505a121e Kostas Papadimitriou
                            user_token="0001")
117 9fd36718 Kostas Papadimitriou
        self.assertEqual(r.status_code, 404)
118 9fd36718 Kostas Papadimitriou
119 d59d86d4 Kostas Papadimitriou
    def test_ip_lookup(self):
120 d59d86d4 Kostas Papadimitriou
        # ip does not exist, proper message gets displayed
121 d59d86d4 Kostas Papadimitriou
        r = self.client.get(reverse('helpdesk-details',
122 505a121e Kostas Papadimitriou
                            args=["195.251.221.122"]), user_token='0001')
123 d59d86d4 Kostas Papadimitriou
        self.assertContains(r, 'User with IP')
124 d59d86d4 Kostas Papadimitriou
125 d59d86d4 Kostas Papadimitriou
        # ip exists, 'test' account discovered
126 d59d86d4 Kostas Papadimitriou
        r = self.client.get(reverse('helpdesk-details',
127 505a121e Kostas Papadimitriou
                            args=["195.251.222.211"]), user_token='0001')
128 505a121e Kostas Papadimitriou
        self.assertEqual(r.context['account'], USER2)
129 d59d86d4 Kostas Papadimitriou
130 505a121e Kostas Papadimitriou
    def test_vm_lookup(self):
131 505a121e Kostas Papadimitriou
        # vm id does not exist
132 505a121e Kostas Papadimitriou
        r = self.client.get(reverse('helpdesk-details',
133 505a121e Kostas Papadimitriou
                            args=["vm-123"]), user_token='0001')
134 505a121e Kostas Papadimitriou
        self.assertContains(r, 'User with Virtual Machine')
135 505a121e Kostas Papadimitriou
136 505a121e Kostas Papadimitriou
        # vm exists, 'test' account discovered
137 505a121e Kostas Papadimitriou
        r = self.client.get(reverse('helpdesk-details',
138 505a121e Kostas Papadimitriou
                            args=["vm1001"]), user_token='0001')
139 505a121e Kostas Papadimitriou
        self.assertEqual(r.context['account'], USER1)
140 505a121e Kostas Papadimitriou
        r = self.client.get(reverse('helpdesk-details',
141 505a121e Kostas Papadimitriou
                            args=["vm1002"]), user_token='0001')
142 505a121e Kostas Papadimitriou
        self.assertEqual(r.context['account'], USER2)
143 505a121e Kostas Papadimitriou
        # dash also works
144 505a121e Kostas Papadimitriou
        r = self.client.get(reverse('helpdesk-details',
145 505a121e Kostas Papadimitriou
                            args=["vm-1002"]), user_token='0001')
146 505a121e Kostas Papadimitriou
        self.assertEqual(r.context['account'], USER2)
147 c4d1f3b7 Kostas Papadimitriou
148 505a121e Kostas Papadimitriou
    def test_view_permissions(self):
149 c4d1f3b7 Kostas Papadimitriou
        # anonymous user gets 403
150 c4d1f3b7 Kostas Papadimitriou
        r = self.client.get(reverse('helpdesk-index'), user_token=None)
151 c4d1f3b7 Kostas Papadimitriou
        self.assertEqual(r.status_code, 403)
152 505a121e Kostas Papadimitriou
        r = self.client.get(reverse('helpdesk-details',
153 505a121e Kostas Papadimitriou
                                    args=['testuser@test.com']),
154 505a121e Kostas Papadimitriou
                            user_token=None)
155 c4d1f3b7 Kostas Papadimitriou
        self.assertEqual(r.status_code, 403)
156 c4d1f3b7 Kostas Papadimitriou
157 c4d1f3b7 Kostas Papadimitriou
        # user not in helpdesk group gets 403
158 c4d1f3b7 Kostas Papadimitriou
        r = self.client.get(reverse('helpdesk-index'))
159 c4d1f3b7 Kostas Papadimitriou
        self.assertEqual(r.status_code, 403)
160 505a121e Kostas Papadimitriou
        r = self.client.get(reverse('helpdesk-details',
161 505a121e Kostas Papadimitriou
                                    args=['testuser@test.com']))
162 c4d1f3b7 Kostas Papadimitriou
        self.assertEqual(r.status_code, 403)
163 c4d1f3b7 Kostas Papadimitriou
164 c4d1f3b7 Kostas Papadimitriou
        # user with helpdesk group gets 200
165 c4d1f3b7 Kostas Papadimitriou
        r = self.client.get(reverse('helpdesk-index'), user_token="0001")
166 c4d1f3b7 Kostas Papadimitriou
        self.assertEqual(r.status_code, 200)
167 505a121e Kostas Papadimitriou
        r = self.client.get(reverse('helpdesk-details',
168 505a121e Kostas Papadimitriou
                                    args=['testuser@test.com']),
169 505a121e Kostas Papadimitriou
                            user_token="0001")
170 c4d1f3b7 Kostas Papadimitriou
        self.assertEqual(r.status_code, 200)
171 c4d1f3b7 Kostas Papadimitriou
172 505a121e Kostas Papadimitriou
        r = self.client.post(reverse('helpdesk-suspend-vm', args=(1001,)))
173 505a121e Kostas Papadimitriou
        r = self.client.get(reverse('helpdesk-suspend-vm', args=(1001,)),
174 505a121e Kostas Papadimitriou
                            user_token="0001", data={'token': '1234'})
175 505a121e Kostas Papadimitriou
        self.assertEqual(r.status_code, 403)
176 505a121e Kostas Papadimitriou
        r = self.client.get(reverse('helpdesk-suspend-vm', args=(1001,)),
177 505a121e Kostas Papadimitriou
                            user_token="0001")
178 505a121e Kostas Papadimitriou
        self.assertEqual(r.status_code, 403)
179 505a121e Kostas Papadimitriou
        r = self.client.post(reverse('helpdesk-suspend-vm', args=(1001,)),
180 505a121e Kostas Papadimitriou
                             user_token="0001", data={'token': '0001'})
181 505a121e Kostas Papadimitriou
        self.assertEqual(r.status_code, 302)
182 505a121e Kostas Papadimitriou
        r = self.client.post(reverse('helpdesk-suspend-vm', args=(1001,)),
183 505a121e Kostas Papadimitriou
                             user_token="0000", data={'token': '0000'})
184 505a121e Kostas Papadimitriou
        self.assertEqual(r.status_code, 403)
185 505a121e Kostas Papadimitriou
186 505a121e Kostas Papadimitriou
    def test_suspend_vm(self):
187 505a121e Kostas Papadimitriou
        r = self.client.get(reverse('helpdesk-details',
188 505a121e Kostas Papadimitriou
                                    args=['testuser@test.com']),
189 505a121e Kostas Papadimitriou
                            user_token="0001")
190 505a121e Kostas Papadimitriou
        self.assertEqual(r.status_code, 200)
191 505a121e Kostas Papadimitriou
        vmid = r.context['vms'][0].pk
192 505a121e Kostas Papadimitriou
        r = self.client.post(reverse('helpdesk-suspend-vm', args=(vmid,)),
193 505a121e Kostas Papadimitriou
                             data={'token': '0001'}, user_token="0001")
194 505a121e Kostas Papadimitriou
        self.assertEqual(r.status_code, 302)
195 505a121e Kostas Papadimitriou
196 505a121e Kostas Papadimitriou
        r = self.client.get(reverse('helpdesk-details',
197 505a121e Kostas Papadimitriou
                                    args=['testuser@test.com']),
198 505a121e Kostas Papadimitriou
                            user_token="0001")
199 505a121e Kostas Papadimitriou
        self.assertTrue(r.context['vms'][0].suspended)
200 505a121e Kostas Papadimitriou
201 505a121e Kostas Papadimitriou
        r = self.client.post(reverse('helpdesk-suspend-vm-release',
202 505a121e Kostas Papadimitriou
                                     args=(vmid,)), data={'token': '0001'},
203 505a121e Kostas Papadimitriou
                             user_token="0001")
204 505a121e Kostas Papadimitriou
        self.assertEqual(r.status_code, 302)
205 505a121e Kostas Papadimitriou
        r = self.client.get(reverse('helpdesk-details',
206 505a121e Kostas Papadimitriou
                                    args=['testuser@test.com']),
207 505a121e Kostas Papadimitriou
                            user_token="0001")
208 505a121e Kostas Papadimitriou
        self.assertFalse(r.context['vms'][0].suspended)
209 505a121e Kostas Papadimitriou
210 c4d1f3b7 Kostas Papadimitriou
    def test_results_get_filtered(self):
211 c4d1f3b7 Kostas Papadimitriou
        """
212 c4d1f3b7 Kostas Papadimitriou
        Test that view context data are filtered based on userid provided.
213 c4d1f3b7 Kostas Papadimitriou
        Check helpdesk_test.json to see the existing database data.
214 c4d1f3b7 Kostas Papadimitriou
        """
215 c4d1f3b7 Kostas Papadimitriou
216 505a121e Kostas Papadimitriou
        # 'testuser@test.com' details, see
217 505a121e Kostas Papadimitriou
        # helpdes/fixtures/helpdesk_test.json for more details
218 505a121e Kostas Papadimitriou
        r = self.client.get(reverse('helpdesk-details',
219 505a121e Kostas Papadimitriou
                                    args=['testuser@test.com']),
220 505a121e Kostas Papadimitriou
                            user_token="0001")
221 c4d1f3b7 Kostas Papadimitriou
        account = r.context['account']
222 c4d1f3b7 Kostas Papadimitriou
        vms = r.context['vms']
223 c4d1f3b7 Kostas Papadimitriou
        nets = r.context['networks']
224 505a121e Kostas Papadimitriou
        self.assertEqual(account, USER1)
225 c4d1f3b7 Kostas Papadimitriou
        self.assertEqual(vms[0].name, "user1 vm")
226 c4d1f3b7 Kostas Papadimitriou
        self.assertEqual(vms.count(), 1)
227 505a121e Kostas Papadimitriou
        self.assertEqual(len(nets), 1)
228 9e3519e0 Kostas Papadimitriou
        self.assertEqual(r.context['account_exists'], True)
229 c4d1f3b7 Kostas Papadimitriou
230 505a121e Kostas Papadimitriou
        # 'testuser2@test.com' details, see helpdesk
231 505a121e Kostas Papadimitriou
        # /fixtures/helpdesk_test.json for more details
232 505a121e Kostas Papadimitriou
        r = self.client.get(reverse('helpdesk-details',
233 505a121e Kostas Papadimitriou
                                    args=['testuser2@test.com']),
234 505a121e Kostas Papadimitriou
                            user_token="0001")
235 c4d1f3b7 Kostas Papadimitriou
        account = r.context['account']
236 c4d1f3b7 Kostas Papadimitriou
        vms = r.context['vms']
237 c4d1f3b7 Kostas Papadimitriou
        nets = r.context['networks']
238 505a121e Kostas Papadimitriou
        self.assertEqual(account, USER2)
239 c4d1f3b7 Kostas Papadimitriou
        self.assertEqual(vms.count(), 2)
240 d91de78c Christos Stavrakakis
        self.assertEqual(sorted([vms[0].name, vms[1].name]),
241 d91de78c Christos Stavrakakis
                         sorted(["user2 vm1", "user2 vm2"]))
242 505a121e Kostas Papadimitriou
        self.assertEqual(len(nets), 0)
243 9e3519e0 Kostas Papadimitriou
        self.assertEqual(r.context['account_exists'], True)
244 9e3519e0 Kostas Papadimitriou
245 505a121e Kostas Papadimitriou
        # 'testuser5@test.com' does not exist, should be redirected to
246 505a121e Kostas Papadimitriou
        # helpdesk home
247 505a121e Kostas Papadimitriou
        r = self.client.get(reverse('helpdesk-details',
248 505a121e Kostas Papadimitriou
                                    args=['testuser5@test.com']),
249 505a121e Kostas Papadimitriou
                            user_token="0001")
250 9e3519e0 Kostas Papadimitriou
        vms = r.context['vms']
251 9e3519e0 Kostas Papadimitriou
        self.assertEqual(r.context['account_exists'], False)
252 9e3519e0 Kostas Papadimitriou
        self.assertEqual(vms.count(), 0)
253 cc5c8608 Kostas Papadimitriou
254 cc5c8608 Kostas Papadimitriou
    def test_start_shutdown(self):
255 cc5c8608 Kostas Papadimitriou
        from synnefo.logic import backend
256 cc5c8608 Kostas Papadimitriou
257 cc5c8608 Kostas Papadimitriou
        self.vm1 = mfactory.VirtualMachineFactory(userid=USER1)
258 cc5c8608 Kostas Papadimitriou
        pk = self.vm1.pk
259 cc5c8608 Kostas Papadimitriou
260 cc5c8608 Kostas Papadimitriou
        r = self.client.post(reverse('helpdesk-vm-shutdown', args=(pk,)))
261 cc5c8608 Kostas Papadimitriou
        self.assertEqual(r.status_code, 403)
262 cc5c8608 Kostas Papadimitriou
263 cc5c8608 Kostas Papadimitriou
        r = self.client.post(reverse('helpdesk-vm-shutdown', args=(pk,)),
264 cc5c8608 Kostas Papadimitriou
                             data={'token': '0001'})
265 cc5c8608 Kostas Papadimitriou
        self.assertEqual(r.status_code, 403)
266 cc5c8608 Kostas Papadimitriou
267 cc5c8608 Kostas Papadimitriou
        backend.shutdown_instance = shutdown = mock.Mock()
268 cc5c8608 Kostas Papadimitriou
        self.vm1.operstate = 'STARTED'
269 cc5c8608 Kostas Papadimitriou
        self.vm1.save()
270 cc5c8608 Kostas Papadimitriou
        r = self.client.post(reverse('helpdesk-vm-shutdown', args=(pk,)),
271 cc5c8608 Kostas Papadimitriou
                             data={'token': '0001'}, user_token='0001')
272 cc5c8608 Kostas Papadimitriou
        self.assertEqual(r.status_code, 302)
273 cc5c8608 Kostas Papadimitriou
        self.assertTrue(shutdown.called)
274 cc5c8608 Kostas Papadimitriou
        self.assertEqual(len(shutdown.mock_calls), 1)
275 cc5c8608 Kostas Papadimitriou
276 cc5c8608 Kostas Papadimitriou
        backend.startup_instance = startup = mock.Mock()
277 cc5c8608 Kostas Papadimitriou
        self.vm1.operstate = 'STOPPED'
278 cc5c8608 Kostas Papadimitriou
        self.vm1.save()
279 cc5c8608 Kostas Papadimitriou
        r = self.client.post(reverse('helpdesk-vm-start', args=(pk,)),
280 cc5c8608 Kostas Papadimitriou
                             data={'token': '0001'}, user_token='0001')
281 cc5c8608 Kostas Papadimitriou
        self.assertEqual(r.status_code, 302)
282 cc5c8608 Kostas Papadimitriou
        self.assertTrue(startup.called)
283 cc5c8608 Kostas Papadimitriou
        self.assertEqual(len(startup.mock_calls), 1)