Add Subsystem Restart(SSR) detection.

Failed the Passed test case if Subsystem Restart occurred.

1.Test Passed, But DUTs have SSR rump:
  - Fail the test.
  - Sample log: https://paste.googleplex.com/6325057534558208

2.Test Failed + Any one of the DUTs has SSR dump:
  - Two different Error message shown
  - Sample log: https://paste.googleplex.com/4808091929935872

Bug: None
Test: act.py
Change-Id: Id8a917b98eff1c30267086fd7025efb67e1d21c4
diff --git a/acts_tests/acts_contrib/test_utils/wifi/WifiBaseTest.py b/acts_tests/acts_contrib/test_utils/wifi/WifiBaseTest.py
index f57fab9..b9bbf09 100644
--- a/acts_tests/acts_contrib/test_utils/wifi/WifiBaseTest.py
+++ b/acts_tests/acts_contrib/test_utils/wifi/WifiBaseTest.py
@@ -17,7 +17,9 @@
     Base Class for Defining Common WiFi Test Functionality
 """
 
+import contextlib
 import copy
+import logging
 import os
 import time
 
@@ -41,6 +43,27 @@
 AP_2 = 1
 MAX_AP_COUNT = 2
 
+@contextlib.contextmanager
+def logged_suppress(message: str, allow_test_fail: bool = False):
+  """Suppresses any Exceptions and logs the outcome.
+
+  This is to make sure all steps in every test class's teardown_test/on_fail
+  are executed even if super().teardown_test() or super().on_fail()
+  is called at the very beginning.
+
+  Args:
+    message: message to describe the error.
+    allow_test_fail: True to re-raise the exception, False to suppress it.
+
+  Yields:
+    None
+  """
+  try:
+    yield
+  except signals.TestFailure:
+    if allow_test_fail:
+      raise
+    logging.exception(message)
 
 class WifiBaseTest(BaseTestClass):
     def __init__(self, configs):
@@ -85,11 +108,21 @@
             for ad in self.android_devices:
                 proc = nutils.start_tcpdump(ad, self.test_name)
                 self.tcpdump_proc.append((ad, proc))
+
+                # Delete any existing ssrdumps.
+                ad.log.info("Deleting existing ssrdumps")
+                ad.adb.shell("find /data/vendor/ssrdump/ -type f -delete",
+                             ignore_status=True)
+
         if hasattr(self, "packet_logger"):
             self.packet_log_pid = wutils.start_pcap(self.packet_logger, 'dual',
                                                     self.test_name)
 
     def teardown_test(self):
+        with logged_suppress("SubSystem Restart(SSR) Exception.",
+                             allow_test_fail=True):
+            self._check_ssrdumps()
+
         if (hasattr(self, "android_devices")):
             wutils.stop_all_wlan_logs(self.android_devices)
             for proc in self.tcpdump_proc:
@@ -115,7 +148,6 @@
             for ad in self.android_devices:
                 ad.take_bug_report(test_name, begin_time)
                 ad.cat_adb_log(test_name, begin_time)
-                wutils.get_ssrdumps(ad)
             wutils.stop_all_wlan_logs(self.android_devices)
             for ad in self.android_devices:
                 wutils.get_wlan_logs(ad)
@@ -132,6 +164,20 @@
         for device in getattr(self, "fuchsia_devices", []):
             self.on_device_fail(device, test_name, begin_time)
 
+    def _check_ssrdumps(self):
+        """Failed the test if SubSystem Restart occurred on any device."""
+        is_ramdump_happened = False
+        if (hasattr(self, "android_devices")):
+            for ad in self.android_devices:
+                wutils.get_ssrdumps(ad)
+                if wutils.has_ssrdumps(ad):
+                    is_ramdump_happened = True
+
+        if is_ramdump_happened:
+            raise signals.TestFailure(
+              f"SubSystem Restart(SSR) occurred on "
+              f"{self.TAG}:{self.current_test_name}")
+
     def on_device_fail(self, device, test_name, begin_time):
         """Gets a generic device DUT bug report.
 
diff --git a/acts_tests/acts_contrib/test_utils/wifi/wifi_test_utils.py b/acts_tests/acts_contrib/test_utils/wifi/wifi_test_utils.py
index 5af1971..7f939f2 100755
--- a/acts_tests/acts_contrib/test_utils/wifi/wifi_test_utils.py
+++ b/acts_tests/acts_contrib/test_utils/wifi/wifi_test_utils.py
@@ -2534,6 +2534,15 @@
 
     return capability
 
+def has_ssrdumps(ad) -> bool:
+    """Checks if ssrdumps files are present in ssrdump dir
+
+    Returns:
+        True if ssrdumps are present, False otherwise.
+    """
+    files = ad.get_file_names("/data/vendor/ssrdump/")
+    return bool(files)
+
 def get_ssrdumps(ad):
     """Pulls dumps in the ssrdump dir
     Args:
@@ -2545,9 +2554,6 @@
         log_path = os.path.join(ad.device_log_path, "SSRDUMPS_%s" % ad.serial)
         os.makedirs(log_path, exist_ok=True)
         ad.pull_files(logs, log_path)
-    ad.adb.shell("find /data/vendor/ssrdump/ -type f -delete",
-                 ignore_status=True)
-
 
 def start_pcap(pcap, wifi_band, test_name):
     """Start packet capture in monitor mode.
@@ -2653,7 +2659,7 @@
 def stop_all_wlan_logs(ads):
     for ad in ads:
         stop_wlan_logs(ad)
-    ad.log.info("Wait 30s for the createion of zip file for wlan logs")
+    ad.log.info("Wait 30s for the creation of zip file for wlan logs")
     time.sleep(30)
 
 def stop_wlan_logs(ad):
diff --git a/acts_tests/tests/google/wifi/WifiCrashStressTest.py b/acts_tests/tests/google/wifi/WifiCrashStressTest.py
index 9982cd8..4b0a8a5 100644
--- a/acts_tests/tests/google/wifi/WifiCrashStressTest.py
+++ b/acts_tests/tests/google/wifi/WifiCrashStressTest.py
@@ -74,6 +74,10 @@
         wutils.wifi_toggle_state(self.dut_client, True)
 
     def teardown_test(self):
+        # Deletes all ssrdump files in every DUTs.
+        for ad in self.android_devices:
+            ad.adb.shell("find /data/vendor/ssrdump/ -type f -delete",
+                         ignore_status=True)
         super().teardown_test()
         if self.dut.droid.wifiIsApEnabled():
             wutils.stop_wifi_tethering(self.dut)