1 /*
2  * Copyright 2023 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 #undef LOG_TAG
18 #define LOG_TAG "TransactionTraceWriterTest"
19 
20 #include <gmock/gmock.h>
21 #include <gtest/gtest.h>
22 #include <log/log.h>
23 #include <filesystem>
24 
25 #include "TestableSurfaceFlinger.h"
26 
27 namespace android {
28 
29 class TransactionTraceWriterTest : public testing::Test {
30 protected:
31     std::string mFilename = "/data/local/tmp/testfile_transaction_trace.winscope";
32 
SetUp()33     void SetUp() { mFlinger.initTransactionTraceWriter(); }
TearDown()34     void TearDown() { std::filesystem::remove(mFilename); }
35 
verifyTraceFile()36     void verifyTraceFile() {
37         std::fstream file(mFilename, std::ios::in);
38         ASSERT_TRUE(file.is_open());
39         std::string line;
40         char magicNumber[8];
41         file.read(magicNumber, 8);
42         EXPECT_EQ("\tTNXTRAC", std::string(magicNumber, magicNumber + 8));
43     }
44 
45     TestableSurfaceFlinger mFlinger;
46 };
47 
48 // Check that a new file is written if overwrite=true and no file exists.
TEST_F(TransactionTraceWriterTest,canWriteToFile_overwriteTrue)49 TEST_F(TransactionTraceWriterTest, canWriteToFile_overwriteTrue) {
50     TransactionTraceWriter::getInstance().invokeForTest(mFilename, /* overwrite */ true);
51     EXPECT_EQ(access(mFilename.c_str(), F_OK), 0);
52     verifyTraceFile();
53 }
54 
55 // Check that a new file is written if overwrite=false and no file exists.
TEST_F(TransactionTraceWriterTest,canWriteToFile_overwriteFalse)56 TEST_F(TransactionTraceWriterTest, canWriteToFile_overwriteFalse) {
57     TransactionTraceWriter::getInstance().invokeForTest(mFilename, /* overwrite */ false);
58     EXPECT_EQ(access(mFilename.c_str(), F_OK), 0);
59     verifyTraceFile();
60 }
61 
62 // Check that an existing file is overwritten when overwrite=true.
TEST_F(TransactionTraceWriterTest,canOverwriteFile)63 TEST_F(TransactionTraceWriterTest, canOverwriteFile) {
64     std::string testLine = "test";
65     {
66         std::ofstream file(mFilename, std::ios::out);
67         file << testLine;
68     }
69     TransactionTraceWriter::getInstance().invokeForTest(mFilename, /* overwrite */ true);
70     verifyTraceFile();
71 }
72 
73 // Check that an existing file isn't overwritten when it is new and overwrite=false.
TEST_F(TransactionTraceWriterTest,doNotOverwriteFile)74 TEST_F(TransactionTraceWriterTest, doNotOverwriteFile) {
75     std::string testLine = "test";
76     {
77         std::ofstream file(mFilename, std::ios::out);
78         file << testLine;
79     }
80     TransactionTraceWriter::getInstance().invokeForTest(mFilename, /* overwrite */ false);
81     {
82         std::fstream file(mFilename, std::ios::in);
83         ASSERT_TRUE(file.is_open());
84         std::string line;
85         std::getline(file, line);
86         EXPECT_EQ(line, testLine);
87     }
88 }
89 
90 // Check that an existing file is overwritten when it is old and overwrite=false.
TEST_F(TransactionTraceWriterTest,overwriteOldFile)91 TEST_F(TransactionTraceWriterTest, overwriteOldFile) {
92     std::string testLine = "test";
93     {
94         std::ofstream file(mFilename, std::ios::out);
95         file << testLine;
96     }
97 
98     // Update file modification time to 15 minutes ago.
99     using Clock = std::filesystem::file_time_type::clock;
100     std::error_code error;
101     std::filesystem::last_write_time(mFilename, Clock::now() - std::chrono::minutes{15}, error);
102     ASSERT_EQ(error.value(), 0);
103 
104     TransactionTraceWriter::getInstance().invokeForTest(mFilename, /* overwrite */ false);
105     verifyTraceFile();
106 }
107 
108 // Check we cannot write to file if the trace write is disabled.
TEST_F(TransactionTraceWriterTest,canDisableTraceWriter)109 TEST_F(TransactionTraceWriterTest, canDisableTraceWriter) {
110     TransactionTraceWriter::getInstance().disable();
111     TransactionTraceWriter::getInstance().invokeForTest(mFilename, /* overwrite */ true);
112     EXPECT_NE(access(mFilename.c_str(), F_OK), 0);
113 
114     TransactionTraceWriter::getInstance().enable();
115     TransactionTraceWriter::getInstance().invokeForTest(mFilename, /* overwrite */ true);
116     EXPECT_EQ(access(mFilename.c_str(), F_OK), 0);
117     verifyTraceFile();
118 }
119 
120 } // namespace android