blob: 1c82597461894ab418ca5d1aee8c6d3022bd7d82 [file] [log] [blame]
Mårten Kongstad02751232018-04-27 13:16:32 +02001/*
2 * Copyright (C) 2018 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/*
18 * The tests in this file operate on a higher level than the tests in the other
19 * files. Here, all tests execute the idmap2 binary and only depend on
20 * libidmap2 to verify the output of idmap2.
21 */
22#include <fcntl.h>
23#include <sys/stat.h>
24#include <sys/types.h>
25#include <sys/wait.h>
26#include <unistd.h>
27
28#include <cerrno>
29#include <cstdlib>
30#include <cstring> // strerror
31#include <fstream>
32#include <memory>
33#include <sstream>
34#include <string>
35#include <vector>
36
Winson62ac8b52019-12-04 08:36:48 -080037#include "R.h"
Ryan Mitchell30dc2e02020-12-02 11:43:18 -080038#include "TestConstants.h"
Ryan Mitchell52e1f7a2019-04-12 12:31:42 -070039#include "TestHelpers.h"
40#include "androidfw/PosixUtils.h"
Mårten Kongstad02751232018-04-27 13:16:32 +020041#include "gmock/gmock.h"
42#include "gtest/gtest.h"
Mårten Kongstad02751232018-04-27 13:16:32 +020043#include "idmap2/FileUtils.h"
44#include "idmap2/Idmap.h"
Ryan Mitchell52e1f7a2019-04-12 12:31:42 -070045#include "private/android_filesystem_config.h"
Mårten Kongstad02751232018-04-27 13:16:32 +020046
Ryan Mitchell30dc2e02020-12-02 11:43:18 -080047using ::android::base::StringPrintf;
Mårten Kongstad02751232018-04-27 13:16:32 +020048using ::android::util::ExecuteBinary;
49using ::testing::NotNull;
50
Mårten Kongstad0eba72a2018-11-29 08:23:14 +010051namespace android::idmap2 {
Mårten Kongstad02751232018-04-27 13:16:32 +020052
53class Idmap2BinaryTests : public Idmap2Tests {};
54
Mårten Kongstad744ccfe2018-12-20 14:56:14 +010055namespace {
56
57void AssertIdmap(const Idmap& idmap, const std::string& target_apk_path,
58 const std::string& overlay_apk_path) {
Mårten Kongstad02751232018-04-27 13:16:32 +020059 // check that the idmap file looks reasonable (IdmapTests is responsible for
60 // more in-depth verification)
61 ASSERT_EQ(idmap.GetHeader()->GetMagic(), kIdmapMagic);
62 ASSERT_EQ(idmap.GetHeader()->GetVersion(), kIdmapCurrentVersion);
63 ASSERT_EQ(idmap.GetHeader()->GetTargetPath(), target_apk_path);
64 ASSERT_EQ(idmap.GetHeader()->GetOverlayPath(), overlay_apk_path);
Mårten Kongstadb8779022018-11-29 09:53:17 +010065 ASSERT_EQ(idmap.GetData().size(), 1U);
Mårten Kongstad02751232018-04-27 13:16:32 +020066}
67
68#define ASSERT_IDMAP(idmap_ref, target_apk_path, overlay_apk_path) \
69 do { \
70 ASSERT_NO_FATAL_FAILURE(AssertIdmap(idmap_ref, target_apk_path, overlay_apk_path)); \
71 } while (0)
72
Mårten Kongstad1da49dc2019-01-14 10:03:53 +010073#ifdef __ANDROID__
74#define SKIP_TEST_IF_CANT_EXEC_IDMAP2 \
75 do { \
76 const uid_t uid = getuid(); \
77 if (uid != AID_ROOT && uid != AID_SYSTEM) { \
78 GTEST_SKIP(); \
79 } \
80 } while (0)
81#else
82#define SKIP_TEST_IF_CANT_EXEC_IDMAP2
83#endif
84
Mårten Kongstad744ccfe2018-12-20 14:56:14 +010085} // namespace
86
Mårten Kongstad02751232018-04-27 13:16:32 +020087TEST_F(Idmap2BinaryTests, Create) {
Mårten Kongstad1da49dc2019-01-14 10:03:53 +010088 SKIP_TEST_IF_CANT_EXEC_IDMAP2;
89
Mårten Kongstad02751232018-04-27 13:16:32 +020090 // clang-format off
91 auto result = ExecuteBinary({"idmap2",
92 "create",
93 "--target-apk-path", GetTargetApkPath(),
94 "--overlay-apk-path", GetOverlayApkPath(),
Ryan Mitchell30dc2e02020-12-02 11:43:18 -080095 "--overlay-name", TestConstants::OVERLAY_NAME_DEFAULT,
Mårten Kongstad02751232018-04-27 13:16:32 +020096 "--idmap-path", GetIdmapPath()});
97 // clang-format on
98 ASSERT_THAT(result, NotNull());
Colin Crossfaa5e272021-08-16 13:00:28 -070099 ASSERT_EQ(result->status, EXIT_SUCCESS) << result->stderr_str;
Mårten Kongstad02751232018-04-27 13:16:32 +0200100
101 struct stat st;
102 ASSERT_EQ(stat(GetIdmapPath().c_str(), &st), 0);
103
Mårten Kongstad02751232018-04-27 13:16:32 +0200104 std::ifstream fin(GetIdmapPath());
Mårten Kongstadce424902019-03-01 08:35:37 +0100105 const auto idmap = Idmap::FromBinaryStream(fin);
Mårten Kongstad02751232018-04-27 13:16:32 +0200106 fin.close();
107
Mårten Kongstadce424902019-03-01 08:35:37 +0100108 ASSERT_TRUE(idmap);
109 ASSERT_IDMAP(**idmap, GetTargetApkPath(), GetOverlayApkPath());
Mårten Kongstad02751232018-04-27 13:16:32 +0200110
111 unlink(GetIdmapPath().c_str());
112}
113
114TEST_F(Idmap2BinaryTests, Dump) {
Mårten Kongstad1da49dc2019-01-14 10:03:53 +0100115 SKIP_TEST_IF_CANT_EXEC_IDMAP2;
116
Mårten Kongstad02751232018-04-27 13:16:32 +0200117 // clang-format off
118 auto result = ExecuteBinary({"idmap2",
119 "create",
120 "--target-apk-path", GetTargetApkPath(),
121 "--overlay-apk-path", GetOverlayApkPath(),
Ryan Mitchell30dc2e02020-12-02 11:43:18 -0800122 "--overlay-name", TestConstants::OVERLAY_NAME_DEFAULT,
Mårten Kongstad02751232018-04-27 13:16:32 +0200123 "--idmap-path", GetIdmapPath()});
124 // clang-format on
125 ASSERT_THAT(result, NotNull());
Colin Crossfaa5e272021-08-16 13:00:28 -0700126 ASSERT_EQ(result->status, EXIT_SUCCESS) << result->stderr_str;
Mårten Kongstad02751232018-04-27 13:16:32 +0200127
128 // clang-format off
129 result = ExecuteBinary({"idmap2",
130 "dump",
131 "--idmap-path", GetIdmapPath()});
132 // clang-format on
133 ASSERT_THAT(result, NotNull());
Colin Crossfaa5e272021-08-16 13:00:28 -0700134 ASSERT_EQ(result->status, EXIT_SUCCESS) << result->stderr_str;
Ryan Mitchell30dc2e02020-12-02 11:43:18 -0800135
Colin Crossfaa5e272021-08-16 13:00:28 -0700136 ASSERT_NE(result->stdout_str.find(StringPrintf("0x%08x -> 0x%08x", R::target::integer::int1,
Ryan Mitchell30dc2e02020-12-02 11:43:18 -0800137 R::overlay::integer::int1)),
138 std::string::npos)
Colin Crossfaa5e272021-08-16 13:00:28 -0700139 << result->stdout_str;
140 ASSERT_NE(result->stdout_str.find(StringPrintf("0x%08x -> 0x%08x", R::target::string::str1,
Ryan Mitchell30dc2e02020-12-02 11:43:18 -0800141 R::overlay::string::str1)),
142 std::string::npos)
Colin Crossfaa5e272021-08-16 13:00:28 -0700143 << result->stdout_str;
144 ASSERT_NE(result->stdout_str.find(StringPrintf("0x%08x -> 0x%08x", R::target::string::str3,
Ryan Mitchell30dc2e02020-12-02 11:43:18 -0800145 R::overlay::string::str3)),
146 std::string::npos)
Colin Crossfaa5e272021-08-16 13:00:28 -0700147 << result->stdout_str;
148 ASSERT_NE(result->stdout_str.find(StringPrintf("0x%08x -> 0x%08x", R::target::string::str4,
Ryan Mitchell30dc2e02020-12-02 11:43:18 -0800149 R::overlay::string::str4)),
150 std::string::npos)
Colin Crossfaa5e272021-08-16 13:00:28 -0700151 << result->stdout_str;
Mårten Kongstad02751232018-04-27 13:16:32 +0200152
153 // clang-format off
154 result = ExecuteBinary({"idmap2",
155 "dump",
156 "--verbose",
157 "--idmap-path", GetIdmapPath()});
158 // clang-format on
159 ASSERT_THAT(result, NotNull());
Colin Crossfaa5e272021-08-16 13:00:28 -0700160 ASSERT_EQ(result->status, EXIT_SUCCESS) << result->stderr_str;
161 ASSERT_NE(result->stdout_str.find("00000000: 504d4449 magic"), std::string::npos);
Mårten Kongstad02751232018-04-27 13:16:32 +0200162
163 // clang-format off
164 result = ExecuteBinary({"idmap2",
165 "dump",
166 "--verbose",
167 "--idmap-path", GetTestDataPath() + "/DOES-NOT-EXIST"});
168 // clang-format on
169 ASSERT_THAT(result, NotNull());
170 ASSERT_NE(result->status, EXIT_SUCCESS);
171
172 unlink(GetIdmapPath().c_str());
173}
174
Mårten Kongstad02751232018-04-27 13:16:32 +0200175TEST_F(Idmap2BinaryTests, Lookup) {
Ryan Mitchell8a891d82019-07-01 09:48:23 -0700176 SKIP_TEST_IF_CANT_EXEC_IDMAP2;
177
178 // clang-format off
179 auto result = ExecuteBinary({"idmap2",
180 "create",
181 "--target-apk-path", GetTargetApkPath(),
182 "--overlay-apk-path", GetOverlayApkPath(),
Ryan Mitchell30dc2e02020-12-02 11:43:18 -0800183 "--overlay-name", TestConstants::OVERLAY_NAME_DEFAULT,
Ryan Mitchell8a891d82019-07-01 09:48:23 -0700184 "--idmap-path", GetIdmapPath()});
185 // clang-format on
186 ASSERT_THAT(result, NotNull());
Colin Crossfaa5e272021-08-16 13:00:28 -0700187 ASSERT_EQ(result->status, EXIT_SUCCESS) << result->stderr_str;
Ryan Mitchell8a891d82019-07-01 09:48:23 -0700188
189 // clang-format off
190 result = ExecuteBinary({"idmap2",
191 "lookup",
192 "--idmap-path", GetIdmapPath(),
193 "--config", "",
Ryan Mitchell30dc2e02020-12-02 11:43:18 -0800194 "--resid", StringPrintf("0x%08x", R::target::string::str1)});
Ryan Mitchell8a891d82019-07-01 09:48:23 -0700195 // clang-format on
196 ASSERT_THAT(result, NotNull());
Colin Crossfaa5e272021-08-16 13:00:28 -0700197 ASSERT_EQ(result->status, EXIT_SUCCESS) << result->stderr_str;
198 ASSERT_NE(result->stdout_str.find("overlay-1"), std::string::npos);
199 ASSERT_EQ(result->stdout_str.find("overlay-1-sv"), std::string::npos);
Ryan Mitchell8a891d82019-07-01 09:48:23 -0700200
201 // clang-format off
202 result = ExecuteBinary({"idmap2",
203 "lookup",
204 "--idmap-path", GetIdmapPath(),
205 "--config", "",
206 "--resid", "test.target:string/str1"});
207 // clang-format on
208 ASSERT_THAT(result, NotNull());
Colin Crossfaa5e272021-08-16 13:00:28 -0700209 ASSERT_EQ(result->status, EXIT_SUCCESS) << result->stderr_str;
210 ASSERT_NE(result->stdout_str.find("overlay-1"), std::string::npos);
211 ASSERT_EQ(result->stdout_str.find("overlay-1-sv"), std::string::npos);
Ryan Mitchell8a891d82019-07-01 09:48:23 -0700212
213 // clang-format off
214 result = ExecuteBinary({"idmap2",
215 "lookup",
216 "--idmap-path", GetIdmapPath(),
217 "--config", "sv",
218 "--resid", "test.target:string/str1"});
219 // clang-format on
220 ASSERT_THAT(result, NotNull());
Colin Crossfaa5e272021-08-16 13:00:28 -0700221 ASSERT_EQ(result->status, EXIT_SUCCESS) << result->stderr_str;
222 ASSERT_NE(result->stdout_str.find("overlay-1-sv"), std::string::npos);
Ryan Mitchell8a891d82019-07-01 09:48:23 -0700223
224 unlink(GetIdmapPath().c_str());
Mårten Kongstad02751232018-04-27 13:16:32 +0200225}
226
227TEST_F(Idmap2BinaryTests, InvalidCommandLineOptions) {
Mårten Kongstad1da49dc2019-01-14 10:03:53 +0100228 SKIP_TEST_IF_CANT_EXEC_IDMAP2;
229
Mårten Kongstad02751232018-04-27 13:16:32 +0200230 const std::string invalid_target_apk_path = GetTestDataPath() + "/DOES-NOT-EXIST";
231
232 // missing mandatory options
233 // clang-format off
234 auto result = ExecuteBinary({"idmap2",
235 "create"});
236 // clang-format on
237 ASSERT_THAT(result, NotNull());
238 ASSERT_NE(result->status, EXIT_SUCCESS);
239
240 // missing argument to option
241 // clang-format off
242 result = ExecuteBinary({"idmap2",
243 "create",
244 "--target-apk-path", GetTargetApkPath(),
245 "--overlay-apk-path", GetOverlayApkPath(),
Ryan Mitchell30dc2e02020-12-02 11:43:18 -0800246 "--overlay-name", TestConstants::OVERLAY_NAME_DEFAULT,
Mårten Kongstad02751232018-04-27 13:16:32 +0200247 "--idmap-path"});
248 // clang-format on
249 ASSERT_THAT(result, NotNull());
250 ASSERT_NE(result->status, EXIT_SUCCESS);
251
252 // invalid target apk path
253 // clang-format off
254 result = ExecuteBinary({"idmap2",
255 "create",
256 "--target-apk-path", invalid_target_apk_path,
257 "--overlay-apk-path", GetOverlayApkPath(),
Ryan Mitchell30dc2e02020-12-02 11:43:18 -0800258 "--overlay-name", TestConstants::OVERLAY_NAME_DEFAULT,
Mårten Kongstad02751232018-04-27 13:16:32 +0200259 "--idmap-path", GetIdmapPath()});
260 // clang-format on
261 ASSERT_THAT(result, NotNull());
262 ASSERT_NE(result->status, EXIT_SUCCESS);
Mårten Kongstadd10d06d2019-01-07 17:26:25 -0800263
264 // unknown policy
265 // clang-format off
266 result = ExecuteBinary({"idmap2",
267 "create",
268 "--target-apk-path", GetTargetApkPath(),
269 "--overlay-apk-path", GetOverlayApkPath(),
Ryan Mitchell30dc2e02020-12-02 11:43:18 -0800270 "--overlay-name", TestConstants::OVERLAY_NAME_DEFAULT,
Mårten Kongstadd10d06d2019-01-07 17:26:25 -0800271 "--idmap-path", GetIdmapPath(),
272 "--policy", "this-does-not-exist"});
273 // clang-format on
274 ASSERT_THAT(result, NotNull());
275 ASSERT_NE(result->status, EXIT_SUCCESS);
Mårten Kongstad02751232018-04-27 13:16:32 +0200276}
277
Mårten Kongstad0eba72a2018-11-29 08:23:14 +0100278} // namespace android::idmap2