Commit f5f2dc53 authored by Stavros Sachtouris's avatar Stavros Sachtouris
Browse files

Rename tests to livetest in kamaki.clients

Update documentation to reflect these changes
parent c501d3df
......@@ -105,7 +105,7 @@ A more detailed example of using virtual env can be found at the `snf-image-crea
Install objpool (was: snf-common)
"""""""""""""""""""""""""""""""""
Since 0.6.2, kamaki is based on python-objpool. The objpool package is easy to install from source (even on windows platforms):
Kamaki is based on python-objpool. The objpool package is easy to install from source, even on windows platforms:
.. code-block:: console
......@@ -121,7 +121,7 @@ Kamaki can be downloaded from `this location <https://code.grnet.gr/projects/kam
.. code-block:: console
$ tar xvfz kamaki-0.6.2.tar.gz
$ tar xvfz kamaki-0.7.tar.gz
or it can be downloaded directly from the git repository:
......@@ -156,7 +156,7 @@ Kamaki can be installed on Mac OS X systems from source, by following the steps
Windows
-------
Since version 0.6.2 kamaki can run on Windows, either on standard Windows console, or inside an improved command line shell. The present guide presents a tested method for using kamaki in windows
Kamaki can run on Windows, either on standard Windows console, or inside an improved command line shell. The present guide presents a tested method for setting up kamaki in windows
Requirements
^^^^^^^^^^^^
......@@ -242,8 +242,6 @@ Install kamaki
$ python setup.py install
running install
...
Finished processing dependencies for kamaki==0.6.2
.. warning:: kamaki version should be 0.6.2 or better, otherwise it will not function. Users can test that by running::
Finished processing dependencies for kamaki==0.7
$ kamaki --version
......@@ -29,7 +29,7 @@ For installing any all of the following, consult the `kamaki installation guide
* progress
* Attach progress bars to various kamaki commands (e.g. kamaki store upload)
* Since version 0.6.1 kamaki "requires" progress version 1.0.2 or better
* If desired, progress version should be 1.0.2 or better
Any of the above features can be installed at any time before or after kamaki installation.
......@@ -157,15 +157,103 @@ The [global] group is treated by kamaki as a generic group for arbitrary options
Hidden features
^^^^^^^^^^^^^^^
Since version 0.6.1 kamaki contains a test suite for the kamaki.clients API. The test suite can be activated with the following option on the configuration file::
The livetest suite
""""""""""""""""""
[test]
cli=test_cli
Kamaki contains a live test suite for the kamaki.clients API, where "live" means that the tests are performed against active services that up and running. The live test package is named "livetest", it is accessible as kamaki.clients.livetest and it is designed to check the actual relation between kamaki and synnefo services.
After that, users can run "kamaki test" commands to unit-test the prepackaged client APIs. Unit-tests are still experimental and there is a high probability of false alarms due to some of the expected values being hard-coded in the testing code.
The livetest suite can be activated with the following option on the configuration file::
Since version 0.6.3, a quotaholder client is introduced as an advanced feature. Quotaholder client is mostly used as a client library for accessing a synnefo quota service, but it can also be allowed as a kamaki command set, but setting the quotaholder.cli and quotaholder.url methods:
[livetest]
cli=livetest_cli
In most tests, livetest will run as long as an Astakos identity manager service is accessible and kamaki is set up to authenticate a valid token on this server.
In specific, a setup file needs at least the following mandatory settings in the configuration file:
* If authentication information is used for default kamaki clients::
[astakos]
url=<Astakos Identity Manager URL>
token=<A valid user token>
* else if this authentication information is only for testing add this under [livetest]::
astakos_url=<Astakos Identity Manager URL>
astakos_token=<A valid user token>
Each service tested in livetest might need some more options under the [livetest] label, as shown bellow:
* kamaki livetest astakos::
astakos_email = <The valid email of testing user>
astakos_name = <The exact "real" name of testing user>
astakos_username = <The username of the testing user>
astakos_uuid = <The valid unique user id of the testing user>
* kamaki livetest pithos::
astakos_uuid = <The valid unique user id of the testing user>
* kamaki livetest cyclades / image::
image_id = <A valid image id used for testing>
image_local_path = <The local path of the testing image>
image_details = <A text file containing testing image details in a python dict>
- example image.details content:
{
u'id': u'b3e68235-3abd-4d60-adfe-1379a4f8d3fe',
u'metadata': {
u'values': {
u'description': u'Debian 6.0.6 (Squeeze) Base System',
u'gui': u'No GUI',
u'kernel': u'2.6.32',
u'os': u'debian',
u'osfamily': u'linux',
u'root_partition': u'1',
u'sortorder': u'1',
u'users': u'root'
}
},
u'name': u'Debian Base',
u'progress': u'100',
u'status': u'ACTIVE',
u'created': u'2012-11-19T14:54:57+00:00',
u'updated': u'2012-11-19T15:29:51+00:00'
}
flavor_details = <A text file containing the testing images' flavor details in a python dict>
- example flavor.details content:
{
u'name': u'C1R1drbd',
u'ram': 1024,
u'id': 1,
u'SNF:disk_template': u'drbd',
u'disk': 20,
u'cpu': 1
}
After setup, kamaki can run all tests::
$ kamaki livetest all
a specific test (e.g. astakos)::
$ kamaki livetest astakos
or a specific method from a service (e.g. astakos authenticate)::
$ kamaki livetest astakos authenticate
The quotaholder client
""""""""""""""""""""""
A quotaholder client is introduced as an advanced feature. Quotaholder client is mostly used as a client library for accessing a synnefo quota service, but it can also be allowed as a kamaki command set, but setting the quotaholder.cli and quotaholder.url methods::
[quotaholder]
cli=quotaholder_cli
url=<URL of quotaholder service>
Quotaholder is not tested in livetest
......@@ -35,27 +35,27 @@ from kamaki.cli.commands import errors
from kamaki.cli import command
from kamaki.cli.commands import _command_init
from kamaki.cli.command_tree import CommandTree
from kamaki.clients import tests
from kamaki.clients import livetest
from kamaki.cli.errors import raiseCLIError
test_cmds = CommandTree('test', 'Unitest clients')
_commands = [test_cmds]
livetest_cmds = CommandTree('livetest', 'Test clients on live servers')
_commands = [livetest_cmds]
class _test_init(_command_init):
class _livetest_init(_command_init):
def _run(self, client, method=None):
if method:
tests._main([client, method], config=self.config)
livetest._main([client, method], config=self.config)
else:
tests._main([client], config=self.config)
livetest._main([client], config=self.config)
def main(self, client, method=None):
return self._run(client, method)
@command(test_cmds)
class test_error(_test_init):
@command(livetest_cmds)
class livetest_error(_livetest_init):
"""Create an error message with optional message"""
@errors.generic.all
......@@ -71,8 +71,8 @@ class test_error(_test_init):
self._run(errmsg, importance, index)
@command(test_cmds)
class test_args(_test_init):
@command(livetest_cmds)
class livetest_args(_livetest_init):
"""Test how arguments are treated by kamaki"""
@errors.generic.all
......@@ -83,8 +83,8 @@ class test_args(_test_init):
self._run(args)
@command(test_cmds)
class test_all(_test_init):
@command(livetest_cmds)
class livetest_all(_livetest_init):
"""test all clients"""
@errors.generic.all
......@@ -96,8 +96,8 @@ class test_all(_test_init):
self._run()
@command(test_cmds)
class test_pithos(_test_init):
@command(livetest_cmds)
class livetest_pithos(_livetest_init):
""" test Pithos client"""
@errors.generic.all
......@@ -108,8 +108,8 @@ class test_pithos(_test_init):
self._run(method)
@command(test_cmds)
class test_cyclades(_test_init):
@command(livetest_cmds)
class livetest_cyclades(_livetest_init):
""" test Cyclades client"""
@errors.generic.all
......@@ -120,8 +120,8 @@ class test_cyclades(_test_init):
self._run(method)
@command(test_cmds)
class test_image(_test_init):
@command(livetest_cmds)
class livetest_image(_livetest_init):
""" test Image client"""
@errors.generic.all
......@@ -132,8 +132,8 @@ class test_image(_test_init):
self._run(method)
@command(test_cmds)
class test_astakos(_test_init):
@command(livetest_cmds)
class livetest_astakos(_livetest_init):
""" test Astakos client"""
@errors.generic.all
......@@ -144,8 +144,8 @@ class test_astakos(_test_init):
self._run(method)
@command(test_cmds)
class test_prints(_test_init):
@command(livetest_cmds)
class livetest_prints(_livetest_init):
""" user-test print methods for lists and dicts"""
d1 = {'key0a': 'val0a', 'key0b': 'val0b', 'key0c': 'val0c'}
......
......@@ -64,8 +64,12 @@ class Generic(TestCase):
def __getitem__(self, key):
key = self._key(key)
try:
r = self._fetched[key]
return r
return self._fetched[key]
except KeyError:
r = self._get_from_cnf(key)
return r
return self._get_from_cnf(key)
def _key(self, key):
......@@ -76,9 +80,10 @@ class Generic(TestCase):
def _get_from_cnf(self, key):
val = 0
if key[0]:
val = self._cnf.get('test', '%s_%s' % key) or self._cnf.get(*key)
keystr = '%s_%s' % key
val = self._cnf.get('livetest', keystr) or self._cnf.get(*key)
if not val:
val = self._cnf.get('test', key[1]) or self._cnf.get(
val = self._cnf.get('livetest', key[1]) or self._cnf.get(
'global',
key[1])
self._fetched[key] = val
......@@ -171,19 +176,19 @@ def main(argv):
def _main(argv, config=None):
suiteFew = TestSuite()
if len(argv) == 0 or argv[0] == 'pithos':
from kamaki.clients.tests.pithos import Pithos
from kamaki.clients.livetest.pithos import Pithos
test_method = 'test_%s' % (argv[1] if len(argv) > 1 else '000')
suiteFew.addTest(Pithos(test_method, config))
if len(argv) == 0 or argv[0] == 'cyclades':
from kamaki.clients.tests.cyclades import Cyclades
from kamaki.clients.livetest.cyclades import Cyclades
test_method = 'test_%s' % (argv[1] if len(argv) > 1 else '000')
suiteFew.addTest(Cyclades(test_method, config))
if len(argv) == 0 or argv[0] == 'image':
from kamaki.clients.tests.image import Image
from kamaki.clients.livetest.image import Image
test_method = 'test_%s' % (argv[1] if len(argv) > 1 else '000')
suiteFew.addTest(Image(test_method, config))
if len(argv) == 0 or argv[0] == 'astakos':
from kamaki.clients.tests.astakos import Astakos
from kamaki.clients.livetest.astakos import Astakos
test_method = 'test_%s' % (argv[1] if len(argv) > 1 else '000')
suiteFew.addTest(Astakos(test_method, config))
......@@ -193,5 +198,5 @@ if __name__ == '__main__':
parser = init_parser()
args, argv = parser.parse_known_args()
if len(argv) > 2 or getattr(args, 'help') or len(argv) < 1:
raise Exception('\tusage: tests <group> [command]')
raise Exception('\tusage: livetest <group> [command]')
main(argv)
......@@ -31,11 +31,11 @@
# interpreted as representing official policies, either expressed
# or implied, of GRNET S.A.
from kamaki.clients import tests
from kamaki.clients import livetest
from kamaki.clients.astakos import AstakosClient
class Astakos(tests.Generic):
class Astakos(livetest.Generic):
def setUp(self):
self.client = AstakosClient(
self['astakos', 'url'],
......
......@@ -33,11 +33,11 @@
import time
from kamaki.clients import tests, ClientError
from kamaki.clients import livetest, ClientError
from kamaki.clients.cyclades import CycladesClient
class Cyclades(tests.Generic):
class Cyclades(livetest.Generic):
"""Set up a Cyclades thorough test"""
def setUp(self):
print
......@@ -172,7 +172,7 @@ class Cyclades(tests.Generic):
def test_parallel_creation(self):
"""test create with multiple threads
Do not use this in regular tests
Do not use this in regular livetest
"""
from kamaki.clients import SilentEvent
c1 = SilentEvent(
......
......@@ -33,13 +33,13 @@
import time
from kamaki.clients import tests
from kamaki.clients import livetest
from kamaki.clients.cyclades import CycladesClient
from kamaki.clients.image import ImageClient
from kamaki.clients import ClientError
class Image(tests.Generic):
class Image(livetest.Generic):
def setUp(self):
self.now = time.mktime(time.gmtime())
......@@ -57,11 +57,9 @@ class Image(tests.Generic):
def _prepare_img(self):
f = open(self['image', 'local_path'], 'rb')
(token, uuid) = (self['token'], self['store', 'account'])
print('UUID HERE: %s (%s)' % (uuid, token))
if not uuid:
from kamaki.clients.astakos import AstakosClient
uuid = AstakosClient(self['astakos', 'url'], token).term('uuid')
print('UUID HERE: %s' % uuid)
from kamaki.clients.pithos import PithosClient
self.pithcli = PithosClient(self['store', 'url'], token, uuid)
cont = 'cont_%s' % self.now
......
......@@ -36,12 +36,12 @@ import datetime
from os import urandom
from tempfile import NamedTemporaryFile
from kamaki.clients import tests, ClientError
from kamaki.clients import livetest, ClientError
from kamaki.clients.pithos import PithosClient
from kamaki.clients.astakos import AstakosClient
class Pithos(tests.Generic):
class Pithos(livetest.Generic):
files = []
......@@ -1063,13 +1063,13 @@ class Pithos(tests.Generic):
read=['accX:groupA', 'u1', 'u2'],
write=['u2', 'u3']))
"""Append tests update, content_range, content_type, content_length"""
"""Append livetest update, content_range, content_type, content_length"""
newf.seek(0)
self.client.append_object(obj, newf)
r = self.client.object_get(obj)
self.assertTrue(r.text.startswith('Hello!'))
"""Overwrite tests update,
"""Overwrite livetest update,
content_type, content_length, content_range
"""
newf.seek(0)
......@@ -1077,7 +1077,7 @@ class Pithos(tests.Generic):
r = self.client.object_get(obj)
self.assertTrue(r.text.startswith('ello!'))
"""Truncate tests update,
"""Truncate livetest update,
content_range, content_type, object_bytes and source_object"""
r = self.client.truncate_object(obj, 5)
r = self.client.object_get(obj)
......
......@@ -446,9 +446,11 @@ class PithosClient(PithosRestAPI):
def _thread2file(self, flying, local_file, offset=0, **restargs):
"""write the results of a greenleted rest call to a file
@offset: the offset of the file up to blocksize
- e.g. if the range is 10-100, all
blocks will be written to normal_position - 10"""
:param offset: the offset of the file up to blocksize
- e.g. if the range is 10-100, all blocks will be written to
normal_position - 10
"""
finished = []
for i, (start, g) in enumerate(flying.items()):
if not g.isAlive():
......@@ -509,8 +511,7 @@ class PithosClient(PithosRestAPI):
if_none_match=None,
if_modified_since=None,
if_unmodified_since=None):
"""Download an object using multiple connections (threads) and
writing to random parts of the file
"""Download an object (multiple connections, random blocks)
:param obj: (str) remote object path
......@@ -522,8 +523,7 @@ class PithosClient(PithosRestAPI):
:param resume: (bool) if set, preserve already downloaded file parts
:param range_str: (str) from-to where from and to are integers
denoting file positions in bytes
:param range_str: (str) from, to are file positions (int) in bytes
:param if_match: (str)
......@@ -531,9 +531,7 @@ class PithosClient(PithosRestAPI):
:param if_modified_since: (str) formated date
:param if_unmodified_since: (str) formated date
"""
:param if_unmodified_since: (str) formated date"""
restargs = dict(
version=version,
data_range=None if range_str is None else 'bytes=%s' % range_str,
......
......@@ -63,7 +63,7 @@ setup(
'kamaki.cli',
'kamaki.cli.commands',
'kamaki.clients',
'kamaki.clients.tests',
'kamaki.clients.livetest',
'kamaki.clients.connection',
'kamaki.clients.commissioning',
'kamaki.clients.quotaholder',
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment