blob: 8001871dea792fdad1c73d6f2be3b33350085a49 [file] [log] [blame]
#!/usr/bin/env python3
#
# Copyright (C) 2023 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import re
import subprocess
import unittest
KNOWN_NON_LOGGING_SERVICES = [
"vendor.ir-default",
"SELF_TEST_SERVICE_DOES_NOT_EXIST",
]
KNOWN_LOGGING_SERVICES = [
"vendor.wifi_hal_legacy",
"zygote",
# b/210919187 - main log is too busy, gets dropped off
# "statsd",
# "vendor.audio-hal-aidl",
"SELF_TEST_SERVICE_DOES_NOT_EXIST",
]
def get_service_pid(svc):
return int(subprocess.check_output(["adb", "shell", "getprop", "init.svc_debug_pid." + svc]))
def get_pid_logs(pid):
return subprocess.check_output(["adb", "logcat", "--pid", str(pid), "-d"]).decode()
def iter_service_pids(test_case, services):
a_service_worked = False
for service in services:
try:
yield service, get_service_pid(service)
a_service_worked = True
except subprocess.CalledProcessError:
continue
except ValueError:
continue
test_case.assertTrue(a_service_worked)
def get_dropped_logs(test_case, buffer):
output = subprocess.check_output(["adb", "logcat", "-b", buffer, "--statistics"]).decode()
output = iter(output.split("\n"))
res = []
# Search for these lines, in order. Consider output:
# :) adb logcat -b system -S | grep -E "Total|Now"
# size/num system Total
# Total 883973/6792 883973/6792
# Now 883973/6792 883973/6792
for indication in ["Total", "Now"]:
reLineCount = re.compile(f"^{indication}.*\s+[0-9]+/([0-9]+)")
while True:
line = next(output)
match = reLineCount.match(line)
if match:
res.append(int(match.group(1)))
break
total, now = res
return total - now
class LogdIntegrationTest(unittest.TestCase):
def test_no_logs(self):
for service, pid in iter_service_pids(self, KNOWN_NON_LOGGING_SERVICES):
with self.subTest(service):
lines = get_pid_logs(pid)
self.assertFalse("\n" in lines, f"{service} ({pid}) shouldn't have logs, but found: {lines}")
def test_has_logs(self):
for service, pid in iter_service_pids(self, KNOWN_LOGGING_SERVICES):
with self.subTest(service):
lines = get_pid_logs(pid)
self.assertTrue("\n" in lines, f"{service} ({pid}) should have logs, but found: {lines}")
def test_no_dropped_logs(self):
for buffer in ["system", "main", "kernel", "crash"]:
dropped = get_dropped_logs(self, buffer)
if buffer == "main":
# after b/276957640, should be able to reduce this to ~4000
self.assertLess(dropped, 30000, f"Buffer {buffer} has {dropped} dropped logs.")
else:
self.assertEqual(dropped, 0, f"Buffer {buffer} has {dropped} dropped logs.")
def main():
unittest.main(verbosity=3)
if __name__ == "__main__":
main()