1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.tests.rollback.host; 18 19 import static com.google.common.truth.Truth.assertThat; 20 21 import com.android.tradefed.device.ITestDevice; 22 import com.android.tradefed.log.LogUtil.CLog; 23 24 import com.google.common.truth.FailureMetadata; 25 import com.google.common.truth.Truth; 26 27 import java.util.regex.Matcher; 28 import java.util.regex.Pattern; 29 30 public class WatchdogEventLogger { 31 32 private ITestDevice mDevice; 33 updateTestSysProp(boolean enabled)34 private void updateTestSysProp(boolean enabled) throws Exception { 35 try { 36 mDevice.enableAdbRoot(); 37 assertThat(mDevice.setProperty( 38 "persist.sys.rollbacktest.enabled", String.valueOf(enabled))).isTrue(); 39 } finally { 40 mDevice.disableAdbRoot(); 41 } 42 } 43 start(ITestDevice device)44 public void start(ITestDevice device) throws Exception { 45 mDevice = device; 46 updateTestSysProp(true); 47 } 48 stop()49 public void stop() throws Exception { 50 if (mDevice != null) { 51 updateTestSysProp(false); 52 } 53 } 54 verifyEventContainsVal(String watchdogEvent, String expectedVal)55 private boolean verifyEventContainsVal(String watchdogEvent, String expectedVal) { 56 return expectedVal == null || watchdogEvent.contains(expectedVal); 57 } 58 59 /** 60 * Returns whether a Watchdog event has occurred that matches the given criteria. 61 * 62 * Check the value of all non-null parameters against the list of Watchdog events that have 63 * occurred, and return {@code true} if an event exists which matches all criteria. 64 */ watchdogEventOccurred(String type, String logPackage, String rollbackReason, String failedPackageName)65 public boolean watchdogEventOccurred(String type, String logPackage, 66 String rollbackReason, String failedPackageName) { 67 String watchdogEvent = getEventForRollbackType(type); 68 return (watchdogEvent != null) 69 && verifyEventContainsVal(watchdogEvent, logPackage) 70 && verifyEventContainsVal(watchdogEvent, rollbackReason) 71 && verifyEventContainsVal(watchdogEvent, failedPackageName); 72 } 73 74 /** Returns last matched event for rollbackType **/ getEventForRollbackType(String rollbackType)75 private String getEventForRollbackType(String rollbackType) { 76 String lastMatchedEvent = null; 77 try { 78 String rollbackDump = mDevice.executeShellCommand("dumpsys rollback"); 79 String eventRegex = ".*%s%s(.*)\\n"; 80 String eventPrefix = "Watchdog event occurred with type: "; 81 82 final Pattern pattern = Pattern.compile( 83 String.format(eventRegex, eventPrefix, rollbackType)); 84 final Matcher matcher = pattern.matcher(rollbackDump); 85 while (matcher.find()) { 86 lastMatchedEvent = matcher.group(1); 87 } 88 CLog.d("Found watchdogEvent: " + lastMatchedEvent + " for type: " + rollbackType); 89 } catch (Exception e) { 90 CLog.e("Unable to find event for type: " + rollbackType, e); 91 } 92 return lastMatchedEvent; 93 } 94 95 static class Subject extends com.google.common.truth.Subject { 96 private final WatchdogEventLogger mActual; 97 Subject(FailureMetadata failureMetadata, WatchdogEventLogger subject)98 private Subject(FailureMetadata failureMetadata, WatchdogEventLogger subject) { 99 super(failureMetadata, subject); 100 mActual = subject; 101 } 102 103 private static com.google.common.truth.Subject.Factory<Subject, loggers()104 WatchdogEventLogger> loggers() { 105 return Subject::new; 106 } 107 assertThat(WatchdogEventLogger actual)108 static Subject assertThat(WatchdogEventLogger actual) { 109 return Truth.assertAbout(loggers()).that(actual); 110 } 111 eventOccurred(String type, String logPackage, String rollbackReason, String failedPackageName)112 void eventOccurred(String type, String logPackage, String rollbackReason, 113 String failedPackageName) { 114 check("watchdogEventOccurred(type=%s, logPackage=%s, rollbackReason=%s, " 115 + "failedPackageName=%s)", type, logPackage, rollbackReason, failedPackageName) 116 .that(mActual.watchdogEventOccurred(type, logPackage, rollbackReason, 117 failedPackageName)).isTrue(); 118 } 119 } 120 } 121