Only write a job keyval out if there isn't already a keyval with
"job_started" in it. This way we don't stomp all over any existing
values when doing secondary follow-up jobs like crashinfo collection.

Risk: Low
Visibility: Prevents secondary jobs from overwriting the keyvals of
the primary job.

Signed-off-by: John Admanski <jadmanski@google.com>




git-svn-id: http://test.kernel.org/svn/autotest/trunk@3024 592f7852-d20e-0410-864c-8624ca9c26a4
diff --git a/client/common_lib/utils.py b/client/common_lib/utils.py
index 36a0689..106fa2c 100644
--- a/client/common_lib/utils.py
+++ b/client/common_lib/utils.py
@@ -161,16 +161,17 @@
     if os.path.isdir(path):
         path = os.path.join(path, 'keyval')
     keyval = {}
-    for line in open(path):
-        line = re.sub('#.*', '', line).rstrip()
-        if not re.search(r'^[-\.\w]+=', line):
-            raise ValueError('Invalid format line: %s' % line)
-        key, value = line.split('=', 1)
-        if re.search('^\d+$', value):
-            value = int(value)
-        elif re.search('^(\d+\.)?\d+$', value):
-            value = float(value)
-        keyval[key] = value
+    if os.path.exists(path):
+        for line in open(path):
+            line = re.sub('#.*', '', line).rstrip()
+            if not re.search(r'^[-\.\w]+=', line):
+                raise ValueError('Invalid format line: %s' % line)
+            key, value = line.split('=', 1)
+            if re.search('^\d+$', value):
+                value = int(value)
+            elif re.search('^(\d+\.)?\d+$', value):
+                value = float(value)
+            keyval[key] = value
     return keyval
 
 
diff --git a/client/common_lib/utils_unittest.py b/client/common_lib/utils_unittest.py
index 4e08a2d..ae45894 100644
--- a/client/common_lib/utils_unittest.py
+++ b/client/common_lib/utils_unittest.py
@@ -152,6 +152,7 @@
         self.god = mock.mock_god()
         self.god.stub_function(utils, "open")
         self.god.stub_function(os.path, "isdir")
+        self.god.stub_function(os.path, "exists")
 
 
     def tearDown(self):
@@ -160,6 +161,7 @@
 
     def create_test_file(self, filename, contents):
         test_file = StringIO.StringIO(contents)
+        os.path.exists.expect_call(filename).and_return(True)
         utils.open.expect_call(filename).and_return(test_file)
 
 
@@ -171,6 +173,13 @@
         return keyval
 
 
+    def test_returns_empty_when_file_doesnt_exist(self):
+        os.path.isdir.expect_call("file").and_return(False)
+        os.path.exists.expect_call("file").and_return(False)
+        self.assertEqual({}, utils.read_keyval("file"))
+        self.god.check_playback()
+
+
     def test_accesses_files_directly(self):
         os.path.isdir.expect_call("file").and_return(False)
         self.create_test_file("file", "")
diff --git a/server/server_job.py b/server/server_job.py
index 9425530..7fdd9d0 100755
--- a/server/server_job.py
+++ b/server/server_job.py
@@ -162,8 +162,10 @@
                     'status_version' : str(self.STATUS_VERSION),
                     'job_started' : str(int(time.time()))}
         if self.resultdir:
-            job_data.update(get_site_job_data(self))
-            utils.write_keyval(self.resultdir, job_data)
+            # only write these keyvals out on the first job in a resultdir
+            if 'job_started' not in utils.read_keyval(self.resultdir):
+                job_data.update(get_site_job_data(self))
+                utils.write_keyval(self.resultdir, job_data)
 
         self.parse_job = parse_job
         if self.parse_job and len(machines) == 1:
diff --git a/server/server_job_unittest.py b/server/server_job_unittest.py
index a553d6a..9fa14b4 100644
--- a/server/server_job_unittest.py
+++ b/server/server_job_unittest.py
@@ -88,6 +88,8 @@
 
         cls = server_job.base_server_job
         compare = mock.is_instance_comparator(cls)
+        os.path.isdir.expect_call('results').and_return(True)
+        os.path.exists.expect_call('results/keyval').and_return(False)
         server_job.get_site_job_data.expect_call(compare).and_return({})
         utils.write_keyval.expect_call(mock.is_string_comparator(),
                                        mock.is_instance_comparator(dict))