1 /*
2  * Copyright (C) 2009 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 android.util.cts;
18 
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertNull;
21 import static org.junit.Assert.assertTrue;
22 
23 import android.os.Process;
24 import android.platform.test.annotations.IgnoreUnderRavenwood;
25 import android.platform.test.ravenwood.RavenwoodRule;
26 import android.util.EventLog;
27 import android.util.EventLog.Event;
28 
29 import androidx.test.filters.SmallTest;
30 import androidx.test.runner.AndroidJUnit4;
31 
32 import org.junit.Rule;
33 import org.junit.Test;
34 import org.junit.runner.RunWith;
35 
36 import java.io.IOException;
37 import java.util.ArrayList;
38 import java.util.Iterator;
39 import java.util.List;
40 
41 @SmallTest
42 @RunWith(AndroidJUnit4.class)
43 @IgnoreUnderRavenwood(blockedBy = EventLog.class)
44 public class EventLogTest {
45     private static final int ANSWER_TAG = 42;
46     private static final int PI_TAG = 314;
47     private static final int E_TAG = 2718;
48 
49     @Rule
50     public final RavenwoodRule mRavenwood = new RavenwoodRule();
51 
52     @Test
testWriteEvent()53     public void testWriteEvent() throws Exception {
54         long markerData = System.currentTimeMillis();
55         EventLog.writeEvent(ANSWER_TAG, markerData);
56         EventLog.writeEvent(ANSWER_TAG, 12345);
57         EventLog.writeEvent(ANSWER_TAG, 23456L);
58         EventLog.writeEvent(ANSWER_TAG, 42.4242f);
59         EventLog.writeEvent(ANSWER_TAG, "Test");
60         EventLog.writeEvent(ANSWER_TAG, 12345, 23456L, 42.4242f, "Test");
61 
62         List<EventLog.Event> events = getEventsAfterMarker(markerData, ANSWER_TAG);
63         assertEquals(5, events.size());
64         assertEquals(ANSWER_TAG, events.get(0).getTag());
65         assertEquals(12345, events.get(0).getData());
66         assertEquals(23456L, events.get(1).getData());
67         assertEquals(42.4242f, events.get(2).getData());
68         assertEquals("Test", events.get(3).getData());
69 
70         Object[] arr = (Object[]) events.get(4).getData();
71         assertEquals(4, arr.length);
72         assertEquals(12345, arr[0]);
73         assertEquals(23456L, arr[1]);
74         assertEquals(42.4242f, arr[2]);
75         assertEquals("Test", arr[3]);
76     }
77 
78     @Test
testWriteEventWithOversizeValueLimitElision()79     public void testWriteEventWithOversizeValueLimitElision() throws Exception {
80         // make sure big events are postsed and only elided to no less than about 4K.
81         StringBuilder longString = new StringBuilder();
82         for (int i = 0; i < 1000; i++) longString.append("xyzzy");
83 
84         Object[] longArray = new Object[1000];
85         for (int i = 0; i < 1000; i++) longArray[i] = 12345;
86 
87         Long markerData = System.currentTimeMillis();
88         EventLog.writeEvent(ANSWER_TAG, markerData);
89         EventLog.writeEvent(ANSWER_TAG, longString.toString());
90         EventLog.writeEvent(ANSWER_TAG, "hi", longString.toString());
91         EventLog.writeEvent(ANSWER_TAG, 12345, longString.toString());
92         EventLog.writeEvent(ANSWER_TAG, 12345L, longString.toString());
93         EventLog.writeEvent(ANSWER_TAG, 42.4242f, longString.toString());
94         EventLog.writeEvent(ANSWER_TAG, longString.toString(), longString.toString());
95         EventLog.writeEvent(ANSWER_TAG, longArray);
96         List<Event> events = getEventsAfterMarker(markerData, ANSWER_TAG);
97         assertEquals(7, events.size());
98 
99         final int big = 4000; // expect at least this many bytes to get through.
100 
101         // subtract: string header (type + length)
102         String val0 = (String) events.get(0).getData();
103         assertNull("getData on object 0 raised a WTF", events.get(0).getLastError());
104         assertTrue("big string 0 seems short", big < val0.length());
105 
106         // subtract: array header, "hi" header, "hi", string header
107         Object[] arr1 = (Object[]) events.get(1).getData();
108         assertNull("getData on object 1 raised a WTF", events.get(1).getLastError());
109         assertEquals(2, arr1.length);
110         assertEquals("hi", arr1[0]);
111         assertTrue("big string 1 seems short", big < ((String) arr1[1]).length());
112 
113         // subtract: array header, int (type + value), string header
114         Object[] arr2 = (Object[]) events.get(2).getData();
115         assertNull("getData on object 2 raised a WTF", events.get(2).getLastError());
116         assertEquals(2, arr2.length);
117         assertEquals(12345, arr2[0]);
118         assertTrue("big string 2 seems short", big < ((String) arr2[1]).length());
119 
120         // subtract: array header, long, string header
121         Object[] arr3 = (Object[]) events.get(3).getData();
122         assertNull("getData on object 3 raised a WTF", events.get(3).getLastError());
123         assertEquals(2, arr3.length);
124         assertEquals(12345L, arr3[0]);
125         assertTrue("big string 3 seems short", big < ((String) arr3[1]).length());
126 
127         // subtract: array header, float, string header
128         Object[] arr4 = (Object[]) events.get(4).getData();
129         assertNull("getData on object 4 raised a WTF", events.get(4).getLastError());
130         assertEquals(2, arr4.length);
131         assertEquals(42.4242f, arr4[0]);
132         assertTrue("big string 4 seems short", big < ((String) arr4[1]).length());
133 
134         // subtract: array header, string header (second string is dropped entirely)
135         String string5 = (String) events.get(5).getData();
136         assertNull("getData on object 5 raised a WTF", events.get(5).getLastError());
137         assertTrue("big string 5 seems short", big < string5.length());
138 
139         Object[] arr6 = (Object[]) events.get(6).getData();
140         assertNull("getData on object 6 raised a WTF", events.get(6).getLastError());
141         assertEquals(255, arr6.length);
142         assertEquals(12345, arr6[0]);
143         assertEquals(12345, arr6[arr6.length - 1]);
144     }
145 
146     @Test
testOversizeStringMayBeTruncated()147     public void testOversizeStringMayBeTruncated() throws Exception {
148         // make sure big events elide from the end, not the  from the front or middle.
149         StringBuilder longBuilder = new StringBuilder();
150 
151         // build a long string where the prefix is never repeated
152         for (int step = 1; step < 256; step += 2) { // all odds are relatively prime to 256
153             for (int i = 0; i < 255; i++) {
154                 longBuilder.append(String.valueOf((char) (((step * i) % 256) + 1))); // never emit 0
155             }
156         }
157         String longString = longBuilder.toString(); // 32K
158 
159         Long markerData = System.currentTimeMillis();
160         EventLog.writeEvent(ANSWER_TAG, markerData);
161         EventLog.writeEvent(ANSWER_TAG, longString);
162 
163         List<Event> events = getEventsAfterMarker(markerData, ANSWER_TAG);
164         assertEquals(1, events.size());
165 
166         // subtract: string header (type + length)
167         String out = (String) events.get(0).getData();
168         assertNull("getData on big string raised a WTF", events.get(0).getLastError());
169         assertEquals("output is not a prefix of the input", 0, longString.indexOf(out), 0);
170     }
171 
172     @Test
testWriteNullEvent()173     public void testWriteNullEvent() throws Exception {
174         Long markerData = System.currentTimeMillis();
175         EventLog.writeEvent(ANSWER_TAG, markerData);
176         EventLog.writeEvent(ANSWER_TAG, (String) null);
177         EventLog.writeEvent(ANSWER_TAG, 12345, null);
178 
179         List<EventLog.Event> events = getEventsAfterMarker(markerData, ANSWER_TAG);
180         assertEquals(2, events.size());
181         assertEquals("NULL", events.get(0).getData());
182 
183         Object[] arr = (Object[]) events.get(1).getData();
184         assertEquals(2, arr.length);
185         assertEquals(12345, arr[0]);
186         assertEquals("NULL", arr[1]);
187     }
188 
189     @Test
testReadDataWhenNone()190     public void testReadDataWhenNone() throws Exception {
191         Long markerData = System.currentTimeMillis();
192         EventLog.writeEvent(ANSWER_TAG, markerData);
193         EventLog.writeEvent(ANSWER_TAG);
194 
195         List<EventLog.Event> events = getEventsAfterMarker(markerData, ANSWER_TAG);
196         assertEquals(1, events.size());
197         assertEquals("getData on empty data did not return null", null, events.get(0).getData());
198         assertNull("getData on object 0 raised a WTF", events.get(0).getLastError());
199     }
200 
201     @Test
testReadEvents()202     public void testReadEvents() throws Exception {
203         Long markerData = System.currentTimeMillis();
204         EventLog.writeEvent(ANSWER_TAG, markerData);
205 
206         Long data0 = markerData + 1;
207         EventLog.writeEvent(ANSWER_TAG, data0);
208 
209         Long data1 = data0 + 1;
210         EventLog.writeEvent(PI_TAG, data1);
211 
212         Long data2 = data1 + 1;
213         EventLog.writeEvent(E_TAG, data2);
214 
215         List<Event> events = getEventsAfterMarker(markerData, ANSWER_TAG, PI_TAG, E_TAG);
216         assertEquals(3, events.size());
217         verifyEvent(events.get(0), ANSWER_TAG, data0);
218         verifyEvent(events.get(1), PI_TAG, data1);
219         verifyEvent(events.get(2), E_TAG, data2);
220 
221         events = getEventsAfterMarker(markerData, ANSWER_TAG, E_TAG);
222         assertEquals(2, events.size());
223         verifyEvent(events.get(0), ANSWER_TAG, data0);
224         verifyEvent(events.get(1), E_TAG, data2);
225 
226         events = getEventsAfterMarker(markerData, ANSWER_TAG);
227         assertEquals(1, events.size());
228         verifyEvent(events.get(0), ANSWER_TAG, data0);
229     }
230 
231     /** Return elements after and the event that has the marker data and matching tag. */
getEventsAfterMarker(Object marker, int... tags)232     private List<Event> getEventsAfterMarker(Object marker, int... tags)
233             throws IOException, InterruptedException {
234         List<Event> events = new ArrayList<>();
235         // Give the message some time to show up in the log
236         Thread.sleep(20);
237         EventLog.readEvents(tags, events);
238 
239         for (Iterator<Event> itr = events.iterator(); itr.hasNext(); ) {
240             Event event = itr.next();
241             itr.remove();
242             if (marker.equals(event.getData())) {
243                 break;
244             }
245         }
246 
247         verifyEventTimes(events);
248 
249         return events;
250     }
251 
verifyEvent(Event event, int expectedTag, Object expectedData)252     private void verifyEvent(Event event, int expectedTag, Object expectedData) {
253         assertEquals(Process.myPid(), event.getProcessId());
254         assertEquals(Process.myTid(), event.getThreadId());
255         assertEquals(expectedTag, event.getTag());
256         assertEquals(expectedData, event.getData());
257     }
258 
verifyEventTimes(List<Event> events)259     private void verifyEventTimes(List<Event> events) {
260         for (int i = 0; i + 1 < events.size(); i++) {
261             long time = events.get(i).getTimeNanos();
262             long nextTime = events.get(i).getTimeNanos();
263             assertTrue(time <= nextTime);
264         }
265     }
266 
267     @Test
testGetTagName()268     public void testGetTagName() throws Exception {
269         assertEquals("answer", EventLog.getTagName(ANSWER_TAG));
270         assertEquals("pi", EventLog.getTagName(PI_TAG));
271         assertEquals("e", EventLog.getTagName(E_TAG));
272         assertEquals(null, EventLog.getTagName(999999999));
273     }
274 
275     @Test
testGetTagCode()276     public void testGetTagCode() throws Exception {
277         assertEquals(ANSWER_TAG, EventLog.getTagCode("answer"));
278         assertEquals(PI_TAG, EventLog.getTagCode("pi"));
279         assertEquals(E_TAG, EventLog.getTagCode("e"));
280         assertEquals(-1, EventLog.getTagCode("does_not_exist"));
281     }
282 }
283