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 #include "serviceutils/PriorityDumper.h"
18 
19 #include <vector>
20 
21 #include <gmock/gmock.h>
22 #include <gtest/gtest.h>
23 
24 #include <utils/String16.h>
25 #include <utils/Vector.h>
26 
27 using namespace android;
28 
29 using ::testing::ElementsAreArray;
30 using ::testing::Mock;
31 using ::testing::Test;
32 
33 class PriorityDumperMock : public PriorityDumper {
34 public:
35     MOCK_METHOD3(dumpCritical, status_t(int, const Vector<String16>&, bool));
36     MOCK_METHOD3(dumpHigh, status_t(int, const Vector<String16>&, bool));
37     MOCK_METHOD3(dumpNormal, status_t(int, const Vector<String16>&, bool));
38     MOCK_METHOD3(dumpAll, status_t(int, const Vector<String16>&, bool));
39 };
40 
41 class DumpAllMock : public PriorityDumper {
42 public:
43     MOCK_METHOD3(dumpCritical, status_t(int, const Vector<String16>&, bool));
44     MOCK_METHOD3(dumpHigh, status_t(int, const Vector<String16>&, bool));
45     MOCK_METHOD3(dumpNormal, status_t(int, const Vector<String16>&, bool));
46 };
47 
48 class PriorityDumperTest : public Test {
49 public:
PriorityDumperTest()50     PriorityDumperTest() : dumper_(), dumpAlldumper_(), fd(1) {}
51     PriorityDumperMock dumper_;
52     DumpAllMock dumpAlldumper_;
53     int fd;
54 };
55 
addAll(Vector<String16> & av,const std::vector<std::string> & v)56 static void addAll(Vector<String16>& av, const std::vector<std::string>& v) {
57     for (const auto& element : v) {
58         av.add(String16(element.c_str()));
59     }
60 }
61 
TEST_F(PriorityDumperTest,noArgsPassed)62 TEST_F(PriorityDumperTest, noArgsPassed) {
63     Vector<String16> args;
64     EXPECT_CALL(dumper_, dumpAll(fd, ElementsAreArray(args), /*asProto=*/false));
65     dumper_.priorityDump(fd, args);
66 }
67 
TEST_F(PriorityDumperTest,noPriorityArgsPassed)68 TEST_F(PriorityDumperTest, noPriorityArgsPassed) {
69     Vector<String16> args;
70     addAll(args, {"bunch", "of", "args"});
71     EXPECT_CALL(dumper_, dumpAll(fd, ElementsAreArray(args), /*asProto=*/false));
72     dumper_.priorityDump(fd, args);
73 }
74 
TEST_F(PriorityDumperTest,priorityArgsOnly)75 TEST_F(PriorityDumperTest, priorityArgsOnly) {
76     Vector<String16> args;
77     addAll(args, {"--dump-priority", "CRITICAL"});
78     Vector<String16> strippedArgs;
79     EXPECT_CALL(dumper_, dumpCritical(fd, ElementsAreArray(strippedArgs), /*asProto=*/false));
80     dumper_.priorityDump(fd, args);
81 }
82 
TEST_F(PriorityDumperTest,dumpCritical)83 TEST_F(PriorityDumperTest, dumpCritical) {
84     Vector<String16> args;
85     addAll(args, {"--dump-priority", "CRITICAL", "args", "left", "behind"});
86     Vector<String16> strippedArgs;
87     addAll(strippedArgs, {"args", "left", "behind"});
88 
89     EXPECT_CALL(dumper_, dumpCritical(fd, ElementsAreArray(strippedArgs), /*asProto=*/false));
90     dumper_.priorityDump(fd, args);
91 }
92 
TEST_F(PriorityDumperTest,dumpCriticalInMiddle)93 TEST_F(PriorityDumperTest, dumpCriticalInMiddle) {
94     Vector<String16> args;
95     addAll(args, {"args", "left", "--dump-priority", "CRITICAL", "behind"});
96     Vector<String16> strippedArgs;
97     addAll(strippedArgs, {"args", "left", "behind"});
98 
99     EXPECT_CALL(dumper_, dumpCritical(fd, ElementsAreArray(strippedArgs), /*asProto=*/false));
100     dumper_.priorityDump(fd, args);
101 }
102 
TEST_F(PriorityDumperTest,dumpHigh)103 TEST_F(PriorityDumperTest, dumpHigh) {
104     Vector<String16> args;
105     addAll(args, {"--dump-priority", "HIGH", "args", "left", "behind"});
106     Vector<String16> strippedArgs;
107     addAll(strippedArgs, {"args", "left", "behind"});
108 
109     EXPECT_CALL(dumper_, dumpHigh(fd, ElementsAreArray(strippedArgs), /*asProto=*/false));
110     dumper_.priorityDump(fd, args);
111 }
112 
TEST_F(PriorityDumperTest,dumpHighInEnd)113 TEST_F(PriorityDumperTest, dumpHighInEnd) {
114     Vector<String16> args;
115     addAll(args, {"args", "left", "behind", "--dump-priority", "HIGH"});
116     Vector<String16> strippedArgs;
117     addAll(strippedArgs, {"args", "left", "behind"});
118 
119     EXPECT_CALL(dumper_, dumpHigh(fd, ElementsAreArray(strippedArgs), /*asProto=*/false));
120     dumper_.priorityDump(fd, args);
121 }
122 
TEST_F(PriorityDumperTest,dumpNormal)123 TEST_F(PriorityDumperTest, dumpNormal) {
124     Vector<String16> args;
125     addAll(args, {"--dump-priority", "NORMAL", "args", "left", "behind"});
126     Vector<String16> strippedArgs;
127     addAll(strippedArgs, {"args", "left", "behind"});
128 
129     EXPECT_CALL(dumper_, dumpNormal(fd, ElementsAreArray(strippedArgs), /*asProto=*/false));
130     dumper_.priorityDump(fd, args);
131 }
132 
TEST_F(PriorityDumperTest,dumpAll)133 TEST_F(PriorityDumperTest, dumpAll) {
134     Vector<String16> args;
135     addAll(args, {"args", "left", "behind"});
136 
137     EXPECT_CALL(dumpAlldumper_, dumpCritical(fd, ElementsAreArray(args), /*asProto=*/false));
138     EXPECT_CALL(dumpAlldumper_, dumpHigh(fd, ElementsAreArray(args), /*asProto=*/false));
139     EXPECT_CALL(dumpAlldumper_, dumpNormal(fd, ElementsAreArray(args), /*asProto=*/false));
140 
141     dumpAlldumper_.priorityDump(fd, args);
142 }
143 
TEST_F(PriorityDumperTest,priorityArgWithPriorityMissing)144 TEST_F(PriorityDumperTest, priorityArgWithPriorityMissing) {
145     Vector<String16> args;
146     addAll(args, {"--dump-priority"});
147     Vector<String16> strippedArgs;
148     EXPECT_CALL(dumper_, dumpAll(fd, ElementsAreArray(strippedArgs), /*asProto=*/false));
149 
150     dumper_.priorityDump(fd, args);
151 }
152 
TEST_F(PriorityDumperTest,priorityArgWithInvalidPriority)153 TEST_F(PriorityDumperTest, priorityArgWithInvalidPriority) {
154     Vector<String16> args;
155     addAll(args, {"--dump-priority", "REALLY_HIGH"});
156     Vector<String16> strippedArgs;
157     EXPECT_CALL(dumper_, dumpAll(fd, ElementsAreArray(strippedArgs), /*asProto=*/false));
158 
159     dumper_.priorityDump(fd, args);
160 }
161 
TEST_F(PriorityDumperTest,protoArg)162 TEST_F(PriorityDumperTest, protoArg) {
163     Vector<String16> args;
164     addAll(args, {"--proto"});
165     Vector<String16> strippedArgs;
166     EXPECT_CALL(dumper_, dumpAll(fd, ElementsAreArray(strippedArgs), /*asProto=*/true));
167 
168     dumper_.priorityDump(fd, args);
169 }
170 
TEST_F(PriorityDumperTest,protoArgWithPriorityArgs)171 TEST_F(PriorityDumperTest, protoArgWithPriorityArgs) {
172     Vector<String16> args;
173     addAll(args, {"--proto", "args", "--dump-priority", "NORMAL", "left", "behind"});
174     Vector<String16> strippedArgs;
175     addAll(strippedArgs, {"args", "left", "behind"});
176     EXPECT_CALL(dumper_, dumpNormal(fd, ElementsAreArray(strippedArgs), /*asProto=*/true));
177 
178     dumper_.priorityDump(fd, args);
179 }
180 
TEST_F(PriorityDumperTest,protoArgWithPriorityArgsInReverseOrder)181 TEST_F(PriorityDumperTest, protoArgWithPriorityArgsInReverseOrder) {
182     Vector<String16> args;
183     addAll(args, {"--dump-priority", "NORMAL", "--proto", "args", "left", "behind"});
184     Vector<String16> strippedArgs;
185     addAll(strippedArgs, {"args", "left", "behind"});
186     EXPECT_CALL(dumper_, dumpNormal(fd, ElementsAreArray(strippedArgs), /*asProto=*/true));
187 
188     dumper_.priorityDump(fd, args);
189 }
190 
TEST_F(PriorityDumperTest,protoArgInMiddle)191 TEST_F(PriorityDumperTest, protoArgInMiddle) {
192     Vector<String16> args;
193     addAll(args, {"--unknown", "args", "--proto", "args", "left", "behind"});
194     Vector<String16> strippedArgs;
195     addAll(strippedArgs, {"--unknown", "args", "args", "left", "behind"});
196     EXPECT_CALL(dumper_, dumpAll(fd, ElementsAreArray(strippedArgs), /*asProto=*/true));
197 
198     dumper_.priorityDump(fd, args);
199 }
200 
TEST_F(PriorityDumperTest,protoArgAtEnd)201 TEST_F(PriorityDumperTest, protoArgAtEnd) {
202     Vector<String16> args;
203     addAll(args, {"--unknown", "args", "args", "left", "behind", "--proto"});
204     Vector<String16> strippedArgs;
205     addAll(strippedArgs, {"--unknown", "args", "args", "left", "behind"});
206     EXPECT_CALL(dumper_, dumpAll(fd, ElementsAreArray(strippedArgs), /*asProto=*/true));
207 
208     dumper_.priorityDump(fd, args);
209 }
210 
TEST_F(PriorityDumperTest,protoArgWithInvalidPriorityType)211 TEST_F(PriorityDumperTest, protoArgWithInvalidPriorityType) {
212     Vector<String16> args;
213     addAll(args, {"--dump-priority", "NOT_SO_HIGH", "--proto", "args", "left", "behind"});
214     Vector<String16> strippedArgs;
215     addAll(strippedArgs, {"args", "left", "behind"});
216     EXPECT_CALL(dumper_, dumpAll(fd, ElementsAreArray(strippedArgs), /*asProto=*/true));
217 
218     dumper_.priorityDump(fd, args);
219 }