Initial release of test auto importer
Update models.py to reflect database changes
Add the following columns to autotests table:
* author
* dependencies
* experimental
* run_verify
* test_time
* test_category
* sync_count
Add run_verify to jobs table
Update scheduler to assert with run_verify
Risk: Medium
Visibility: High, people addings tests will now see more fields via the admin frontend
Signed-off-by: Scott Zawalski <scottz@google.com>
git-svn-id: http://test.kernel.org/svn/autotest/trunk@1837 592f7852-d20e-0410-864c-8624ca9c26a4
diff --git a/frontend/afe/doctests/001_rpc_test.txt b/frontend/afe/doctests/001_rpc_test.txt
index 3815736..d3e5679 100644
--- a/frontend/afe/doctests/001_rpc_test.txt
+++ b/frontend/afe/doctests/001_rpc_test.txt
@@ -91,16 +91,25 @@
True
# tests...
->>> rpc_interface.add_test(name='sleeptest', test_type='Client',
+>>> rpc_interface.add_test(name='sleeptest', test_type='Client', author='Test',
+... description='Sleep Test', test_time=1,
+... test_category='Functional',
... 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': '',
+... 'author': 'Test',
+... 'description': 'Sleep Test',
+... 'dependencies': '',
+... 'experimental': 1,
+... 'sync_count': 1L,
... 'test_type': 'Client',
... 'test_class': 'Kernel',
+... 'test_time': 'SHORT',
+... 'run_verify': 1,
+... 'test_category': 'Functional',
... 'synch_type': 'Asynchronous',
... 'path': '/my/path'}]
True
@@ -303,10 +312,13 @@
>>> rpc_interface.add_label(name='my_label', kernel_config='my_kernel_config')
5L
>>> test_control_path = os.path.join(test_path, 'test.control')
->>> rpc_interface.add_test(name='sleeptest', test_type='Client',
+>>> rpc_interface.add_test(name='sleeptest', test_type='Client', author='Test',
+... test_category='Test',
... test_class='Kernel', path=test_control_path)
2L
->>> rpc_interface.add_test(name='my_test', test_type='Client',
+>>> test_control_path = os.path.join(test_path, 'test.control.2')
+>>> rpc_interface.add_test(name='my_test', test_type='Client', author='Test',
+... test_category='Test',
... test_class='Kernel', path=test_control_path)
3L
>>> rpc_interface.add_host(hostname='my_label_host1')
@@ -387,7 +399,8 @@
... 'synch_count': None,
... 'synch_type': 'Asynchronous',
... 'synchronizing': 0,
-... 'timeout': 72}
+... 'timeout': 72,
+... 'run_verify': 1}
True
# get_host_queue_entries returns a lot of data, so let's only check a couple
diff --git a/frontend/afe/doctests/test.control.2 b/frontend/afe/doctests/test.control.2
new file mode 100644
index 0000000..653fafe
--- /dev/null
+++ b/frontend/afe/doctests/test.control.2
@@ -0,0 +1 @@
+job.run_test('testname')
diff --git a/frontend/afe/models.py b/frontend/afe/models.py
index 1e48f6d..e9bc2c8 100644
--- a/frontend/afe/models.py
+++ b/frontend/afe/models.py
@@ -189,30 +189,45 @@
class Test(dbmodels.Model, model_logic.ModelExtensions):
"""\
Required:
+ author: author name
+ description: description of the test
name: test name
+ time: short, medium, long
+ test_class: This describes the class for your the test belongs in.
+ test_category: This describes the category for your tests
test_type: Client or Server
path: path to pass to run_test()
synch_type: whether the test should run synchronously or asynchronously
-
+ sync_count: is a number >=1 (1 being the default). If it's 1, then it's an
+ async job. If it's >1 it's sync job for that number of machines
+ i.e. if sync_count = 2 it is a sync job that requires two
+ machines.
Optional:
- test_class: used for categorization of tests
- description: arbirary text description
+ dependencies: What the test requires to run. Comma deliminated list
+ experimental: If this is set to True production servers will ignore the test
+ run_verify: Whether or not the scheduler should run the verify stage
"""
- Classes = enum.Enum('Kernel', 'Hardware', 'Canned Test Sets',
- string_values=True)
+ TestTime = enum.Enum('SHORT', 'MEDIUM', 'LONG', start_value=1)
SynchType = enum.Enum('Asynchronous', 'Synchronous', start_value=1)
# TODO(showard) - this should be merged with Job.ControlType (but right
# now they use opposite values)
Types = enum.Enum('Client', 'Server', start_value=1)
name = dbmodels.CharField(maxlength=255, unique=True)
- test_class = dbmodels.CharField(maxlength=255,
- choices=Classes.choices())
+ author = dbmodels.CharField(maxlength=255)
+ test_class = dbmodels.CharField(maxlength=255)
+ test_category = dbmodels.CharField(maxlength=255)
+ dependencies = dbmodels.CharField(maxlength=255, blank=True)
description = dbmodels.TextField(blank=True)
+ experimental = dbmodels.BooleanField(default=True)
+ run_verify = dbmodels.BooleanField(default=True)
+ test_time = dbmodels.SmallIntegerField(choices=TestTime.choices(),
+ default=TestTime.MEDIUM)
test_type = dbmodels.SmallIntegerField(choices=Types.choices())
+ sync_count = dbmodels.IntegerField(default=1)
synch_type = dbmodels.SmallIntegerField(choices=SynchType.choices(),
default=SynchType.ASYNCHRONOUS)
- path = dbmodels.CharField(maxlength=255)
+ path = dbmodels.CharField(maxlength=255, unique=True)
name_field = 'name'
objects = model_logic.ExtendedManager()
@@ -224,11 +239,12 @@
class Admin:
fields = (
(None, {'fields' :
- ('name', 'test_class', 'test_type', 'synch_type',
- 'path', 'description')}),
+ ('name', 'author', 'test_category', 'test_class',
+ 'test_time', 'synch_type', 'test_type', 'sync_count',
+ 'path', 'dependencies', 'experimental', 'run_verify',
+ 'description')}),
)
- list_display = ('name', 'test_type', 'synch_type',
- 'description')
+ list_display = ('name', 'test_type', 'description', 'synch_type')
search_fields = ('name',)
def __str__(self):
@@ -447,6 +463,7 @@
synch_type: Asynchronous or Synchronous (i.e. job must run on all hosts
simultaneously; used for server-side control files)
synch_count: ???
+ run_verify: Whether or not to run the verify phase
synchronizing: for scheduler use
timeout: hours until job times out
"""
@@ -469,6 +486,7 @@
blank=True, null=True, choices=Test.SynchType.choices())
synch_count = dbmodels.IntegerField(blank=True, null=True)
synchronizing = dbmodels.BooleanField(default=False)
+ run_verify = dbmodels.BooleanField(default=True)
timeout = dbmodels.IntegerField()
@@ -482,7 +500,7 @@
@classmethod
def create(cls, owner, name, priority, control_file, control_type,
- hosts, synch_type, timeout):
+ hosts, synch_type, timeout, run_verify):
"""\
Creates a job by taking some information (the listed args)
and filling in the rest of the necessary information.
@@ -491,7 +509,8 @@
job = cls.add_object(
owner=owner, name=name, priority=priority,
control_file=control_file, control_type=control_type,
- synch_type=synch_type, timeout=timeout)
+ synch_type=synch_type, timeout=timeout,
+ run_verify=run_verify)
if job.synch_type == Test.SynchType.SYNCHRONOUS:
job.synch_count = len(hosts)
@@ -520,7 +539,8 @@
owner=new_owner, name=self.name, priority=self.priority,
control_file=self.control_file,
control_type=self.control_type, hosts=hosts,
- synch_type=self.synch_type, timeout=self.timeout)
+ synch_type=self.synch_type, timeout=self.timeout,
+ run_verify=self.run_verify)
new_job.queue(hosts)
return new_job
diff --git a/frontend/afe/rpc_interface.py b/frontend/afe/rpc_interface.py
index bac3aa8..dba79f4 100644
--- a/frontend/afe/rpc_interface.py
+++ b/frontend/afe/rpc_interface.py
@@ -115,8 +115,16 @@
# tests
-def add_test(name, test_type, path, test_class=None, description=None):
+def add_test(name, test_type, path, author=None, dependencies=None,
+ experimental=True, run_verify=None, test_class=None,
+ test_time=None, test_category=None, description=None,
+ sync_count=1):
return models.Test.add_object(name=name, test_type=test_type, path=path,
+ author=author, dependencies=dependencies,
+ experimental=experimental,
+ run_verify=run_verify, test_time=test_time,
+ test_category=test_category,
+ sync_count=sync_count,
test_class=test_class,
description=description).id
@@ -253,7 +261,7 @@
def create_job(name, priority, control_file, control_type, timeout=None,
is_synchronous=None, hosts=None, meta_hosts=None,
- one_time_hosts=None):
+ run_verify=True, one_time_hosts=None):
"""\
Create and enqueue a job.
@@ -324,7 +332,8 @@
control_type=control_type,
synch_type=synch_type,
hosts=host_objects,
- timeout=timeout)
+ timeout=timeout,
+ run_verify=run_verify)
job.queue(host_objects)
return job.id
diff --git a/frontend/migrations/013_new_test_fields.py b/frontend/migrations/013_new_test_fields.py
new file mode 100644
index 0000000..02ce6e8
--- /dev/null
+++ b/frontend/migrations/013_new_test_fields.py
@@ -0,0 +1,20 @@
+def migrate_up(manager):
+ manager.execute('ALTER TABLE jobs ADD run_verify tinyint(1) default 1')
+ manager.execute('ALTER TABLE autotests ADD author VARCHAR(256)')
+ manager.execute('ALTER TABLE autotests ADD dependencies VARCHAR(256)')
+ manager.execute('ALTER TABLE autotests ADD experimental SMALLINT DEFAULT 0')
+ manager.execute('ALTER TABLE autotests ADD run_verify SMALLINT DEFAULT 1')
+ manager.execute('ALTER TABLE autotests ADD test_time SMALLINT DEFAULT 1')
+ manager.execute('ALTER TABLE autotests ADD test_category VARCHAR(256)')
+ manager.execute('ALTER TABLE autotests ADD sync_count INT(11) DEFAULT 1')
+
+
+def migrate_down(manager):
+ manager.execute('ALTER TABLE jobs DROP run_verify')
+ manager.execute('ALTER TABLE autotests DROP sync_count')
+ manager.execute('ALTER TABLE autotests DROP author')
+ manager.execute('ALTER TABLE autotests DROP dependencies')
+ manager.execute('ALTER TABLE autotests DROP experimental')
+ manager.execute('ALTER TABLE autotests DROP run_verify')
+ manager.execute('ALTER TABLE autotests DROP test_time')
+ manager.execute('ALTER TABLE autotests DROP test_category')