blob: 247951080d1b306fde28dedf2f28ab3b906c5083 [file] [log] [blame]
Rui Qiu337cb242021-06-03 11:26:16 -07001/*
2 * Copyright (C) 2021 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
17package com.android.car.telemetry.databroker;
18
19import static com.google.common.truth.Truth.assertThat;
Rui Qiu033041e2021-06-21 14:59:11 -070020import static com.google.common.truth.Truth.assertWithMessage;
Rui Qiu337cb242021-06-03 11:26:16 -070021
Rui Qiua86ab602021-07-02 10:40:36 -070022import static org.mockito.ArgumentMatchers.any;
23import static org.mockito.ArgumentMatchers.anyInt;
24import static org.mockito.ArgumentMatchers.anyString;
Rui Qiuaba02082021-08-16 16:24:00 -070025import static org.mockito.ArgumentMatchers.eq;
Rui Qiua86ab602021-07-02 10:40:36 -070026import static org.mockito.Mockito.verify;
Zhomart Mukhamejanov44570cb2021-06-07 10:23:13 -070027import static org.mockito.Mockito.when;
Rui Qiu337cb242021-06-03 11:26:16 -070028
Rui Qiua86ab602021-07-02 10:40:36 -070029import android.annotation.Nullable;
Zhomart Mukhamejanov44570cb2021-06-07 10:23:13 -070030import android.car.hardware.CarPropertyConfig;
Rui Qiua86ab602021-07-02 10:40:36 -070031import android.content.Context;
32import android.content.ServiceConnection;
Zhomart Mukhamejanovcdcb4e12021-08-23 18:24:40 -070033import android.content.SharedPreferences;
Rui Qiu033041e2021-06-21 14:59:11 -070034import android.os.Handler;
Rui Qiua86ab602021-07-02 10:40:36 -070035import android.os.IBinder;
Rui Qiuaba02082021-08-16 16:24:00 -070036import android.os.PersistableBundle;
Rui Qiua86ab602021-07-02 10:40:36 -070037import android.os.RemoteException;
Rui Qiu033041e2021-06-21 14:59:11 -070038import android.os.SystemClock;
Zhomart Mukhamejanov44570cb2021-06-07 10:23:13 -070039
40import com.android.car.CarPropertyService;
Rui Qiuaba02082021-08-16 16:24:00 -070041import com.android.car.telemetry.ResultStore;
Zhomart Mukhamejanov44570cb2021-06-07 10:23:13 -070042import com.android.car.telemetry.TelemetryProto;
43import com.android.car.telemetry.publisher.PublisherFactory;
Zhomart Mukhamejanovcdcb4e12021-08-23 18:24:40 -070044import com.android.car.telemetry.publisher.StatsManagerProxy;
Max Dashouk9912ac32021-08-13 17:54:51 +000045import com.android.car.telemetry.scriptexecutorinterface.IScriptExecutor;
46import com.android.car.telemetry.scriptexecutorinterface.IScriptExecutorListener;
Zhomart Mukhamejanov44570cb2021-06-07 10:23:13 -070047
48import org.junit.Before;
Rui Qiu337cb242021-06-03 11:26:16 -070049import org.junit.Test;
50import org.junit.runner.RunWith;
Rui Qiua86ab602021-07-02 10:40:36 -070051import org.mockito.ArgumentCaptor;
Zhomart Mukhamejanov44570cb2021-06-07 10:23:13 -070052import org.mockito.Mock;
Rui Qiuac8b5ba2021-08-25 16:04:17 -070053import org.mockito.Mockito;
Rui Qiu337cb242021-06-03 11:26:16 -070054import org.mockito.junit.MockitoJUnitRunner;
55
Zhomart Mukhamejanov44570cb2021-06-07 10:23:13 -070056import java.util.Collections;
Rui Qiuac8b5ba2021-08-25 16:04:17 -070057import java.util.concurrent.CountDownLatch;
Rui Qiu033041e2021-06-21 14:59:11 -070058import java.util.concurrent.PriorityBlockingQueue;
Rui Qiuac8b5ba2021-08-25 16:04:17 -070059import java.util.concurrent.TimeUnit;
Zhomart Mukhamejanov44570cb2021-06-07 10:23:13 -070060
Rui Qiu337cb242021-06-03 11:26:16 -070061@RunWith(MockitoJUnitRunner.class)
Rui Qiuac8b5ba2021-08-25 16:04:17 -070062public class DataBrokerTest {
Zhomart Mukhamejanov44570cb2021-06-07 10:23:13 -070063 private static final int PROP_ID = 100;
64 private static final int PROP_AREA = 200;
Rui Qiu033041e2021-06-21 14:59:11 -070065 private static final int PRIORITY_HIGH = 1;
Rui Qiud95f95d2021-08-17 12:29:33 -070066 private static final int PRIORITY_LOW = 100;
Rui Qiu033041e2021-06-21 14:59:11 -070067 private static final long TIMEOUT_MS = 5_000L;
Zhomart Mukhamejanov44570cb2021-06-07 10:23:13 -070068 private static final CarPropertyConfig<Integer> PROP_CONFIG =
69 CarPropertyConfig.newBuilder(Integer.class, PROP_ID, PROP_AREA).setAccess(
70 CarPropertyConfig.VEHICLE_PROPERTY_ACCESS_READ).build();
Max Dashoukdafdd222021-08-20 10:42:25 -070071 private static final PersistableBundle DATA = new PersistableBundle();
Rui Qiu337cb242021-06-03 11:26:16 -070072 private static final TelemetryProto.VehiclePropertyPublisher
73 VEHICLE_PROPERTY_PUBLISHER_CONFIGURATION =
74 TelemetryProto.VehiclePropertyPublisher.newBuilder().setReadRate(
Zhomart Mukhamejanov44570cb2021-06-07 10:23:13 -070075 1).setVehiclePropertyId(PROP_ID).build();
Rui Qiu337cb242021-06-03 11:26:16 -070076 private static final TelemetryProto.Publisher PUBLISHER_CONFIGURATION =
77 TelemetryProto.Publisher.newBuilder().setVehicleProperty(
78 VEHICLE_PROPERTY_PUBLISHER_CONFIGURATION).build();
79 private static final TelemetryProto.Subscriber SUBSCRIBER_FOO =
80 TelemetryProto.Subscriber.newBuilder().setHandler("function_name_foo").setPublisher(
Rui Qiud95f95d2021-08-17 12:29:33 -070081 PUBLISHER_CONFIGURATION).setPriority(PRIORITY_HIGH).build();
Rui Qiu337cb242021-06-03 11:26:16 -070082 private static final TelemetryProto.MetricsConfig METRICS_CONFIG_FOO =
83 TelemetryProto.MetricsConfig.newBuilder().setName("Foo").setVersion(
84 1).addSubscribers(SUBSCRIBER_FOO).build();
85 private static final TelemetryProto.Subscriber SUBSCRIBER_BAR =
86 TelemetryProto.Subscriber.newBuilder().setHandler("function_name_bar").setPublisher(
Rui Qiud95f95d2021-08-17 12:29:33 -070087 PUBLISHER_CONFIGURATION).setPriority(PRIORITY_LOW).build();
Rui Qiu337cb242021-06-03 11:26:16 -070088 private static final TelemetryProto.MetricsConfig METRICS_CONFIG_BAR =
89 TelemetryProto.MetricsConfig.newBuilder().setName("Bar").setVersion(
90 1).addSubscribers(SUBSCRIBER_BAR).build();
91
Rui Qiuac8b5ba2021-08-25 16:04:17 -070092 // when count reaches 0, all messages are handled, so assertions won't have race condition
93 private CountDownLatch mIdleHandlerLatch = new CountDownLatch(1);
Zhomart Mukhamejanov44570cb2021-06-07 10:23:13 -070094 private DataBrokerImpl mDataBroker;
Rui Qiua86ab602021-07-02 10:40:36 -070095 private FakeScriptExecutor mFakeScriptExecutor;
Rui Qiu033041e2021-06-21 14:59:11 -070096 private ScriptExecutionTask mHighPriorityTask;
97 private ScriptExecutionTask mLowPriorityTask;
Zhomart Mukhamejanov44570cb2021-06-07 10:23:13 -070098
Rui Qiua86ab602021-07-02 10:40:36 -070099 @Mock
100 private Context mMockContext;
101 @Mock
102 private CarPropertyService mMockCarPropertyService;
103 @Mock
Rui Qiuac8b5ba2021-08-25 16:04:17 -0700104 private Handler mMockHandler;
105 @Mock
Zhomart Mukhamejanovcdcb4e12021-08-23 18:24:40 -0700106 private StatsManagerProxy mMockStatsManager;
107 @Mock
108 private SharedPreferences mMockSharedPreferences;
109 @Mock
Rui Qiua86ab602021-07-02 10:40:36 -0700110 private IBinder mMockScriptExecutorBinder;
Rui Qiuaba02082021-08-16 16:24:00 -0700111 @Mock
112 private ResultStore mMockResultStore;
Rui Qiua86ab602021-07-02 10:40:36 -0700113
Zhomart Mukhamejanov44570cb2021-06-07 10:23:13 -0700114 @Before
115 public void setUp() {
116 when(mMockCarPropertyService.getPropertyList())
117 .thenReturn(Collections.singletonList(PROP_CONFIG));
Rui Qiua86ab602021-07-02 10:40:36 -0700118 // bind service should return true, otherwise broker is disabled
119 when(mMockContext.bindServiceAsUser(any(), any(), anyInt(), any())).thenReturn(true);
Zhomart Mukhamejanovcdcb4e12021-08-23 18:24:40 -0700120 PublisherFactory factory = new PublisherFactory(
Rui Qiuac8b5ba2021-08-25 16:04:17 -0700121 mMockCarPropertyService, mMockHandler, mMockStatsManager, mMockSharedPreferences);
Rui Qiuaba02082021-08-16 16:24:00 -0700122 mDataBroker = new DataBrokerImpl(mMockContext, factory, mMockResultStore);
Rui Qiuac8b5ba2021-08-25 16:04:17 -0700123 // add IdleHandler to get notified when all messages and posts are handled
124 mDataBroker.getTelemetryHandler().getLooper().getQueue().addIdleHandler(() -> {
125 mIdleHandlerLatch.countDown();
126 return true;
127 });
Rui Qiua86ab602021-07-02 10:40:36 -0700128
129 mFakeScriptExecutor = new FakeScriptExecutor();
130 when(mMockScriptExecutorBinder.queryLocalInterface(anyString()))
131 .thenReturn(mFakeScriptExecutor);
Rui Qiuac8b5ba2021-08-25 16:04:17 -0700132 when(mMockContext.bindServiceAsUser(any(), any(), anyInt(), any())).thenAnswer(i -> {
133 ServiceConnection conn = i.getArgument(1);
134 conn.onServiceConnected(null, mMockScriptExecutorBinder);
135 return true;
136 });
Rui Qiua86ab602021-07-02 10:40:36 -0700137
Rui Qiu033041e2021-06-21 14:59:11 -0700138 mHighPriorityTask = new ScriptExecutionTask(
Rui Qiud95f95d2021-08-17 12:29:33 -0700139 new DataSubscriber(mDataBroker, METRICS_CONFIG_FOO, SUBSCRIBER_FOO),
Rui Qiu033041e2021-06-21 14:59:11 -0700140 DATA,
141 SystemClock.elapsedRealtime());
142 mLowPriorityTask = new ScriptExecutionTask(
Rui Qiud95f95d2021-08-17 12:29:33 -0700143 new DataSubscriber(mDataBroker, METRICS_CONFIG_BAR, SUBSCRIBER_BAR),
Rui Qiu033041e2021-06-21 14:59:11 -0700144 DATA,
145 SystemClock.elapsedRealtime());
146 }
147
148 @Test
Rui Qiuac8b5ba2021-08-25 16:04:17 -0700149 public void testSetTaskExecutionPriority_whenNoTask_shouldNotInvokeScriptExecutor()
150 throws Exception {
Rui Qiu033041e2021-06-21 14:59:11 -0700151 mDataBroker.setTaskExecutionPriority(PRIORITY_HIGH);
152
Rui Qiua86ab602021-07-02 10:40:36 -0700153 waitForHandlerThreadToFinish();
154 assertThat(mFakeScriptExecutor.getApiInvocationCount()).isEqualTo(0);
Rui Qiu033041e2021-06-21 14:59:11 -0700155 }
156
157 @Test
Rui Qiuac8b5ba2021-08-25 16:04:17 -0700158 public void testSetTaskExecutionPriority_whenNextTaskPriorityLow_shouldNotRunTask()
159 throws Exception {
Rui Qiu033041e2021-06-21 14:59:11 -0700160 mDataBroker.getTaskQueue().add(mLowPriorityTask);
161
162 mDataBroker.setTaskExecutionPriority(PRIORITY_HIGH);
163
164 waitForHandlerThreadToFinish();
165 // task is not polled
166 assertThat(mDataBroker.getTaskQueue().peek()).isEqualTo(mLowPriorityTask);
Rui Qiua86ab602021-07-02 10:40:36 -0700167 assertThat(mFakeScriptExecutor.getApiInvocationCount()).isEqualTo(0);
Rui Qiu033041e2021-06-21 14:59:11 -0700168 }
169
170 @Test
Rui Qiuac8b5ba2021-08-25 16:04:17 -0700171 public void testSetTaskExecutionPriority_whenNextTaskPriorityHigh_shouldInvokeScriptExecutor()
172 throws Exception {
Rui Qiu033041e2021-06-21 14:59:11 -0700173 mDataBroker.getTaskQueue().add(mHighPriorityTask);
174
175 mDataBroker.setTaskExecutionPriority(PRIORITY_HIGH);
176
177 waitForHandlerThreadToFinish();
178 // task is polled and run
179 assertThat(mDataBroker.getTaskQueue().peek()).isNull();
Rui Qiua86ab602021-07-02 10:40:36 -0700180 assertThat(mFakeScriptExecutor.getApiInvocationCount()).isEqualTo(1);
Rui Qiu033041e2021-06-21 14:59:11 -0700181 }
182
183 @Test
Rui Qiuac8b5ba2021-08-25 16:04:17 -0700184 public void testScheduleNextTask_whenNoTask_shouldNotInvokeScriptExecutor() throws Exception {
Rui Qiu033041e2021-06-21 14:59:11 -0700185 mDataBroker.scheduleNextTask();
186
Rui Qiua86ab602021-07-02 10:40:36 -0700187 waitForHandlerThreadToFinish();
188 assertThat(mFakeScriptExecutor.getApiInvocationCount()).isEqualTo(0);
Rui Qiu033041e2021-06-21 14:59:11 -0700189 }
190
191 @Test
Rui Qiuac8b5ba2021-08-25 16:04:17 -0700192 public void testScheduleNextTask_whenTaskInProgress_shouldNotInvokeScriptExecutorAgain()
193 throws Exception {
Rui Qiu033041e2021-06-21 14:59:11 -0700194 PriorityBlockingQueue<ScriptExecutionTask> taskQueue = mDataBroker.getTaskQueue();
195 taskQueue.add(mHighPriorityTask);
196 mDataBroker.scheduleNextTask(); // start a task
197 waitForHandlerThreadToFinish();
198 assertThat(taskQueue.peek()).isNull(); // assert that task is polled and running
199 taskQueue.add(mHighPriorityTask); // add another task into the queue
200
201 mDataBroker.scheduleNextTask(); // schedule next task while the last task is in progress
202
Rui Qiua86ab602021-07-02 10:40:36 -0700203 // verify task is not polled
204 assertThat(taskQueue.peek()).isEqualTo(mHighPriorityTask);
205 // expect one invocation for the task that is running
206 assertThat(mFakeScriptExecutor.getApiInvocationCount()).isEqualTo(1);
207 }
208
209 @Test
Rui Qiuac8b5ba2021-08-25 16:04:17 -0700210 public void testScheduleNextTask_whenTaskCompletes_shouldAutomaticallyScheduleNextTask()
211 throws Exception {
Rui Qiua86ab602021-07-02 10:40:36 -0700212 PriorityBlockingQueue<ScriptExecutionTask> taskQueue = mDataBroker.getTaskQueue();
213 // add two tasks into the queue for execution
214 taskQueue.add(mHighPriorityTask);
215 taskQueue.add(mHighPriorityTask);
216
217 mDataBroker.scheduleNextTask(); // start a task
218 waitForHandlerThreadToFinish();
Rui Qiuac8b5ba2021-08-25 16:04:17 -0700219 mIdleHandlerLatch = new CountDownLatch(1); // reset handler idle condition
Rui Qiua86ab602021-07-02 10:40:36 -0700220 // end a task, should automatically schedule the next task
Rui Qiuac8b5ba2021-08-25 16:04:17 -0700221 mFakeScriptExecutor.notifyScriptSuccess(DATA); // posts to handler
Rui Qiua86ab602021-07-02 10:40:36 -0700222
223 waitForHandlerThreadToFinish();
224 // verify queue is empty, both tasks are polled and executed
225 assertThat(taskQueue.peek()).isNull();
226 assertThat(mFakeScriptExecutor.getApiInvocationCount()).isEqualTo(2);
227 }
228
229 @Test
Rui Qiuac8b5ba2021-08-25 16:04:17 -0700230 public void testScheduleNextTask_onScriptSuccess_shouldStoreInterimResult() throws Exception {
Rui Qiuaba02082021-08-16 16:24:00 -0700231 mDataBroker.getTaskQueue().add(mHighPriorityTask);
232 ArgumentCaptor<PersistableBundle> persistableBundleCaptor =
233 ArgumentCaptor.forClass(PersistableBundle.class);
234
235 mDataBroker.scheduleNextTask();
236 waitForHandlerThreadToFinish();
Rui Qiuac8b5ba2021-08-25 16:04:17 -0700237 mFakeScriptExecutor.notifyScriptSuccess(DATA);
Rui Qiuaba02082021-08-16 16:24:00 -0700238
239 assertThat(mFakeScriptExecutor.getApiInvocationCount()).isEqualTo(1);
240 verify(mMockResultStore).putInterimResult(eq(METRICS_CONFIG_FOO.getName()),
241 persistableBundleCaptor.capture());
242 assertThat(persistableBundleCaptor.getValue().toString()).isEqualTo(
Rui Qiuac8b5ba2021-08-25 16:04:17 -0700243 DATA.toString()); // expect same persistable bundle
Rui Qiuaba02082021-08-16 16:24:00 -0700244 }
245
246 @Test
Rui Qiuac8b5ba2021-08-25 16:04:17 -0700247 public void testScheduleNextTask_whenBindScriptExecutorFailed_shouldDisableBroker()
248 throws Exception {
249 // fail all future attempts to bind to it
250 Mockito.reset(mMockContext);
251 when(mMockContext.bindServiceAsUser(any(), any(), anyInt(), any())).thenReturn(false);
Rui Qiua86ab602021-07-02 10:40:36 -0700252 mDataBroker.addMetricsConfiguration(METRICS_CONFIG_FOO);
253 PriorityBlockingQueue<ScriptExecutionTask> taskQueue = mDataBroker.getTaskQueue();
254 taskQueue.add(mHighPriorityTask);
Rui Qiua86ab602021-07-02 10:40:36 -0700255
256 // will rebind to ScriptExecutor if it is null
257 mDataBroker.scheduleNextTask();
258
259 waitForHandlerThreadToFinish();
260 // all subscribers should have been removed
261 assertThat(mDataBroker.getSubscriptionMap()).hasSize(0);
262 assertThat(mFakeScriptExecutor.getApiInvocationCount()).isEqualTo(0);
263 }
264
265 @Test
Rui Qiuac8b5ba2021-08-25 16:04:17 -0700266 public void testScheduleNextTask_whenScriptExecutorThrowsException_shouldRequeueTask()
267 throws Exception {
Rui Qiua86ab602021-07-02 10:40:36 -0700268 PriorityBlockingQueue<ScriptExecutionTask> taskQueue = mDataBroker.getTaskQueue();
269 taskQueue.add(mHighPriorityTask);
270 mFakeScriptExecutor.failNextApiCalls(1); // fail the next invokeScript() call
271
272 mDataBroker.scheduleNextTask();
273
274 waitForHandlerThreadToFinish();
275 // expect invokeScript() to be called and failed, causing the same task to be re-queued
276 assertThat(mFakeScriptExecutor.getApiInvocationCount()).isEqualTo(1);
Rui Qiu033041e2021-06-21 14:59:11 -0700277 assertThat(taskQueue.peek()).isEqualTo(mHighPriorityTask);
278 }
279
280 @Test
Rui Qiuac8b5ba2021-08-25 16:04:17 -0700281 public void testAddTaskToQueue_shouldInvokeScriptExecutor() throws Exception {
Rui Qiu033041e2021-06-21 14:59:11 -0700282 mDataBroker.addTaskToQueue(mHighPriorityTask);
283
Rui Qiua86ab602021-07-02 10:40:36 -0700284 waitForHandlerThreadToFinish();
285 assertThat(mFakeScriptExecutor.getApiInvocationCount()).isEqualTo(1);
Zhomart Mukhamejanov44570cb2021-06-07 10:23:13 -0700286 }
287
Rui Qiu337cb242021-06-03 11:26:16 -0700288 @Test
289 public void testAddMetricsConfiguration_newMetricsConfig() {
Rui Qiuf14c6a22021-07-14 10:39:16 -0700290 mDataBroker.addMetricsConfiguration(METRICS_CONFIG_BAR);
291
Rui Qiuf14c6a22021-07-14 10:39:16 -0700292 assertThat(mDataBroker.getSubscriptionMap()).hasSize(1);
293 assertThat(mDataBroker.getSubscriptionMap()).containsKey(METRICS_CONFIG_BAR.getName());
294 // there should be one data subscriber in the subscription list of METRICS_CONFIG_BAR
295 assertThat(mDataBroker.getSubscriptionMap().get(METRICS_CONFIG_BAR.getName())).hasSize(1);
296 }
297
298
299 @Test
300 public void testAddMetricsConfiguration_duplicateMetricsConfig_shouldDoNothing() {
301 // this metrics config has already been added in setUp()
Rui Qiu337cb242021-06-03 11:26:16 -0700302 mDataBroker.addMetricsConfiguration(METRICS_CONFIG_FOO);
303
Rui Qiuf14c6a22021-07-14 10:39:16 -0700304 assertThat(mDataBroker.getSubscriptionMap()).hasSize(1);
Rui Qiu337cb242021-06-03 11:26:16 -0700305 assertThat(mDataBroker.getSubscriptionMap()).containsKey(METRICS_CONFIG_FOO.getName());
Rui Qiu337cb242021-06-03 11:26:16 -0700306 assertThat(mDataBroker.getSubscriptionMap().get(METRICS_CONFIG_FOO.getName())).hasSize(1);
307 }
308
309 @Test
Rui Qiuf14c6a22021-07-14 10:39:16 -0700310 public void testRemoveMetricsConfiguration_shouldRemoveAllAssociatedTasks() {
Rui Qiu337cb242021-06-03 11:26:16 -0700311 mDataBroker.addMetricsConfiguration(METRICS_CONFIG_FOO);
312 mDataBroker.addMetricsConfiguration(METRICS_CONFIG_BAR);
Rui Qiud95f95d2021-08-17 12:29:33 -0700313 ScriptExecutionTask taskWithMetricsConfigFoo = new ScriptExecutionTask(
314 new DataSubscriber(mDataBroker, METRICS_CONFIG_FOO, SUBSCRIBER_FOO),
315 DATA,
Rui Qiuf14c6a22021-07-14 10:39:16 -0700316 SystemClock.elapsedRealtime());
317 PriorityBlockingQueue<ScriptExecutionTask> taskQueue = mDataBroker.getTaskQueue();
318 taskQueue.add(mHighPriorityTask); // associated with METRICS_CONFIG_FOO
Rui Qiud95f95d2021-08-17 12:29:33 -0700319 taskQueue.add(mLowPriorityTask); // associated with METRICS_CONFIG_BAR
320 taskQueue.add(taskWithMetricsConfigFoo); // associated with METRICS_CONFIG_FOO
Rui Qiuf14c6a22021-07-14 10:39:16 -0700321 assertThat(taskQueue).hasSize(3);
322
323 mDataBroker.removeMetricsConfiguration(METRICS_CONFIG_FOO);
Rui Qiu337cb242021-06-03 11:26:16 -0700324
Rui Qiuf14c6a22021-07-14 10:39:16 -0700325 assertThat(taskQueue).hasSize(1);
Rui Qiud95f95d2021-08-17 12:29:33 -0700326 assertThat(taskQueue.poll()).isEqualTo(mLowPriorityTask);
Rui Qiuf14c6a22021-07-14 10:39:16 -0700327 }
328
329 @Test
330 public void testRemoveMetricsConfiguration_whenMetricsConfigNonExistent_shouldDoNothing() {
331 mDataBroker.removeMetricsConfiguration(METRICS_CONFIG_BAR);
332
Rui Qiuf14c6a22021-07-14 10:39:16 -0700333 assertThat(mDataBroker.getSubscriptionMap()).hasSize(0);
Rui Qiu337cb242021-06-03 11:26:16 -0700334 }
335
Rui Qiuac8b5ba2021-08-25 16:04:17 -0700336 private void waitForHandlerThreadToFinish() throws Exception {
Rui Qiu033041e2021-06-21 14:59:11 -0700337 assertWithMessage("handler not idle in %sms", TIMEOUT_MS)
Rui Qiuac8b5ba2021-08-25 16:04:17 -0700338 .that(mIdleHandlerLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
Rui Qiu337cb242021-06-03 11:26:16 -0700339 }
Rui Qiua86ab602021-07-02 10:40:36 -0700340
341 private static class FakeScriptExecutor implements IScriptExecutor {
342 private IScriptExecutorListener mListener;
343 private int mApiInvocationCount = 0;
344 private int mFailApi = 0;
345
346 @Override
Max Dashoukdafdd222021-08-20 10:42:25 -0700347 public void invokeScript(String scriptBody, String functionName,
348 PersistableBundle publishedData, @Nullable PersistableBundle savedState,
349 IScriptExecutorListener listener)
Rui Qiua86ab602021-07-02 10:40:36 -0700350 throws RemoteException {
351 mApiInvocationCount++;
352 mListener = listener;
353 if (mFailApi > 0) {
354 mFailApi--;
355 throw new RemoteException("Simulated failure");
356 }
357 }
358
359 @Override
360 public IBinder asBinder() {
361 return null;
362 }
363
Rui Qiuaba02082021-08-16 16:24:00 -0700364 /** Mocks script temporary completion. */
Max Dashoukdafdd222021-08-20 10:42:25 -0700365 public void notifyScriptSuccess(PersistableBundle bundle) {
Rui Qiua86ab602021-07-02 10:40:36 -0700366 try {
Rui Qiuaba02082021-08-16 16:24:00 -0700367 mListener.onSuccess(bundle);
Rui Qiua86ab602021-07-02 10:40:36 -0700368 } catch (RemoteException e) {
369 // nothing to do
370 }
371 }
372
373 /** Fails the next N invokeScript() call. */
374 public void failNextApiCalls(int n) {
375 mFailApi = n;
376 }
377
378 /** Returns number of times the ScriptExecutor API was invoked. */
379 public int getApiInvocationCount() {
380 return mApiInvocationCount;
381 }
382 }
Rui Qiu337cb242021-06-03 11:26:16 -0700383}