1 /*
2  * Copyright (C) 2023 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 "dex/proto_reference.h"
18 #include <vector>
19 
20 #include "dex/dex_file_types.h"
21 #include "dex/test_dex_file_builder.h"
22 #include "gtest/gtest.h"
23 
24 namespace art {
25 
TEST(ProtoReference,WithinOneDexFile)26 TEST(ProtoReference, WithinOneDexFile) {
27     TestDexFileBuilder builder;
28     builder.AddMethod("LClass", "()I", "sideEffect2");
29     builder.AddMethod("LClass", "(I)Ljava/lang/String;", "toString");
30     builder.AddMethod("LClass", "(II)Ljava/lang/String;", "toString");
31     builder.AddMethod("LClass", "(IJ)Ljava/lang/String;", "toString");
32     builder.AddMethod("LClass", "(JJ)Ljava/lang/String;", "toString");
33     builder.AddMethod("LClass", "()V", "sideEffect1");
34 
35     std::unique_ptr<const DexFile> dex_file = builder.Build("fake location");
36     const size_t num_protos = 6u;
37     EXPECT_EQ(num_protos, dex_file->NumProtoIds());
38 
39     std::vector<ProtoReference> protos;
40 
41     for (size_t i = 0; i < num_protos; ++i) {
42         protos.emplace_back(ProtoReference(dex_file.get(), dex::ProtoIndex(i)));
43     }
44 
45     ProtoReferenceValueComparator cmp;
46     for (size_t i = 0; i < num_protos; ++i) {
47         for (size_t j = 0; j < num_protos; ++j) {
48             EXPECT_EQ(cmp(protos[i], protos[j]), i < j)
49                 << "Inconsistent at i=" << i << " and j=" << j;
50         }
51     }
52 }
53 
TEST(ProtoReference,AcrossDifferentDexFiles)54 TEST(ProtoReference, AcrossDifferentDexFiles) {
55     TestDexFileBuilder builder1;
56     builder1.AddMethod("LClass", "()I", "sideEffect2");
57     builder1.AddMethod("LClass", "(I)Ljava/lang/String;", "toString");
58     builder1.AddMethod("LClass", "(II)Ljava/lang/String;", "toString");
59     builder1.AddMethod("LClass", "(IJ)Ljava/lang/String;", "toString");
60     builder1.AddMethod("LClass", "(IJZ)Ljava/lang/String;", "toString");
61     builder1.AddMethod("LClass", "()V", "sideEffect1");
62 
63     std::unique_ptr<const DexFile> dex_file1 = builder1.Build("fake location");
64     EXPECT_EQ(6u, dex_file1->NumProtoIds());
65 
66     TestDexFileBuilder builder2;
67     builder2.AddMethod("LClass2", "(IJ)Ljava/lang/String;", "toString");
68     builder2.AddMethod("LClass2", "()V", "sideEffect1");
69     builder2.AddMethod("LClass2", "(I)V", "sideEffect2");
70 
71     std::unique_ptr<const DexFile> dex_file2 = builder2.Build("fake location 2");
72     EXPECT_EQ(3u, dex_file2->NumProtoIds());
73 
74     ProtoReference V_dex1 = ProtoReference(dex_file1.get(), dex::ProtoIndex(5));
75     ProtoReference V_dex2 = ProtoReference(dex_file2.get(), dex::ProtoIndex(1));
76 
77     ProtoReferenceValueComparator cmp;
78 
79     EXPECT_FALSE(cmp(V_dex1, V_dex2));
80     EXPECT_FALSE(cmp(V_dex2, V_dex1));
81 
82     ProtoReference IString_dex1 = ProtoReference(dex_file1.get(), dex::ProtoIndex(1));
83     ProtoReference IIString_dex1 = ProtoReference(dex_file1.get(), dex::ProtoIndex(2));
84     ProtoReference IJString_dex1 = ProtoReference(dex_file1.get(), dex::ProtoIndex(3));
85     ProtoReference IJZString_dex1 = ProtoReference(dex_file1.get(), dex::ProtoIndex(4));
86 
87     ProtoReference IJString_dex2 = ProtoReference(dex_file2.get(), dex::ProtoIndex(0));
88 
89     EXPECT_TRUE(cmp(IString_dex1, V_dex2));
90 
91     EXPECT_TRUE(cmp(IString_dex1, IJString_dex2));
92     EXPECT_TRUE(cmp(IIString_dex1, IJString_dex2));
93     EXPECT_FALSE(cmp(IJString_dex1, IJString_dex2));
94     EXPECT_FALSE(cmp(IJString_dex2, IJString_dex1));
95     EXPECT_FALSE(cmp(IJZString_dex1, IJString_dex2));
96 
97     EXPECT_TRUE(cmp(IJString_dex2, IJZString_dex1));
98 }
99 
100 }  // namespace art
101