| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include <stddef.h> | |
| 6 | |
| 7 #include "base/macros.h" | |
| 8 #include "base/strings/string_number_conversions.h" | |
| 9 #include "base/strings/string_util.h" | |
| 10 #include "base/strings/utf_string_conversions.h" | |
| 11 #include "chrome/browser/enumerate_modules_model_win.h" | |
| 12 #include "testing/gtest/include/gtest/gtest.h" | |
| 13 | |
| 14 typedef testing::Test EnumerateModulesTest; | |
| 15 | |
| 16 // Set up some constants to use as default when creating the structs. | |
| 17 static const ModuleEnumerator::ModuleType kType = | |
| 18 ModuleEnumerator::LOADED_MODULE; | |
| 19 | |
| 20 static const ModuleEnumerator::ModuleStatus kStatus = | |
| 21 ModuleEnumerator::NOT_MATCHED; | |
| 22 | |
| 23 static const ModuleEnumerator::RecommendedAction kAction = | |
| 24 ModuleEnumerator::NONE; | |
| 25 | |
| 26 static const ModuleEnumerator::OperatingSystem kOs = | |
| 27 ModuleEnumerator::ALL; | |
| 28 | |
| 29 // This is a list of test cases to normalize. | |
| 30 static const struct NormalizationEntryList { | |
| 31 ModuleEnumerator::Module test_case; | |
| 32 ModuleEnumerator::Module expected; | |
| 33 } kNormalizationTestCases[] = { | |
| 34 { | |
| 35 // Only path normalization needed. | |
| 36 {kType, kStatus, L"c:\\foo\\bar.dll", L"", L"Prod", L"Desc", L"1.0", | |
| 37 L"Sig", kAction}, | |
| 38 {kType, kStatus, L"c:\\foo\\", L"bar.dll", L"Prod", L"Desc", L"1.0", | |
| 39 L"Sig", kAction}, | |
| 40 }, { | |
| 41 // Lower case normalization. | |
| 42 {kType, kStatus, L"C:\\Foo\\Bar.dll", L"", L"", L"", L"1.0", | |
| 43 L"", kAction}, | |
| 44 {kType, kStatus, L"c:\\foo\\", L"bar.dll", L"", L"", L"1.0", | |
| 45 L"", kAction}, | |
| 46 }, { | |
| 47 // Version can include strings after the version number. Strip that away. | |
| 48 {kType, kStatus, L"c:\\foo.dll", L"", L"", L"", L"1.0 asdf", | |
| 49 L"", kAction}, | |
| 50 {kType, kStatus, L"c:\\", L"foo.dll", L"", L"", L"1.0", | |
| 51 L"", kAction}, | |
| 52 }, { | |
| 53 // Corner case: No path (not sure this will ever happen). | |
| 54 {kType, kStatus, L"bar.dll", L"", L"", L"", L"", L"", kAction}, | |
| 55 {kType, kStatus, L"", L"bar.dll", L"", L"", L"", L"", kAction}, | |
| 56 }, { | |
| 57 // Error case: Missing filename (not sure this will ever happen). | |
| 58 {kType, kStatus, L"", L"", L"", L"", L"1.0", L"", kAction}, | |
| 59 {kType, kStatus, L"", L"", L"", L"", L"1.0", L"", kAction}, | |
| 60 }, | |
| 61 }; | |
| 62 | |
| 63 TEST_F(EnumerateModulesTest, NormalizeEntry) { | |
| 64 for (size_t i = 0; i < arraysize(kNormalizationTestCases); ++i) { | |
| 65 ModuleEnumerator::Module test = kNormalizationTestCases[i].test_case; | |
| 66 EXPECT_FALSE(test.normalized); | |
| 67 ModuleEnumerator::NormalizeModule(&test); | |
| 68 ModuleEnumerator::Module expected = kNormalizationTestCases[i].expected; | |
| 69 | |
| 70 SCOPED_TRACE("Test case no: " + base::IntToString(i)); | |
| 71 EXPECT_EQ(expected.type, test.type); | |
| 72 EXPECT_EQ(expected.status, test.status); | |
| 73 EXPECT_STREQ(expected.location.c_str(), test.location.c_str()); | |
| 74 EXPECT_STREQ(expected.name.c_str(), test.name.c_str()); | |
| 75 EXPECT_STREQ(expected.product_name.c_str(), test.product_name.c_str()); | |
| 76 EXPECT_STREQ(expected.description.c_str(), test.description.c_str()); | |
| 77 EXPECT_STREQ(expected.version.c_str(), test.version.c_str()); | |
| 78 EXPECT_STREQ(expected.digital_signer.c_str(), test.digital_signer.c_str()); | |
| 79 EXPECT_EQ(expected.recommended_action, test.recommended_action); | |
| 80 EXPECT_TRUE(test.normalized); | |
| 81 } | |
| 82 } | |
| 83 | |
| 84 const ModuleEnumerator::Module kStandardModule = | |
| 85 { kType, kStatus, L"c:\\foo\\bar.dll", L"", L"Prod", L"Desc", L"1.0", L"Sig", | |
| 86 ModuleEnumerator::NONE }; | |
| 87 const ModuleEnumerator::Module kStandardModuleNoDescription = | |
| 88 { kType, kStatus, L"c:\\foo\\bar.dll", L"", L"Prod", L"", L"1.0", L"Sig", | |
| 89 ModuleEnumerator::NONE }; | |
| 90 const ModuleEnumerator::Module kStandardModuleNoSignature = | |
| 91 { kType, kStatus, L"c:\\foo\\bar.dll", L"", L"Prod", L"Desc", L"1.0", L"", | |
| 92 ModuleEnumerator::NONE }; | |
| 93 | |
| 94 // Name, location, description and signature are compared by hashing. | |
| 95 static const char kMatchName[] = "88e8c9e0"; // "bar.dll". | |
| 96 static const char kMatchLocation[] = "e6ca7b1c"; // "c:\\foo\\". | |
| 97 static const char kNoMatchLocation[] = "c:\\foobar\\"; | |
| 98 static const char kMatchDesc[] = "5c4419a6"; // "Desc". | |
| 99 static const char kVersionHigh[] = "2.0"; | |
| 100 static const char kVersionLow[] = "0.5"; | |
| 101 static const char kMatchSignature[] = "7bfd87e1"; // "Sig". | |
| 102 static const char kEmpty[] = ""; | |
| 103 | |
| 104 const struct MatchingEntryList { | |
| 105 ModuleEnumerator::ModuleStatus expected_result; | |
| 106 ModuleEnumerator::Module test_case; | |
| 107 ModuleEnumerator::BlacklistEntry blacklist; | |
| 108 } kMatchineEntryList[] = { | |
| 109 // Each BlacklistEntry is: | |
| 110 // Filename, location, desc_or_signer, version from, version to, help_tip. | |
| 111 | |
| 112 { // Matches: Name (location doesn't match) => Not enough for a match. | |
| 113 ModuleEnumerator::NOT_MATCHED, | |
| 114 kStandardModule, | |
| 115 { kMatchName, kNoMatchLocation, kEmpty, kEmpty, kEmpty, kOs, | |
| 116 ModuleEnumerator::SEE_LINK } | |
| 117 }, { // Matches: Name (location not given) => Suspected match. | |
| 118 ModuleEnumerator::SUSPECTED_BAD, | |
| 119 kStandardModule, | |
| 120 { kMatchName, kEmpty, kEmpty, kEmpty, kEmpty, kOs, | |
| 121 ModuleEnumerator::SEE_LINK } | |
| 122 }, { // Matches: Name, not version (location not given) => Not a match. | |
| 123 ModuleEnumerator::NOT_MATCHED, | |
| 124 kStandardModule, | |
| 125 { kMatchName, kEmpty, kEmpty, kVersionHigh, kVersionHigh, kOs, | |
| 126 ModuleEnumerator::SEE_LINK } | |
| 127 }, { // Matches: Name, location => Suspected match. | |
| 128 ModuleEnumerator::SUSPECTED_BAD, | |
| 129 kStandardModule, | |
| 130 { kMatchName, kMatchLocation, kEmpty, kEmpty, kEmpty, kOs, | |
| 131 ModuleEnumerator::SEE_LINK } | |
| 132 }, { // Matches: Name, location, (description not given) => Confirmed match. | |
| 133 ModuleEnumerator::CONFIRMED_BAD, | |
| 134 kStandardModuleNoDescription, // Note: No description. | |
| 135 { kMatchName, kMatchLocation, kEmpty, kEmpty, kEmpty, kOs, | |
| 136 ModuleEnumerator::SEE_LINK } | |
| 137 }, { // Matches: Name, location, (signature not given) => Confirmed match. | |
| 138 ModuleEnumerator::CONFIRMED_BAD, | |
| 139 kStandardModuleNoSignature, // Note: No signature. | |
| 140 { kMatchName, kMatchLocation, kEmpty, kEmpty, kEmpty, kOs, | |
| 141 ModuleEnumerator::SEE_LINK } | |
| 142 }, { // Matches: Name, location (not version) => Not a match. | |
| 143 ModuleEnumerator::NOT_MATCHED, | |
| 144 kStandardModule, | |
| 145 { kMatchName, kMatchLocation, kEmpty, kVersionHigh, kVersionLow, kOs, | |
| 146 ModuleEnumerator::SEE_LINK } | |
| 147 }, { // Matches: Name, location, signature => Confirmed match. | |
| 148 ModuleEnumerator::CONFIRMED_BAD, | |
| 149 kStandardModule, | |
| 150 { kMatchName, kMatchLocation, kMatchSignature, kEmpty, kEmpty, kOs, | |
| 151 ModuleEnumerator::SEE_LINK } | |
| 152 }, { // Matches: Name, location, signature (not version) => No match. | |
| 153 ModuleEnumerator::NOT_MATCHED, | |
| 154 kStandardModule, | |
| 155 { kMatchName, kMatchLocation, kMatchSignature, | |
| 156 kVersionLow, kVersionLow, kOs, ModuleEnumerator::SEE_LINK } | |
| 157 }, { // Matches: Name, location, description => Confirmed match. | |
| 158 ModuleEnumerator::CONFIRMED_BAD, | |
| 159 kStandardModule, | |
| 160 { kMatchName, kMatchLocation, kMatchDesc, kEmpty, kEmpty, kOs, | |
| 161 ModuleEnumerator::SEE_LINK } | |
| 162 }, { // Matches: Name, location, description (not version) => No match. | |
| 163 ModuleEnumerator::NOT_MATCHED, | |
| 164 kStandardModule, | |
| 165 { kMatchName, kMatchLocation, kMatchDesc, | |
| 166 kVersionHigh, kVersionHigh, kOs, ModuleEnumerator::SEE_LINK } | |
| 167 }, { // Matches: Name, location, signature, version => Confirmed match. | |
| 168 ModuleEnumerator::CONFIRMED_BAD, | |
| 169 kStandardModule, | |
| 170 { kMatchName, kMatchLocation, kMatchSignature, | |
| 171 kVersionLow, kVersionHigh, kOs, ModuleEnumerator::SEE_LINK } | |
| 172 }, { // Matches: Name, location, signature, version (lower) => Confirmed. | |
| 173 ModuleEnumerator::CONFIRMED_BAD, | |
| 174 kStandardModule, | |
| 175 { kMatchName, kMatchLocation, kMatchSignature, | |
| 176 kVersionLow, kEmpty, kOs, ModuleEnumerator::SEE_LINK } | |
| 177 }, { // Matches: Name, location, signature, version (upper) => Confirmed. | |
| 178 ModuleEnumerator::CONFIRMED_BAD, | |
| 179 kStandardModule, | |
| 180 { kMatchName, kMatchLocation, kMatchSignature, | |
| 181 kEmpty, kVersionHigh, kOs, ModuleEnumerator::SEE_LINK } | |
| 182 }, { // Matches: Name, Location, Version lower is inclusive => Confirmed. | |
| 183 ModuleEnumerator::CONFIRMED_BAD, | |
| 184 kStandardModule, | |
| 185 { kMatchName, kMatchLocation, kMatchSignature, | |
| 186 "1.0", "2.0", kOs, ModuleEnumerator::SEE_LINK } | |
| 187 }, { // Matches: Name, Location, Version higher is exclusive => No match. | |
| 188 ModuleEnumerator::NOT_MATCHED, | |
| 189 kStandardModule, | |
| 190 { kMatchName, kMatchLocation, kEmpty, | |
| 191 "0.0", "1.0", kOs, ModuleEnumerator::SEE_LINK } | |
| 192 }, { // All empty fields doesn't produce a match. | |
| 193 ModuleEnumerator::NOT_MATCHED, | |
| 194 { kType, kStatus, L"", L"", L"", L"", L"", L"", ModuleEnumerator::NONE }, | |
| 195 { "a.dll", "", "", "", "", kOs, ModuleEnumerator::SEE_LINK } | |
| 196 }, | |
| 197 }; | |
| 198 | |
| 199 TEST_F(EnumerateModulesTest, MatchFunction) { | |
| 200 for (size_t i = 0; i < arraysize(kMatchineEntryList); ++i) { | |
| 201 ModuleEnumerator::Module test = kMatchineEntryList[i].test_case; | |
| 202 ModuleEnumerator::NormalizeModule(&test); | |
| 203 ModuleEnumerator::BlacklistEntry blacklist = | |
| 204 kMatchineEntryList[i].blacklist; | |
| 205 | |
| 206 SCOPED_TRACE("Test case no " + base::IntToString(i) + | |
| 207 ": '" + base::UTF16ToASCII(test.name) + "'"); | |
| 208 EXPECT_EQ(kMatchineEntryList[i].expected_result, | |
| 209 ModuleEnumerator::Match(test, blacklist)); | |
| 210 } | |
| 211 } | |
| 212 | |
| 213 const struct CollapsePathList { | |
| 214 base::string16 expected_result; | |
| 215 base::string16 test_case; | |
| 216 } kCollapsePathList[] = { | |
| 217 // Negative testing (should not collapse this path). | |
| 218 { base::ASCIIToUTF16("c:\\a\\a.dll"), base::ASCIIToUTF16("c:\\a\\a.dll") }, | |
| 219 // These two are to test that we select the maximum collapsed path. | |
| 220 { base::ASCIIToUTF16("%foo%\\a.dll"), base::ASCIIToUTF16("c:\\foo\\a.dll") }, | |
| 221 { base::ASCIIToUTF16("%x%\\a.dll"), | |
| 222 base::ASCIIToUTF16("c:\\foo\\bar\\a.dll") }, | |
| 223 }; | |
| 224 | |
| 225 TEST_F(EnumerateModulesTest, CollapsePath) { | |
| 226 scoped_refptr<ModuleEnumerator> module_enumerator(new ModuleEnumerator(NULL)); | |
| 227 module_enumerator->path_mapping_.clear(); | |
| 228 module_enumerator->path_mapping_.push_back( | |
| 229 std::make_pair(L"c:\\foo\\", L"%foo%")); | |
| 230 module_enumerator->path_mapping_.push_back( | |
| 231 std::make_pair(L"c:\\foo\\bar\\", L"%x%")); | |
| 232 | |
| 233 for (size_t i = 0; i < arraysize(kCollapsePathList); ++i) { | |
| 234 ModuleEnumerator::Module module; | |
| 235 module.location = kCollapsePathList[i].test_case; | |
| 236 module_enumerator->CollapsePath(&module); | |
| 237 | |
| 238 SCOPED_TRACE("Test case no " + base::IntToString(i) + ": '" + | |
| 239 base::UTF16ToASCII(kCollapsePathList[i].expected_result) + | |
| 240 "'"); | |
| 241 EXPECT_EQ(kCollapsePathList[i].expected_result, module.location); | |
| 242 } | |
| 243 } | |
| OLD | NEW |