File: network_quality_netinfo_browsertest.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 (160 lines) | stat: -rw-r--r-- 6,823 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
// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <string>

#include "base/command_line.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_base.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "net/nqe/effective_connection_type.h"
#include "services/network/test/test_network_quality_tracker.h"

namespace {

void VerifyDownlinkKbps(double expected_kbps, double got_kbps) {
  // First verify that |got_kbps| is a multiple of 50.
  int quotient = static_cast<int>(got_kbps / 50);
  // |mod| is the remainder left after dividing |got_kbps| by 50 while
  // restricting the quotient to integer.  For example, if |got_kbps| is
  // 1050, then mod will be 0. If |got_kbps| is 1030, mod will be 30.
  double mod = got_kbps - 50 * quotient;
  EXPECT_LE(0.0, mod);
  EXPECT_GT(50.0, mod);
  // It is possible that |mod| is not exactly 0 because of floating point
  // computations. e.g., |got_kbps| may be 99.999999, in which case |mod|
  // will be 49.999999.
  EXPECT_TRUE(mod < (1e-5) || (50 - mod) < 1e-5) << " got_kbps=" << got_kbps;

  if (expected_kbps > 10000)
    expected_kbps = 10000;

  // The difference between the actual and the estimate value should be within
  // 10%. Add 50 (bucket size used in Blink) to account for the cases when the
  // sample may spill over to the next bucket due to the added noise of 10%.
  // For example, if sample is 300 kbps, after adding noise, it may become 330,
  // and after rounding off, it would spill over to the next bucket of 350 kbps.
  EXPECT_GE((expected_kbps * 0.1) + 50, std::abs(expected_kbps - got_kbps))
      << " expected_kbps=" << expected_kbps << " got_kbps=" << got_kbps;
}

}  // namespace

class NetInfoBrowserTest : public InProcessBrowserTest {
 public:
  network::NetworkQualityTracker* GetNetworkQualityTracker() const {
    return g_browser_process->network_quality_tracker();
  }

 protected:
  void SetUpOnMainThread() override {}

  // Runs |script| repeatedly until the |script| returns |expected_value|.
  void RunScriptUntilExpectedStringValueMet(const std::string& script,
                                            const std::string& expected_value) {
    while (true) {
      if (RunScriptExtractString(script) == expected_value)
        return;
      base::RunLoop().RunUntilIdle();
    }
  }

  // Repeatedly runs NetInfo JavaScript API to get RTT until it returns
  // |expected_rtt|.
  void RunGetRttUntilExpectedValueReached(base::TimeDelta expected_rtt) {
    if (expected_rtt > base::Milliseconds(3000))
      expected_rtt = base::Milliseconds(3000);

    while (true) {
      int32_t got_rtt_milliseconds = RunScriptExtractInt("getRtt()");
      EXPECT_EQ(0, got_rtt_milliseconds % 50)
          << " got_rtt_milliseconds=" << got_rtt_milliseconds;

      // The difference between the actual and the estimate value should be
      // within 10%. Add 50 (bucket size used in Blink) to account for the cases
      // when the sample may spill over to the next bucket due to the added
      // noise of 10%. For example, if sample is 300 msec, after adding noise,
      // it may become 330, and after rounding off, it would spill over to the
      // next bucket of 350 msec.
      if (expected_rtt.InMilliseconds() * 0.1 + 50 >=
          std::abs(expected_rtt.InMilliseconds() - got_rtt_milliseconds)) {
        return;
      }
    }
  }

  std::string RunScriptExtractString(const std::string& script) {
    return content::EvalJs(browser()->tab_strip_model()->GetActiveWebContents(),
                           script)
        .ExtractString();
  }

  double RunScriptExtractDouble(const std::string& script) {
    return content::EvalJs(browser()->tab_strip_model()->GetActiveWebContents(),
                           script)
        .ExtractDouble();
  }

  int RunScriptExtractInt(const std::string& script) {
    return content::EvalJs(browser()->tab_strip_model()->GetActiveWebContents(),
                           script)
        .ExtractInt();
  }
};

// Make sure the changes in the effective connection type are notified to the
// render thread.
IN_PROC_BROWSER_TEST_F(NetInfoBrowserTest,
                       EffectiveConnectionTypeChangeNotfied) {
  embedded_test_server()->ServeFilesFromSourceDirectory("content/test/data");
  EXPECT_TRUE(embedded_test_server()->Start());
  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browser(), embedded_test_server()->GetURL("/net_info.html")));

  // Change effective connection type so that the renderer process is notified.
  // Changing the effective connection type from 2G to 3G is guaranteed to
  // generate the notification to the renderers, irrespective of the current
  // effective connection type.
  GetNetworkQualityTracker()->ReportEffectiveConnectionTypeForTesting(
      net::EFFECTIVE_CONNECTION_TYPE_2G);
  RunScriptUntilExpectedStringValueMet("getEffectiveType()", "2g");
  GetNetworkQualityTracker()->ReportEffectiveConnectionTypeForTesting(
      net::EFFECTIVE_CONNECTION_TYPE_3G);
  RunScriptUntilExpectedStringValueMet("getEffectiveType()", "3g");
}

// Make sure the changes in the network quality are notified to the render
// thread, and the changed network quality is accessible via Javascript API.
IN_PROC_BROWSER_TEST_F(NetInfoBrowserTest, NetworkQualityChangeNotified) {
  GetNetworkQualityTracker()->ReportRTTsAndThroughputForTesting(
      base::Seconds(1), 300);

  embedded_test_server()->ServeFilesFromSourceDirectory("content/test/data");
  EXPECT_TRUE(embedded_test_server()->Start());
  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browser(), embedded_test_server()->GetURL("/net_info.html")));

  RunGetRttUntilExpectedValueReached(base::Seconds(1));
  // If the updated RTT is available via JavaScript, then downlink must have
  // been updated too.
  VerifyDownlinkKbps(300, RunScriptExtractDouble("getDownlink()") * 1000);

  // Verify that the network quality change is accessible via Javascript API.
  GetNetworkQualityTracker()->ReportRTTsAndThroughputForTesting(
      base::Seconds(10), 3000);
  RunGetRttUntilExpectedValueReached(base::Seconds(10));
  VerifyDownlinkKbps(3000, RunScriptExtractDouble("getDownlink()") * 1000);
}