Remove PlatformFile from profile_browsertest
[chromium-blink-merge.git] / content / browser / download / base_file_unittest.cc
blob6fe652f3272d2e253e7544f9a32d6a509d9ebf1b
1 // Copyright (c) 2012 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.
5 #include "content/browser/download/base_file.h"
7 #include "base/file_util.h"
8 #include "base/files/scoped_temp_dir.h"
9 #include "base/logging.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/strings/string_number_conversions.h"
12 #include "base/test/test_file_util.h"
13 #include "content/browser/browser_thread_impl.h"
14 #include "content/public/browser/download_interrupt_reasons.h"
15 #include "crypto/secure_hash.h"
16 #include "crypto/sha2.h"
17 #include "net/base/file_stream.h"
18 #include "net/base/mock_file_stream.h"
19 #include "testing/gtest/include/gtest/gtest.h"
21 namespace content {
22 namespace {
24 const char kTestData1[] = "Let's write some data to the file!\n";
25 const char kTestData2[] = "Writing more data.\n";
26 const char kTestData3[] = "Final line.";
27 const char kTestData4[] = "supercalifragilisticexpialidocious";
28 const int kTestDataLength1 = arraysize(kTestData1) - 1;
29 const int kTestDataLength2 = arraysize(kTestData2) - 1;
30 const int kTestDataLength3 = arraysize(kTestData3) - 1;
31 const int kTestDataLength4 = arraysize(kTestData4) - 1;
32 const int kElapsedTimeSeconds = 5;
33 const base::TimeDelta kElapsedTimeDelta = base::TimeDelta::FromSeconds(
34 kElapsedTimeSeconds);
36 } // namespace
38 class BaseFileTest : public testing::Test {
39 public:
40 static const unsigned char kEmptySha256Hash[crypto::kSHA256Length];
42 BaseFileTest()
43 : expect_file_survives_(false),
44 expect_in_progress_(true),
45 expected_error_(DOWNLOAD_INTERRUPT_REASON_NONE),
46 file_thread_(BrowserThread::FILE, &message_loop_) {
49 virtual void SetUp() {
50 ResetHash();
51 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
52 base_file_.reset(new BaseFile(base::FilePath(),
53 GURL(),
54 GURL(),
56 false,
57 std::string(),
58 scoped_ptr<net::FileStream>(),
59 net::BoundNetLog()));
62 virtual void TearDown() {
63 EXPECT_FALSE(base_file_->in_progress());
64 if (!expected_error_) {
65 EXPECT_EQ(static_cast<int64>(expected_data_.size()),
66 base_file_->bytes_so_far());
69 base::FilePath full_path = base_file_->full_path();
71 if (!expected_data_.empty() && !expected_error_) {
72 // Make sure the data has been properly written to disk.
73 std::string disk_data;
74 EXPECT_TRUE(base::ReadFileToString(full_path, &disk_data));
75 EXPECT_EQ(expected_data_, disk_data);
78 // Make sure the mock BrowserThread outlives the BaseFile to satisfy
79 // thread checks inside it.
80 base_file_.reset();
82 EXPECT_EQ(expect_file_survives_, base::PathExists(full_path));
85 void ResetHash() {
86 secure_hash_.reset(crypto::SecureHash::Create(crypto::SecureHash::SHA256));
87 memcpy(sha256_hash_, kEmptySha256Hash, crypto::kSHA256Length);
90 void UpdateHash(const char* data, size_t length) {
91 secure_hash_->Update(data, length);
94 std::string GetFinalHash() {
95 std::string hash;
96 secure_hash_->Finish(sha256_hash_, crypto::kSHA256Length);
97 hash.assign(reinterpret_cast<const char*>(sha256_hash_),
98 sizeof(sha256_hash_));
99 return hash;
102 void MakeFileWithHash() {
103 base_file_.reset(new BaseFile(base::FilePath(),
104 GURL(),
105 GURL(),
107 true,
108 std::string(),
109 scoped_ptr<net::FileStream>(),
110 net::BoundNetLog()));
113 bool InitializeFile() {
114 DownloadInterruptReason result = base_file_->Initialize(temp_dir_.path());
115 EXPECT_EQ(expected_error_, result);
116 return result == DOWNLOAD_INTERRUPT_REASON_NONE;
119 bool AppendDataToFile(const std::string& data) {
120 EXPECT_EQ(expect_in_progress_, base_file_->in_progress());
121 DownloadInterruptReason result =
122 base_file_->AppendDataToFile(data.data(), data.size());
123 if (result == DOWNLOAD_INTERRUPT_REASON_NONE)
124 EXPECT_TRUE(expect_in_progress_) << " result = " << result;
126 EXPECT_EQ(expected_error_, result);
127 if (base_file_->in_progress()) {
128 expected_data_ += data;
129 if (expected_error_ == DOWNLOAD_INTERRUPT_REASON_NONE) {
130 EXPECT_EQ(static_cast<int64>(expected_data_.size()),
131 base_file_->bytes_so_far());
134 return result == DOWNLOAD_INTERRUPT_REASON_NONE;
137 void set_expected_data(const std::string& data) { expected_data_ = data; }
139 // Helper functions.
140 // Create a file. Returns the complete file path.
141 base::FilePath CreateTestFile() {
142 base::FilePath file_name;
143 BaseFile file(base::FilePath(),
144 GURL(),
145 GURL(),
147 false,
148 std::string(),
149 scoped_ptr<net::FileStream>(),
150 net::BoundNetLog());
152 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
153 file.Initialize(temp_dir_.path()));
154 file_name = file.full_path();
155 EXPECT_NE(base::FilePath::StringType(), file_name.value());
157 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
158 file.AppendDataToFile(kTestData4, kTestDataLength4));
160 // Keep the file from getting deleted when existing_file_name is deleted.
161 file.Detach();
163 return file_name;
166 // Create a file with the specified file name.
167 void CreateFileWithName(const base::FilePath& file_name) {
168 EXPECT_NE(base::FilePath::StringType(), file_name.value());
169 BaseFile duplicate_file(file_name,
170 GURL(),
171 GURL(),
173 false,
174 std::string(),
175 scoped_ptr<net::FileStream>(),
176 net::BoundNetLog());
177 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
178 duplicate_file.Initialize(temp_dir_.path()));
179 // Write something into it.
180 duplicate_file.AppendDataToFile(kTestData4, kTestDataLength4);
181 // Detach the file so it isn't deleted on destruction of |duplicate_file|.
182 duplicate_file.Detach();
185 int64 CurrentSpeedAtTime(base::TimeTicks current_time) {
186 EXPECT_TRUE(base_file_.get());
187 return base_file_->CurrentSpeedAtTime(current_time);
190 base::TimeTicks StartTick() {
191 EXPECT_TRUE(base_file_.get());
192 return base_file_->start_tick_;
195 void set_expected_error(DownloadInterruptReason err) {
196 expected_error_ = err;
199 protected:
200 linked_ptr<net::testing::MockFileStream> mock_file_stream_;
202 // BaseClass instance we are testing.
203 scoped_ptr<BaseFile> base_file_;
205 // Temporary directory for renamed downloads.
206 base::ScopedTempDir temp_dir_;
208 // Expect the file to survive deletion of the BaseFile instance.
209 bool expect_file_survives_;
211 // Expect the file to be in progress.
212 bool expect_in_progress_;
214 // Hash calculator.
215 scoped_ptr<crypto::SecureHash> secure_hash_;
217 unsigned char sha256_hash_[crypto::kSHA256Length];
219 private:
220 // Keep track of what data should be saved to the disk file.
221 std::string expected_data_;
222 DownloadInterruptReason expected_error_;
224 // Mock file thread to satisfy debug checks in BaseFile.
225 base::MessageLoop message_loop_;
226 BrowserThreadImpl file_thread_;
229 // This will initialize the entire array to zero.
230 const unsigned char BaseFileTest::kEmptySha256Hash[] = { 0 };
232 // Test the most basic scenario: just create the object and do a sanity check
233 // on all its accessors. This is actually a case that rarely happens
234 // in production, where we would at least Initialize it.
235 TEST_F(BaseFileTest, CreateDestroy) {
236 EXPECT_EQ(base::FilePath().value(), base_file_->full_path().value());
239 // Cancel the download explicitly.
240 TEST_F(BaseFileTest, Cancel) {
241 ASSERT_TRUE(InitializeFile());
242 EXPECT_TRUE(base::PathExists(base_file_->full_path()));
243 base_file_->Cancel();
244 EXPECT_FALSE(base::PathExists(base_file_->full_path()));
245 EXPECT_NE(base::FilePath().value(), base_file_->full_path().value());
248 // Write data to the file and detach it, so it doesn't get deleted
249 // automatically when base_file_ is destructed.
250 TEST_F(BaseFileTest, WriteAndDetach) {
251 ASSERT_TRUE(InitializeFile());
252 ASSERT_TRUE(AppendDataToFile(kTestData1));
253 base_file_->Finish();
254 base_file_->Detach();
255 expect_file_survives_ = true;
258 // Write data to the file and detach it, and calculate its sha256 hash.
259 TEST_F(BaseFileTest, WriteWithHashAndDetach) {
260 // Calculate the final hash.
261 ResetHash();
262 UpdateHash(kTestData1, kTestDataLength1);
263 std::string expected_hash = GetFinalHash();
264 std::string expected_hash_hex =
265 base::HexEncode(expected_hash.data(), expected_hash.size());
267 MakeFileWithHash();
268 ASSERT_TRUE(InitializeFile());
269 ASSERT_TRUE(AppendDataToFile(kTestData1));
270 base_file_->Finish();
272 std::string hash;
273 base_file_->GetHash(&hash);
274 EXPECT_EQ("0B2D3F3F7943AD64B860DF94D05CB56A8A97C6EC5768B5B70B930C5AA7FA9ADE",
275 expected_hash_hex);
276 EXPECT_EQ(expected_hash_hex, base::HexEncode(hash.data(), hash.size()));
278 base_file_->Detach();
279 expect_file_survives_ = true;
282 // Rename the file after writing to it, then detach.
283 TEST_F(BaseFileTest, WriteThenRenameAndDetach) {
284 ASSERT_TRUE(InitializeFile());
286 base::FilePath initial_path(base_file_->full_path());
287 EXPECT_TRUE(base::PathExists(initial_path));
288 base::FilePath new_path(temp_dir_.path().AppendASCII("NewFile"));
289 EXPECT_FALSE(base::PathExists(new_path));
291 ASSERT_TRUE(AppendDataToFile(kTestData1));
293 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, base_file_->Rename(new_path));
294 EXPECT_FALSE(base::PathExists(initial_path));
295 EXPECT_TRUE(base::PathExists(new_path));
297 base_file_->Finish();
298 base_file_->Detach();
299 expect_file_survives_ = true;
302 // Write data to the file once.
303 TEST_F(BaseFileTest, SingleWrite) {
304 ASSERT_TRUE(InitializeFile());
305 ASSERT_TRUE(AppendDataToFile(kTestData1));
306 base_file_->Finish();
309 // Write data to the file multiple times.
310 TEST_F(BaseFileTest, MultipleWrites) {
311 ASSERT_TRUE(InitializeFile());
312 ASSERT_TRUE(AppendDataToFile(kTestData1));
313 ASSERT_TRUE(AppendDataToFile(kTestData2));
314 ASSERT_TRUE(AppendDataToFile(kTestData3));
315 std::string hash;
316 EXPECT_FALSE(base_file_->GetHash(&hash));
317 base_file_->Finish();
320 // Write data to the file once and calculate its sha256 hash.
321 TEST_F(BaseFileTest, SingleWriteWithHash) {
322 // Calculate the final hash.
323 ResetHash();
324 UpdateHash(kTestData1, kTestDataLength1);
325 std::string expected_hash = GetFinalHash();
326 std::string expected_hash_hex =
327 base::HexEncode(expected_hash.data(), expected_hash.size());
329 MakeFileWithHash();
330 ASSERT_TRUE(InitializeFile());
331 // Can get partial hash states before Finish() is called.
332 EXPECT_STRNE(std::string().c_str(), base_file_->GetHashState().c_str());
333 ASSERT_TRUE(AppendDataToFile(kTestData1));
334 EXPECT_STRNE(std::string().c_str(), base_file_->GetHashState().c_str());
335 base_file_->Finish();
337 std::string hash;
338 base_file_->GetHash(&hash);
339 EXPECT_EQ(expected_hash_hex, base::HexEncode(hash.data(), hash.size()));
342 // Write data to the file multiple times and calculate its sha256 hash.
343 TEST_F(BaseFileTest, MultipleWritesWithHash) {
344 // Calculate the final hash.
345 ResetHash();
346 UpdateHash(kTestData1, kTestDataLength1);
347 UpdateHash(kTestData2, kTestDataLength2);
348 UpdateHash(kTestData3, kTestDataLength3);
349 std::string expected_hash = GetFinalHash();
350 std::string expected_hash_hex =
351 base::HexEncode(expected_hash.data(), expected_hash.size());
353 std::string hash;
354 MakeFileWithHash();
355 ASSERT_TRUE(InitializeFile());
356 ASSERT_TRUE(AppendDataToFile(kTestData1));
357 ASSERT_TRUE(AppendDataToFile(kTestData2));
358 ASSERT_TRUE(AppendDataToFile(kTestData3));
359 // No hash before Finish() is called.
360 EXPECT_FALSE(base_file_->GetHash(&hash));
361 base_file_->Finish();
363 EXPECT_TRUE(base_file_->GetHash(&hash));
364 EXPECT_EQ("CBF68BF10F8003DB86B31343AFAC8C7175BD03FB5FC905650F8C80AF087443A8",
365 expected_hash_hex);
366 EXPECT_EQ(expected_hash_hex, base::HexEncode(hash.data(), hash.size()));
369 // Write data to the file multiple times, interrupt it, and continue using
370 // another file. Calculate the resulting combined sha256 hash.
371 TEST_F(BaseFileTest, MultipleWritesInterruptedWithHash) {
372 // Calculate the final hash.
373 ResetHash();
374 UpdateHash(kTestData1, kTestDataLength1);
375 UpdateHash(kTestData2, kTestDataLength2);
376 UpdateHash(kTestData3, kTestDataLength3);
377 std::string expected_hash = GetFinalHash();
378 std::string expected_hash_hex =
379 base::HexEncode(expected_hash.data(), expected_hash.size());
381 MakeFileWithHash();
382 ASSERT_TRUE(InitializeFile());
383 // Write some data
384 ASSERT_TRUE(AppendDataToFile(kTestData1));
385 ASSERT_TRUE(AppendDataToFile(kTestData2));
386 // Get the hash state and file name.
387 std::string hash_state;
388 hash_state = base_file_->GetHashState();
389 // Finish the file.
390 base_file_->Finish();
392 base::FilePath new_file_path(temp_dir_.path().Append(
393 base::FilePath(FILE_PATH_LITERAL("second_file"))));
395 ASSERT_TRUE(base::CopyFile(base_file_->full_path(), new_file_path));
397 // Create another file
398 BaseFile second_file(new_file_path,
399 GURL(),
400 GURL(),
401 base_file_->bytes_so_far(),
402 true,
403 hash_state,
404 scoped_ptr<net::FileStream>(),
405 net::BoundNetLog());
406 ASSERT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
407 second_file.Initialize(base::FilePath()));
408 std::string data(kTestData3);
409 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
410 second_file.AppendDataToFile(data.data(), data.size()));
411 second_file.Finish();
413 std::string hash;
414 EXPECT_TRUE(second_file.GetHash(&hash));
415 // This will fail until getting the hash state is supported in SecureHash.
416 EXPECT_STREQ(expected_hash_hex.c_str(),
417 base::HexEncode(hash.data(), hash.size()).c_str());
420 // Rename the file after all writes to it.
421 TEST_F(BaseFileTest, WriteThenRename) {
422 ASSERT_TRUE(InitializeFile());
424 base::FilePath initial_path(base_file_->full_path());
425 EXPECT_TRUE(base::PathExists(initial_path));
426 base::FilePath new_path(temp_dir_.path().AppendASCII("NewFile"));
427 EXPECT_FALSE(base::PathExists(new_path));
429 ASSERT_TRUE(AppendDataToFile(kTestData1));
431 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
432 base_file_->Rename(new_path));
433 EXPECT_FALSE(base::PathExists(initial_path));
434 EXPECT_TRUE(base::PathExists(new_path));
436 base_file_->Finish();
439 // Rename the file while the download is still in progress.
440 TEST_F(BaseFileTest, RenameWhileInProgress) {
441 ASSERT_TRUE(InitializeFile());
443 base::FilePath initial_path(base_file_->full_path());
444 EXPECT_TRUE(base::PathExists(initial_path));
445 base::FilePath new_path(temp_dir_.path().AppendASCII("NewFile"));
446 EXPECT_FALSE(base::PathExists(new_path));
448 ASSERT_TRUE(AppendDataToFile(kTestData1));
450 EXPECT_TRUE(base_file_->in_progress());
451 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, base_file_->Rename(new_path));
452 EXPECT_FALSE(base::PathExists(initial_path));
453 EXPECT_TRUE(base::PathExists(new_path));
455 ASSERT_TRUE(AppendDataToFile(kTestData2));
457 base_file_->Finish();
460 // Test that a failed rename reports the correct error.
461 TEST_F(BaseFileTest, RenameWithError) {
462 ASSERT_TRUE(InitializeFile());
464 // TestDir is a subdirectory in |temp_dir_| that we will make read-only so
465 // that the rename will fail.
466 base::FilePath test_dir(temp_dir_.path().AppendASCII("TestDir"));
467 ASSERT_TRUE(base::CreateDirectory(test_dir));
469 base::FilePath new_path(test_dir.AppendASCII("TestFile"));
470 EXPECT_FALSE(base::PathExists(new_path));
473 file_util::PermissionRestorer restore_permissions_for(test_dir);
474 ASSERT_TRUE(file_util::MakeFileUnwritable(test_dir));
475 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED,
476 base_file_->Rename(new_path));
479 base_file_->Finish();
482 // Write data to the file multiple times.
483 TEST_F(BaseFileTest, MultipleWritesWithError) {
484 base::FilePath path;
485 ASSERT_TRUE(base::CreateTemporaryFile(&path));
486 // Create a new file stream. scoped_ptr takes ownership and passes it to
487 // BaseFile; we use the pointer anyway and rely on the BaseFile not
488 // deleting the MockFileStream until the BaseFile is reset.
489 net::testing::MockFileStream* mock_file_stream(
490 new net::testing::MockFileStream(NULL));
491 scoped_ptr<net::FileStream> mock_file_stream_scoped_ptr(mock_file_stream);
493 ASSERT_EQ(0,
494 mock_file_stream->OpenSync(
495 path,
496 base::PLATFORM_FILE_OPEN_ALWAYS | base::PLATFORM_FILE_WRITE));
498 // Copy of mock_file_stream; we pass ownership and rely on the BaseFile
499 // not deleting it until it is reset.
501 base_file_.reset(new BaseFile(mock_file_stream->get_path(),
502 GURL(),
503 GURL(),
505 false,
506 std::string(),
507 mock_file_stream_scoped_ptr.Pass(),
508 net::BoundNetLog()));
509 ASSERT_TRUE(InitializeFile());
510 ASSERT_TRUE(AppendDataToFile(kTestData1));
511 ASSERT_TRUE(AppendDataToFile(kTestData2));
512 mock_file_stream->set_forced_error(net::ERR_ACCESS_DENIED);
513 set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED);
514 ASSERT_FALSE(AppendDataToFile(kTestData3));
515 std::string hash;
516 EXPECT_FALSE(base_file_->GetHash(&hash));
517 base_file_->Finish();
520 // Try to write to uninitialized file.
521 TEST_F(BaseFileTest, UninitializedFile) {
522 expect_in_progress_ = false;
523 set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED);
524 EXPECT_FALSE(AppendDataToFile(kTestData1));
527 // Create two |BaseFile|s with the same file, and attempt to write to both.
528 // Overwrite base_file_ with another file with the same name and
529 // non-zero contents, and make sure the last file to close 'wins'.
530 TEST_F(BaseFileTest, DuplicateBaseFile) {
531 ASSERT_TRUE(InitializeFile());
533 // Create another |BaseFile| referring to the file that |base_file_| owns.
534 CreateFileWithName(base_file_->full_path());
536 ASSERT_TRUE(AppendDataToFile(kTestData1));
537 base_file_->Finish();
540 // Create a file and append to it.
541 TEST_F(BaseFileTest, AppendToBaseFile) {
542 // Create a new file.
543 base::FilePath existing_file_name = CreateTestFile();
545 set_expected_data(kTestData4);
547 // Use the file we've just created.
548 base_file_.reset(new BaseFile(existing_file_name,
549 GURL(),
550 GURL(),
551 kTestDataLength4,
552 false,
553 std::string(),
554 scoped_ptr<net::FileStream>(),
555 net::BoundNetLog()));
557 ASSERT_TRUE(InitializeFile());
559 const base::FilePath file_name = base_file_->full_path();
560 EXPECT_NE(base::FilePath::StringType(), file_name.value());
562 // Write into the file.
563 EXPECT_TRUE(AppendDataToFile(kTestData1));
565 base_file_->Finish();
566 base_file_->Detach();
567 expect_file_survives_ = true;
570 // Create a read-only file and attempt to write to it.
571 TEST_F(BaseFileTest, ReadonlyBaseFile) {
572 // Create a new file.
573 base::FilePath readonly_file_name = CreateTestFile();
575 // Restore permissions to the file when we are done with this test.
576 file_util::PermissionRestorer restore_permissions(readonly_file_name);
578 // Make it read-only.
579 EXPECT_TRUE(file_util::MakeFileUnwritable(readonly_file_name));
581 // Try to overwrite it.
582 base_file_.reset(new BaseFile(readonly_file_name,
583 GURL(),
584 GURL(),
586 false,
587 std::string(),
588 scoped_ptr<net::FileStream>(),
589 net::BoundNetLog()));
591 expect_in_progress_ = false;
592 set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED);
593 EXPECT_FALSE(InitializeFile());
595 const base::FilePath file_name = base_file_->full_path();
596 EXPECT_NE(base::FilePath::StringType(), file_name.value());
598 // Write into the file.
599 set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED);
600 EXPECT_FALSE(AppendDataToFile(kTestData1));
602 base_file_->Finish();
603 base_file_->Detach();
604 expect_file_survives_ = true;
607 TEST_F(BaseFileTest, IsEmptyHash) {
608 std::string empty(crypto::kSHA256Length, '\x00');
609 EXPECT_TRUE(BaseFile::IsEmptyHash(empty));
610 std::string not_empty(crypto::kSHA256Length, '\x01');
611 EXPECT_FALSE(BaseFile::IsEmptyHash(not_empty));
612 EXPECT_FALSE(BaseFile::IsEmptyHash(std::string()));
614 std::string also_not_empty = empty;
615 also_not_empty[crypto::kSHA256Length - 1] = '\x01';
616 EXPECT_FALSE(BaseFile::IsEmptyHash(also_not_empty));
619 // Test that a temporary file is created in the default download directory.
620 TEST_F(BaseFileTest, CreatedInDefaultDirectory) {
621 ASSERT_TRUE(base_file_->full_path().empty());
622 ASSERT_TRUE(InitializeFile());
623 EXPECT_FALSE(base_file_->full_path().empty());
625 // On Windows, CreateTemporaryFileInDir() will cause a path with short names
626 // to be expanded into a path with long names. Thus temp_dir.path() might not
627 // be a string-wise match to base_file_->full_path().DirName() even though
628 // they are in the same directory.
629 base::FilePath temp_file;
630 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &temp_file));
631 ASSERT_FALSE(temp_file.empty());
632 EXPECT_STREQ(temp_file.DirName().value().c_str(),
633 base_file_->full_path().DirName().value().c_str());
634 base_file_->Finish();
637 } // namespace content