Chromium Code Reviews| Index: chrome/browser/net/network_stats.cc |
| =================================================================== |
| --- chrome/browser/net/network_stats.cc (revision 152367) |
| +++ chrome/browser/net/network_stats.cc (working copy) |
| @@ -22,7 +22,6 @@ |
| #include "net/base/network_change_notifier.h" |
| #include "net/base/test_completion_callback.h" |
| #include "net/proxy/proxy_service.h" |
| -#include "net/socket/tcp_client_socket.h" |
| #include "net/udp/udp_client_socket.h" |
| #include "net/udp/udp_server_socket.h" |
| @@ -30,21 +29,18 @@ |
| namespace chrome_browser_net { |
| -// This specifies the number of bytes to be sent to the TCP/UDP servers as part |
| +// This specifies the number of bytes to be sent to the UDP echo servers as part |
| // of small packet size test. |
| static const uint32 kSmallTestBytesToSend = 100; |
| -// This specifies the number of bytes to be sent to the TCP/UDP servers as part |
| +// This specifies the number of bytes to be sent to the UDP echo servers as part |
| // of medium packet size test. |
| static const uint32 kMediumTestBytesToSend = 500; |
| -// This specifies the number of bytes to be sent to the TCP/UDP servers as part |
| +// This specifies the number of bytes to be sent to the UDP echo servers as part |
| // of large packet size test. |
| static const uint32 kLargeTestBytesToSend = 1200; |
| -// This specifies the maximum message (payload) size. |
| -static const uint32 kMaxMessage = 2048; |
| - |
| // This specifies starting position of the <version> and length of the |
| // <version> in "echo request" and "echo response". |
| static const uint32 kVersionNumber = 1; |
| @@ -85,11 +81,8 @@ |
| static const uint32 kEncodedPayloadStart = kKeyEnd; |
| // HistogramPortSelector and kPorts should be kept in sync. |
| -static const int32 kPorts[] = {53, 80, 587, 6121, 8080, 999999}; |
| +static const int32 kPorts[] = {6121, 999999}; |
|
jar (doing other things)
2012/09/05 01:00:55
Is this a sentinel? If so, use a named constant to
ramant (doing other things)
2012/09/05 04:28:54
999999 is used by the unit tests. Added a comment
|
| -// The packet number that is to be sent to the server. |
| -static uint32 g_packet_number_ = 0; |
| - |
| // Maximum number of packets that can be sent to the server for packet loss |
| // correlation test. |
| static const uint32 kMaximumCorrelationPackets = 6; |
| @@ -97,16 +90,26 @@ |
| // Maximum number of packets that can be sent to the server. |
| static const uint32 kMaximumSequentialPackets = 21; |
| +// This specifies the maximum message (payload) size. |
| +static const uint32 kMaxMessage = kMaximumSequentialPackets * 2048; |
| + |
| // NetworkStats methods and members. |
| NetworkStats::NetworkStats() |
| - : load_size_(0), |
| + : read_buffer_(NULL), |
| + write_buffer_(NULL), |
| + load_size_(0), |
| bytes_to_read_(0), |
| bytes_to_send_(0), |
| has_proxy_server_(false), |
| packets_to_send_(0), |
| packets_sent_(0), |
| + packets_received_(0), |
| + packets_received_mask_(0), |
| + packet_number_(0), |
| base_packet_number_(0), |
| - packets_received_mask_(0), |
| + sending_complete_(false), |
| + current_test_(START_PACKET_TEST), |
| + next_test_(TEST_TYPE_MAX), |
| ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { |
| } |
| @@ -142,6 +145,17 @@ |
| return DoConnect(rv); |
| } |
| +void NetworkStats::RestartPacketTest() { |
| + ResetData(); |
| + current_test_ = next_test_; |
| + next_test_ = TEST_TYPE_MAX; |
| + if (!bytes_to_read_) { |
| + read_buffer_ = NULL; |
| + ReadData(); |
| + } |
| + SendPacket(); |
| +} |
| + |
| void NetworkStats::Initialize( |
| uint32 bytes_to_send, |
| HistogramPortSelector histogram_port, |
| @@ -151,39 +165,119 @@ |
| DCHECK(bytes_to_send); // We should have data to send. |
| DCHECK(packets_to_send); // We should send at least 1 packet. |
| DCHECK_LE(bytes_to_send, kLargeTestBytesToSend); |
| + DCHECK_LE(packets_to_send, 8 * sizeof(packets_received_mask_)); |
| load_size_ = bytes_to_send; |
| packets_to_send_ = packets_to_send; |
| - |
| histogram_port_ = histogram_port; |
| has_proxy_server_ = has_proxy_server; |
| finished_callback_ = finished_callback; |
| + ResetData(); |
| + packet_number_ = base::RandInt(1 << 28, INT_MAX); |
| } |
| +void NetworkStats::ResetData() { |
| + write_buffer_ = NULL; |
| + bytes_to_send_ = 0; |
| + packet_status_.clear(); |
| + packet_status_.resize(packets_to_send_); |
| + packets_sent_ = 0; |
| + packets_received_ = 0; |
| + packets_received_mask_ = 0; |
| + sending_complete_ = false; |
| +} |
| + |
| +void NetworkStats::OnResolveComplete(int result) { |
| + DoConnect(result); |
| +} |
| + |
| +bool NetworkStats::DoConnect(int result) { |
| + if (result != net::OK) { |
| + Finish(RESOLVE_FAILED, result); |
| + return false; |
| + } |
| + |
| + net::UDPClientSocket* udp_socket = |
| + new net::UDPClientSocket(net::DatagramSocket::DEFAULT_BIND, |
| + net::RandIntCallback(), |
| + NULL, |
| + net::NetLog::Source()); |
| + if (!udp_socket) { |
| + Finish(SOCKET_CREATE_FAILED, net::ERR_INVALID_ARGUMENT); |
| + return false; |
| + } |
| + set_socket(udp_socket); |
| + |
| + if (addresses().empty()) { |
| + Finish(RESOLVE_FAILED, net::ERR_INVALID_ARGUMENT); |
| + return false; |
| + } |
| + |
| + const net::IPEndPoint& endpoint = addresses().front(); |
| + int rv = udp_socket->Connect(endpoint); |
| + if (rv < 0) { |
| + Finish(CONNECT_FAILED, rv); |
| + return false; |
| + } |
| + |
| + const int kSocketBufferSize = packets_to_send_ * 2048; |
|
jar (doing other things)
2012/09/05 01:00:55
Perhaps we want this to be double the packets_to_s
ramant (doing other things)
2012/09/05 04:28:54
Done.
|
| + udp_socket->SetSendBufferSize(kSocketBufferSize); |
| + udp_socket->SetReceiveBufferSize(kSocketBufferSize); |
| + return ConnectComplete(rv); |
| +} |
| + |
| bool NetworkStats::ConnectComplete(int result) { |
| if (result < 0) { |
| Finish(CONNECT_FAILED, result); |
| return false; |
| } |
| - base_packet_number_ = g_packet_number_; |
| - start_time_ = base::TimeTicks::Now(); |
| + ReadData(); |
| SendPacket(); |
| return true; |
| } |
| -void NetworkStats::DoFinishCallback(int result) { |
| - if (!finished_callback_.is_null()) { |
| - net::CompletionCallback callback = finished_callback_; |
| - finished_callback_.Reset(); |
| - callback.Run(result); |
| - } |
| +void NetworkStats::SendPacket() { |
| + while (true) { |
| + if (bytes_to_send_ == 0u) { |
| + if (packets_sent_ >= packets_to_send_) { |
| + // Timeout if we don't get response back from echo servers in 30 secs. |
| + sending_complete_ = true; |
| + const int kReadDataTimeoutMs = 30000; |
| + StartReadDataTimer(kReadDataTimeoutMs); |
| + break; |
| + } |
| + |
| + ++packet_number_; |
| + if (packets_sent_ == 0) |
| + base_packet_number_ = packet_number_; |
| + bytes_to_send_ = SendingPacketSize(); |
| + SendNextPacketAfterDelay(); |
| + break; |
| + } |
| + |
| + int rv = SendData(); |
| + if (rv < 0) { |
| + if (rv != net::ERR_IO_PENDING) |
| + Finish(WRITE_FAILED, rv); |
| + break; |
| + } |
| + DCHECK_EQ(bytes_to_send_, 0u); |
| + }; |
| } |
| -void NetworkStats::set_socket(net::Socket* socket) { |
| - DCHECK(socket); |
| - DCHECK(!socket_.get()); |
| - socket_.reset(socket); |
| +void NetworkStats::SendNextPacketAfterDelay() { |
| + if (current_test_ == PACED_PACKET_TEST) { |
| + MessageLoop::current()->PostDelayedTask( |
| + FROM_HERE, |
| + base::Bind(&NetworkStats::SendPacket, weak_factory_.GetWeakPtr()), |
| + average_time_); |
| + return; |
| + } |
| + |
| + MessageLoop::current()->PostTask( |
| + FROM_HERE, |
| + base::Bind(&NetworkStats::SendPacket, weak_factory_.GetWeakPtr())); |
| } |
| bool NetworkStats::ReadComplete(int result) { |
| @@ -194,13 +288,29 @@ |
| return true; |
| } |
| - encoded_message_.append(read_buffer_->data(), result); |
| + if (result > 0) { |
| + std::string encoded_message; |
| + encoded_message.append(read_buffer_->data(), result); |
| + if (VerifyBytes(encoded_message) == SUCCESS) { |
| + base::TimeTicks now = base::TimeTicks::Now(); |
| + if (packets_received_ == 0) |
| + packet_1st_byte_read_time_ = now; |
| + packet_last_byte_read_time_ = now; |
| + DCHECK_GE(bytes_to_read_, static_cast<uint32>(result)); |
| + if (bytes_to_read_ >= static_cast<uint32>(result)) |
| + bytes_to_read_ -= result; |
| + ++packets_received_; |
| + } |
| + } |
| + |
| read_buffer_ = NULL; |
| - bytes_to_read_ -= result; |
| // No more data to read. |
| if (!bytes_to_read_ || result == 0) { |
| + if (!sending_complete_) |
| + return false; |
| + |
| Status status = VerifyPackets(); |
| if (status == SUCCESS) |
| Finish(status, net::OK); |
| @@ -211,35 +321,6 @@ |
| return false; |
| } |
| -void NetworkStats::OnResolveComplete(int result) { |
| - DoConnect(result); |
| -} |
| - |
| -void NetworkStats::SendPacket() { |
| - DCHECK_EQ(bytes_to_send_, 0u); |
| - uint32 sending_packet_size = SendingPacketSize(); |
| - |
| - while (packets_to_send_ > packets_sent_) { |
| - ++g_packet_number_; |
| - |
| - bytes_to_send_ = sending_packet_size; |
| - int rv = SendData(); |
| - if (rv < 0) { |
| - if (rv != net::ERR_IO_PENDING) |
| - Finish(WRITE_FAILED, rv); |
| - return; |
| - } |
| - DCHECK_EQ(bytes_to_send_, 0u); |
| - } |
| - |
| - // Timeout if we don't get response back from echo servers in 60 secs. |
| - const int kReadDataTimeoutMs = 60000; |
| - StartReadDataTimer(kReadDataTimeoutMs); |
| - |
| - bytes_to_read_ = packets_sent_ * ReceivingPacketSize(); |
| - ReadData(); |
| -} |
| - |
| void NetworkStats::OnReadComplete(int result) { |
| if (!ReadComplete(result)) { |
| // Called ReadData() via PostDelayedTask() to avoid recursion. Added a delay |
| @@ -282,7 +363,7 @@ |
| int rv; |
| do { |
| if (!socket_.get()) |
| - return; |
| + break; |
| DCHECK(!read_buffer_.get()); |
| @@ -293,10 +374,11 @@ |
| base::Bind(&NetworkStats::OnReadComplete, |
| base::Unretained(this))); |
| if (rv == net::ERR_IO_PENDING) |
| - return; |
| + break; |
| + |
| // If we have read all the data then return. |
| if (ReadComplete(rv)) |
| - return; |
| + break; |
| } while (rv > 0); |
| } |
| @@ -304,10 +386,23 @@ |
| DCHECK(bytes_to_send_); // We should have data to send. |
| do { |
| if (!write_buffer_.get()) { |
| + // Send a new packet. |
| scoped_refptr<net::IOBufferWithSize> buffer( |
| new net::IOBufferWithSize(bytes_to_send_)); |
| GetEchoRequest(buffer); |
| write_buffer_ = new net::DrainableIOBuffer(buffer, bytes_to_send_); |
| + |
| + // As soon as we write, a read could happen. Thus update all the book |
| + // keeping data. |
| + bytes_to_read_ += ReceivingPacketSize(); |
| + ++packets_sent_; |
| + if (packets_sent_ >= packets_to_send_) |
| + sending_complete_ = true; |
| + |
| + uint32 packet_index = packet_number_ - base_packet_number_; |
| + DCHECK_GE(packet_index, 0u); |
| + DCHECK_LT(packet_index, packet_status_.size()); |
| + packet_status_[packet_index].start_time_ = base::TimeTicks::Now(); |
| } |
| if (!socket_.get()) |
| @@ -337,18 +432,21 @@ |
| if (!write_buffer_->BytesRemaining()) |
| write_buffer_ = NULL; |
| bytes_to_send_ -= bytes_sent; |
| - if (bytes_to_send_ == 0) |
| - ++packets_sent_; |
| } |
| void NetworkStats::StartReadDataTimer(int milliseconds) { |
| MessageLoop::current()->PostDelayedTask( |
| FROM_HERE, |
| - base::Bind(&NetworkStats::OnReadDataTimeout, weak_factory_.GetWeakPtr()), |
| + base::Bind(&NetworkStats::OnReadDataTimeout, |
| + weak_factory_.GetWeakPtr(), |
| + base_packet_number_), |
| base::TimeDelta::FromMilliseconds(milliseconds)); |
| } |
| -void NetworkStats::OnReadDataTimeout() { |
| +void NetworkStats::OnReadDataTimeout(uint32 test_base_packet_number) { |
| + if (test_base_packet_number != base_packet_number_) |
| + return; |
| + |
| Status status = VerifyPackets(); |
| if (status == SUCCESS) |
| Finish(status, net::OK); |
| @@ -395,7 +493,7 @@ |
| memcpy(buffer + kVersionStart, version.c_str(), kVersionLength); |
| // Copy the packet_number into the payload. |
| - std::string packet_number = base::StringPrintf("%010d", g_packet_number_); |
| + std::string packet_number = base::StringPrintf("%010d", packet_number_); |
| DCHECK(kPacketNumberLength == packet_number.length()); |
| DCHECK_GE(buffer_size, kPayloadStart + kPacketNumberLength); |
| memcpy(buffer + kPayloadStart, packet_number.c_str(), kPacketNumberLength); |
| @@ -426,24 +524,49 @@ |
| } |
| NetworkStats::Status NetworkStats::VerifyPackets() { |
| - uint32 packet_start = 0; |
| - size_t message_length = encoded_message_.length(); |
| - uint32 receiving_packet_size = ReceivingPacketSize(); |
| Status status = SUCCESS; |
| - for (uint32 i = 0; i < packets_to_send_; i++) { |
| - if (message_length <= packet_start) { |
| - status = ZERO_LENGTH_ERROR; |
| - break; |
| + uint32 successful_packets = 0; |
| + |
| + for (uint32 i = 0; i < packet_status_.size(); i++) { |
| + if (packets_received_mask_ & (1 << i)) |
| + ++successful_packets; |
| + } |
| + |
| + if (packets_received_ > packets_to_send_) |
| + status = TOO_MANY_PACKETS; |
| + |
| + if (packets_to_send_ > successful_packets) |
| + status = SOME_PACKETS_NOT_VERIFIED; |
| + |
| + if (current_test_ == START_PACKET_TEST && |
| + packets_to_send_ == kMaximumSequentialPackets && |
| + successful_packets > 1) { |
| + base::TimeDelta total_time; |
| + if (packet_last_byte_read_time_ > packet_1st_byte_read_time_) { |
| + total_time = |
| + packet_last_byte_read_time_ - packet_1st_byte_read_time_; |
| } |
| - std::string response = |
| - encoded_message_.substr(packet_start, receiving_packet_size); |
| - Status packet_status = VerifyBytes(response); |
| - if (packet_status != SUCCESS) |
| - status = packet_status; |
| - packet_start += receiving_packet_size; |
| + average_time_ = total_time / (successful_packets - 1); |
| + std::string load_size_string = base::StringPrintf("%dB", load_size_); |
|
jar (doing other things)
2012/09/05 01:00:55
nit: We only use this on line 556, so we might as
ramant (doing other things)
2012/09/05 04:28:54
Done.
|
| + std::string histogram_name = base::StringPrintf( |
| + "NetConnectivity3.%s.Sent%02d.%d.%s.PacketDelay", |
| + TestName(), |
| + kMaximumSequentialPackets, |
| + kPorts[histogram_port_], |
| + load_size_string.c_str()); |
| + base::Histogram* histogram = base::Histogram::FactoryTimeGet( |
| + histogram_name, base::TimeDelta::FromMilliseconds(1), |
| + base::TimeDelta::FromSeconds(30), 50, |
| + base::Histogram::kUmaTargetedHistogramFlag); |
| + histogram->AddTime(total_time); |
| + |
| + int experiment_to_run = base::RandInt(1, 2); |
| + if (experiment_to_run == 1) |
| + next_test_ = NON_PACED_PACKET_TEST; |
| + else |
| + next_test_ = PACED_PACKET_TEST; |
| } |
| - if (message_length > packet_start) |
| - status = TOO_MANY_PACKETS; |
| + |
| return status; |
| } |
| @@ -496,9 +619,11 @@ |
| char packet_number_data[kPacketNumberLength + 1]; |
| memset(packet_number_data, 0, kPacketNumberLength + 1); |
| memcpy(packet_number_data, decoded_data, kPacketNumberLength); |
| - uint32 packet_number = atoi(packet_number_data); |
| - uint32 packet_index = packet_number - base_packet_number_; |
| - if (packet_index > packets_to_send_) |
| + uint32 packet_number_received = atoi(packet_number_data); |
| + if (packet_number_received < base_packet_number_) |
| + return PREVIOUS_PACKET_NUMBER; |
| + uint32 packet_index = packet_number_received - base_packet_number_; |
| + if (packet_index >= packets_to_send_) |
| return INVALID_PACKET_NUMBER; |
| stream_.Reset(); |
| @@ -507,26 +632,100 @@ |
| return PATTERN_CHANGED; |
| } |
| - packets_received_mask_ |= 1 << (packet_index - 1); |
| + if (packets_received_mask_ & (1 << packet_index)) |
| + return DUPLICATE_PACKET; |
| + |
| + packets_received_mask_ |= 1 << packet_index; |
| + DCHECK_GE(packet_index, 0u); |
| + DCHECK_LT(packet_index, packet_status_.size()); |
| + packet_status_[packet_index].end_time_ = base::TimeTicks::Now(); |
| return SUCCESS; |
| } |
| -void NetworkStats::RecordAcksReceivedHistograms(const char* load_size_string) { |
| +void NetworkStats::Finish(Status status, int result) { |
| + // Set the base_packet_number_ for the start of next test. Changing the |
| + // |base_packet_number_| indicates to OnReadDataTimeout that the Finish has |
| + // already been called for the test and that it doesn't need to call Finish |
| + // again. |
| + base_packet_number_ = packet_number_ + 1; |
| + RecordHistograms(PROTOCOL_UDP, status, result); |
| + |
| + if (next_test() == NON_PACED_PACKET_TEST || |
| + next_test() == PACED_PACKET_TEST) { |
| + MessageLoop::current()->PostTask( |
| + FROM_HERE, |
| + base::Bind(&NetworkStats::RestartPacketTest, |
| + weak_factory_.GetWeakPtr())); |
| + return; |
| + } |
| + |
| + DoFinishCallback(result); |
| + |
| + // Close the socket so that there are no more IO operations. |
| + net::UDPClientSocket* udp_socket = |
| + static_cast<net::UDPClientSocket*>(socket()); |
| + if (udp_socket) |
| + udp_socket->Close(); |
| + |
| + delete this; |
| +} |
| + |
| +void NetworkStats::DoFinishCallback(int result) { |
| + if (!finished_callback_.is_null()) { |
| + net::CompletionCallback callback = finished_callback_; |
| + finished_callback_.Reset(); |
| + callback.Run(result); |
| + } |
| +} |
| + |
| +void NetworkStats::RecordHistograms(const ProtocolValue& protocol, |
| + const Status& status, |
| + int result) { |
| + if (packets_to_send_ != kMaximumSequentialPackets && |
| + packets_to_send_ != kMaximumCorrelationPackets) { |
| + return; |
| + } |
| + |
| + std::string load_size_string = base::StringPrintf("%dB", load_size_); |
| + |
| + if (packets_to_send_ != kMaximumSequentialPackets) { |
| + RecordPacketLossSeriesHistograms( |
| + protocol, load_size_string, status, result); |
| + return; |
| + } |
| + |
| + for (uint32 i = 0; i < 3; i++) |
| + RecordRTTHistograms(protocol, load_size_string, i); |
| + |
| + RecordRTTHistograms(protocol, load_size_string, 9); |
| + RecordRTTHistograms(protocol, load_size_string, 19); |
| + |
| + RecordAcksReceivedHistograms(load_size_string); |
| +} |
| + |
| +void NetworkStats::RecordAcksReceivedHistograms( |
| + const std::string& load_size_string) { |
| + DCHECK_EQ(packets_to_send_, kMaximumSequentialPackets); |
| + |
| + const char* test_name = TestName(); |
| bool received_atleast_one_packet = packets_received_mask_ > 0; |
| + |
| std::string histogram_name = base::StringPrintf( |
| - "NetConnectivity2.Sent%d.GotAnAck.%d.%s", |
| + "NetConnectivity3.%s.Sent%02d.GotAnAck.%d.%s", |
| + test_name, |
| kMaximumSequentialPackets, |
| kPorts[histogram_port_], |
| - load_size_string); |
| + load_size_string.c_str()); |
| base::Histogram* got_an_ack_histogram = base::BooleanHistogram::FactoryGet( |
| histogram_name, base::Histogram::kUmaTargetedHistogramFlag); |
| got_an_ack_histogram->AddBoolean(received_atleast_one_packet); |
| histogram_name = base::StringPrintf( |
| - "NetConnectivity2.Sent%d.PacketsSent.%d.%s", |
| + "NetConnectivity3.%s.Sent%02d.PacketsSent.%d.%s", |
| + test_name, |
| kMaximumSequentialPackets, |
| kPorts[histogram_port_], |
| - load_size_string); |
| + load_size_string.c_str()); |
| base::Histogram* packets_sent_histogram = |
| base::Histogram::FactoryGet( |
| histogram_name, |
| @@ -538,14 +737,15 @@ |
| return; |
| histogram_name = base::StringPrintf( |
| - "NetConnectivity2.Sent%d.AckReceivedForNthPacket.%d.%s", |
| + "NetConnectivity3.%s.Sent%02d.AckReceivedForNthPacket.%02d.%s", |
| + test_name, |
| kMaximumSequentialPackets, |
| kPorts[histogram_port_], |
| - load_size_string); |
| + load_size_string.c_str()); |
| base::Histogram* ack_received_for_nth_packet_histogram = |
| base::Histogram::FactoryGet( |
| histogram_name, |
| - 1, kMaximumSequentialPackets, kMaximumSequentialPackets + 1, |
| + 1, kMaximumSequentialPackets + 1, kMaximumSequentialPackets + 2, |
| base::Histogram::kUmaTargetedHistogramFlag); |
| int count = 0; |
| @@ -558,11 +758,12 @@ |
| if (packet_number < 2) |
| continue; |
| histogram_name = base::StringPrintf( |
| - "NetConnectivity2.Sent%d.AcksReceivedFromFirst%dPackets.%d.%s", |
| + "NetConnectivity3.%s.Sent%02d.AcksReceivedFromFirst%02dPackets.%d.%s", |
| + test_name, |
| kMaximumSequentialPackets, |
| packet_number, |
| kPorts[histogram_port_], |
| - load_size_string); |
| + load_size_string.c_str()); |
| base::Histogram* acks_received_count_histogram = |
| base::Histogram::FactoryGet( |
| histogram_name, 1, packet_number, packet_number + 1, |
| @@ -573,24 +774,28 @@ |
| void NetworkStats::RecordPacketLossSeriesHistograms( |
| const ProtocolValue& protocol, |
| + const std::string& load_size_string, |
| const Status& status, |
| - const char* load_size_string, |
| int result) { |
| if (packets_to_send_ < 2 || protocol != PROTOCOL_UDP) |
| return; |
| - // Build "NetConnectivity2.Send6.SeriesAcked.<port>.<load_size>" histogram |
| + const char* test_name = TestName(); |
| + |
| + // Build "NetConnectivity3.Send6.SeriesAcked.<port>.<load_size>" histogram |
| // name. Total number of histograms are 5*2. |
| std::string series_acked_histogram_name = base::StringPrintf( |
| - "NetConnectivity2.Send6.SeriesAcked.%d.%s", |
| + "NetConnectivity3.%s.Send6.SeriesAcked.%d.%s", |
| + test_name, |
| kPorts[histogram_port_], |
| - load_size_string); |
| - // Build "NetConnectivity2.Send6.PacketsSent.<port>.<load_size>" histogram |
| + load_size_string.c_str()); |
| + // Build "NetConnectivity3.Send6.PacketsSent.<port>.<load_size>" histogram |
| // name. Total number of histograms are 5*2. |
| std::string packets_sent_histogram_name = base::StringPrintf( |
| - "NetConnectivity2.Send6.PacketsSent.%d.%s", |
| + "NetConnectivity3.%s.Send6.PacketsSent.%d.%s", |
| + test_name, |
| kPorts[histogram_port_], |
| - load_size_string); |
| + load_size_string.c_str()); |
| // If we are running without a proxy, we'll generate 2 distinct histograms in |
| // each case, one will have the ".NoProxy" suffix. |
| @@ -616,146 +821,50 @@ |
| } |
| } |
| -void NetworkStats::RecordHistograms(const ProtocolValue& protocol, |
| - const Status& status, |
| - int result) { |
| - // Build <load_size> string. |
| - const char* kSmallLoadString = "100B"; |
| - const char* kMediumLoadString = "500B"; |
| - const char* kLargeLoadString = "1K"; |
| - const char* load_size_string; |
| - if (load_size_ == kSmallTestBytesToSend) |
| - load_size_string = kSmallLoadString; |
| - else if (load_size_ == kMediumTestBytesToSend) |
| - load_size_string = kMediumLoadString; |
| - else |
| - load_size_string = kLargeLoadString; |
| +void NetworkStats::RecordRTTHistograms(const ProtocolValue& protocol, |
| + const std::string& load_size_string, |
| + uint32 index) { |
| + DCHECK_GE(index, 0u); |
| + DCHECK_LT(index, packet_status_.size()); |
| - if (packets_to_send_ == kMaximumSequentialPackets) { |
| - RecordAcksReceivedHistograms(load_size_string); |
| - return; |
| - } |
| - RecordPacketLossSeriesHistograms(protocol, status, load_size_string, result); |
| + const char* test_name = TestName(); |
| + std::string rtt_histogram_name = base::StringPrintf( |
| + "NetConnectivity3.%s.Sent%02d.Success.RTT.Packet%02d.%d.%s", |
| + test_name, |
| + packets_to_send_, |
| + index + 1, |
| + kPorts[histogram_port_], |
| + load_size_string.c_str()); |
| + base::Histogram* rtt_histogram = base::Histogram::FactoryTimeGet( |
| + rtt_histogram_name, |
| + base::TimeDelta::FromMilliseconds(10), |
| + base::TimeDelta::FromSeconds(30), 50, |
| + base::Histogram::kUmaTargetedHistogramFlag); |
| + base::TimeDelta duration = |
| + packet_status_[index].end_time_ - packet_status_[index].start_time_; |
| + rtt_histogram->AddTime(duration); |
| } |
| -// UDPStatsClient methods and members. |
| -UDPStatsClient::UDPStatsClient() |
| - : NetworkStats() { |
| -} |
| - |
| -UDPStatsClient::~UDPStatsClient() { |
| -} |
| - |
| -bool UDPStatsClient::DoConnect(int result) { |
| - if (result != net::OK) { |
| - Finish(RESOLVE_FAILED, result); |
| - return false; |
| +const char* NetworkStats::TestName() { |
| + switch (current_test_) { |
| + case START_PACKET_TEST: |
| + return "StartPacket"; |
| + case NON_PACED_PACKET_TEST: |
| + return "NonPacedPacket"; |
| + case PACED_PACKET_TEST: |
| + return "PacedPacket"; |
| + default: |
| + NOTREACHED(); |
| + return "None"; |
| } |
| - |
| - net::UDPClientSocket* udp_socket = |
| - new net::UDPClientSocket(net::DatagramSocket::DEFAULT_BIND, |
| - net::RandIntCallback(), |
| - NULL, |
| - net::NetLog::Source()); |
| - if (!udp_socket) { |
| - Finish(SOCKET_CREATE_FAILED, net::ERR_INVALID_ARGUMENT); |
| - return false; |
| - } |
| - set_socket(udp_socket); |
| - |
| - if (addresses().empty()) { |
| - Finish(RESOLVE_FAILED, net::ERR_INVALID_ARGUMENT); |
| - return false; |
| - } |
| - |
| - const net::IPEndPoint& endpoint = addresses().front(); |
| - int rv = udp_socket->Connect(endpoint); |
| - if (rv < 0) { |
| - Finish(CONNECT_FAILED, rv); |
| - return false; |
| - } |
| - return NetworkStats::ConnectComplete(rv); |
| } |
| -bool UDPStatsClient::ReadComplete(int result) { |
| - DCHECK_NE(net::ERR_IO_PENDING, result); |
| - if (result <= 0) { |
| - Finish(READ_FAILED, result); |
| - return true; |
| - } |
| - return NetworkStats::ReadComplete(result); |
| +void NetworkStats::set_socket(net::Socket* socket) { |
| + DCHECK(socket); |
| + DCHECK(!socket_.get()); |
| + socket_.reset(socket); |
| } |
| -void UDPStatsClient::Finish(Status status, int result) { |
| - RecordHistograms(PROTOCOL_UDP, status, result); |
| - |
| - DoFinishCallback(result); |
| - |
| - // Close the socket so that there are no more IO operations. |
| - net::UDPClientSocket* udp_socket = |
| - static_cast<net::UDPClientSocket*>(socket()); |
| - if (udp_socket) |
| - udp_socket->Close(); |
| - |
| - delete this; |
| -} |
| - |
| -// TCPStatsClient methods and members. |
| -TCPStatsClient::TCPStatsClient() { |
| -} |
| - |
| -TCPStatsClient::~TCPStatsClient() { |
| -} |
| - |
| -bool TCPStatsClient::DoConnect(int result) { |
| - if (result != net::OK) { |
| - Finish(RESOLVE_FAILED, result); |
| - return false; |
| - } |
| - |
| - net::TCPClientSocket* tcp_socket = |
| - new net::TCPClientSocket(addresses(), NULL, net::NetLog::Source()); |
| - if (!tcp_socket) { |
| - Finish(SOCKET_CREATE_FAILED, net::ERR_INVALID_ARGUMENT); |
| - return false; |
| - } |
| - set_socket(tcp_socket); |
| - |
| - int rv = tcp_socket->Connect(base::Bind(&TCPStatsClient::OnConnectComplete, |
| - base::Unretained(this))); |
| - if (rv == net::ERR_IO_PENDING) |
| - return true; |
| - |
| - return NetworkStats::ConnectComplete(rv); |
| -} |
| - |
| -void TCPStatsClient::OnConnectComplete(int result) { |
| - NetworkStats::ConnectComplete(result); |
| -} |
| - |
| -bool TCPStatsClient::ReadComplete(int result) { |
| - DCHECK_NE(net::ERR_IO_PENDING, result); |
| - if (result < 0) { |
| - Finish(READ_FAILED, result); |
| - return true; |
| - } |
| - return NetworkStats::ReadComplete(result); |
| -} |
| - |
| -void TCPStatsClient::Finish(Status status, int result) { |
| - RecordHistograms(PROTOCOL_TCP, status, result); |
| - |
| - DoFinishCallback(result); |
| - |
| - // Disconnect the socket so that there are no more IO operations. |
| - net::TCPClientSocket* tcp_socket = |
| - static_cast<net::TCPClientSocket*>(socket()); |
| - if (tcp_socket) |
| - tcp_socket->Disconnect(); |
| - |
| - delete this; |
| -} |
| - |
| // ProxyDetector methods and members. |
| ProxyDetector::ProxyDetector(net::ProxyService* proxy_service, |
| const net::HostPortPair& server_address, |
| @@ -834,7 +943,7 @@ |
| NetworkStats::PORT_6121; |
| if (!trial.get()) { |
| - // Set up a field trial to collect network stats for UDP and TCP. |
| + // Set up a field trial to collect network stats for UDP. |
| const base::FieldTrial::Probability kDivisor = 1000; |
| // Enable the connectivity testing for 0.5% of the users in stable channel. |
| @@ -902,16 +1011,16 @@ |
| switch (experiment_to_run) { |
| case 1: |
| { |
| - UDPStatsClient* udp_stats_client = new UDPStatsClient(); |
| + NetworkStats* udp_stats_client = new NetworkStats(); |
| udp_stats_client->Start( |
| host_resolver, server_address, histogram_port, has_proxy_server, |
| - kSmallTestBytesToSend, kMaximumCorrelationPackets, |
| + kLargeTestBytesToSend, kMaximumCorrelationPackets, |
| net::CompletionCallback()); |
| } |
| break; |
| case 2: |
| { |
| - UDPStatsClient* udp_stats_client = new UDPStatsClient(); |
| + NetworkStats* udp_stats_client = new NetworkStats(); |
| udp_stats_client->Start( |
| host_resolver, server_address, histogram_port, has_proxy_server, |
| kSmallTestBytesToSend, kMaximumSequentialPackets, |
| @@ -920,7 +1029,7 @@ |
| break; |
| case 3: |
| { |
| - UDPStatsClient* udp_stats_client = new UDPStatsClient(); |
| + NetworkStats* udp_stats_client = new NetworkStats(); |
| udp_stats_client->Start( |
| host_resolver, server_address, histogram_port, has_proxy_server, |
| kMediumTestBytesToSend, kMaximumSequentialPackets, |
| @@ -929,7 +1038,7 @@ |
| break; |
| case 4: |
| { |
| - UDPStatsClient* udp_stats_client = new UDPStatsClient(); |
| + NetworkStats* udp_stats_client = new NetworkStats(); |
| udp_stats_client->Start( |
| host_resolver, server_address, histogram_port, has_proxy_server, |
| kLargeTestBytesToSend, kMaximumSequentialPackets, |