1 /* 2 * Copyright (C) 2024 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 package com.android.adservices.shared.meta_testing; 17 18 import com.android.adservices.shared.testing.AndroidSdk.Level; 19 import com.android.adservices.shared.testing.Nullable; 20 import com.android.adservices.shared.testing.device.AbstractDeviceGateway; 21 import com.android.adservices.shared.testing.device.ShellCommandInput; 22 import com.android.adservices.shared.testing.device.ShellCommandOutput; 23 24 import com.google.common.truth.Expect; 25 import com.google.common.truth.StandardSubjectBuilder; 26 import com.google.errorprone.annotations.FormatMethod; 27 import com.google.errorprone.annotations.FormatString; 28 29 import java.util.ArrayList; 30 import java.util.HashMap; 31 import java.util.List; 32 import java.util.Map; 33 import java.util.Objects; 34 35 public final class FakeDeviceGateway extends AbstractDeviceGateway { 36 37 private final Map<String, ShellCommandOutput> mResultExpectations = new HashMap<>(); 38 private final List<String> mCalls = new ArrayList<>(); 39 40 @Nullable private Level mSdkLevel; 41 42 /** Sets what the given command will return. */ 43 @FormatMethod onCommand(String result, @FormatString String cmdFmt, @Nullable Object... cmdArgs)44 public void onCommand(String result, @FormatString String cmdFmt, @Nullable Object... cmdArgs) { 45 Objects.requireNonNull(result, "result cannot be null"); 46 Objects.requireNonNull(cmdFmt, "cmdFmt cannot be null"); 47 String cmd = String.format(cmdFmt, cmdArgs); 48 49 mLog.i("expectCalled: %s => %s", cmd, result); 50 mResultExpectations.put(cmd, new ShellCommandOutput(result)); 51 } 52 53 /** Sets what the given command will return. */ onCommand(ShellCommandInput input, ShellCommandOutput output)54 public void onCommand(ShellCommandInput input, ShellCommandOutput output) { 55 Objects.requireNonNull(input, "input cannot be null"); 56 Objects.requireNonNull(output, "output cannot be null"); 57 58 mLog.i("expectCalled: %s => %s", input, output); 59 mResultExpectations.put(input.getCommand(), output); 60 } 61 62 /** Expects that the given command was called. */ 63 @FormatMethod expectCalled( StandardSubjectBuilder expect, @FormatString String cmdFmt, @Nullable Object... cmdArgs)64 public void expectCalled( 65 StandardSubjectBuilder expect, 66 @FormatString String cmdFmt, 67 @Nullable Object... cmdArgs) { 68 expectCalled(expect, new ShellCommandInput(cmdFmt, cmdArgs)); 69 } 70 71 /** Expects that the given command was called. */ expectCalled(StandardSubjectBuilder expect, ShellCommandInput input)72 public void expectCalled(StandardSubjectBuilder expect, ShellCommandInput input) { 73 Objects.requireNonNull(input, "input cannot be null"); 74 String cmd = input.getCommand(); 75 if (!mCalls.contains(cmd)) { 76 expect.withMessage( 77 "Command %s not called (commands called so far were: %s)", cmd, mCalls) 78 .fail(); 79 } 80 } 81 82 /** Asserts that no command has been called so far. */ expectNothingCalled(Expect expect)83 public void expectNothingCalled(Expect expect) { 84 expect.withMessage("calls so far").that(mCalls).isEmpty(); 85 } 86 87 /** 88 * Sets the SDK Level of the device. 89 * 90 * @return itself, so it can be nested 91 */ setSdkLevel(Level level)92 public FakeDeviceGateway setSdkLevel(Level level) { 93 Objects.requireNonNull(level, "level cannot be null"); 94 mSdkLevel = level; 95 return this; 96 } 97 98 @Override runShellCommandRwe(ShellCommandInput input)99 public ShellCommandOutput runShellCommandRwe(ShellCommandInput input) { 100 Objects.requireNonNull(input, "input cannot be null"); 101 102 mLog.i("runShellCommandRwe(): running %s", input); 103 104 mCalls.add(input.getCommand()); 105 106 ShellCommandOutput output = mResultExpectations.get(input.getCommand()); 107 mLog.i("runShellCommandRwe(): returning %s", output); 108 109 return output; 110 } 111 112 @Override getSdkLevel()113 public Level getSdkLevel() { 114 if (mSdkLevel == null) { 115 throw new IllegalStateException("must call setSdkLevel() first"); 116 } 117 return mSdkLevel; 118 } 119 120 @Override toString()121 public String toString() { 122 return "FakeDeviceGateway [mLog=" 123 + mLog 124 + ", mSdkLevel=" 125 + mSdkLevel 126 + ", mResultExpectations=" 127 + mResultExpectations 128 + ", mCalls=" 129 + mCalls 130 + "]"; 131 } 132 } 133