Home | History | Annotate | Download | only in download
      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.
      4 
      5 #include "content/browser/download/base_file.h"
      6 
      7 #include "base/file_util.h"
      8 #include "base/files/file.h"
      9 #include "base/files/scoped_temp_dir.h"
     10 #include "base/logging.h"
     11 #include "base/message_loop/message_loop.h"
     12 #include "base/strings/string_number_conversions.h"
     13 #include "base/test/test_file_util.h"
     14 #include "content/browser/browser_thread_impl.h"
     15 #include "content/public/browser/download_interrupt_reasons.h"
     16 #include "crypto/secure_hash.h"
     17 #include "crypto/sha2.h"
     18 #include "testing/gtest/include/gtest/gtest.h"
     19 
     20 namespace content {
     21 namespace {
     22 
     23 const char kTestData1[] = "Let's write some data to the file!\n";
     24 const char kTestData2[] = "Writing more data.\n";
     25 const char kTestData3[] = "Final line.";
     26 const char kTestData4[] = "supercalifragilisticexpialidocious";
     27 const int kTestDataLength1 = arraysize(kTestData1) - 1;
     28 const int kTestDataLength2 = arraysize(kTestData2) - 1;
     29 const int kTestDataLength3 = arraysize(kTestData3) - 1;
     30 const int kTestDataLength4 = arraysize(kTestData4) - 1;
     31 const int kElapsedTimeSeconds = 5;
     32 const base::TimeDelta kElapsedTimeDelta = base::TimeDelta::FromSeconds(
     33     kElapsedTimeSeconds);
     34 
     35 }  // namespace
     36 
     37 class BaseFileTest : public testing::Test {
     38  public:
     39   static const unsigned char kEmptySha256Hash[crypto::kSHA256Length];
     40 
     41   BaseFileTest()
     42       : expect_file_survives_(false),
     43         expect_in_progress_(true),
     44         expected_error_(DOWNLOAD_INTERRUPT_REASON_NONE),
     45         file_thread_(BrowserThread::FILE, &message_loop_) {
     46   }
     47 
     48   virtual void SetUp() {
     49     ResetHash();
     50     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
     51     base_file_.reset(new BaseFile(base::FilePath(),
     52                                   GURL(),
     53                                   GURL(),
     54                                   0,
     55                                   false,
     56                                   std::string(),
     57                                   base::File(),
     58                                   net::BoundNetLog()));
     59   }
     60 
     61   virtual void TearDown() {
     62     EXPECT_FALSE(base_file_->in_progress());
     63     if (!expected_error_) {
     64       EXPECT_EQ(static_cast<int64>(expected_data_.size()),
     65                 base_file_->bytes_so_far());
     66     }
     67 
     68     base::FilePath full_path = base_file_->full_path();
     69 
     70     if (!expected_data_.empty() && !expected_error_) {
     71       // Make sure the data has been properly written to disk.
     72       std::string disk_data;
     73       EXPECT_TRUE(base::ReadFileToString(full_path, &disk_data));
     74       EXPECT_EQ(expected_data_, disk_data);
     75     }
     76 
     77     // Make sure the mock BrowserThread outlives the BaseFile to satisfy
     78     // thread checks inside it.
     79     base_file_.reset();
     80 
     81     EXPECT_EQ(expect_file_survives_, base::PathExists(full_path));
     82   }
     83 
     84   void ResetHash() {
     85     secure_hash_.reset(crypto::SecureHash::Create(crypto::SecureHash::SHA256));
     86     memcpy(sha256_hash_, kEmptySha256Hash, crypto::kSHA256Length);
     87   }
     88 
     89   void UpdateHash(const char* data, size_t length) {
     90     secure_hash_->Update(data, length);
     91   }
     92 
     93   std::string GetFinalHash() {
     94     std::string hash;
     95     secure_hash_->Finish(sha256_hash_, crypto::kSHA256Length);
     96     hash.assign(reinterpret_cast<const char*>(sha256_hash_),
     97                 sizeof(sha256_hash_));
     98     return hash;
     99   }
    100 
    101   void MakeFileWithHash() {
    102     base_file_.reset(new BaseFile(base::FilePath(),
    103                                   GURL(),
    104                                   GURL(),
    105                                   0,
    106                                   true,
    107                                   std::string(),
    108                                   base::File(),
    109                                   net::BoundNetLog()));
    110   }
    111 
    112   bool InitializeFile() {
    113     DownloadInterruptReason result = base_file_->Initialize(temp_dir_.path());
    114     EXPECT_EQ(expected_error_, result);
    115     return result == DOWNLOAD_INTERRUPT_REASON_NONE;
    116   }
    117 
    118   bool AppendDataToFile(const std::string& data) {
    119     EXPECT_EQ(expect_in_progress_, base_file_->in_progress());
    120     DownloadInterruptReason result =
    121         base_file_->AppendDataToFile(data.data(), data.size());
    122     if (result == DOWNLOAD_INTERRUPT_REASON_NONE)
    123       EXPECT_TRUE(expect_in_progress_) << " result = " << result;
    124 
    125     EXPECT_EQ(expected_error_, result);
    126     if (base_file_->in_progress()) {
    127       expected_data_ += data;
    128       if (expected_error_ == DOWNLOAD_INTERRUPT_REASON_NONE) {
    129         EXPECT_EQ(static_cast<int64>(expected_data_.size()),
    130                   base_file_->bytes_so_far());
    131       }
    132     }
    133     return result == DOWNLOAD_INTERRUPT_REASON_NONE;
    134   }
    135 
    136   void set_expected_data(const std::string& data) { expected_data_ = data; }
    137 
    138   // Helper functions.
    139   // Create a file.  Returns the complete file path.
    140   base::FilePath CreateTestFile() {
    141     base::FilePath file_name;
    142     BaseFile file(base::FilePath(),
    143                   GURL(),
    144                   GURL(),
    145                   0,
    146                   false,
    147                   std::string(),
    148                   base::File(),
    149                   net::BoundNetLog());
    150 
    151     EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
    152               file.Initialize(temp_dir_.path()));
    153     file_name = file.full_path();
    154     EXPECT_NE(base::FilePath::StringType(), file_name.value());
    155 
    156     EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
    157               file.AppendDataToFile(kTestData4, kTestDataLength4));
    158 
    159     // Keep the file from getting deleted when existing_file_name is deleted.
    160     file.Detach();
    161 
    162     return file_name;
    163   }
    164 
    165   // Create a file with the specified file name.
    166   void CreateFileWithName(const base::FilePath& file_name) {
    167     EXPECT_NE(base::FilePath::StringType(), file_name.value());
    168     BaseFile duplicate_file(file_name,
    169                             GURL(),
    170                             GURL(),
    171                             0,
    172                             false,
    173                             std::string(),
    174                             base::File(),
    175                             net::BoundNetLog());
    176     EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
    177               duplicate_file.Initialize(temp_dir_.path()));
    178     // Write something into it.
    179     duplicate_file.AppendDataToFile(kTestData4, kTestDataLength4);
    180     // Detach the file so it isn't deleted on destruction of |duplicate_file|.
    181     duplicate_file.Detach();
    182   }
    183 
    184   int64 CurrentSpeedAtTime(base::TimeTicks current_time) {
    185     EXPECT_TRUE(base_file_.get());
    186     return base_file_->CurrentSpeedAtTime(current_time);
    187   }
    188 
    189   base::TimeTicks StartTick() {
    190     EXPECT_TRUE(base_file_.get());
    191     return base_file_->start_tick_;
    192   }
    193 
    194   void set_expected_error(DownloadInterruptReason err) {
    195     expected_error_ = err;
    196   }
    197 
    198  protected:
    199   // BaseClass instance we are testing.
    200   scoped_ptr<BaseFile> base_file_;
    201 
    202   // Temporary directory for renamed downloads.
    203   base::ScopedTempDir temp_dir_;
    204 
    205   // Expect the file to survive deletion of the BaseFile instance.
    206   bool expect_file_survives_;
    207 
    208   // Expect the file to be in progress.
    209   bool expect_in_progress_;
    210 
    211   // Hash calculator.
    212   scoped_ptr<crypto::SecureHash> secure_hash_;
    213 
    214   unsigned char sha256_hash_[crypto::kSHA256Length];
    215 
    216  private:
    217   // Keep track of what data should be saved to the disk file.
    218   std::string expected_data_;
    219   DownloadInterruptReason expected_error_;
    220 
    221   // Mock file thread to satisfy debug checks in BaseFile.
    222   base::MessageLoop message_loop_;
    223   BrowserThreadImpl file_thread_;
    224 };
    225 
    226 // This will initialize the entire array to zero.
    227 const unsigned char BaseFileTest::kEmptySha256Hash[] = { 0 };
    228 
    229 // Test the most basic scenario: just create the object and do a sanity check
    230 // on all its accessors. This is actually a case that rarely happens
    231 // in production, where we would at least Initialize it.
    232 TEST_F(BaseFileTest, CreateDestroy) {
    233   EXPECT_EQ(base::FilePath().value(), base_file_->full_path().value());
    234 }
    235 
    236 // Cancel the download explicitly.
    237 TEST_F(BaseFileTest, Cancel) {
    238   ASSERT_TRUE(InitializeFile());
    239   EXPECT_TRUE(base::PathExists(base_file_->full_path()));
    240   base_file_->Cancel();
    241   EXPECT_FALSE(base::PathExists(base_file_->full_path()));
    242   EXPECT_NE(base::FilePath().value(), base_file_->full_path().value());
    243 }
    244 
    245 // Write data to the file and detach it, so it doesn't get deleted
    246 // automatically when base_file_ is destructed.
    247 TEST_F(BaseFileTest, WriteAndDetach) {
    248   ASSERT_TRUE(InitializeFile());
    249   ASSERT_TRUE(AppendDataToFile(kTestData1));
    250   base_file_->Finish();
    251   base_file_->Detach();
    252   expect_file_survives_ = true;
    253 }
    254 
    255 // Write data to the file and detach it, and calculate its sha256 hash.
    256 TEST_F(BaseFileTest, WriteWithHashAndDetach) {
    257   // Calculate the final hash.
    258   ResetHash();
    259   UpdateHash(kTestData1, kTestDataLength1);
    260   std::string expected_hash = GetFinalHash();
    261   std::string expected_hash_hex =
    262       base::HexEncode(expected_hash.data(), expected_hash.size());
    263 
    264   MakeFileWithHash();
    265   ASSERT_TRUE(InitializeFile());
    266   ASSERT_TRUE(AppendDataToFile(kTestData1));
    267   base_file_->Finish();
    268 
    269   std::string hash;
    270   base_file_->GetHash(&hash);
    271   EXPECT_EQ("0B2D3F3F7943AD64B860DF94D05CB56A8A97C6EC5768B5B70B930C5AA7FA9ADE",
    272             expected_hash_hex);
    273   EXPECT_EQ(expected_hash_hex, base::HexEncode(hash.data(), hash.size()));
    274 
    275   base_file_->Detach();
    276   expect_file_survives_ = true;
    277 }
    278 
    279 // Rename the file after writing to it, then detach.
    280 TEST_F(BaseFileTest, WriteThenRenameAndDetach) {
    281   ASSERT_TRUE(InitializeFile());
    282 
    283   base::FilePath initial_path(base_file_->full_path());
    284   EXPECT_TRUE(base::PathExists(initial_path));
    285   base::FilePath new_path(temp_dir_.path().AppendASCII("NewFile"));
    286   EXPECT_FALSE(base::PathExists(new_path));
    287 
    288   ASSERT_TRUE(AppendDataToFile(kTestData1));
    289 
    290   EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, base_file_->Rename(new_path));
    291   EXPECT_FALSE(base::PathExists(initial_path));
    292   EXPECT_TRUE(base::PathExists(new_path));
    293 
    294   base_file_->Finish();
    295   base_file_->Detach();
    296   expect_file_survives_ = true;
    297 }
    298 
    299 // Write data to the file once.
    300 TEST_F(BaseFileTest, SingleWrite) {
    301   ASSERT_TRUE(InitializeFile());
    302   ASSERT_TRUE(AppendDataToFile(kTestData1));
    303   base_file_->Finish();
    304 }
    305 
    306 // Write data to the file multiple times.
    307 TEST_F(BaseFileTest, MultipleWrites) {
    308   ASSERT_TRUE(InitializeFile());
    309   ASSERT_TRUE(AppendDataToFile(kTestData1));
    310   ASSERT_TRUE(AppendDataToFile(kTestData2));
    311   ASSERT_TRUE(AppendDataToFile(kTestData3));
    312   std::string hash;
    313   EXPECT_FALSE(base_file_->GetHash(&hash));
    314   base_file_->Finish();
    315 }
    316 
    317 // Write data to the file once and calculate its sha256 hash.
    318 TEST_F(BaseFileTest, SingleWriteWithHash) {
    319   // Calculate the final hash.
    320   ResetHash();
    321   UpdateHash(kTestData1, kTestDataLength1);
    322   std::string expected_hash = GetFinalHash();
    323   std::string expected_hash_hex =
    324       base::HexEncode(expected_hash.data(), expected_hash.size());
    325 
    326   MakeFileWithHash();
    327   ASSERT_TRUE(InitializeFile());
    328   // Can get partial hash states before Finish() is called.
    329   EXPECT_STRNE(std::string().c_str(), base_file_->GetHashState().c_str());
    330   ASSERT_TRUE(AppendDataToFile(kTestData1));
    331   EXPECT_STRNE(std::string().c_str(), base_file_->GetHashState().c_str());
    332   base_file_->Finish();
    333 
    334   std::string hash;
    335   base_file_->GetHash(&hash);
    336   EXPECT_EQ(expected_hash_hex, base::HexEncode(hash.data(), hash.size()));
    337 }
    338 
    339 // Write data to the file multiple times and calculate its sha256 hash.
    340 TEST_F(BaseFileTest, MultipleWritesWithHash) {
    341   // Calculate the final hash.
    342   ResetHash();
    343   UpdateHash(kTestData1, kTestDataLength1);
    344   UpdateHash(kTestData2, kTestDataLength2);
    345   UpdateHash(kTestData3, kTestDataLength3);
    346   std::string expected_hash = GetFinalHash();
    347   std::string expected_hash_hex =
    348       base::HexEncode(expected_hash.data(), expected_hash.size());
    349 
    350   std::string hash;
    351   MakeFileWithHash();
    352   ASSERT_TRUE(InitializeFile());
    353   ASSERT_TRUE(AppendDataToFile(kTestData1));
    354   ASSERT_TRUE(AppendDataToFile(kTestData2));
    355   ASSERT_TRUE(AppendDataToFile(kTestData3));
    356   // No hash before Finish() is called.
    357   EXPECT_FALSE(base_file_->GetHash(&hash));
    358   base_file_->Finish();
    359 
    360   EXPECT_TRUE(base_file_->GetHash(&hash));
    361   EXPECT_EQ("CBF68BF10F8003DB86B31343AFAC8C7175BD03FB5FC905650F8C80AF087443A8",
    362             expected_hash_hex);
    363   EXPECT_EQ(expected_hash_hex, base::HexEncode(hash.data(), hash.size()));
    364 }
    365 
    366 // Write data to the file multiple times, interrupt it, and continue using
    367 // another file.  Calculate the resulting combined sha256 hash.
    368 TEST_F(BaseFileTest, MultipleWritesInterruptedWithHash) {
    369   // Calculate the final hash.
    370   ResetHash();
    371   UpdateHash(kTestData1, kTestDataLength1);
    372   UpdateHash(kTestData2, kTestDataLength2);
    373   UpdateHash(kTestData3, kTestDataLength3);
    374   std::string expected_hash = GetFinalHash();
    375   std::string expected_hash_hex =
    376       base::HexEncode(expected_hash.data(), expected_hash.size());
    377 
    378   MakeFileWithHash();
    379   ASSERT_TRUE(InitializeFile());
    380   // Write some data
    381   ASSERT_TRUE(AppendDataToFile(kTestData1));
    382   ASSERT_TRUE(AppendDataToFile(kTestData2));
    383   // Get the hash state and file name.
    384   std::string hash_state;
    385   hash_state = base_file_->GetHashState();
    386   // Finish the file.
    387   base_file_->Finish();
    388 
    389   base::FilePath new_file_path(temp_dir_.path().Append(
    390       base::FilePath(FILE_PATH_LITERAL("second_file"))));
    391 
    392   ASSERT_TRUE(base::CopyFile(base_file_->full_path(), new_file_path));
    393 
    394   // Create another file
    395   BaseFile second_file(new_file_path,
    396                        GURL(),
    397                        GURL(),
    398                        base_file_->bytes_so_far(),
    399                        true,
    400                        hash_state,
    401                        base::File(),
    402                        net::BoundNetLog());
    403   ASSERT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
    404             second_file.Initialize(base::FilePath()));
    405   std::string data(kTestData3);
    406   EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
    407             second_file.AppendDataToFile(data.data(), data.size()));
    408   second_file.Finish();
    409 
    410   std::string hash;
    411   EXPECT_TRUE(second_file.GetHash(&hash));
    412   // This will fail until getting the hash state is supported in SecureHash.
    413   EXPECT_STREQ(expected_hash_hex.c_str(),
    414                base::HexEncode(hash.data(), hash.size()).c_str());
    415 }
    416 
    417 // Rename the file after all writes to it.
    418 TEST_F(BaseFileTest, WriteThenRename) {
    419   ASSERT_TRUE(InitializeFile());
    420 
    421   base::FilePath initial_path(base_file_->full_path());
    422   EXPECT_TRUE(base::PathExists(initial_path));
    423   base::FilePath new_path(temp_dir_.path().AppendASCII("NewFile"));
    424   EXPECT_FALSE(base::PathExists(new_path));
    425 
    426   ASSERT_TRUE(AppendDataToFile(kTestData1));
    427 
    428   EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
    429             base_file_->Rename(new_path));
    430   EXPECT_FALSE(base::PathExists(initial_path));
    431   EXPECT_TRUE(base::PathExists(new_path));
    432 
    433   base_file_->Finish();
    434 }
    435 
    436 // Rename the file while the download is still in progress.
    437 TEST_F(BaseFileTest, RenameWhileInProgress) {
    438   ASSERT_TRUE(InitializeFile());
    439 
    440   base::FilePath initial_path(base_file_->full_path());
    441   EXPECT_TRUE(base::PathExists(initial_path));
    442   base::FilePath new_path(temp_dir_.path().AppendASCII("NewFile"));
    443   EXPECT_FALSE(base::PathExists(new_path));
    444 
    445   ASSERT_TRUE(AppendDataToFile(kTestData1));
    446 
    447   EXPECT_TRUE(base_file_->in_progress());
    448   EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, base_file_->Rename(new_path));
    449   EXPECT_FALSE(base::PathExists(initial_path));
    450   EXPECT_TRUE(base::PathExists(new_path));
    451 
    452   ASSERT_TRUE(AppendDataToFile(kTestData2));
    453 
    454   base_file_->Finish();
    455 }
    456 
    457 // Test that a failed rename reports the correct error.
    458 TEST_F(BaseFileTest, RenameWithError) {
    459   ASSERT_TRUE(InitializeFile());
    460 
    461   // TestDir is a subdirectory in |temp_dir_| that we will make read-only so
    462   // that the rename will fail.
    463   base::FilePath test_dir(temp_dir_.path().AppendASCII("TestDir"));
    464   ASSERT_TRUE(base::CreateDirectory(test_dir));
    465 
    466   base::FilePath new_path(test_dir.AppendASCII("TestFile"));
    467   EXPECT_FALSE(base::PathExists(new_path));
    468 
    469   {
    470     file_util::PermissionRestorer restore_permissions_for(test_dir);
    471     ASSERT_TRUE(file_util::MakeFileUnwritable(test_dir));
    472     EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED,
    473               base_file_->Rename(new_path));
    474   }
    475 
    476   base_file_->Finish();
    477 }
    478 
    479 // Test that a failed write reports an error.
    480 TEST_F(BaseFileTest, WriteWithError) {
    481   base::FilePath path;
    482   ASSERT_TRUE(base::CreateTemporaryFile(&path));
    483 
    484   // Pass a file handle which was opened without the WRITE flag.
    485   // This should result in an error when writing.
    486   base::File file(path, base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_READ);
    487   base_file_.reset(new BaseFile(path,
    488                                 GURL(),
    489                                 GURL(),
    490                                 0,
    491                                 false,
    492                                 std::string(),
    493                                 file.Pass(),
    494                                 net::BoundNetLog()));
    495   ASSERT_TRUE(InitializeFile());
    496 #if defined(OS_WIN)
    497   set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED);
    498 #elif defined (OS_POSIX)
    499   set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED);
    500 #endif
    501   ASSERT_FALSE(AppendDataToFile(kTestData1));
    502   base_file_->Finish();
    503 }
    504 
    505 // Try to write to uninitialized file.
    506 TEST_F(BaseFileTest, UninitializedFile) {
    507   expect_in_progress_ = false;
    508   set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED);
    509   EXPECT_FALSE(AppendDataToFile(kTestData1));
    510 }
    511 
    512 // Create two |BaseFile|s with the same file, and attempt to write to both.
    513 // Overwrite base_file_ with another file with the same name and
    514 // non-zero contents, and make sure the last file to close 'wins'.
    515 TEST_F(BaseFileTest, DuplicateBaseFile) {
    516   ASSERT_TRUE(InitializeFile());
    517 
    518   // Create another |BaseFile| referring to the file that |base_file_| owns.
    519   CreateFileWithName(base_file_->full_path());
    520 
    521   ASSERT_TRUE(AppendDataToFile(kTestData1));
    522   base_file_->Finish();
    523 }
    524 
    525 // Create a file and append to it.
    526 TEST_F(BaseFileTest, AppendToBaseFile) {
    527   // Create a new file.
    528   base::FilePath existing_file_name = CreateTestFile();
    529 
    530   set_expected_data(kTestData4);
    531 
    532   // Use the file we've just created.
    533   base_file_.reset(new BaseFile(existing_file_name,
    534                                 GURL(),
    535                                 GURL(),
    536                                 kTestDataLength4,
    537                                 false,
    538                                 std::string(),
    539                                 base::File(),
    540                                 net::BoundNetLog()));
    541 
    542   ASSERT_TRUE(InitializeFile());
    543 
    544   const base::FilePath file_name = base_file_->full_path();
    545   EXPECT_NE(base::FilePath::StringType(), file_name.value());
    546 
    547   // Write into the file.
    548   EXPECT_TRUE(AppendDataToFile(kTestData1));
    549 
    550   base_file_->Finish();
    551   base_file_->Detach();
    552   expect_file_survives_ = true;
    553 }
    554 
    555 // Create a read-only file and attempt to write to it.
    556 TEST_F(BaseFileTest, ReadonlyBaseFile) {
    557   // Create a new file.
    558   base::FilePath readonly_file_name = CreateTestFile();
    559 
    560   // Restore permissions to the file when we are done with this test.
    561   file_util::PermissionRestorer restore_permissions(readonly_file_name);
    562 
    563   // Make it read-only.
    564   EXPECT_TRUE(file_util::MakeFileUnwritable(readonly_file_name));
    565 
    566   // Try to overwrite it.
    567   base_file_.reset(new BaseFile(readonly_file_name,
    568                                 GURL(),
    569                                 GURL(),
    570                                 0,
    571                                 false,
    572                                 std::string(),
    573                                 base::File(),
    574                                 net::BoundNetLog()));
    575 
    576   expect_in_progress_ = false;
    577   set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED);
    578   EXPECT_FALSE(InitializeFile());
    579 
    580   const base::FilePath file_name = base_file_->full_path();
    581   EXPECT_NE(base::FilePath::StringType(), file_name.value());
    582 
    583   // Write into the file.
    584   set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED);
    585   EXPECT_FALSE(AppendDataToFile(kTestData1));
    586 
    587   base_file_->Finish();
    588   base_file_->Detach();
    589   expect_file_survives_ = true;
    590 }
    591 
    592 TEST_F(BaseFileTest, IsEmptyHash) {
    593   std::string empty(crypto::kSHA256Length, '\x00');
    594   EXPECT_TRUE(BaseFile::IsEmptyHash(empty));
    595   std::string not_empty(crypto::kSHA256Length, '\x01');
    596   EXPECT_FALSE(BaseFile::IsEmptyHash(not_empty));
    597   EXPECT_FALSE(BaseFile::IsEmptyHash(std::string()));
    598 
    599   std::string also_not_empty = empty;
    600   also_not_empty[crypto::kSHA256Length - 1] = '\x01';
    601   EXPECT_FALSE(BaseFile::IsEmptyHash(also_not_empty));
    602 }
    603 
    604 // Test that a temporary file is created in the default download directory.
    605 TEST_F(BaseFileTest, CreatedInDefaultDirectory) {
    606   ASSERT_TRUE(base_file_->full_path().empty());
    607   ASSERT_TRUE(InitializeFile());
    608   EXPECT_FALSE(base_file_->full_path().empty());
    609 
    610   // On Windows, CreateTemporaryFileInDir() will cause a path with short names
    611   // to be expanded into a path with long names. Thus temp_dir.path() might not
    612   // be a string-wise match to base_file_->full_path().DirName() even though
    613   // they are in the same directory.
    614   base::FilePath temp_file;
    615   ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &temp_file));
    616   ASSERT_FALSE(temp_file.empty());
    617   EXPECT_STREQ(temp_file.DirName().value().c_str(),
    618                base_file_->full_path().DirName().value().c_str());
    619   base_file_->Finish();
    620 }
    621 
    622 TEST_F(BaseFileTest, NoDoubleDeleteAfterCancel) {
    623   ASSERT_TRUE(InitializeFile());
    624   base::FilePath full_path = base_file_->full_path();
    625   ASSERT_FALSE(full_path.empty());
    626   ASSERT_TRUE(base::PathExists(full_path));
    627 
    628   base_file_->Cancel();
    629   ASSERT_FALSE(base::PathExists(full_path));
    630 
    631   const char kData[] = "hello";
    632   const int kDataLength = static_cast<int>(arraysize(kData) - 1);
    633   ASSERT_EQ(kDataLength, base::WriteFile(full_path, kData, kDataLength));
    634   // The file that we created here should stick around when the BaseFile is
    635   // destroyed during TearDown.
    636   expect_file_survives_ = true;
    637 }
    638 
    639 }  // namespace content
    640