• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2017 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 #define DEBUG false
15 #include "Log.h"
16 
17 #include "Reporter.h"
18 
19 #include <android/os/BnIncidentReportStatusListener.h>
20 #include <frameworks/base/libs/incident/proto/android/os/header.pb.h>
21 
22 #include <android-base/file.h>
23 #include <android-base/test_utils.h>
24 #include <dirent.h>
25 #include <gmock/gmock.h>
26 #include <gtest/gtest.h>
27 #include <string.h>
28 
29 using namespace android;
30 using namespace android::base;
31 using namespace android::binder;
32 using namespace android::os;
33 using namespace android::os::incidentd;
34 using namespace std;
35 using ::testing::StrEq;
36 using ::testing::Test;
37 
38 class TestListener : public IIncidentReportStatusListener {
39 public:
40     int startInvoked;
41     int finishInvoked;
42     int failedInvoked;
43     map<int, int> startSections;
44     map<int, int> finishSections;
45 
TestListener()46     TestListener() : startInvoked(0), finishInvoked(0), failedInvoked(0){};
~TestListener()47     virtual ~TestListener(){};
48 
onReportStarted()49     virtual Status onReportStarted() {
50         startInvoked++;
51         return Status::ok();
52     };
onReportSectionStatus(int section,int status)53     virtual Status onReportSectionStatus(int section, int status) {
54         switch (status) {
55             case IIncidentReportStatusListener::STATUS_STARTING:
56                 if (startSections.count(section) == 0) startSections[section] = 0;
57                 startSections[section] = startSections[section] + 1;
58                 break;
59             case IIncidentReportStatusListener::STATUS_FINISHED:
60                 if (finishSections.count(section) == 0) finishSections[section] = 0;
61                 finishSections[section] = finishSections[section] + 1;
62                 break;
63         }
64         return Status::ok();
65     };
onReportFinished()66     virtual Status onReportFinished() {
67         finishInvoked++;
68         return Status::ok();
69     };
onReportFailed()70     virtual Status onReportFailed() {
71         failedInvoked++;
72         return Status::ok();
73     };
74 
75 protected:
onAsBinder()76     virtual IBinder* onAsBinder() override { return nullptr; };
77 };
78 
79 class ReporterTest : public Test {
80 public:
SetUp()81     virtual void SetUp() {
82         reporter = new Reporter(td.path);
83         l = new TestListener();
84     }
85 
InspectFiles()86     vector<string> InspectFiles() {
87         DIR* dir;
88         struct dirent* entry;
89         vector<string> results;
90 
91         string dirbase = string(td.path) + "/";
92         dir = opendir(td.path);
93 
94         while ((entry = readdir(dir)) != NULL) {
95             if (entry->d_name[0] == '.') {
96                 continue;
97             }
98             string filename = dirbase + entry->d_name;
99             string content;
100             ReadFileToString(filename, &content);
101             results.push_back(content);
102         }
103         return results;
104     }
105 
106 protected:
107     TemporaryDir td;
108     ReportRequestSet requests;
109     sp<Reporter> reporter;
110     sp<TestListener> l;
111     size_t size;
112 };
113 
TEST_F(ReporterTest,IncidentReportArgs)114 TEST_F(ReporterTest, IncidentReportArgs) {
115     IncidentReportArgs args1, args2;
116     args1.addSection(1);
117     args2.addSection(3);
118 
119     args1.merge(args2);
120     ASSERT_TRUE(args1.containsSection(1));
121     ASSERT_FALSE(args1.containsSection(2));
122     ASSERT_TRUE(args1.containsSection(3));
123 }
124 
TEST_F(ReporterTest,ReportRequestSetEmpty)125 TEST_F(ReporterTest, ReportRequestSetEmpty) {
126     requests.setMainFd(STDOUT_FILENO);
127     ASSERT_EQ(requests.mainFd(), STDOUT_FILENO);
128 }
129 
TEST_F(ReporterTest,RunReportEmpty)130 TEST_F(ReporterTest, RunReportEmpty) {
131     ASSERT_EQ(Reporter::REPORT_FINISHED, reporter->runReport(&size));
132     EXPECT_EQ(l->startInvoked, 0);
133     EXPECT_EQ(l->finishInvoked, 0);
134     EXPECT_TRUE(l->startSections.empty());
135     EXPECT_TRUE(l->finishSections.empty());
136     EXPECT_EQ(l->failedInvoked, 0);
137 }
138 
TEST_F(ReporterTest,RunReportWithHeaders)139 TEST_F(ReporterTest, RunReportWithHeaders) {
140     TemporaryFile tf;
141     IncidentReportArgs args1, args2;
142     args1.addSection(1);
143     args2.addSection(2);
144     IncidentHeaderProto header;
145     header.set_alert_id(12);
146     args2.addHeader(header);
147     sp<ReportRequest> r1 = new ReportRequest(args1, l, tf.fd);
148     sp<ReportRequest> r2 = new ReportRequest(args2, l, tf.fd);
149 
150     reporter->batch.add(r1);
151     reporter->batch.add(r2);
152 
153     ASSERT_EQ(Reporter::REPORT_FINISHED, reporter->runReport(&size));
154 
155     string result;
156     ReadFileToString(tf.path, &result);
157     EXPECT_THAT(result, StrEq("\n\x2"
158                               "\b\f"));
159 
160     EXPECT_EQ(l->startInvoked, 2);
161     EXPECT_EQ(l->finishInvoked, 2);
162     EXPECT_TRUE(l->startSections.empty());
163     EXPECT_TRUE(l->finishSections.empty());
164     EXPECT_EQ(l->failedInvoked, 0);
165 }
166 
TEST_F(ReporterTest,RunReportToGivenDirectory)167 TEST_F(ReporterTest, RunReportToGivenDirectory) {
168     IncidentReportArgs args;
169     IncidentHeaderProto header1, header2;
170     header1.set_alert_id(12);
171     header2.set_reason("abcd");
172     args.addHeader(header1);
173     args.addHeader(header2);
174     sp<ReportRequest> r = new ReportRequest(args, l, -1);
175     reporter->batch.add(r);
176 
177     ASSERT_EQ(Reporter::REPORT_FINISHED, reporter->runReport(&size));
178     vector<string> results = InspectFiles();
179     ASSERT_EQ((int)results.size(), 1);
180     EXPECT_EQ(results[0],
181               "\n\x2"
182               "\b\f\n\x6"
183               "\x12\x4"
184               "abcd");
185 }
186 
TEST_F(ReporterTest,ReportMetadata)187 TEST_F(ReporterTest, ReportMetadata) {
188     IncidentReportArgs args;
189     args.addSection(1);
190     args.setDest(android::os::DEST_EXPLICIT);
191     sp<ReportRequest> r = new ReportRequest(args, l, -1);
192     reporter->batch.add(r);
193 
194     ASSERT_EQ(Reporter::REPORT_FINISHED, reporter->runReport(&size));
195     IncidentMetadata metadata = reporter->batch.metadata();
196     EXPECT_EQ(IncidentMetadata_Destination_EXPLICIT, metadata.dest());
197     EXPECT_EQ(1, metadata.request_size());
198     EXPECT_TRUE(metadata.use_dropbox());
199     EXPECT_EQ(0, metadata.sections_size());
200 }