Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(235)

Side by Side Diff: chrome/browser/chromeos/system_logs/single_log_source_unittest.cc

Issue 2844163005: Add SingleLogSource to system_logs sources (Closed)
Patch Set: Respond to afakhry's comments on .cc and .h files Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 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/chromeos/system_logs/single_log_source.h"
6
7 #include <string>
8
9 #include "base/bind.h"
10 #include "base/files/file_path.h"
11 #include "base/files/file_util.h"
12 #include "base/files/scoped_temp_dir.h"
13 #include "base/macros.h"
14 #include "base/run_loop.h"
15 #include "base/test/scoped_task_scheduler.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17
18 namespace system_logs {
19
20 class TestSingleLogSource : public SingleLogSource {
afakhry 2017/05/08 19:20:48 You don't need this class at all, or the mutable_f
Simon Que 2017/05/08 19:58:36 Done.
21 public:
22 TestSingleLogSource() : SingleLogSource(SupportedSource::kMessages) {}
23 ~TestSingleLogSource() override {}
24
25 base::File* mutable_file() { return SingleLogSource::mutable_file(); }
26
27 private:
28 DISALLOW_COPY_AND_ASSIGN(TestSingleLogSource);
29 };
30
31 class SingleLogSourceTest : public ::testing::Test {
32 public:
33 SingleLogSourceTest()
34 : num_callback_calls_(0),
35 callback_(base::Bind(&SingleLogSourceTest::OnFileRead,
36 base::Unretained(this))) {
37 CHECK(dir_.CreateUniqueTempDir());
38 log_file_path_ = dir_.GetPath().Append("log_file");
39
40 // Create the dummy log file for writing.
41 base::File new_file;
42 new_file.Initialize(log_file_path_,
43 base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_READ);
44 new_file.Close();
45 CHECK(base::PathExists(log_file_path_));
46
47 // Open the dummy log file for reading from within the log source.
48 source_.mutable_file()->Initialize(
49 log_file_path_, base::File::FLAG_OPEN | base::File::FLAG_READ);
50 CHECK(source_.mutable_file()->IsValid());
51 }
52
53 ~SingleLogSourceTest() override { dir_.Take(); }
afakhry 2017/05/08 19:20:48 Why do you want to make this dir outlive SingleLog
Simon Que 2017/05/08 19:58:36 Done.
54
55 protected:
56 // Writes a string to |log_file_path_|.
57 bool WriteFile(const std::string& input) {
58 return base::WriteFile(log_file_path_, input.data(), input.size());
59 }
60 // Appends a string to |log_file_path_|.
61 bool AppendToFile(const std::string& input) {
62 return base::AppendToFile(log_file_path_, input.data(), input.size());
63 }
64
65 // Callback for fetching logs from |source_|. Overwrites the previous stored
66 // value of |latest_response_|.
67 void OnFileRead(SystemLogsResponse* response) {
68 ++num_callback_calls_;
69 if (response->empty())
70 return;
71
72 // Since |source_| represents a single log source, it should only return a
73 // single string result.
74 EXPECT_EQ(1U, response->size());
75 latest_response_ = std::move(response->begin()->second);
76 }
77
78 // Unit under test.
79 TestSingleLogSource source_;
80
81 // Counts the number of times that |source_| has invoked the callback.
82 int num_callback_calls_;
83
84 // Stores the string response returned from |source_| the last time it invoked
85 // OnFileRead.
86 std::string latest_response_;
87
88 // Callback object for invoking OnFileRead.
89 const SysLogsSourceCallback callback_;
90
91 // Temporary dir for creating a dummy log file.
92 base::ScopedTempDir dir_;
93
94 // Path to the dummy log file in |dir_|.
95 base::FilePath log_file_path_;
96
97 // Used for running scheduled tasks.
98 base::test::ScopedTaskScheduler scheduler_;
99
100 DISALLOW_COPY_AND_ASSIGN(SingleLogSourceTest);
101 };
102
103 TEST_F(SingleLogSourceTest, EmptyFile) {
104 source_.Fetch(callback_);
105 base::RunLoop().RunUntilIdle();
106
107 EXPECT_EQ(1, num_callback_calls_);
afakhry 2017/05/08 19:20:48 num_callback_calls_ should not be mutable and expo
Simon Que 2017/05/08 19:58:36 Done.
108 EXPECT_EQ("", latest_response_);
109 }
110
111 TEST_F(SingleLogSourceTest, SingleRead) {
112 EXPECT_TRUE(AppendToFile("Hello world!\n"));
113 source_.Fetch(callback_);
114 base::RunLoop().RunUntilIdle();
115
116 EXPECT_EQ(1, num_callback_calls_);
117 EXPECT_EQ("Hello world!\n", latest_response_);
118 }
119
120 TEST_F(SingleLogSourceTest, IncrementalReads) {
121 EXPECT_TRUE(AppendToFile("Hello world!\n"));
122 source_.Fetch(callback_);
123 base::RunLoop().RunUntilIdle();
124
125 EXPECT_EQ(1, num_callback_calls_);
126 EXPECT_EQ("Hello world!\n", latest_response_);
127
128 EXPECT_TRUE(AppendToFile("The quick brown fox jumps over the lazy dog\n"));
129 source_.Fetch(callback_);
130 base::RunLoop().RunUntilIdle();
131
132 EXPECT_EQ(2, num_callback_calls_);
133 EXPECT_EQ("The quick brown fox jumps over the lazy dog\n", latest_response_);
134
135 EXPECT_TRUE(AppendToFile("Some like it hot.\nSome like it cold\n"));
136 source_.Fetch(callback_);
137 base::RunLoop().RunUntilIdle();
138
139 EXPECT_EQ(3, num_callback_calls_);
140 EXPECT_EQ("Some like it hot.\nSome like it cold\n", latest_response_);
141
142 // As a sanity check, read entire contents of file separately to make sure it
143 // was written incrementally, and hence read incrementally.
144 std::string file_contents;
145 EXPECT_TRUE(base::ReadFileToString(log_file_path_, &file_contents));
146 EXPECT_EQ(
147 "Hello world!\nThe quick brown fox jumps over the lazy dog\n"
148 "Some like it hot.\nSome like it cold\n",
149 file_contents);
150 }
151
152 TEST_F(SingleLogSourceTest, FileOverwrite) {
153 EXPECT_TRUE(AppendToFile("0123456789\n"));
154 source_.Fetch(callback_);
155 base::RunLoop().RunUntilIdle();
156
157 EXPECT_EQ(1, num_callback_calls_);
158 EXPECT_EQ("0123456789\n", latest_response_);
159
160 // Overwrite the file.
161 EXPECT_TRUE(WriteFile("abcdefg\n"));
afakhry 2017/05/08 19:20:48 That's just a side effect of having the overwrite
Simon Que 2017/05/08 19:58:36 I'm not sure that's possible. See my analysis of t
afakhry 2017/05/09 00:39:23 Acknowledged.
162 source_.Fetch(callback_);
163 base::RunLoop().RunUntilIdle();
164
165 // Should re-read from the beginning.
166 EXPECT_EQ(2, num_callback_calls_);
167 EXPECT_EQ("abcdefg\n", latest_response_);
168
169 // Append to the file to make sure incremental read still works.
170 EXPECT_TRUE(AppendToFile("hijk\n"));
171 source_.Fetch(callback_);
172 base::RunLoop().RunUntilIdle();
173
174 EXPECT_EQ(3, num_callback_calls_);
175 EXPECT_EQ("hijk\n", latest_response_);
176
177 // Overwrite again, this time with a longer length than the existing file.
178 // Previous contents:
179 // abcdefg~hijk~ <-- "~" is a single-char representation of newline.
180 // New contents:
181 // lmnopqrstuvwxyz~ <-- excess text beyond end of prev contents: "yz~"
182 EXPECT_TRUE(WriteFile("lmnopqrstuvwxyz\n"));
183 source_.Fetch(callback_);
184 base::RunLoop().RunUntilIdle();
185
186 EXPECT_EQ(4, num_callback_calls_);
187 EXPECT_EQ("yz\n", latest_response_);
afakhry 2017/05/08 19:20:48 Similarly, this should be smarter at detecting ove
188 }
189
190 TEST_F(SingleLogSourceTest, IncompleteLines) {
191 EXPECT_TRUE(AppendToFile("0123456789"));
192 source_.Fetch(callback_);
193 base::RunLoop().RunUntilIdle();
194
195 EXPECT_EQ(1, num_callback_calls_);
196 EXPECT_EQ("", latest_response_);
197
198 EXPECT_TRUE(AppendToFile("abcdefg"));
199 source_.Fetch(callback_);
200 base::RunLoop().RunUntilIdle();
201
202 EXPECT_EQ(2, num_callback_calls_);
203 EXPECT_EQ("", latest_response_);
204
205 EXPECT_TRUE(AppendToFile("hijk\n"));
206 source_.Fetch(callback_);
207 base::RunLoop().RunUntilIdle();
208
209 EXPECT_EQ(3, num_callback_calls_);
210 // All the previously written text should be read this time.
211 EXPECT_EQ("0123456789abcdefghijk\n", latest_response_);
212
213 EXPECT_TRUE(AppendToFile("Hello world\n"));
214 EXPECT_TRUE(AppendToFile("Goodbye world"));
215 source_.Fetch(callback_);
216 base::RunLoop().RunUntilIdle();
217
218 // Partial whole-line reads are not supported. The last byte of the read must
219 // be a new line.
220 EXPECT_EQ(4, num_callback_calls_);
221 EXPECT_EQ("", latest_response_);
222
223 EXPECT_TRUE(AppendToFile("\n"));
224 source_.Fetch(callback_);
225 base::RunLoop().RunUntilIdle();
226
227 EXPECT_EQ(5, num_callback_calls_);
228 EXPECT_EQ("Hello world\nGoodbye world\n", latest_response_);
229 }
230
231 TEST_F(SingleLogSourceTest, Anonymize) {
232 EXPECT_TRUE(AppendToFile("My MAC address is: 11:22:33:44:55:66\n"));
233 source_.Fetch(callback_);
234 base::RunLoop().RunUntilIdle();
235
236 EXPECT_EQ(1, num_callback_calls_);
237 EXPECT_EQ("My MAC address is: 11:22:33:00:00:01\n", latest_response_);
238
239 // Suppose the write operation is not atomic, and the MAC address is written
240 // across two separate writes.
241 EXPECT_TRUE(AppendToFile("Your MAC address is: AB:88:C"));
242 source_.Fetch(callback_);
243 base::RunLoop().RunUntilIdle();
244
245 EXPECT_EQ(2, num_callback_calls_);
246 EXPECT_EQ("", latest_response_);
247
248 EXPECT_TRUE(AppendToFile("D:99:EF:77\n"));
249 source_.Fetch(callback_);
250 base::RunLoop().RunUntilIdle();
251
252 EXPECT_EQ(3, num_callback_calls_);
253 EXPECT_EQ("Your MAC address is: ab:88:cd:00:00:02\n", latest_response_);
254 }
255
256 } // namespace system_logs
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698