blob: 5cff0048c062bc4f52fae1eb57663d646ecd5815 [file] [log] [blame]
Adam Lesinski1ab598f2015-08-14 14:26:04 -07001/*
2 * Copyright (C) 2015 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 "compile/IdAssigner.h"
Adam Lesinskice5e56e2016-10-21 17:56:45 -070018
Adam Lesinskibf0bd0f2016-06-01 15:31:50 -070019#include "test/Test.h"
Adam Lesinski1ab598f2015-08-14 14:26:04 -070020
21namespace aapt {
22
Adam Lesinskice5e56e2016-10-21 17:56:45 -070023::testing::AssertionResult VerifyIds(ResourceTable* table);
Adam Lesinski1ab598f2015-08-14 14:26:04 -070024
25TEST(IdAssignerTest, AssignIds) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -070026 std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder()
Adam Lesinskice5e56e2016-10-21 17:56:45 -070027 .AddSimple("android:attr/foo")
28 .AddSimple("android:attr/bar")
29 .AddSimple("android:id/foo")
30 .SetPackageId("android", 0x01)
31 .Build();
Adam Lesinski1ab598f2015-08-14 14:26:04 -070032
Adam Lesinskice5e56e2016-10-21 17:56:45 -070033 std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
Adam Lesinskicacb28f2016-10-19 12:18:14 -070034 IdAssigner assigner;
Adam Lesinski1ab598f2015-08-14 14:26:04 -070035
Adam Lesinskice5e56e2016-10-21 17:56:45 -070036 ASSERT_TRUE(assigner.Consume(context.get(), table.get()));
37 ASSERT_TRUE(VerifyIds(table.get()));
Adam Lesinski1ab598f2015-08-14 14:26:04 -070038}
39
40TEST(IdAssignerTest, AssignIdsWithReservedIds) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -070041 std::unique_ptr<ResourceTable> table =
42 test::ResourceTableBuilder()
Adam Lesinskice5e56e2016-10-21 17:56:45 -070043 .AddSimple("android:id/foo", ResourceId(0x01010000))
44 .AddSimple("android:dimen/two")
45 .AddSimple("android:integer/three")
46 .AddSimple("android:string/five")
47 .AddSimple("android:attr/fun", ResourceId(0x01040000))
48 .AddSimple("android:attr/foo", ResourceId(0x01040006))
49 .AddSimple("android:attr/bar")
50 .AddSimple("android:attr/baz")
51 .AddSimple("app:id/biz")
52 .SetPackageId("android", 0x01)
53 .SetPackageId("app", 0x7f)
54 .Build();
Adam Lesinski1ab598f2015-08-14 14:26:04 -070055
Adam Lesinskice5e56e2016-10-21 17:56:45 -070056 std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
Adam Lesinskicacb28f2016-10-19 12:18:14 -070057 IdAssigner assigner;
Adam Lesinski1ab598f2015-08-14 14:26:04 -070058
Adam Lesinskice5e56e2016-10-21 17:56:45 -070059 ASSERT_TRUE(assigner.Consume(context.get(), table.get()));
60 ASSERT_TRUE(VerifyIds(table.get()));
Adam Lesinskibf0bd0f2016-06-01 15:31:50 -070061
Adam Lesinskice5e56e2016-10-21 17:56:45 -070062 Maybe<ResourceTable::SearchResult> maybe_result;
Adam Lesinskibf0bd0f2016-06-01 15:31:50 -070063
Adam Lesinskicacb28f2016-10-19 12:18:14 -070064 // Expect to fill in the gaps between 0x0101XXXX and 0x0104XXXX.
Adam Lesinskibf0bd0f2016-06-01 15:31:50 -070065
Adam Lesinskice5e56e2016-10-21 17:56:45 -070066 maybe_result = table->FindResource(test::ParseNameOrDie("android:dimen/two"));
Adam Lesinskia45893a2017-05-30 15:19:02 -070067 ASSERT_TRUE(maybe_result);
Adam Lesinskice5e56e2016-10-21 17:56:45 -070068 EXPECT_EQ(make_value<uint8_t>(2), maybe_result.value().type->id);
Adam Lesinskibf0bd0f2016-06-01 15:31:50 -070069
Adam Lesinskice5e56e2016-10-21 17:56:45 -070070 maybe_result =
71 table->FindResource(test::ParseNameOrDie("android:integer/three"));
Adam Lesinskia45893a2017-05-30 15:19:02 -070072 ASSERT_TRUE(maybe_result);
Adam Lesinskice5e56e2016-10-21 17:56:45 -070073 EXPECT_EQ(make_value<uint8_t>(3), maybe_result.value().type->id);
Adam Lesinskibf0bd0f2016-06-01 15:31:50 -070074
Adam Lesinskicacb28f2016-10-19 12:18:14 -070075 // Expect to bypass the reserved 0x0104XXXX IDs and use the next 0x0105XXXX
76 // IDs.
Adam Lesinskibf0bd0f2016-06-01 15:31:50 -070077
Adam Lesinskice5e56e2016-10-21 17:56:45 -070078 maybe_result =
79 table->FindResource(test::ParseNameOrDie("android:string/five"));
Adam Lesinskia45893a2017-05-30 15:19:02 -070080 ASSERT_TRUE(maybe_result);
Adam Lesinskice5e56e2016-10-21 17:56:45 -070081 EXPECT_EQ(make_value<uint8_t>(5), maybe_result.value().type->id);
Adam Lesinskibf0bd0f2016-06-01 15:31:50 -070082
Adam Lesinskicacb28f2016-10-19 12:18:14 -070083 // Expect to fill in the gaps between 0x01040000 and 0x01040006.
Adam Lesinskibf0bd0f2016-06-01 15:31:50 -070084
Adam Lesinskice5e56e2016-10-21 17:56:45 -070085 maybe_result = table->FindResource(test::ParseNameOrDie("android:attr/bar"));
Adam Lesinskia45893a2017-05-30 15:19:02 -070086 ASSERT_TRUE(maybe_result);
Adam Lesinskice5e56e2016-10-21 17:56:45 -070087 EXPECT_EQ(make_value<uint16_t>(1), maybe_result.value().entry->id);
Adam Lesinskibf0bd0f2016-06-01 15:31:50 -070088
Adam Lesinskice5e56e2016-10-21 17:56:45 -070089 maybe_result = table->FindResource(test::ParseNameOrDie("android:attr/baz"));
Adam Lesinskia45893a2017-05-30 15:19:02 -070090 ASSERT_TRUE(maybe_result);
Adam Lesinskice5e56e2016-10-21 17:56:45 -070091 EXPECT_EQ(make_value<uint16_t>(2), maybe_result.value().entry->id);
Adam Lesinski1ab598f2015-08-14 14:26:04 -070092}
93
94TEST(IdAssignerTest, FailWhenNonUniqueIdsAssigned) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -070095 std::unique_ptr<ResourceTable> table =
96 test::ResourceTableBuilder()
Adam Lesinskice5e56e2016-10-21 17:56:45 -070097 .AddSimple("android:attr/foo", ResourceId(0x01040006))
98 .AddSimple("android:attr/bar", ResourceId(0x01040006))
99 .SetPackageId("android", 0x01)
100 .SetPackageId("app", 0x7f)
101 .Build();
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700102
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700103 std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700104 IdAssigner assigner;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700105
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700106 ASSERT_FALSE(assigner.Consume(context.get(), table.get()));
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700107}
108
Adam Lesinskibf0bd0f2016-06-01 15:31:50 -0700109TEST(IdAssignerTest, AssignIdsWithIdMap) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700110 std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder()
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700111 .AddSimple("android:attr/foo")
112 .AddSimple("android:attr/bar")
113 .SetPackageId("android", 0x01)
114 .Build();
Adam Lesinskibf0bd0f2016-06-01 15:31:50 -0700115
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700116 std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
117 std::unordered_map<ResourceName, ResourceId> id_map = {
118 {test::ParseNameOrDie("android:attr/foo"), ResourceId(0x01010002)}};
119 IdAssigner assigner(&id_map);
120 ASSERT_TRUE(assigner.Consume(context.get(), table.get()));
121 ASSERT_TRUE(VerifyIds(table.get()));
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700122 Maybe<ResourceTable::SearchResult> result =
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700123 table->FindResource(test::ParseNameOrDie("android:attr/foo"));
Adam Lesinskia45893a2017-05-30 15:19:02 -0700124 ASSERT_TRUE(result);
Adam Lesinskibf0bd0f2016-06-01 15:31:50 -0700125
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700126 const ResourceTable::SearchResult& search_result = result.value();
127 EXPECT_EQ(make_value<uint8_t>(0x01), search_result.package->id);
128 EXPECT_EQ(make_value<uint8_t>(0x01), search_result.type->id);
129 EXPECT_EQ(make_value<uint16_t>(0x0002), search_result.entry->id);
Adam Lesinskibf0bd0f2016-06-01 15:31:50 -0700130}
131
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700132::testing::AssertionResult VerifyIds(ResourceTable* table) {
133 std::set<uint8_t> package_ids;
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700134 for (auto& package : table->packages) {
135 if (!package->id) {
136 return ::testing::AssertionFailure() << "package " << package->name
137 << " has no ID";
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700138 }
139
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700140 if (!package_ids.insert(package->id.value()).second) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700141 return ::testing::AssertionFailure()
142 << "package " << package->name << " has non-unique ID " << std::hex
143 << (int)package->id.value() << std::dec;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700144 }
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700145 }
146
147 for (auto& package : table->packages) {
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700148 std::set<uint8_t> type_ids;
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700149 for (auto& type : package->types) {
150 if (!type->id) {
151 return ::testing::AssertionFailure() << "type " << type->type
152 << " of package " << package->name
153 << " has no ID";
154 }
155
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700156 if (!type_ids.insert(type->id.value()).second) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700157 return ::testing::AssertionFailure()
158 << "type " << type->type << " of package " << package->name
159 << " has non-unique ID " << std::hex << (int)type->id.value()
160 << std::dec;
161 }
162 }
163
164 for (auto& type : package->types) {
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700165 std::set<uint16_t> entry_ids;
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700166 for (auto& entry : type->entries) {
167 if (!entry->id) {
168 return ::testing::AssertionFailure()
169 << "entry " << entry->name << " of type " << type->type
170 << " of package " << package->name << " has no ID";
171 }
172
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700173 if (!entry_ids.insert(entry->id.value()).second) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700174 return ::testing::AssertionFailure()
175 << "entry " << entry->name << " of type " << type->type
176 << " of package " << package->name << " has non-unique ID "
177 << std::hex << (int)entry->id.value() << std::dec;
178 }
179 }
180 }
181 }
182 return ::testing::AssertionSuccess() << "all IDs are unique and assigned";
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700183}
184
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700185} // namespace aapt