Various changes to support further high-level automation efforts.

* added a RESTful interface for TKO.  right now there's only a single, simple resource for accessing test attributes.
* extended the REST server library in a few ways, most notably to support
* querying on keyvals, with something like ?has_keyval=mykey=myvalue&...
* operators, delimited by a colon, like ?hostname:in=host1,host2,host3
* loading relationships over many items efficiently (see InstanceEntry.prepare_for_full_representation()).  this is used to fill in keyvals when requesting a job listing, but it can (and should) be used in other places, such as listing labels for a host collection.
* loading a collection with inlined full representations, by passing full_representations=true
* added various features to the AFE RESTful interface as necessary.
* various fixes to the rest_client library, most notably
* changed HTTP client in rest_client.py to use DI rather than singleton, easing testability.  the same should be done for _get_request_headers(), to be honest.
* better support for query params, including accepting a MultiValueDict and supporting URIs that already have query args
* basic support for redirects
* builtin support for requesting a full collection (get_full()), when clients explicitly expect the result not to be paged.  i'm still considering alternative approaches to this -- it may make sense to have something like this be the default, and have clients set a default page size limit rather than passing it every time.
* minor change to mock.py to provide better debugging output.

Signed-off-by: Steve Howard <showard@google.com>



git-svn-id: http://test.kernel.org/svn/autotest/trunk@4438 592f7852-d20e-0410-864c-8624ca9c26a4
diff --git a/frontend/tko/rpc_interface_unittest.py b/frontend/tko/rpc_interface_unittest.py
index c711e35..91be76e 100644
--- a/frontend/tko/rpc_interface_unittest.py
+++ b/frontend/tko/rpc_interface_unittest.py
@@ -87,13 +87,12 @@
     cursor.execute(_CREATE_ITERATION_RESULTS)
 
 
-class RpcInterfaceTest(unittest.TestCase):
-    def setUp(self):
-        self._god = mock.mock_god()
-        self._god.stub_with(models.TempManager, '_get_column_names',
-                            self._get_column_names_for_sqlite3)
-        self._god.stub_with(models.TempManager, '_cursor_rowcount',
-                            self._cursor_rowcount_for_sqlite3)
+class TkoTestMixin(object):
+    def _patch_sqlite_stuff(self):
+        self.god.stub_with(models.TempManager, '_get_column_names',
+                           self._get_column_names_for_sqlite3)
+        self.god.stub_with(models.TempManager, '_cursor_rowcount',
+                           self._cursor_rowcount_for_sqlite3)
 
         # add some functions to SQLite for MySQL compatibility
         connection.cursor() # ensure connection is alive
@@ -101,10 +100,7 @@
         connection.connection.create_function('find_in_set', 2,
                                               self._sqlite_find_in_set)
 
-        setup_test_environment.set_up()
         fix_iteration_tables()
-        setup_test_view()
-        self._create_initial_data()
 
 
     def _cursor_rowcount_for_sqlite3(self, cursor):
@@ -139,11 +135,6 @@
         return names
 
 
-    def tearDown(self):
-        setup_test_environment.tear_down()
-        self._god.unstub_all()
-
-
     def _create_initial_data(self):
         machine = models.Machine.objects.create(hostname='myhost')
 
@@ -162,9 +153,11 @@
         failed_status = models.Status.objects.create(word='FAILED')
 
         job1 = models.Job.objects.create(tag='1-myjobtag1', label='myjob1',
-                                         username='myuser', machine=machine)
+                                         username='myuser', machine=machine,
+                                         afe_job_id=1)
         job2 = models.Job.objects.create(tag='2-myjobtag2', label='myjob2',
-                                         username='myuser', machine=machine)
+                                         username='myuser', machine=machine,
+                                         afe_job_id=2)
 
         job1_test1 = models.Test.objects.create(job=job1, test='mytest1',
                                                 kernel=kernel1,
@@ -216,6 +209,21 @@
                        (test.test_idx, iteration, attribute, value))
 
 
+class RpcInterfaceTest(unittest.TestCase, TkoTestMixin):
+    def setUp(self):
+        self.god = mock.mock_god()
+
+        setup_test_environment.set_up()
+        self._patch_sqlite_stuff()
+        setup_test_view()
+        self._create_initial_data()
+
+
+    def tearDown(self):
+        setup_test_environment.tear_down()
+        self.god.unstub_all()
+
+
     def _check_for_get_test_views(self, test):
         self.assertEquals(test['test_name'], 'mytest1')
         self.assertEquals(test['job_tag'], '1-myjobtag1')