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

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: Remove TODO, already done 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
afakhry 2017/05/06 01:12:13 I will look at this test when you handle the previ
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/run_loop.h"
14 #include "base/test/scoped_task_scheduler.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16
17 namespace system_logs {
18
19 class TestSingleLogSource : public SingleLogSource {
20 public:
21 TestSingleLogSource() {}
22 ~TestSingleLogSource() override {}
23
24 // Disable copy/move operations.
25 TestSingleLogSource(const TestSingleLogSource&) = delete;
26 TestSingleLogSource& operator=(const TestSingleLogSource&) = delete;
27
28 base::File* mutable_file() { return SingleLogSource::mutable_file(); }
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(); }
54
55 // Disable copy/move operations.
56 SingleLogSourceTest(const SingleLogSourceTest&) = delete;
57 SingleLogSourceTest& operator=(const SingleLogSourceTest&) = delete;
58
59 protected:
60 // Writes a string to |log_file_path_|.
61 bool WriteFile(const std::string& input) {
62 return base::WriteFile(log_file_path_, input.data(), input.size());
63 }
64 // Appends a string to |log_file_path_|.
65 bool AppendToFile(const std::string& input) {
66 return base::AppendToFile(log_file_path_, input.data(), input.size());
67 }
68
69 // Callback for fetching logs from |source_|. Overwrites the previous stored
70 // value of |latest_response_|.
71 void OnFileRead(SystemLogsResponse* response) {
72 ++num_callback_calls_;
73 if (response->empty())
74 return;
75
76 // Since |source_| represents a single log source, it should only return a
77 // single string result.
78 EXPECT_EQ(1U, response->size());
79 latest_response_ = std::move(response->begin()->second);
80 }
81
82 // Unit under test.
83 TestSingleLogSource source_;
84
85 // Counts the number of times that |source_| has invoked the callback.
86 int num_callback_calls_;
87
88 // Stores the string response returned from |source_| the last time it invoked
89 // OnFileRead.
90 std::string latest_response_;
91
92 // Callback object for invoking OnFileRead.
93 const SysLogsSourceCallback callback_;
94
95 // Temporary dir for creating a dummy log file.
96 base::ScopedTempDir dir_;
97
98 // Path to the dummy log file in |dir_|.
99 base::FilePath log_file_path_;
100
101 // Used for running scheduled tasks.
102 base::test::ScopedTaskScheduler scheduler_;
103 };
104
105 TEST_F(SingleLogSourceTest, EmptyFile) {
106 source_.Fetch(callback_);
107 base::RunLoop().RunUntilIdle();
108
109 EXPECT_EQ(1, num_callback_calls_);
110 EXPECT_EQ("", latest_response_);
111 }
112
113 TEST_F(SingleLogSourceTest, SingleRead) {
114 EXPECT_TRUE(AppendToFile("Hello world!\n"));
115 source_.Fetch(callback_);
116 base::RunLoop().RunUntilIdle();
117
118 EXPECT_EQ(1, num_callback_calls_);
119 EXPECT_EQ("Hello world!\n", latest_response_);
120 }
121
122 TEST_F(SingleLogSourceTest, IncrementalReads) {
123 EXPECT_TRUE(AppendToFile("Hello world!\n"));
124 source_.Fetch(callback_);
125 base::RunLoop().RunUntilIdle();
126
127 EXPECT_EQ(1, num_callback_calls_);
128 EXPECT_EQ("Hello world!\n", latest_response_);
129
130 EXPECT_TRUE(AppendToFile("The quick brown fox jumps over the lazy dog\n"));
131 source_.Fetch(callback_);
132 base::RunLoop().RunUntilIdle();
133
134 EXPECT_EQ(2, num_callback_calls_);
135 EXPECT_EQ("The quick brown fox jumps over the lazy dog\n", latest_response_);
136
137 EXPECT_TRUE(AppendToFile("Some like it hot.\nSome like it cold\n"));
138 source_.Fetch(callback_);
139 base::RunLoop().RunUntilIdle();
140
141 EXPECT_EQ(3, num_callback_calls_);
142 EXPECT_EQ("Some like it hot.\nSome like it cold\n", latest_response_);
143
144 // As a sanity check, read entire contents of file separately to make sure it
145 // was written incrementally, and hence read incrementally.
146 std::string file_contents;
147 EXPECT_TRUE(base::ReadFileToString(log_file_path_, &file_contents));
148 EXPECT_EQ(
149 "Hello world!\nThe quick brown fox jumps over the lazy dog\n"
150 "Some like it hot.\nSome like it cold\n",
151 file_contents);
152 }
153
154 TEST_F(SingleLogSourceTest, FileOverwrite) {
155 EXPECT_TRUE(AppendToFile("0123456789\n"));
156 source_.Fetch(callback_);
157 base::RunLoop().RunUntilIdle();
158
159 EXPECT_EQ(1, num_callback_calls_);
160 EXPECT_EQ("0123456789\n", latest_response_);
161
162 // Overwrite the file.
163 EXPECT_TRUE(WriteFile("abcdefg\n"));
164 source_.Fetch(callback_);
165 base::RunLoop().RunUntilIdle();
166
167 // Should re-read from the beginning.
168 EXPECT_EQ(2, num_callback_calls_);
169 EXPECT_EQ("abcdefg\n", latest_response_);
170
171 // Append to the file to make sure incremental read still works.
172 EXPECT_TRUE(AppendToFile("hijk\n"));
173 source_.Fetch(callback_);
174 base::RunLoop().RunUntilIdle();
175
176 EXPECT_EQ(3, num_callback_calls_);
177 EXPECT_EQ("hijk\n", latest_response_);
178
179 // Overwrite again, this time with a longer length than the existing file.
180 // Previous contents:
181 // abcdefg~hijk~ <-- "~" is a single-char representation of newline.
182 // New contents:
183 // lmnopqrstuvwxyz~ <-- excess text beyond end of prev contents: "yz~"
184 EXPECT_TRUE(WriteFile("lmnopqrstuvwxyz\n"));
185 source_.Fetch(callback_);
186 base::RunLoop().RunUntilIdle();
187
188 EXPECT_EQ(4, num_callback_calls_);
189 EXPECT_EQ("yz\n", latest_response_);
190 }
191
192 TEST_F(SingleLogSourceTest, IncompleteLines) {
193 EXPECT_TRUE(AppendToFile("0123456789"));
194 source_.Fetch(callback_);
195 base::RunLoop().RunUntilIdle();
196
197 EXPECT_EQ(1, num_callback_calls_);
198 EXPECT_EQ("", latest_response_);
199
200 EXPECT_TRUE(AppendToFile("abcdefg"));
201 source_.Fetch(callback_);
202 base::RunLoop().RunUntilIdle();
203
204 EXPECT_EQ(2, num_callback_calls_);
205 EXPECT_EQ("", latest_response_);
206
207 EXPECT_TRUE(AppendToFile("hijk\n"));
208 source_.Fetch(callback_);
209 base::RunLoop().RunUntilIdle();
210
211 EXPECT_EQ(3, num_callback_calls_);
212 // All the previously written text should be read this time.
213 EXPECT_EQ("0123456789abcdefghijk\n", latest_response_);
214
215 EXPECT_TRUE(AppendToFile("Hello world\n"));
216 EXPECT_TRUE(AppendToFile("Goodbye world"));
217 source_.Fetch(callback_);
218 base::RunLoop().RunUntilIdle();
219
220 // Partial whole-line reads are not supported. The last byte of the read must
221 // be a new line.
222 EXPECT_EQ(4, num_callback_calls_);
223 EXPECT_EQ("", latest_response_);
224
225 EXPECT_TRUE(AppendToFile("\n"));
226 source_.Fetch(callback_);
227 base::RunLoop().RunUntilIdle();
228
229 EXPECT_EQ(5, num_callback_calls_);
230 EXPECT_EQ("Hello world\nGoodbye world\n", latest_response_);
231 }
232
233 TEST_F(SingleLogSourceTest, Anonymize) {
234 EXPECT_TRUE(AppendToFile("My MAC address is: 11:22:33:44:55:66\n"));
235 source_.Fetch(callback_);
236 base::RunLoop().RunUntilIdle();
237
238 EXPECT_EQ(1, num_callback_calls_);
239 EXPECT_EQ("My MAC address is: 11:22:33:00:00:01\n", latest_response_);
240
241 // Suppose the write operation is not atomic, and the MAC address is written
242 // across two separate writes.
243 EXPECT_TRUE(AppendToFile("Your MAC address is: AB:88:C"));
244 source_.Fetch(callback_);
245 base::RunLoop().RunUntilIdle();
246
247 EXPECT_EQ(2, num_callback_calls_);
248 EXPECT_EQ("", latest_response_);
249
250 EXPECT_TRUE(AppendToFile("D:99:EF:77\n"));
251 source_.Fetch(callback_);
252 base::RunLoop().RunUntilIdle();
253
254 EXPECT_EQ(3, num_callback_calls_);
255 EXPECT_EQ("Your MAC address is: ab:88:cd:00:00:02\n", latest_response_);
256 }
257
258 } // namespace system_logs
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698