Home | History | Annotate | Download | only in net
      1 // Copyright 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/renderer/net/net_error_helper.h"
      6 
      7 #include "base/logging.h"
      8 #include "chrome/common/net/net_error_info.h"
      9 #include "testing/gtest/include/gtest/gtest.h"
     10 
     11 using chrome_common_net::DnsProbeStatus;
     12 using chrome_common_net::DnsProbeStatusToString;
     13 
     14 // NetErrorHelperTest cases consist of a string of these steps.
     15 enum TestStep {
     16   // Simulate a provisional load start, fail, commit or a finish-load event.
     17   // (Start and fail differentiate between normal and error pages.)
     18   LOAD_NORMAL_START, LOAD_NORMAL_FAIL, LOAD_ERROR_START,
     19   LOAD_COMMIT, LOAD_FINISH,
     20 
     21   // Simulate an IPC from the browser with DNS_PROBE_STARTED, _NOT_RUN, or
     22   // _FINISHED_NXDOMAIN.
     23   STATUS_STARTED, STATUS_NOT_RUN, STATUS_FINISHED,
     24 
     25   // Expect that the *next* step will cause an update.  (Any step that is not
     26   // prefixed by this pseudo-step is expected *not* to cause an update.)
     27   EXPECT_UPDATE
     28 };
     29 
     30 class TestNetErrorHelper : public NetErrorHelper {
     31  public:
     32   TestNetErrorHelper()
     33       : NetErrorHelper(NULL),
     34         mock_page_update_count_(0),
     35         mock_displayed_probe_status_(chrome_common_net::DNS_PROBE_MAX) {}
     36 
     37   virtual ~TestNetErrorHelper() {}
     38 
     39   void StartLoad(bool is_main_frame, bool is_error_page) {
     40     OnStartLoad(is_main_frame, is_error_page);
     41   }
     42 
     43   void FailLoad(bool is_main_frame, bool is_dns_error) {
     44     OnFailLoad(is_main_frame, is_dns_error);
     45   }
     46 
     47   void CommitLoad(bool is_main_frame) {
     48     OnCommitLoad(is_main_frame);
     49   }
     50 
     51   void FinishLoad(bool is_main_frame) {
     52     OnFinishLoad(is_main_frame);
     53   }
     54 
     55   void ReceiveProbeStatus(DnsProbeStatus status) {
     56     OnNetErrorInfo(static_cast<int>(status));
     57   }
     58 
     59   int mock_page_update_count() const { return mock_page_update_count_;  }
     60   DnsProbeStatus mock_displayed_probe_status() const {
     61     return mock_displayed_probe_status_;
     62   }
     63 
     64  protected:
     65   virtual void UpdateErrorPage() OVERRIDE {
     66     DVLOG(1) << "Updating error page with status "
     67              << DnsProbeStatusToString(last_probe_status_);
     68     mock_page_update_count_++;
     69     mock_displayed_probe_status_ = last_probe_status_;
     70   }
     71 
     72  private:
     73   int mock_page_update_count_;
     74   DnsProbeStatus mock_displayed_probe_status_;
     75 };
     76 
     77 class NetErrorHelperTest : public testing::Test {
     78  protected:
     79   enum MainFrame { SUB_FRAME, MAIN_FRAME };
     80   enum ErrorPage { NORMAL_PAGE, ERROR_PAGE };
     81   enum ErrorType { OTHER_ERROR, DNS_ERROR };
     82 
     83   void StartLoad(MainFrame main_frame, ErrorPage error_page) {
     84     helper_.StartLoad(main_frame == MAIN_FRAME, error_page == ERROR_PAGE);
     85   }
     86 
     87   void FailLoad(MainFrame main_frame, ErrorType error_type) {
     88     helper_.FailLoad(main_frame == MAIN_FRAME, error_type == DNS_ERROR);
     89   }
     90 
     91   void CommitLoad(MainFrame main_frame) {
     92     helper_.CommitLoad(main_frame == MAIN_FRAME);
     93   }
     94 
     95   void FinishLoad(MainFrame main_frame) {
     96     helper_.FinishLoad(main_frame == MAIN_FRAME);
     97   }
     98 
     99   void ReceiveProbeStatus(DnsProbeStatus status) {
    100     helper_.ReceiveProbeStatus(status);
    101   }
    102 
    103   void RunTest(const TestStep steps[], int step_count);
    104 
    105   int page_update_count() const { return helper_.mock_page_update_count(); }
    106   DnsProbeStatus displayed_probe_status() const {
    107     return helper_.mock_displayed_probe_status();
    108   }
    109 
    110  private:
    111   TestNetErrorHelper helper_;
    112 };
    113 
    114 void NetErrorHelperTest::RunTest(const TestStep steps[], int step_count) {
    115   // Whether the next instruction is expected to cause an update (since the
    116   // step right before it was EXPECT_UPDATE) or not.
    117   bool update_expected = false;
    118   int expected_update_count = page_update_count();
    119   // The last status that the test simulated receiving from the browser.
    120   // When an update is expected, the status is expected to match this.
    121   chrome_common_net::DnsProbeStatus last_status_received =
    122       chrome_common_net::DNS_PROBE_POSSIBLE;
    123 
    124   for (int i = 0; i < step_count; i++) {
    125     switch (steps[i]) {
    126     case LOAD_NORMAL_START:
    127       StartLoad(MAIN_FRAME, NORMAL_PAGE);
    128       break;
    129     case LOAD_NORMAL_FAIL:
    130       FailLoad(MAIN_FRAME, DNS_ERROR);
    131       break;
    132     case LOAD_ERROR_START:
    133       StartLoad(MAIN_FRAME, ERROR_PAGE);
    134       break;
    135     case LOAD_COMMIT:
    136       CommitLoad(MAIN_FRAME);
    137       break;
    138     case LOAD_FINISH:
    139       FinishLoad(MAIN_FRAME);
    140       break;
    141     case STATUS_STARTED:
    142       ReceiveProbeStatus(chrome_common_net::DNS_PROBE_STARTED);
    143       last_status_received = chrome_common_net::DNS_PROBE_STARTED;
    144       break;
    145     case STATUS_NOT_RUN:
    146       ReceiveProbeStatus(chrome_common_net::DNS_PROBE_NOT_RUN);
    147       last_status_received = chrome_common_net::DNS_PROBE_NOT_RUN;
    148       break;
    149     case STATUS_FINISHED:
    150       ReceiveProbeStatus(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN);
    151       last_status_received = chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN;
    152       break;
    153     case EXPECT_UPDATE:
    154       ASSERT_FALSE(update_expected);
    155       update_expected = true;
    156       // Skip to next step to see if it updates the status, instead of
    157       // checking whether EXPECT_UPDATE itself caused an update.
    158       continue;
    159     }
    160 
    161     if (update_expected) {
    162       DCHECK_NE(chrome_common_net::DNS_PROBE_POSSIBLE, last_status_received);
    163       ++expected_update_count;
    164 
    165       EXPECT_EQ(last_status_received, displayed_probe_status());
    166       if (displayed_probe_status() != last_status_received) {
    167         LOG(ERROR) << "Unexpected status at step " << i << ".";
    168         return;
    169       }
    170     }
    171 
    172     EXPECT_EQ(expected_update_count, page_update_count());
    173     if (page_update_count() != expected_update_count) {
    174       LOG(ERROR) << (update_expected ? "Missing" : "Spurious")
    175                  << " update at step " << i << ".";
    176       return;
    177     }
    178 
    179     update_expected = false;
    180   }
    181 
    182   DCHECK(!update_expected);
    183 }
    184 
    185 TEST_F(NetErrorHelperTest, Null) {
    186   // Test that we can simply create and destroy a NetErrorHelper.
    187 }
    188 
    189 TEST_F(NetErrorHelperTest, SuccessfulPageLoad) {
    190   StartLoad(MAIN_FRAME, NORMAL_PAGE);
    191   CommitLoad(MAIN_FRAME);
    192   FinishLoad(MAIN_FRAME);
    193 
    194   // Ignore spurious status.
    195   ReceiveProbeStatus(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN);
    196   EXPECT_EQ(0, page_update_count());
    197 }
    198 
    199 TEST_F(NetErrorHelperTest, MainFrameNonDnsError) {
    200   StartLoad(MAIN_FRAME, NORMAL_PAGE);
    201   FailLoad(MAIN_FRAME, OTHER_ERROR);
    202   StartLoad(MAIN_FRAME, ERROR_PAGE);
    203   CommitLoad(MAIN_FRAME);
    204   FinishLoad(MAIN_FRAME);
    205 
    206   // Ignore spurious status.
    207   ReceiveProbeStatus(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN);
    208   EXPECT_EQ(0, page_update_count());
    209 }
    210 
    211 TEST_F(NetErrorHelperTest, SubFrameDnsError) {
    212   StartLoad(SUB_FRAME, NORMAL_PAGE);
    213   FailLoad(SUB_FRAME, DNS_ERROR);
    214   StartLoad(SUB_FRAME, ERROR_PAGE);
    215   CommitLoad(SUB_FRAME);
    216   FinishLoad(SUB_FRAME);
    217 
    218   // Ignore spurious status.
    219   ReceiveProbeStatus(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN);
    220   EXPECT_EQ(0, page_update_count());
    221 }
    222 
    223 TEST_F(NetErrorHelperTest, FinishedAfterFail) {
    224   const TestStep steps[] = {
    225     LOAD_NORMAL_START, LOAD_NORMAL_FAIL, STATUS_FINISHED, LOAD_ERROR_START,
    226     LOAD_COMMIT, EXPECT_UPDATE, LOAD_FINISH
    227   };
    228   RunTest(steps, arraysize(steps));
    229 }
    230 
    231 TEST_F(NetErrorHelperTest, FinishedAfterFail_StartedAfterFail) {
    232   const TestStep steps[] = {
    233     LOAD_NORMAL_START, LOAD_NORMAL_FAIL, STATUS_STARTED, STATUS_FINISHED,
    234     LOAD_ERROR_START, LOAD_COMMIT, EXPECT_UPDATE, LOAD_FINISH
    235   };
    236   RunTest(steps, arraysize(steps));
    237 }
    238 
    239 TEST_F(NetErrorHelperTest, FinishedAfterStart) {
    240   const TestStep steps[] = {
    241     LOAD_NORMAL_START, LOAD_NORMAL_FAIL, LOAD_ERROR_START, STATUS_FINISHED,
    242     LOAD_COMMIT, EXPECT_UPDATE, LOAD_FINISH
    243   };
    244   RunTest(steps, arraysize(steps));
    245 }
    246 
    247 TEST_F(NetErrorHelperTest, FinishedAfterStart_StartedAfterFail) {
    248   const TestStep steps[] = {
    249     LOAD_NORMAL_START, LOAD_NORMAL_FAIL, STATUS_STARTED, LOAD_ERROR_START,
    250     STATUS_FINISHED, LOAD_COMMIT, EXPECT_UPDATE, LOAD_FINISH
    251   };
    252   RunTest(steps, arraysize(steps));
    253 }
    254 
    255 TEST_F(NetErrorHelperTest, FinishedAfterStart_StartedAfterStart) {
    256   const TestStep steps[] = {
    257     LOAD_NORMAL_START, LOAD_NORMAL_FAIL, STATUS_STARTED, LOAD_ERROR_START,
    258     STATUS_FINISHED, LOAD_COMMIT, EXPECT_UPDATE, LOAD_FINISH
    259   };
    260   RunTest(steps, arraysize(steps));
    261 }
    262 
    263 TEST_F(NetErrorHelperTest, FinishedAfterCommit) {
    264   const TestStep steps[] = {
    265     LOAD_NORMAL_START, LOAD_NORMAL_FAIL, LOAD_ERROR_START, LOAD_COMMIT,
    266     STATUS_FINISHED, EXPECT_UPDATE, LOAD_FINISH
    267   };
    268   RunTest(steps, arraysize(steps));
    269 }
    270 
    271 TEST_F(NetErrorHelperTest, FinishedAfterCommit_StartedAfterFail) {
    272   const TestStep steps[] = {
    273     LOAD_NORMAL_START, LOAD_NORMAL_FAIL, STATUS_STARTED, LOAD_ERROR_START,
    274     LOAD_COMMIT, STATUS_FINISHED, EXPECT_UPDATE, LOAD_FINISH
    275   };
    276   RunTest(steps, arraysize(steps));
    277 }
    278 
    279 TEST_F(NetErrorHelperTest, FinishedAfterCommit_StartedAfterStart) {
    280   const TestStep steps[] = {
    281     LOAD_NORMAL_START, LOAD_NORMAL_FAIL, LOAD_ERROR_START, STATUS_STARTED,
    282     LOAD_ERROR_START, LOAD_COMMIT, STATUS_FINISHED, EXPECT_UPDATE, LOAD_FINISH
    283   };
    284   RunTest(steps, arraysize(steps));
    285 }
    286 
    287 TEST_F(NetErrorHelperTest, FinishedAfterCommit_StartedAfterCommit) {
    288   const TestStep steps[] = {
    289     LOAD_NORMAL_START, LOAD_NORMAL_FAIL, LOAD_ERROR_START, LOAD_COMMIT,
    290     STATUS_STARTED, STATUS_FINISHED, EXPECT_UPDATE, LOAD_FINISH
    291   };
    292   RunTest(steps, arraysize(steps));
    293 }
    294 
    295 TEST_F(NetErrorHelperTest, FinishedAfterFinish) {
    296   const TestStep steps[] = {
    297     LOAD_NORMAL_START, LOAD_NORMAL_FAIL, LOAD_ERROR_START, LOAD_COMMIT,
    298     LOAD_FINISH, EXPECT_UPDATE, STATUS_FINISHED
    299   };
    300   RunTest(steps, arraysize(steps));
    301 }
    302 
    303 TEST_F(NetErrorHelperTest, FinishedAfterFinish_StartAfterFail) {
    304   const TestStep steps[] = {
    305     LOAD_NORMAL_START, LOAD_NORMAL_FAIL, STATUS_STARTED, LOAD_ERROR_START,
    306     LOAD_COMMIT, EXPECT_UPDATE, LOAD_FINISH, EXPECT_UPDATE, STATUS_FINISHED
    307   };
    308   RunTest(steps, arraysize(steps));
    309 }
    310 
    311 TEST_F(NetErrorHelperTest, FinishedAfterFinish_StartAfterStart) {
    312   const TestStep steps[] = {
    313     LOAD_NORMAL_START, LOAD_NORMAL_FAIL, LOAD_ERROR_START, STATUS_STARTED,
    314     LOAD_COMMIT, EXPECT_UPDATE, LOAD_FINISH, EXPECT_UPDATE, STATUS_FINISHED
    315   };
    316   RunTest(steps, arraysize(steps));
    317 }
    318 
    319 TEST_F(NetErrorHelperTest, FinishedAfterFinish_StartAfterCommit) {
    320   const TestStep steps[] = {
    321     LOAD_NORMAL_START, LOAD_NORMAL_FAIL, LOAD_ERROR_START, LOAD_COMMIT,
    322     STATUS_STARTED, EXPECT_UPDATE, LOAD_FINISH, EXPECT_UPDATE, STATUS_FINISHED
    323   };
    324   RunTest(steps, arraysize(steps));
    325 }
    326 
    327 TEST_F(NetErrorHelperTest, FinishedAfterFinish_StartAfterFinish) {
    328   const TestStep steps[] = {
    329     LOAD_NORMAL_START, LOAD_NORMAL_FAIL, LOAD_ERROR_START, LOAD_COMMIT,
    330     LOAD_FINISH, EXPECT_UPDATE, STATUS_STARTED, EXPECT_UPDATE, STATUS_FINISHED
    331   };
    332   RunTest(steps, arraysize(steps));
    333 }
    334 
    335 TEST_F(NetErrorHelperTest, FinishedAfterNewStart) {
    336   const TestStep steps[] = {
    337     LOAD_NORMAL_START, LOAD_NORMAL_FAIL, LOAD_ERROR_START, LOAD_COMMIT,
    338     LOAD_FINISH, LOAD_NORMAL_START, EXPECT_UPDATE, STATUS_FINISHED,
    339     LOAD_COMMIT, LOAD_FINISH
    340   };
    341   RunTest(steps, arraysize(steps));
    342 }
    343 
    344 TEST_F(NetErrorHelperTest, NotRunAfterFail) {
    345   const TestStep steps[] = {
    346     LOAD_NORMAL_START, LOAD_NORMAL_FAIL, STATUS_NOT_RUN, LOAD_ERROR_START,
    347     LOAD_COMMIT, EXPECT_UPDATE, LOAD_FINISH
    348   };
    349   RunTest(steps, arraysize(steps));
    350 }
    351 
    352 TEST_F(NetErrorHelperTest, NotRunAfterStart) {
    353   const TestStep steps[] = {
    354     LOAD_NORMAL_START, LOAD_NORMAL_FAIL, LOAD_ERROR_START, STATUS_NOT_RUN,
    355     LOAD_COMMIT, EXPECT_UPDATE, LOAD_FINISH
    356   };
    357   RunTest(steps, arraysize(steps));
    358 }
    359 
    360 TEST_F(NetErrorHelperTest, NotRunAfterCommit) {
    361   const TestStep steps[] = {
    362     LOAD_NORMAL_START, LOAD_NORMAL_FAIL, LOAD_ERROR_START, LOAD_COMMIT,
    363     STATUS_NOT_RUN, EXPECT_UPDATE, LOAD_FINISH
    364   };
    365   RunTest(steps, arraysize(steps));
    366 }
    367 
    368 TEST_F(NetErrorHelperTest, NotRunAfterFinish) {
    369   const TestStep steps[] = {
    370     LOAD_NORMAL_START, LOAD_NORMAL_FAIL, LOAD_ERROR_START, LOAD_COMMIT,
    371     LOAD_FINISH, EXPECT_UPDATE, STATUS_NOT_RUN
    372   };
    373   RunTest(steps, arraysize(steps));
    374 }
    375 
    376 TEST_F(NetErrorHelperTest, FinishedAfterNewCommit) {
    377   const TestStep steps[] = {
    378     LOAD_NORMAL_START, LOAD_NORMAL_FAIL, LOAD_ERROR_START, LOAD_COMMIT,
    379     LOAD_FINISH, LOAD_NORMAL_START, LOAD_COMMIT, STATUS_FINISHED, LOAD_FINISH
    380   };
    381   RunTest(steps, arraysize(steps));
    382 }
    383 
    384 TEST_F(NetErrorHelperTest, FinishedAfterNewFinish) {
    385   const TestStep steps[] = {
    386     LOAD_NORMAL_START, LOAD_NORMAL_FAIL, LOAD_ERROR_START, LOAD_COMMIT,
    387     LOAD_FINISH, LOAD_NORMAL_START, LOAD_COMMIT, LOAD_FINISH, STATUS_FINISHED
    388   };
    389   RunTest(steps, arraysize(steps));
    390 }
    391 
    392 // Two iterations of FinishedAfterStart_StartAfterFail
    393 TEST_F(NetErrorHelperTest, TwoProbes_FinishedAfterStart_StartAfterFail) {
    394   const TestStep steps[] = {
    395     LOAD_NORMAL_START, LOAD_NORMAL_FAIL, STATUS_STARTED, LOAD_ERROR_START,
    396     STATUS_FINISHED, LOAD_COMMIT, EXPECT_UPDATE, LOAD_FINISH,
    397     LOAD_NORMAL_START, LOAD_NORMAL_FAIL, STATUS_STARTED, LOAD_ERROR_START,
    398     STATUS_FINISHED, LOAD_COMMIT, EXPECT_UPDATE, LOAD_FINISH
    399   };
    400   RunTest(steps, arraysize(steps));
    401 }
    402 
    403 // Two iterations of FinishedAfterFinish
    404 TEST_F(NetErrorHelperTest, TwoProbes_FinishedAfterFinish) {
    405   const TestStep steps[] = {
    406     LOAD_NORMAL_START, LOAD_NORMAL_FAIL, LOAD_ERROR_START, LOAD_COMMIT,
    407     LOAD_FINISH, EXPECT_UPDATE, STATUS_FINISHED,
    408     LOAD_NORMAL_START, LOAD_NORMAL_FAIL, LOAD_ERROR_START, LOAD_COMMIT,
    409     LOAD_FINISH, EXPECT_UPDATE, STATUS_FINISHED
    410   };
    411   RunTest(steps, arraysize(steps));
    412 }
    413