1 /*
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 
17 package com.android.server.util;
18 
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertTrue;
21 
22 import android.net.util.SharedLog;
23 
24 import androidx.test.filters.SmallTest;
25 import androidx.test.runner.AndroidJUnit4;
26 
27 import org.junit.Test;
28 import org.junit.runner.RunWith;
29 
30 import java.io.ByteArrayOutputStream;
31 import java.io.PrintWriter;
32 
33 @RunWith(AndroidJUnit4.class)
34 @SmallTest
35 public class SharedLogTest {
36     private static final String TIMESTAMP_PATTERN = "\\d{2}:\\d{2}:\\d{2}";
37     private static final String TIMESTAMP = "HH:MM:SS";
38 
39     @Test
testBasicOperation()40     public void testBasicOperation() {
41         final SharedLog logTop = new SharedLog("top");
42         logTop.mark("first post!");
43 
44         final SharedLog logLevel2a = logTop.forSubComponent("twoA");
45         final SharedLog logLevel2b = logTop.forSubComponent("twoB");
46         logLevel2b.e("2b or not 2b");
47         logLevel2b.e("No exception", null);
48         logLevel2b.e("Wait, here's one", new Exception("Test"));
49         logLevel2a.w("second post?");
50 
51         final SharedLog logLevel3 = logLevel2a.forSubComponent("three");
52         logTop.log("still logging");
53         logLevel3.log("3 >> 2");
54         logLevel2a.mark("ok: last post");
55 
56         final String[] expected = {
57             " - MARK first post!",
58             " - [twoB] ERROR 2b or not 2b",
59             " - [twoB] ERROR No exception",
60             // No stacktrace in shared log, only in logcat
61             " - [twoB] ERROR Wait, here's one: Test",
62             " - [twoA] WARN second post?",
63             " - still logging",
64             " - [twoA.three] 3 >> 2",
65             " - [twoA] MARK ok: last post",
66         };
67         // Verify the logs are all there and in the correct order.
68         verifyLogLines(expected, logTop);
69 
70         // In fact, because they all share the same underlying LocalLog,
71         // every subcomponent SharedLog's dump() is identical.
72         verifyLogLines(expected, logLevel2a);
73         verifyLogLines(expected, logLevel2b);
74         verifyLogLines(expected, logLevel3);
75     }
76 
verifyLogLines(String[] expected, SharedLog log)77     private static void verifyLogLines(String[] expected, SharedLog log) {
78         final ByteArrayOutputStream ostream = new ByteArrayOutputStream();
79         final PrintWriter pw = new PrintWriter(ostream, true);
80         log.dump(null, pw, null);
81 
82         final String dumpOutput = ostream.toString();
83         assertTrue(dumpOutput != null);
84         assertTrue(!"".equals(dumpOutput));
85 
86         final String[] lines = dumpOutput.split("\n");
87         assertEquals(expected.length, lines.length);
88 
89         for (int i = 0; i < expected.length; i++) {
90             String got = lines[i];
91             String want = expected[i];
92             assertTrue(String.format("'%s' did not contain '%s'", got, want), got.endsWith(want));
93             assertTrue(String.format("'%s' did not contain a %s timestamp", got, TIMESTAMP),
94                     got.replaceFirst(TIMESTAMP_PATTERN, TIMESTAMP).contains(TIMESTAMP));
95         }
96     }
97 }
98