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

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

Issue 2939543002: Refactor SingleLogSource for better test coverage (Closed)
Patch Set: Created 3 years, 6 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
« no previous file with comments | « chrome/browser/chromeos/system_logs/single_log_source.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/chromeos/system_logs/single_log_source.h" 5 #include "chrome/browser/chromeos/system_logs/single_log_source.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/files/file_path.h" 10 #include "base/files/file_path.h"
11 #include "base/files/file_util.h" 11 #include "base/files/file_util.h"
12 #include "base/files/scoped_temp_dir.h" 12 #include "base/files/scoped_temp_dir.h"
13 #include "base/macros.h" 13 #include "base/macros.h"
14 #include "base/memory/ptr_util.h"
14 #include "base/run_loop.h" 15 #include "base/run_loop.h"
15 #include "base/test/scoped_task_environment.h" 16 #include "base/test/scoped_task_environment.h"
16 #include "content/public/test/test_browser_thread_bundle.h" 17 #include "content/public/test/test_browser_thread_bundle.h"
17 #include "testing/gtest/include/gtest/gtest.h" 18 #include "testing/gtest/include/gtest/gtest.h"
18 19
19 namespace system_logs { 20 namespace system_logs {
20 21
21 class SingleLogSourceTest : public ::testing::Test { 22 class SingleLogSourceTest : public ::testing::Test {
22 public: 23 public:
23 SingleLogSourceTest() 24 SingleLogSourceTest()
24 : scoped_task_environment_( 25 : scoped_task_environment_(
25 base::test::ScopedTaskEnvironment::MainThreadType::UI), 26 base::test::ScopedTaskEnvironment::MainThreadType::UI),
26 source_(SingleLogSource::SupportedSource::kMessages),
27 num_callback_calls_(0) { 27 num_callback_calls_(0) {
28 CHECK(dir_.CreateUniqueTempDir()); 28 InitializeTestLogDir();
29 log_file_path_ = dir_.GetPath().Append("log_file");
30
31 // Create the dummy log file for writing.
32 base::File new_file;
33 new_file.Initialize(log_file_path_, base::File::FLAG_CREATE_ALWAYS |
34 base::File::FLAG_WRITE);
35 new_file.Close();
36 CHECK(base::PathExists(log_file_path_));
37
38 // Open the dummy log file for reading from within the log source.
39 source_.file_.Initialize(log_file_path_,
40 base::File::FLAG_OPEN | base::File::FLAG_READ);
41 CHECK(source_.file_.IsValid());
42 } 29 }
43 30
44 ~SingleLogSourceTest() override {} 31 ~SingleLogSourceTest() override {}
45 32
46 // Writes a string to |log_file_path_|. 33 protected:
47 bool WriteFile(const std::string& input) { 34 // Sets up a dummy system log directory.
48 return base::WriteFile(log_file_path_, input.data(), input.size()); 35 void InitializeTestLogDir() {
36 ASSERT_TRUE(log_dir_.CreateUniqueTempDir());
37
38 // Create file "messages".
39 const base::FilePath messages_path = log_dir_.GetPath().Append("messages");
40 base::WriteFile(messages_path, "", 0);
41 EXPECT_TRUE(base::PathExists(messages_path)) << messages_path.value();
42
43 // Create file "ui/ui.LATEST".
44 const base::FilePath ui_dir_path = log_dir_.GetPath().Append("ui");
45 ASSERT_TRUE(base::CreateDirectory(ui_dir_path)) << ui_dir_path.value();
46
47 const base::FilePath ui_latest_path = ui_dir_path.Append("ui.LATEST");
48 base::WriteFile(ui_latest_path, "", 0);
49 ASSERT_TRUE(base::PathExists(ui_latest_path)) << ui_latest_path.value();
49 } 50 }
50 // Appends a string to |log_file_path_|. 51
51 bool AppendToFile(const std::string& input) { 52 // Initializes the unit under test, |source_| to read a file from the dummy
52 return base::AppendToFile(log_file_path_, input.data(), input.size()); 53 // system log directory.
54 void InitializeSource(SingleLogSource::SupportedSource source_type) {
55 source_ = base::MakeUnique<SingleLogSource>(source_type);
56 source_->log_file_dir_path_ = log_dir_.GetPath();
57 log_file_path_ = source_->log_file_dir_path_.Append(source_->source_name());
58 ASSERT_TRUE(base::PathExists(log_file_path_)) << log_file_path_.value();
59 }
60
61 // Writes/appends (respectively) a string |input| to file indicated by
62 // |relative_path| under |log_dir_|.
63 bool WriteFile(const base::FilePath& relative_path,
64 const std::string& input) {
65 return base::WriteFile(log_dir_.GetPath().Append(relative_path),
66 input.data(), input.size());
67 }
68 bool AppendToFile(const base::FilePath& relative_path,
69 const std::string& input) {
70 return base::AppendToFile(log_dir_.GetPath().Append(relative_path),
71 input.data(), input.size());
53 } 72 }
54 73
55 // Calls source_.Fetch() to start a logs fetch operation. Passes in 74 // Calls source_.Fetch() to start a logs fetch operation. Passes in
56 // OnFileRead() as a callback. Runs until Fetch() has completed. 75 // OnFileRead() as a callback. Runs until Fetch() has completed.
57 void FetchFromSource() { 76 void FetchFromSource() {
58 source_.Fetch( 77 source_->Fetch(
59 base::Bind(&SingleLogSourceTest::OnFileRead, base::Unretained(this))); 78 base::Bind(&SingleLogSourceTest::OnFileRead, base::Unretained(this)));
60 scoped_task_environment_.RunUntilIdle(); 79 scoped_task_environment_.RunUntilIdle();
61 } 80 }
62 81
63 // Callback for fetching logs from |source_|. Overwrites the previous stored 82 // Callback for fetching logs from |source_|. Overwrites the previous stored
64 // value of |latest_response_|. 83 // value of |latest_response_|.
65 void OnFileRead(SystemLogsResponse* response) { 84 void OnFileRead(SystemLogsResponse* response) {
66 ++num_callback_calls_; 85 ++num_callback_calls_;
67 if (response->empty()) 86 if (response->empty())
68 return; 87 return;
(...skipping 12 matching lines...) Expand all
81 100
82 private: 101 private:
83 // For running scheduled tasks. 102 // For running scheduled tasks.
84 base::test::ScopedTaskEnvironment scoped_task_environment_; 103 base::test::ScopedTaskEnvironment scoped_task_environment_;
85 104
86 // Creates the necessary browser threads. Defined after 105 // Creates the necessary browser threads. Defined after
87 // |scoped_task_environment_| in order to use the MessageLoop it created. 106 // |scoped_task_environment_| in order to use the MessageLoop it created.
88 content::TestBrowserThreadBundle browser_thread_bundle_; 107 content::TestBrowserThreadBundle browser_thread_bundle_;
89 108
90 // Unit under test. 109 // Unit under test.
91 SingleLogSource source_; 110 std::unique_ptr<SingleLogSource> source_;
92 111
93 // Counts the number of times that |source_| has invoked the callback. 112 // Counts the number of times that |source_| has invoked the callback.
94 int num_callback_calls_; 113 int num_callback_calls_;
95 114
96 // Stores the string response returned from |source_| the last time it invoked 115 // Stores the string response returned from |source_| the last time it invoked
97 // OnFileRead. 116 // OnFileRead.
98 std::string latest_response_; 117 std::string latest_response_;
99 118
100 // Temporary dir for creating a dummy log file. 119 // Temporary dir for creating a dummy log file.
101 base::ScopedTempDir dir_; 120 base::ScopedTempDir log_dir_;
102 121
103 // Path to the dummy log file in |dir_|. 122 // Path to the dummy log file in |log_dir_|.
104 base::FilePath log_file_path_; 123 base::FilePath log_file_path_;
105 124
106 DISALLOW_COPY_AND_ASSIGN(SingleLogSourceTest); 125 DISALLOW_COPY_AND_ASSIGN(SingleLogSourceTest);
107 }; 126 };
108 127
109 TEST_F(SingleLogSourceTest, EmptyFile) { 128 TEST_F(SingleLogSourceTest, EmptyFile) {
129 InitializeSource(SingleLogSource::SupportedSource::kMessages);
110 FetchFromSource(); 130 FetchFromSource();
111 131
112 EXPECT_EQ(1, num_callback_calls()); 132 EXPECT_EQ(1, num_callback_calls());
113 EXPECT_EQ("", latest_response()); 133 EXPECT_EQ("", latest_response());
114 } 134 }
115 135
116 TEST_F(SingleLogSourceTest, SingleRead) { 136 TEST_F(SingleLogSourceTest, SingleRead) {
117 EXPECT_TRUE(AppendToFile("Hello world!\n")); 137 InitializeSource(SingleLogSource::SupportedSource::kUiLatest);
138
139 EXPECT_TRUE(AppendToFile(base::FilePath("ui/ui.LATEST"), "Hello world!\n"));
118 FetchFromSource(); 140 FetchFromSource();
119 141
120 EXPECT_EQ(1, num_callback_calls()); 142 EXPECT_EQ(1, num_callback_calls());
121 EXPECT_EQ("Hello world!\n", latest_response()); 143 EXPECT_EQ("Hello world!\n", latest_response());
122 } 144 }
123 145
124 TEST_F(SingleLogSourceTest, IncrementalReads) { 146 TEST_F(SingleLogSourceTest, IncrementalReads) {
125 EXPECT_TRUE(AppendToFile("Hello world!\n")); 147 InitializeSource(SingleLogSource::SupportedSource::kMessages);
148
149 EXPECT_TRUE(AppendToFile(base::FilePath("messages"), "Hello world!\n"));
126 FetchFromSource(); 150 FetchFromSource();
127 151
128 EXPECT_EQ(1, num_callback_calls()); 152 EXPECT_EQ(1, num_callback_calls());
129 EXPECT_EQ("Hello world!\n", latest_response()); 153 EXPECT_EQ("Hello world!\n", latest_response());
130 154
131 EXPECT_TRUE(AppendToFile("The quick brown fox jumps over the lazy dog\n")); 155 EXPECT_TRUE(AppendToFile(base::FilePath("messages"),
156 "The quick brown fox jumps over the lazy dog\n"));
132 FetchFromSource(); 157 FetchFromSource();
133 158
134 EXPECT_EQ(2, num_callback_calls()); 159 EXPECT_EQ(2, num_callback_calls());
135 EXPECT_EQ("The quick brown fox jumps over the lazy dog\n", latest_response()); 160 EXPECT_EQ("The quick brown fox jumps over the lazy dog\n", latest_response());
136 161
137 EXPECT_TRUE(AppendToFile("Some like it hot.\nSome like it cold\n")); 162 EXPECT_TRUE(AppendToFile(base::FilePath("messages"),
163 "Some like it hot.\nSome like it cold\n"));
138 FetchFromSource(); 164 FetchFromSource();
139 165
140 EXPECT_EQ(3, num_callback_calls()); 166 EXPECT_EQ(3, num_callback_calls());
141 EXPECT_EQ("Some like it hot.\nSome like it cold\n", latest_response()); 167 EXPECT_EQ("Some like it hot.\nSome like it cold\n", latest_response());
142 168
143 // As a sanity check, read entire contents of file separately to make sure it 169 // As a sanity check, read entire contents of file separately to make sure it
144 // was written incrementally, and hence read incrementally. 170 // was written incrementally, and hence read incrementally.
145 std::string file_contents; 171 std::string file_contents;
146 EXPECT_TRUE(base::ReadFileToString(log_file_path(), &file_contents)); 172 EXPECT_TRUE(base::ReadFileToString(log_file_path(), &file_contents));
147 EXPECT_EQ( 173 EXPECT_EQ(
148 "Hello world!\nThe quick brown fox jumps over the lazy dog\n" 174 "Hello world!\nThe quick brown fox jumps over the lazy dog\n"
149 "Some like it hot.\nSome like it cold\n", 175 "Some like it hot.\nSome like it cold\n",
150 file_contents); 176 file_contents);
151 } 177 }
152 178
153 // The log files read by SingleLogSource are not expected to be overwritten. 179 // The log files read by SingleLogSource are not expected to be overwritten.
154 // This test is just to ensure that the SingleLogSource class is robust enough 180 // This test is just to ensure that the SingleLogSource class is robust enough
155 // not to break in the event of an overwrite. 181 // not to break in the event of an overwrite.
156 TEST_F(SingleLogSourceTest, FileOverwrite) { 182 TEST_F(SingleLogSourceTest, FileOverwrite) {
157 EXPECT_TRUE(AppendToFile("0123456789\n")); 183 InitializeSource(SingleLogSource::SupportedSource::kUiLatest);
184
185 EXPECT_TRUE(AppendToFile(base::FilePath("ui/ui.LATEST"), "0123456789\n"));
158 FetchFromSource(); 186 FetchFromSource();
159 187
160 EXPECT_EQ(1, num_callback_calls()); 188 EXPECT_EQ(1, num_callback_calls());
161 EXPECT_EQ("0123456789\n", latest_response()); 189 EXPECT_EQ("0123456789\n", latest_response());
162 190
163 // Overwrite the file. 191 // Overwrite the file.
164 EXPECT_TRUE(WriteFile("abcdefg\n")); 192 EXPECT_TRUE(WriteFile(base::FilePath("ui/ui.LATEST"), "abcdefg\n"));
165 FetchFromSource(); 193 FetchFromSource();
166 194
167 // Should re-read from the beginning. 195 // Should re-read from the beginning.
168 EXPECT_EQ(2, num_callback_calls()); 196 EXPECT_EQ(2, num_callback_calls());
169 EXPECT_EQ("abcdefg\n", latest_response()); 197 EXPECT_EQ("abcdefg\n", latest_response());
170 198
171 // Append to the file to make sure incremental read still works. 199 // Append to the file to make sure incremental read still works.
172 EXPECT_TRUE(AppendToFile("hijk\n")); 200 EXPECT_TRUE(AppendToFile(base::FilePath("ui/ui.LATEST"), "hijk\n"));
173 FetchFromSource(); 201 FetchFromSource();
174 202
175 EXPECT_EQ(3, num_callback_calls()); 203 EXPECT_EQ(3, num_callback_calls());
176 EXPECT_EQ("hijk\n", latest_response()); 204 EXPECT_EQ("hijk\n", latest_response());
177 205
178 // Overwrite again, this time with a longer length than the existing file. 206 // Overwrite again, this time with a longer length than the existing file.
179 // Previous contents: 207 // Previous contents:
180 // abcdefg~hijk~ <-- "~" is a single-char representation of newline. 208 // abcdefg~hijk~ <-- "~" is a single-char representation of newline.
181 // New contents: 209 // New contents:
182 // lmnopqrstuvwxyz~ <-- excess text beyond end of prev contents: "yz~" 210 // lmnopqrstuvwxyz~ <-- excess text beyond end of prev contents: "yz~"
183 EXPECT_TRUE(WriteFile("lmnopqrstuvwxyz\n")); 211 EXPECT_TRUE(WriteFile(base::FilePath("ui/ui.LATEST"), "lmnopqrstuvwxyz\n"));
184 FetchFromSource(); 212 FetchFromSource();
185 213
186 EXPECT_EQ(4, num_callback_calls()); 214 EXPECT_EQ(4, num_callback_calls());
187 EXPECT_EQ("yz\n", latest_response()); 215 EXPECT_EQ("yz\n", latest_response());
188 } 216 }
189 217
190 TEST_F(SingleLogSourceTest, IncompleteLines) { 218 TEST_F(SingleLogSourceTest, IncompleteLines) {
191 EXPECT_TRUE(AppendToFile("0123456789")); 219 InitializeSource(SingleLogSource::SupportedSource::kMessages);
220
221 EXPECT_TRUE(AppendToFile(base::FilePath("messages"), "0123456789"));
192 FetchFromSource(); 222 FetchFromSource();
193 223
194 EXPECT_EQ(1, num_callback_calls()); 224 EXPECT_EQ(1, num_callback_calls());
195 EXPECT_EQ("", latest_response()); 225 EXPECT_EQ("", latest_response());
196 226
197 EXPECT_TRUE(AppendToFile("abcdefg")); 227 EXPECT_TRUE(AppendToFile(base::FilePath("messages"), "abcdefg"));
198 FetchFromSource(); 228 FetchFromSource();
199 229
200 EXPECT_EQ(2, num_callback_calls()); 230 EXPECT_EQ(2, num_callback_calls());
201 EXPECT_EQ("", latest_response()); 231 EXPECT_EQ("", latest_response());
202 232
203 EXPECT_TRUE(AppendToFile("hijk\n")); 233 EXPECT_TRUE(AppendToFile(base::FilePath("messages"), "hijk\n"));
204 FetchFromSource(); 234 FetchFromSource();
205 235
206 EXPECT_EQ(3, num_callback_calls()); 236 EXPECT_EQ(3, num_callback_calls());
207 // All the previously written text should be read this time. 237 // All the previously written text should be read this time.
208 EXPECT_EQ("0123456789abcdefghijk\n", latest_response()); 238 EXPECT_EQ("0123456789abcdefghijk\n", latest_response());
209 239
210 EXPECT_TRUE(AppendToFile("Hello world\n")); 240 // Partial whole-line reads are not supported. The last byte of the read must
211 EXPECT_TRUE(AppendToFile("Goodbye world")); 241 // be a new line.
242 EXPECT_TRUE(AppendToFile(base::FilePath("messages"), "Hello world\n"));
243 EXPECT_TRUE(AppendToFile(base::FilePath("messages"), "Goodbye world"));
212 FetchFromSource(); 244 FetchFromSource();
213 245
214 // Partial whole-line reads are not supported. The last byte of the read must
215 // be a new line.
216 EXPECT_EQ(4, num_callback_calls()); 246 EXPECT_EQ(4, num_callback_calls());
217 EXPECT_EQ("", latest_response()); 247 EXPECT_EQ("", latest_response());
218 248
219 EXPECT_TRUE(AppendToFile("\n")); 249 EXPECT_TRUE(AppendToFile(base::FilePath("messages"), "\n"));
220 FetchFromSource(); 250 FetchFromSource();
221 251
222 EXPECT_EQ(5, num_callback_calls()); 252 EXPECT_EQ(5, num_callback_calls());
223 EXPECT_EQ("Hello world\nGoodbye world\n", latest_response()); 253 EXPECT_EQ("Hello world\nGoodbye world\n", latest_response());
224 } 254 }
225 255
226 TEST_F(SingleLogSourceTest, Anonymize) { 256 TEST_F(SingleLogSourceTest, Anonymize) {
227 EXPECT_TRUE(AppendToFile("My MAC address is: 11:22:33:44:55:66\n")); 257 InitializeSource(SingleLogSource::SupportedSource::kUiLatest);
258
259 EXPECT_TRUE(AppendToFile(base::FilePath("ui/ui.LATEST"),
260 "My MAC address is: 11:22:33:44:55:66\n"));
228 FetchFromSource(); 261 FetchFromSource();
229 262
230 EXPECT_EQ(1, num_callback_calls()); 263 EXPECT_EQ(1, num_callback_calls());
231 EXPECT_EQ("My MAC address is: 11:22:33:00:00:01\n", latest_response()); 264 EXPECT_EQ("My MAC address is: 11:22:33:00:00:01\n", latest_response());
232 265
233 // Suppose the write operation is not atomic, and the MAC address is written 266 // Suppose the write operation is not atomic, and the MAC address is written
234 // across two separate writes. 267 // across two separate writes.
235 EXPECT_TRUE(AppendToFile("Your MAC address is: AB:88:C")); 268 EXPECT_TRUE(AppendToFile(base::FilePath("ui/ui.LATEST"),
269 "Your MAC address is: AB:88:C"));
236 FetchFromSource(); 270 FetchFromSource();
237 271
238 EXPECT_EQ(2, num_callback_calls()); 272 EXPECT_EQ(2, num_callback_calls());
239 EXPECT_EQ("", latest_response()); 273 EXPECT_EQ("", latest_response());
240 274
241 EXPECT_TRUE(AppendToFile("D:99:EF:77\n")); 275 EXPECT_TRUE(AppendToFile(base::FilePath("ui/ui.LATEST"), "D:99:EF:77\n"));
242 FetchFromSource(); 276 FetchFromSource();
243 277
244 EXPECT_EQ(3, num_callback_calls()); 278 EXPECT_EQ(3, num_callback_calls());
245 EXPECT_EQ("Your MAC address is: ab:88:cd:00:00:02\n", latest_response()); 279 EXPECT_EQ("Your MAC address is: ab:88:cd:00:00:02\n", latest_response());
246 } 280 }
247 281
248 } // namespace system_logs 282 } // namespace system_logs
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/system_logs/single_log_source.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698