Added full E2E kcrash testing

BUG=1914

Review URL: http://codereview.chromium.org/3114016
diff --git a/client/bin/site_crash_test.py b/client/bin/site_crash_test.py
index 7a6eaa9..8a556b2 100644
--- a/client/bin/site_crash_test.py
+++ b/client/bin/site_crash_test.py
@@ -15,7 +15,7 @@
     _CRASH_SENDER_RATE_DIR = '/var/lib/crash_sender'
     _CRASH_SENDER_RUN_PATH = '/var/run/crash_sender.pid'
     _MOCK_CRASH_SENDING = '/tmp/mock-crash-sending'
-    _PAUSE_FILE = '/tmp/pause-crash-sending'
+    _PAUSE_FILE = '/var/lib/crash_sender_paused'
     _SYSTEM_CRASH_DIR = '/var/spool/crash'
     _USER_CRASH_DIR = '/home/chronos/user/crash'
 
@@ -92,7 +92,7 @@
         utils.system('%s --init --nounclean_check' % self._CRASH_REPORTER_PATH)
 
 
-    def _create_fake_crash_dir_entry(self, name):
+    def create_fake_crash_dir_entry(self, name):
         entry = os.path.join(self._SYSTEM_CRASH_DIR, name)
         if not os.path.exists(self._SYSTEM_CRASH_DIR):
             os.makedirs(self._SYSTEM_CRASH_DIR)
@@ -104,12 +104,12 @@
                                   send_success,
                                   reports_enabled,
                                   username,
-                                  minidump):
+                                  report):
         self._set_sending_mock(mock_enabled=True, send_success=send_success)
         self._set_consent(reports_enabled)
-        if minidump is None:
-            minidump = self._create_fake_crash_dir_entry('fake.dmp')
-        return minidump
+        if report is None:
+            report = self.create_fake_crash_dir_entry('fake.dmp')
+        return report
 
 
     def _parse_sender_output(self, output):
@@ -123,6 +123,9 @@
 
         Returns:
           A dictionary with these values:
+            exec_name: name of executable which crashed
+            report_kind: kind of report sent (minidump vs kernel)
+            report_name: name of the report sent
             send_attempt: did the script attempt to send a crash.
             send_success: if it attempted, was the crash send successful.
             sleep_time: if it attempted, how long did it sleep before
@@ -135,8 +138,23 @@
             sleep_time = int(sleep_match.group(1))
         else:
             sleep_time = None
+        report_kind_match = re.search('Report: (\S+) \((\S+)\)', output)
+        if report_kind_match:
+            report_name = report_kind_match.group(1)
+            report_kind = report_kind_match.group(2)
+        else:
+            report_name = None
+            report_kind = None
+        exec_name_match = re.search('Exec name: (\S+)', output)
+        if exec_name_match:
+            exec_name = exec_name_match.group(1)
+        else:
+            exec_name = None
         send_success = 'Mocking successful send' in output
-        return {'send_attempt': send_attempt,
+        return {'exec_name': exec_name,
+                'report_kind': report_kind,
+                'report_name': report_name,
+                'send_attempt': send_attempt,
                 'send_success': send_success,
                 'sleep_time': sleep_time,
                 'output': output}
@@ -146,27 +164,27 @@
                                send_success=True,
                                reports_enabled=True,
                                username='root',
-                               minidump=None):
+                               report=None):
         """Call the crash sender script to mock upload one crash.
 
         Args:
           send_success: Mock a successful send if true
           reports_enabled: Has the user consented to sending crash reports.
           username: user to emulate a crash from
-          minidump: minidump to use for crash, if None we create one.
+          report: report to use for crash, if None we create one.
 
         Returns:
           Returns a dictionary describing the result with the keys
           from _parse_sender_output, as well as:
-            minidump_exists: does the minidump still exist after calling
+            report_exists: does the minidump still exist after calling
               send script
             rate_count: how many crashes have been uploaded in the past
               24 hours.
         """
-        minidump = self._prepare_sender_one_crash(send_success,
-                                                  reports_enabled,
-                                                  username,
-                                                  minidump)
+        report = self._prepare_sender_one_crash(send_success,
+                                                reports_enabled,
+                                                username,
+                                                report)
         self._log_reader.set_start_by_current()
         script_output = utils.system_output(
             '/bin/sh -c "%s" 2>&1' % self._CRASH_SENDER_PATH,
@@ -187,18 +205,18 @@
             raise error.TestFail(
                 'Unexpected crash_sender stdout/stderr: ' + script_output)
 
-        if os.path.exists(minidump):
-            minidump_exists = True
-            os.remove(minidump)
+        if os.path.exists(report):
+            report_exists = True
+            os.remove(report)
         else:
-            minidump_exists = False
+            report_exists = False
         if os.path.exists(self._CRASH_SENDER_RATE_DIR):
             rate_count = len(os.listdir(self._CRASH_SENDER_RATE_DIR))
         else:
             rate_count = 0
 
         result = self._parse_sender_output(output)
-        result['minidump_exists'] = minidump_exists
+        result['report_exists'] = report_exists
         result['rate_count'] = rate_count
 
         # Show the result for debugging but remove 'output' key
@@ -213,32 +231,48 @@
     def initialize(self):
         test.test.initialize(self)
         self._log_reader = site_log_reader.LogReader()
+        self._leave_crash_sending = True
 
 
     def cleanup(self):
         self._reset_rate_limiting()
         self._clear_spooled_crashes()
-        self._set_sending(True)
+        self._set_sending(self._leave_crash_sending)
         self._set_sending_mock(mock_enabled=False)
         self._pop_consent()
         test.test.cleanup(self)
 
 
-    def run_crash_tests(self, test_names):
+    def run_crash_tests(self,
+                        test_names,
+                        initialize_crash_reporter=False,
+                        clear_spool_first=True,
+                        must_run_all=True):
+        """Run crash tests defined in this class.
+
+        Args:
+          test_names: array of test names
+          initialize_crash_reporter: should set up crash reporter for every run
+          must_run_all: should make sure every test in this class is mentioned
+            in test_names
+        """
         self._push_consent()
 
-        # Sanity check test_names is complete
-        for attr in dir(self):
-            if attr.find('_test_') == 0:
-                test_name = attr[6:]
-                if not test_name in test_names:
-                    raise error.TestError('Test %s is missing' % test_name)
+        if must_run_all:
+            # Sanity check test_names is complete
+            for attr in dir(self):
+                if attr.find('_test_') == 0:
+                    test_name = attr[6:]
+                    if not test_name in test_names:
+                        raise error.TestError('Test %s is missing' % test_name)
 
         for test_name in test_names:
             logging.info(('=' * 20) + ('Running %s' % test_name) + ('=' * 20))
-            self._initialize_crash_reporter()
+            if initialize_crash_reporter:
+                self._initialize_crash_reporter()
             self._kill_running_sender()
             self._reset_rate_limiting()
-            self._clear_spooled_crashes()
+            if clear_spool_first:
+                self._clear_spooled_crashes()
             self._set_sending(False)
             getattr(self, '_test_' + test_name)()