1 // Copyright (c) 2013 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.
5 #include "base/json/json_reader.h"
6 #include "gpu/config/gpu_control_list.h"
7 #include "gpu/config/gpu_info.h"
8 #include "testing/gtest/include/gtest/gtest.h"
10 #define LONG_STRING_CONST(...) #__VA_ARGS__
14 enum TestFeatureType {
20 class GpuControlListEntryTest : public testing::Test {
22 GpuControlListEntryTest() { }
23 virtual ~GpuControlListEntryTest() { }
25 const GPUInfo& gpu_info() const {
29 typedef GpuControlList::ScopedGpuControlListEntry ScopedEntry;
31 static ScopedEntry GetEntryFromString(
32 const std::string& json, bool supports_feature_type_all) {
33 scoped_ptr<base::Value> root;
34 root.reset(base::JSONReader::Read(json));
35 base::DictionaryValue* value = NULL;
36 if (root.get() == NULL || !root->GetAsDictionary(&value))
39 GpuControlList::FeatureMap feature_map;
40 feature_map["test_feature_0"] = TEST_FEATURE_0;
41 feature_map["test_feature_1"] = TEST_FEATURE_1;
42 feature_map["test_feature_2"] = TEST_FEATURE_2;
44 return GpuControlList::GpuControlListEntry::GetEntryFromValue(
45 value, true, feature_map, supports_feature_type_all);
48 static ScopedEntry GetEntryFromString(const std::string& json) {
49 return GetEntryFromString(json, false);
52 virtual void SetUp() {
53 gpu_info_.gpu.vendor_id = 0x10de;
54 gpu_info_.gpu.device_id = 0x0640;
55 gpu_info_.gpu.active = true;
56 gpu_info_.driver_vendor = "NVIDIA";
57 gpu_info_.driver_version = "1.6.18";
58 gpu_info_.driver_date = "7-14-2009";
59 gpu_info_.machine_model = "MacBookPro 7.1";
60 gpu_info_.gl_vendor = "NVIDIA Corporation";
61 gpu_info_.gl_renderer = "NVIDIA GeForce GT 120 OpenGL Engine";
62 gpu_info_.performance_stats.graphics = 5.0;
63 gpu_info_.performance_stats.gaming = 5.0;
64 gpu_info_.performance_stats.overall = 5.0;
71 TEST_F(GpuControlListEntryTest, DetailedEntry) {
72 const std::string json = LONG_STRING_CONST(
75 "description": "test entry",
76 "cr_bugs": [1024, 678],
77 "webkit_bugs": [1950],
85 "vendor_id": "0x10de",
86 "device_id": ["0x0640"],
97 ScopedEntry entry(GetEntryFromString(json));
98 EXPECT_TRUE(entry.get() != NULL);
99 EXPECT_EQ(GpuControlList::kOsMacosx, entry->GetOsType());
100 EXPECT_FALSE(entry->disabled());
101 EXPECT_EQ(5u, entry->id());
102 EXPECT_STREQ("test entry", entry->description().c_str());
103 EXPECT_EQ(2u, entry->cr_bugs().size());
104 EXPECT_EQ(1024, entry->cr_bugs()[0]);
105 EXPECT_EQ(678, entry->cr_bugs()[1]);
106 EXPECT_EQ(1u, entry->webkit_bugs().size());
107 EXPECT_EQ(1950, entry->webkit_bugs()[0]);
108 EXPECT_EQ(1u, entry->features().size());
109 EXPECT_EQ(1u, entry->features().count(TEST_FEATURE_0));
110 EXPECT_FALSE(entry->NeedsMoreInfo(gpu_info()));
111 EXPECT_TRUE(entry->Contains(
112 GpuControlList::kOsMacosx, "10.6.4", gpu_info()));
115 TEST_F(GpuControlListEntryTest, VendorOnAllOsEntry) {
116 const std::string json = LONG_STRING_CONST(
119 "vendor_id": "0x10de",
125 ScopedEntry entry(GetEntryFromString(json));
126 EXPECT_TRUE(entry.get() != NULL);
127 EXPECT_EQ(GpuControlList::kOsAny, entry->GetOsType());
129 const GpuControlList::OsType os_type[] = {
130 GpuControlList::kOsMacosx,
131 GpuControlList::kOsWin,
132 GpuControlList::kOsLinux,
133 GpuControlList::kOsChromeOS,
134 GpuControlList::kOsAndroid
136 for (size_t i = 0; i < arraysize(os_type); ++i)
137 EXPECT_TRUE(entry->Contains(os_type[i], "10.6", gpu_info()));
140 TEST_F(GpuControlListEntryTest, VendorOnLinuxEntry) {
141 const std::string json = LONG_STRING_CONST(
147 "vendor_id": "0x10de",
153 ScopedEntry entry(GetEntryFromString(json));
154 EXPECT_TRUE(entry.get() != NULL);
155 EXPECT_EQ(GpuControlList::kOsLinux, entry->GetOsType());
157 const GpuControlList::OsType os_type[] = {
158 GpuControlList::kOsMacosx,
159 GpuControlList::kOsWin,
160 GpuControlList::kOsChromeOS,
161 GpuControlList::kOsAndroid
163 for (size_t i = 0; i < arraysize(os_type); ++i)
164 EXPECT_FALSE(entry->Contains(os_type[i], "10.6", gpu_info()));
165 EXPECT_TRUE(entry->Contains(
166 GpuControlList::kOsLinux, "10.6", gpu_info()));
169 TEST_F(GpuControlListEntryTest, AllExceptNVidiaOnLinuxEntry) {
170 const std::string json = LONG_STRING_CONST(
178 "vendor_id": "0x10de"
186 ScopedEntry entry(GetEntryFromString(json));
187 EXPECT_TRUE(entry.get() != NULL);
188 EXPECT_EQ(GpuControlList::kOsLinux, entry->GetOsType());
190 const GpuControlList::OsType os_type[] = {
191 GpuControlList::kOsMacosx,
192 GpuControlList::kOsWin,
193 GpuControlList::kOsLinux,
194 GpuControlList::kOsChromeOS,
195 GpuControlList::kOsAndroid
197 for (size_t i = 0; i < arraysize(os_type); ++i)
198 EXPECT_FALSE(entry->Contains(os_type[i], "10.6", gpu_info()));
201 TEST_F(GpuControlListEntryTest, AllExceptIntelOnLinuxEntry) {
202 const std::string json = LONG_STRING_CONST(
210 "vendor_id": "0x8086"
218 ScopedEntry entry(GetEntryFromString(json));
219 EXPECT_TRUE(entry.get() != NULL);
220 EXPECT_EQ(GpuControlList::kOsLinux, entry->GetOsType());
222 const GpuControlList::OsType os_type[] = {
223 GpuControlList::kOsMacosx,
224 GpuControlList::kOsWin,
225 GpuControlList::kOsChromeOS,
226 GpuControlList::kOsAndroid
228 for (size_t i = 0; i < arraysize(os_type); ++i)
229 EXPECT_FALSE(entry->Contains(os_type[i], "10.6", gpu_info()));
230 EXPECT_TRUE(entry->Contains(
231 GpuControlList::kOsLinux, "10.6", gpu_info()));
234 TEST_F(GpuControlListEntryTest, DateOnWindowsEntry) {
235 const std::string json = LONG_STRING_CONST(
250 ScopedEntry entry(GetEntryFromString(json));
251 EXPECT_TRUE(entry.get() != NULL);
252 EXPECT_EQ(GpuControlList::kOsWin, entry->GetOsType());
255 gpu_info.driver_date = "4-12-2010";
256 EXPECT_TRUE(entry->Contains(
257 GpuControlList::kOsWin, "10.6", gpu_info));
258 gpu_info.driver_date = "5-8-2010";
259 EXPECT_FALSE(entry->Contains(
260 GpuControlList::kOsWin, "10.6", gpu_info));
261 gpu_info.driver_date = "5-9-2010";
262 EXPECT_FALSE(entry->Contains(
263 GpuControlList::kOsWin, "10.6", gpu_info));
266 TEST_F(GpuControlListEntryTest, MultipleDevicesEntry) {
267 const std::string json = LONG_STRING_CONST(
270 "vendor_id": "0x10de",
271 "device_id": ["0x1023", "0x0640"],
277 ScopedEntry entry(GetEntryFromString(json));
278 EXPECT_TRUE(entry.get() != NULL);
279 EXPECT_EQ(GpuControlList::kOsAny, entry->GetOsType());
281 const GpuControlList::OsType os_type[] = {
282 GpuControlList::kOsMacosx,
283 GpuControlList::kOsWin,
284 GpuControlList::kOsLinux,
285 GpuControlList::kOsChromeOS,
286 GpuControlList::kOsAndroid
288 for (size_t i = 0; i < arraysize(os_type); ++i)
289 EXPECT_TRUE(entry->Contains(os_type[i], "10.6", gpu_info()));
292 TEST_F(GpuControlListEntryTest, ChromeOSEntry) {
293 const std::string json = LONG_STRING_CONST(
304 ScopedEntry entry(GetEntryFromString(json));
305 EXPECT_TRUE(entry.get() != NULL);
306 EXPECT_EQ(GpuControlList::kOsChromeOS, entry->GetOsType());
308 const GpuControlList::OsType os_type[] = {
309 GpuControlList::kOsMacosx,
310 GpuControlList::kOsWin,
311 GpuControlList::kOsLinux,
312 GpuControlList::kOsAndroid
314 for (size_t i = 0; i < arraysize(os_type); ++i)
315 EXPECT_FALSE(entry->Contains(os_type[i], "10.6", gpu_info()));
316 EXPECT_TRUE(entry->Contains(
317 GpuControlList::kOsChromeOS, "10.6", gpu_info()));
320 TEST_F(GpuControlListEntryTest, MalformedVendor) {
321 const std::string json = LONG_STRING_CONST(
324 "vendor_id": "[0x10de]",
330 ScopedEntry entry(GetEntryFromString(json));
331 EXPECT_TRUE(entry.get() == NULL);
334 TEST_F(GpuControlListEntryTest, UnknownFieldEntry) {
335 const std::string json = LONG_STRING_CONST(
344 ScopedEntry entry(GetEntryFromString(json));
345 EXPECT_TRUE(entry.get() == NULL);
348 TEST_F(GpuControlListEntryTest, UnknownExceptionFieldEntry) {
349 const std::string json = LONG_STRING_CONST(
362 ScopedEntry entry(GetEntryFromString(json));
363 EXPECT_TRUE(entry.get() == NULL);
366 TEST_F(GpuControlListEntryTest, UnknownFeatureEntry) {
367 const std::string json = LONG_STRING_CONST(
371 "some_unknown_feature",
376 ScopedEntry entry(GetEntryFromString(json));
377 EXPECT_TRUE(entry.get() == NULL);
380 TEST_F(GpuControlListEntryTest, GlVendorEntry) {
381 const std::string json = LONG_STRING_CONST(
393 ScopedEntry entry(GetEntryFromString(json));
394 EXPECT_TRUE(entry.get() != NULL);
396 const GpuControlList::OsType os_type[] = {
397 GpuControlList::kOsMacosx,
398 GpuControlList::kOsWin,
399 GpuControlList::kOsLinux,
400 GpuControlList::kOsChromeOS,
401 GpuControlList::kOsAndroid
403 for (size_t i = 0; i < arraysize(os_type); ++i)
404 EXPECT_TRUE(entry->Contains(os_type[i], "10.6", gpu_info()));
407 TEST_F(GpuControlListEntryTest, GlRendererEntry) {
408 const std::string json = LONG_STRING_CONST(
420 ScopedEntry entry(GetEntryFromString(json));
421 EXPECT_TRUE(entry.get() != NULL);
423 const GpuControlList::OsType os_type[] = {
424 GpuControlList::kOsMacosx,
425 GpuControlList::kOsWin,
426 GpuControlList::kOsLinux,
427 GpuControlList::kOsChromeOS,
428 GpuControlList::kOsAndroid
430 for (size_t i = 0; i < arraysize(os_type); ++i)
431 EXPECT_TRUE(entry->Contains(os_type[i], "10.6", gpu_info()));
434 TEST_F(GpuControlListEntryTest, PerfGraphicsEntry) {
435 const std::string json = LONG_STRING_CONST(
447 ScopedEntry entry(GetEntryFromString(json));
448 EXPECT_TRUE(entry.get() != NULL);
449 EXPECT_TRUE(entry->Contains(GpuControlList::kOsWin, "10.6", gpu_info()));
452 TEST_F(GpuControlListEntryTest, PerfGamingEntry) {
453 const std::string json = LONG_STRING_CONST(
465 ScopedEntry entry(GetEntryFromString(json));
466 EXPECT_TRUE(entry.get() != NULL);
467 EXPECT_FALSE(entry->Contains(GpuControlList::kOsWin, "10.6", gpu_info()));
470 TEST_F(GpuControlListEntryTest, PerfOverallEntry) {
471 const std::string json = LONG_STRING_CONST(
484 ScopedEntry entry(GetEntryFromString(json));
485 EXPECT_TRUE(entry.get() != NULL);
486 EXPECT_TRUE(entry->Contains(GpuControlList::kOsWin, "10.6", gpu_info()));
489 TEST_F(GpuControlListEntryTest, DisabledEntry) {
490 const std::string json = LONG_STRING_CONST(
499 ScopedEntry entry(GetEntryFromString(json));
500 EXPECT_TRUE(entry.get() != NULL);
501 EXPECT_TRUE(entry->disabled());
504 TEST_F(GpuControlListEntryTest, OptimusEntry) {
505 const std::string json = LONG_STRING_CONST(
511 "multi_gpu_style": "optimus",
518 gpu_info.optimus = true;
520 ScopedEntry entry(GetEntryFromString(json));
521 EXPECT_TRUE(entry.get() != NULL);
522 EXPECT_EQ(GpuControlList::kOsLinux, entry->GetOsType());
523 EXPECT_TRUE(entry->Contains(
524 GpuControlList::kOsLinux, "10.6", gpu_info));
527 TEST_F(GpuControlListEntryTest, AMDSwitchableEntry) {
528 const std::string json = LONG_STRING_CONST(
534 "multi_gpu_style": "amd_switchable",
541 gpu_info.amd_switchable = true;
543 ScopedEntry entry(GetEntryFromString(json));
544 EXPECT_TRUE(entry.get() != NULL);
545 EXPECT_EQ(GpuControlList::kOsMacosx, entry->GetOsType());
546 EXPECT_TRUE(entry->Contains(
547 GpuControlList::kOsMacosx, "10.6", gpu_info));
550 TEST_F(GpuControlListEntryTest, LexicalDriverVersionEntry) {
551 const std::string json = LONG_STRING_CONST(
557 "vendor_id": "0x1002",
569 gpu_info.gpu.vendor_id = 0x1002;
571 ScopedEntry entry(GetEntryFromString(json));
572 EXPECT_TRUE(entry.get() != NULL);
573 EXPECT_EQ(GpuControlList::kOsLinux, entry->GetOsType());
575 gpu_info.driver_version = "8.76";
576 EXPECT_TRUE(entry->Contains(
577 GpuControlList::kOsLinux, "10.6", gpu_info));
579 gpu_info.driver_version = "8.768";
580 EXPECT_TRUE(entry->Contains(
581 GpuControlList::kOsLinux, "10.6", gpu_info));
583 gpu_info.driver_version = "8.76.8";
584 EXPECT_TRUE(entry->Contains(
585 GpuControlList::kOsLinux, "10.6", gpu_info));
588 TEST_F(GpuControlListEntryTest, NeedsMoreInfoEntry) {
589 const std::string json = LONG_STRING_CONST(
592 "vendor_id": "0x8086",
602 ScopedEntry entry(GetEntryFromString(json));
603 EXPECT_TRUE(entry.get() != NULL);
606 gpu_info.gpu.vendor_id = 0x8086;
607 EXPECT_TRUE(entry->NeedsMoreInfo(gpu_info));
609 gpu_info.driver_version = "10.6";
610 EXPECT_FALSE(entry->NeedsMoreInfo(gpu_info));
613 TEST_F(GpuControlListEntryTest, NeedsMoreInfoForExceptionsEntry) {
614 const std::string json = LONG_STRING_CONST(
617 "vendor_id": "0x8086",
631 ScopedEntry entry(GetEntryFromString(json));
632 EXPECT_TRUE(entry.get() != NULL);
635 gpu_info.gpu.vendor_id = 0x8086;
636 EXPECT_TRUE(entry->NeedsMoreInfo(gpu_info));
638 gpu_info.gl_renderer = "mesa";
639 EXPECT_FALSE(entry->NeedsMoreInfo(gpu_info));
642 TEST_F(GpuControlListEntryTest, FeatureTypeAllEntry) {
643 const std::string json = LONG_STRING_CONST(
651 ScopedEntry entry(GetEntryFromString(json, true));
652 EXPECT_TRUE(entry.get() != NULL);
653 EXPECT_EQ(3u, entry->features().size());
654 EXPECT_EQ(1u, entry->features().count(TEST_FEATURE_0));
655 EXPECT_EQ(1u, entry->features().count(TEST_FEATURE_1));
656 EXPECT_EQ(1u, entry->features().count(TEST_FEATURE_2));
659 TEST_F(GpuControlListEntryTest, InvalidVendorIdEntry) {
660 const std::string json = LONG_STRING_CONST(
663 "vendor_id": "0x0000",
669 ScopedEntry entry(GetEntryFromString(json));
670 EXPECT_TRUE(entry.get() == NULL);
673 TEST_F(GpuControlListEntryTest, InvalidDeviceIdEntry) {
674 const std::string json = LONG_STRING_CONST(
677 "vendor_id": "0x10de",
678 "device_id": ["0x1023", "0x0000"],
684 ScopedEntry entry(GetEntryFromString(json));
685 EXPECT_TRUE(entry.get() == NULL);
688 TEST_F(GpuControlListEntryTest, SingleActiveGPU) {
689 const std::string json = LONG_STRING_CONST(
695 "vendor_id": "0x10de",
696 "device_id": ["0x0640"],
697 "multi_gpu_category": "active",
703 ScopedEntry entry(GetEntryFromString(json));
704 EXPECT_TRUE(entry.get() != NULL);
705 EXPECT_EQ(GpuControlList::kOsMacosx, entry->GetOsType());
706 EXPECT_TRUE(entry->Contains(
707 GpuControlList::kOsMacosx, "10.6", gpu_info()));
710 class GpuControlListEntryDualGPUTest : public GpuControlListEntryTest {
712 GpuControlListEntryDualGPUTest() { }
713 virtual ~GpuControlListEntryDualGPUTest() { }
715 virtual void SetUp() OVERRIDE {
716 // Set up a NVIDIA/Intel dual, with NVIDIA as primary and Intel as
717 // secondary, and initially Intel is active.
718 gpu_info_.gpu.vendor_id = 0x10de;
719 gpu_info_.gpu.device_id = 0x0640;
720 gpu_info_.gpu.active = false;
721 GPUInfo::GPUDevice second_gpu;
722 second_gpu.vendor_id = 0x8086;
723 second_gpu.device_id = 0x0166;
724 second_gpu.active = true;
725 gpu_info_.secondary_gpus.push_back(second_gpu);
728 void ActivatePrimaryGPU() {
729 gpu_info_.gpu.active = true;
730 gpu_info_.secondary_gpus[0].active = false;
733 void EntryShouldApply(const std::string& entry_json) const {
734 EXPECT_TRUE(EntryApplies(entry_json));
737 void EntryShouldNotApply(const std::string& entry_json) const {
738 EXPECT_FALSE(EntryApplies(entry_json));
742 bool EntryApplies(const std::string& entry_json) const {
743 ScopedEntry entry(GetEntryFromString(entry_json));
744 EXPECT_TRUE(entry.get());
745 EXPECT_EQ(GpuControlList::kOsMacosx, entry->GetOsType());
746 return entry->Contains(GpuControlList::kOsMacosx, "10.6", gpu_info());
750 TEST_F(GpuControlListEntryDualGPUTest, CategoryAny) {
751 const std::string json_intel = LONG_STRING_CONST(
757 "vendor_id": "0x8086",
758 "device_id": ["0x0166"],
759 "multi_gpu_category": "any",
765 EntryShouldApply(json_intel);
767 const std::string json_nvidia = LONG_STRING_CONST(
773 "vendor_id": "0x10de",
774 "device_id": ["0x0640"],
775 "multi_gpu_category": "any",
781 EntryShouldApply(json_nvidia);
784 TEST_F(GpuControlListEntryDualGPUTest, CategoryPrimarySecondary) {
785 const std::string json_secondary = LONG_STRING_CONST(
791 "vendor_id": "0x8086",
792 "device_id": ["0x0166"],
793 "multi_gpu_category": "secondary",
799 EntryShouldApply(json_secondary);
801 const std::string json_primary = LONG_STRING_CONST(
807 "vendor_id": "0x8086",
808 "device_id": ["0x0166"],
809 "multi_gpu_category": "primary",
815 EntryShouldNotApply(json_primary);
817 const std::string json_default = LONG_STRING_CONST(
823 "vendor_id": "0x8086",
824 "device_id": ["0x0166"],
830 // Default is primary.
831 EntryShouldNotApply(json_default);
834 TEST_F(GpuControlListEntryDualGPUTest, ActiveSecondaryGPU) {
835 const std::string json = LONG_STRING_CONST(
841 "vendor_id": "0x8086",
842 "device_id": ["0x0166", "0x0168"],
843 "multi_gpu_category": "active",
849 // By default, secondary GPU is active.
850 EntryShouldApply(json);
852 ActivatePrimaryGPU();
853 EntryShouldNotApply(json);
856 TEST_F(GpuControlListEntryDualGPUTest, VendorOnlyActiveSecondaryGPU) {
857 const std::string json = LONG_STRING_CONST(
863 "vendor_id": "0x8086",
864 "multi_gpu_category": "active",
870 // By default, secondary GPU is active.
871 EntryShouldApply(json);
873 ActivatePrimaryGPU();
874 EntryShouldNotApply(json);
877 TEST_F(GpuControlListEntryDualGPUTest, ActivePrimaryGPU) {
878 const std::string json = LONG_STRING_CONST(
884 "vendor_id": "0x10de",
885 "device_id": ["0x0640"],
886 "multi_gpu_category": "active",
892 // By default, secondary GPU is active.
893 EntryShouldNotApply(json);
895 ActivatePrimaryGPU();
896 EntryShouldApply(json);
899 TEST_F(GpuControlListEntryDualGPUTest, VendorOnlyActivePrimaryGPU) {
900 const std::string json = LONG_STRING_CONST(
906 "vendor_id": "0x10de",
907 "multi_gpu_category": "active",
913 // By default, secondary GPU is active.
914 EntryShouldNotApply(json);
916 ActivatePrimaryGPU();
917 EntryShouldApply(json);