1 : // Copyright 2016 Google Inc. All Rights Reserved.
2 : //
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 : #include "syzygy/agent/asan/reporters/exported_function.h"
16 :
17 : #include "base/bind.h"
18 : #include "gtest/gtest.h"
19 :
20 : // A dummy export for the unittest to find.
21 E : extern "C" int __declspec(dllexport) ExportedFunctionTarget(int i) {
22 E : return i;
23 E : }
24 :
25 : namespace agent {
26 : namespace asan {
27 : namespace reporters {
28 :
29 : using ExportedFunctionType = ExportedFunction<int __cdecl(int), 0>;
30 : const char* ExportedFunctionType::name_ = "ExportedFunctionTarget";
31 :
32 : using MissingExportedFunctionType = ExportedFunction<int __cdecl(int), 1>;
33 : const char* MissingExportedFunctionType::name_ =
34 : "MissingExportedFunctionTarget";
35 :
36 : // An equivalent signature function, but that doubles the input value.
37 E : int Double(int i) {
38 E : return 2 * i;
39 E : }
40 :
41 E : TEST(ExportedFunctionTest, Constructor) {
42 E : ExportedFunctionType exported_function;
43 E : EXPECT_TRUE(exported_function.function() == nullptr);
44 E : EXPECT_TRUE(exported_function.callback().is_null());
45 E : }
46 :
47 E : TEST(ExportedFunctionTest, DoesntFindMissingExport) {
48 E : MissingExportedFunctionType exported_function;
49 E : EXPECT_FALSE(exported_function.Lookup());
50 E : EXPECT_TRUE(exported_function.function() == nullptr);
51 E : EXPECT_TRUE(exported_function.callback().is_null());
52 E : }
53 :
54 E : TEST(ExportedFunctionTest, FindsActualExport) {
55 E : ExportedFunctionType exported_function;
56 E : EXPECT_TRUE(exported_function.Lookup());
57 : #ifdef NDEBUG
58 : EXPECT_EQ(&ExportedFunctionTarget, exported_function.function());
59 : #else
60 : // In debug builds the function is incrementally linked so there's
61 : // a level of indirection involved.
62 E : EXPECT_TRUE(exported_function.function() != nullptr);
63 : #endif
64 E : EXPECT_TRUE(exported_function.callback().is_null());
65 E : }
66 :
67 E : TEST(ExportedFunctionTest, InvokesActualExport) {
68 E : ExportedFunctionType exported_function;
69 E : ASSERT_TRUE(exported_function.Lookup());
70 E : ASSERT_TRUE(exported_function.function() != nullptr);
71 E : EXPECT_EQ(37, exported_function.Run(37));
72 E : EXPECT_EQ(42, exported_function.Run(42));
73 E : }
74 :
75 E : TEST(ExportedFunctionTest, InvokesSetFunction) {
76 E : MissingExportedFunctionType exported_function;
77 E : ASSERT_TRUE(exported_function.function() == nullptr);
78 E : ASSERT_TRUE(exported_function.callback().is_null());
79 :
80 E : exported_function.set_function(&Double);
81 E : ASSERT_TRUE(exported_function.function() == &Double);
82 E : ASSERT_TRUE(exported_function.callback().is_null());
83 :
84 E : EXPECT_EQ(4, exported_function.Run(2));
85 E : EXPECT_EQ(26, exported_function.Run(13));
86 E : }
87 :
88 E : TEST(ExportedFunctionTest, InvokesSetCallback) {
89 E : MissingExportedFunctionType exported_function;
90 E : ASSERT_TRUE(exported_function.function() == nullptr);
91 E : ASSERT_TRUE(exported_function.callback().is_null());
92 :
93 E : exported_function.set_callback(base::Bind(&Double));
94 E : ASSERT_TRUE(exported_function.function() == nullptr);
95 E : ASSERT_FALSE(exported_function.callback().is_null());
96 :
97 E : EXPECT_EQ(4, exported_function.Run(2));
98 E : EXPECT_EQ(26, exported_function.Run(13));
99 E : }
100 :
101 : } // namespace reporters
102 : } // namespace asan
103 : } // namespace agent
|