Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(9)

Side by Side Diff: base/win/pe_image_unittest.cc

Issue 948593004: Rework PE image tests to use a compiled DLL instead of a system one. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: update expectations Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/win/pe_image_test.cc ('k') | testing/buildbot/chromium_win8_trybot.json » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // This file contains unit tests for PEImage. 5 // This file contains unit tests for PEImage.
6 #include <algorithm>
7 #include <vector>
6 8
7 #include "testing/gtest/include/gtest/gtest.h" 9 #include "testing/gtest/include/gtest/gtest.h"
8 #include "base/win/pe_image.h" 10 #include "base/win/pe_image.h"
9 #include "base/win/windows_version.h" 11 #include "base/win/windows_version.h"
10 12
11 namespace base { 13 namespace base {
12 namespace win { 14 namespace win {
13 15
16 namespace {
17
18 class Expectations {
19 public:
20 enum Value {
21 sections = 0,
22 imports_dlls,
23 delay_dlls,
24 exports,
25 imports,
26 delay_imports,
27 relocs
28 };
29
30 enum Arch {
31 ARCH_X86 = 0,
32 ARCH_X64,
33 ARCH_X86_ON_X64,
34 ARCH_X64_ON_X64,
35 ARCH_X86_ON_X86,
36 ARCH_ALL
37 };
38
39 int GetExpectation(Value value);
40 void SetOverride(Value value, Version version, Arch arch, int count);
41 void SetOverride(Value value, Version version, int count);
42 void SetOverride(Value value, Arch arch, int count);
43
44 void SetDefault(Value value, int count) {
45 SetOverride(value, VERSION_WIN_LAST, ARCH_ALL, count);
46 }
47
48 Expectations() {
49 my_version_ = GetVersion();
50 #if defined(ARCH_CPU_64_BITS)
51 my_arch_ = ARCH_X64_ON_X64;
52 #else
53 OSInfo* os_info = OSInfo::GetInstance();
54 if (os_info->wow64_status() == OSInfo::WOW64_DISABLED)
55 my_arch_ = ARCH_X86_ON_X86;
56 else
57 my_arch_ = ARCH_X86_ON_X64;
58 #endif
59 }
60
61 private:
62 class Override {
63 public:
64 enum MatchType { MATCH_VERSION, MATCH_ARCH, MATCH_BOTH, MATCH_NONE };
65 explicit Override(Value value, Version version, Arch arch, int count)
66 : value_(value), version_(version), arch_(arch), count_(count){};
67
68 bool Matches(Value value, Version version, Arch arch, MatchType type) {
69 if (value_ != value)
70 return false;
71 switch (type) {
72 case MATCH_BOTH:
73 return MatchesVersion(version) && MatchesArch(arch);
74 break;
75 case MATCH_ARCH:
76 return MatchesArch(arch);
77 break;
78 case MATCH_VERSION:
79 return MatchesVersion(version);
80 break;
81 case MATCH_NONE:
82 return true;
83 break;
84 }
85 return false;
86 }
87
88 int GetCount() { return count_; }
89
90 private:
91 bool MatchesArch(Arch arch) {
92 switch (arch) {
93 case ARCH_X64_ON_X64:
94 return (arch_ == ARCH_X64_ON_X64 || arch_ == ARCH_X64);
95 break;
96 case ARCH_X86_ON_X86:
97 return (arch_ == ARCH_X86_ON_X86 || arch_ == ARCH_X86);
98 break;
99 case ARCH_X86_ON_X64:
100 return (arch_ == ARCH_X86_ON_X64 || arch_ == ARCH_X86);
101 break;
102 default:
103 return false;
104 }
105 }
106
107 bool MatchesVersion(Version version) { return (version == version_); }
108
109 Value value_;
110 Version version_;
111 Arch arch_;
112 int count_;
113 };
114
115 bool MatchesMyArch(Arch arch);
116
117 std::vector<Override> overrides_;
118 Arch my_arch_;
119 Version my_version_;
120 };
121
122 int Expectations::GetExpectation(Value value) {
123 // Prefer OS version specificity over Arch specificity.
124 for (auto type : {Expectations::Override::MATCH_BOTH,
125 Expectations::Override::MATCH_VERSION,
126 Expectations::Override::MATCH_ARCH,
127 Expectations::Override::MATCH_NONE})
128 for (auto or : overrides_)
129 if (or.Matches(value, my_version_, my_arch_, type))
130 return or.GetCount();
131 return 0;
132 }
133
134 void Expectations::SetOverride(Value value,
135 Version version,
136 Arch arch,
137 int count) {
138 overrides_.push_back(Override(value, version, arch, count));
139 }
140
141 void Expectations::SetOverride(Value value, Version version, int count) {
142 SetOverride(value, version, ARCH_ALL, count);
143 }
144
145 void Expectations::SetOverride(Value value, Arch arch, int count) {
146 SetOverride(value, VERSION_WIN_LAST, arch, count);
147 }
148
14 // Just counts the number of invocations. 149 // Just counts the number of invocations.
15 bool ExportsCallback(const PEImage &image, 150 bool ExportsCallback(const PEImage &image,
16 DWORD ordinal, 151 DWORD ordinal,
17 DWORD hint, 152 DWORD hint,
18 LPCSTR name, 153 LPCSTR name,
19 PVOID function, 154 PVOID function,
20 LPCSTR forward, 155 LPCSTR forward,
21 PVOID cookie) { 156 PVOID cookie) {
22 int* count = reinterpret_cast<int*>(cookie); 157 int* count = reinterpret_cast<int*>(cookie);
23 (*count)++; 158 (*count)++;
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 PIMAGE_THUNK_DATA name_table, 211 PIMAGE_THUNK_DATA name_table,
77 PIMAGE_THUNK_DATA iat, 212 PIMAGE_THUNK_DATA iat,
78 PIMAGE_THUNK_DATA bound_iat, 213 PIMAGE_THUNK_DATA bound_iat,
79 PIMAGE_THUNK_DATA unload_iat, 214 PIMAGE_THUNK_DATA unload_iat,
80 PVOID cookie) { 215 PVOID cookie) {
81 int* count = reinterpret_cast<int*>(cookie); 216 int* count = reinterpret_cast<int*>(cookie);
82 (*count)++; 217 (*count)++;
83 return true; 218 return true;
84 } 219 }
85 220
86 // Identifiers for the set of supported expectations. 221 } // namespace
87 enum ExpectationSet {
88 WIN_2K_SET,
89 WIN_XP_SET,
90 WIN_VISTA_SET,
91 WIN_7_SET,
92 WIN_8_SET,
93 UNSUPPORTED_SET,
94 };
95
96 // We'll be using some known values for the tests.
97 enum Value {
98 sections = 0,
99 imports_dlls,
100 delay_dlls,
101 exports,
102 imports,
103 delay_imports,
104 relocs
105 };
106
107 ExpectationSet GetExpectationSet(DWORD os) {
108 if (os == 50)
109 return WIN_2K_SET;
110 if (os == 51)
111 return WIN_XP_SET;
112 if (os == 60)
113 return WIN_VISTA_SET;
114 if (os == 61)
115 return WIN_7_SET;
116 if (os >= 62)
117 return WIN_8_SET;
118 return UNSUPPORTED_SET;
119 }
120
121 // Retrieves the expected value from advapi32.dll based on the OS.
122 int GetExpectedValue(Value value, DWORD os) {
123 const int xp_delay_dlls = 2;
124 const int xp_exports = 675;
125 const int xp_imports = 422;
126 const int xp_delay_imports = 8;
127 const int xp_relocs = 9180;
128 const int vista_delay_dlls = 4;
129 const int vista_exports = 799;
130 const int vista_imports = 476;
131 const int vista_delay_imports = 24;
132 const int vista_relocs = 10188;
133 const int w2k_delay_dlls = 0;
134 const int w2k_exports = 566;
135 const int w2k_imports = 357;
136 const int w2k_delay_imports = 0;
137 const int w2k_relocs = 7388;
138 const int win7_delay_dlls = 7;
139 const int win7_exports = 806;
140 const int win7_imports = 568;
141 const int win7_delay_imports = 71;
142 int win7_relocs = 7812;
143 int win7_sections = 4;
144 const int win8_delay_dlls = 9;
145 const int win8_exports = 806;
146 const int win8_imports = 568;
147 const int win8_delay_imports = 113;
148 const int win8_relocs = 9478;
149 int win8_sections = 4;
150 int win8_import_dlls = 17;
151
152 base::win::OSInfo* os_info = base::win::OSInfo::GetInstance();
153 // 32-bit process on a 32-bit system.
154 if (os_info->architecture() == base::win::OSInfo::X86_ARCHITECTURE) {
155 win8_sections = 5;
156 win8_import_dlls = 19;
157
158 // 64-bit process on a 64-bit system.
159 } else if (os_info->wow64_status() == base::win::OSInfo::WOW64_DISABLED) {
160 win7_sections = 6;
161 win7_relocs = 2712;
162 }
163
164 // Contains the expected value, for each enumerated property (Value), and the
165 // OS version: [Value][os_version]
166 const int expected[][5] = {
167 {4, 4, 4, win7_sections, win8_sections},
168 {3, 3, 3, 13, win8_import_dlls},
169 {w2k_delay_dlls, xp_delay_dlls, vista_delay_dlls, win7_delay_dlls,
170 win8_delay_dlls},
171 {w2k_exports, xp_exports, vista_exports, win7_exports, win8_exports},
172 {w2k_imports, xp_imports, vista_imports, win7_imports, win8_imports},
173 {w2k_delay_imports, xp_delay_imports,
174 vista_delay_imports, win7_delay_imports, win8_delay_imports},
175 {w2k_relocs, xp_relocs, vista_relocs, win7_relocs, win8_relocs}
176 };
177 COMPILE_ASSERT(arraysize(expected[0]) == UNSUPPORTED_SET,
178 expected_value_set_mismatch);
179
180 if (value > relocs)
181 return 0;
182 ExpectationSet expected_set = GetExpectationSet(os);
183 if (expected_set >= arraysize(expected)) {
184 // This should never happen. Log a failure if it does.
185 EXPECT_NE(UNSUPPORTED_SET, expected_set);
186 expected_set = WIN_2K_SET;
187 }
188
189 return expected[value][expected_set];
190 }
191
192
193 // TODO(jschuh): crbug.com/167707 Need to fix test on Win64 bots
194 #if defined(OS_WIN) && defined(ARCH_CPU_X86_64)
195 #define MAYBE_EnumeratesPE DISABLED_EnumeratesPE
196 #else
197 #define MAYBE_EnumeratesPE EnumeratesPE
198 #endif
199 222
200 // Tests that we are able to enumerate stuff from a PE file, and that 223 // Tests that we are able to enumerate stuff from a PE file, and that
201 // the actual number of items found is within the expected range. 224 // the actual number of items found is within the expected range.
202 TEST(PEImageTest, MAYBE_EnumeratesPE) { 225 TEST(PEImageTest, EnumeratesPE) {
203 HMODULE module = LoadLibrary(L"advapi32.dll"); 226 Expectations expectations;
227
228 // Default expectations.
229 expectations.SetDefault(Expectations::sections, 5);
230 expectations.SetDefault(Expectations::imports_dlls, 1);
231 expectations.SetDefault(Expectations::delay_dlls, 1);
232 expectations.SetDefault(Expectations::exports, 1);
233 expectations.SetDefault(Expectations::imports, 63);
234 expectations.SetDefault(Expectations::delay_imports, 2);
235 expectations.SetDefault(Expectations::relocs, 1584);
236
237 // win_chromium_x64_rel_ng (Win7 x64 on x64)
238 expectations.SetOverride(Expectations::sections, VERSION_WIN7,
239 Expectations::ARCH_X64, 6);
240 expectations.SetOverride(Expectations::imports, VERSION_WIN7,
241 Expectations::ARCH_X64, 66);
242 expectations.SetOverride(Expectations::relocs, VERSION_WIN7,
243 Expectations::ARCH_X64, 630);
244
245 HMODULE module = LoadLibrary(L"pe_image_test.dll");
204 ASSERT_TRUE(NULL != module); 246 ASSERT_TRUE(NULL != module);
205 247
206 PEImage pe(module); 248 PEImage pe(module);
207 int count = 0; 249 int count = 0;
208 EXPECT_TRUE(pe.VerifyMagic()); 250 EXPECT_TRUE(pe.VerifyMagic());
209 251
210 DWORD os = pe.GetNTHeaders()->OptionalHeader.MajorOperatingSystemVersion;
211 os = os * 10 + pe.GetNTHeaders()->OptionalHeader.MinorOperatingSystemVersion;
212
213 // Skip this test for unsupported OS versions.
214 if (GetExpectationSet(os) == UNSUPPORTED_SET)
215 return;
216
217 pe.EnumSections(SectionsCallback, &count); 252 pe.EnumSections(SectionsCallback, &count);
218 EXPECT_EQ(GetExpectedValue(sections, os), count); 253 EXPECT_EQ(expectations.GetExpectation(Expectations::sections), count);
219 254
220 count = 0; 255 count = 0;
221 pe.EnumImportChunks(ImportChunksCallback, &count); 256 pe.EnumImportChunks(ImportChunksCallback, &count);
222 EXPECT_EQ(GetExpectedValue(imports_dlls, os), count); 257 EXPECT_EQ(expectations.GetExpectation(Expectations::imports_dlls), count);
223 258
224 count = 0; 259 count = 0;
225 pe.EnumDelayImportChunks(DelayImportChunksCallback, &count); 260 pe.EnumDelayImportChunks(DelayImportChunksCallback, &count);
226 EXPECT_EQ(GetExpectedValue(delay_dlls, os), count); 261 EXPECT_EQ(expectations.GetExpectation(Expectations::delay_dlls), count);
227 262
228 count = 0; 263 count = 0;
229 pe.EnumExports(ExportsCallback, &count); 264 pe.EnumExports(ExportsCallback, &count);
230 EXPECT_GT(count, GetExpectedValue(exports, os) - 20); 265 EXPECT_EQ(expectations.GetExpectation(Expectations::exports), count);
231 EXPECT_LT(count, GetExpectedValue(exports, os) + 100);
232 266
233 count = 0; 267 count = 0;
234 pe.EnumAllImports(ImportsCallback, &count); 268 pe.EnumAllImports(ImportsCallback, &count);
235 EXPECT_GT(count, GetExpectedValue(imports, os) - 20); 269 EXPECT_EQ(expectations.GetExpectation(Expectations::imports), count);
236 EXPECT_LT(count, GetExpectedValue(imports, os) + 100);
237 270
238 count = 0; 271 count = 0;
239 pe.EnumAllDelayImports(ImportsCallback, &count); 272 pe.EnumAllDelayImports(ImportsCallback, &count);
240 EXPECT_GT(count, GetExpectedValue(delay_imports, os) - 2); 273 EXPECT_EQ(expectations.GetExpectation(Expectations::delay_imports), count);
241 EXPECT_LT(count, GetExpectedValue(delay_imports, os) + 8);
242 274
243 count = 0; 275 count = 0;
244 pe.EnumRelocs(RelocsCallback, &count); 276 pe.EnumRelocs(RelocsCallback, &count);
245 EXPECT_GT(count, GetExpectedValue(relocs, os) - 150); 277 EXPECT_EQ(expectations.GetExpectation(Expectations::relocs), count);
246 EXPECT_LT(count, GetExpectedValue(relocs, os) + 1500);
247 278
248 FreeLibrary(module); 279 FreeLibrary(module);
249 } 280 }
250 281
251 // Tests that we can locate an specific exported symbol, by name and by ordinal. 282 // Tests that we can locate an specific exported symbol, by name and by ordinal.
252 TEST(PEImageTest, RetrievesExports) { 283 TEST(PEImageTest, RetrievesExports) {
253 HMODULE module = LoadLibrary(L"advapi32.dll"); 284 HMODULE module = LoadLibrary(L"advapi32.dll");
254 ASSERT_TRUE(NULL != module); 285 ASSERT_TRUE(NULL != module);
255 286
256 PEImage pe(module); 287 PEImage pe(module);
(...skipping 21 matching lines...) Expand all
278 EXPECT_TRUE(pe.GetDebugId(&guid, &age)); 309 EXPECT_TRUE(pe.GetDebugId(&guid, &age));
279 310
280 GUID empty_guid = {0}; 311 GUID empty_guid = {0};
281 EXPECT_TRUE(!IsEqualGUID(empty_guid, guid)); 312 EXPECT_TRUE(!IsEqualGUID(empty_guid, guid));
282 EXPECT_NE(0U, age); 313 EXPECT_NE(0U, age);
283 FreeLibrary(module); 314 FreeLibrary(module);
284 } 315 }
285 316
286 } // namespace win 317 } // namespace win
287 } // namespace base 318 } // namespace base
OLDNEW
« no previous file with comments | « base/win/pe_image_test.cc ('k') | testing/buildbot/chromium_win8_trybot.json » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698