blob: 5a7fcd519cfd4a7c764dba623d8e8d4f829a0b2e [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;
Mårten Kongstad02751232018-04-27 13:16:32 +020049
Mårten Kongstad0eba72a2018-11-29 08:23:14 +010050namespace android::idmap2 {
Mårten Kongstad02751232018-04-27 13:16:32 +020051
52class Idmap2BinaryTests : public Idmap2Tests {};
53
Mårten Kongstad744ccfe2018-12-20 14:56:14 +010054namespace {
55
56void AssertIdmap(const Idmap& idmap, const std::string& target_apk_path,
57 const std::string& overlay_apk_path) {
Mårten Kongstad02751232018-04-27 13:16:32 +020058 // check that the idmap file looks reasonable (IdmapTests is responsible for
59 // more in-depth verification)
60 ASSERT_EQ(idmap.GetHeader()->GetMagic(), kIdmapMagic);
61 ASSERT_EQ(idmap.GetHeader()->GetVersion(), kIdmapCurrentVersion);
62 ASSERT_EQ(idmap.GetHeader()->GetTargetPath(), target_apk_path);
63 ASSERT_EQ(idmap.GetHeader()->GetOverlayPath(), overlay_apk_path);
Mårten Kongstadb8779022018-11-29 09:53:17 +010064 ASSERT_EQ(idmap.GetData().size(), 1U);
Mårten Kongstad02751232018-04-27 13:16:32 +020065}
66
67#define ASSERT_IDMAP(idmap_ref, target_apk_path, overlay_apk_path) \
68 do { \
69 ASSERT_NO_FATAL_FAILURE(AssertIdmap(idmap_ref, target_apk_path, overlay_apk_path)); \
70 } while (0)
71
Mårten Kongstad1da49dc2019-01-14 10:03:53 +010072#ifdef __ANDROID__
73#define SKIP_TEST_IF_CANT_EXEC_IDMAP2 \
74 do { \
75 const uid_t uid = getuid(); \
76 if (uid != AID_ROOT && uid != AID_SYSTEM) { \
77 GTEST_SKIP(); \
78 } \
79 } while (0)
80#else
81#define SKIP_TEST_IF_CANT_EXEC_IDMAP2
82#endif
83
Mårten Kongstad744ccfe2018-12-20 14:56:14 +010084} // namespace
85
Mårten Kongstad02751232018-04-27 13:16:32 +020086TEST_F(Idmap2BinaryTests, Create) {
Mårten Kongstad1da49dc2019-01-14 10:03:53 +010087 SKIP_TEST_IF_CANT_EXEC_IDMAP2;
88
Mårten Kongstad02751232018-04-27 13:16:32 +020089 // clang-format off
90 auto result = ExecuteBinary({"idmap2",
91 "create",
92 "--target-apk-path", GetTargetApkPath(),
93 "--overlay-apk-path", GetOverlayApkPath(),
Ryan Mitchell30dc2e02020-12-02 11:43:18 -080094 "--overlay-name", TestConstants::OVERLAY_NAME_DEFAULT,
Mårten Kongstad02751232018-04-27 13:16:32 +020095 "--idmap-path", GetIdmapPath()});
96 // clang-format on
Yurii Zubrytskyi1fc44eb2022-09-28 22:52:37 -070097 ASSERT_TRUE((bool)result);
98 ASSERT_EQ(result.status, EXIT_SUCCESS) << result.stderr_str;
Mårten Kongstad02751232018-04-27 13:16:32 +020099
100 struct stat st;
101 ASSERT_EQ(stat(GetIdmapPath().c_str(), &st), 0);
102
Mårten Kongstad02751232018-04-27 13:16:32 +0200103 std::ifstream fin(GetIdmapPath());
Mårten Kongstadce424902019-03-01 08:35:37 +0100104 const auto idmap = Idmap::FromBinaryStream(fin);
Mårten Kongstad02751232018-04-27 13:16:32 +0200105 fin.close();
106
Mårten Kongstadce424902019-03-01 08:35:37 +0100107 ASSERT_TRUE(idmap);
108 ASSERT_IDMAP(**idmap, GetTargetApkPath(), GetOverlayApkPath());
Mårten Kongstad02751232018-04-27 13:16:32 +0200109
110 unlink(GetIdmapPath().c_str());
111}
112
113TEST_F(Idmap2BinaryTests, Dump) {
Mårten Kongstad1da49dc2019-01-14 10:03:53 +0100114 SKIP_TEST_IF_CANT_EXEC_IDMAP2;
115
Mårten Kongstad02751232018-04-27 13:16:32 +0200116 // clang-format off
117 auto result = ExecuteBinary({"idmap2",
118 "create",
119 "--target-apk-path", GetTargetApkPath(),
120 "--overlay-apk-path", GetOverlayApkPath(),
Ryan Mitchell30dc2e02020-12-02 11:43:18 -0800121 "--overlay-name", TestConstants::OVERLAY_NAME_DEFAULT,
Mårten Kongstad02751232018-04-27 13:16:32 +0200122 "--idmap-path", GetIdmapPath()});
123 // clang-format on
Yurii Zubrytskyi1fc44eb2022-09-28 22:52:37 -0700124 ASSERT_TRUE((bool)result);
125 ASSERT_EQ(result.status, EXIT_SUCCESS) << result.stderr_str;
Mårten Kongstad02751232018-04-27 13:16:32 +0200126
127 // clang-format off
128 result = ExecuteBinary({"idmap2",
129 "dump",
130 "--idmap-path", GetIdmapPath()});
131 // clang-format on
Yurii Zubrytskyi1fc44eb2022-09-28 22:52:37 -0700132 ASSERT_TRUE((bool)result);
133 ASSERT_EQ(result.status, EXIT_SUCCESS) << result.stderr_str;
Ryan Mitchell30dc2e02020-12-02 11:43:18 -0800134
Yurii Zubrytskyi1fc44eb2022-09-28 22:52:37 -0700135 ASSERT_NE(result.stdout_str.find(StringPrintf("0x%08x -> 0x%08x", R::target::integer::int1,
Mårten Kongstad546e8e92022-02-14 09:29:18 +0000136 R::overlay::integer::int1)),
Ryan Mitchell30dc2e02020-12-02 11:43:18 -0800137 std::string::npos)
Yurii Zubrytskyi1fc44eb2022-09-28 22:52:37 -0700138 << result.stdout_str;
139 ASSERT_NE(result.stdout_str.find(StringPrintf("0x%08x -> 0x%08x", R::target::string::str1,
Mårten Kongstad546e8e92022-02-14 09:29:18 +0000140 R::overlay::string::str1)),
Ryan Mitchell30dc2e02020-12-02 11:43:18 -0800141 std::string::npos)
Yurii Zubrytskyi1fc44eb2022-09-28 22:52:37 -0700142 << result.stdout_str;
143 ASSERT_NE(result.stdout_str.find(StringPrintf("0x%08x -> 0x%08x", R::target::string::str3,
Mårten Kongstad546e8e92022-02-14 09:29:18 +0000144 R::overlay::string::str3)),
Ryan Mitchell30dc2e02020-12-02 11:43:18 -0800145 std::string::npos)
Yurii Zubrytskyi1fc44eb2022-09-28 22:52:37 -0700146 << result.stdout_str;
147 ASSERT_NE(result.stdout_str.find(StringPrintf("0x%08x -> 0x%08x", R::target::string::str4,
Mårten Kongstad546e8e92022-02-14 09:29:18 +0000148 R::overlay::string::str4)),
Ryan Mitchell30dc2e02020-12-02 11:43:18 -0800149 std::string::npos)
Yurii Zubrytskyi1fc44eb2022-09-28 22:52:37 -0700150 << result.stdout_str;
Mårten Kongstad02751232018-04-27 13:16:32 +0200151
152 // clang-format off
153 result = ExecuteBinary({"idmap2",
154 "dump",
155 "--verbose",
156 "--idmap-path", GetIdmapPath()});
157 // clang-format on
Yurii Zubrytskyi1fc44eb2022-09-28 22:52:37 -0700158 ASSERT_TRUE((bool)result);
159 ASSERT_EQ(result.status, EXIT_SUCCESS) << result.stderr_str;
160 ASSERT_NE(result.stdout_str.find("00000000: 504d4449 magic"), std::string::npos);
Mårten Kongstad02751232018-04-27 13:16:32 +0200161
162 // clang-format off
163 result = ExecuteBinary({"idmap2",
164 "dump",
165 "--verbose",
166 "--idmap-path", GetTestDataPath() + "/DOES-NOT-EXIST"});
167 // clang-format on
Yurii Zubrytskyi1fc44eb2022-09-28 22:52:37 -0700168 ASSERT_TRUE((bool)result);
169 ASSERT_NE(result.status, EXIT_SUCCESS);
Mårten Kongstad02751232018-04-27 13:16:32 +0200170
171 unlink(GetIdmapPath().c_str());
172}
173
Mårten Kongstad02751232018-04-27 13:16:32 +0200174TEST_F(Idmap2BinaryTests, Lookup) {
Ryan Mitchell8a891d82019-07-01 09:48:23 -0700175 SKIP_TEST_IF_CANT_EXEC_IDMAP2;
176
177 // clang-format off
178 auto result = ExecuteBinary({"idmap2",
179 "create",
180 "--target-apk-path", GetTargetApkPath(),
181 "--overlay-apk-path", GetOverlayApkPath(),
Ryan Mitchell30dc2e02020-12-02 11:43:18 -0800182 "--overlay-name", TestConstants::OVERLAY_NAME_DEFAULT,
Ryan Mitchell8a891d82019-07-01 09:48:23 -0700183 "--idmap-path", GetIdmapPath()});
184 // clang-format on
Yurii Zubrytskyi1fc44eb2022-09-28 22:52:37 -0700185 ASSERT_TRUE((bool)result);
186 ASSERT_EQ(result.status, EXIT_SUCCESS) << result.stderr_str;
Ryan Mitchell8a891d82019-07-01 09:48:23 -0700187
188 // clang-format off
189 result = ExecuteBinary({"idmap2",
190 "lookup",
191 "--idmap-path", GetIdmapPath(),
192 "--config", "",
Ryan Mitchell30dc2e02020-12-02 11:43:18 -0800193 "--resid", StringPrintf("0x%08x", R::target::string::str1)});
Ryan Mitchell8a891d82019-07-01 09:48:23 -0700194 // clang-format on
Yurii Zubrytskyi1fc44eb2022-09-28 22:52:37 -0700195 ASSERT_TRUE((bool)result);
196 ASSERT_EQ(result.status, EXIT_SUCCESS) << result.stderr_str;
197 ASSERT_NE(result.stdout_str.find("overlay-1"), std::string::npos);
198 ASSERT_EQ(result.stdout_str.find("overlay-1-sv"), std::string::npos);
Ryan Mitchell8a891d82019-07-01 09:48:23 -0700199
200 // clang-format off
201 result = ExecuteBinary({"idmap2",
202 "lookup",
203 "--idmap-path", GetIdmapPath(),
204 "--config", "",
205 "--resid", "test.target:string/str1"});
206 // clang-format on
Yurii Zubrytskyi1fc44eb2022-09-28 22:52:37 -0700207 ASSERT_TRUE((bool)result);
208 ASSERT_EQ(result.status, EXIT_SUCCESS) << result.stderr_str;
209 ASSERT_NE(result.stdout_str.find("overlay-1"), std::string::npos);
210 ASSERT_EQ(result.stdout_str.find("overlay-1-sv"), std::string::npos);
Ryan Mitchell8a891d82019-07-01 09:48:23 -0700211
212 // clang-format off
213 result = ExecuteBinary({"idmap2",
214 "lookup",
215 "--idmap-path", GetIdmapPath(),
216 "--config", "sv",
217 "--resid", "test.target:string/str1"});
218 // clang-format on
Yurii Zubrytskyi1fc44eb2022-09-28 22:52:37 -0700219 ASSERT_TRUE((bool)result);
220 ASSERT_EQ(result.status, EXIT_SUCCESS) << result.stderr_str;
221 ASSERT_NE(result.stdout_str.find("overlay-1-sv"), std::string::npos);
Ryan Mitchell8a891d82019-07-01 09:48:23 -0700222
223 unlink(GetIdmapPath().c_str());
Mårten Kongstad02751232018-04-27 13:16:32 +0200224}
225
226TEST_F(Idmap2BinaryTests, InvalidCommandLineOptions) {
Mårten Kongstad1da49dc2019-01-14 10:03:53 +0100227 SKIP_TEST_IF_CANT_EXEC_IDMAP2;
228
Mårten Kongstad02751232018-04-27 13:16:32 +0200229 const std::string invalid_target_apk_path = GetTestDataPath() + "/DOES-NOT-EXIST";
230
231 // missing mandatory options
232 // clang-format off
233 auto result = ExecuteBinary({"idmap2",
234 "create"});
235 // clang-format on
Yurii Zubrytskyi1fc44eb2022-09-28 22:52:37 -0700236 ASSERT_TRUE((bool)result);
237 ASSERT_NE(result.status, EXIT_SUCCESS);
Mårten Kongstad02751232018-04-27 13:16:32 +0200238
239 // missing argument to option
240 // clang-format off
241 result = ExecuteBinary({"idmap2",
242 "create",
243 "--target-apk-path", GetTargetApkPath(),
244 "--overlay-apk-path", GetOverlayApkPath(),
Ryan Mitchell30dc2e02020-12-02 11:43:18 -0800245 "--overlay-name", TestConstants::OVERLAY_NAME_DEFAULT,
Mårten Kongstad02751232018-04-27 13:16:32 +0200246 "--idmap-path"});
247 // clang-format on
Yurii Zubrytskyi1fc44eb2022-09-28 22:52:37 -0700248 ASSERT_TRUE((bool)result);
249 ASSERT_NE(result.status, EXIT_SUCCESS);
Mårten Kongstad02751232018-04-27 13:16:32 +0200250
251 // invalid target apk path
252 // clang-format off
253 result = ExecuteBinary({"idmap2",
254 "create",
255 "--target-apk-path", invalid_target_apk_path,
256 "--overlay-apk-path", GetOverlayApkPath(),
Ryan Mitchell30dc2e02020-12-02 11:43:18 -0800257 "--overlay-name", TestConstants::OVERLAY_NAME_DEFAULT,
Mårten Kongstad02751232018-04-27 13:16:32 +0200258 "--idmap-path", GetIdmapPath()});
259 // clang-format on
Yurii Zubrytskyi1fc44eb2022-09-28 22:52:37 -0700260 ASSERT_TRUE((bool)result);
261 ASSERT_NE(result.status, EXIT_SUCCESS);
Mårten Kongstadd10d06d2019-01-07 17:26:25 -0800262
263 // unknown policy
264 // clang-format off
265 result = ExecuteBinary({"idmap2",
266 "create",
267 "--target-apk-path", GetTargetApkPath(),
268 "--overlay-apk-path", GetOverlayApkPath(),
Ryan Mitchell30dc2e02020-12-02 11:43:18 -0800269 "--overlay-name", TestConstants::OVERLAY_NAME_DEFAULT,
Mårten Kongstadd10d06d2019-01-07 17:26:25 -0800270 "--idmap-path", GetIdmapPath(),
271 "--policy", "this-does-not-exist"});
272 // clang-format on
Yurii Zubrytskyi1fc44eb2022-09-28 22:52:37 -0700273 ASSERT_TRUE((bool)result);
274 ASSERT_NE(result.status, EXIT_SUCCESS);
Mårten Kongstad02751232018-04-27 13:16:32 +0200275}
276
Mårten Kongstad0eba72a2018-11-29 08:23:14 +0100277} // namespace android::idmap2