1 // Copyright 2016 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 "chrome/browser/media/webrtc/test_stats_dictionary.h"
6 
7 #include <memory>
8 #include <set>
9 #include <vector>
10 
11 #include "base/check.h"
12 #include "base/json/json_reader.h"
13 #include "base/macros.h"
14 #include "base/memory/ref_counted.h"
15 #include "base/values.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17 
18 namespace content {
19 
20 namespace {
21 
22 const char kTestStatsReportJson[] =
23     R"({
24   "GarbageA": {
25     "id": "GarbageA",
26     "timestamp": 0.0,
27     "type": "garbage"
28   },
29   "RTCTestStatsID": {
30     "id": "RTCTestStatsID",
31     "timestamp": 13.37,
32     "type": "test",
33     "boolean": true,
34     "number": 42,
35     "string": "text",
36     "sequenceBoolean": [ true ],
37     "sequenceNumber": [ 42 ],
38     "sequenceString": [ "text" ]
39   },
40   "GarbageB": {
41     "id": "GarbageB",
42     "timestamp": 0.0,
43     "type": "garbage"
44   }
45 })";
46 
47 class TestStatsDictionaryTest : public testing::Test {
48  public:
TestStatsDictionaryTest()49   TestStatsDictionaryTest() {
50     std::unique_ptr<base::Value> value =
51         base::JSONReader::ReadDeprecated(kTestStatsReportJson);
52     CHECK(value);
53     base::DictionaryValue* dictionary;
54     CHECK(value->GetAsDictionary(&dictionary));
55     ignore_result(value.release());
56     report_ = new TestStatsReportDictionary(
57         std::unique_ptr<base::DictionaryValue>(dictionary));
58   }
59 
60  protected:
61   scoped_refptr<TestStatsReportDictionary> report_;
62 };
63 
TEST_F(TestStatsDictionaryTest,ReportGetStats)64 TEST_F(TestStatsDictionaryTest, ReportGetStats) {
65   EXPECT_FALSE(report_->Get("InvalidID"));
66   EXPECT_TRUE(report_->Get("GarbageA"));
67   EXPECT_TRUE(report_->Get("RTCTestStatsID"));
68   EXPECT_TRUE(report_->Get("GarbageB"));
69 }
70 
TEST_F(TestStatsDictionaryTest,ReportForEach)71 TEST_F(TestStatsDictionaryTest, ReportForEach) {
72   std::set<std::string> remaining;
73   remaining.insert("GarbageA");
74   remaining.insert("RTCTestStatsID");
75   remaining.insert("GarbageB");
76   report_->ForEach([&remaining](const TestStatsDictionary& stats) {
77     remaining.erase(stats.GetString("id"));
78   });
79   EXPECT_TRUE(remaining.empty());
80 }
81 
TEST_F(TestStatsDictionaryTest,ReportFilterStats)82 TEST_F(TestStatsDictionaryTest, ReportFilterStats) {
83   std::vector<TestStatsDictionary> filtered_stats = report_->Filter(
84       [](const TestStatsDictionary& stats) -> bool {
85           return false;
86       });
87   EXPECT_EQ(filtered_stats.size(), 0u);
88 
89   filtered_stats = report_->Filter(
90       [](const TestStatsDictionary& stats) -> bool {
91           return true;
92       });
93   EXPECT_EQ(filtered_stats.size(), 3u);
94 
95   filtered_stats = report_->Filter(
96       [](const TestStatsDictionary& stats) -> bool {
97           return stats.GetString("id") == "RTCTestStatsID";
98       });
99   EXPECT_EQ(filtered_stats.size(), 1u);
100 }
101 
TEST_F(TestStatsDictionaryTest,ReportGetAll)102 TEST_F(TestStatsDictionaryTest, ReportGetAll) {
103   std::set<std::string> remaining;
104   remaining.insert("GarbageA");
105   remaining.insert("RTCTestStatsID");
106   remaining.insert("GarbageB");
107   for (const TestStatsDictionary& stats : report_->GetAll()) {
108     remaining.erase(stats.GetString("id"));
109   }
110   EXPECT_TRUE(remaining.empty());
111 }
112 
TEST_F(TestStatsDictionaryTest,ReportGetByType)113 TEST_F(TestStatsDictionaryTest, ReportGetByType) {
114   std::vector<TestStatsDictionary> stats = report_->GetByType("garbage");
115   EXPECT_EQ(stats.size(), 2u);
116   std::set<std::string> remaining;
117   remaining.insert("GarbageA");
118   remaining.insert("GarbageB");
119   report_->ForEach([&remaining](const TestStatsDictionary& stats) {
120     remaining.erase(stats.GetString("id"));
121   });
122   EXPECT_TRUE(remaining.empty());
123 }
124 
TEST_F(TestStatsDictionaryTest,StatsVerifyMembers)125 TEST_F(TestStatsDictionaryTest, StatsVerifyMembers) {
126   std::unique_ptr<TestStatsDictionary> stats = report_->Get("RTCTestStatsID");
127   EXPECT_TRUE(stats);
128 
129   EXPECT_FALSE(stats->IsBoolean("nonexistentMember"));
130   EXPECT_FALSE(stats->IsNumber("nonexistentMember"));
131   EXPECT_FALSE(stats->IsString("nonexistentMember"));
132   EXPECT_FALSE(stats->IsSequenceBoolean("nonexistentMember"));
133   EXPECT_FALSE(stats->IsSequenceNumber("nonexistentMember"));
134   EXPECT_FALSE(stats->IsSequenceString("nonexistentMember"));
135 
136   ASSERT_TRUE(stats->IsBoolean("boolean"));
137   EXPECT_EQ(stats->GetBoolean("boolean"), true);
138 
139   ASSERT_TRUE(stats->IsNumber("number"));
140   EXPECT_EQ(stats->GetNumber("number"), 42.0);
141 
142   ASSERT_TRUE(stats->IsString("string"));
143   EXPECT_EQ(stats->GetString("string"), "text");
144 
145   ASSERT_TRUE(stats->IsSequenceBoolean("sequenceBoolean"));
146   EXPECT_EQ(stats->GetSequenceBoolean("sequenceBoolean"),
147             std::vector<bool> { true });
148 
149   ASSERT_TRUE(stats->IsSequenceNumber("sequenceNumber"));
150   EXPECT_EQ(stats->GetSequenceNumber("sequenceNumber"),
151             std::vector<double> { 42.0 });
152 
153   ASSERT_TRUE(stats->IsSequenceString("sequenceString"));
154   EXPECT_EQ(stats->GetSequenceString("sequenceString"),
155             std::vector<std::string> { "text" });
156 }
157 
TEST_F(TestStatsDictionaryTest,TestStatsDictionaryShouldKeepReportAlive)158 TEST_F(TestStatsDictionaryTest, TestStatsDictionaryShouldKeepReportAlive) {
159   std::unique_ptr<TestStatsDictionary> stats = report_->Get("RTCTestStatsID");
160   EXPECT_TRUE(stats);
161   report_ = nullptr;
162   EXPECT_EQ(stats->GetString("string"), "text");
163 }
164 
165 }  // namespace
166 
167 }  // namespace content
168