diff options
Diffstat (limited to 'net/curvecp/curvecp_transfer_unittest.cc')
-rw-r--r-- | net/curvecp/curvecp_transfer_unittest.cc | 313 |
1 files changed, 313 insertions, 0 deletions
diff --git a/net/curvecp/curvecp_transfer_unittest.cc b/net/curvecp/curvecp_transfer_unittest.cc new file mode 100644 index 0000000..e433118 --- /dev/null +++ b/net/curvecp/curvecp_transfer_unittest.cc @@ -0,0 +1,313 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <poll.h> + +#include "base/basictypes.h" +#include "base/message_loop.h" +#include "base/metrics/histogram.h" +#include "net/base/net_test_suite.h" +#include "net/base/test_completion_callback.h" +#include "net/curvecp/circular_buffer.h" +#include "net/curvecp/received_block_list.h" +#include "net/curvecp/rtt_and_send_rate_calculator.h" +#include "net/curvecp/test_client.h" +#include "net/curvecp/test_server.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "testing/platform_test.h" + +namespace net { + +class CurveCPTransferTest : public PlatformTest { + public: + CurveCPTransferTest() {} +}; + +void RunEchoTest(int bytes) { + TestServer server; + TestClient client; + + EXPECT_TRUE(server.Start(1234)); + HostPortPair server_address("localhost", 1234); + TestCompletionCallback cb; + EXPECT_TRUE(client.Start(server_address, bytes, &cb)); + + int rv = cb.WaitForResult(); + EXPECT_EQ(0, rv); + EXPECT_EQ(0, server.error_count()); + EXPECT_EQ(0, client.error_count()); +} + +/* +TEST_F(CurveCPTransferTest, Echo_50B_Of_Data) { + RunEchoTest(50); +} + +TEST_F(CurveCPTransferTest, Echo_1KB_Of_Data) { + RunEchoTest(1024); +} + +TEST_F(CurveCPTransferTest, Echo_4KB_Of_Data) { + RunEchoTest(4096); +} +*/ + +// XXXMB +TEST_F(CurveCPTransferTest, Echo_1MB_Of_Data) { + RunEchoTest(1024*1024); +} + +// TODO(mbelshe): Do something meaningful with this test. +TEST_F(CurveCPTransferTest, RTTIntial) { + RttAndSendRateCalculator rate; + printf("initial %d (%d, %d/%d)\n", rate.send_rate(), + rate.rtt_average(), + rate.rtt_lo(), + rate.rtt_hi()); + + for (int i = 0; i < 10; ++i) { + rate.OnMessage(100*1000); + printf("%d: %d (%d, %d/%d)\n", i, rate.send_rate(), + rate.rtt_average(), + rate.rtt_lo(), + rate.rtt_hi()); + usleep(200000); + } + + rate.OnTimeout(); + rate.OnTimeout(); + rate.OnTimeout(); + rate.OnTimeout(); + + // Get worse + for (int i = 0; i < 10; ++i) { + rate.OnMessage((500 + i)*1000); + printf("%d: %d (%d, %d/%d)\n", i, rate.send_rate(), + rate.rtt_average(), + rate.rtt_lo(), + rate.rtt_hi()); + usleep(200000); + } + + // Get better + for (int i = 0; i < 10; ++i) { + rate.OnMessage((100 - i)*1000); + printf("%d: %d (%d, %d/%d)\n", i, rate.send_rate(), + rate.rtt_average(), + rate.rtt_lo(), + rate.rtt_hi()); + usleep(200000); + } +} + +TEST_F(CurveCPTransferTest, CircularBufferFillAndDrain) { + CircularBuffer buffer(10); + for (int i = 0; i < 30; ++i) { + EXPECT_EQ(0, buffer.length()); + EXPECT_EQ(3, buffer.write("abc", 3)); + EXPECT_EQ(3, buffer.length()); + char read_data[3]; + EXPECT_EQ(3, buffer.read(read_data, 3)); + EXPECT_EQ(0, memcmp(read_data, "abc", 3)); + } +} + +TEST_F(CurveCPTransferTest, CircularBufferTooLargeFill) { + CircularBuffer buffer(10); + EXPECT_EQ(10, buffer.write("abcdefghijklm", 13)); + EXPECT_EQ(0, buffer.write("a", 1)); + char read_data[10]; + EXPECT_EQ(10, buffer.read(read_data, 10)); + EXPECT_EQ(0, memcmp(read_data, "abcdefghij", 10)); + EXPECT_EQ(1, buffer.write("a", 1)); +} + +TEST_F(CurveCPTransferTest, CircularBufferEdgeCases) { + CircularBuffer buffer(10); + char read_data[10]; + EXPECT_EQ(9, buffer.write("abcdefghi", 9)); + EXPECT_EQ(9, buffer.read(read_data, 10)); + EXPECT_EQ(0, memcmp(read_data, "abcdefghi", 9)); + EXPECT_EQ(1, buffer.write("a", 1)); + EXPECT_EQ(1, buffer.write("b", 1)); + EXPECT_EQ(2, buffer.read(read_data, 10)); + EXPECT_EQ(0, memcmp(read_data, "ab", 2)); +} + +TEST_F(CurveCPTransferTest, CircularBufferOneWriteTwoReads) { + CircularBuffer buffer(1000); + char read_data[10]; + EXPECT_EQ(13, buffer.write("abcdefghijklm", 13)); + EXPECT_EQ(10, buffer.read(read_data, 10)); + EXPECT_EQ(0, memcmp(read_data, "abcdefghij", 10)); + EXPECT_EQ(3, buffer.read(read_data, 10)); + EXPECT_EQ(0, memcmp(read_data, "klm", 3)); +} + +TEST_F(CurveCPTransferTest, CircularBufferTwoWritesOneRead) { + CircularBuffer buffer(1000); + char read_data[10]; + EXPECT_EQ(6, buffer.write("abcdef", 6)); + EXPECT_EQ(4, buffer.write("ghij", 4)); + EXPECT_EQ(10, buffer.read(read_data, 10)); + EXPECT_EQ(0, memcmp(read_data, "abcdefghij", 10)); +} + +TEST_F(CurveCPTransferTest, CircularBufferFillOnSpill) { + CircularBuffer buffer(10); + char read_data[10]; + EXPECT_EQ(10, buffer.write("abcdefghij", 10)); + EXPECT_EQ(3, buffer.read(read_data, 3)); + EXPECT_EQ(0, memcmp(read_data, "abc", 3)); + // We now have a hole at the head of the circular buffer. + EXPECT_EQ(1, buffer.write("x", 1)); + EXPECT_EQ(1, buffer.write("y", 1)); + EXPECT_EQ(1, buffer.write("z", 1)); + EXPECT_EQ(0, buffer.write("q", 1)); // Overflow + EXPECT_EQ(10, buffer.read(read_data, 10)); + EXPECT_EQ(0, memcmp(read_data, "defghijxyz", 10)); +} + +TEST_F(CurveCPTransferTest, ReceivedBlockList) { + scoped_refptr<IOBufferWithSize> buffer(new IOBufferWithSize(16)); + memcpy(buffer->data(), "abcdefghijklmnop", 16); + scoped_refptr<IOBufferWithSize> read_buffer(new IOBufferWithSize(100)); + + ReceivedBlockList list; + EXPECT_EQ(0, list.current_position()); + list.AddBlock(0, buffer, 16); + EXPECT_EQ(0, list.current_position()); + list.AddBlock(0, buffer, 16); + EXPECT_EQ(16, list.ReadBytes(read_buffer.get(), read_buffer->size())); + EXPECT_EQ(0, memcmp(buffer->data(), read_buffer->data(), 16)); + EXPECT_EQ(16, list.current_position()); +} + +TEST_F(CurveCPTransferTest, ReceivedBlockListCoalesce) { + scoped_refptr<IOBufferWithSize> buffer(new IOBufferWithSize(8)); + memcpy(buffer->data(), "abcdefgh", 8); + scoped_refptr<IOBufferWithSize> read_buffer(new IOBufferWithSize(100)); + + ReceivedBlockList list; + EXPECT_EQ(0, list.current_position()); + list.AddBlock(0, buffer, 8); + EXPECT_EQ(0, list.current_position()); + list.AddBlock(8, buffer, 8); + EXPECT_EQ(16, list.ReadBytes(read_buffer.get(), read_buffer->size())); + EXPECT_EQ(0, memcmp(buffer->data(), read_buffer->data(), 8)); + EXPECT_EQ(0, memcmp(buffer->data(), read_buffer->data() + 8, 8)); + EXPECT_EQ(16, list.current_position()); +} + +TEST_F(CurveCPTransferTest, ReceivedBlockListGap) { + scoped_refptr<IOBufferWithSize> buffer(new IOBufferWithSize(8)); + memcpy(buffer->data(), "abcdefgh", 8); + scoped_refptr<IOBufferWithSize> read_buffer(new IOBufferWithSize(100)); + + ReceivedBlockList list; + EXPECT_EQ(0, list.current_position()); + list.AddBlock(0, buffer, 8); + EXPECT_EQ(0, list.current_position()); + + // Leaves a gap + list.AddBlock(16, buffer, 8); + EXPECT_EQ(8, list.ReadBytes(read_buffer.get(), read_buffer->size())); + EXPECT_EQ(0, list.ReadBytes(read_buffer.get(), read_buffer->size())); + EXPECT_EQ(8, list.current_position()); + + // Fill the gap + list.AddBlock(8, buffer, 8); + EXPECT_EQ(16, list.ReadBytes(read_buffer.get(), read_buffer->size())); + EXPECT_EQ(0, memcmp(buffer->data(), read_buffer->data(), 8)); + EXPECT_EQ(0, memcmp(buffer->data(), read_buffer->data() + 8, 8)); + EXPECT_EQ(24, list.current_position()); +} + +TEST_F(CurveCPTransferTest, ReceivedBlockListPartialRead) { + scoped_refptr<IOBufferWithSize> buffer(new IOBufferWithSize(8)); + memcpy(buffer->data(), "abcdefgh", 8); + scoped_refptr<IOBufferWithSize> read_buffer(new IOBufferWithSize(100)); + + ReceivedBlockList list; + EXPECT_EQ(0, list.current_position()); + list.AddBlock(0, buffer, 8); + EXPECT_EQ(0, list.current_position()); + list.AddBlock(8, buffer, 8); + EXPECT_EQ(3, list.ReadBytes(read_buffer.get(), 3)); + EXPECT_EQ(0, memcmp("abc", read_buffer->data(), 3)); + EXPECT_EQ(3, list.ReadBytes(read_buffer.get(), 3)); + EXPECT_EQ(0, memcmp("def", read_buffer->data(), 3)); + EXPECT_EQ(3, list.ReadBytes(read_buffer.get(), 3)); + EXPECT_EQ(0, memcmp("gha", read_buffer->data(), 3)); + EXPECT_EQ(3, list.ReadBytes(read_buffer.get(), 3)); + EXPECT_EQ(0, memcmp("bcd", read_buffer->data(), 3)); + EXPECT_EQ(3, list.ReadBytes(read_buffer.get(), 3)); + EXPECT_EQ(0, memcmp("efg", read_buffer->data(), 3)); + EXPECT_EQ(1, list.ReadBytes(read_buffer.get(), 3)); + EXPECT_EQ(0, memcmp("h", read_buffer->data(), 1)); + EXPECT_EQ(16, list.current_position()); +} + +/* + +class PollTimerTester { + public: + PollTimerTester() { + Test(); + } + + void Test() { + struct pollfd fds[3]; + memset(fds, 0, sizeof(struct pollfd) * 3); + + while(true) { + (void)poll(fds, 1, 2); + base::TimeTicks now(base::TimeTicks::Now()); + if (!last_.is_null()) { + LOG(ERROR) << "Time was " << (now - last_).InMicroseconds(); + LOG(ERROR) << "Time was " << (now - last_).InMilliseconds(); + } + last_ = now; + } + } + + base::TimeTicks last_; +}; + +class TimerTester { + public: + TimerTester() { + timer_.Start(base::TimeDelta(), this, &TimerTester::OnTimer); + } + void OnTimer() { + base::TimeTicks now(base::TimeTicks::Now()); + if (!last_.is_null()) { + LOG(ERROR) << "Time was " << (now - last_).InMicroseconds(); + LOG(ERROR) << "Time was " << (now - last_).InMilliseconds(); + } + last_ = now; + //timer_.Start(base::TimeDelta(), this, &TimerTester::OnTimer); + timer_.Start(base::TimeDelta::FromMicroseconds(150), + this, + &TimerTester::OnTimer); + } + + base::TimeTicks last_; + base::OneShotTimer<TimerTester> timer_; +}; + +TEST_F(CurveCPTransferTest, MinTimer) { + PollTimerTester tester; + MessageLoop::current()->Run(); +} + +*/ + +} // namespace net + +int main(int argc, char**argv) { + base::StatisticsRecorder recorder; + NetTestSuite test_suite(argc, argv); + return test_suite.Run(); +} |