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