xref: /aosp_15_r20/external/zucchini/zucchini_gen_unittest.cc (revision a03ca8b91e029cd15055c20c78c2e087c84792e4)
1*a03ca8b9SKrzysztof Kosiński // Copyright 2017 The Chromium Authors. All rights reserved.
2*a03ca8b9SKrzysztof Kosiński // Use of this source code is governed by a BSD-style license that can be
3*a03ca8b9SKrzysztof Kosiński // found in the LICENSE file.
4*a03ca8b9SKrzysztof Kosiński 
5*a03ca8b9SKrzysztof Kosiński #include "components/zucchini/zucchini_gen.h"
6*a03ca8b9SKrzysztof Kosiński 
7*a03ca8b9SKrzysztof Kosiński #include <stdint.h>
8*a03ca8b9SKrzysztof Kosiński 
9*a03ca8b9SKrzysztof Kosiński #include <deque>
10*a03ca8b9SKrzysztof Kosiński #include <utility>
11*a03ca8b9SKrzysztof Kosiński #include <vector>
12*a03ca8b9SKrzysztof Kosiński 
13*a03ca8b9SKrzysztof Kosiński #include "components/zucchini/equivalence_map.h"
14*a03ca8b9SKrzysztof Kosiński #include "components/zucchini/image_index.h"
15*a03ca8b9SKrzysztof Kosiński #include "components/zucchini/image_utils.h"
16*a03ca8b9SKrzysztof Kosiński #include "components/zucchini/test_disassembler.h"
17*a03ca8b9SKrzysztof Kosiński #include "testing/gtest/include/gtest/gtest.h"
18*a03ca8b9SKrzysztof Kosiński 
19*a03ca8b9SKrzysztof Kosiński namespace zucchini {
20*a03ca8b9SKrzysztof Kosiński 
21*a03ca8b9SKrzysztof Kosiński namespace {
22*a03ca8b9SKrzysztof Kosiński 
23*a03ca8b9SKrzysztof Kosiński using OffsetVector = std::vector<offset_t>;
24*a03ca8b9SKrzysztof Kosiński 
25*a03ca8b9SKrzysztof Kosiński // In normal usage, 0.0 is an unrealistic similarity value for an
26*a03ca8b9SKrzysztof Kosiński // EquivalenceCandiate. Since similarity doesn't affect results for various unit
27*a03ca8b9SKrzysztof Kosiński // tests in this file, we use this dummy value for simplicity.
28*a03ca8b9SKrzysztof Kosiński constexpr double kDummySim = 0.0;
29*a03ca8b9SKrzysztof Kosiński 
30*a03ca8b9SKrzysztof Kosiński // Helper function wrapping GenerateReferencesDelta().
GenerateReferencesDeltaTest(std::vector<Reference> && old_references,std::vector<Reference> && new_references,std::deque<offset_t> && exp_old_targets,std::deque<offset_t> && exp_projected_old_targets,EquivalenceMap && equivalence_map)31*a03ca8b9SKrzysztof Kosiński std::vector<int32_t> GenerateReferencesDeltaTest(
32*a03ca8b9SKrzysztof Kosiński     std::vector<Reference>&& old_references,
33*a03ca8b9SKrzysztof Kosiński     std::vector<Reference>&& new_references,
34*a03ca8b9SKrzysztof Kosiński     std::deque<offset_t>&& exp_old_targets,
35*a03ca8b9SKrzysztof Kosiński     std::deque<offset_t>&& exp_projected_old_targets,
36*a03ca8b9SKrzysztof Kosiński     EquivalenceMap&& equivalence_map) {
37*a03ca8b9SKrzysztof Kosiński   // OffsetMapper needs image sizes for forward-projection overflow check. These
38*a03ca8b9SKrzysztof Kosiński   // are tested elsewhere, so just use arbitrary large value.
39*a03ca8b9SKrzysztof Kosiński   constexpr offset_t kOldImageSize = 1000000;
40*a03ca8b9SKrzysztof Kosiński   constexpr offset_t kNewImageSize = 1001000;
41*a03ca8b9SKrzysztof Kosiński 
42*a03ca8b9SKrzysztof Kosiński   ReferenceDeltaSink reference_delta_sink;
43*a03ca8b9SKrzysztof Kosiński 
44*a03ca8b9SKrzysztof Kosiński   TargetPool old_targets;
45*a03ca8b9SKrzysztof Kosiński   old_targets.InsertTargets(old_references);
46*a03ca8b9SKrzysztof Kosiński   ReferenceSet old_refs({1, TypeTag(0), PoolTag(0)}, old_targets);
47*a03ca8b9SKrzysztof Kosiński   old_refs.InitReferences(old_references);
48*a03ca8b9SKrzysztof Kosiński   EXPECT_EQ(exp_old_targets, old_targets.targets());
49*a03ca8b9SKrzysztof Kosiński 
50*a03ca8b9SKrzysztof Kosiński   TargetPool new_targets;
51*a03ca8b9SKrzysztof Kosiński   new_targets.InsertTargets(new_references);
52*a03ca8b9SKrzysztof Kosiński   ReferenceSet new_refs({1, TypeTag(0), PoolTag(0)}, new_targets);
53*a03ca8b9SKrzysztof Kosiński   new_refs.InitReferences(new_references);
54*a03ca8b9SKrzysztof Kosiński 
55*a03ca8b9SKrzysztof Kosiński   OffsetMapper offset_mapper(equivalence_map, kOldImageSize, kNewImageSize);
56*a03ca8b9SKrzysztof Kosiński   TargetPool projected_old_targets = old_targets;
57*a03ca8b9SKrzysztof Kosiński   projected_old_targets.FilterAndProject(offset_mapper);
58*a03ca8b9SKrzysztof Kosiński 
59*a03ca8b9SKrzysztof Kosiński   std::vector<offset_t> extra_target =
60*a03ca8b9SKrzysztof Kosiński       FindExtraTargets(projected_old_targets, new_targets);
61*a03ca8b9SKrzysztof Kosiński   projected_old_targets.InsertTargets(extra_target);
62*a03ca8b9SKrzysztof Kosiński   EXPECT_EQ(exp_projected_old_targets, projected_old_targets.targets());
63*a03ca8b9SKrzysztof Kosiński 
64*a03ca8b9SKrzysztof Kosiński   GenerateReferencesDelta(old_refs, new_refs, projected_old_targets,
65*a03ca8b9SKrzysztof Kosiński                           offset_mapper, equivalence_map,
66*a03ca8b9SKrzysztof Kosiński                           &reference_delta_sink);
67*a03ca8b9SKrzysztof Kosiński 
68*a03ca8b9SKrzysztof Kosiński   // Serialize |reference_delta_sink| to patch format, and read it back as
69*a03ca8b9SKrzysztof Kosiński   // std::vector<int32_t>.
70*a03ca8b9SKrzysztof Kosiński   std::vector<uint8_t> buffer(reference_delta_sink.SerializedSize());
71*a03ca8b9SKrzysztof Kosiński   BufferSink sink(buffer.data(), buffer.size());
72*a03ca8b9SKrzysztof Kosiński   reference_delta_sink.SerializeInto(&sink);
73*a03ca8b9SKrzysztof Kosiński 
74*a03ca8b9SKrzysztof Kosiński   BufferSource source(buffer.data(), buffer.size());
75*a03ca8b9SKrzysztof Kosiński   ReferenceDeltaSource reference_delta_source;
76*a03ca8b9SKrzysztof Kosiński   EXPECT_TRUE(reference_delta_source.Initialize(&source));
77*a03ca8b9SKrzysztof Kosiński   std::vector<int32_t> delta_vec;
78*a03ca8b9SKrzysztof Kosiński   for (auto delta = reference_delta_source.GetNext(); delta.has_value();
79*a03ca8b9SKrzysztof Kosiński        delta = reference_delta_source.GetNext()) {
80*a03ca8b9SKrzysztof Kosiński     delta_vec.push_back(*delta);
81*a03ca8b9SKrzysztof Kosiński   }
82*a03ca8b9SKrzysztof Kosiński   EXPECT_TRUE(reference_delta_source.Done());
83*a03ca8b9SKrzysztof Kosiński   return delta_vec;
84*a03ca8b9SKrzysztof Kosiński }
85*a03ca8b9SKrzysztof Kosiński 
86*a03ca8b9SKrzysztof Kosiński }  // namespace
87*a03ca8b9SKrzysztof Kosiński 
TEST(ZucchiniGenTest,FindExtraTargets)88*a03ca8b9SKrzysztof Kosiński TEST(ZucchiniGenTest, FindExtraTargets) {
89*a03ca8b9SKrzysztof Kosiński   EXPECT_EQ(OffsetVector(), FindExtraTargets({}, {}));
90*a03ca8b9SKrzysztof Kosiński   EXPECT_EQ(OffsetVector(), FindExtraTargets(TargetPool({3}), {}));
91*a03ca8b9SKrzysztof Kosiński   EXPECT_EQ(OffsetVector(), FindExtraTargets(TargetPool({3}), TargetPool({3})));
92*a03ca8b9SKrzysztof Kosiński   EXPECT_EQ(OffsetVector({4}),
93*a03ca8b9SKrzysztof Kosiński             FindExtraTargets(TargetPool({3}), TargetPool({4})));
94*a03ca8b9SKrzysztof Kosiński   EXPECT_EQ(OffsetVector({4}),
95*a03ca8b9SKrzysztof Kosiński             FindExtraTargets(TargetPool({3}), TargetPool({3, 4})));
96*a03ca8b9SKrzysztof Kosiński   EXPECT_EQ(OffsetVector({4}),
97*a03ca8b9SKrzysztof Kosiński             FindExtraTargets(TargetPool({2, 3}), TargetPool({3, 4})));
98*a03ca8b9SKrzysztof Kosiński   EXPECT_EQ(OffsetVector({3, 5}),
99*a03ca8b9SKrzysztof Kosiński             FindExtraTargets(TargetPool({2, 4}), TargetPool({3, 5})));
100*a03ca8b9SKrzysztof Kosiński }
101*a03ca8b9SKrzysztof Kosiński 
TEST(ZucchiniGenTest,GenerateReferencesDelta)102*a03ca8b9SKrzysztof Kosiński TEST(ZucchiniGenTest, GenerateReferencesDelta) {
103*a03ca8b9SKrzysztof Kosiński   // No equivalences.
104*a03ca8b9SKrzysztof Kosiński   EXPECT_EQ(std::vector<int32_t>(),
105*a03ca8b9SKrzysztof Kosiński             GenerateReferencesDeltaTest({}, {}, {}, {}, EquivalenceMap()));
106*a03ca8b9SKrzysztof Kosiński   EXPECT_EQ(std::vector<int32_t>(),
107*a03ca8b9SKrzysztof Kosiński             GenerateReferencesDeltaTest({{10, 0}}, {{20, 0}}, {0}, {0},
108*a03ca8b9SKrzysztof Kosiński                                         EquivalenceMap()));
109*a03ca8b9SKrzysztof Kosiński 
110*a03ca8b9SKrzysztof Kosiński   // Simple cases with one equivalence.
111*a03ca8b9SKrzysztof Kosiński   EXPECT_EQ(
112*a03ca8b9SKrzysztof Kosiński       std::vector<int32_t>({0}),  // {0 - 0}.
113*a03ca8b9SKrzysztof Kosiński       GenerateReferencesDeltaTest(
114*a03ca8b9SKrzysztof Kosiński           {{10, 3}}, {{20, 3}}, {3}, {3},
115*a03ca8b9SKrzysztof Kosiński           EquivalenceMap({{{3, 3, 1}, kDummySim}, {{10, 20, 4}, kDummySim}})));
116*a03ca8b9SKrzysztof Kosiński   EXPECT_EQ(
117*a03ca8b9SKrzysztof Kosiński       std::vector<int32_t>({-1}),  // {0 - 1}.
118*a03ca8b9SKrzysztof Kosiński       GenerateReferencesDeltaTest(
119*a03ca8b9SKrzysztof Kosiński           {{10, 3}}, {{20, 3}}, {3}, {3, 4},
120*a03ca8b9SKrzysztof Kosiński           EquivalenceMap({{{3, 4, 1}, kDummySim}, {{10, 20, 4}, kDummySim}})));
121*a03ca8b9SKrzysztof Kosiński   EXPECT_EQ(
122*a03ca8b9SKrzysztof Kosiński       std::vector<int32_t>({1}),  // {1 - 0}.
123*a03ca8b9SKrzysztof Kosiński       GenerateReferencesDeltaTest(
124*a03ca8b9SKrzysztof Kosiński           {{10, 3}}, {{20, 3}}, {3}, {2, 3},
125*a03ca8b9SKrzysztof Kosiński           EquivalenceMap({{{3, 2, 1}, kDummySim}, {{10, 20, 4}, kDummySim}})));
126*a03ca8b9SKrzysztof Kosiński   EXPECT_EQ(std::vector<int32_t>({1, -1}),  // {1 - 0, 0 - 1}.
127*a03ca8b9SKrzysztof Kosiński             GenerateReferencesDeltaTest(
128*a03ca8b9SKrzysztof Kosiński                 {{10, 3}, {11, 4}}, {{20, 3}, {21, 4}}, {3, 4}, {2, 3, 4, 5},
129*a03ca8b9SKrzysztof Kosiński                 EquivalenceMap({{{3, 2, 1}, kDummySim},
130*a03ca8b9SKrzysztof Kosiński                                 {{4, 5, 1}, kDummySim},
131*a03ca8b9SKrzysztof Kosiński                                 {{10, 20, 4}, kDummySim}})));
132*a03ca8b9SKrzysztof Kosiński 
133*a03ca8b9SKrzysztof Kosiński   EXPECT_EQ(
134*a03ca8b9SKrzysztof Kosiński       std::vector<int32_t>({0, 0}),  // {1 - 1, 2 - 2}.
135*a03ca8b9SKrzysztof Kosiński       GenerateReferencesDeltaTest(
136*a03ca8b9SKrzysztof Kosiński           {{10, 3}, {11, 4}, {12, 5}, {13, 6}},
137*a03ca8b9SKrzysztof Kosiński           {{20, 3}, {21, 4}, {22, 5}, {23, 6}}, {3, 4, 5, 6}, {3, 4, 5, 6},
138*a03ca8b9SKrzysztof Kosiński           EquivalenceMap({{{3, 3, 4}, kDummySim}, {{11, 21, 2}, kDummySim}})));
139*a03ca8b9SKrzysztof Kosiński 
140*a03ca8b9SKrzysztof Kosiński   // Multiple equivalences.
141*a03ca8b9SKrzysztof Kosiński   EXPECT_EQ(std::vector<int32_t>({-1, 1}),  // {0 - 1, 1 - 0}.
142*a03ca8b9SKrzysztof Kosiński             GenerateReferencesDeltaTest(
143*a03ca8b9SKrzysztof Kosiński                 {{10, 0}, {12, 1}}, {{10, 0}, {12, 1}}, {0, 1}, {0, 1},
144*a03ca8b9SKrzysztof Kosiński                 EquivalenceMap({{{0, 0, 2}, kDummySim},
145*a03ca8b9SKrzysztof Kosiński                                 {{12, 10, 2}, kDummySim},
146*a03ca8b9SKrzysztof Kosiński                                 {{10, 12, 2}, kDummySim}})));
147*a03ca8b9SKrzysztof Kosiński   EXPECT_EQ(
148*a03ca8b9SKrzysztof Kosiński       std::vector<int32_t>({0, 0}),  // {0 - 0, 1 - 1}.
149*a03ca8b9SKrzysztof Kosiński       GenerateReferencesDeltaTest(
150*a03ca8b9SKrzysztof Kosiński           {{0, 0}, {2, 2}}, {{0, 0}, {2, 2}}, {0, 2}, {0, 2},
151*a03ca8b9SKrzysztof Kosiński           EquivalenceMap({{{2, 0, 2}, kDummySim}, {{0, 2, 2}, kDummySim}})));
152*a03ca8b9SKrzysztof Kosiński 
153*a03ca8b9SKrzysztof Kosiński   EXPECT_EQ(std::vector<int32_t>({-2, 2}),  // {0 - 2, 2 - 0}.
154*a03ca8b9SKrzysztof Kosiński             GenerateReferencesDeltaTest(
155*a03ca8b9SKrzysztof Kosiński                 {{10, 0}, {12, 1}, {14, 2}}, {{10, 0}, {12, 1}, {14, 2}},
156*a03ca8b9SKrzysztof Kosiński                 {0, 1, 2}, {0, 1, 2},
157*a03ca8b9SKrzysztof Kosiński                 EquivalenceMap({{{0, 0, 3}, kDummySim},
158*a03ca8b9SKrzysztof Kosiński                                 {{14, 10, 2}, kDummySim},
159*a03ca8b9SKrzysztof Kosiński                                 {{10, 14, 2}, kDummySim}})));
160*a03ca8b9SKrzysztof Kosiński 
161*a03ca8b9SKrzysztof Kosiński   EXPECT_EQ(std::vector<int32_t>({-2, 2}),  // {0 - 2, 2 - 0}.
162*a03ca8b9SKrzysztof Kosiński             GenerateReferencesDeltaTest(
163*a03ca8b9SKrzysztof Kosiński                 {{11, 0}, {14, 1}, {17, 2}}, {{11, 0}, {14, 1}, {17, 2}},
164*a03ca8b9SKrzysztof Kosiński                 {0, 1, 2}, {0, 1, 2},
165*a03ca8b9SKrzysztof Kosiński                 EquivalenceMap({{{0, 0, 3}, kDummySim},
166*a03ca8b9SKrzysztof Kosiński                                 {{16, 10, 3}, kDummySim},
167*a03ca8b9SKrzysztof Kosiński                                 {{10, 16, 3}, kDummySim}})));
168*a03ca8b9SKrzysztof Kosiński 
169*a03ca8b9SKrzysztof Kosiński   EXPECT_EQ(
170*a03ca8b9SKrzysztof Kosiński       std::vector<int32_t>({-2, 2}),  // {0 - 2, 2 - 0}.
171*a03ca8b9SKrzysztof Kosiński       GenerateReferencesDeltaTest({{10, 0}, {14, 2}, {16, 1}},
172*a03ca8b9SKrzysztof Kosiński                                   {{10, 0}, {14, 2}}, {0, 1, 2}, {0, 1, 2},
173*a03ca8b9SKrzysztof Kosiński                                   EquivalenceMap({{{0, 0, 3}, kDummySim},
174*a03ca8b9SKrzysztof Kosiński                                                   {{14, 10, 2}, kDummySim},
175*a03ca8b9SKrzysztof Kosiński                                                   {{12, 12, 2}, kDummySim},
176*a03ca8b9SKrzysztof Kosiński                                                   {{10, 14, 2}, kDummySim}})));
177*a03ca8b9SKrzysztof Kosiński }
178*a03ca8b9SKrzysztof Kosiński 
179*a03ca8b9SKrzysztof Kosiński // TODO(huangs): Add more tests.
180*a03ca8b9SKrzysztof Kosiński 
181*a03ca8b9SKrzysztof Kosiński }  // namespace zucchini
182