Commit 6fc79ea0 authored by wtc@chromium.org's avatar wtc@chromium.org

Add an async ChannelIDSource for testing.

R=avd@chromium.org,rch@chromium.org
BUG=none

Review URL: https://codereview.chromium.org/380543003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@282253 0039d316-1c4b-4281-b951-d872f2087c98
parent 789640a1
...@@ -255,6 +255,17 @@ TEST_P(QuicCryptoServerStreamTest, WithoutCertificates) { ...@@ -255,6 +255,17 @@ TEST_P(QuicCryptoServerStreamTest, WithoutCertificates) {
TEST_P(QuicCryptoServerStreamTest, ChannelID) { TEST_P(QuicCryptoServerStreamTest, ChannelID) {
client_options_.channel_id_enabled = true; client_options_.channel_id_enabled = true;
client_options_.channel_id_source_async = false;
// CompleteCryptoHandshake verifies
// stream_.crypto_negotiated_params().channel_id is correct.
EXPECT_EQ(2, CompleteCryptoHandshake());
EXPECT_TRUE(stream_.encryption_established());
EXPECT_TRUE(stream_.handshake_confirmed());
}
TEST_P(QuicCryptoServerStreamTest, ChannelIDAsync) {
client_options_.channel_id_enabled = true;
client_options_.channel_id_source_async = true;
// CompleteCryptoHandshake verifies // CompleteCryptoHandshake verifies
// stream_.crypto_negotiated_params().channel_id is correct. // stream_.crypto_negotiated_params().channel_id is correct.
EXPECT_EQ(2, CompleteCryptoHandshake()); EXPECT_EQ(2, CompleteCryptoHandshake());
......
...@@ -124,11 +124,56 @@ bool HexChar(char c, uint8* value) { ...@@ -124,11 +124,56 @@ bool HexChar(char c, uint8* value) {
return false; return false;
} }
// A ChannelIDSource that works in asynchronous mode unless the |callback|
// argument to GetChannelIDKey is NULL.
class AsyncTestChannelIDSource : public ChannelIDSource,
public CryptoTestUtils::WorkSource {
public:
// Takes ownership of |sync_source|, a synchronous ChannelIDSource.
explicit AsyncTestChannelIDSource(ChannelIDSource* sync_source)
: sync_source_(sync_source) {}
virtual ~AsyncTestChannelIDSource() {}
// ChannelIDSource implementation.
virtual QuicAsyncStatus GetChannelIDKey(
const string& hostname,
scoped_ptr<ChannelIDKey>* channel_id_key,
ChannelIDSourceCallback* callback) OVERRIDE {
// Synchronous mode.
if (!callback) {
return sync_source_->GetChannelIDKey(hostname, channel_id_key, NULL);
}
// Asynchronous mode.
QuicAsyncStatus status =
sync_source_->GetChannelIDKey(hostname, &channel_id_key_, NULL);
if (status != QUIC_SUCCESS) {
return QUIC_FAILURE;
}
callback_.reset(callback);
return QUIC_PENDING;
}
// WorkSource implementation.
virtual void DoPendingWork() OVERRIDE {
if (callback_.get()) {
callback_->Run(&channel_id_key_);
callback_.reset();
}
}
private:
scoped_ptr<ChannelIDSource> sync_source_;
scoped_ptr<ChannelIDSourceCallback> callback_;
scoped_ptr<ChannelIDKey> channel_id_key_;
};
} // anonymous namespace } // anonymous namespace
CryptoTestUtils::FakeClientOptions::FakeClientOptions() CryptoTestUtils::FakeClientOptions::FakeClientOptions()
: dont_verify_certs(false), : dont_verify_certs(false),
channel_id_enabled(false) { channel_id_enabled(false),
channel_id_source_async(false) {
} }
// static // static
...@@ -176,9 +221,16 @@ int CryptoTestUtils::HandshakeWithFakeClient( ...@@ -176,9 +221,16 @@ int CryptoTestUtils::HandshakeWithFakeClient(
crypto_config.SetProofVerifier(FakeProofVerifierForTesting()); crypto_config.SetProofVerifier(FakeProofVerifierForTesting());
} }
bool is_https = false; bool is_https = false;
AsyncTestChannelIDSource* async_channel_id_source = NULL;
if (options.channel_id_enabled) { if (options.channel_id_enabled) {
is_https = true; is_https = true;
crypto_config.SetChannelIDSource(ChannelIDSourceForTesting());
ChannelIDSource* source = ChannelIDSourceForTesting();
if (options.channel_id_source_async) {
async_channel_id_source = new AsyncTestChannelIDSource(source);
source = async_channel_id_source;
}
crypto_config.SetChannelIDSource(source);
} }
QuicServerId server_id(kServerHostname, kServerPort, is_https, QuicServerId server_id(kServerHostname, kServerPort, is_https,
PRIVACY_MODE_DISABLED); PRIVACY_MODE_DISABLED);
...@@ -190,7 +242,8 @@ int CryptoTestUtils::HandshakeWithFakeClient( ...@@ -190,7 +242,8 @@ int CryptoTestUtils::HandshakeWithFakeClient(
CHECK(client.CryptoConnect()); CHECK(client.CryptoConnect());
CHECK_EQ(1u, client_conn->packets_.size()); CHECK_EQ(1u, client_conn->packets_.size());
CommunicateHandshakeMessages(client_conn, &client, server_conn, server); CommunicateHandshakeMessagesAndDoWork(
client_conn, &client, server_conn, server, async_channel_id_source);
CompareClientAndServerKeys(&client, server); CompareClientAndServerKeys(&client, server);
...@@ -227,20 +280,33 @@ void CryptoTestUtils::CommunicateHandshakeMessages( ...@@ -227,20 +280,33 @@ void CryptoTestUtils::CommunicateHandshakeMessages(
QuicCryptoStream* a, QuicCryptoStream* a,
PacketSavingConnection* b_conn, PacketSavingConnection* b_conn,
QuicCryptoStream* b) { QuicCryptoStream* b) {
CommunicateHandshakeMessagesAndDoWork(a_conn, a, b_conn, b, NULL);
}
// static
void CryptoTestUtils::CommunicateHandshakeMessagesAndDoWork(
PacketSavingConnection* a_conn,
QuicCryptoStream* a,
PacketSavingConnection* b_conn,
QuicCryptoStream* b,
WorkSource* work_source) {
size_t a_i = 0, b_i = 0; size_t a_i = 0, b_i = 0;
while (!a->handshake_confirmed()) { while (!a->handshake_confirmed()) {
ASSERT_GT(a_conn->packets_.size(), a_i); ASSERT_GT(a_conn->packets_.size(), a_i);
LOG(INFO) << "Processing " << a_conn->packets_.size() - a_i LOG(INFO) << "Processing " << a_conn->packets_.size() - a_i
<< " packets a->b"; << " packets a->b";
MovePackets(a_conn, &a_i, b, b_conn); MovePackets(a_conn, &a_i, b, b_conn);
if (work_source) {
work_source->DoPendingWork();
}
ASSERT_GT(b_conn->packets_.size(), b_i); ASSERT_GT(b_conn->packets_.size(), b_i);
LOG(INFO) << "Processing " << b_conn->packets_.size() - b_i LOG(INFO) << "Processing " << b_conn->packets_.size() - b_i
<< " packets b->a"; << " packets b->a";
if (b_conn->packets_.size() - b_i == 2) {
LOG(INFO) << "here";
}
MovePackets(b_conn, &b_i, a, a_conn); MovePackets(b_conn, &b_i, a, a_conn);
if (work_source) {
work_source->DoPendingWork();
}
} }
} }
......
...@@ -38,6 +38,19 @@ class PacketSavingConnection; ...@@ -38,6 +38,19 @@ class PacketSavingConnection;
class CryptoTestUtils { class CryptoTestUtils {
public: public:
// An interface for a source of work. This may be use for invoking callbacks
// asynchronously.
//
// Call the DoPendingWork method regularly to do the work from this source.
class WorkSource {
public:
virtual ~WorkSource() {}
// Does pending work in this source. If there is no pending work, does
// nothing.
virtual void DoPendingWork() = 0;
};
// FakeClientOptions bundles together a number of options for configuring // FakeClientOptions bundles together a number of options for configuring
// HandshakeWithFakeClient. // HandshakeWithFakeClient.
struct FakeClientOptions { struct FakeClientOptions {
...@@ -50,6 +63,10 @@ class CryptoTestUtils { ...@@ -50,6 +63,10 @@ class CryptoTestUtils {
// If channel_id_enabled is true then the client will attempt to send a // If channel_id_enabled is true then the client will attempt to send a
// ChannelID. // ChannelID.
bool channel_id_enabled; bool channel_id_enabled;
// If channel_id_source_async is true then the client will use an async
// ChannelIDSource for testing. Ignored if channel_id_enabled is false.
bool channel_id_source_async;
}; };
// returns: the number of client hellos that the client sent. // returns: the number of client hellos that the client sent.
...@@ -76,6 +93,17 @@ class CryptoTestUtils { ...@@ -76,6 +93,17 @@ class CryptoTestUtils {
PacketSavingConnection* b_conn, PacketSavingConnection* b_conn,
QuicCryptoStream* b); QuicCryptoStream* b);
// CommunicateHandshakeMessagesAndDoWork moves messages from |a| to |b| and
// back until |a|'s handshake has completed. If |work_source| is not NULL,
// CommunicateHandshakeMessagesAndDoWork also does work from |work_source|
// between processing messages.
static void CommunicateHandshakeMessagesAndDoWork(
PacketSavingConnection* a_conn,
QuicCryptoStream* a,
PacketSavingConnection* b_conn,
QuicCryptoStream* b,
WorkSource* work_source);
// AdvanceHandshake attempts to moves messages from |a| to |b| and |b| to |a|. // AdvanceHandshake attempts to moves messages from |a| to |b| and |b| to |a|.
// Returns the number of messages moved. // Returns the number of messages moved.
static std::pair<size_t, size_t> AdvanceHandshake( static std::pair<size_t, size_t> AdvanceHandshake(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment