1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
// Copyright 2014 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 "extensions/browser/error_map.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_number_conversions.h"
#include "extensions/browser/extension_error.h"
#include "extensions/browser/extension_error_test_util.h"
#include "extensions/common/constants.h"
#include "extensions/common/id_util.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace extensions {
using error_test_util::CreateNewRuntimeError;
class ErrorMapUnitTest : public testing::Test {
public:
ErrorMapUnitTest() { }
virtual ~ErrorMapUnitTest() { }
virtual void SetUp() OVERRIDE {
testing::Test::SetUp();
}
protected:
ErrorMap errors_;
};
// Test adding errors, and removing them by reference, by incognito status,
// and in bulk.
TEST_F(ErrorMapUnitTest, AddAndRemoveErrors) {
ASSERT_EQ(0u, errors_.size());
const size_t kNumTotalErrors = 6;
const size_t kNumNonIncognitoErrors = 3;
const std::string kId = id_util::GenerateId("id");
// Populate with both incognito and non-incognito errors (evenly distributed).
for (size_t i = 0; i < kNumTotalErrors; ++i) {
ASSERT_TRUE(errors_.AddError(
CreateNewRuntimeError(kId, base::UintToString(i), i % 2 == 0)));
}
// There should only be one entry in the map, since errors are stored in lists
// keyed by extension id.
ASSERT_EQ(1u, errors_.size());
ASSERT_EQ(kNumTotalErrors, errors_.GetErrorsForExtension(kId).size());
// Remove the incognito errors; three errors should remain, and all should
// be from non-incognito contexts.
errors_.RemoveIncognitoErrors();
const ErrorList& list = errors_.GetErrorsForExtension(kId);
ASSERT_EQ(kNumNonIncognitoErrors, list.size());
for (size_t i = 0; i < list.size(); ++i)
ASSERT_FALSE(list[i]->from_incognito());
// Add another error for a different extension id.
const std::string kSecondId = id_util::GenerateId("id2");
ASSERT_TRUE(errors_.AddError(CreateNewRuntimeError(kSecondId, "foo")));
// There should be two entries now, one for each id, and there should be one
// error for the second extension.
ASSERT_EQ(2u, errors_.size());
ASSERT_EQ(1u, errors_.GetErrorsForExtension(kSecondId).size());
// Remove all errors for the second id.
errors_.Remove(kSecondId);
ASSERT_EQ(1u, errors_.size());
ASSERT_EQ(0u, errors_.GetErrorsForExtension(kSecondId).size());
// First extension should be unaffected.
ASSERT_EQ(kNumNonIncognitoErrors,
errors_.GetErrorsForExtension(kId).size());
// Remove remaining errors.
errors_.RemoveAllErrors();
ASSERT_EQ(0u, errors_.size());
ASSERT_EQ(0u, errors_.GetErrorsForExtension(kId).size());
}
// Test that if we add enough errors, only the most recent
// kMaxErrorsPerExtension are kept.
TEST_F(ErrorMapUnitTest, ExcessiveErrorsGetCropped) {
ASSERT_EQ(0u, errors_.size());
// This constant matches one of the same name in error_console.cc.
const size_t kMaxErrorsPerExtension = 100;
const size_t kNumExtraErrors = 5;
const std::string kId = id_util::GenerateId("id");
// Add new errors, with each error's message set to its number.
for (size_t i = 0; i < kMaxErrorsPerExtension + kNumExtraErrors; ++i) {
ASSERT_TRUE(errors_.AddError(
CreateNewRuntimeError(kId, base::UintToString(i))));
}
ASSERT_EQ(1u, errors_.size());
const ErrorList& list = errors_.GetErrorsForExtension(kId);
ASSERT_EQ(kMaxErrorsPerExtension, list.size());
// We should have popped off errors in the order they arrived, so the
// first stored error should be the 6th reported (zero-based)...
ASSERT_EQ(base::UintToString16(kNumExtraErrors),
list.front()->message());
// ..and the last stored should be the 105th reported.
ASSERT_EQ(base::UintToString16(kMaxErrorsPerExtension + kNumExtraErrors - 1),
list.back()->message());
}
// Test to ensure that the error console will not add duplicate errors, but will
// keep the latest version of an error.
TEST_F(ErrorMapUnitTest, DuplicateErrorsAreReplaced) {
ASSERT_EQ(0u, errors_.size());
const std::string kId = id_util::GenerateId("id");
const size_t kNumErrors = 3u;
// Report three errors.
for (size_t i = 0; i < kNumErrors; ++i) {
ASSERT_TRUE(errors_.AddError(
CreateNewRuntimeError(kId, base::UintToString(i))));
}
// Create an error identical to the second error reported, save its
// location, and add it to the error map.
scoped_ptr<ExtensionError> runtime_error2 =
CreateNewRuntimeError(kId, base::UintToString(1u));
const ExtensionError* weak_error = runtime_error2.get();
ASSERT_TRUE(errors_.AddError(runtime_error2.Pass()));
// We should only have three errors stored, since two of the four reported
// were identical, and the older should have been replaced.
ASSERT_EQ(1u, errors_.size());
const ErrorList& list = errors_.GetErrorsForExtension(kId);
ASSERT_EQ(kNumErrors, list.size());
// The duplicate error should be the last reported (pointer comparison)...
ASSERT_EQ(weak_error, list.back());
// ... and should have two reported occurrences.
ASSERT_EQ(2u, list.back()->occurrences());
}
} // namespace extensions
|