Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(301)

Side by Side Diff: components/certificate_transparency/log_dns_client_unittest.cc

Issue 2380293002: Adds LogDnsClient::NotifyWhenNotThrottled (Closed)
Patch Set: Rebase Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/certificate_transparency/log_dns_client.h" 5 #include "components/certificate_transparency/log_dns_client.h"
6 6
7 #include <memory> 7 #include <memory>
8 #include <numeric> 8 #include <numeric>
9 #include <string> 9 #include <string>
10 #include <utility> 10 #include <utility>
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 // Each node is 32 bytes, with each byte having a different value. 84 // Each node is 32 bytes, with each byte having a different value.
85 for (size_t j = 0; j < crypto::kSHA256Length; ++j) { 85 for (size_t j = 0; j < crypto::kSHA256Length; ++j) {
86 node[j] = static_cast<char>((-127 + i + j) % 128); 86 node[j] = static_cast<char>((-127 + i + j) % 128);
87 } 87 }
88 audit_proof[i].assign(std::move(node)); 88 audit_proof[i].assign(std::move(node));
89 } 89 }
90 90
91 return audit_proof; 91 return audit_proof;
92 } 92 }
93 93
94 // MockAuditProofCallback can be used as an AuditProofCallback. 94 // MockCallback can be used as a base::Callback.
95 // It will record the arguments it is invoked with and provides a helpful 95 // It will record the arguments it is invoked with, which can be examined by
96 // method for pumping the message loop until it is invoked. 96 // calling args() or arg<N>().
97 class MockAuditProofCallback { 97 // It only expects to be called once, but can be reused by calling Reset().
98 // Example:
99 // MockCallback<int> mock;
100 // foo.RegisterCallback(mock.AsCallback());
101 // foo.DoSomething();
102 // mock.WaitUntilRun(TestTimeouts::action_max_timeout());
103 // ASSERT_TRUE(mock.called());
104 // ASSERT_EQ(123, mock.arg<0>());
105 template <typename... Args>
106 class MockCallback {
98 public: 107 public:
99 MockAuditProofCallback() : called_(false) {} 108 MockCallback() : called_(false) {}
100 109
110 // Returns true if the callback has been invoked.
101 bool called() const { return called_; } 111 bool called() const { return called_; }
102 net::Error result() const { return result_; }
103 const net::ct::MerkleAuditProof* proof() const { return proof_.get(); }
104 112
105 // Get this callback as an AuditProofCallback. 113 // The arguments that the callback was called with.
106 LogDnsClient::AuditProofCallback AsCallback() { 114 const std::tuple<Args...>& args() const {
107 return base::Bind(&MockAuditProofCallback::Run, base::Unretained(this)); 115 DCHECK(called_);
116 return args_;
117 }
118
119 // Gets a particular argument that the callback was invoked with.
120 // For example, to get the first argument: mock_callback.arg<0>();
121 template <size_t N>
122 const typename std::tuple_element<N, std::tuple<Args...>>::type& arg() const {
123 DCHECK(called_);
124 return std::get<N>(args_);
125 }
126
127 // Convert to a base::Callback.
128 // TODO(robpercival): Could this reasonably be an implicit conversion?
129 base::Callback<void(Args...)> AsCallback() {
130 return base::Bind(&MockCallback::Run, base::Unretained(this));
108 } 131 }
109 132
110 // Wait until either the callback is invoked or the message loop goes idle 133 // Wait until either the callback is invoked or the message loop goes idle
111 // (after a specified |timeout|). Returns immediately if the callback has 134 // (after a specified |timeout|). Returns immediately if the callback has
112 // already been invoked. 135 // already been invoked.
113 void WaitUntilRun(base::TimeDelta timeout) { 136 void WaitUntilRun(base::TimeDelta timeout) {
114 if (called_) { 137 if (called_) {
115 return; 138 return;
116 } 139 }
117 140
118 // Pump the message loop until the the callback is invoked, which quits the 141 // Pump the message loop until the the callback is invoked, which quits the
119 // RunLoop, or a timeout expires and the message loop goes idle. 142 // RunLoop, or a timeout expires and the message loop goes idle.
120 run_loop_.reset(new base::RunLoop()); 143 run_loop_.reset(new base::RunLoop());
121 base::Closure quit_closure = run_loop_->QuitWhenIdleClosure(); 144 base::Closure quit_closure = run_loop_->QuitWhenIdleClosure();
122 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(FROM_HERE, 145 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(FROM_HERE,
123 quit_closure, timeout); 146 quit_closure, timeout);
124 run_loop_->Run(); 147 run_loop_->Run();
125 run_loop_.reset(); 148 run_loop_.reset();
126 } 149 }
127 150
151 void Reset() {
152 called_ = false;
153 args_ = std::tuple<Args...>();
154 }
155
128 private: 156 private:
129 void Run(net::Error result, 157 void Run(Args... args) {
130 std::unique_ptr<net::ct::MerkleAuditProof> proof) {
131 EXPECT_FALSE(called_); 158 EXPECT_FALSE(called_);
132 called_ = true; 159 called_ = true;
133 result_ = result; 160 args_ = std::make_tuple(std::forward<Args>(args)...);
134 proof_ = std::move(proof);
135 if (run_loop_) { 161 if (run_loop_) {
136 run_loop_->Quit(); 162 run_loop_->Quit();
137 } 163 }
138 } 164 }
139 165
140 // True if the callback has been invoked. 166 // True if the callback has been invoked.
141 bool called_; 167 bool called_;
142 // The arguments that the callback was invoked with. 168 // The arguments that the callback was invoked with.
143 net::Error result_; 169 std::tuple<Args...> args_;
144 std::unique_ptr<net::ct::MerkleAuditProof> proof_;
145 // The RunLoop currently being used to pump the message loop, as a means to 170 // The RunLoop currently being used to pump the message loop, as a means to
146 // execute this callback. 171 // execute this callback.
147 std::unique_ptr<base::RunLoop> run_loop_; 172 std::unique_ptr<base::RunLoop> run_loop_;
148 }; 173 };
149 174
175 class MockAuditProofCallback
176 : public MockCallback<net::Error,
177 std::unique_ptr<net::ct::MerkleAuditProof>> {
178 public:
179 net::Error result() const { return arg<0>(); }
180 const net::ct::MerkleAuditProof* proof() const { return arg<1>().get(); }
181 };
182
183 class MockClosure : public MockCallback<> {};
184
150 class LogDnsClientTest : public ::testing::TestWithParam<net::IoMode> { 185 class LogDnsClientTest : public ::testing::TestWithParam<net::IoMode> {
151 protected: 186 protected:
152 LogDnsClientTest() 187 LogDnsClientTest()
153 : network_change_notifier_(net::NetworkChangeNotifier::CreateMock()) { 188 : network_change_notifier_(net::NetworkChangeNotifier::CreateMock()) {
154 mock_dns_.SetSocketReadMode(GetParam()); 189 mock_dns_.SetSocketReadMode(GetParam());
155 mock_dns_.InitializeDnsConfig(); 190 mock_dns_.InitializeDnsConfig();
156 } 191 }
157 192
158 std::unique_ptr<LogDnsClient> CreateLogDnsClient( 193 std::unique_ptr<LogDnsClient> CreateLogDnsClient(
159 size_t max_concurrent_queries) { 194 size_t max_concurrent_queries) {
(...skipping 715 matching lines...) Expand 10 before | Expand all | Expand 10 after
875 callback3.WaitUntilRun(TestTimeouts::action_max_timeout()); 910 callback3.WaitUntilRun(TestTimeouts::action_max_timeout());
876 ASSERT_TRUE(callback3.called()); 911 ASSERT_TRUE(callback3.called());
877 EXPECT_THAT(callback3.result(), IsOk()); 912 EXPECT_THAT(callback3.result(), IsOk());
878 ASSERT_THAT(callback3.proof(), NotNull()); 913 ASSERT_THAT(callback3.proof(), NotNull());
879 EXPECT_THAT(callback3.proof()->leaf_index, Eq(666u)); 914 EXPECT_THAT(callback3.proof()->leaf_index, Eq(666u));
880 // TODO(robpercival): Enable this once MerkleAuditProof has tree_size. 915 // TODO(robpercival): Enable this once MerkleAuditProof has tree_size.
881 // EXPECT_THAT(callback3.proof()->tree_size, Eq(999999)); 916 // EXPECT_THAT(callback3.proof()->tree_size, Eq(999999));
882 EXPECT_THAT(callback3.proof()->nodes, Eq(audit_proof)); 917 EXPECT_THAT(callback3.proof()->nodes, Eq(audit_proof));
883 } 918 }
884 919
920 TEST_P(LogDnsClientTest, NotifiesWhenNoLongerThrottled) {
921 const std::vector<std::string> audit_proof = GetSampleAuditProof(20);
922
923 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
924 mock_dns_.ExpectAuditProofRequestAndResponse("0.123456.999999.tree.ct.test.",
925 audit_proof.begin(),
926 audit_proof.begin() + 7);
927 mock_dns_.ExpectAuditProofRequestAndResponse("7.123456.999999.tree.ct.test.",
928 audit_proof.begin() + 7,
929 audit_proof.begin() + 14);
930 mock_dns_.ExpectAuditProofRequestAndResponse("14.123456.999999.tree.ct.test.",
931 audit_proof.begin() + 14,
932 audit_proof.end());
933
934 const size_t kMaxConcurrentQueries = 1;
935 std::unique_ptr<LogDnsClient> log_client =
936 CreateLogDnsClient(kMaxConcurrentQueries);
937
938 // Start a query.
939 MockAuditProofCallback proof_callback1;
940 ASSERT_THAT(log_client->QueryAuditProof("ct.test", kLeafHashes[0], 999999,
941 proof_callback1.AsCallback()),
942 IsError(net::ERR_IO_PENDING));
943
944 MockClosure not_throttled_callback;
945 log_client->NotifyWhenNotThrottled(not_throttled_callback.AsCallback());
946
947 proof_callback1.WaitUntilRun(TestTimeouts::action_max_timeout());
948 ASSERT_TRUE(proof_callback1.called());
949 ASSERT_TRUE(not_throttled_callback.called());
950
951 // Start another query to check |not_throttled_callback| doesn't fire again.
952 not_throttled_callback.Reset();
953
954 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[1], 666);
955 mock_dns_.ExpectAuditProofRequestAndResponse("0.666.999999.tree.ct.test.",
956 audit_proof.begin(),
957 audit_proof.begin() + 7);
958 mock_dns_.ExpectAuditProofRequestAndResponse("7.666.999999.tree.ct.test.",
959 audit_proof.begin() + 7,
960 audit_proof.begin() + 14);
961 mock_dns_.ExpectAuditProofRequestAndResponse("14.666.999999.tree.ct.test.",
962 audit_proof.begin() + 14,
963 audit_proof.end());
964
965 MockAuditProofCallback proof_callback2;
966 ASSERT_THAT(log_client->QueryAuditProof("ct.test", kLeafHashes[1], 999999,
967 proof_callback2.AsCallback()),
968 IsError(net::ERR_IO_PENDING));
969
970 // Give the query a chance to run.
971 proof_callback2.WaitUntilRun(TestTimeouts::action_max_timeout());
972
973 ASSERT_TRUE(proof_callback2.called());
974 ASSERT_FALSE(not_throttled_callback.called());
975 }
976
885 INSTANTIATE_TEST_CASE_P(ReadMode, 977 INSTANTIATE_TEST_CASE_P(ReadMode,
886 LogDnsClientTest, 978 LogDnsClientTest,
887 ::testing::Values(net::IoMode::ASYNC, 979 ::testing::Values(net::IoMode::ASYNC,
888 net::IoMode::SYNCHRONOUS)); 980 net::IoMode::SYNCHRONOUS));
889 981
890 } // namespace 982 } // namespace
891 } // namespace certificate_transparency 983 } // namespace certificate_transparency
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698