File: site_data_writer_unittest.cc

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (191 lines) | stat: -rw-r--r-- 8,107 bytes parent folder | download | duplicates (11)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/performance_manager/persistence/site_data/site_data_writer.h"

#include "base/memory/ptr_util.h"
#include "base/time/time.h"
#include "components/performance_manager/persistence/site_data/site_data_impl.h"
#include "components/performance_manager/public/persistence/site_data/feature_usage.h"
#include "components/performance_manager/test_support/persistence/unittest_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"

namespace performance_manager {

class SiteDataWriterTest : public ::testing::Test {
 protected:
  // The constructors needs to call 'new' directly rather than using the
  // base::MakeRefCounted helper function because the constructor of
  // SiteDataImpl is protected and not visible to
  // base::MakeRefCounted.
  SiteDataWriterTest()
      : test_impl_(base::WrapRefCounted(
            new internal::SiteDataImpl(url::Origin::Create(GURL("foo.com")),
                                       delegate_.GetWeakPtr(),
                                       &data_store_))) {
    SiteDataWriter* writer = new SiteDataWriter(test_impl_.get());
    writer_ = base::WrapUnique(writer);
  }

  SiteDataWriterTest(const SiteDataWriterTest&) = delete;
  SiteDataWriterTest& operator=(const SiteDataWriterTest&) = delete;

  ~SiteDataWriterTest() override = default;

  bool TabIsLoaded() { return test_impl_->IsLoaded(); }

  bool TabIsLoadedAndInBackground() {
    return test_impl_->loaded_tabs_in_background_count_for_testing() != 0U;
  }

  // The mock delegate used by the SiteDataImpl objects
  // created by this class, NiceMock is used to avoid having to set
  // expectations in test cases that don't care about this.
  ::testing::NiceMock<testing::MockSiteDataImplOnDestroyDelegate> delegate_;

  testing::NoopSiteDataStore data_store_;

  // The SiteDataImpl object used in these tests.
  scoped_refptr<internal::SiteDataImpl> test_impl_;

  // A SiteDataWriter object associated with the origin used
  // to create this object.
  std::unique_ptr<SiteDataWriter> writer_;
};

TEST_F(SiteDataWriterTest, TestModifiers) {
  // Make sure that we initially have no information about any of the features
  // and that the site is in an unloaded state.
  EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown,
            test_impl_->UpdatesFaviconInBackground());
  EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown,
            test_impl_->UpdatesTitleInBackground());
  EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown,
            test_impl_->UsesAudioInBackground());

  // Test the OnTabLoaded function.
  EXPECT_FALSE(TabIsLoaded());
  writer_->NotifySiteLoaded(TabVisibility::kBackground);
  EXPECT_TRUE(TabIsLoaded());

  // Test all the modifiers.

  writer_->NotifyUpdatesFaviconInBackground();
  EXPECT_EQ(SiteFeatureUsage::kSiteFeatureInUse,
            test_impl_->UpdatesFaviconInBackground());
  EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown,
            test_impl_->UpdatesTitleInBackground());
  EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown,
            test_impl_->UsesAudioInBackground());

  writer_->NotifyUpdatesTitleInBackground();
  EXPECT_EQ(SiteFeatureUsage::kSiteFeatureInUse,
            test_impl_->UpdatesFaviconInBackground());
  EXPECT_EQ(SiteFeatureUsage::kSiteFeatureInUse,
            test_impl_->UpdatesTitleInBackground());
  EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown,
            test_impl_->UsesAudioInBackground());

  writer_->NotifyUsesAudioInBackground();
  EXPECT_EQ(SiteFeatureUsage::kSiteFeatureInUse,
            test_impl_->UpdatesFaviconInBackground());
  EXPECT_EQ(SiteFeatureUsage::kSiteFeatureInUse,
            test_impl_->UpdatesTitleInBackground());
  EXPECT_EQ(SiteFeatureUsage::kSiteFeatureInUse,
            test_impl_->UsesAudioInBackground());

  writer_->NotifyLoadTimePerformanceMeasurement(base::Microseconds(202),
                                                base::Microseconds(101), 1005);
  EXPECT_EQ(1u, test_impl_->load_duration().num_datums());
  EXPECT_EQ(202.0, test_impl_->load_duration().value());
  EXPECT_EQ(1u, test_impl_->cpu_usage_estimate().num_datums());
  EXPECT_EQ(101.0, test_impl_->cpu_usage_estimate().value());

  EXPECT_EQ(1u, test_impl_->private_footprint_kb_estimate().num_datums());
  EXPECT_EQ(1005.0, test_impl_->private_footprint_kb_estimate().value());

  writer_->NotifySiteUnloaded(TabVisibility::kBackground);
}

TEST_F(SiteDataWriterTest, LoadAndBackgroundStateTransitions) {
  // There's 4 different states a tab can be in:
  //   - Unloaded + Background
  //   - Unloaded + Foreground (might not be possible in practice but this
  //     will depend on the order of the events when an unloaded background tab
  //     gets foregrounded, so it's safer to consider this state).
  //   - Loaded + Background
  //   - Loaded + Foreground
  //
  // Only one of these parameter can change at a time, so you have the following
  // possible transitions:
  //
  //   +-------------+           +-------------+
  //   |Unloaded + Bg|<--------->|Unloaded + Fg|
  //   +-------------+ 1       2 +-------------+
  //         /|\ 3                     /|\ 5
  //          |                         |
  //         \|/ 4                     \|/ 6
  //   +-------------+           +-------------+
  //   | Loaded + Bg |<--------->| Loaded + Fg |
  //   +-------------+ 7       8 +-------------+
  //
  //   - 1,2: There's nothing to do, the tab is already unloaded so |impl_|
  //       shouldn't count it as a background tab anyway.
  //   - 3: The tab gets unloaded while in background, |impl_| should be
  //       notified so it can *decrement* the counter of loaded AND backgrounded
  //       tabs.
  //   - 4: The tab gets loaded while in background, |impl_| should be notified
  //       so it can *increment* the counter of loaded AND backgrounded tabs.
  //   - 5: The tab gets unloaded while in foreground, this should theorically
  //       not happen, but if it does then |impl_| should just be notified about
  //       the unload event so it can update its last loaded timestamp.
  //   - 6: The tab gets loaded while in foreground, |impl_| should only be
  //       notified about the load event, the background state hasn't changed.
  //   - 7: A loaded foreground tab gets backgrounded, |impl_| should be
  //       notified that the tab has been background so it can *increment* the
  //       counter of loaded AND backgrounded tabs.
  //   - 8: A loaded background tab gets foregrounded, |impl_| should be
  //       notified that the tab has been background so it can *decrement* the
  //       counter of loaded AND backgrounded tabs.
  EXPECT_FALSE(TabIsLoaded());

  // Transition #4: Unloaded + Bg -> Loaded + Bg.
  writer_->NotifySiteLoaded(TabVisibility::kBackground);
  EXPECT_TRUE(TabIsLoadedAndInBackground());

  // Transition #8: Loaded + Bg -> Loaded + Fg.
  writer_->NotifySiteForegrounded(true);
  EXPECT_TRUE(TabIsLoaded());
  EXPECT_FALSE(TabIsLoadedAndInBackground());

  // Transition #5: Loaded + Fg -> Unloaded + Fg.
  writer_->NotifySiteUnloaded(TabVisibility::kForeground);
  EXPECT_FALSE(TabIsLoaded());

  // Transition #1: Unloaded + Fg -> Unloaded + Bg.
  writer_->NotifySiteBackgrounded(false);
  EXPECT_FALSE(TabIsLoaded());

  // Transition #2: Unloaded + Bg -> Unloaded + Fg.
  writer_->NotifySiteForegrounded(false);
  EXPECT_FALSE(TabIsLoaded());

  // Transition #6: Unloaded + Fg -> Loaded + Fg.
  writer_->NotifySiteLoaded(TabVisibility::kForeground);
  EXPECT_TRUE(TabIsLoaded());
  EXPECT_FALSE(TabIsLoadedAndInBackground());

  // Transition #7: Loaded + Fg -> Loaded + Bg.
  writer_->NotifySiteBackgrounded(true);
  EXPECT_TRUE(TabIsLoaded());
  EXPECT_TRUE(TabIsLoadedAndInBackground());

  // Transition #3: Loaded + Bg -> Unloaded + Bg.
  writer_->NotifySiteUnloaded(TabVisibility::kBackground);
  EXPECT_FALSE(TabIsLoaded());
  EXPECT_FALSE(TabIsLoadedAndInBackground());
}

}  // namespace performance_manager