diff options
author | zmo@chromium.org <zmo@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-28 23:38:02 +0000 |
---|---|---|
committer | zmo@chromium.org <zmo@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-28 23:38:02 +0000 |
commit | 129f019eaa2016c4a7cf3fffd486d76baf22369c (patch) | |
tree | 779588af03563c46f69dd98bd4afb26887f16cb2 /gpu | |
parent | 8623d0c2c5c9929ce0b1f27ea3915dc5d14eac8c (diff) | |
download | chromium_src-129f019eaa2016c4a7cf3fffd486d76baf22369c.zip chromium_src-129f019eaa2016c4a7cf3fffd486d76baf22369c.tar.gz chromium_src-129f019eaa2016c4a7cf3fffd486d76baf22369c.tar.bz2 |
Move gpu_test_config stuff from content/ to gpu/
Again, these code is not depending on any content stuff, so moving it to gpu/ side will allow us to disable more gpu tests per GPU.
BUG=230477
TEST=gpu_unittests,tree
TBR=kbr@chromium.org, piman@chromium.org
Review URL: https://codereview.chromium.org/15827008
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@202690 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
-rw-r--r-- | gpu/config/gpu_test_config.cc | 272 | ||||
-rw-r--r-- | gpu/config/gpu_test_config.h | 124 | ||||
-rw-r--r-- | gpu/config/gpu_test_config_unittest.cc | 255 | ||||
-rw-r--r-- | gpu/config/gpu_test_expectations_parser.cc | 503 | ||||
-rw-r--r-- | gpu/config/gpu_test_expectations_parser.h | 88 | ||||
-rw-r--r-- | gpu/config/gpu_test_expectations_parser_unittest.cc | 245 | ||||
-rw-r--r-- | gpu/gpu.gyp | 2 | ||||
-rw-r--r-- | gpu/gpu_config.gypi | 4 |
8 files changed, 1493 insertions, 0 deletions
diff --git a/gpu/config/gpu_test_config.cc b/gpu/config/gpu_test_config.cc new file mode 100644 index 0000000..ffb6e5f --- /dev/null +++ b/gpu/config/gpu_test_config.cc @@ -0,0 +1,272 @@ +// 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 "gpu/config/gpu_test_config.h" + +#include "base/logging.h" +#include "base/sys_info.h" +#include "gpu/config/gpu_info.h" +#include "gpu/config/gpu_info_collector.h" +#include "gpu/config/gpu_test_expectations_parser.h" + +namespace gpu { + +namespace { + +GPUTestConfig::OS GetCurrentOS() { +#if defined(OS_CHROMEOS) + return GPUTestConfig::kOsChromeOS; +#elif defined(OS_LINUX) || defined(OS_OPENBSD) + return GPUTestConfig::kOsLinux; +#elif defined(OS_WIN) + int32 major_version = 0; + int32 minor_version = 0; + int32 bugfix_version = 0; + base::SysInfo::OperatingSystemVersionNumbers( + &major_version, &minor_version, &bugfix_version); + if (major_version == 5) + return GPUTestConfig::kOsWinXP; + if (major_version == 6 && minor_version == 0) + return GPUTestConfig::kOsWinVista; + if (major_version == 6 && minor_version == 1) + return GPUTestConfig::kOsWin7; + if (major_version == 6 && minor_version == 2) + return GPUTestConfig::kOsWin8; +#elif defined(OS_MACOSX) + int32 major_version = 0; + int32 minor_version = 0; + int32 bugfix_version = 0; + base::SysInfo::OperatingSystemVersionNumbers( + &major_version, &minor_version, &bugfix_version); + if (major_version == 10) { + switch (minor_version) { + case 5: + return GPUTestConfig::kOsMacLeopard; + case 6: + return GPUTestConfig::kOsMacSnowLeopard; + case 7: + return GPUTestConfig::kOsMacLion; + case 8: + return GPUTestConfig::kOsMacMountainLion; + } + } +#elif defined(OS_ANDROID) + return GPUTestConfig::kOsAndroid; +#endif + return GPUTestConfig::kOsUnknown; +} + +} // namespace anonymous + +GPUTestConfig::GPUTestConfig() + : validate_gpu_info_(true), + os_(kOsUnknown), + gpu_device_id_(0), + build_type_(kBuildTypeUnknown) { +} + +GPUTestConfig::~GPUTestConfig() { +} + +void GPUTestConfig::set_os(int32 os) { + DCHECK_EQ(0, os & ~(kOsAndroid | kOsWin | kOsMac | kOsLinux | kOsChromeOS)); + os_ = os; +} + +void GPUTestConfig::AddGPUVendor(uint32 gpu_vendor) { + DCHECK_NE(0u, gpu_vendor); + for (size_t i = 0; i < gpu_vendor_.size(); ++i) + DCHECK_NE(gpu_vendor_[i], gpu_vendor); + gpu_vendor_.push_back(gpu_vendor); +} + +void GPUTestConfig::set_gpu_device_id(uint32 id) { + gpu_device_id_ = id; +} + +void GPUTestConfig::set_build_type(int32 build_type) { + DCHECK_EQ(0, build_type & ~(kBuildTypeRelease | kBuildTypeDebug)); + build_type_ = build_type; +} + +bool GPUTestConfig::IsValid() const { + if (!validate_gpu_info_) + return true; + if (gpu_device_id_ != 0 && (gpu_vendor_.size() != 1 || gpu_vendor_[0] == 0)) + return false; + return true; +} + +bool GPUTestConfig::OverlapsWith(const GPUTestConfig& config) const { + DCHECK(IsValid()); + DCHECK(config.IsValid()); + if (config.os_ != kOsUnknown && os_ != kOsUnknown && + (os_ & config.os_) == 0) + return false; + if (config.gpu_vendor_.size() > 0 && gpu_vendor_.size() > 0) { + bool shared = false; + for (size_t i = 0; i < config.gpu_vendor_.size() && !shared; ++i) { + for (size_t j = 0; j < gpu_vendor_.size(); ++j) { + if (config.gpu_vendor_[i] == gpu_vendor_[j]) { + shared = true; + break; + } + } + } + if (!shared) + return false; + } + if (config.gpu_device_id_ != 0 && gpu_device_id_ != 0 && + gpu_device_id_ != config.gpu_device_id_) + return false; + if (config.build_type_ != kBuildTypeUnknown && + build_type_ != kBuildTypeUnknown && + (build_type_ & config.build_type_) == 0) + return false; + return true; +} + +void GPUTestConfig::DisableGPUInfoValidation() { + validate_gpu_info_ = false; +} + +void GPUTestConfig::ClearGPUVendor() { + gpu_vendor_.clear(); +} + +GPUTestBotConfig::~GPUTestBotConfig() { +} + +void GPUTestBotConfig::AddGPUVendor(uint32 gpu_vendor) { + DCHECK_EQ(0u, GPUTestConfig::gpu_vendor().size()); + GPUTestConfig::AddGPUVendor(gpu_vendor); +} + +bool GPUTestBotConfig::SetGPUInfo(const GPUInfo& gpu_info) { + DCHECK(validate_gpu_info_); + if (gpu_info.gpu.device_id == 0 || gpu_info.gpu.vendor_id == 0) + return false; + ClearGPUVendor(); + AddGPUVendor(gpu_info.gpu.vendor_id); + set_gpu_device_id(gpu_info.gpu.device_id); + return true; +} + +bool GPUTestBotConfig::IsValid() const { + switch (os()) { + case kOsWinXP: + case kOsWinVista: + case kOsWin7: + case kOsWin8: + case kOsMacLeopard: + case kOsMacSnowLeopard: + case kOsMacLion: + case kOsMacMountainLion: + case kOsLinux: + case kOsChromeOS: + case kOsAndroid: + break; + default: + return false; + } + if (validate_gpu_info_) { + if (gpu_vendor().size() != 1 || gpu_vendor()[0] == 0) + return false; + if (gpu_device_id() == 0) + return false; + } + switch (build_type()) { + case kBuildTypeRelease: + case kBuildTypeDebug: + break; + default: + return false; + } + return true; +} + +bool GPUTestBotConfig::Matches(const GPUTestConfig& config) const { + DCHECK(IsValid()); + DCHECK(config.IsValid()); + if (config.os() != kOsUnknown && (os() & config.os()) == 0) + return false; + if (config.gpu_vendor().size() > 0) { + bool contained = false; + for (size_t i = 0; i < config.gpu_vendor().size(); ++i) { + if (config.gpu_vendor()[i] == gpu_vendor()[0]) { + contained = true; + break; + } + } + if (!contained) + return false; + } + if (config.gpu_device_id() != 0 && + gpu_device_id() != config.gpu_device_id()) + return false; + if (config.build_type() != kBuildTypeUnknown && + (build_type() & config.build_type()) == 0) + return false; + return true; +} + +bool GPUTestBotConfig::Matches(const std::string& config_data) const { + GPUTestExpectationsParser parser; + GPUTestConfig config; + + if (!parser.ParseConfig(config_data, &config)) + return false; + return Matches(config); +} + +bool GPUTestBotConfig::LoadCurrentConfig(const GPUInfo* gpu_info) { + bool rt; + if (gpu_info == NULL) { + GPUInfo my_gpu_info; + GpuIDResult result; + result = CollectGpuID(&my_gpu_info.gpu.vendor_id, + &my_gpu_info.gpu.device_id); + if (result == kGpuIDNotSupported) { + DisableGPUInfoValidation(); + rt = true; + } else { + rt = SetGPUInfo(my_gpu_info); + } + } else { + rt = SetGPUInfo(*gpu_info); + } + set_os(GetCurrentOS()); + if (os() == kOsUnknown) + rt = false; +#if defined(NDEBUG) + set_build_type(kBuildTypeRelease); +#else + set_build_type(kBuildTypeDebug); +#endif + return rt; +} + +// static +bool GPUTestBotConfig::CurrentConfigMatches(const std::string& config_data) { + GPUTestBotConfig my_config; + if (!my_config.LoadCurrentConfig(NULL)) + return false; + return my_config.Matches(config_data); +} + +// static +bool GPUTestBotConfig::CurrentConfigMatches( + const std::vector<std::string>& configs) { + GPUTestBotConfig my_config; + if (!my_config.LoadCurrentConfig(NULL)) + return false; + for (size_t i = 0 ; i < configs.size(); ++i) { + if (my_config.Matches(configs[i])) + return true; + } + return false; +} + +} // namespace gpu + diff --git a/gpu/config/gpu_test_config.h b/gpu/config/gpu_test_config.h new file mode 100644 index 0000000..3c7b038 --- /dev/null +++ b/gpu/config/gpu_test_config.h @@ -0,0 +1,124 @@ +// 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. + +#ifndef GPU_CONFIG_GPU_TEST_CONFIG_H_ +#define GPU_CONFIG_GPU_TEST_CONFIG_H_ + +#include <string> +#include <vector> + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "gpu/gpu_export.h" + +namespace gpu { + +struct GPUInfo; + +class GPU_EXPORT GPUTestConfig { + public: + enum OS { + kOsUnknown = 0, + kOsWinXP = 1 << 0, + kOsWinVista = 1 << 1, + kOsWin7 = 1 << 2, + kOsWin8 = 1 << 3, + kOsWin = kOsWinXP | kOsWinVista | kOsWin7 | kOsWin8, + kOsMacLeopard = 1 << 4, + kOsMacSnowLeopard = 1 << 5, + kOsMacLion = 1 << 6, + kOsMacMountainLion = 1 << 7, + kOsMac = kOsMacLeopard | kOsMacSnowLeopard | kOsMacLion | + kOsMacMountainLion, + kOsLinux = 1 << 8, + kOsChromeOS = 1 << 9, + kOsAndroid = 1 << 10, + }; + + enum BuildType { + kBuildTypeUnknown = 0, + kBuildTypeRelease = 1 << 0, + kBuildTypeDebug = 1 << 1, + }; + + GPUTestConfig(); + virtual ~GPUTestConfig(); + + void set_os(int32 os); + void set_gpu_device_id(uint32 id); + void set_build_type(int32 build_type); + + virtual void AddGPUVendor(uint32 gpu_vendor); + + int32 os() const { return os_; } + const std::vector<uint32>& gpu_vendor() const { return gpu_vendor_; } + uint32 gpu_device_id() const { return gpu_device_id_; } + int32 build_type() const { return build_type_; } + + // Check if the config is valid. For example, if gpu_device_id_ is set, but + // gpu_vendor_ is unknown, then it's invalid. + virtual bool IsValid() const; + + // Check if two configs overlap, i.e., if there exists a config that matches + // both configs. + bool OverlapsWith(const GPUTestConfig& config) const; + + // Disable validation of GPU vendor and device ids. + void DisableGPUInfoValidation(); + + protected: + void ClearGPUVendor(); + + // Indicates that the OS has the notion of a numeric GPU vendor and device id + // and this data should be validated. + bool validate_gpu_info_; + + private: + // operating system. + int32 os_; + + // GPU vendor. + std::vector<uint32> gpu_vendor_; + + // GPU device id (unique to each vendor). + uint32 gpu_device_id_; + + // Release or Debug. + int32 build_type_; +}; + +class GPU_EXPORT GPUTestBotConfig : public GPUTestConfig { + public: + GPUTestBotConfig() { } + virtual ~GPUTestBotConfig(); + + // This should only be called when no gpu_vendor is added. + virtual void AddGPUVendor(uint32 gpu_vendor) OVERRIDE; + + // Return false if gpu_info does not have valid vendor_id and device_id. + bool SetGPUInfo(const GPUInfo& gpu_info); + + // Check if the bot config is valid, i.e., if it is one valid test-bot + // environment. For example, if a field is unknown, or if OS is not one + // fully defined OS, then it's valid. + virtual bool IsValid() const OVERRIDE; + + // Check if a bot config matches a test config, i.e., the test config is a + // superset of the bot config. + bool Matches(const GPUTestConfig& config) const; + bool Matches(const std::string& config_data) const; + + // Setup the config with the current gpu testing environment. + // If gpu_info is NULL, collect GPUInfo first. + bool LoadCurrentConfig(const GPUInfo* gpu_info); + + // Check if this bot's config matches |config_data| or any of the |configs|. + static bool CurrentConfigMatches(const std::string& config_data); + static bool CurrentConfigMatches(const std::vector<std::string>& configs); +}; + +} // namespace gpu + +#endif // GPU_CONFIG_GPU_TEST_CONFIG_H_ + diff --git a/gpu/config/gpu_test_config_unittest.cc b/gpu/config/gpu_test_config_unittest.cc new file mode 100644 index 0000000..b9411dc --- /dev/null +++ b/gpu/config/gpu_test_config_unittest.cc @@ -0,0 +1,255 @@ +// 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 "gpu/config/gpu_info.h" +#include "gpu/config/gpu_test_config.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace gpu { + +class GPUTestConfigTest : public testing::Test { + public: + GPUTestConfigTest() { } + + virtual ~GPUTestConfigTest() { } + + protected: + virtual void SetUp() { } + + virtual void TearDown() { } +}; + +TEST_F(GPUTestConfigTest, EmptyValues) { + GPUTestConfig config; + EXPECT_EQ(GPUTestConfig::kOsUnknown, config.os()); + EXPECT_EQ(0u, config.gpu_vendor().size()); + EXPECT_EQ(0u, config.gpu_device_id()); + EXPECT_EQ(GPUTestConfig::kBuildTypeUnknown, config.build_type()); +} + +TEST_F(GPUTestConfigTest, SetGPUInfo) { + GPUInfo gpu_info; + gpu_info.gpu.vendor_id = 0x10de; + gpu_info.gpu.device_id = 0x0640; + GPUTestBotConfig config; + EXPECT_TRUE(config.SetGPUInfo(gpu_info)); + EXPECT_EQ(1u, config.gpu_vendor().size()); + EXPECT_EQ(gpu_info.gpu.vendor_id, config.gpu_vendor()[0]); + EXPECT_EQ(gpu_info.gpu.device_id, config.gpu_device_id()); + + gpu_info.gpu.vendor_id = 0x8086; + gpu_info.gpu.device_id = 0x0046; + EXPECT_TRUE(config.SetGPUInfo(gpu_info)); + EXPECT_EQ(1u, config.gpu_vendor().size()); + EXPECT_EQ(gpu_info.gpu.vendor_id, config.gpu_vendor()[0]); + EXPECT_EQ(gpu_info.gpu.device_id, config.gpu_device_id()); +} + +TEST_F(GPUTestConfigTest, IsValid) { + { + GPUTestConfig config; + config.set_gpu_device_id(0x0640); + EXPECT_FALSE(config.IsValid()); + config.AddGPUVendor(0x10de); + EXPECT_TRUE(config.IsValid()); + } + + { + GPUTestBotConfig config; + config.set_build_type(GPUTestConfig::kBuildTypeRelease); + config.set_os(GPUTestConfig::kOsWin7); + config.set_gpu_device_id(0x0640); + EXPECT_FALSE(config.IsValid()); + config.AddGPUVendor(0x10de); + EXPECT_TRUE(config.IsValid()); + + config.set_gpu_device_id(0); + EXPECT_FALSE(config.IsValid()); + config.set_gpu_device_id(0x0640); + EXPECT_TRUE(config.IsValid()); + + config.set_os(GPUTestConfig::kOsWin); + EXPECT_FALSE(config.IsValid()); + config.set_os(GPUTestConfig::kOsWin7 | GPUTestConfig::kOsWinXP); + EXPECT_FALSE(config.IsValid()); + config.set_os(GPUTestConfig::kOsWin7); + EXPECT_TRUE(config.IsValid()); + + config.set_build_type(GPUTestConfig::kBuildTypeUnknown); + EXPECT_FALSE(config.IsValid()); + config.set_build_type(GPUTestConfig::kBuildTypeRelease); + EXPECT_TRUE(config.IsValid()); + } +} + +TEST_F(GPUTestConfigTest, Matches) { + GPUTestBotConfig config; + config.set_os(GPUTestConfig::kOsWin7); + config.set_build_type(GPUTestConfig::kBuildTypeRelease); + config.AddGPUVendor(0x10de); + config.set_gpu_device_id(0x0640); + EXPECT_TRUE(config.IsValid()); + + { // os matching + GPUTestConfig config2; + EXPECT_TRUE(config.Matches(config2)); + config2.set_os(GPUTestConfig::kOsWin); + EXPECT_TRUE(config.Matches(config2)); + config2.set_os(GPUTestConfig::kOsWin7); + EXPECT_TRUE(config.Matches(config2)); + config2.set_os(GPUTestConfig::kOsMac); + EXPECT_FALSE(config.Matches(config2)); + config2.set_os(GPUTestConfig::kOsWin7 | GPUTestConfig::kOsLinux); + EXPECT_TRUE(config.Matches(config2)); + } + + { // gpu vendor matching + { + GPUTestConfig config2; + config2.AddGPUVendor(0x10de); + EXPECT_TRUE(config.Matches(config2)); + config2.AddGPUVendor(0x1004); + EXPECT_TRUE(config.Matches(config2)); + } + { + GPUTestConfig config2; + config2.AddGPUVendor(0x8086); + EXPECT_FALSE(config.Matches(config2)); + } + } + + { // build type matching + GPUTestConfig config2; + config2.set_build_type(GPUTestConfig::kBuildTypeRelease); + EXPECT_TRUE(config.Matches(config2)); + config2.set_build_type(GPUTestConfig::kBuildTypeRelease | + GPUTestConfig::kBuildTypeDebug); + EXPECT_TRUE(config.Matches(config2)); + config2.set_build_type(GPUTestConfig::kBuildTypeDebug); + EXPECT_FALSE(config.Matches(config2)); + } + + { // exact matching + GPUTestConfig config2; + config2.set_os(GPUTestConfig::kOsWin7); + config2.set_build_type(GPUTestConfig::kBuildTypeRelease); + config2.AddGPUVendor(0x10de); + config2.set_gpu_device_id(0x0640); + EXPECT_TRUE(config.Matches(config2)); + config2.set_gpu_device_id(0x0641); + EXPECT_FALSE(config.Matches(config2)); + } +} + +TEST_F(GPUTestConfigTest, StringMatches) { + GPUTestBotConfig config; + config.set_os(GPUTestConfig::kOsWin7); + config.set_build_type(GPUTestConfig::kBuildTypeRelease); + config.AddGPUVendor(0x10de); + config.set_gpu_device_id(0x0640); + EXPECT_TRUE(config.IsValid()); + + EXPECT_TRUE(config.Matches(std::string())); + + // os matching + EXPECT_TRUE(config.Matches("WIN")); + EXPECT_TRUE(config.Matches("WIN7")); + EXPECT_FALSE(config.Matches("MAC")); + EXPECT_TRUE(config.Matches("WIN7 LINUX")); + + // gpu vendor matching + EXPECT_TRUE(config.Matches("NVIDIA")); + EXPECT_TRUE(config.Matches("NVIDIA AMD")); + EXPECT_FALSE(config.Matches("INTEL")); + + // build type matching + EXPECT_TRUE(config.Matches("RELEASE")); + EXPECT_TRUE(config.Matches("RELEASE DEBUG")); + EXPECT_FALSE(config.Matches("DEBUG")); + + // exact matching + EXPECT_TRUE(config.Matches("WIN7 RELEASE NVIDIA 0X0640")); + EXPECT_FALSE(config.Matches("WIN7 RELEASE NVIDIA 0X0641")); +} + +TEST_F(GPUTestConfigTest, OverlapsWith) { + { // os + // win vs win7 + GPUTestConfig config; + config.set_os(GPUTestConfig::kOsWin); + GPUTestConfig config2; + config2.set_os(GPUTestConfig::kOsWin7); + EXPECT_TRUE(config.OverlapsWith(config2)); + EXPECT_TRUE(config2.OverlapsWith(config)); + // win vs win7+linux + config2.set_os(GPUTestConfig::kOsWin7 | GPUTestConfig::kOsLinux); + EXPECT_TRUE(config.OverlapsWith(config2)); + EXPECT_TRUE(config2.OverlapsWith(config)); + // win vs mac + config2.set_os(GPUTestConfig::kOsMac); + EXPECT_FALSE(config.OverlapsWith(config2)); + EXPECT_FALSE(config2.OverlapsWith(config)); + // win vs unknown + config2.set_os(GPUTestConfig::kOsUnknown); + EXPECT_TRUE(config.OverlapsWith(config2)); + EXPECT_TRUE(config2.OverlapsWith(config)); + } + + { // gpu vendor + GPUTestConfig config; + config.AddGPUVendor(0x10de); + // nvidia vs unknown + GPUTestConfig config2; + EXPECT_TRUE(config.OverlapsWith(config2)); + EXPECT_TRUE(config2.OverlapsWith(config)); + // nvidia vs intel + config2.AddGPUVendor(0x1086); + EXPECT_FALSE(config.OverlapsWith(config2)); + EXPECT_FALSE(config2.OverlapsWith(config)); + // nvidia vs nvidia+intel + config2.AddGPUVendor(0x10de); + EXPECT_TRUE(config.OverlapsWith(config2)); + EXPECT_TRUE(config2.OverlapsWith(config)); + } + + { // build type + // release vs debug + GPUTestConfig config; + config.set_build_type(GPUTestConfig::kBuildTypeRelease); + GPUTestConfig config2; + config2.set_build_type(GPUTestConfig::kBuildTypeDebug); + EXPECT_FALSE(config.OverlapsWith(config2)); + EXPECT_FALSE(config2.OverlapsWith(config)); + // release vs release+debug + config2.set_build_type(GPUTestConfig::kBuildTypeRelease | + GPUTestConfig::kBuildTypeDebug); + EXPECT_TRUE(config.OverlapsWith(config2)); + EXPECT_TRUE(config2.OverlapsWith(config)); + // release vs unknown + config2.set_build_type(GPUTestConfig::kBuildTypeUnknown); + EXPECT_TRUE(config.OverlapsWith(config2)); + EXPECT_TRUE(config2.OverlapsWith(config)); + } + + { // win7 vs nvidia + GPUTestConfig config; + config.set_os(GPUTestConfig::kOsWin7); + GPUTestConfig config2; + config2.AddGPUVendor(0x10de); + EXPECT_TRUE(config.OverlapsWith(config2)); + EXPECT_TRUE(config2.OverlapsWith(config)); + } +} + +TEST_F(GPUTestConfigTest, LoadCurrentConfig) { + GPUTestBotConfig config; + GPUInfo gpu_info; + gpu_info.gpu.vendor_id = 0x10de; + gpu_info.gpu.device_id = 0x0640; + EXPECT_TRUE(config.LoadCurrentConfig(&gpu_info)); + EXPECT_TRUE(config.IsValid()); +} + +} // namespace gpu + diff --git a/gpu/config/gpu_test_expectations_parser.cc b/gpu/config/gpu_test_expectations_parser.cc new file mode 100644 index 0000000..8cc2b3c --- /dev/null +++ b/gpu/config/gpu_test_expectations_parser.cc @@ -0,0 +1,503 @@ +// 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 "gpu/config/gpu_test_expectations_parser.h" + +#include "base/file_util.h" +#include "base/logging.h" +#include "base/string_number_conversions.h" +#include "base/string_util.h" +#include "base/stringprintf.h" +#include "base/strings/string_split.h" + +namespace gpu { + +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); +} + +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())); +} + +GPUTestExpectationsParser:: GPUTestExpectationEntry::GPUTestExpectationEntry() + : test_expectation(0), + line_number(0) { +} + +} // namespace gpu + diff --git a/gpu/config/gpu_test_expectations_parser.h b/gpu/config/gpu_test_expectations_parser.h new file mode 100644 index 0000000..a69f7e9 --- /dev/null +++ b/gpu/config/gpu_test_expectations_parser.h @@ -0,0 +1,88 @@ +// 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. + +#ifndef GPU_CONFIG_GPU_TEST_EXPECTATIONS_PARSER_H_ +#define GPU_CONFIG_GPU_TEST_EXPECTATIONS_PARSER_H_ + +#include <string> +#include <vector> + +#include "base/basictypes.h" +#include "base/files/file_path.h" +#include "gpu/config/gpu_test_config.h" +#include "gpu/gpu_export.h" + +namespace gpu { + +class GPU_EXPORT GPUTestExpectationsParser { + public: + enum GPUTestExpectation { + kGpuTestPass = 1 << 0, + kGpuTestFail = 1 << 1, + kGpuTestFlaky = 1 << 2, + kGpuTestTimeout = 1 << 3, + kGpuTestSkip = 1 << 4, + }; + + GPUTestExpectationsParser(); + ~GPUTestExpectationsParser(); + + // Parse the text expectations, and if no error is encountered, + // save all the entries. Otherwise, generate error messages. + // Return true if parsing succeeds. + bool LoadTestExpectations(const std::string& data); + bool LoadTestExpectations(const base::FilePath& path); + + // Query error messages from the last LoadTestExpectations() call. + const std::vector<std::string>& GetErrorMessages() const; + + // Get the test expectation of a given test on a given bot. + int32 GetTestExpectation(const std::string& test_name, + const GPUTestBotConfig& bot_config) const; + + // Parse a list of config modifiers. If we have a valid entry with no + // conflicts, | config | stores it, and the function returns true. + bool ParseConfig(const std::string& config_data, GPUTestConfig* config); + + private: + struct GPUTestExpectationEntry { + GPUTestExpectationEntry(); + + std::string test_name; + GPUTestConfig test_config; + int32 test_expectation; + size_t line_number; + }; + + // Parse a line of text. If we have a valid entry, save it; otherwise, + // generate error messages. + bool ParseLine(const std::string& line_data, size_t line_number); + + // Update OS/GPUVendor/BuildType modifiers. May generate an error message. + bool UpdateTestConfig( + GPUTestConfig* config, int32 token, size_t line_number); + + // Update GPUDeviceID modifier. May generate an error message. + bool UpdateTestConfig(GPUTestConfig* config, + const std::string & gpu_device_id, + size_t line_number); + + // Check if two entries' config overlap with each other. May generate an + // error message. + bool DetectConflictsBetweenEntries(); + + // Save an error message, which can be queried later. + void PushErrorMessage(const std::string& message, size_t line_number); + void PushErrorMessage(const std::string& message, + size_t entry1_line_number, + size_t entry2_line_number); + + std::vector<GPUTestExpectationEntry> entries_; + std::vector<std::string> error_messages_; +}; + +} // namespace gpu + +#endif // GPU_CONFIG_GPU_TEST_EXPECTATIONS_PARSER_H_ + diff --git a/gpu/config/gpu_test_expectations_parser_unittest.cc b/gpu/config/gpu_test_expectations_parser_unittest.cc new file mode 100644 index 0000000..79c169c --- /dev/null +++ b/gpu/config/gpu_test_expectations_parser_unittest.cc @@ -0,0 +1,245 @@ +// 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 "base/logging.h" +#include "gpu/config/gpu_test_expectations_parser.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace gpu { + +class GPUTestExpectationsParserTest : public testing::Test { + public: + GPUTestExpectationsParserTest() { } + + virtual ~GPUTestExpectationsParserTest() { } + + const GPUTestBotConfig& bot_config() const { + return bot_config_; + } + + protected: + virtual void SetUp() { + bot_config_.set_os(GPUTestConfig::kOsWin7); + bot_config_.set_build_type(GPUTestConfig::kBuildTypeRelease); + bot_config_.AddGPUVendor(0x10de); + bot_config_.set_gpu_device_id(0x0640); + ASSERT_TRUE(bot_config_.IsValid()); + } + + virtual void TearDown() { } + + private: + GPUTestBotConfig bot_config_; +}; + +TEST_F(GPUTestExpectationsParserTest, CommentOnly) { + const std::string text = + " \n" + "// This is just some comment\n" + ""; + GPUTestExpectationsParser parser; + EXPECT_TRUE(parser.LoadTestExpectations(text)); + EXPECT_EQ(0u, parser.GetErrorMessages().size()); + EXPECT_EQ(GPUTestExpectationsParser::kGpuTestPass, + parser.GetTestExpectation("some_test", bot_config())); +} + +TEST_F(GPUTestExpectationsParserTest, ValidFullEntry) { + const std::string text = + "BUG12345 WIN7 RELEASE NVIDIA 0x0640 : MyTest = FAIL"; + + GPUTestExpectationsParser parser; + EXPECT_TRUE(parser.LoadTestExpectations(text)); + EXPECT_EQ(0u, parser.GetErrorMessages().size()); + EXPECT_EQ(GPUTestExpectationsParser::kGpuTestFail, + parser.GetTestExpectation("MyTest", bot_config())); +} + +TEST_F(GPUTestExpectationsParserTest, ValidPartialEntry) { + const std::string text = + "BUG12345 WIN NVIDIA : MyTest = TIMEOUT"; + + GPUTestExpectationsParser parser; + EXPECT_TRUE(parser.LoadTestExpectations(text)); + EXPECT_EQ(0u, parser.GetErrorMessages().size()); + EXPECT_EQ(GPUTestExpectationsParser::kGpuTestTimeout, + parser.GetTestExpectation("MyTest", bot_config())); +} + +TEST_F(GPUTestExpectationsParserTest, ValidUnrelatedOsEntry) { + const std::string text = + "BUG12345 LEOPARD : MyTest = TIMEOUT"; + + GPUTestExpectationsParser parser; + EXPECT_TRUE(parser.LoadTestExpectations(text)); + EXPECT_EQ(0u, parser.GetErrorMessages().size()); + EXPECT_EQ(GPUTestExpectationsParser::kGpuTestPass, + parser.GetTestExpectation("MyTest", bot_config())); +} + +TEST_F(GPUTestExpectationsParserTest, ValidUnrelatedTestEntry) { + const std::string text = + "BUG12345 WIN7 RELEASE NVIDIA 0x0640 : AnotherTest = FAIL"; + + GPUTestExpectationsParser parser; + EXPECT_TRUE(parser.LoadTestExpectations(text)); + EXPECT_EQ(0u, parser.GetErrorMessages().size()); + EXPECT_EQ(GPUTestExpectationsParser::kGpuTestPass, + parser.GetTestExpectation("MyTest", bot_config())); +} + +TEST_F(GPUTestExpectationsParserTest, AllModifiers) { + const std::string text = + "BUG12345 XP VISTA WIN7 WIN8 LEOPARD SNOWLEOPARD LION MOUNTAINLION " + "LINUX CHROMEOS ANDROID " + "NVIDIA INTEL AMD VMWARE RELEASE DEBUG : MyTest = " + "PASS FAIL FLAKY TIMEOUT SKIP"; + + GPUTestExpectationsParser parser; + EXPECT_TRUE(parser.LoadTestExpectations(text)); + EXPECT_EQ(0u, parser.GetErrorMessages().size()); + EXPECT_EQ(GPUTestExpectationsParser::kGpuTestPass | + GPUTestExpectationsParser::kGpuTestFail | + GPUTestExpectationsParser::kGpuTestFlaky | + GPUTestExpectationsParser::kGpuTestTimeout | + GPUTestExpectationsParser::kGpuTestSkip, + parser.GetTestExpectation("MyTest", bot_config())); +} + +TEST_F(GPUTestExpectationsParserTest, DuplicateModifiers) { + const std::string text = + "BUG12345 WIN7 WIN7 RELEASE NVIDIA 0x0640 : MyTest = FAIL"; + + GPUTestExpectationsParser parser; + EXPECT_FALSE(parser.LoadTestExpectations(text)); + EXPECT_NE(0u, parser.GetErrorMessages().size()); +} + +TEST_F(GPUTestExpectationsParserTest, AllModifiersLowerCase) { + const std::string text = + "BUG12345 xp vista win7 leopard snowleopard lion linux chromeos android " + "nvidia intel amd vmware release debug : MyTest = " + "pass fail flaky timeout skip"; + + GPUTestExpectationsParser parser; + EXPECT_TRUE(parser.LoadTestExpectations(text)); + EXPECT_EQ(0u, parser.GetErrorMessages().size()); + EXPECT_EQ(GPUTestExpectationsParser::kGpuTestPass | + GPUTestExpectationsParser::kGpuTestFail | + GPUTestExpectationsParser::kGpuTestFlaky | + GPUTestExpectationsParser::kGpuTestTimeout | + GPUTestExpectationsParser::kGpuTestSkip, + parser.GetTestExpectation("MyTest", bot_config())); +} + +TEST_F(GPUTestExpectationsParserTest, MissingColon) { + const std::string text = + "BUG12345 XP MyTest = FAIL"; + + GPUTestExpectationsParser parser; + EXPECT_FALSE(parser.LoadTestExpectations(text)); + EXPECT_NE(0u, parser.GetErrorMessages().size()); +} + +TEST_F(GPUTestExpectationsParserTest, MissingEqual) { + const std::string text = + "BUG12345 XP : MyTest FAIL"; + + GPUTestExpectationsParser parser; + EXPECT_FALSE(parser.LoadTestExpectations(text)); + EXPECT_NE(0u, parser.GetErrorMessages().size()); +} + +TEST_F(GPUTestExpectationsParserTest, IllegalModifier) { + const std::string text = + "BUG12345 XP XXX : MyTest = FAIL"; + + GPUTestExpectationsParser parser; + EXPECT_FALSE(parser.LoadTestExpectations(text)); + EXPECT_NE(0u, parser.GetErrorMessages().size()); +} + +TEST_F(GPUTestExpectationsParserTest, OsConflicts) { + const std::string text = + "BUG12345 XP WIN : MyTest = FAIL"; + + GPUTestExpectationsParser parser; + EXPECT_FALSE(parser.LoadTestExpectations(text)); + EXPECT_NE(0u, parser.GetErrorMessages().size()); +} + +TEST_F(GPUTestExpectationsParserTest, InvalidModifierCombination) { + const std::string text = + "BUG12345 XP NVIDIA INTEL 0x0640 : MyTest = FAIL"; + + GPUTestExpectationsParser parser; + EXPECT_FALSE(parser.LoadTestExpectations(text)); + EXPECT_NE(0u, parser.GetErrorMessages().size()); +} + +TEST_F(GPUTestExpectationsParserTest, BadGpuDeviceID) { + const std::string text = + "BUG12345 XP NVIDIA 0xU07X : MyTest = FAIL"; + + GPUTestExpectationsParser parser; + EXPECT_FALSE(parser.LoadTestExpectations(text)); + EXPECT_NE(0u, parser.GetErrorMessages().size()); +} + +TEST_F(GPUTestExpectationsParserTest, MoreThanOneGpuDeviceID) { + const std::string text = + "BUG12345 XP NVIDIA 0x0640 0x0641 : MyTest = FAIL"; + + GPUTestExpectationsParser parser; + EXPECT_FALSE(parser.LoadTestExpectations(text)); + EXPECT_NE(0u, parser.GetErrorMessages().size()); +} + +TEST_F(GPUTestExpectationsParserTest, MultipleEntriesConflicts) { + const std::string text = + "BUG12345 WIN7 RELEASE NVIDIA 0x0640 : MyTest = FAIL\n" + "BUG12345 WIN : MyTest = FAIL"; + + GPUTestExpectationsParser parser; + EXPECT_FALSE(parser.LoadTestExpectations(text)); + EXPECT_NE(0u, parser.GetErrorMessages().size()); +} + +TEST_F(GPUTestExpectationsParserTest, MultipleTests) { + const std::string text = + "BUG12345 WIN7 RELEASE NVIDIA 0x0640 : MyTest = FAIL\n" + "BUG12345 WIN : AnotherTest = FAIL"; + + GPUTestExpectationsParser parser; + EXPECT_TRUE(parser.LoadTestExpectations(text)); + EXPECT_EQ(0u, parser.GetErrorMessages().size()); +} + +TEST_F(GPUTestExpectationsParserTest, ValidMultipleEntries) { + const std::string text = + "BUG12345 WIN7 RELEASE NVIDIA 0x0640 : MyTest = FAIL\n" + "BUG12345 LINUX : MyTest = TIMEOUT"; + + GPUTestExpectationsParser parser; + EXPECT_TRUE(parser.LoadTestExpectations(text)); + EXPECT_EQ(0u, parser.GetErrorMessages().size()); + EXPECT_EQ(GPUTestExpectationsParser::kGpuTestFail, + parser.GetTestExpectation("MyTest", bot_config())); +} + +TEST_F(GPUTestExpectationsParserTest, StarMatching) { + const std::string text = + "BUG12345 WIN7 RELEASE NVIDIA 0x0640 : MyTest* = FAIL"; + + GPUTestExpectationsParser parser; + EXPECT_TRUE(parser.LoadTestExpectations(text)); + EXPECT_EQ(0u, parser.GetErrorMessages().size()); + EXPECT_EQ(GPUTestExpectationsParser::kGpuTestFail, + parser.GetTestExpectation("MyTest0", bot_config())); + EXPECT_EQ(GPUTestExpectationsParser::kGpuTestPass, + parser.GetTestExpectation("OtherTest", bot_config())); +} + +} // namespace gpu + diff --git a/gpu/gpu.gyp b/gpu/gpu.gyp index 78c44c2..9c72995 100644 --- a/gpu/gpu.gyp +++ b/gpu/gpu.gyp @@ -218,6 +218,8 @@ 'config/gpu_info_collector_unittest.cc', 'config/gpu_info_unittest.cc', 'config/gpu_switching_list_unittest.cc', + 'config/gpu_test_config_unittest.cc', + 'config/gpu_test_expectations_parser_unittest.cc', 'config/gpu_util_unittest.cc', ], 'conditions': [ diff --git a/gpu/gpu_config.gypi b/gpu/gpu_config.gypi index 5c33f91..7ea4b56 100644 --- a/gpu/gpu_config.gypi +++ b/gpu/gpu_config.gypi @@ -38,6 +38,10 @@ 'config/gpu_switching_list.cc', 'config/gpu_switching_list.h', 'config/gpu_switching_option.h', + 'config/gpu_test_config.cc', + 'config/gpu_test_config.h', + 'config/gpu_test_expectations_parser.cc', + 'config/gpu_test_expectations_parser.h', 'config/gpu_util.cc', 'config/gpu_util.h', 'config/software_rendering_list_json.cc', |