blob: b8b15d4ead55761ca327f4d33df0136c386597c7 [file] [log] [blame]
# setup (you can ignore this)
# ###########################
# a bit of setup to allow overriding rpc_interace with an RPC proxy
# (to use RPC, we would say
# import rpc_client_lib
# rpc_interface = rpc_client_lib.get_proxy('http://hostname:8000/rpc/')
# )
>>> if 'rpc_interface' not in globals():
... from frontend.afe import rpc_interface, rpc_utils, models
... # set up a user for us to "login" as
... user = models.User(login='debug_user')
... user.save()
... rpc_utils.set_user(user)
...
# get directory of this test file; we'll need it later
>>> import frontend.afe.test
>>> import os
>>> test_path = os.path.join(os.path.dirname(frontend.afe.test.__file__),
... 'doctests')
>>> test_path = os.path.abspath(test_path)
# basic object management
# #######################
# create a label
>>> rpc_interface.add_label(name='test_label')
1L
# we can modify the label by referencing its ID...
>>> rpc_interface.modify_label(1, kernel_config='/my/kernel/config')
# ...or by referencing it's name
>>> rpc_interface.modify_label('test_label', platform=True)
# we use get_labels to retrieve object data
>>> data = rpc_interface.get_labels(name='test_label')
>>> data == [{'id': 1L,
... 'name': 'test_label',
... 'platform': 1,
... 'kernel_config': '/my/kernel/config'}]
True
# get_labels return multiple matches as lists of dictionaries
>>> rpc_interface.add_label(name='label1', platform=False)
2L
>>> rpc_interface.add_label(name='label2', platform=True)
3L
>>> rpc_interface.add_label(name='label3', platform=False)
4L
>>> data = rpc_interface.get_labels(platform=False)
>>> data == [{'id': 2L, 'name': 'label1', 'platform': 0, 'kernel_config': ''},
... {'id': 4L, 'name': 'label3', 'platform': 0, 'kernel_config': ''}]
True
# delete_label takes an ID or a name as well
>>> rpc_interface.delete_label(3)
>>> rpc_interface.get_labels(name='label2')
[]
>>> rpc_interface.delete_label('test_label')
>>> rpc_interface.delete_label('label1')
>>> rpc_interface.delete_label('label3')
>>> rpc_interface.get_labels()
[]
# all the add*, modify*, delete*, and get* methods work the same way
# hosts...
>>> rpc_interface.add_host(hostname='ipaj1', locked=True)
1L
>>> rpc_interface.modify_host('ipaj1', status='Hello')
>>> data = rpc_interface.get_hosts()
>>> data == [{'id': 1L,
... 'hostname': 'ipaj1',
... 'locked': 1,
... 'synch_id': None,
... 'status': 'Hello',
... 'labels': [],
... 'platform': None}]
True
>>> rpc_interface.delete_host('ipaj1')
>>> rpc_interface.get_hosts() == []
True
# tests...
>>> rpc_interface.add_test(name='sleeptest', test_type='Client',
... test_class='Kernel', path='sleeptest')
1L
>>> rpc_interface.modify_test('sleeptest', path='/my/path')
>>> data = rpc_interface.get_tests()
>>> data == [{'id': 1L,
... 'name': 'sleeptest',
... 'description': '',
... 'test_type': 'Client',
... 'test_class': 'Kernel',
... 'path': '/my/path'}]
True
>>> rpc_interface.delete_test('sleeptest')
>>> rpc_interface.get_tests() == []
True
# users...
>>> rpc_interface.add_user(login='showard')
2L
>>> rpc_interface.modify_user('showard', access_level=1)
>>> data = rpc_interface.get_users(login='showard')
>>> data == [{'id': 2L,
... 'login': 'showard',
... 'access_level': 1}]
True
>>> rpc_interface.delete_user('showard')
>>> rpc_interface.get_users(login='showard') == []
True
# acl groups...
# 1 ACL group already exists, named "Everyone" (ID 1)
>>> rpc_interface.add_acl_group(name='my_group')
2L
>>> rpc_interface.modify_acl_group('my_group', description='my new acl group')
>>> data = rpc_interface.get_acl_groups(name='my_group')
>>> data == [{'id': 2L,
... 'name': 'my_group',
... 'description': 'my new acl group',
... 'users': [],
... 'hosts': []}]
True
>>> rpc_interface.delete_acl_group('my_group')
>>> data = rpc_interface.get_acl_groups()
>>> data == [{'id': 1L,
... 'name': 'Everyone',
... 'description': '',
... 'users': ['debug_user'],
... 'hosts': []}]
True
# managing many-to-many relationships
# ###################################
# first, create some hosts and labels to play around with
>>> rpc_interface.add_host(hostname='host1')
2L
>>> rpc_interface.add_host(hostname='host2')
3L
>>> rpc_interface.add_label(name='label1')
5L
>>> rpc_interface.add_label(name='label2', platform=True)
6L
# add hosts to labels
>>> rpc_interface.host_add_labels('host1', ['label1'])
>>> rpc_interface.host_add_labels('host2', ['label1', 'label2'])
# check labels for hosts
>>> data = rpc_interface.get_hosts(hostname='host1')
>>> data[0]['labels']
['label1']
>>> data = rpc_interface.get_hosts(hostname='host2')
>>> data[0]['labels']
['label1', 'label2']
>>> data[0]['platform']
'label2'
# check host lists for labels -- use double underscore to specify fields of
# related objects
>>> data = rpc_interface.get_hosts(labels__name='label1')
>>> [host['hostname'] for host in data]
['host1', 'host2']
>>> data = rpc_interface.get_hosts(labels__name='label2')
>>> [host['hostname'] for host in data]
['host2']
# remove a host from a label
>>> rpc_interface.host_remove_labels('host2', ['label2'])
>>> data = rpc_interface.get_hosts(hostname='host1')
>>> data[0]['labels']
['label1']
>>> rpc_interface.get_hosts(labels__name='label2')
[]
# ACL group relationships work similarly
# note that all users and hosts are a member of 'Everyone' by default
>>> rpc_interface.add_user(login='showard', access_level=0)
3L
>>> rpc_interface.add_acl_group(name='my_group')
3L
>>> rpc_interface.acl_group_add_users('my_group', ['showard'])
>>> rpc_interface.acl_group_add_hosts('my_group', ['host1'])
>>> data = rpc_interface.get_acl_groups(name='my_group')
>>> data[0]['users']
['showard']
>>> data[0]['hosts']
['host1']
>>> data = rpc_interface.get_acl_groups(users__login='showard')
>>> [acl_group['name'] for acl_group in data]
['Everyone', 'my_group']
>>> data = rpc_interface.get_acl_groups(hosts__hostname='host1')
>>> [acl_group['name'] for acl_group in data]
['Everyone', 'my_group']
>>> rpc_interface.acl_group_remove_users('my_group', ['showard'])
>>> rpc_interface.acl_group_remove_hosts('my_group', ['host1'])
>>> data = rpc_interface.get_acl_groups(name='my_group')
>>> data[0]['users'] == data[0]['hosts'] == []
True
>>> data = rpc_interface.get_acl_groups(users__login='showard')
>>> [acl_group['name'] for acl_group in data]
['Everyone']
>>> data = rpc_interface.get_acl_groups(hosts__hostname='host1')
>>> [acl_group['name'] for acl_group in data]
['Everyone']
# job management
# ############
# note that job functions require job IDs to identify jobs, since job names are
# not unique
# add some entries to play with
>>> rpc_interface.add_label(name='my_label', kernel_config='my_kernel_config')
7L
>>> test_control_path = os.path.join(test_path, 'test.control')
>>> rpc_interface.add_test(name='sleeptest', test_type='Client',
... test_class='Kernel', path=test_control_path)
2L
>>> rpc_interface.add_test(name='my_test', test_type='Client',
... test_class='Kernel', path=test_control_path)
3L
# generate a control file
>>> control_file = rpc_interface.generate_control_file(
... tests=['sleeptest', 'my_test'],
... kernel='1.2.3.4',
... label='my_label')
>>> control_file
"def step_init():\n\tjob.next_step([step_test])\n\ttestkernel = job.kernel('1.2.3.4')\n\ttestkernel.config('my_kernel_config')\n\ttestkernel.install()\n\ttestkernel.boot(args='')\n\ndef step_test():\n\tjob.run_test('testname')\n\tjob.run_test('testname')"
>>> print control_file #doctest: +NORMALIZE_WHITESPACE
def step_init():
job.next_step([step_test])
testkernel = job.kernel('1.2.3.4')
testkernel.config('my_kernel_config')
testkernel.install()
testkernel.boot(args='')
<BLANKLINE>
def step_test():
job.run_test('testname')
job.run_test('testname')
# create a job to run on host1, host2, and any two machines in my_label
>>> rpc_interface.create_job(name='my_job',
... priority='Low',
... control_file=control_file,
... control_type='Client',
... hosts=['host1', 'host2'],
... meta_hosts=['my_label', 'my_label'])
1L
# get job info - this does not include status info for particular hosts
>>> data = rpc_interface.get_jobs()
>>> data = data[0]
>>> data['id'], data['owner'], data['name'], data['priority']
(1L, 'debug_user', 'my_job', 'Low')
>>> data['control_file'] == control_file
True
>>> data['control_type']
'Client'
>>> data['created_on'] #doctest: +ELLIPSIS
'200...'
# get_num_jobs - useful when dealing with large numbers of jobs
>>> rpc_interface.get_num_jobs(name='my_job')
1L
# check job status, i.e. status for each host in the job
# job_status requires ID number, not job name
>>> data = rpc_interface.job_status(1)
>>> data == {'host1': {'status': 'Queued', 'meta_count': None},
... 'host2': {'status': 'Queued', 'meta_count': None},
... 'my_label': {'status': 'Queued', 'meta_count': 2}}
True
# get_jobs_summary adds status counts to the rest of the get_jobs info
>>> data = rpc_interface.get_jobs_summary()
>>> counts = data[0]['status_counts']
>>> counts
{'Queued': 4L}
# abort the job
>>> rpc_interface.abort_job(1)
>>> data = rpc_interface.get_jobs_summary(id=1)
>>> data[0]['status_counts']
{'Aborted': 4L}
# extra querying parameters
# #########################
# get_* methods can take query_start and query_limit arguments to implement
# paging and a sort_by argument to specify the sort column
>>> data = rpc_interface.get_hosts(query_limit=1)
>>> [host['hostname'] for host in data]
['host1']
>>> data = rpc_interface.get_hosts(query_start=1, query_limit=1)
>>> [host['hostname'] for host in data]
['host2']
# sort_by = '-hostname' indicates sorting in descending order by hostname
>>> data = rpc_interface.get_hosts(sort_by='-hostname')
>>> [host['hostname'] for host in data]
['host2', 'host1']
# advanced args
# #############
# is_synchronous
>>> rpc_interface.create_job(name='my_job',
... priority='Low',
... control_file=control_file,
... control_type='Server',
... is_synchronous=False,
... hosts=['host1'])
2L
>>> data = rpc_interface.get_jobs()
>>> data[0]['synch_type']
'Asynchronous'