blob: 58dc2dd5e04b9bce317044aafe497df92fe7ba29 [file] [log] [blame]
// Copyright 2017 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 "services/network/network_usage_accumulator.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace network {
namespace {
struct BytesTransferredKey {
uint32_t process_id;
uint32_t routing_id;
};
} // namespace
class NetworkUsageAccumulatorTest : public testing::Test {
public:
NetworkUsageAccumulatorTest() {}
~NetworkUsageAccumulatorTest() override {}
void SimulateRawBytesTransferred(const BytesTransferredKey& key,
int64_t bytes_received,
int64_t bytes_sent) {
network_usage_accumulator_.OnBytesTransferred(
key.process_id, key.routing_id, bytes_received, bytes_sent);
}
mojom::NetworkUsage* GetUsageForKey(
const std::vector<mojom::NetworkUsagePtr>& usages,
const BytesTransferredKey& key) {
for (const auto& usage : usages) {
if (key.process_id == usage->process_id &&
key.routing_id == usage->routing_id)
return usage.get();
}
return nullptr;
}
void ClearBytesTransferredForProcess(uint32_t process_id) {
network_usage_accumulator_.ClearBytesTransferredForProcess(process_id);
}
std::vector<mojom::NetworkUsagePtr> GetTotalNetworkUsages() const {
return network_usage_accumulator_.GetTotalNetworkUsages();
}
private:
NetworkUsageAccumulator network_usage_accumulator_;
DISALLOW_COPY_AND_ASSIGN(NetworkUsageAccumulatorTest);
};
// Tests that the |process_id| and |routing_id| are used in the map correctly.
TEST_F(NetworkUsageAccumulatorTest, ChildRouteData) {
BytesTransferredKey key = {100, 190};
int64_t correct_read_bytes = 0;
int64_t correct_sent_bytes = 0;
int read_bytes_array[] = {900, 300, 100};
int sent_bytes_array[] = {130, 153, 934};
for (int i : read_bytes_array) {
SimulateRawBytesTransferred(key, i, 0);
correct_read_bytes += i;
}
for (int i : sent_bytes_array) {
SimulateRawBytesTransferred(key, 0, i);
correct_sent_bytes += i;
}
auto returned_usages = GetTotalNetworkUsages();
EXPECT_EQ(1U, returned_usages.size());
EXPECT_EQ(correct_sent_bytes,
GetUsageForKey(returned_usages, key)->total_bytes_sent);
EXPECT_EQ(correct_read_bytes,
GetUsageForKey(returned_usages, key)->total_bytes_received);
}
// Tests that two distinct |process_id| and |routing_id| pairs are tracked
// separately in the unordered map.
TEST_F(NetworkUsageAccumulatorTest, TwoChildRouteData) {
BytesTransferredKey key1 = {32, 1};
BytesTransferredKey key2 = {17, 2};
int64_t correct_read_bytes1 = 0;
int64_t correct_sent_bytes1 = 0;
int64_t correct_read_bytes2 = 0;
int64_t correct_sent_bytes2 = 0;
int read_bytes_array1[] = {453, 987654, 946650};
int sent_bytes_array1[] = {138450, 1556473, 954434};
int read_bytes_array2[] = {905643, 324340, 654150};
int sent_bytes_array2[] = {1232138, 157312, 965464};
for (int i : read_bytes_array1) {
SimulateRawBytesTransferred(key1, i, 0);
correct_read_bytes1 += i;
}
for (int i : sent_bytes_array1) {
SimulateRawBytesTransferred(key1, 0, i);
correct_sent_bytes1 += i;
}
for (int i : read_bytes_array2) {
SimulateRawBytesTransferred(key2, i, 0);
correct_read_bytes2 += i;
}
for (int i : sent_bytes_array2) {
SimulateRawBytesTransferred(key2, 0, i);
correct_sent_bytes2 += i;
}
auto returned_usages = GetTotalNetworkUsages();
EXPECT_EQ(2U, returned_usages.size());
EXPECT_EQ(correct_sent_bytes1,
GetUsageForKey(returned_usages, key1)->total_bytes_sent);
EXPECT_EQ(correct_read_bytes1,
GetUsageForKey(returned_usages, key1)->total_bytes_received);
EXPECT_EQ(correct_sent_bytes2,
GetUsageForKey(returned_usages, key2)->total_bytes_sent);
EXPECT_EQ(correct_read_bytes2,
GetUsageForKey(returned_usages, key2)->total_bytes_received);
}
// Tests that two keys with the same |process_id| and |routing_id| are tracked
// together in the accumulator.
TEST_F(NetworkUsageAccumulatorTest, TwoSameChildRouteData) {
BytesTransferredKey key1 = {123, 456};
BytesTransferredKey key2 = {123, 456};
int64_t correct_read_bytes = 0;
int64_t correct_sent_bytes = 0;
int read_bytes_array[] = {90440, 12300, 103420};
int sent_bytes_array[] = {44130, 12353, 93234};
for (int i : read_bytes_array) {
SimulateRawBytesTransferred(key1, i, 0);
correct_read_bytes += i;
}
for (int i : sent_bytes_array) {
SimulateRawBytesTransferred(key1, 0, i);
correct_sent_bytes += i;
}
for (int i : read_bytes_array) {
SimulateRawBytesTransferred(key2, i, 0);
correct_read_bytes += i;
}
for (int i : sent_bytes_array) {
SimulateRawBytesTransferred(key2, 0, i);
correct_sent_bytes += i;
}
auto returned_usages = GetTotalNetworkUsages();
EXPECT_EQ(1U, returned_usages.size());
EXPECT_EQ(correct_sent_bytes,
GetUsageForKey(returned_usages, key1)->total_bytes_sent);
EXPECT_EQ(correct_read_bytes,
GetUsageForKey(returned_usages, key1)->total_bytes_received);
EXPECT_EQ(correct_sent_bytes,
GetUsageForKey(returned_usages, key2)->total_bytes_sent);
EXPECT_EQ(correct_read_bytes,
GetUsageForKey(returned_usages, key2)->total_bytes_received);
}
// Tests that the map can handle two process_ids with the same routing_id.
TEST_F(NetworkUsageAccumulatorTest, SameRouteDifferentProcesses) {
BytesTransferredKey key1 = {12, 143};
BytesTransferredKey key2 = {13, 143};
int64_t correct_read_bytes1 = 0;
int64_t correct_sent_bytes1 = 0;
int64_t correct_read_bytes2 = 0;
int64_t correct_sent_bytes2 = 0;
int read_bytes_array1[] = {453, 98754, 94650};
int sent_bytes_array1[] = {1350, 15643, 95434};
int read_bytes_array2[] = {905643, 3243, 654150};
int sent_bytes_array2[] = {12338, 157312, 9664};
for (int i : read_bytes_array1) {
SimulateRawBytesTransferred(key1, i, 0);
correct_read_bytes1 += i;
}
for (int i : sent_bytes_array1) {
SimulateRawBytesTransferred(key1, 0, i);
correct_sent_bytes1 += i;
}
for (int i : read_bytes_array2) {
SimulateRawBytesTransferred(key2, i, 0);
correct_read_bytes2 += i;
}
for (int i : sent_bytes_array2) {
SimulateRawBytesTransferred(key2, 0, i);
correct_sent_bytes2 += i;
}
auto returned_usages = GetTotalNetworkUsages();
EXPECT_EQ(2U, returned_usages.size());
EXPECT_EQ(correct_sent_bytes1,
GetUsageForKey(returned_usages, key1)->total_bytes_sent);
EXPECT_EQ(correct_read_bytes1,
GetUsageForKey(returned_usages, key1)->total_bytes_received);
EXPECT_EQ(correct_sent_bytes2,
GetUsageForKey(returned_usages, key2)->total_bytes_sent);
EXPECT_EQ(correct_read_bytes2,
GetUsageForKey(returned_usages, key2)->total_bytes_received);
}
// Tests that process data is cleared after termination.
TEST_F(NetworkUsageAccumulatorTest, ClearAfterTermination) {
// |key1| and |key2| belongs to the same process.
BytesTransferredKey key1 = {100, 190};
BytesTransferredKey key2 = {100, 191};
BytesTransferredKey key3 = {101, 191};
// No data has been transferred yet.
auto returned_usages = GetTotalNetworkUsages();
EXPECT_EQ(0U, returned_usages.size());
EXPECT_EQ(nullptr, GetUsageForKey(returned_usages, key1));
EXPECT_EQ(nullptr, GetUsageForKey(returned_usages, key2));
EXPECT_EQ(nullptr, GetUsageForKey(returned_usages, key3));
// Simulate data transfer on all three keys.
SimulateRawBytesTransferred(key1, 100, 1);
SimulateRawBytesTransferred(key2, 2, 200);
SimulateRawBytesTransferred(key3, 33, 333);
returned_usages = GetTotalNetworkUsages();
// Should have data observed on all three keys.
EXPECT_EQ(3U, returned_usages.size());
EXPECT_NE(nullptr, GetUsageForKey(returned_usages, key1));
EXPECT_NE(nullptr, GetUsageForKey(returned_usages, key2));
EXPECT_NE(nullptr, GetUsageForKey(returned_usages, key3));
// Simulate process termination on the first process.
ClearBytesTransferredForProcess(key1.process_id);
// |key1| and |key2| should both be cleared.
returned_usages = GetTotalNetworkUsages();
EXPECT_EQ(1U, returned_usages.size());
EXPECT_EQ(nullptr, GetUsageForKey(returned_usages, key1));
EXPECT_EQ(nullptr, GetUsageForKey(returned_usages, key2));
// |key3| shouldn't be affected.
EXPECT_NE(nullptr, GetUsageForKey(returned_usages, key3));
}
// Tests that the map can store both types of keys and that it does update after
// a process has gone.
TEST_F(NetworkUsageAccumulatorTest, MultipleWavesMixedData) {
BytesTransferredKey key1 = {12, 143};
BytesTransferredKey key2 = {0, 0};
int64_t correct_read_bytes1 = 0;
int64_t correct_sent_bytes1 = 0;
int read_bytes_array1[] = {453, 98754, 94650};
int sent_bytes_array1[] = {1350, 15643, 95434};
for (int i : read_bytes_array1) {
SimulateRawBytesTransferred(key1, i, 0);
correct_read_bytes1 += i;
}
for (int i : sent_bytes_array1) {
SimulateRawBytesTransferred(key1, 0, i);
correct_sent_bytes1 += i;
}
auto returned_usages = GetTotalNetworkUsages();
EXPECT_NE(nullptr, GetUsageForKey(returned_usages, key1));
// |key2| has not been used yet so it shouldn't exist in the returned usages.
EXPECT_EQ(nullptr, GetUsageForKey(returned_usages, key2));
SimulateRawBytesTransferred(key2, 0, 10);
returned_usages = GetTotalNetworkUsages();
EXPECT_NE(nullptr, GetUsageForKey(returned_usages, key2));
ClearBytesTransferredForProcess(key1.process_id);
ClearBytesTransferredForProcess(key2.process_id);
correct_sent_bytes1 = 0;
correct_read_bytes1 = 0;
SimulateRawBytesTransferred(key1, 0, 10);
correct_sent_bytes1 += 10;
returned_usages = GetTotalNetworkUsages();
EXPECT_EQ(1U, returned_usages.size());
EXPECT_EQ(correct_sent_bytes1,
GetUsageForKey(returned_usages, key1)->total_bytes_sent);
EXPECT_EQ(correct_read_bytes1,
GetUsageForKey(returned_usages, key1)->total_bytes_received);
// |key2| has been cleared.
EXPECT_EQ(nullptr, GetUsageForKey(returned_usages, key2));
ClearBytesTransferredForProcess(key1.process_id);
correct_read_bytes1 = 0;
correct_sent_bytes1 = 0;
int correct_read_bytes2 = 0;
int correct_sent_bytes2 = 0;
int read_bytes_array_second_1[] = {4153, 987154, 946501};
int sent_bytes_array_second_1[] = {13510, 115643, 954134};
int read_bytes_array2[] = {9056243, 32243, 6541250};
int sent_bytes_array2[] = {123238, 1527312, 96624};
for (int i : read_bytes_array_second_1) {
SimulateRawBytesTransferred(key1, i, 0);
correct_read_bytes1 += i;
}
for (int i : sent_bytes_array_second_1) {
SimulateRawBytesTransferred(key1, 0, i);
correct_sent_bytes1 += i;
}
for (int i : read_bytes_array2) {
SimulateRawBytesTransferred(key2, i, 0);
correct_read_bytes2 += i;
}
for (int i : sent_bytes_array2) {
SimulateRawBytesTransferred(key2, 0, i);
correct_sent_bytes2 += i;
}
returned_usages = GetTotalNetworkUsages();
EXPECT_EQ(2U, returned_usages.size());
EXPECT_EQ(correct_sent_bytes1,
GetUsageForKey(returned_usages, key1)->total_bytes_sent);
EXPECT_EQ(correct_read_bytes1,
GetUsageForKey(returned_usages, key1)->total_bytes_received);
EXPECT_EQ(correct_sent_bytes2,
GetUsageForKey(returned_usages, key2)->total_bytes_sent);
EXPECT_EQ(correct_read_bytes2,
GetUsageForKey(returned_usages, key2)->total_bytes_received);
}
} // namespace network