[dali_2.3.38] Merge branch 'devel/master'
[platform/core/uifw/dali-core.git] / automated-tests / src / dali / utc-Dali-Hash.cpp
1 /*
2  * Copyright (c) 2024 Samsung Electronics Co., Ltd.
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 #include <dali-test-suite-utils.h>
19 #include <dali/devel-api/common/hash.h>
20 #include <stdlib.h>
21
22 #include <string>
23
24 namespace
25 {
26 Dali::Vector<std::uint8_t> ConverterVector(const std::vector<std::uint8_t>& v)
27 {
28   Dali::Vector<std::uint8_t> res;
29   for(const auto it : v)
30   {
31     res.PushBack(it);
32   }
33   return res;
34 };
35 } // namespace
36
37 void utc_dali_hash_startup(void)
38 {
39   test_return_value = TET_UNDEF;
40 }
41
42 void utc_dali_hash_cleanup(void)
43 {
44   test_return_value = TET_PASS;
45 }
46
47 int UtcDaliHash(void)
48 {
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;
53
54   tet_infoline("UtcDaliHash");
55
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 );");
58
59   const std::string_view testStringView1(testString1);
60   const std::string_view testStringView2(testString2);
61
62   DALI_TEST_CHECK(Dali::CalculateHash(testString1) != Dali::CalculateHash(testString2));
63   DALI_TEST_CHECK(Dali::CalculateHash(testString1, testString2) != Dali::CalculateHash(testString2, testString1));
64
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));
68
69   DALI_TEST_CHECK(Dali::CalculateHash(testString1) != Dali::CalculateHash(testStringView1.substr(0, testStringView1.size() - 1)));
70
71   END_TEST;
72 }
73
74 int UtcDaliHashNegative(void)
75 {
76   // negative test, check hash value == initial value
77   const std::string      emptyString;
78   const std::string_view emptyStringView(emptyString);
79
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));
85
86   END_TEST;
87 }
88
89 int UtcDaliHashBuffer(void)
90 {
91   TestApplication application;
92
93   tet_infoline("UtcDaliHashBuffer");
94
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 = {};
99
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());
104
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));
108
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));
116
117   END_TEST;
118 }
119
120 int UtcDaliHashBuffer02(void)
121 {
122   TestApplication application;
123
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>.");
126
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());
129
130   DALI_TEST_CHECK(Dali::CalculateHash(testString) == Dali::CalculateHash(testBuffer));
131
132   END_TEST;
133 }
134
135 int UtcDaliHashBufferNegative(void)
136 {
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};
141
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);
146
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));
151
152   END_TEST;
153 }
154
155 int UtcDaliHashDaliBuffer(void)
156 {
157   TestApplication application;
158
159   tet_infoline("UtcDaliHashDaliBuffer");
160
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({});
165
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));
172
173   END_TEST;
174 }
175
176 int UtcDaliHashDaliBuffer02(void)
177 {
178   TestApplication application;
179
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>.");
182
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);
187
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));
191
192   END_TEST;
193 }
194
195 int UtcDaliHashDaliBufferNegative(void)
196 {
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});
201
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);
206
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));
211
212   END_TEST;
213 }
214
215 int UtcDaliHashWithTerminator(void)
216 {
217   TestApplication application;
218
219   tet_infoline("UtcDaliHashWithTerminator");
220
221   const std::string testString1("uJoints[10]");
222   const std::string testString2("uJoints[3]");
223
224   const std::string_view testStringView1(testString1);
225   const std::string_view testStringView2(testString2);
226
227   DALI_TEST_CHECK(Dali::CalculateHash(testString1) != Dali::CalculateHash(testString2));
228   DALI_TEST_CHECK(Dali::CalculateHash(testString1, testString2) != Dali::CalculateHash(testString2, testString1));
229
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));
233
234   const char terminator = '[';
235
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));
239
240   const char invalidTerminator = '?';
241
242   DALI_TEST_CHECK(Dali::CalculateHash(testString1) == Dali::CalculateHash(testString1, invalidTerminator));
243   DALI_TEST_CHECK(Dali::CalculateHash(testString1) == Dali::CalculateHash(testStringView1, invalidTerminator));
244
245   END_TEST;
246 }