summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/socket/socket_test_util.cc176
-rw-r--r--net/socket/socket_test_util.h51
-rw-r--r--net/spdy/spdy_network_transaction_unittest.cc207
3 files changed, 227 insertions, 207 deletions
diff --git a/net/socket/socket_test_util.cc b/net/socket/socket_test_util.cc
index 360f34f..399a34c 100644
--- a/net/socket/socket_test_util.cc
+++ b/net/socket/socket_test_util.cc
@@ -16,8 +16,98 @@
#include "net/socket/socket.h"
#include "testing/gtest/include/gtest/gtest.h"
+#define NET_TRACE(level, s) DLOG(level) << s << __FUNCTION__ << "() "
+
namespace net {
+namespace {
+
+inline char AsciifyHigh(char x) {
+ char nybble = static_cast<char>((x >> 4) & 0x0F);
+ return nybble + ((nybble < 0x0A) ? '0' : 'A' - 10);
+}
+
+inline char AsciifyLow(char x) {
+ char nybble = static_cast<char>((x >> 0) & 0x0F);
+ return nybble + ((nybble < 0x0A) ? '0' : 'A' - 10);
+}
+
+inline char Asciify(char x) {
+ if ((x < 0) || !isprint(x))
+ return '.';
+ return x;
+}
+
+void DumpData(const char* data, int data_len) {
+ if (logging::LOG_INFO < logging::GetMinLogLevel())
+ return;
+ DLOG(INFO) << "Length: " << data_len;
+ const char* pfx = "Data: ";
+ if (!data || (data_len <= 0)) {
+ DLOG(INFO) << pfx << "<None>";
+ } else {
+ int i;
+ for (i = 0; i <= (data_len - 4); i += 4) {
+ DLOG(INFO) << pfx
+ << AsciifyHigh(data[i + 0]) << AsciifyLow(data[i + 0])
+ << AsciifyHigh(data[i + 1]) << AsciifyLow(data[i + 1])
+ << AsciifyHigh(data[i + 2]) << AsciifyLow(data[i + 2])
+ << AsciifyHigh(data[i + 3]) << AsciifyLow(data[i + 3])
+ << " '"
+ << Asciify(data[i + 0])
+ << Asciify(data[i + 1])
+ << Asciify(data[i + 2])
+ << Asciify(data[i + 3])
+ << "'";
+ pfx = " ";
+ }
+ // Take care of any 'trailing' bytes, if data_len was not a multiple of 4.
+ switch (data_len - i) {
+ case 3:
+ DLOG(INFO) << pfx
+ << AsciifyHigh(data[i + 0]) << AsciifyLow(data[i + 0])
+ << AsciifyHigh(data[i + 1]) << AsciifyLow(data[i + 1])
+ << AsciifyHigh(data[i + 2]) << AsciifyLow(data[i + 2])
+ << " '"
+ << Asciify(data[i + 0])
+ << Asciify(data[i + 1])
+ << Asciify(data[i + 2])
+ << " '";
+ break;
+ case 2:
+ DLOG(INFO) << pfx
+ << AsciifyHigh(data[i + 0]) << AsciifyLow(data[i + 0])
+ << AsciifyHigh(data[i + 1]) << AsciifyLow(data[i + 1])
+ << " '"
+ << Asciify(data[i + 0])
+ << Asciify(data[i + 1])
+ << " '";
+ break;
+ case 1:
+ DLOG(INFO) << pfx
+ << AsciifyHigh(data[i + 0]) << AsciifyLow(data[i + 0])
+ << " '"
+ << Asciify(data[i + 0])
+ << " '";
+ break;
+ }
+ }
+}
+
+void DumpMockRead(const MockRead& r) {
+ if (logging::LOG_INFO < logging::GetMinLogLevel())
+ return;
+ DLOG(INFO) << "Async: " << r.async;
+ DLOG(INFO) << "Result: " << r.result;
+ DumpData(r.data, r.data_len);
+ const char* stop = (r.sequence_number & MockRead::STOPLOOP) ? " (STOP)" : "";
+ DLOG(INFO) << "Stage: " << (r.sequence_number & ~MockRead::STOPLOOP)
+ << stop;
+ DLOG(INFO) << "Time: " << r.time_stamp.ToInternalValue();
+}
+
+} // namespace
+
MockClientSocket::MockClientSocket(net::NetLog* net_log)
: ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)),
connected_(false),
@@ -437,6 +527,92 @@ void DelayedSocketData::CompleteRead() {
socket()->OnReadComplete(GetNextRead());
}
+OrderedSocketData::OrderedSocketData(
+ MockRead* reads, size_t reads_count, MockWrite* writes, size_t writes_count)
+ : StaticSocketDataProvider(reads, reads_count, writes, writes_count),
+ sequence_number_(0), loop_stop_stage_(0), callback_(NULL),
+ ALLOW_THIS_IN_INITIALIZER_LIST(factory_(this)) {
+}
+
+OrderedSocketData::OrderedSocketData(
+ const MockConnect& connect,
+ MockRead* reads, size_t reads_count,
+ MockWrite* writes, size_t writes_count)
+ : StaticSocketDataProvider(reads, reads_count, writes, writes_count),
+ sequence_number_(0), loop_stop_stage_(0), callback_(NULL),
+ ALLOW_THIS_IN_INITIALIZER_LIST(factory_(this)) {
+ set_connect_data(connect);
+}
+
+MockRead OrderedSocketData::GetNextRead() {
+ const MockRead& next_read = StaticSocketDataProvider::PeekRead();
+ if (next_read.sequence_number & MockRead::STOPLOOP)
+ EndLoop();
+ if ((next_read.sequence_number & ~MockRead::STOPLOOP) <=
+ sequence_number_++) {
+ NET_TRACE(INFO, " *** ") << "Stage " << sequence_number_ - 1
+ << ": Read " << read_index();
+ DumpMockRead(next_read);
+ return StaticSocketDataProvider::GetNextRead();
+ }
+ NET_TRACE(INFO, " *** ") << "Stage " << sequence_number_ - 1
+ << ": I/O Pending";
+ MockRead result = MockRead(true, ERR_IO_PENDING);
+ DumpMockRead(result);
+ return result;
+}
+
+MockWriteResult OrderedSocketData::OnWrite(const std::string& data) {
+ NET_TRACE(INFO, " *** ") << "Stage " << sequence_number_
+ << ": Write " << write_index();
+ DumpMockRead(PeekWrite());
+ ++sequence_number_;
+ MessageLoop::current()->PostDelayedTask(
+ FROM_HERE,
+ factory_.NewRunnableMethod(&OrderedSocketData::CompleteRead), 100);
+ return StaticSocketDataProvider::OnWrite(data);
+}
+
+void OrderedSocketData::Reset() {
+ NET_TRACE(INFO, " *** ") << "Stage "
+ << sequence_number_ << ": Reset()";
+ sequence_number_ = 0;
+ loop_stop_stage_ = 0;
+ set_socket(NULL);
+ factory_.RevokeAll();
+ StaticSocketDataProvider::Reset();
+}
+
+void OrderedSocketData::EndLoop() {
+ // If we've already stopped the loop, don't do it again until we've advanced
+ // to the next sequence_number.
+ NET_TRACE(INFO, " *** ") << "Stage " << sequence_number_ << ": EndLoop()";
+ if (loop_stop_stage_ > 0) {
+ const MockRead& next_read = StaticSocketDataProvider::PeekRead();
+ if ((next_read.sequence_number & ~MockRead::STOPLOOP) >
+ loop_stop_stage_) {
+ NET_TRACE(INFO, " *** ") << "Stage " << sequence_number_
+ << ": Clearing stop index";
+ loop_stop_stage_ = 0;
+ } else {
+ return;
+ }
+ }
+ // Record the sequence_number at which we stopped the loop.
+ NET_TRACE(INFO, " *** ") << "Stage " << sequence_number_
+ << ": Posting Quit at read " << read_index();
+ loop_stop_stage_ = sequence_number_;
+ if (callback_)
+ callback_->RunWithParams(Tuple1<int>(ERR_IO_PENDING));
+}
+
+void OrderedSocketData::CompleteRead() {
+ if (socket()) {
+ NET_TRACE(INFO, " *** ") << "Stage " << sequence_number_;
+ socket()->OnReadComplete(GetNextRead());
+ }
+}
+
void MockClientSocketFactory::AddSocketDataProvider(
SocketDataProvider* data) {
mock_data_.Add(data);
diff --git a/net/socket/socket_test_util.h b/net/socket/socket_test_util.h
index f30a641..6a47539 100644
--- a/net/socket/socket_test_util.h
+++ b/net/socket/socket_test_util.h
@@ -276,6 +276,57 @@ class DelayedSocketData : public StaticSocketDataProvider,
ScopedRunnableMethodFactory<DelayedSocketData> factory_;
};
+// A DataProvider where the reads are ordered.
+// If a read is requested before its sequence number is reached, we return an
+// ERR_IO_PENDING (that way we don't have to explicitly add a MockRead just to
+// wait).
+// The sequence number is incremented on every read and write operation.
+// The message loop may be interrupted by setting the high bit of the sequence
+// number in the MockRead's sequence number. When that MockRead is reached,
+// we post a Quit message to the loop. This allows us to interrupt the reading
+// of data before a complete message has arrived, and provides support for
+// testing server push when the request is issued while the response is in the
+// middle of being received.
+class OrderedSocketData : public StaticSocketDataProvider,
+ public base::RefCounted<OrderedSocketData> {
+ public:
+ // |reads| the list of MockRead completions.
+ // |writes| the list of MockWrite completions.
+ // Note: All MockReads and MockWrites must be async.
+ // Note: The MockRead and MockWrite lists musts end with a EOF
+ // e.g. a MockRead(true, 0, 0);
+ OrderedSocketData(MockRead* reads, size_t reads_count,
+ MockWrite* writes, size_t writes_count);
+
+ // |connect| the result for the connect phase.
+ // |reads| the list of MockRead completions.
+ // |writes| the list of MockWrite completions.
+ // Note: All MockReads and MockWrites must be async.
+ // Note: The MockRead and MockWrite lists musts end with a EOF
+ // e.g. a MockRead(true, 0, 0);
+ OrderedSocketData(const MockConnect& connect,
+ MockRead* reads, size_t reads_count,
+ MockWrite* writes, size_t writes_count);
+
+ virtual MockRead GetNextRead();
+ virtual MockWriteResult OnWrite(const std::string& data);
+ virtual void Reset();
+ void SetCompletionCallback(CompletionCallback* callback) {
+ callback_ = callback;
+ }
+
+ // Posts a quit message to the current message loop, if one is running.
+ void EndLoop();
+
+ void CompleteRead();
+
+ private:
+ int sequence_number_;
+ int loop_stop_stage_;
+ CompletionCallback* callback_;
+ ScopedRunnableMethodFactory<OrderedSocketData> factory_;
+};
+
// Holds an array of SocketDataProvider elements. As Mock{TCP,SSL}ClientSocket
// objects get instantiated, they take their data from the i'th element of this
// array.
diff --git a/net/spdy/spdy_network_transaction_unittest.cc b/net/spdy/spdy_network_transaction_unittest.cc
index 28e00d0..b36a04e 100644
--- a/net/spdy/spdy_network_transaction_unittest.cc
+++ b/net/spdy/spdy_network_transaction_unittest.cc
@@ -23,8 +23,6 @@
#include "net/spdy/spdy_test_util.h"
#include "testing/platform_test.h"
-#define NET_TRACE(level, s) DLOG(level) << s << __FUNCTION__ << "() "
-
//-----------------------------------------------------------------------------
namespace net {
@@ -108,90 +106,6 @@ MockWrite* ChopFrame(const char* data, int length, int num_chunks) {
return chunks;
}
-inline char AsciifyHigh(char x) {
- char nybble = static_cast<char>((x >> 4) & 0x0F);
- return nybble + ((nybble < 0x0A) ? '0' : 'A' - 10);
-}
-
-inline char AsciifyLow(char x) {
- char nybble = static_cast<char>((x >> 0) & 0x0F);
- return nybble + ((nybble < 0x0A) ? '0' : 'A' - 10);
-}
-
-inline char Asciify(char x) {
- if ((x < 0) || !isprint(x))
- return '.';
- return x;
-}
-
-void DumpData(const char* data, int data_len) {
- if (logging::LOG_INFO < logging::GetMinLogLevel())
- return;
- DLOG(INFO) << "Length: " << data_len;
- const char* pfx = "Data: ";
- if (!data || (data_len <= 0)) {
- DLOG(INFO) << pfx << "<None>";
- } else {
- int i;
- for (i = 0; i <= (data_len - 4); i += 4) {
- DLOG(INFO) << pfx
- << AsciifyHigh(data[i + 0]) << AsciifyLow(data[i + 0])
- << AsciifyHigh(data[i + 1]) << AsciifyLow(data[i + 1])
- << AsciifyHigh(data[i + 2]) << AsciifyLow(data[i + 2])
- << AsciifyHigh(data[i + 3]) << AsciifyLow(data[i + 3])
- << " '"
- << Asciify(data[i + 0])
- << Asciify(data[i + 1])
- << Asciify(data[i + 2])
- << Asciify(data[i + 3])
- << "'";
- pfx = " ";
- }
- // Take care of any 'trailing' bytes, if data_len was not a multiple of 4.
- switch (data_len - i) {
- case 3:
- DLOG(INFO) << pfx
- << AsciifyHigh(data[i + 0]) << AsciifyLow(data[i + 0])
- << AsciifyHigh(data[i + 1]) << AsciifyLow(data[i + 1])
- << AsciifyHigh(data[i + 2]) << AsciifyLow(data[i + 2])
- << " '"
- << Asciify(data[i + 0])
- << Asciify(data[i + 1])
- << Asciify(data[i + 2])
- << " '";
- break;
- case 2:
- DLOG(INFO) << pfx
- << AsciifyHigh(data[i + 0]) << AsciifyLow(data[i + 0])
- << AsciifyHigh(data[i + 1]) << AsciifyLow(data[i + 1])
- << " '"
- << Asciify(data[i + 0])
- << Asciify(data[i + 1])
- << " '";
- break;
- case 1:
- DLOG(INFO) << pfx
- << AsciifyHigh(data[i + 0]) << AsciifyLow(data[i + 0])
- << " '"
- << Asciify(data[i + 0])
- << " '";
- break;
- }
- }
-}
-
-void DumpMockRead(const MockRead& r) {
- if (logging::LOG_INFO < logging::GetMinLogLevel())
- return;
- DLOG(INFO) << "Async: " << r.async;
- DLOG(INFO) << "Result: " << r.result;
- DumpData(r.data, r.data_len);
- const char* stop = (r.sequence_number & MockRead::STOPLOOP) ? " (STOP)" : "";
- DLOG(INFO) << "Stage: " << (r.sequence_number & ~MockRead::STOPLOOP)
- << stop;
- DLOG(INFO) << "Time: " << r.time_stamp.ToInternalValue();
-}
-
// ----------------------------------------------------------------------------
// Adds headers and values to a map.
@@ -494,127 +408,6 @@ spdy::SpdyFrame* ConstructSpdyGet(const char* const extra_headers[],
} // namespace
-// A DataProvider where the reads are ordered.
-// If a read is requested before its sequence number is reached, we return an
-// ERR_IO_PENDING (that way we don't have to explicitly add a MockRead just to
-// wait).
-// The sequence number is incremented on every read and write operation.
-// The message loop may be interrupted by setting the high bit of the sequence
-// number in the MockRead's sequence number. When that MockRead is reached,
-// we post a Quit message to the loop. This allows us to interrupt the reading
-// of data before a complete message has arrived, and provides support for
-// testing server push when the request is issued while the response is in the
-// middle of being received.
-class OrderedSocketData : public StaticSocketDataProvider,
- public base::RefCounted<OrderedSocketData> {
- public:
- // |reads| the list of MockRead completions.
- // |writes| the list of MockWrite completions.
- // Note: All MockReads and MockWrites must be async.
- // Note: The MockRead and MockWrite lists musts end with a EOF
- // e.g. a MockRead(true, 0, 0);
- OrderedSocketData(MockRead* reads, size_t reads_count,
- MockWrite* writes, size_t writes_count)
- : StaticSocketDataProvider(reads, reads_count, writes, writes_count),
- sequence_number_(0), loop_stop_stage_(0), callback_(NULL),
- ALLOW_THIS_IN_INITIALIZER_LIST(factory_(this)) {
- }
-
- // |connect| the result for the connect phase.
- // |reads| the list of MockRead completions.
- // |writes| the list of MockWrite completions.
- // Note: All MockReads and MockWrites must be async.
- // Note: The MockRead and MockWrite lists musts end with a EOF
- // e.g. a MockRead(true, 0, 0);
- OrderedSocketData(const MockConnect& connect,
- MockRead* reads, size_t reads_count,
- MockWrite* writes, size_t writes_count)
- : StaticSocketDataProvider(reads, reads_count, writes, writes_count),
- sequence_number_(0), loop_stop_stage_(0), callback_(NULL),
- ALLOW_THIS_IN_INITIALIZER_LIST(factory_(this)) {
- set_connect_data(connect);
- }
-
- virtual MockRead GetNextRead() {
- const MockRead& next_read = StaticSocketDataProvider::PeekRead();
- if (next_read.sequence_number & MockRead::STOPLOOP)
- EndLoop();
- if ((next_read.sequence_number & ~MockRead::STOPLOOP) <=
- sequence_number_++) {
- NET_TRACE(INFO, " *** ") << "Stage " << sequence_number_ - 1
- << ": Read " << read_index();
- DumpMockRead(next_read);
- return StaticSocketDataProvider::GetNextRead();
- }
- NET_TRACE(INFO, " *** ") << "Stage " << sequence_number_ - 1
- << ": I/O Pending";
- MockRead result = MockRead(true, ERR_IO_PENDING);
- DumpMockRead(result);
- return result;
- }
-
- virtual MockWriteResult OnWrite(const std::string& data) {
- NET_TRACE(INFO, " *** ") << "Stage " << sequence_number_
- << ": Write " << write_index();
- DumpMockRead(PeekWrite());
- ++sequence_number_;
- MessageLoop::current()->PostDelayedTask(FROM_HERE,
- factory_.NewRunnableMethod(&OrderedSocketData::CompleteRead), 100);
- return StaticSocketDataProvider::OnWrite(data);
- }
-
- virtual void Reset() {
- NET_TRACE(INFO, " *** ") << "Stage "
- << sequence_number_ << ": Reset()";
- sequence_number_ = 0;
- loop_stop_stage_ = 0;
- set_socket(NULL);
- factory_.RevokeAll();
- StaticSocketDataProvider::Reset();
- }
-
- void SetCompletionCallback(CompletionCallback* callback) {
- callback_ = callback;
- }
-
- // Posts a quit message to the current message loop, if one is running.
- void EndLoop() {
- // If we've already stopped the loop, don't do it again until we've advanced
- // to the next sequence_number.
- NET_TRACE(INFO, " *** ") << "Stage " << sequence_number_ << ": EndLoop()";
- if (loop_stop_stage_ > 0) {
- const MockRead& next_read = StaticSocketDataProvider::PeekRead();
- if ((next_read.sequence_number & ~MockRead::STOPLOOP) >
- loop_stop_stage_) {
- NET_TRACE(INFO, " *** ") << "Stage " << sequence_number_
- << ": Clearing stop index";
- loop_stop_stage_ = 0;
- } else {
- return;
- }
- }
- // Record the sequence_number at which we stopped the loop.
- NET_TRACE(INFO, " *** ") << "Stage " << sequence_number_
- << ": Posting Quit at read " << read_index();
- loop_stop_stage_ = sequence_number_;
- if (callback_)
- callback_->RunWithParams(Tuple1<int>(ERR_IO_PENDING));
- }
-
- void CompleteRead() {
- if (socket()) {
- NET_TRACE(INFO, " *** ") << "Stage " << sequence_number_;
- socket()->OnReadComplete(GetNextRead());
- }
- }
-
- private:
- int sequence_number_;
- int loop_stop_stage_;
- CompletionCallback* callback_;
- ScopedRunnableMethodFactory<OrderedSocketData> factory_;
-};
-
class SpdyNetworkTransactionTest : public PlatformTest {
protected:
virtual void SetUp() {