Revision 2f0cd9e1
b/snf-astakos-app/astakos/test/README | ||
---|---|---|
1 |
Create the database: |
|
2 |
CREATE DATABASE astakos_test WITH ENCODING 'UTF8' LC_COLLATE='C' LC_CTYPE='C' TEMPLATE=template0; |
|
3 |
CREATE USER tester WITH PASSWORD 'test'; |
|
4 |
GRANT ALL PRIVILEGES ON DATABASE astakos_test TO tester; |
|
5 |
|
|
6 |
Setup the database: |
|
7 |
./setup.sh |
|
8 |
|
|
9 |
Launch server: |
|
10 |
./launch.sh |
|
11 |
|
|
12 |
Initialize (the first time you set up the database): |
|
13 |
./init.sh |
|
14 |
|
|
15 |
In terminal 1: ./submit-and-approve.py 1 dummy |
|
16 |
In terminal 2: ./join-and-leave.py 1 dummy |
b/snf-astakos-app/astakos/test/init.sh | ||
---|---|---|
1 |
#!/bin/sh |
|
2 |
|
|
3 |
d=`dirname $0` |
|
4 |
export SYNNEFO_SETTINGS_DIR=$d/settings |
|
5 |
snf-manage astakos-load-service-resources |
|
6 |
snf-manage user-add --active test@synnefo.org Tester Tester |
|
7 |
snf-manage user-add --active test2@synnefo.org Tester2 Tester2 |
b/snf-astakos-app/astakos/test/join-and-leave.py | ||
---|---|---|
1 |
#!/usr/bin/env python |
|
2 |
|
|
3 |
# Copyright 2013 GRNET S.A. All rights reserved. |
|
4 |
# |
|
5 |
# Redistribution and use in source and binary forms, with or |
|
6 |
# without modification, are permitted provided that the following |
|
7 |
# conditions are met: |
|
8 |
# |
|
9 |
# 1. Redistributions of source code must retain the above |
|
10 |
# copyright notice, this list of conditions and the following |
|
11 |
# disclaimer. |
|
12 |
# |
|
13 |
# 2. Redistributions in binary form must reproduce the above |
|
14 |
# copyright notice, this list of conditions and the following |
|
15 |
# disclaimer in the documentation and/or other materials |
|
16 |
# provided with the distribution. |
|
17 |
# |
|
18 |
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS |
|
19 |
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
|
20 |
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
|
21 |
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR |
|
22 |
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
23 |
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
|
24 |
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
|
25 |
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
26 |
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
27 |
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
|
28 |
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
29 |
# POSSIBILITY OF SUCH DAMAGE. |
|
30 |
# |
|
31 |
# The views and conclusions contained in the software and |
|
32 |
# documentation are those of the authors and should not be |
|
33 |
# interpreted as representing official policies, either expressed |
|
34 |
# or implied, of GRNET S.A. |
|
35 |
|
|
36 |
import os |
|
37 |
import sys |
|
38 |
|
|
39 |
path = os.path.dirname(os.path.realpath(__file__)) |
|
40 |
os.environ['SYNNEFO_SETTINGS_DIR'] = path + '/settings' |
|
41 |
os.environ['DJANGO_SETTINGS_MODULE'] = 'synnefo.settings' |
|
42 |
|
|
43 |
from astakos.im.functions import get_project_by_name, get_project_by_id |
|
44 |
from views import join, leave |
|
45 |
|
|
46 |
USAGE = "usage: join-and-leave <user_id> <project_id or name>" |
|
47 |
|
|
48 |
def main(): |
|
49 |
argv = sys.argv |
|
50 |
argc = len(sys.argv) |
|
51 |
|
|
52 |
if argc < 3: |
|
53 |
raise AttributeError(USAGE) |
|
54 |
try: |
|
55 |
user_id = int(argv[1]) |
|
56 |
proj = argv[2] |
|
57 |
except ValueError: |
|
58 |
raise AttributeError(USAGE) |
|
59 |
|
|
60 |
proj_id = resolve(proj) |
|
61 |
join_and_leave(proj_id, user_id) |
|
62 |
|
|
63 |
def resolve(proj): |
|
64 |
if proj.isdigit(): |
|
65 |
return proj |
|
66 |
else: |
|
67 |
try: |
|
68 |
return get_project_by_name(proj).id |
|
69 |
except: |
|
70 |
AttributeError(USAGE) |
|
71 |
|
|
72 |
def join_and_leave(proj_id, user_id, times=20): |
|
73 |
for i in range(times): |
|
74 |
try: |
|
75 |
print '%s: joining project %s' % (i, proj_id) |
|
76 |
join(proj_id, user_id) |
|
77 |
except Exception as e: |
|
78 |
print e |
|
79 |
try: |
|
80 |
print '%s: leaving project %s' % (i, proj_id) |
|
81 |
leave(proj_id, user_id) |
|
82 |
except Exception as e: |
|
83 |
print e |
|
84 |
|
|
85 |
|
|
86 |
if __name__ == "__main__": |
|
87 |
main() |
b/snf-astakos-app/astakos/test/launch.sh | ||
---|---|---|
1 |
#!/bin/bash |
|
2 |
|
|
3 |
cwd=`dirname $0` |
|
4 |
cd "$cwd" |
|
5 |
|
|
6 |
export SYNNEFO_SETTINGS_DIR=./settings |
|
7 |
HOST=127.0.0.1 |
|
8 |
|
|
9 |
pkill -f "runserver $HOST:8000" |
|
10 |
pkill -f "runserver $HOST:8008" |
|
11 |
|
|
12 |
snf-manage runserver $HOST:8000 & |
|
13 |
snf-manage runserver $HOST:8008 & |
b/snf-astakos-app/astakos/test/settings/local.conf | ||
---|---|---|
1 |
DEBUG = True |
|
2 |
ASTAKOS_COOKIE_SECURE = False |
|
3 |
SESSION_COOKIE_SECURE = False |
|
4 |
|
|
5 |
EMAIL_BACKEND='django.core.mail.backends.dummy.EmailBackend' |
|
6 |
|
|
7 |
DATABASES = { |
|
8 |
'default': { |
|
9 |
'ENGINE': 'django.db.backends.postgresql_psycopg2', |
|
10 |
'NAME': 'astakos_test', |
|
11 |
'USER': 'tester', |
|
12 |
'PASSWORD': 'test', |
|
13 |
'HOST': '127.0.0.1', |
|
14 |
'PORT': '5432', |
|
15 |
'OPTIONS' : {}, |
|
16 |
} |
|
17 |
} |
|
18 |
|
|
19 |
HOST = 'http://127.0.0.1' |
|
20 |
|
|
21 |
QUOTAHOLDER_URL = HOST + ':8008/quotaholder/v' |
|
22 |
QUOTAHOLDER_TOKEN = 'token' |
|
23 |
|
|
24 |
ASTAKOS_URL = HOST + ':8000/im/authenticate' |
|
25 |
ASTAKOS_BASEURL = HOST + ':8000/' |
|
26 |
ASTAKOS_IM_MODULES = ['local'] |
|
27 |
ASTAKOS_RECAPTCHA_ENABLED = False |
|
28 |
|
|
29 |
ASTAKOS_QUOTAHOLDER_URL = HOST + ':8008/quotaholder/v' |
|
30 |
ASTAKOS_QUOTAHOLDER_TOKEN = 'token' |
b/snf-astakos-app/astakos/test/setup.sh | ||
---|---|---|
1 |
#!/bin/sh |
|
2 |
|
|
3 |
d=`dirname $0` |
|
4 |
export SYNNEFO_SETTINGS_DIR=$d/settings |
|
5 |
snf-manage syncdb --noinput |
|
6 |
snf-manage migrate |
b/snf-astakos-app/astakos/test/submit-and-approve.py | ||
---|---|---|
1 |
#!/usr/bin/env python |
|
2 |
|
|
3 |
# Copyright 2013 GRNET S.A. All rights reserved. |
|
4 |
# |
|
5 |
# Redistribution and use in source and binary forms, with or |
|
6 |
# without modification, are permitted provided that the following |
|
7 |
# conditions are met: |
|
8 |
# |
|
9 |
# 1. Redistributions of source code must retain the above |
|
10 |
# copyright notice, this list of conditions and the following |
|
11 |
# disclaimer. |
|
12 |
# |
|
13 |
# 2. Redistributions in binary form must reproduce the above |
|
14 |
# copyright notice, this list of conditions and the following |
|
15 |
# disclaimer in the documentation and/or other materials |
|
16 |
# provided with the distribution. |
|
17 |
# |
|
18 |
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS |
|
19 |
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
|
20 |
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
|
21 |
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR |
|
22 |
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
23 |
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
|
24 |
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
|
25 |
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
26 |
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
27 |
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
|
28 |
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
29 |
# POSSIBILITY OF SUCH DAMAGE. |
|
30 |
# |
|
31 |
# The views and conclusions contained in the software and |
|
32 |
# documentation are those of the authors and should not be |
|
33 |
# interpreted as representing official policies, either expressed |
|
34 |
# or implied, of GRNET S.A. |
|
35 |
|
|
36 |
import os |
|
37 |
import sys |
|
38 |
import random |
|
39 |
import string |
|
40 |
|
|
41 |
path = os.path.dirname(os.path.realpath(__file__)) |
|
42 |
os.environ['SYNNEFO_SETTINGS_DIR'] = path + '/settings' |
|
43 |
os.environ['DJANGO_SETTINGS_MODULE'] = 'synnefo.settings' |
|
44 |
from astakos.im.models import Chain, ProjectApplication, Project |
|
45 |
from views import submit, approve |
|
46 |
|
|
47 |
USAGE = "usage: submit-and-approve <user_id> <precursor id or name>" |
|
48 |
|
|
49 |
def main(): |
|
50 |
argv = sys.argv |
|
51 |
argc = len(sys.argv) |
|
52 |
|
|
53 |
if argc < 3: |
|
54 |
raise AttributeError(USAGE) |
|
55 |
try: |
|
56 |
user_id = int(argv[1]) |
|
57 |
chain = argv[2] |
|
58 |
except ValueError: |
|
59 |
raise AttributeError(USAGE) |
|
60 |
|
|
61 |
prec, name = resolve(chain) |
|
62 |
submit_and_approve(name, user_id, prec) |
|
63 |
|
|
64 |
def rand_name(): |
|
65 |
char_set = string.ascii_letters + string.digits |
|
66 |
return ''.join(random.sample(char_set, 6)) |
|
67 |
|
|
68 |
def resolve_chain(chain): |
|
69 |
state, project, app = chain.full_state() |
|
70 |
if state not in Chain.PENDING_STATES and project is not None: |
|
71 |
app = project.application |
|
72 |
return app.id, app.name |
|
73 |
else: |
|
74 |
return app.id, app.name |
|
75 |
|
|
76 |
def resolve(chain): |
|
77 |
if chain is None: |
|
78 |
return None, rand_name() |
|
79 |
|
|
80 |
if chain.isdigit(): |
|
81 |
try: |
|
82 |
chain = Chain.objects.get(chain=chain) |
|
83 |
return resolve_chain(chain) |
|
84 |
except: |
|
85 |
raise AttributeError('there is no chain %s' % (chain,)) |
|
86 |
|
|
87 |
else: |
|
88 |
try: |
|
89 |
project = Project.objects.get(name=chain) |
|
90 |
return resolve_chain(project.id) |
|
91 |
except Project.DoesNotExist: |
|
92 |
try: |
|
93 |
apps = ProjectApplication.objects.filter(name=chain) |
|
94 |
last = apps.order_by('-id')[0] |
|
95 |
return last.id, chain |
|
96 |
except: |
|
97 |
return None, chain |
|
98 |
|
|
99 |
def submit_and_approve(name, user_id, prec, times=20): |
|
100 |
for i in range(times): |
|
101 |
try: |
|
102 |
print '%s: submitting with precursor %s' % (i, prec) |
|
103 |
app_id = submit(name, user_id, prec) |
|
104 |
prec = app_id |
|
105 |
except Exception as e: |
|
106 |
raise e |
|
107 |
try: |
|
108 |
print '%s: approving application %s' % (i, app_id) |
|
109 |
approve(app_id) |
|
110 |
except Exception as e: |
|
111 |
raise e |
|
112 |
|
|
113 |
if __name__ == "__main__": |
|
114 |
main() |
b/snf-astakos-app/astakos/test/views.py | ||
---|---|---|
1 |
# Copyright 2013 GRNET S.A. All rights reserved. |
|
2 |
# |
|
3 |
# Redistribution and use in source and binary forms, with or |
|
4 |
# without modification, are permitted provided that the following |
|
5 |
# conditions are met: |
|
6 |
# |
|
7 |
# 1. Redistributions of source code must retain the above |
|
8 |
# copyright notice, this list of conditions and the following |
|
9 |
# disclaimer. |
|
10 |
# |
|
11 |
# 2. Redistributions in binary form must reproduce the above |
|
12 |
# copyright notice, this list of conditions and the following |
|
13 |
# disclaimer in the documentation and/or other materials |
|
14 |
# provided with the distribution. |
|
15 |
# |
|
16 |
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS |
|
17 |
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
|
18 |
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
|
19 |
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR |
|
20 |
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
21 |
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
|
22 |
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
|
23 |
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
24 |
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
25 |
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
|
26 |
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
27 |
# POSSIBILITY OF SUCH DAMAGE. |
|
28 |
# |
|
29 |
# The views and conclusions contained in the software and |
|
30 |
# documentation are those of the authors and should not be |
|
31 |
# interpreted as representing official policies, either expressed |
|
32 |
# or implied, of GRNET S.A. |
|
33 |
|
|
34 |
from datetime import datetime, timedelta |
|
35 |
|
|
36 |
from astakos.im.models import AstakosUser, PendingMembershipError |
|
37 |
from astakos.im.functions import (join_project, leave_project, |
|
38 |
submit_application, approve_application) |
|
39 |
from astakos.im.project_xctx import project_transaction_context |
|
40 |
from astakos.im.retry_xctx import RetryException |
|
41 |
|
|
42 |
@project_transaction_context(sync=True) |
|
43 |
def join(proj_id, user_id, ctx=None): |
|
44 |
join_project(proj_id, user_id) |
|
45 |
|
|
46 |
@project_transaction_context(sync=True) |
|
47 |
def leave(proj_id, user_id, ctx=None): |
|
48 |
try: |
|
49 |
leave_project(proj_id, user_id) |
|
50 |
except PendingMembershipError as e: |
|
51 |
print e |
|
52 |
raise RetryException() |
|
53 |
|
|
54 |
@project_transaction_context(sync=True) |
|
55 |
def submit(name, user_id, prec, ctx=None): |
|
56 |
try: |
|
57 |
owner = AstakosUser.objects.get(id=user_id) |
|
58 |
except AstakosUser.DoesNotExist: |
|
59 |
raise AttributeError('user does not exist') |
|
60 |
|
|
61 |
resource_policies = [{'service': 'cyclades', |
|
62 |
'resource': 'network.private', |
|
63 |
'uplimit': 5}] |
|
64 |
data = {'owner': owner, |
|
65 |
'name': name, |
|
66 |
'precursor_application': prec, |
|
67 |
'end_date': datetime.now() + timedelta(days=1), |
|
68 |
'member_join_policy': 1, |
|
69 |
'member_leave_policy': 1, |
|
70 |
'resource_policies': resource_policies, |
|
71 |
} |
|
72 |
|
|
73 |
app = submit_application(data, request_user=owner) |
|
74 |
return app.id |
|
75 |
|
|
76 |
@project_transaction_context(sync=True) |
|
77 |
def approve(app_id, ctx=None): |
|
78 |
approve_application(app_id) |
Also available in: Unified diff