Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
itminedu
synnefo
Commits
fdc452c6
Commit
fdc452c6
authored
Apr 15, 2011
by
Georgios Gousios
Browse files
Merge branch 'master' of
https://code.grnet.gr/git/synnefo
parents
3316449a
de71e571
Changes
15
Hide whitespace changes
Inline
Side-by-side
README.develop
View file @
fdc452c6
...
...
@@ -171,19 +171,18 @@ print out DDL statements. It should not fail.
$ ./bin/python manage.py loaddata db/fixtures/flavors.json
$ ./bin/python manage.py loaddata db/fixtures/images.json
The following fi
c
tures can be loaded optionally depending on
The following fi
x
tures can be loaded optionally depending on
testing requirements:
$ ./bin/python manage.py loaddata db/fixtures/vms.json
$ ./bin/python manage.py loaddata db/fixtures/initial_data.json
$ ./bin/python manage.py loaddata db/fixtures/disks.json
7. Set the BACKEND_PREFIX_ID variable to some unique prefix, e.g. your commit
username
8. Start the system
$ ./bin/python db/db_controller.py #DB synch daemon
$ ./bin/python manage.py runserver #Django
$ ./bin/python db/db_controller.py #
DB synch daemon
$ ./bin/python manage.py runserver #
Django
9. (Hopefully) Done
...
...
api/actions.py
View file @
fdc452c6
...
...
@@ -38,11 +38,26 @@ def get_console(request, vm, args):
"""Arrange for an OOB console of the specified type
This method arranges for an OOB console of the specified type.
Only "vnc" type consoles are supported for now.
Only consoles of type "vnc" are supported for now.
It uses a running instance of vncauthproxy to setup proper
VNC forwarding with a random password, then returns the necessary
VNC connection info to the caller.
JSON Request: {
"console": {
"type": "vnc"
}
}
JSON Reply: {
"vnc": {
"host": "fqdn_here",
"port": a_port_here,
"password": "a_password_here"
}
}
"""
# Normal Response Code: 200
# Error Response Codes: computeFault (400, 500),
...
...
@@ -55,28 +70,39 @@ def get_console(request, vm, args):
# overLimit (413)
try
:
console_type
=
args
.
get
(
'type'
,
''
)
if
console_type
!=
'
VNC
'
:
raise
BadRequest
(
message
=
"type can only be '
VNC
'"
)
if
console_type
!=
'
vnc
'
:
raise
BadRequest
(
message
=
"type can only be '
vnc
'"
)
except
KeyError
:
raise
BadRequest
()
# Use RAPI to get VNC console information for this instance
if
get_rsapi_state
(
vm
)
!=
'ACTIVE'
:
raise
BadRequest
(
message
=
"Server not in ACTIVE state"
)
console_data
=
rapi
.
GetInstanceConsole
(
vm
.
backend_id
)
if
settings
.
TEST
:
console_data
=
{
'kind'
:
'vnc'
,
'host'
:
'ganeti_node'
,
'port'
:
1000
}
else
:
console_data
=
rapi
.
GetInstanceConsole
(
vm
.
backend_id
)
if
console_data
[
'kind'
]
!=
'vnc'
:
raise
ServiceUnavailable
()
# Let vncauthproxy decide on the source port.
#
FIXME
# sport = 0
sport
=
console_data
[
'port'
]
-
100
0
#
The alternative: static allocation, e.g.
# sport =
console_data['port'] - 100
0
sport
=
0
daddr
=
console_data
[
'host'
]
dport
=
console_data
[
'port'
]
passwd
=
random_password
()
request_vnc_forwarding
(
sport
,
daddr
,
dport
,
passwd
)
vnc
=
{
'host'
:
getfqdn
(),
'port'
:
sport
,
'password'
:
passwd
}
try
:
if
settings
.
TEST
:
fwd
=
{
'source_port'
:
1234
,
'status'
:
'OK'
}
else
:
fwd
=
request_vnc_forwarding
(
sport
,
daddr
,
dport
,
passwd
)
if
fwd
[
'status'
]
!=
"OK"
:
raise
ServiceUnavailable
()
vnc
=
{
'host'
:
getfqdn
(),
'port'
:
fwd
[
'source_port'
],
'password'
:
passwd
}
except
Exception
:
raise
ServiceUnavailable
(
"Could not allocate VNC console port"
)
# Format to be reviewed by [verigak], FIXME
if
request
.
serialization
==
'xml'
:
...
...
@@ -84,7 +110,7 @@ def get_console(request, vm, args):
data
=
render_to_string
(
'vnc.xml'
,
{
'vnc'
:
vnc
})
else
:
mimetype
=
'application/json'
data
=
json
.
dumps
(
vnc
)
data
=
json
.
dumps
(
{
'
vnc
'
:
vnc
}
)
return
HttpResponse
(
data
,
mimetype
=
mimetype
,
status
=
200
)
...
...
api/faults.py
View file @
fdc452c6
...
...
@@ -6,9 +6,9 @@ def camelCase(s):
return
s
[
0
].
lower
()
+
s
[
1
:]
class
Fault
(
Base
Exception
):
class
Fault
(
Exception
):
def
__init__
(
self
,
message
=
''
,
details
=
''
,
name
=
''
):
Base
Exception
.
__init__
(
self
,
message
,
details
,
name
)
Exception
.
__init__
(
self
,
message
,
details
,
name
)
self
.
message
=
message
self
.
details
=
details
self
.
name
=
name
or
camelCase
(
self
.
__class__
.
__name__
)
...
...
api/images.py
View file @
fdc452c6
...
...
@@ -220,7 +220,7 @@ def update_metadata(request, image_id):
except
ImageMetadata
.
DoesNotExist
:
pass
# Ignore non-existent metadata
return
render_metadata
(
request
,
meta
dat
a
,
status
=
201
)
return
render_metadata
(
request
,
up
dat
ed
,
status
=
201
)
@
api_method
(
'GET'
)
def
get_metadata_item
(
request
,
image_id
,
key
):
...
...
api/servers.py
View file @
fdc452c6
...
...
@@ -178,17 +178,10 @@ def create_server(request):
# so that it gets a vm.id and vm.backend_id is valid.
vm
.
save
()
if
request
.
META
.
get
(
'SERVER_NAME'
,
None
)
==
'testserver'
:
backend_name
=
'test-server'
dry_run
=
True
else
:
backend_name
=
vm
.
backend_id
dry_run
=
False
try
:
jobId
=
rapi
.
CreateInstance
(
mode
=
'create'
,
name
=
backend_
name
,
name
=
vm
.
backend_
id
,
disk_template
=
'plain'
,
disks
=
[{
"size"
:
2000
}],
#FIXME: Always ask for a 2GB disk for now
nics
=
[{}],
...
...
@@ -196,7 +189,7 @@ def create_server(request):
ip_check
=
False
,
name_check
=
False
,
pnode
=
rapi
.
GetNodes
()[
0
],
#TODO: verify if this is necessary
dry_run
=
dry_run
,
dry_run
=
settings
.
TEST
,
beparams
=
dict
(
auto_balance
=
True
,
vcpus
=
flavor
.
cpu
,
memory
=
flavor
.
ram
))
except
GanetiApiError
:
vm
.
delete
()
...
...
@@ -370,7 +363,7 @@ def update_metadata(request, server_id):
except
VirtualMachineMetadata
.
DoesNotExist
:
pass
# Ignore non-existent metadata
return
render_metadata
(
request
,
meta
dat
a
,
status
=
201
)
return
render_metadata
(
request
,
up
dat
ed
,
status
=
201
)
@
api_method
(
'GET'
)
def
get_metadata_item
(
request
,
server_id
,
key
):
...
...
api/tests.py
View file @
fdc452c6
...
...
@@ -2,7 +2,11 @@
# Copyright (c) 2010 Greek Research and Technology Network
#
from
__future__
import
with_statement
from
collections
import
defaultdict
from
email.utils
import
parsedate
from
random
import
choice
,
randint
,
sample
from
time
import
mktime
import
datetime
...
...
@@ -12,8 +16,7 @@ from django.test import TestCase
from
django.test.client
import
Client
#from synnefo.api.tests_auth import AuthTestCase
from
synnefo.db.models
import
VirtualMachine
,
VirtualMachineGroup
from
synnefo.db.models
import
Flavor
,
Image
from
synnefo.db.models
import
*
from
synnefo.logic
import
utils
...
...
@@ -344,77 +347,380 @@ class APITestCase(TestCase):
self
.
assertEqual
(
response
.
status_code
,
201
)
class
APITestCase2
(
TestCase
):
"""An attempt for a more thorough test scenario."""
def
create_users
(
n
=
1
):
for
i
in
range
(
n
):
SynnefoUser
.
objects
.
create
(
name
=
'User %d'
%
i
,
credit
=
0
)
def
create_flavors
(
n
=
1
):
for
i
in
range
(
n
):
Flavor
.
objects
.
create
(
cpu
=
randint
(
1
,
4
),
ram
=
randint
(
1
,
8
)
*
512
,
disk
=
randint
(
1
,
40
))
def
create_images
(
n
=
1
):
users
=
SynnefoUser
.
objects
.
all
()
for
i
in
range
(
n
):
Image
.
objects
.
create
(
name
=
'Image %d'
%
(
i
+
1
),
state
=
'ACTIVE'
,
owner
=
choice
(
users
))
def
create_image_metadata
(
n
=
1
):
images
=
Image
.
objects
.
all
()
for
i
in
range
(
n
):
ImageMetadata
.
objects
.
create
(
meta_key
=
'Key%d'
%
(
i
+
1
),
meta_value
=
'Value %d'
%
(
i
+
1
),
image
=
choice
(
images
))
def
create_servers
(
n
=
1
):
users
=
SynnefoUser
.
objects
.
all
()
flavors
=
Flavor
.
objects
.
all
()
images
=
Image
.
objects
.
all
()
for
i
in
range
(
n
):
VirtualMachine
.
objects
.
create
(
name
=
'Server %d'
%
(
i
+
1
),
owner
=
choice
(
users
),
sourceimage
=
choice
(
images
),
hostid
=
str
(
i
),
ipfour
=
'0.0.0.0'
,
ipsix
=
'::1'
,
flavor
=
choice
(
flavors
))
def
create_server_metadata
(
n
=
1
):
servers
=
VirtualMachine
.
objects
.
all
()
for
i
in
range
(
n
):
VirtualMachineMetadata
.
objects
.
create
(
meta_key
=
'Key%d'
%
(
i
+
1
),
meta_value
=
'Value %d'
%
(
i
+
1
),
vm
=
choice
(
servers
))
class
AssertInvariant
(
object
):
def
__init__
(
self
,
callable
,
*
args
,
**
kwargs
):
self
.
callable
=
callable
self
.
args
=
args
self
.
kwargs
=
kwargs
def
__enter__
(
self
):
self
.
value
=
self
.
callable
(
*
self
.
args
,
**
self
.
kwargs
)
return
self
.
value
fixtures
=
[
'api_test_data2'
]
def
__exit__
(
self
,
type
,
value
,
tb
):
assert
self
.
value
==
self
.
callable
(
*
self
.
args
,
**
self
.
kwargs
)
class
BaseTestCase
(
TestCase
):
USERS
=
1
FLAVORS
=
1
IMAGES
=
1
SERVERS
=
1
SERVER_METADATA
=
0
IMAGE_METADATA
=
0
def
setUp
(
self
):
self
.
client
=
Client
()
self
.
server_id
=
0
def
create_server_name
(
self
):
self
.
server_id
+=
1
return
'server%d'
%
self
.
server_id
def
test_create_server_json
(
self
):
TEMPLATE
=
'''
{
"server" : {
"name" : "%(name)s",
"flavorRef" : "%(flavorRef)s",
"imageRef" : "%(imageRef)s"
}
}
'''
def
new_server
(
imageRef
=
1
,
flavorRef
=
1
):
name
=
self
.
create_server_name
()
return
name
,
TEMPLATE
%
dict
(
name
=
name
,
imageRef
=
imageRef
,
flavorRef
=
flavorRef
)
def
verify_response
(
response
,
name
):
assert
response
.
status_code
==
202
reply
=
json
.
loads
(
response
.
content
)
server
=
reply
[
'server'
]
assert
server
[
'name'
]
==
name
assert
server
[
'imageRef'
]
==
1
assert
server
[
'flavorRef'
]
==
1
assert
server
[
'status'
]
==
'BUILD'
assert
server
[
'adminPass'
]
assert
server
[
'addresses'
]
def
verify_error
(
response
,
code
,
name
):
assert
response
.
status_code
==
code
reply
=
json
.
loads
(
response
.
content
)
assert
name
in
reply
assert
reply
[
name
][
'code'
]
==
code
name
,
data
=
new_server
()
url
=
'/api/v1.1/servers'
response
=
self
.
client
.
post
(
url
,
content_type
=
'application/json'
,
data
=
data
)
verify_response
(
response
,
name
)
name
,
data
=
new_server
()
url
=
'/api/v1.1/servers.json'
response
=
self
.
client
.
post
(
url
,
content_type
=
'application/json'
,
data
=
data
)
verify_response
(
response
,
name
)
name
,
data
=
new_server
()
url
=
'/api/v1.1/servers.json'
response
=
self
.
client
.
post
(
url
,
content_type
=
'application/json'
,
data
=
data
,
HTTP_ACCEPT
=
'application/xml'
)
verify_response
(
response
,
name
)
name
,
data
=
new_server
(
imageRef
=
0
)
url
=
'/api/v1.1/servers'
response
=
self
.
client
.
post
(
url
,
content_type
=
'application/json'
,
data
=
data
)
verify_error
(
response
,
404
,
'itemNotFound'
)
name
,
data
=
new_server
(
flavorRef
=
0
)
url
=
'/api/v1.1/servers'
response
=
self
.
client
.
post
(
url
,
content_type
=
'application/json'
,
data
=
data
)
verify_error
(
response
,
404
,
'itemNotFound'
)
url
=
'/api/v1.1/servers'
response
=
self
.
client
.
post
(
url
,
content_type
=
'application/json'
,
data
=
'INVALID'
)
verify_error
(
response
,
400
,
'badRequest'
)
create_users
(
self
.
USERS
)
create_flavors
(
self
.
FLAVORS
)
create_images
(
self
.
IMAGES
)
create_image_metadata
(
self
.
IMAGE_METADATA
)
create_servers
(
self
.
SERVERS
)
create_server_metadata
(
self
.
SERVER_METADATA
)
def
assertFault
(
self
,
response
,
status_code
,
name
):
self
.
assertEqual
(
response
.
status_code
,
status_code
)
fault
=
json
.
loads
(
response
.
content
)
self
.
assertEqual
(
fault
.
keys
(),
[
name
])
def
assertBadRequest
(
self
,
response
):
self
.
assertFault
(
response
,
400
,
'badRequest'
)
def
assertItemNotFound
(
self
,
response
):
self
.
assertFault
(
response
,
404
,
'itemNotFound'
)
def
list_metadata
(
self
,
path
):
response
=
self
.
client
.
get
(
path
)
self
.
assertTrue
(
response
.
status_code
in
(
200
,
203
))
reply
=
json
.
loads
(
response
.
content
)
self
.
assertEqual
(
reply
.
keys
(),
[
'metadata'
])
self
.
assertEqual
(
reply
[
'metadata'
].
keys
(),
[
'values'
])
return
reply
[
'metadata'
][
'values'
]
def
list_server_metadata
(
self
,
server_id
):
path
=
'/api/v1.1/servers/%d/meta'
%
server_id
return
self
.
list_metadata
(
path
)
def
list_image_metadata
(
self
,
image_id
):
path
=
'/api/v1.1/images/%d/meta'
%
image_id
return
self
.
list_metadata
(
path
)
def
update_metadata
(
self
,
path
,
metadata
):
data
=
json
.
dumps
({
'metadata'
:
metadata
})
response
=
self
.
client
.
post
(
path
,
data
,
content_type
=
'application/json'
)
self
.
assertEqual
(
response
.
status_code
,
201
)
reply
=
json
.
loads
(
response
.
content
)
self
.
assertEqual
(
reply
.
keys
(),
[
'metadata'
])
return
reply
[
'metadata'
]
def
update_server_metadata
(
self
,
server_id
,
metadata
):
path
=
'/api/v1.1/servers/%d/meta'
%
server_id
return
self
.
update_metadata
(
path
,
metadata
)
def
update_image_metadata
(
self
,
image_id
,
metadata
):
path
=
'/api/v1.1/images/%d/meta'
%
image_id
return
self
.
update_metadata
(
path
,
metadata
)
def
create_server_meta
(
self
,
server_id
,
meta
):
key
=
meta
.
keys
()[
0
]
path
=
'/api/v1.1/servers/%d/meta/%s'
%
(
server_id
,
key
)
data
=
json
.
dumps
({
'meta'
:
meta
})
response
=
self
.
client
.
put
(
path
,
data
,
content_type
=
'application/json'
)
self
.
assertEqual
(
response
.
status_code
,
201
)
reply
=
json
.
loads
(
response
.
content
)
self
.
assertEqual
(
reply
.
keys
(),
[
'meta'
])
response_meta
=
reply
[
'meta'
]
self
.
assertEqual
(
response_meta
,
meta
)
def
get_all_server_metadata
(
self
):
metadata
=
defaultdict
(
dict
)
for
m
in
VirtualMachineMetadata
.
objects
.
all
():
metadata
[
m
.
vm
.
id
][
m
.
meta_key
]
=
m
.
meta_value
return
metadata
def
get_all_image_metadata
(
self
):
metadata
=
defaultdict
(
dict
)
for
m
in
ImageMetadata
.
objects
.
all
():
metadata
[
m
.
image
.
id
][
m
.
meta_key
]
=
m
.
meta_value
return
metadata
class
ListServerMetadata
(
BaseTestCase
):
SERVERS
=
5
SERVER_METADATA
=
100
def
test_list_metadata
(
self
):
with
AssertInvariant
(
self
.
get_all_server_metadata
)
as
metadata
:
for
vm
in
VirtualMachine
.
objects
.
all
():
response_metadata
=
self
.
list_server_metadata
(
vm
.
id
)
self
.
assertEqual
(
response_metadata
,
metadata
[
vm
.
id
])
def
test_invalid_server
(
self
):
with
AssertInvariant
(
self
.
get_all_server_metadata
):
response
=
self
.
client
.
get
(
'/api/v1.1/servers/0/meta'
)
self
.
assertItemNotFound
(
response
)
class
UpdateServerMetadata
(
BaseTestCase
):
SERVER_METADATA
=
10
def
test_update_metadata
(
self
):
metadata
=
self
.
get_all_server_metadata
()
server_id
=
choice
(
metadata
.
keys
())
new_metadata
=
{}
for
key
in
sample
(
metadata
[
server_id
].
keys
(),
3
):
new_metadata
[
key
]
=
'New %s value'
%
key
response_metadata
=
self
.
update_server_metadata
(
server_id
,
new_metadata
)
self
.
assertEqual
(
response_metadata
,
new_metadata
)
metadata
[
server_id
].
update
(
new_metadata
)
self
.
assertEqual
(
metadata
,
self
.
get_all_server_metadata
())
def
test_does_not_create
(
self
):
with
AssertInvariant
(
self
.
get_all_server_metadata
)
as
metadata
:
server_id
=
choice
(
metadata
.
keys
())
new_metadata
=
{
'Foo'
:
'Bar'
}
response_metadata
=
self
.
update_server_metadata
(
server_id
,
new_metadata
)
self
.
assertEqual
(
response_metadata
,
{})
def
test_invalid_data
(
self
):
with
AssertInvariant
(
self
.
get_all_server_metadata
)
as
metadata
:
server_id
=
choice
(
metadata
.
keys
())
path
=
'/api/v1.1/servers/%d/meta'
%
server_id
response
=
self
.
client
.
post
(
path
,
'metadata'
,
content_type
=
'application/json'
)
self
.
assertBadRequest
(
response
)
def
test_invalid_server
(
self
):
with
AssertInvariant
(
self
.
get_all_server_metadata
):
path
=
'/api/v1.1/servers/0/meta'
data
=
json
.
dumps
({
'metadata'
:
{
'Key1'
:
'A Value'
}})
response
=
self
.
client
.
post
(
path
,
data
,
content_type
=
'application/json'
)
self
.
assertItemNotFound
(
response
)
class
GetServerMetadataItem
(
BaseTestCase
):
SERVERS
=
5
SERVER_METADATA
=
100
def
test_get_metadata_item
(
self
):
with
AssertInvariant
(
self
.
get_all_server_metadata
)
as
metadata
:
server_id
=
choice
(
metadata
.
keys
())
key
=
choice
(
metadata
[
server_id
].
keys
())
path
=
'/api/v1.1/servers/%d/meta/%s'
%
(
server_id
,
key
)
response
=
self
.
client
.
get
(
path
)
self
.
assertTrue
(
response
.
status_code
in
(
200
,
203
))
reply
=
json
.
loads
(
response
.
content
)
self
.
assertEqual
(
reply
[
'meta'
],
{
key
:
metadata
[
server_id
][
key
]})
def
test_invalid_key
(
self
):
with
AssertInvariant
(
self
.
get_all_server_metadata
)
as
metadata
:
server_id
=
choice
(
metadata
.
keys
())
response
=
self
.
client
.
get
(
'/api/v1.1/servers/%d/meta/foo'
%
server_id
)
self
.
assertItemNotFound
(
response
)
def
test_invalid_server
(
self
):
with
AssertInvariant
(
self
.
get_all_server_metadata
):
response
=
self
.
client
.
get
(
'/api/v1.1/servers/0/meta/foo'
)
self
.
assertItemNotFound
(
response
)
class
CreateServerMetadataItem
(
BaseTestCase
):
SERVER_METADATA
=
10
def
test_create_metadata
(
self
):
metadata
=
self
.
get_all_server_metadata
()
server_id
=
choice
(
metadata
.
keys
())
meta
=
{
'Foo'
:
'Bar'
}
self
.
create_server_meta
(
server_id
,
meta
)
metadata
[
server_id
].
update
(
meta
)
self
.
assertEqual
(
metadata
,
self
.
get_all_server_metadata
())
def
test_update_metadata
(
self
):
metadata
=
self
.
get_all_server_metadata
()
server_id
=
choice
(
metadata
.
keys
())
key
=
choice
(
metadata
[
server_id
].
keys
())
meta
=
{
key
:
'New Value'
}
self
.
create_server_meta
(
server_id
,
meta
)
metadata
[
server_id
].
update
(
meta
)
self
.
assertEqual
(
metadata
,
self
.
get_all_server_metadata
())
def
test_invalid_server
(
self
):
with
AssertInvariant
(
self
.
get_all_server_metadata
):
path
=
'/api/v1.1/servers/0/meta/foo'
data
=
json
.
dumps
({
'meta'
:
{
'foo'
:
'bar'
}})
response
=
self
.
client
.
put
(
path
,
data
,
content_type
=
'application/json'
)
self
.
assertItemNotFound
(
response
)
def
test_invalid_key
(
self
):
with
AssertInvariant
(
self
.
get_all_server_metadata
)
as
metadata
:
server_id
=
choice
(
metadata
.
keys
())
path
=
'/api/v1.1/servers/%d/meta/baz'
%
server_id
data
=
json
.
dumps
({
'meta'
:
{
'foo'
:
'bar'
}})
response
=
self
.
client
.
put
(
path
,
data
,
content_type
=
'application/json'
)
self
.
assertBadRequest
(
response
)
def
test_invalid_data
(
self
):
with
AssertInvariant
(
self
.
get_all_server_metadata
)
as
metadata
:
server_id
=
choice
(
metadata
.
keys
())
path
=
'/api/v1.1/servers/%d/meta/foo'
%
server_id
response
=
self
.
client
.
put
(
path
,
'meta'
,
content_type
=
'application/json'
)
self
.
assertBadRequest
(
response
)
class
DeleteServerMetadataItem
(
BaseTestCase
):
SERVER_METADATA
=
10
def
test_delete_metadata
(
self
):
metadata
=
self
.
get_all_server_metadata
()
server_id
=
choice
(
metadata
.
keys
())
key
=
choice
(
metadata
[
server_id
].
keys
())
path
=
'/api/v1.1/servers/%d/meta/%s'
%
(
server_id
,
key
)
response
=
self
.
client
.
delete
(
path
)
self
.
assertEqual
(
response
.
status_code
,
204
)
metadata
[
server_id
].
pop
(
key
)
self
.
assertEqual
(
metadata
,
self
.
get_all_server_metadata
())
def
test_invalid_server
(
self
):
with
AssertInvariant
(
self
.
get_all_server_metadata
):
response
=
self
.
client
.
delete
(
'/api/v1.1/servers/9/meta/Key1'
)
self
.
assertItemNotFound
(
response
)
def
test_invalid_key
(
self
):
with
AssertInvariant
(
self
.
get_all_server_metadata
)
as
metadata
:
server_id
=
choice
(
metadata
.
keys
())
path
=
'/api/v1.1/servers/%d/meta/foo'
%
server_id
response
=
self
.
client
.
delete
(
path
)
self
.
assertItemNotFound
(
response
)
class
ListImageMetadata
(
BaseTestCase
):
IMAGES
=
5
IMAGE_METADATA
=
100
def
test_list_metadata
(
self
):
with
AssertInvariant
(
self
.
get_all_image_metadata
)
as
metadata
:
for
image
in
Image
.
objects
.
all
():
response_metadata
=
self
.
list_image_metadata
(
image
.
id
)
self
.
assertEqual
(
response_metadata
,
metadata
[
image
.
id
])
def
test_invalid_image
(
self
):
with
AssertInvariant
(
self
.
get_all_image_metadata
):
response
=
self
.
client
.
get
(
'/api/v1.1/images/0/meta'
)
self
.
assertItemNotFound
(
response
)
class
UpdateImageMetadata
(
BaseTestCase
):
IMAGE_METADATA
=
10
def
test_update_metadata
(
self
):
metadata
=
self
.
get_all_image_metadata
()
image_id
=
choice
(
metadata
.
keys
())
new_metadata
=
{}
for
key
in
sample
(
metadata
[
image_id
].
keys
(),
3
):
new_metadata
[
key
]
=
'New %s value'
%
key
response_metadata
=
self
.
update_image_metadata
(
image_id
,
new_metadata
)
self
.
assertEqual
(
response_metadata
,
new_metadata
)
metadata
[
image_id
].
update
(
new_metadata
)
self
.
assertEqual
(
metadata
,
self
.
get_all_image_metadata
())
def
test_does_not_create
(
self
):
with
AssertInvariant
(
self
.
get_all_image_metadata
)
as
metadata
:
image_id
=
choice
(
metadata
.
keys
())
new_metadata
=
{
'Foo'
:
'Bar'
}
response_metadata
=
self
.
update_image_metadata
(
image_id
,
new_metadata
)
self
.
assertEqual
(
response_metadata
,
{})
def
test_invalid_data
(
self
):
with
AssertInvariant
(
self
.
get_all_image_metadata
)
as
metadata
:
image_id
=
choice
(
metadata
.
keys
())
path
=
'/api/v1.1/images/%d/meta'
%
image_id
response
=
self
.
client
.
post
(
path
,
'metadata'
,
content_type
=
'application/json'
)
self
.
assertBadRequest
(
response
)
def
test_invalid_server
(
self
):
with
AssertInvariant
(
self
.
get_all_image_metadata
):
path
=
'/api/v1.1/images/0/meta'
data
=
json
.
dumps
({
'metadata'
:
{
'Key1'
:
'A Value'
}})
response
=
self
.
client
.
post
(
path
,
data
,
content_type
=
'application/json'
)
self
.
assertItemNotFound
(
response
)