Index: content/test/gpu/gpu_test_expectations_parser.cc |
=================================================================== |
--- content/test/gpu/gpu_test_expectations_parser.cc (revision 202179) |
+++ content/test/gpu/gpu_test_expectations_parser.cc (working copy) |
@@ -1,532 +0,0 @@ |
-// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "content/test/gpu/gpu_test_expectations_parser.h" |
- |
-#include "base/base_paths.h" |
-#include "base/file_util.h" |
-#include "base/logging.h" |
-#include "base/path_service.h" |
-#include "base/string_number_conversions.h" |
-#include "base/string_util.h" |
-#include "base/stringprintf.h" |
-#include "base/strings/string_split.h" |
-#include "content/public/common/content_paths.h" |
- |
-namespace { |
- |
-enum LineParserStage { |
- kLineParserBegin = 0, |
- kLineParserBugID, |
- kLineParserConfigs, |
- kLineParserColon, |
- kLineParserTestName, |
- kLineParserEqual, |
- kLineParserExpectations, |
-}; |
- |
-enum Token { |
- // os |
- kConfigWinXP = 0, |
- kConfigWinVista, |
- kConfigWin7, |
- kConfigWin8, |
- kConfigWin, |
- kConfigMacLeopard, |
- kConfigMacSnowLeopard, |
- kConfigMacLion, |
- kConfigMacMountainLion, |
- kConfigMac, |
- kConfigLinux, |
- kConfigChromeOS, |
- kConfigAndroid, |
- // gpu vendor |
- kConfigNVidia, |
- kConfigAMD, |
- kConfigIntel, |
- kConfigVMWare, |
- // build type |
- kConfigRelease, |
- kConfigDebug, |
- // expectation |
- kExpectationPass, |
- kExpectationFail, |
- kExpectationFlaky, |
- kExpectationTimeout, |
- kExpectationSkip, |
- // separator |
- kSeparatorColon, |
- kSeparatorEqual, |
- |
- kNumberOfExactMatchTokens, |
- |
- // others |
- kConfigGPUDeviceID, |
- kTokenComment, |
- kTokenWord, |
-}; |
- |
-struct TokenInfo { |
- const char* name; |
- int32 flag; |
-}; |
- |
-const TokenInfo kTokenData[] = { |
- { "xp", GPUTestConfig::kOsWinXP }, |
- { "vista", GPUTestConfig::kOsWinVista }, |
- { "win7", GPUTestConfig::kOsWin7 }, |
- { "win8", GPUTestConfig::kOsWin8 }, |
- { "win", GPUTestConfig::kOsWin }, |
- { "leopard", GPUTestConfig::kOsMacLeopard }, |
- { "snowleopard", GPUTestConfig::kOsMacSnowLeopard }, |
- { "lion", GPUTestConfig::kOsMacLion }, |
- { "mountainlion", GPUTestConfig::kOsMacMountainLion }, |
- { "mac", GPUTestConfig::kOsMac }, |
- { "linux", GPUTestConfig::kOsLinux }, |
- { "chromeos", GPUTestConfig::kOsChromeOS }, |
- { "android", GPUTestConfig::kOsAndroid }, |
- { "nvidia", 0x10DE }, |
- { "amd", 0x1002 }, |
- { "intel", 0x8086 }, |
- { "vmware", 0x15ad }, |
- { "release", GPUTestConfig::kBuildTypeRelease }, |
- { "debug", GPUTestConfig::kBuildTypeDebug }, |
- { "pass", GPUTestExpectationsParser::kGpuTestPass }, |
- { "fail", GPUTestExpectationsParser::kGpuTestFail }, |
- { "flaky", GPUTestExpectationsParser::kGpuTestFlaky }, |
- { "timeout", GPUTestExpectationsParser::kGpuTestTimeout }, |
- { "skip", GPUTestExpectationsParser::kGpuTestSkip }, |
- { ":", 0 }, |
- { "=", 0 }, |
-}; |
- |
-enum ErrorType { |
- kErrorFileIO = 0, |
- kErrorIllegalEntry, |
- kErrorInvalidEntry, |
- kErrorEntryWithOsConflicts, |
- kErrorEntryWithGpuVendorConflicts, |
- kErrorEntryWithBuildTypeConflicts, |
- kErrorEntryWithGpuDeviceIdConflicts, |
- kErrorEntryWithExpectationConflicts, |
- kErrorEntriesOverlap, |
- |
- kNumberOfErrors, |
-}; |
- |
-const char* kErrorMessage[] = { |
- "file IO failed", |
- "entry with wrong format", |
- "entry invalid, likely wrong modifiers combination", |
- "entry with OS modifier conflicts", |
- "entry with GPU vendor modifier conflicts", |
- "entry with GPU build type conflicts", |
- "entry with GPU device id conflicts or malformat", |
- "entry with expectation modifier conflicts", |
- "two entries's configs overlap", |
-}; |
- |
-Token ParseToken(const std::string& word) { |
- if (StartsWithASCII(word, "//", false)) |
- return kTokenComment; |
- if (StartsWithASCII(word, "0x", false)) |
- return kConfigGPUDeviceID; |
- |
- for (int32 i = 0; i < kNumberOfExactMatchTokens; ++i) { |
- if (LowerCaseEqualsASCII(word, kTokenData[i].name)) |
- return static_cast<Token>(i); |
- } |
- return kTokenWord; |
-} |
- |
-// reference name can have the last character as *. |
-bool NamesMatching(const std::string& ref, const std::string& test_name) { |
- size_t len = ref.length(); |
- if (len == 0) |
- return false; |
- if (ref[len - 1] == '*') { |
- if (test_name.length() > len -1 && |
- ref.compare(0, len - 1, test_name, 0, len - 1) == 0) |
- return true; |
- return false; |
- } |
- return (ref == test_name); |
-} |
- |
-} // namespace anonymous |
- |
-GPUTestExpectationsParser::GPUTestExpectationsParser() { |
- // Some sanity check. |
- DCHECK_EQ(static_cast<unsigned int>(kNumberOfExactMatchTokens), |
- sizeof(kTokenData) / sizeof(kTokenData[0])); |
- DCHECK_EQ(static_cast<unsigned int>(kNumberOfErrors), |
- sizeof(kErrorMessage) / sizeof(kErrorMessage[0])); |
-} |
- |
-GPUTestExpectationsParser::~GPUTestExpectationsParser() { |
-} |
- |
-bool GPUTestExpectationsParser::LoadTestExpectations(const std::string& data) { |
- entries_.clear(); |
- error_messages_.clear(); |
- |
- std::vector<std::string> lines; |
- base::SplitString(data, '\n', &lines); |
- bool rt = true; |
- for (size_t i = 0; i < lines.size(); ++i) { |
- if (!ParseLine(lines[i], i + 1)) |
- rt = false; |
- } |
- if (DetectConflictsBetweenEntries()) { |
- entries_.clear(); |
- rt = false; |
- } |
- |
- return rt; |
-} |
- |
-bool GPUTestExpectationsParser::LoadTestExpectations( |
- const base::FilePath& path) { |
- entries_.clear(); |
- error_messages_.clear(); |
- |
- std::string data; |
- if (!file_util::ReadFileToString(path, &data)) { |
- error_messages_.push_back(kErrorMessage[kErrorFileIO]); |
- return false; |
- } |
- return LoadTestExpectations(data); |
-} |
- |
-bool GPUTestExpectationsParser::LoadTestExpectations( |
- GPUTestProfile profile) { |
- base::FilePath path; |
- if (!GetExpectationsPath(profile, &path)) |
- return false; |
- return LoadTestExpectations(path); |
-} |
- |
-int32 GPUTestExpectationsParser::GetTestExpectation( |
- const std::string& test_name, |
- const GPUTestBotConfig& bot_config) const { |
- for (size_t i = 0; i < entries_.size(); ++i) { |
- if (NamesMatching(entries_[i].test_name, test_name) && |
- bot_config.Matches(entries_[i].test_config)) |
- return entries_[i].test_expectation; |
- } |
- return kGpuTestPass; |
-} |
- |
-const std::vector<std::string>& |
-GPUTestExpectationsParser::GetErrorMessages() const { |
- return error_messages_; |
-} |
- |
-bool GPUTestExpectationsParser::ParseConfig( |
- const std::string& config_data, GPUTestConfig* config) { |
- DCHECK(config); |
- std::vector<std::string> tokens; |
- base::SplitStringAlongWhitespace(config_data, &tokens); |
- |
- for (size_t i = 0; i < tokens.size(); ++i) { |
- Token token = ParseToken(tokens[i]); |
- switch (token) { |
- case kConfigWinXP: |
- case kConfigWinVista: |
- case kConfigWin7: |
- case kConfigWin8: |
- case kConfigWin: |
- case kConfigMacLeopard: |
- case kConfigMacSnowLeopard: |
- case kConfigMacLion: |
- case kConfigMacMountainLion: |
- case kConfigMac: |
- case kConfigLinux: |
- case kConfigChromeOS: |
- case kConfigAndroid: |
- case kConfigNVidia: |
- case kConfigAMD: |
- case kConfigIntel: |
- case kConfigVMWare: |
- case kConfigRelease: |
- case kConfigDebug: |
- case kConfigGPUDeviceID: |
- if (token == kConfigGPUDeviceID) { |
- if (!UpdateTestConfig(config, tokens[i], 0)) |
- return false; |
- } else { |
- if (!UpdateTestConfig(config, token, 0)) |
- return false; |
- } |
- break; |
- default: |
- return false; |
- } |
- } |
- return true; |
-} |
- |
-bool GPUTestExpectationsParser::ParseLine( |
- const std::string& line_data, size_t line_number) { |
- std::vector<std::string> tokens; |
- base::SplitStringAlongWhitespace(line_data, &tokens); |
- int32 stage = kLineParserBegin; |
- GPUTestExpectationEntry entry; |
- entry.line_number = line_number; |
- GPUTestConfig& config = entry.test_config; |
- bool comments_encountered = false; |
- for (size_t i = 0; i < tokens.size() && !comments_encountered; ++i) { |
- Token token = ParseToken(tokens[i]); |
- switch (token) { |
- case kTokenComment: |
- comments_encountered = true; |
- break; |
- case kConfigWinXP: |
- case kConfigWinVista: |
- case kConfigWin7: |
- case kConfigWin8: |
- case kConfigWin: |
- case kConfigMacLeopard: |
- case kConfigMacSnowLeopard: |
- case kConfigMacLion: |
- case kConfigMacMountainLion: |
- case kConfigMac: |
- case kConfigLinux: |
- case kConfigChromeOS: |
- case kConfigAndroid: |
- case kConfigNVidia: |
- case kConfigAMD: |
- case kConfigIntel: |
- case kConfigVMWare: |
- case kConfigRelease: |
- case kConfigDebug: |
- case kConfigGPUDeviceID: |
- // MODIFIERS, could be in any order, need at least one. |
- if (stage != kLineParserConfigs && stage != kLineParserBugID) { |
- PushErrorMessage(kErrorMessage[kErrorIllegalEntry], |
- line_number); |
- return false; |
- } |
- if (token == kConfigGPUDeviceID) { |
- if (!UpdateTestConfig(&config, tokens[i], line_number)) |
- return false; |
- } else { |
- if (!UpdateTestConfig(&config, token, line_number)) |
- return false; |
- } |
- if (stage == kLineParserBugID) |
- stage++; |
- break; |
- case kSeparatorColon: |
- // : |
- if (stage != kLineParserConfigs) { |
- PushErrorMessage(kErrorMessage[kErrorIllegalEntry], |
- line_number); |
- return false; |
- } |
- stage++; |
- break; |
- case kSeparatorEqual: |
- // = |
- if (stage != kLineParserTestName) { |
- PushErrorMessage(kErrorMessage[kErrorIllegalEntry], |
- line_number); |
- return false; |
- } |
- stage++; |
- break; |
- case kTokenWord: |
- // BUG_ID or TEST_NAME |
- if (stage == kLineParserBegin) { |
- // Bug ID is not used for anything; ignore it. |
- } else if (stage == kLineParserColon) { |
- entry.test_name = tokens[i]; |
- } else { |
- PushErrorMessage(kErrorMessage[kErrorIllegalEntry], |
- line_number); |
- return false; |
- } |
- stage++; |
- break; |
- case kExpectationPass: |
- case kExpectationFail: |
- case kExpectationFlaky: |
- case kExpectationTimeout: |
- case kExpectationSkip: |
- // TEST_EXPECTATIONS |
- if (stage != kLineParserEqual && stage != kLineParserExpectations) { |
- PushErrorMessage(kErrorMessage[kErrorIllegalEntry], |
- line_number); |
- return false; |
- } |
- if ((kTokenData[token].flag & entry.test_expectation) != 0) { |
- PushErrorMessage(kErrorMessage[kErrorEntryWithExpectationConflicts], |
- line_number); |
- return false; |
- } |
- entry.test_expectation = |
- (kTokenData[token].flag | entry.test_expectation); |
- if (stage == kLineParserEqual) |
- stage++; |
- break; |
- default: |
- DCHECK(false); |
- break; |
- } |
- } |
- if (stage == kLineParserBegin) { |
- // The whole line is empty or all comments |
- return true; |
- } |
- if (stage == kLineParserExpectations) { |
- if (!config.IsValid()) { |
- PushErrorMessage(kErrorMessage[kErrorInvalidEntry], line_number); |
- return false; |
- } |
- entries_.push_back(entry); |
- return true; |
- } |
- PushErrorMessage(kErrorMessage[kErrorIllegalEntry], line_number); |
- return false; |
-} |
- |
-bool GPUTestExpectationsParser::UpdateTestConfig( |
- GPUTestConfig* config, int32 token, size_t line_number) { |
- DCHECK(config); |
- switch (token) { |
- case kConfigWinXP: |
- case kConfigWinVista: |
- case kConfigWin7: |
- case kConfigWin8: |
- case kConfigWin: |
- case kConfigMacLeopard: |
- case kConfigMacSnowLeopard: |
- case kConfigMacLion: |
- case kConfigMacMountainLion: |
- case kConfigMac: |
- case kConfigLinux: |
- case kConfigChromeOS: |
- case kConfigAndroid: |
- if ((config->os() & kTokenData[token].flag) != 0) { |
- PushErrorMessage(kErrorMessage[kErrorEntryWithOsConflicts], |
- line_number); |
- return false; |
- } |
- config->set_os(config->os() | kTokenData[token].flag); |
- break; |
- case kConfigNVidia: |
- case kConfigAMD: |
- case kConfigIntel: |
- case kConfigVMWare: |
- { |
- uint32 gpu_vendor = |
- static_cast<uint32>(kTokenData[token].flag); |
- for (size_t i = 0; i < config->gpu_vendor().size(); ++i) { |
- if (config->gpu_vendor()[i] == gpu_vendor) { |
- PushErrorMessage( |
- kErrorMessage[kErrorEntryWithGpuVendorConflicts], |
- line_number); |
- return false; |
- } |
- } |
- config->AddGPUVendor(gpu_vendor); |
- } |
- break; |
- case kConfigRelease: |
- case kConfigDebug: |
- if ((config->build_type() & kTokenData[token].flag) != 0) { |
- PushErrorMessage( |
- kErrorMessage[kErrorEntryWithBuildTypeConflicts], |
- line_number); |
- return false; |
- } |
- config->set_build_type( |
- config->build_type() | kTokenData[token].flag); |
- break; |
- default: |
- DCHECK(false); |
- break; |
- } |
- return true; |
-} |
- |
-bool GPUTestExpectationsParser::UpdateTestConfig( |
- GPUTestConfig* config, |
- const std::string& gpu_device_id, |
- size_t line_number) { |
- DCHECK(config); |
- uint32 device_id = 0; |
- if (config->gpu_device_id() != 0 || |
- !base::HexStringToInt(gpu_device_id, |
- reinterpret_cast<int*>(&device_id)) || |
- device_id == 0) { |
- PushErrorMessage(kErrorMessage[kErrorEntryWithGpuDeviceIdConflicts], |
- line_number); |
- return false; |
- } |
- config->set_gpu_device_id(device_id); |
- return true; |
-} |
- |
-bool GPUTestExpectationsParser::DetectConflictsBetweenEntries() { |
- bool rt = false; |
- for (size_t i = 0; i < entries_.size(); ++i) { |
- for (size_t j = i + 1; j < entries_.size(); ++j) { |
- if (entries_[i].test_name == entries_[j].test_name && |
- entries_[i].test_config.OverlapsWith(entries_[j].test_config)) { |
- PushErrorMessage(kErrorMessage[kErrorEntriesOverlap], |
- entries_[i].line_number, |
- entries_[j].line_number); |
- rt = true; |
- } |
- } |
- } |
- return rt; |
-} |
- |
-void GPUTestExpectationsParser::PushErrorMessage( |
- const std::string& message, size_t line_number) { |
- error_messages_.push_back( |
- base::StringPrintf("Line %d : %s", |
- static_cast<int>(line_number), message.c_str())); |
-} |
- |
-void GPUTestExpectationsParser::PushErrorMessage( |
- const std::string& message, |
- size_t entry1_line_number, |
- size_t entry2_line_number) { |
- error_messages_.push_back( |
- base::StringPrintf("Line %d and %d : %s", |
- static_cast<int>(entry1_line_number), |
- static_cast<int>(entry2_line_number), |
- message.c_str())); |
-} |
- |
-// static |
-bool GPUTestExpectationsParser::GetExpectationsPath( |
- GPUTestProfile profile, base::FilePath* path) { |
- DCHECK(path); |
- |
- bool rt = true; |
- switch (profile) { |
- case kWebGLConformanceTest: |
- rt = PathService::Get(content::DIR_TEST_DATA, path); |
- if (rt) { |
- *path = path->Append(FILE_PATH_LITERAL("gpu")) |
- .Append(FILE_PATH_LITERAL( |
- "webgl_conformance_test_expectations.txt")); |
- rt = file_util::PathExists(*path); |
- } |
- break; |
- default: |
- DCHECK(false); |
- } |
- return rt; |
-} |
- |
-GPUTestExpectationsParser:: GPUTestExpectationEntry::GPUTestExpectationEntry() |
- : test_expectation(0), |
- line_number(0) { |
-} |
- |