blob: 21d45b1e17bb247632b51fe2d947d63dda1094cd [file] [log] [blame]
// Copyright 2019 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 <utility>
#include "chrome/browser/page_load_metrics/resource_tracker.h"
#include "chrome/common/page_load_metrics/page_load_metrics.mojom.h"
#include "content/public/browser/global_request_id.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
class ResourceTrackerTest : public testing::Test {
public:
ResourceTrackerTest() = default;
void StartResourceLoad(int resource_id, bool is_complete = false) {
CreateResourceUpdate(resource_id, 0 /* delta_bytes */,
is_complete /* is_complete */);
}
void AdvanceResourceLoad(int resource_id, int bytes = 0) {
CreateResourceUpdate(resource_id, bytes /* delta_bytes */,
false /* is_complete */);
}
void CompleteResourceLoad(int resource_id) {
CreateResourceUpdate(resource_id, 0 /* delta_bytes */,
true /* is_complete */);
}
bool HasUnfinishedResource(int resource_id) {
return resource_tracker_.unfinished_resources().find(
content::GlobalRequestID(process_id_, resource_id)) !=
resource_tracker_.unfinished_resources().end();
}
int GetUnfinishedResourceBytes(int resource_id) {
return resource_tracker_.unfinished_resources()
.find(content::GlobalRequestID(process_id_, resource_id))
->second->delta_bytes;
}
bool HasPreviousUpdateForResource(int resource_id) {
return resource_tracker_.HasPreviousUpdateForResource(
content::GlobalRequestID(process_id_, resource_id));
}
int GetPreviousResourceUpdateBytes(int resource_id) {
return resource_tracker_
.GetPreviousUpdateForResource(
content::GlobalRequestID(process_id_, resource_id))
->delta_bytes;
}
private:
void CreateResourceUpdate(int request_id,
int64_t delta_bytes,
bool is_complete) {
std::vector<page_load_metrics::mojom::ResourceDataUpdatePtr> resources;
auto resource_data_update =
page_load_metrics::mojom::ResourceDataUpdate::New();
resource_data_update->request_id = request_id;
resource_data_update->delta_bytes = delta_bytes;
resource_data_update->is_complete = is_complete;
resources.push_back(std::move(resource_data_update));
resource_tracker_.UpdateResourceDataUse(process_id_, resources);
}
const int process_id_ = 0;
page_load_metrics::ResourceTracker resource_tracker_;
};
// Verifies that resources are added to and removed from the map
// of ongoing resource loads as expected.
TEST_F(ResourceTrackerTest, UnfinishedResourceMap) {
StartResourceLoad(0 /* resource_id */);
StartResourceLoad(1 /* resource_id */);
StartResourceLoad(2 /* resource_id */);
// Verify completed resources are not stored in the unfinished map.
EXPECT_TRUE(HasUnfinishedResource(0 /* resource_id */));
CompleteResourceLoad(0 /* resource_id */);
EXPECT_FALSE(HasUnfinishedResource(0 /* resource_id */));
// Verify that resources receiving multiple updates are not removed from the
// map.
AdvanceResourceLoad(1 /* resource_id */, 10 /* bytes */);
AdvanceResourceLoad(1 /* resource_id */, 20 /* bytes */);
EXPECT_TRUE(HasUnfinishedResource(1 /* resource_id */));
CompleteResourceLoad(1 /* resource_id */);
EXPECT_FALSE(HasUnfinishedResource(1 /* resource_id */));
// Verify the unfinished map stores the most recent resource update.
EXPECT_EQ(0, GetUnfinishedResourceBytes(2 /* resource_id */));
AdvanceResourceLoad(2 /* resource_id */, 10 /* bytes */);
EXPECT_EQ(10, GetUnfinishedResourceBytes(2 /* resource_id */));
AdvanceResourceLoad(2 /* resource_id */, 20 /* bytes */);
AdvanceResourceLoad(2 /* resource_id */, 30 /* bytes */);
EXPECT_EQ(30, GetUnfinishedResourceBytes(2 /* resource_id */));
}
// Verifies that resources are added to and removed from the map
// of previous resource updates as expected.
TEST_F(ResourceTrackerTest, PreviousUpdateResourceMap) {
StartResourceLoad(0 /* resource_id */);
StartResourceLoad(1 /* resource_id */);
EXPECT_FALSE(HasPreviousUpdateForResource(0 /* resource_id */));
EXPECT_FALSE(HasPreviousUpdateForResource(1 /* resource_id */));
AdvanceResourceLoad(1 /* resource_id */, 10 /* bytes */);
EXPECT_TRUE(HasPreviousUpdateForResource(1 /* resource_id */));
// Previous resource update should only be available for resources
// who received resource updates in the previous call to
// ResourceTracker::UpdateResourceDataUse(). resource_id "1" should not be
// available in this case.
AdvanceResourceLoad(0 /* resource_id */, 0 /* bytes */);
EXPECT_FALSE(HasPreviousUpdateForResource(1 /* resource_id */));
// The update should not be available because the load for resource_id "1" was
// still ongoing. This should hold the data for the last update, 10 bytes.
AdvanceResourceLoad(1 /* resource_id */, 20 /* bytes */);
EXPECT_TRUE(HasPreviousUpdateForResource(1 /* resource_id */));
EXPECT_EQ(10, GetPreviousResourceUpdateBytes(1 /* resource_id */));
// Verify previous resource update is available for newly complete resources.
CompleteResourceLoad(1 /* resource_id */);
EXPECT_TRUE(HasPreviousUpdateForResource(1 /* resource_id */));
EXPECT_EQ(20, GetPreviousResourceUpdateBytes(1 /* resource_id */));
// Verify this completed resource update is removed once other resources are
// loaded.
CompleteResourceLoad(0 /* resource_id */);
EXPECT_FALSE(HasPreviousUpdateForResource(1 /* resource_id */));
}
TEST_F(ResourceTrackerTest, SingleUpdateResourceNotStored) {
// Verify that resources who only receive one update and complete are never
// stored.
StartResourceLoad(0 /* resource_id */, true /* is_complete */);
EXPECT_FALSE(HasUnfinishedResource(0 /* resource_id */));
EXPECT_FALSE(HasPreviousUpdateForResource(0 /* resource_id */));
// Load new resource and verify we don't have a previous update for the
// resource that completed.
StartResourceLoad(1 /* resource_id */, true /* is_complete */);
EXPECT_FALSE(HasUnfinishedResource(0 /* resource_id */));
EXPECT_FALSE(HasPreviousUpdateForResource(0 /* resource_id */));
}