blob: 50852548f5253b14e9cfe7e786ce683d03cf9c6f [file] [log] [blame]
Adrian Roos111aff92017-09-27 18:11:46 +02001/*
2 * Copyright (C) 2017 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.server.wm;
18
19import static org.junit.Assert.assertArrayEquals;
20import static org.junit.Assert.assertEquals;
21import static org.junit.Assert.assertFalse;
22import static org.junit.Assert.assertTrue;
23import static org.mockito.ArgumentMatchers.any;
24import static org.mockito.ArgumentMatchers.eq;
25import static org.mockito.Mockito.doAnswer;
26import static org.mockito.Mockito.mock;
27import static org.mockito.Mockito.verify;
28import static org.mockito.Mockito.verifyZeroInteractions;
29
30import android.content.Context;
31import android.platform.test.annotations.Presubmit;
32import android.support.test.InstrumentationRegistry;
33import android.support.test.filters.SmallTest;
chaviw4f0f3482018-03-01 15:47:56 -080034import android.support.test.filters.FlakyTest;
Adrian Roos111aff92017-09-27 18:11:46 +020035import android.support.test.runner.AndroidJUnit4;
36import android.util.proto.ProtoOutputStream;
37
38import com.android.internal.util.Preconditions;
Yi Jin6c6e9ca2018-03-20 16:53:35 -070039import com.android.server.wm.WindowManagerTraceProto;
Adrian Roos111aff92017-09-27 18:11:46 +020040
41import org.junit.After;
42import org.junit.Before;
43import org.junit.Ignore;
44import org.junit.Test;
45import org.junit.runner.RunWith;
46
47import java.io.File;
48import java.io.FileInputStream;
49import java.io.InputStream;
50import java.io.PrintWriter;
51import java.nio.charset.StandardCharsets;
52
53/**
54 * Test class for {@link WindowTracing}.
55 *
56 * Build/Install/Run:
57 * bit FrameworksServicesTests:com.android.server.wm.WindowTracingTest
58 */
59@SmallTest
chaviw36d0a342018-03-01 17:29:21 -080060@FlakyTest(bugId = 74078662)
Adrian Roos111aff92017-09-27 18:11:46 +020061@Presubmit
62@RunWith(AndroidJUnit4.class)
63public class WindowTracingTest extends WindowTestsBase {
64
65 private static final byte[] MAGIC_HEADER = new byte[] {
66 0x9, 0x57, 0x49, 0x4e, 0x54, 0x52, 0x41, 0x43, 0x45,
67 };
68
69 private Context mTestContext;
70 private WindowTracing mWindowTracing;
71 private WindowManagerService mWmMock;
72 private File mFile;
73
74 @Override
75 @Before
76 public void setUp() throws Exception {
77 super.setUp();
78
79 mWmMock = mock(WindowManagerService.class);
80
81 mTestContext = InstrumentationRegistry.getContext();
82
83 mFile = mTestContext.getFileStreamPath("tracing_test.dat");
84 mFile.delete();
85
86 mWindowTracing = new WindowTracing(mFile);
87 }
88
89 @Test
90 public void isEnabled_returnsFalseByDefault() throws Exception {
91 assertFalse(mWindowTracing.isEnabled());
92 }
93
94 @Test
95 public void isEnabled_returnsTrueAfterStart() throws Exception {
96 mWindowTracing.startTrace(mock(PrintWriter.class));
97 assertTrue(mWindowTracing.isEnabled());
98 }
99
100 @Test
101 public void isEnabled_returnsFalseAfterStop() throws Exception {
102 mWindowTracing.startTrace(mock(PrintWriter.class));
103 mWindowTracing.stopTrace(mock(PrintWriter.class));
104 assertFalse(mWindowTracing.isEnabled());
105 }
106
107 @Test
108 public void trace_discared_whenNotTracing() throws Exception {
109 mWindowTracing.traceStateLocked("where", mWmMock);
110 verifyZeroInteractions(mWmMock);
111 }
112
113 @Test
114 public void trace_dumpsWindowManagerState_whenTracing() throws Exception {
115 mWindowTracing.startTrace(mock(PrintWriter.class));
116 mWindowTracing.traceStateLocked("where", mWmMock);
117
118 verify(mWmMock).writeToProtoLocked(any(), eq(true));
119 }
120
121 @Test
122 public void traceFile_startsWithMagicHeader() throws Exception {
123 mWindowTracing.startTrace(mock(PrintWriter.class));
124 mWindowTracing.stopTrace(mock(PrintWriter.class));
125
126 byte[] header = new byte[MAGIC_HEADER.length];
127 try (InputStream is = new FileInputStream(mFile)) {
128 assertEquals(MAGIC_HEADER.length, is.read(header));
129 assertArrayEquals(MAGIC_HEADER, header);
130 }
131 }
132
133 @Test
134 @Ignore("Figure out why this test is crashing when setting up mWmMock.")
135 public void tracing_endsUpInFile() throws Exception {
136 mWindowTracing.startTrace(mock(PrintWriter.class));
137
138 doAnswer((inv) -> {
139 inv.<ProtoOutputStream>getArgument(0).write(
140 WindowManagerTraceProto.WHERE, "TEST_WM_PROTO");
141 return null;
142 }).when(mWmMock).writeToProtoLocked(any(), any());
143 mWindowTracing.traceStateLocked("TEST_WHERE", mWmMock);
144
145 mWindowTracing.stopTrace(mock(PrintWriter.class));
146
147 byte[] file = new byte[1000];
148 int fileLength;
149 try (InputStream is = new FileInputStream(mFile)) {
150 fileLength = is.read(file);
151 assertTrue(containsBytes(file, fileLength,
152 "TEST_WHERE".getBytes(StandardCharsets.UTF_8)));
153 assertTrue(containsBytes(file, fileLength,
154 "TEST_WM_PROTO".getBytes(StandardCharsets.UTF_8)));
155 }
156 }
157
158 @Override
159 @After
160 public void tearDown() throws Exception {
161 super.tearDown();
162
163 mFile.delete();
164 }
165
166 /** Return true if {@code needle} appears anywhere in {@code haystack[0..length]} */
167 boolean containsBytes(byte[] haystack, int haystackLenght, byte[] needle) {
168 Preconditions.checkArgument(haystackLenght > 0);
169 Preconditions.checkArgument(needle.length > 0);
170
171 outer: for (int i = 0; i <= haystackLenght - needle.length; i++) {
172 for (int j = 0; j < needle.length; j++) {
173 if (haystack[i+j] != needle[j]) {
174 continue outer;
175 }
176 }
177 return true;
178 }
179 return false;
180 }
181
182 @Test
183 public void test_containsBytes() {
184 byte[] haystack = "hello_world".getBytes(StandardCharsets.UTF_8);
185 assertTrue(containsBytes(haystack, haystack.length,
186 "hello".getBytes(StandardCharsets.UTF_8)));
187 assertTrue(containsBytes(haystack, haystack.length,
188 "world".getBytes(StandardCharsets.UTF_8)));
189 assertFalse(containsBytes(haystack, 6,
190 "world".getBytes(StandardCharsets.UTF_8)));
191 assertFalse(containsBytes(haystack, haystack.length,
192 "world_".getBytes(StandardCharsets.UTF_8)));
193 assertFalse(containsBytes(haystack, haystack.length,
194 "absent".getBytes(StandardCharsets.UTF_8)));
195 }
196}