Home | History | Annotate | Download | only in http
      1 // Copyright 2014 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 "net/http/disk_cache_based_quic_server_info.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/bind_helpers.h"
      9 #include "base/compiler_specific.h"
     10 #include "base/message_loop/message_loop.h"
     11 #include "net/base/net_errors.h"
     12 #include "net/http/mock_http_cache.h"
     13 #include "net/quic/crypto/quic_server_info.h"
     14 #include "net/quic/quic_server_id.h"
     15 #include "testing/gtest/include/gtest/gtest.h"
     16 
     17 namespace net {
     18 namespace {
     19 
     20 // This is an empty transaction, needed to register the URL and the test mode.
     21 const MockTransaction kHostInfoTransaction1 = {
     22   "quicserverinfo:https://www.google.com:443",
     23   "",
     24   base::Time(),
     25   "",
     26   LOAD_NORMAL,
     27   "",
     28   "",
     29   base::Time(),
     30   "",
     31   TEST_MODE_NORMAL,
     32   NULL,
     33   0
     34 };
     35 
     36 const MockTransaction kHostInfoTransaction2 = {
     37   "quicserverinfo:http://www.google.com:80",
     38   "",
     39   base::Time(),
     40   "",
     41   LOAD_NORMAL,
     42   "",
     43   "",
     44   base::Time(),
     45   "",
     46   TEST_MODE_NORMAL,
     47   NULL,
     48   0
     49 };
     50 
     51 }  // namespace
     52 
     53 // Tests that we can delete a DiskCacheBasedQuicServerInfo object in a
     54 // completion callback for DiskCacheBasedQuicServerInfo::WaitForDataReady.
     55 TEST(DiskCacheBasedQuicServerInfo, DeleteInCallback) {
     56   // Use the blocking mock backend factory to force asynchronous completion
     57   // of quic_server_info->WaitForDataReady(), so that the callback will run.
     58   MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
     59   MockHttpCache cache(factory);
     60   QuicServerId server_id("www.verisign.com", 443, true, PRIVACY_MODE_DISABLED);
     61   scoped_ptr<QuicServerInfo> quic_server_info(
     62       new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache()));
     63   quic_server_info->Start();
     64   TestCompletionCallback callback;
     65   int rv = quic_server_info->WaitForDataReady(callback.callback());
     66   EXPECT_EQ(ERR_IO_PENDING, rv);
     67   // Now complete the backend creation and let the callback run.
     68   factory->FinishCreation();
     69   EXPECT_EQ(OK, callback.GetResult(rv));
     70 }
     71 
     72 // Tests the basic logic of storing, retrieving and updating data.
     73 TEST(DiskCacheBasedQuicServerInfo, Update) {
     74   MockHttpCache cache;
     75   AddMockTransaction(&kHostInfoTransaction1);
     76   TestCompletionCallback callback;
     77 
     78   QuicServerId server_id("www.google.com", 443, true, PRIVACY_MODE_DISABLED);
     79   scoped_ptr<QuicServerInfo> quic_server_info(
     80       new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache()));
     81   quic_server_info->Start();
     82   int rv = quic_server_info->WaitForDataReady(callback.callback());
     83   EXPECT_EQ(OK, callback.GetResult(rv));
     84 
     85   QuicServerInfo::State* state = quic_server_info->mutable_state();
     86   EXPECT_TRUE(state->certs.empty());
     87   const string server_config_a = "server_config_a";
     88   const string source_address_token_a = "source_address_token_a";
     89   const string server_config_sig_a = "server_config_sig_a";
     90   const string cert_a = "cert_a";
     91   const string cert_b = "cert_b";
     92 
     93   state->server_config = server_config_a;
     94   state->source_address_token = source_address_token_a;
     95   state->server_config_sig = server_config_sig_a;
     96   state->certs.push_back(cert_a);
     97   quic_server_info->Persist();
     98 
     99   // Wait until Persist() does the work.
    100   base::MessageLoop::current()->RunUntilIdle();
    101 
    102   // Open the stored QuicServerInfo.
    103   quic_server_info.reset(
    104       new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache()));
    105   quic_server_info->Start();
    106   rv = quic_server_info->WaitForDataReady(callback.callback());
    107   EXPECT_EQ(OK, callback.GetResult(rv));
    108 
    109   // And now update the data.
    110   state = quic_server_info->mutable_state();
    111   state->certs.push_back(cert_b);
    112 
    113   // Fail instead of DCHECKing double creates.
    114   cache.disk_cache()->set_double_create_check(false);
    115   quic_server_info->Persist();
    116   base::MessageLoop::current()->RunUntilIdle();
    117 
    118   // Verify that the state was updated.
    119   quic_server_info.reset(
    120       new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache()));
    121   quic_server_info->Start();
    122   rv = quic_server_info->WaitForDataReady(callback.callback());
    123   EXPECT_EQ(OK, callback.GetResult(rv));
    124   EXPECT_TRUE(quic_server_info->IsDataReady());
    125 
    126   const QuicServerInfo::State& state1 = quic_server_info->state();
    127   EXPECT_EQ(server_config_a, state1.server_config);
    128   EXPECT_EQ(source_address_token_a, state1.source_address_token);
    129   EXPECT_EQ(server_config_sig_a, state1.server_config_sig);
    130   EXPECT_EQ(2U, state1.certs.size());
    131   EXPECT_EQ(cert_a, state1.certs[0]);
    132   EXPECT_EQ(cert_b, state1.certs[1]);
    133 
    134   RemoveMockTransaction(&kHostInfoTransaction1);
    135 }
    136 
    137 // Test that demonstrates different info is returned when the ports differ.
    138 TEST(DiskCacheBasedQuicServerInfo, UpdateDifferentPorts) {
    139   MockHttpCache cache;
    140   AddMockTransaction(&kHostInfoTransaction1);
    141   AddMockTransaction(&kHostInfoTransaction2);
    142   TestCompletionCallback callback;
    143 
    144   // Persist data for port 443.
    145   QuicServerId server_id1("www.google.com", 443, true, PRIVACY_MODE_DISABLED);
    146   scoped_ptr<QuicServerInfo> quic_server_info1(
    147       new DiskCacheBasedQuicServerInfo(server_id1, cache.http_cache()));
    148   quic_server_info1->Start();
    149   int rv = quic_server_info1->WaitForDataReady(callback.callback());
    150   EXPECT_EQ(OK, callback.GetResult(rv));
    151 
    152   QuicServerInfo::State* state1 = quic_server_info1->mutable_state();
    153   EXPECT_TRUE(state1->certs.empty());
    154   const string server_config_a = "server_config_a";
    155   const string source_address_token_a = "source_address_token_a";
    156   const string server_config_sig_a = "server_config_sig_a";
    157   const string cert_a = "cert_a";
    158 
    159   state1->server_config = server_config_a;
    160   state1->source_address_token = source_address_token_a;
    161   state1->server_config_sig = server_config_sig_a;
    162   state1->certs.push_back(cert_a);
    163   quic_server_info1->Persist();
    164 
    165   // Wait until Persist() does the work.
    166   base::MessageLoop::current()->RunUntilIdle();
    167 
    168   // Persist data for port 80.
    169   QuicServerId server_id2("www.google.com", 80, false, PRIVACY_MODE_DISABLED);
    170   scoped_ptr<QuicServerInfo> quic_server_info2(
    171       new DiskCacheBasedQuicServerInfo(server_id2, cache.http_cache()));
    172   quic_server_info2->Start();
    173   rv = quic_server_info2->WaitForDataReady(callback.callback());
    174   EXPECT_EQ(OK, callback.GetResult(rv));
    175 
    176   QuicServerInfo::State* state2 = quic_server_info2->mutable_state();
    177   EXPECT_TRUE(state2->certs.empty());
    178   const string server_config_b = "server_config_b";
    179   const string source_address_token_b = "source_address_token_b";
    180   const string server_config_sig_b = "server_config_sig_b";
    181   const string cert_b = "cert_b";
    182 
    183   state2->server_config = server_config_b;
    184   state2->source_address_token = source_address_token_b;
    185   state2->server_config_sig = server_config_sig_b;
    186   state2->certs.push_back(cert_b);
    187   quic_server_info2->Persist();
    188 
    189   // Wait until Persist() does the work.
    190   base::MessageLoop::current()->RunUntilIdle();
    191 
    192   // Verify the stored QuicServerInfo for port 443.
    193   scoped_ptr<QuicServerInfo> quic_server_info(
    194       new DiskCacheBasedQuicServerInfo(server_id1, cache.http_cache()));
    195   quic_server_info->Start();
    196   rv = quic_server_info->WaitForDataReady(callback.callback());
    197   EXPECT_EQ(OK, callback.GetResult(rv));
    198   EXPECT_TRUE(quic_server_info->IsDataReady());
    199 
    200   const QuicServerInfo::State& state_a = quic_server_info->state();
    201   EXPECT_EQ(server_config_a, state_a.server_config);
    202   EXPECT_EQ(source_address_token_a, state_a.source_address_token);
    203   EXPECT_EQ(server_config_sig_a, state_a.server_config_sig);
    204   EXPECT_EQ(1U, state_a.certs.size());
    205   EXPECT_EQ(cert_a, state_a.certs[0]);
    206 
    207   // Verify the stored QuicServerInfo for port 80.
    208   quic_server_info.reset(
    209       new DiskCacheBasedQuicServerInfo(server_id2, cache.http_cache()));
    210   quic_server_info->Start();
    211   rv = quic_server_info->WaitForDataReady(callback.callback());
    212   EXPECT_EQ(OK, callback.GetResult(rv));
    213   EXPECT_TRUE(quic_server_info->IsDataReady());
    214 
    215   const QuicServerInfo::State& state_b = quic_server_info->state();
    216   EXPECT_EQ(server_config_b, state_b.server_config);
    217   EXPECT_EQ(source_address_token_b, state_b.source_address_token);
    218   EXPECT_EQ(server_config_sig_b, state_b.server_config_sig);
    219   EXPECT_EQ(1U, state_b.certs.size());
    220   EXPECT_EQ(cert_b, state_b.certs[0]);
    221 
    222   RemoveMockTransaction(&kHostInfoTransaction2);
    223   RemoveMockTransaction(&kHostInfoTransaction1);
    224 }
    225 
    226 // Test IsReadyToPersist when there is a pending write.
    227 TEST(DiskCacheBasedQuicServerInfo, IsReadyToPersist) {
    228   MockHttpCache cache;
    229   AddMockTransaction(&kHostInfoTransaction1);
    230   TestCompletionCallback callback;
    231 
    232   QuicServerId server_id("www.google.com", 443, true, PRIVACY_MODE_DISABLED);
    233   scoped_ptr<QuicServerInfo> quic_server_info(
    234       new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache()));
    235   EXPECT_FALSE(quic_server_info->IsDataReady());
    236   quic_server_info->Start();
    237   int rv = quic_server_info->WaitForDataReady(callback.callback());
    238   EXPECT_EQ(OK, callback.GetResult(rv));
    239   EXPECT_TRUE(quic_server_info->IsDataReady());
    240 
    241   QuicServerInfo::State* state = quic_server_info->mutable_state();
    242   EXPECT_TRUE(state->certs.empty());
    243   const string server_config_a = "server_config_a";
    244   const string source_address_token_a = "source_address_token_a";
    245   const string server_config_sig_a = "server_config_sig_a";
    246   const string cert_a = "cert_a";
    247 
    248   state->server_config = server_config_a;
    249   state->source_address_token = source_address_token_a;
    250   state->server_config_sig = server_config_sig_a;
    251   state->certs.push_back(cert_a);
    252   EXPECT_TRUE(quic_server_info->IsReadyToPersist());
    253   quic_server_info->Persist();
    254 
    255   // Once we call Persist, IsReadyToPersist should return false until Persist
    256   // has completed.
    257   EXPECT_FALSE(quic_server_info->IsReadyToPersist());
    258 
    259   // Wait until Persist() does the work.
    260   base::MessageLoop::current()->RunUntilIdle();
    261 
    262   EXPECT_TRUE(quic_server_info->IsReadyToPersist());
    263 
    264   // Verify that the state was updated.
    265   quic_server_info.reset(
    266       new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache()));
    267   quic_server_info->Start();
    268   rv = quic_server_info->WaitForDataReady(callback.callback());
    269   EXPECT_EQ(OK, callback.GetResult(rv));
    270   EXPECT_TRUE(quic_server_info->IsDataReady());
    271 
    272   const QuicServerInfo::State& state1 = quic_server_info->state();
    273   EXPECT_EQ(server_config_a, state1.server_config);
    274   EXPECT_EQ(source_address_token_a, state1.source_address_token);
    275   EXPECT_EQ(server_config_sig_a, state1.server_config_sig);
    276   EXPECT_EQ(1U, state1.certs.size());
    277   EXPECT_EQ(cert_a, state1.certs[0]);
    278 
    279   RemoveMockTransaction(&kHostInfoTransaction1);
    280 }
    281 
    282 }  // namespace net
    283