2 * Copyright (c) 2024 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 #include <dali-test-suite-utils.h>
19 #include <dali/devel-api/common/hash.h>
26 Dali::Vector<std::uint8_t> ConverterVector(const std::vector<std::uint8_t>& v)
28 Dali::Vector<std::uint8_t> res;
29 for(const auto it : v)
37 void utc_dali_hash_startup(void)
39 test_return_value = TET_UNDEF;
42 void utc_dali_hash_cleanup(void)
44 test_return_value = TET_PASS;
49 // To fully test the Hash distribution we need to use a tool like http://code.google.com/p/smhasher/
50 // DALi currently uses the hash for variable length strings which come from:
51 // shader vert+frag source, font family + style, image filename.
52 TestApplication application;
54 tet_infoline("UtcDaliHash");
56 const std::string testString1("highp vec4 glowColor = vec4( uGlowColor.rgb, uGlowColor.a * clampedColor.a );");
57 const std::string testString2("lowp vec4 glowColor = vec4( uGlowColor.rgb, uGlowColor.a * clampedColor.a );");
59 const std::string_view testStringView1(testString1);
60 const std::string_view testStringView2(testString2);
62 DALI_TEST_CHECK(Dali::CalculateHash(testString1) != Dali::CalculateHash(testString2));
63 DALI_TEST_CHECK(Dali::CalculateHash(testString1, testString2) != Dali::CalculateHash(testString2, testString1));
65 DALI_TEST_CHECK(Dali::CalculateHash(testString1) == Dali::CalculateHash(testStringView1));
66 DALI_TEST_CHECK(Dali::CalculateHash(testString2) == Dali::CalculateHash(testStringView2));
67 DALI_TEST_CHECK(Dali::CalculateHash(testString1, testString2) == Dali::CalculateHash(testStringView1, testStringView2));
69 DALI_TEST_CHECK(Dali::CalculateHash(testString1) != Dali::CalculateHash(testStringView1.substr(0, testStringView1.size() - 1)));
74 int UtcDaliHashNegative(void)
76 // negative test, check hash value == initial value
77 const std::string emptyString;
78 const std::string_view emptyStringView(emptyString);
80 DALI_TEST_CHECK(Dali::CalculateHash(emptyString) != 0);
81 DALI_TEST_CHECK(Dali::CalculateHash(emptyString, emptyString) != 0);
82 DALI_TEST_CHECK(Dali::CalculateHash(emptyStringView) != 0);
83 DALI_TEST_CHECK(Dali::CalculateHash(emptyStringView, emptyStringView) != 0);
84 DALI_TEST_CHECK(Dali::CalculateHash(emptyString) == Dali::CalculateHash(emptyStringView));
89 int UtcDaliHashBuffer(void)
91 TestApplication application;
93 tet_infoline("UtcDaliHashBuffer");
95 const std::vector<std::uint8_t> testBuffer1 = {11, 22, 33, 0, 0};
96 const std::vector<std::uint8_t> testBuffer2 = {11, 22, 33};
97 const std::vector<std::uint8_t> testBuffer3 = {0, 0, 33, 22, 11};
98 const std::vector<std::uint8_t> testBuffer4 = {};
100 const std::string testString1 = std::string(testBuffer1.begin(), testBuffer1.end());
101 const std::string testString2 = std::string(testBuffer2.begin(), testBuffer2.end());
102 const std::string testString3 = std::string(testBuffer3.begin(), testBuffer3.end());
103 const std::string testString4 = std::string(testBuffer4.begin(), testBuffer4.end());
105 tet_printf("const char * type terminate by \\0 char. we cannot seperate two buffer only by std::string().c_str()\n");
106 DALI_TEST_CHECK(Dali::CalculateHash(testString1) == Dali::CalculateHash(testString2));
107 DALI_TEST_CHECK(Dali::CalculateHash(testString3) == Dali::CalculateHash(testString4));
109 tet_printf("To fix this limitation, we make one more API for hashing std::vector<std::uint8_t>\n");
110 DALI_TEST_CHECK(Dali::CalculateHash(testBuffer1) != Dali::CalculateHash(testBuffer2));
111 DALI_TEST_CHECK(Dali::CalculateHash(testBuffer1) != Dali::CalculateHash(testBuffer3));
112 DALI_TEST_CHECK(Dali::CalculateHash(testBuffer1) != Dali::CalculateHash(testBuffer4));
113 DALI_TEST_CHECK(Dali::CalculateHash(testBuffer2) != Dali::CalculateHash(testBuffer3));
114 DALI_TEST_CHECK(Dali::CalculateHash(testBuffer2) != Dali::CalculateHash(testBuffer4));
115 DALI_TEST_CHECK(Dali::CalculateHash(testBuffer3) != Dali::CalculateHash(testBuffer4));
120 int UtcDaliHashBuffer02(void)
122 TestApplication application;
124 tet_infoline("UtcDaliHashBuffer02");
125 tet_infoline("Same string must have same hash value. even though generated by std::string and std::vector<std::uint8_t>.");
127 const std::string testString("highp vec4 glowColor = vec4( uGlowColor.rgb, uGlowColor.a * clampedColor.a );");
128 const std::vector<std::uint8_t> testBuffer = std::vector<std::uint8_t>(testString.begin(), testString.end());
130 DALI_TEST_CHECK(Dali::CalculateHash(testString) == Dali::CalculateHash(testBuffer));
135 int UtcDaliHashBufferNegative(void)
137 // negative test, check hash value == initial value
138 const std::vector<std::uint8_t> emptyBuffer;
139 const std::vector<std::uint8_t> notEmptyBuffer1{0};
140 const std::vector<std::uint8_t> notEmptyBuffer2{0, 0};
142 // Check with zero-only buffers also did not zero.
143 DALI_TEST_CHECK(Dali::CalculateHash(emptyBuffer) != 0);
144 DALI_TEST_CHECK(Dali::CalculateHash(notEmptyBuffer1) != 0);
145 DALI_TEST_CHECK(Dali::CalculateHash(notEmptyBuffer2) != 0);
147 // Check with zero-only buffers with difference lengths have difference value each other.
148 DALI_TEST_CHECK(Dali::CalculateHash(emptyBuffer) != Dali::CalculateHash(notEmptyBuffer1));
149 DALI_TEST_CHECK(Dali::CalculateHash(emptyBuffer) != Dali::CalculateHash(notEmptyBuffer2));
150 DALI_TEST_CHECK(Dali::CalculateHash(notEmptyBuffer1) != Dali::CalculateHash(notEmptyBuffer2));
155 int UtcDaliHashDaliBuffer(void)
157 TestApplication application;
159 tet_infoline("UtcDaliHashDaliBuffer");
161 Dali::Vector<std::uint8_t> testBuffer1 = ConverterVector({11, 22, 33, 0, 0});
162 Dali::Vector<std::uint8_t> testBuffer2 = ConverterVector({11, 22, 33});
163 Dali::Vector<std::uint8_t> testBuffer3 = ConverterVector({0, 0, 33, 22, 11});
164 Dali::Vector<std::uint8_t> testBuffer4 = ConverterVector({});
166 DALI_TEST_CHECK(Dali::CalculateHash(testBuffer1) != Dali::CalculateHash(testBuffer2));
167 DALI_TEST_CHECK(Dali::CalculateHash(testBuffer1) != Dali::CalculateHash(testBuffer3));
168 DALI_TEST_CHECK(Dali::CalculateHash(testBuffer1) != Dali::CalculateHash(testBuffer4));
169 DALI_TEST_CHECK(Dali::CalculateHash(testBuffer2) != Dali::CalculateHash(testBuffer3));
170 DALI_TEST_CHECK(Dali::CalculateHash(testBuffer2) != Dali::CalculateHash(testBuffer4));
171 DALI_TEST_CHECK(Dali::CalculateHash(testBuffer3) != Dali::CalculateHash(testBuffer4));
176 int UtcDaliHashDaliBuffer02(void)
178 TestApplication application;
180 tet_infoline("UtcDaliHashDaliBuffer02");
181 tet_infoline("Same string must have same hash value. even though generated by std::string and std::vector<std::uint8_t> and Dali::Vector<std::uint8_t>.");
183 const std::string testString("highp vec4 glowColor = vec4( uGlowColor.rgb, uGlowColor.a * clampedColor.a );");
184 const std::string_view testStringView(testString);
185 const std::vector<std::uint8_t> testBuffer = std::vector<std::uint8_t>(testString.begin(), testString.end());
186 const Dali::Vector<std::uint8_t> testBuffer2 = ConverterVector(testBuffer);
188 DALI_TEST_CHECK(Dali::CalculateHash(testString) == Dali::CalculateHash(testBuffer2));
189 DALI_TEST_CHECK(Dali::CalculateHash(testBuffer) == Dali::CalculateHash(testBuffer2));
190 DALI_TEST_CHECK(Dali::CalculateHash(testStringView) == Dali::CalculateHash(testBuffer2));
195 int UtcDaliHashDaliBufferNegative(void)
197 // negative test, check hash value == initial value
198 const Dali::Vector<std::uint8_t> emptyBuffer;
199 const Dali::Vector<std::uint8_t> notEmptyBuffer1 = ConverterVector({0});
200 const Dali::Vector<std::uint8_t> notEmptyBuffer2 = ConverterVector({0, 0});
202 // Check with zero-only buffers also did not zero.
203 DALI_TEST_CHECK(Dali::CalculateHash(emptyBuffer) != 0);
204 DALI_TEST_CHECK(Dali::CalculateHash(notEmptyBuffer1) != 0);
205 DALI_TEST_CHECK(Dali::CalculateHash(notEmptyBuffer2) != 0);
207 // Check with zero-only buffers with difference lengths have difference value each other.
208 DALI_TEST_CHECK(Dali::CalculateHash(emptyBuffer) != Dali::CalculateHash(notEmptyBuffer1));
209 DALI_TEST_CHECK(Dali::CalculateHash(emptyBuffer) != Dali::CalculateHash(notEmptyBuffer2));
210 DALI_TEST_CHECK(Dali::CalculateHash(notEmptyBuffer1) != Dali::CalculateHash(notEmptyBuffer2));
215 int UtcDaliHashWithTerminator(void)
217 TestApplication application;
219 tet_infoline("UtcDaliHashWithTerminator");
221 const std::string testString1("uJoints[10]");
222 const std::string testString2("uJoints[3]");
224 const std::string_view testStringView1(testString1);
225 const std::string_view testStringView2(testString2);
227 DALI_TEST_CHECK(Dali::CalculateHash(testString1) != Dali::CalculateHash(testString2));
228 DALI_TEST_CHECK(Dali::CalculateHash(testString1, testString2) != Dali::CalculateHash(testString2, testString1));
230 DALI_TEST_CHECK(Dali::CalculateHash(testString1) == Dali::CalculateHash(testStringView1));
231 DALI_TEST_CHECK(Dali::CalculateHash(testString2) == Dali::CalculateHash(testStringView2));
232 DALI_TEST_CHECK(Dali::CalculateHash(testString1, testString2) == Dali::CalculateHash(testStringView1, testStringView2));
234 const char terminator = '[';
236 DALI_TEST_CHECK(Dali::CalculateHash(testString1, terminator) == Dali::CalculateHash(testString2, terminator));
237 DALI_TEST_CHECK(Dali::CalculateHash(testStringView1, terminator) == Dali::CalculateHash(testStringView2, terminator));
238 DALI_TEST_CHECK(Dali::CalculateHash(testString1, terminator) == Dali::CalculateHash(testStringView2, terminator));
240 const char invalidTerminator = '?';
242 DALI_TEST_CHECK(Dali::CalculateHash(testString1) == Dali::CalculateHash(testString1, invalidTerminator));
243 DALI_TEST_CHECK(Dali::CalculateHash(testString1) == Dali::CalculateHash(testStringView1, invalidTerminator));