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.eventlib; 18 19 import static com.android.eventlib.truth.EventLogsSubject.assertThat; 20 21 import static java.time.temporal.ChronoUnit.SECONDS; 22 23 import android.util.Log; 24 25 import java.io.Serializable; 26 import java.time.Duration; 27 import java.time.Instant; 28 29 /** Interface to interact with the results of an {@link EventLogsQuery}. */ 30 public abstract class EventLogs<E extends Event> implements Serializable { 31 32 private static final long serialVersionUID = 1; 33 34 static final Duration DEFAULT_POLL_TIMEOUT = Duration.ofMinutes(5); 35 36 // We need to set this earlier than construction otherwise we will skip all events that happen 37 // before creating the first query 38 static Instant sEarliestLogTime = Instant.now().minus(30, SECONDS); 39 40 /** 41 * Returns the {@link EventQuerier} to be used to interact with the 42 * appropriate {@link Event} store. 43 */ getQuerier()44 protected abstract EventQuerier<E> getQuerier(); 45 46 /** 47 * Ensures that future calls to {@link #get()}, {@link #next()}, and {@link #poll()} only return 48 * events which are not already logged before this call to {@link #resetLogs()}. 49 */ resetLogs()50 public static void resetLogs() { 51 // We delay 1 ms before and after to separate the cutoff from logs which are 52 // triggered immediately by the tests - this makes behaviour more predictable 53 54 try { 55 Thread.sleep(1); 56 } catch (InterruptedException e) { 57 Log.d("EventLogs", "Interrupted when sleeping during resetLogs"); 58 } 59 60 sEarliestLogTime = Instant.now(); 61 62 try { 63 Thread.sleep(1); 64 } catch (InterruptedException e) { 65 Log.d("EventLogs", "Interrupted when sleeping during resetLogs"); 66 } 67 } 68 69 /** 70 * Gets the earliest logged event matching the query which has not be returned by a previous 71 * call to {@link #poll()}, or blocks until a matching event is logged. 72 * 73 * <p>This will timeout after {@code timeout} and return null if no matching event is logged. 74 */ poll(Duration timeout)75 public E poll(Duration timeout) { 76 return getQuerier().poll(sEarliestLogTime, timeout); 77 } 78 79 /** 80 * Gets the earliest logged event matching the query which has not be returned by a previous 81 * call to {@link #poll()}, or blocks until a matching event is logged. 82 * 83 * <p>This will timeout after {@link #DEFAULT_POLL_TIMEOUT} and return null if no matching 84 * event is logged. 85 */ poll()86 public E poll() { 87 return poll(DEFAULT_POLL_TIMEOUT); 88 } 89 90 /** 91 * Returns immediately if there is an existing event matching the query which has not be 92 * returned by a previous call to {@link #poll()}, or blocks until a matching event is logged. 93 * 94 * <p>This will timeout after {@code timeout} and throw an {@link AssertionError} if no 95 * matching event is logged. 96 */ waitForEvent(Duration timeout)97 public E waitForEvent(Duration timeout) { 98 return assertThat(this).eventOccurredWithin(timeout); 99 } 100 101 /** 102 * Returns immediately if there is an existing event matching the query which has not be 103 * returned by a previous call to {@link #poll()}, or blocks until a matching event is logged. 104 * 105 * <p>This will timeout after {@link #DEFAULT_POLL_TIMEOUT} and throw an {@link AssertionError} 106 * if no matching event is logged. 107 */ waitForEvent()108 public E waitForEvent() { 109 return waitForEvent(DEFAULT_POLL_TIMEOUT); 110 } 111 } 112