1 /*
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
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 */
15
16 #include "hap_resource_test.h"
17
18 #include <climits>
19 #include <gtest/gtest.h>
20
21 #include "hap_parser.h"
22 #include "hap_resource.h"
23 #include "test_common.h"
24 #include "utils/date_utils.h"
25 #include "utils/errors.h"
26 #include "utils/string_utils.h"
27
28 #define private public
29
30 using namespace OHOS::Global::Resource;
31 using namespace testing::ext;
32 namespace {
33 class HapResourceTest : public testing::Test {
34 public:
35 static void SetUpTestCase(void);
36
37 static void TearDownTestCase(void);
38
39 void SetUp();
40
41 void TearDown();
42 };
43
SetUpTestCase(void)44 void HapResourceTest::SetUpTestCase(void)
45 {
46 // step 1: input testsuit setup step
47 g_logLevel = LOG_DEBUG;
48 }
49
TearDownTestCase(void)50 void HapResourceTest::TearDownTestCase(void)
51 {
52 // step 2: input testsuit teardown step
53 }
54
SetUp()55 void HapResourceTest::SetUp()
56 {
57 // step 3: input testcase setup step
58 }
59
TearDown()60 void HapResourceTest::TearDown()
61 {
62 // step 4: input testcase teardown step
63 }
64
65 /*
66 * this test shows how to load a hap, defaultConfig set to null
67 * @tc.name: HapResourceFuncTest001
68 * @tc.desc: Test Load & GetIdValues & GetIdValuesByName function, file case.
69 * @tc.type: FUNC
70 */
71 HWTEST_F(HapResourceTest, HapResourceFuncTest001, TestSize.Level1)
72 {
73 auto start = CurrentTimeUsec();
74 const HapResource *pResource = HapResource::LoadFromIndex(FormatFullPath(g_resFilePath).c_str(), nullptr);
75 auto cost = CurrentTimeUsec() - start;
76 HILOG_DEBUG("load cost: %ld us.", cost);
77
78 if (pResource == nullptr) {
79 EXPECT_TRUE(false);
80 return;
81 }
82 EXPECT_EQ(static_cast<size_t>(80), pResource->IdSize());
83
84 int id = pResource->GetIdByName("app_name", ResType::STRING);
85 start = CurrentTimeUsec();
86 auto idValues = pResource->GetIdValues(id);
87 cost = CurrentTimeUsec() - start;
88 EXPECT_EQ(static_cast<size_t>(3), idValues->GetLimitPathsConst().size());
89 HILOG_DEBUG("GetIdValues by id cost: %ld us.", cost);
90 PrintIdValues(idValues);
91 {
92 auto limitPath = idValues->GetLimitPathsConst()[0];
93 EXPECT_TRUE(limitPath->GetFolder() == "en_US");
94 EXPECT_TRUE(limitPath->GetIdItem()->name_ == "app_name");
95 EXPECT_TRUE(limitPath->GetIdItem()->value_ == "App Name");
96 }
97 {
98 auto limitPath = idValues->GetLimitPathsConst()[1];
99 EXPECT_TRUE(limitPath->GetFolder() == "zh_CN");
100 EXPECT_TRUE(limitPath->GetIdItem()->name_ == "app_name");
101 EXPECT_TRUE(limitPath->GetIdItem()->value_ == "应用名称");
102 }
103 {
104 auto limitPath = idValues->GetLimitPathsConst()[2];
105 EXPECT_TRUE(limitPath->GetFolder() == "default");
106 EXPECT_TRUE(limitPath->GetIdItem()->name_ == "app_name");
107 EXPECT_TRUE(limitPath->GetIdItem()->value_ == "About");
108 }
109
110 std::string name = std::string("app_name");
111 start = CurrentTimeUsec();
112 auto idValues2 = pResource->GetIdValuesByName(name, ResType::STRING);
113 cost = CurrentTimeUsec() - start;
114 EXPECT_EQ(static_cast<size_t>(3), idValues2->GetLimitPathsConst().size());
115 HILOG_DEBUG("GetIdValues by name cost: %ld us.", cost);
116 PrintIdValues(idValues);
117 {
118 auto limitPath = idValues->GetLimitPathsConst()[0];
119 EXPECT_TRUE(limitPath->GetFolder() == "en_US");
120 EXPECT_TRUE(limitPath->GetIdItem()->name_ == "app_name");
121 EXPECT_TRUE(limitPath->GetIdItem()->value_ == "App Name");
122 }
123 {
124 auto limitPath = idValues->GetLimitPathsConst()[1];
125 EXPECT_TRUE(limitPath->GetFolder() == "zh_CN");
126 EXPECT_TRUE(limitPath->GetIdItem()->name_ == "app_name");
127 EXPECT_TRUE(limitPath->GetIdItem()->value_ == "应用名称");
128 }
129 {
130 auto limitPath = idValues->GetLimitPathsConst()[2];
131 EXPECT_TRUE(limitPath->GetFolder() == "default");
132 EXPECT_TRUE(limitPath->GetIdItem()->name_ == "app_name");
133 EXPECT_TRUE(limitPath->GetIdItem()->value_ == "About");
134 }
135
136 delete (pResource);
137 }
138
139 /*
140 * load a hap, set config en_US
141 * @tc.name: HapResourceFuncTest002
142 * @tc.desc: Test Load & GetIdValues & GetIdValuesByName function, file case.
143 * @tc.type: FUNC
144 */
145 HWTEST_F(HapResourceTest, HapResourceFuncTest002, TestSize.Level1)
146 {
147 ResConfigImpl *rc = new ResConfigImpl;
148 rc->SetLocaleInfo("en", nullptr, "US");
149 std::string resPath = FormatFullPath(g_resFilePath);
150 const char *path = resPath.c_str();
151
152 auto start = CurrentTimeUsec();
153 const HapResource *pResource = HapResource::LoadFromIndex(path, rc);
154 auto cost = CurrentTimeUsec() - start;
155 HILOG_DEBUG("load cost: %ld us.", cost);
156
157 if (pResource == nullptr) {
158 delete rc;
159 EXPECT_TRUE(false);
160 return;
161 }
162
163 EXPECT_EQ(static_cast<size_t>(79), pResource->IdSize());
164
165 int id = pResource->GetIdByName("app_name", ResType::STRING);
166 start = CurrentTimeUsec();
167 auto idValues = pResource->GetIdValues(id);
168 cost = CurrentTimeUsec() - start;
169 EXPECT_EQ(static_cast<size_t>(2), idValues->GetLimitPathsConst().size());
170 HILOG_DEBUG("GetIdValues by id cost: %ld us.", cost);
171 PrintIdValues(idValues);
172
173 {
174 auto limitPath = idValues->GetLimitPathsConst()[0];
175 EXPECT_TRUE(limitPath->GetFolder() == "en_US");
176 EXPECT_TRUE(limitPath->GetIdItem()->name_ == "app_name");
177 EXPECT_TRUE(limitPath->GetIdItem()->value_ == "App Name");
178 }
179
180 {
181 auto limitPath = idValues->GetLimitPathsConst()[1];
182 EXPECT_TRUE(limitPath->GetFolder() == "default");
183 EXPECT_TRUE(limitPath->GetIdItem()->name_ == "app_name");
184 EXPECT_TRUE(limitPath->GetIdItem()->value_ == "About");
185 }
186
187 std::string name = std::string("app_name");
188 start = CurrentTimeUsec();
189 auto idValues2 = pResource->GetIdValuesByName(name, ResType::STRING);
190 cost = CurrentTimeUsec() - start;
191 EXPECT_EQ(static_cast<size_t>(2), idValues2->GetLimitPathsConst().size());
192 HILOG_DEBUG("GetIdValues by name cost: %ld us.", cost);
193 PrintIdValues(idValues);
194
195 {
196 auto limitPath = idValues2->GetLimitPathsConst()[0];
197 EXPECT_TRUE(limitPath->GetFolder() == "en_US");
198 EXPECT_TRUE(limitPath->GetIdItem()->id_ == static_cast<uint32_t>(id));
199 EXPECT_TRUE(limitPath->GetIdItem()->value_ == "App Name");
200 }
201
202 {
203 auto limitPath = idValues->GetLimitPathsConst()[1];
204 EXPECT_TRUE(limitPath->GetFolder() == "default");
205 EXPECT_TRUE(limitPath->GetIdItem()->id_ == static_cast<uint32_t>(id));
206 EXPECT_TRUE(limitPath->GetIdItem()->value_ == "About");
207 }
208 delete pResource;
209 delete rc;
210 }
211
212 /*
213 * load a hap, get a value which is ref
214 * @tc.name: HapResourceFuncTest003
215 * @tc.desc: Test GetIdValuesByName function, file case.
216 * @tc.type: FUNC
217 */
218 HWTEST_F(HapResourceTest, HapResourceFuncTest003, TestSize.Level1)
219 {
220 auto start = CurrentTimeUsec();
221 const HapResource *pResource = HapResource::LoadFromIndex(FormatFullPath(g_resFilePath).c_str(), nullptr);
222 auto cost = CurrentTimeUsec() - start;
223 HILOG_DEBUG("load cost: %ld us.", cost);
224
225 if (pResource == nullptr) {
226 EXPECT_TRUE(false);
227 return;
228 }
229
230 auto idv = pResource->GetIdValuesByName(std::string("integer_ref"), ResType::INTEGER);
231 PrintIdValues(idv);
232
233 idv = pResource->GetIdValuesByName(std::string("string_ref"), ResType::STRING);
234 PrintIdValues(idv);
235
236 // ref propagation
237 idv = pResource->GetIdValuesByName(std::string("string_ref2"), ResType::STRING);
238 PrintIdValues(idv);
239
240 idv = pResource->GetIdValuesByName(std::string("boolean_ref"), ResType::BOOLEAN);
241 PrintIdValues(idv);
242
243 idv = pResource->GetIdValuesByName(std::string("color_ref"), ResType::COLOR);
244 PrintIdValues(idv);
245
246 idv = pResource->GetIdValuesByName(std::string("float_ref"), ResType::FLOAT);
247 PrintIdValues(idv);
248
249 // ref in array ,
250 idv = pResource->GetIdValuesByName(std::string("intarray_1"), ResType::INTARRAY);
251 PrintIdValues(idv);
252
253 // "parent": was ref too
254 idv = pResource->GetIdValuesByName(std::string("child"), ResType::PATTERN);
255 PrintIdValues(idv);
256 }
257
LoadFromHap(const char * hapPath,const ResConfigImpl * defaultConfig)258 ResDesc *LoadFromHap(const char *hapPath, const ResConfigImpl *defaultConfig)
259 {
260 std::string errOut;
261 void *buf = nullptr;
262 size_t bufLen;
263 int32_t out = HapParser::ReadIndexFromFile(hapPath,
264 &buf, bufLen, errOut);
265 if (out != OK) {
266 HILOG_ERROR("ReadIndexFromFile failed! retcode:%d,err:%s", out, errOut.c_str());
267 return nullptr;
268 }
269 HILOG_DEBUG("extract success, bufLen:%zu", bufLen);
270
271 ResDesc *resDesc = new ResDesc();
272 out = HapParser::ParseResHex((char *)buf, bufLen, *resDesc, defaultConfig);
273 if (out != OK) {
274 delete (resDesc);
275 free(buf);
276 HILOG_ERROR("ParseResHex failed! retcode:%d", out);
277 return nullptr;
278 } else {
279 HILOG_DEBUG("ParseResHex success:\n%s", resDesc->ToString().c_str());
280 }
281 free(buf);
282 // construct hapresource
283 return resDesc;
284 }
285
286 /*
287 * @tc.name: HapResourceFuncTest004
288 * @tc.desc: Test HapParser::ReadIndexFromFile function, file case.
289 * @tc.type: FUNC
290 */
291 HWTEST_F(HapResourceTest, HapResourceFuncTest004, TestSize.Level1)
292 {
293 // 1. normal case
294 ResDesc *resDesc = LoadFromHap(FormatFullPath("all.hap").c_str(), nullptr);
295 ASSERT_TRUE(resDesc != nullptr);
296
297 // 2. hap file exists, config.json does not exist
298 resDesc = LoadFromHap(FormatFullPath("err-config.json-1.hap").c_str(), nullptr);
299 ASSERT_TRUE(resDesc == nullptr);
300
301 // 3. hap file exists, config.json error: missing "moduleName"
302 resDesc = LoadFromHap(FormatFullPath("err-config.json-2.hap").c_str(), nullptr);
303 ASSERT_TRUE(resDesc == nullptr);
304 }
305 }