VtsKernelProcFileApiTest: Fix testProcUidProcstatSet IndexError

testProcUidProcstatSet test was crashing python with the following exception:

======================================================================
ERROR: testProcUidProcstatSet (__main__.VtsKernelProcFileApiTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tmp/Soong.python_bfmswr_h/vts_kernel_proc_file_api_test.py", line 203,
	in testProcUidProcstatSet
  CheckStatsInState(False)
  File "/tmp/Soong.python_bfmswr_h/vts_kernel_proc_file_api_test.py", line 194,
	in CheckStatsInState
    old_wchar = UidIOStats(root_uid)[wchar_index]
IndexError: list index out of range

This resolves the crash and allows the test suite to finish, but in the
error case which is causing the above crash, the test case will fail
with the following signature:

__main__.VtsKernelProcFileApiTest.testProcUidProcstatSet#testProcUidProcstatSet
	fail: Traceback (most recent call last):
  File "/tmp/Soong.python_s5nustga/vts_kernel_proc_file_api_test.py", line 228,
	in testProcUidProcstatSet
    CheckStatsInState(False)
  File "/tmp/Soong.python_s5nustga/vts_kernel_proc_file_api_test.py", line 218,
	in CheckStatsInState
    old_wchar = GetWcharCount(root_uid, state)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/tmp/Soong.python_s5nustga/vts_kernel_proc_file_api_test.py", line 202,
	in GetWcharCount
    self.assertTrue(arr_len == 11,
AssertionError: False is not true : Array len returned by UidIOStats()
	 unexpected: 0
armeabi-v7a vts_kernel_proc_file_api_test completed in 1m 14s. 66 passed,
	 1 failed, 0 not executed

The underlying cause of the issue is still under investigation.

Bug: 293215373
Bug: 304711159
Test: manual execution of vts_kernel_proc_file_api_test with and without
error data injected into UidIOStats()
Signed-off-by: Neill Kapron <nkapron@google.com>
(cherry picked from https://android-review.googlesource.com/q/commit:a82c4edb8bd3fe69f5d3caf073046405afc2daea)
Merged-In: I2bd9d5ae9764e2a56b68a898d648facc49114d07
Change-Id: I2bd9d5ae9764e2a56b68a898d648facc49114d07
diff --git a/tests/kernel_proc_file_api_test/vts_kernel_proc_file_api_test.py b/tests/kernel_proc_file_api_test/vts_kernel_proc_file_api_test.py
index 5cd1686..7e77164 100644
--- a/tests/kernel_proc_file_api_test/vts_kernel_proc_file_api_test.py
+++ b/tests/kernel_proc_file_api_test/vts_kernel_proc_file_api_test.py
@@ -171,13 +171,43 @@
                 uid, uid number.
 
             Returns:
-                list of I/O numbers.
+                list of I/O numbers, can be blank if uid not found.
             """
             stats_path = "/proc/uid_io/stats"
             out, err, r_code = self.dut.shell.Execute(
                     "cat %s | grep '^%d'" % (stats_path, uid))
             return out.split()
 
+        def GetWcharCount(uid, state):
+            """Returns the wchar count (bytes written) for a given uid.
+
+            Args:
+                uid, uid number.
+                state, boolean. Use False for foreground,
+                and True for background.
+
+            Returns:
+                wchar, the number of bytes written by a uid in the given state..
+            """
+            # fg write chars are at index 2, and bg write chars are at 6.
+            wchar_index = 6 if state else 2
+
+            stats = UidIOStats(uid)
+            # UidIOStats() can return a blank line if the entries are not found
+            # so we need to check the length of the return to prevent a list
+            # index out of range exception.
+            arr_len = len(stats)
+
+            # On a properly running system, the output of
+            # 'cat /proc/uid_io/stats | grep ^0'
+            # (which is what UidIOStats() does) results in something that has 11
+            # fields and looks like this:
+            # "0 9006642940 84253078 9751207936 1064480768 0 0 0 0 1048 0"
+            self.assertTrue(arr_len == 11,
+                            "Array len returned by UidIOStats() unexpected: %d" %
+                            arr_len)
+            return int(stats[wchar_index])
+
         def CheckStatsInState(state):
             """Sets VTS (root uid) into a given state and checks the stats.
 
@@ -189,15 +219,14 @@
             filepath = "/proc/uid_procstat/set"
             root_uid = 0
 
-            # fg write chars are at index 2, and bg write chars are at 6.
-            wchar_index = 6 if state else 2
-            old_wchar = UidIOStats(root_uid)[wchar_index]
+            old_wchar = GetWcharCount(root_uid, state)
             self.dut.shell.Execute("echo %d %s > %s" % (root_uid, state, filepath))
             # This should increase the number of write syscalls.
             self.dut.shell.Execute("echo foo")
+            new_wchar = GetWcharCount(root_uid, state)
             self.assertLess(
-                int(old_wchar),
-                int(UidIOStats(root_uid)[wchar_index]),
+                old_wchar,
+                new_wchar,
                 "Number of write syscalls has not increased.")
 
         CheckStatsInState(False)