Home | History | Annotate | Download | only in net
      1 // Copyright (c) 2013 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/net/net_log_temp_file.h"
      6 
      7 #include "base/basictypes.h"
      8 #include "base/files/file_path.h"
      9 #include "base/files/file_util.h"
     10 #include "base/message_loop/message_loop.h"
     11 #include "base/values.h"
     12 #include "build/build_config.h"
     13 #include "chrome/browser/net/chrome_net_log.h"
     14 #include "content/public/test/test_browser_thread.h"
     15 #include "testing/gtest/include/gtest/gtest.h"
     16 
     17 using content::BrowserThread;
     18 
     19 class TestNetLogTempFile : public NetLogTempFile {
     20  public:
     21   explicit TestNetLogTempFile(ChromeNetLog* chrome_net_log)
     22       : NetLogTempFile(chrome_net_log),
     23         lie_about_net_export_log_directory_(false),
     24         lie_about_file_existence_(false) {
     25   }
     26 
     27   // NetLogTempFile implementation:
     28   virtual bool GetNetExportLogDirectory(base::FilePath* path) OVERRIDE {
     29     if (lie_about_net_export_log_directory_)
     30       return false;
     31     return NetLogTempFile::GetNetExportLogDirectory(path);
     32   }
     33 
     34   virtual bool NetExportLogExists() OVERRIDE {
     35     if (lie_about_file_existence_)
     36       return false;
     37     return NetLogTempFile::NetExportLogExists();
     38   }
     39 
     40   void set_lie_about_net_export_log_directory(
     41       bool lie_about_net_export_log_directory) {
     42     lie_about_net_export_log_directory_ = lie_about_net_export_log_directory;
     43   }
     44 
     45   void set_lie_about_file_existence(bool lie_about_file_existence) {
     46     lie_about_file_existence_ = lie_about_file_existence;
     47   }
     48 
     49  private:
     50   bool lie_about_net_export_log_directory_;
     51   bool lie_about_file_existence_;
     52 };
     53 
     54 class NetLogTempFileTest : public ::testing::Test {
     55  public:
     56   NetLogTempFileTest()
     57       : net_log_(new ChromeNetLog),
     58         net_log_temp_file_(new TestNetLogTempFile(net_log_.get())),
     59         file_user_blocking_thread_(BrowserThread::FILE_USER_BLOCKING,
     60                                    &message_loop_) {
     61   }
     62 
     63   // ::testing::Test implementation:
     64   virtual void SetUp() OVERRIDE {
     65     // Get a temporary file name for unit tests.
     66     base::FilePath net_log_dir;
     67     ASSERT_TRUE(net_log_temp_file_->GetNetExportLogDirectory(&net_log_dir));
     68     ASSERT_TRUE(base::CreateTemporaryFileInDir(net_log_dir, &net_export_log_));
     69 
     70     net_log_temp_file_->log_filename_ = net_export_log_.BaseName().value();
     71 
     72     // CreateTemporaryFileInDir may return a legacy 8.3 file name on windows.
     73     // Need to use the original directory name for string comparisons.
     74     ASSERT_TRUE(net_log_temp_file_->GetNetExportLog());
     75     net_export_log_ = net_log_temp_file_->log_path_;
     76     ASSERT_FALSE(net_export_log_.empty());
     77   }
     78 
     79   virtual void TearDown() OVERRIDE {
     80     // Delete the temporary file we have created.
     81     ASSERT_TRUE(base::DeleteFile(net_export_log_, false));
     82   }
     83 
     84   std::string GetStateString() const {
     85     scoped_ptr<base::DictionaryValue> dict(net_log_temp_file_->GetState());
     86     std::string state;
     87     EXPECT_TRUE(dict->GetString("state", &state));
     88     return state;
     89   }
     90 
     91   std::string GetLogTypeString() const {
     92     scoped_ptr<base::DictionaryValue> dict(net_log_temp_file_->GetState());
     93     std::string log_type;
     94     EXPECT_TRUE(dict->GetString("logType", &log_type));
     95     return log_type;
     96   }
     97 
     98   // Make sure the export file has been created and is non-empty, as net
     99   // constants will always be written to it on creation.
    100   void VerifyNetExportLog() {
    101     EXPECT_EQ(net_export_log_, net_log_temp_file_->log_path_);
    102     EXPECT_TRUE(base::PathExists(net_export_log_));
    103 
    104     int64 file_size;
    105     // base::GetFileSize returns proper file size on open handles.
    106     EXPECT_TRUE(base::GetFileSize(net_export_log_, &file_size));
    107     EXPECT_GT(file_size, 0);
    108   }
    109 
    110   // Verify state and GetFilePath return correct values if EnsureInit() fails.
    111   void VerifyFilePathAndStateAfterEnsureInitFailure() {
    112     EXPECT_EQ("UNINITIALIZED", GetStateString());
    113     EXPECT_EQ(NetLogTempFile::STATE_UNINITIALIZED,
    114               net_log_temp_file_->state());
    115 
    116     base::FilePath net_export_file_path;
    117     EXPECT_FALSE(net_log_temp_file_->GetFilePath(&net_export_file_path));
    118   }
    119 
    120   // When we lie in NetExportLogExists, make sure state and GetFilePath return
    121   // correct values.
    122   void VerifyFilePathAndStateAfterEnsureInit() {
    123     EXPECT_EQ("NOT_LOGGING", GetStateString());
    124     EXPECT_EQ(NetLogTempFile::STATE_NOT_LOGGING, net_log_temp_file_->state());
    125     EXPECT_EQ("NONE", GetLogTypeString());
    126     EXPECT_EQ(NetLogTempFile::LOG_TYPE_NONE, net_log_temp_file_->log_type());
    127 
    128     base::FilePath net_export_file_path;
    129     EXPECT_FALSE(net_log_temp_file_->GetFilePath(&net_export_file_path));
    130     EXPECT_FALSE(net_log_temp_file_->NetExportLogExists());
    131   }
    132 
    133   // Make sure the export file has been successfully initialized.
    134   void VerifyFileAndStateAfterDoStart() {
    135     EXPECT_EQ("LOGGING", GetStateString());
    136     EXPECT_EQ(NetLogTempFile::STATE_LOGGING, net_log_temp_file_->state());
    137     EXPECT_EQ("NORMAL", GetLogTypeString());
    138     EXPECT_EQ(NetLogTempFile::LOG_TYPE_NORMAL, net_log_temp_file_->log_type());
    139 
    140     // Check GetFilePath returns false, if we are still writing to file.
    141     base::FilePath net_export_file_path;
    142     EXPECT_FALSE(net_log_temp_file_->GetFilePath(&net_export_file_path));
    143 
    144     VerifyNetExportLog();
    145     EXPECT_EQ(net::NetLog::LOG_ALL_BUT_BYTES, net_log_->GetLogLevel());
    146   }
    147 
    148   // Make sure the export file has been successfully initialized.
    149   void VerifyFileAndStateAfterDoStartStripPrivateData() {
    150     EXPECT_EQ("LOGGING", GetStateString());
    151     EXPECT_EQ(NetLogTempFile::STATE_LOGGING, net_log_temp_file_->state());
    152     EXPECT_EQ("STRIP_PRIVATE_DATA", GetLogTypeString());
    153     EXPECT_EQ(NetLogTempFile::LOG_TYPE_STRIP_PRIVATE_DATA,
    154               net_log_temp_file_->log_type());
    155 
    156     // Check GetFilePath returns false, if we are still writing to file.
    157     base::FilePath net_export_file_path;
    158     EXPECT_FALSE(net_log_temp_file_->GetFilePath(&net_export_file_path));
    159 
    160     VerifyNetExportLog();
    161     EXPECT_EQ(net::NetLog::LOG_STRIP_PRIVATE_DATA, net_log_->GetLogLevel());
    162   }
    163 
    164   // Make sure the export file has been successfully initialized.
    165   void VerifyFileAndStateAfterDoStop() {
    166     EXPECT_EQ("NOT_LOGGING", GetStateString());
    167     EXPECT_EQ(NetLogTempFile::STATE_NOT_LOGGING, net_log_temp_file_->state());
    168     EXPECT_EQ("NORMAL", GetLogTypeString());
    169     EXPECT_EQ(NetLogTempFile::LOG_TYPE_NORMAL, net_log_temp_file_->log_type());
    170 
    171     base::FilePath net_export_file_path;
    172     EXPECT_TRUE(net_log_temp_file_->GetFilePath(&net_export_file_path));
    173     EXPECT_TRUE(base::PathExists(net_export_file_path));
    174     EXPECT_EQ(net_export_log_, net_export_file_path);
    175 
    176     VerifyNetExportLog();
    177   }
    178 
    179   scoped_ptr<ChromeNetLog> net_log_;
    180   // |net_log_temp_file_| is initialized after |net_log_| so that it can stop
    181   // obvserving on destruction.
    182   scoped_ptr<TestNetLogTempFile> net_log_temp_file_;
    183   base::FilePath net_export_log_;
    184 
    185  private:
    186   base::MessageLoop message_loop_;
    187   content::TestBrowserThread file_user_blocking_thread_;
    188 };
    189 
    190 TEST_F(NetLogTempFileTest, EnsureInitFailure) {
    191   net_log_temp_file_->set_lie_about_net_export_log_directory(true);
    192 
    193   EXPECT_FALSE(net_log_temp_file_->EnsureInit());
    194   VerifyFilePathAndStateAfterEnsureInitFailure();
    195 
    196   net_log_temp_file_->ProcessCommand(NetLogTempFile::DO_START);
    197   VerifyFilePathAndStateAfterEnsureInitFailure();
    198 }
    199 
    200 TEST_F(NetLogTempFileTest, EnsureInitAllowStart) {
    201   net_log_temp_file_->set_lie_about_file_existence(true);
    202 
    203   EXPECT_TRUE(net_log_temp_file_->EnsureInit());
    204   VerifyFilePathAndStateAfterEnsureInit();
    205 
    206   // Calling EnsureInit() second time should be a no-op.
    207   EXPECT_TRUE(net_log_temp_file_->EnsureInit());
    208   VerifyFilePathAndStateAfterEnsureInit();
    209 }
    210 
    211 TEST_F(NetLogTempFileTest, EnsureInitAllowStartOrSend) {
    212   EXPECT_TRUE(net_log_temp_file_->EnsureInit());
    213 
    214   EXPECT_EQ("NOT_LOGGING", GetStateString());
    215   EXPECT_EQ(NetLogTempFile::STATE_NOT_LOGGING, net_log_temp_file_->state());
    216   EXPECT_EQ("UNKNOWN", GetLogTypeString());
    217   EXPECT_EQ(NetLogTempFile::LOG_TYPE_UNKNOWN, net_log_temp_file_->log_type());
    218   EXPECT_EQ(net_export_log_, net_log_temp_file_->log_path_);
    219   EXPECT_TRUE(base::PathExists(net_export_log_));
    220 
    221   base::FilePath net_export_file_path;
    222   EXPECT_TRUE(net_log_temp_file_->GetFilePath(&net_export_file_path));
    223   EXPECT_TRUE(base::PathExists(net_export_file_path));
    224   EXPECT_EQ(net_export_log_, net_export_file_path);
    225 
    226   // GetFilePath should return false if NetExportLogExists() fails.
    227   net_log_temp_file_->set_lie_about_file_existence(true);
    228   EXPECT_FALSE(net_log_temp_file_->GetFilePath(&net_export_file_path));
    229 }
    230 
    231 TEST_F(NetLogTempFileTest, ProcessCommandDoStartAndStop) {
    232   net_log_temp_file_->ProcessCommand(NetLogTempFile::DO_START);
    233   VerifyFileAndStateAfterDoStart();
    234 
    235   // Calling DO_START second time should be a no-op.
    236   net_log_temp_file_->ProcessCommand(NetLogTempFile::DO_START);
    237   VerifyFileAndStateAfterDoStart();
    238 
    239   net_log_temp_file_->ProcessCommand(NetLogTempFile::DO_STOP);
    240   VerifyFileAndStateAfterDoStop();
    241 
    242   // Calling DO_STOP second time should be a no-op.
    243   net_log_temp_file_->ProcessCommand(NetLogTempFile::DO_STOP);
    244   VerifyFileAndStateAfterDoStop();
    245 }
    246 
    247 TEST_F(NetLogTempFileTest, DoStartClearsFile) {
    248   // Verify file sizes after two consecutives start/stop are the same (even if
    249   // we add some junk data in between).
    250   net_log_temp_file_->ProcessCommand(NetLogTempFile::DO_START);
    251   VerifyFileAndStateAfterDoStart();
    252 
    253   int64 start_file_size;
    254   EXPECT_TRUE(base::GetFileSize(net_export_log_, &start_file_size));
    255 
    256   net_log_temp_file_->ProcessCommand(NetLogTempFile::DO_STOP);
    257   VerifyFileAndStateAfterDoStop();
    258 
    259   int64 stop_file_size;
    260   EXPECT_TRUE(base::GetFileSize(net_export_log_, &stop_file_size));
    261   EXPECT_GE(stop_file_size, start_file_size);
    262 
    263   // Add some junk at the end of the file.
    264   std::string junk_data("Hello");
    265   EXPECT_GT(base::AppendToFile(
    266       net_export_log_, junk_data.c_str(), junk_data.size()), 0);
    267 
    268   int64 junk_file_size;
    269   EXPECT_TRUE(base::GetFileSize(net_export_log_, &junk_file_size));
    270   EXPECT_GT(junk_file_size, stop_file_size);
    271 
    272   // Execute DO_START/DO_STOP commands and make sure the file is back to the
    273   // size before addition of junk data.
    274   net_log_temp_file_->ProcessCommand(NetLogTempFile::DO_START);
    275   VerifyFileAndStateAfterDoStart();
    276 
    277   int64 new_start_file_size;
    278   EXPECT_TRUE(base::GetFileSize(net_export_log_, &new_start_file_size));
    279   EXPECT_EQ(new_start_file_size, start_file_size);
    280 
    281   net_log_temp_file_->ProcessCommand(NetLogTempFile::DO_STOP);
    282   VerifyFileAndStateAfterDoStop();
    283 
    284   int64 new_stop_file_size;
    285   EXPECT_TRUE(base::GetFileSize(net_export_log_, &new_stop_file_size));
    286   EXPECT_EQ(new_stop_file_size, stop_file_size);
    287 }
    288 
    289 TEST_F(NetLogTempFileTest, CheckAddEvent) {
    290   // Add an event to |net_log_| and then test to make sure that, after we stop
    291   // logging, the file is larger than the file created without that event.
    292   net_log_temp_file_->ProcessCommand(NetLogTempFile::DO_START);
    293   VerifyFileAndStateAfterDoStart();
    294 
    295   // Get file size without the event.
    296   net_log_temp_file_->ProcessCommand(NetLogTempFile::DO_STOP);
    297   VerifyFileAndStateAfterDoStop();
    298 
    299   int64 stop_file_size;
    300   EXPECT_TRUE(base::GetFileSize(net_export_log_, &stop_file_size));
    301 
    302   // Perform DO_START and add an Event and then DO_STOP and then compare
    303   // file sizes.
    304   net_log_temp_file_->ProcessCommand(NetLogTempFile::DO_START);
    305   VerifyFileAndStateAfterDoStart();
    306 
    307   // Log an event.
    308   net_log_->AddGlobalEntry(net::NetLog::TYPE_CANCELLED);
    309 
    310   net_log_temp_file_->ProcessCommand(NetLogTempFile::DO_STOP);
    311   VerifyFileAndStateAfterDoStop();
    312 
    313   int64 new_stop_file_size;
    314   EXPECT_TRUE(base::GetFileSize(net_export_log_, &new_stop_file_size));
    315   EXPECT_GE(new_stop_file_size, stop_file_size);
    316 }
    317