From e4a672a97b24768d0f17164425f7a654c66eeb34 Mon Sep 17 00:00:00 2001 From: ankur22 Date: Fri, 10 Nov 2023 14:51:51 +0000 Subject: [PATCH 1/6] Add NetworkProfiles --- browser/module.go | 8 +++++--- browser/module_test.go | 1 + common/network_profile.go | 7 +++++++ 3 files changed, 13 insertions(+), 3 deletions(-) create mode 100644 common/network_profile.go diff --git a/browser/module.go b/browser/module.go index efc312a34..a736ac51c 100644 --- a/browser/module.go +++ b/browser/module.go @@ -27,8 +27,9 @@ type ( // JSModule exposes the properties available to the JS script. JSModule struct { - Browser *goja.Object - Devices map[string]common.Device + Browser *goja.Object + Devices map[string]common.Device + NetworkProfiles map[string]common.NetworkProfile `js:"networkProfiles"` } // ModuleInstance represents an instance of the JS module. @@ -69,7 +70,8 @@ func (m *RootModule) NewModuleInstance(vu k6modules.VU) k6modules.Instance { browserRegistry: newBrowserRegistry(vu, m.remoteRegistry, m.PidRegistry), taskQueueRegistry: newTaskQueueRegistry(vu), }), - Devices: common.GetDevices(), + Devices: common.GetDevices(), + NetworkProfiles: common.GetNetworkProfiles(), }, } } diff --git a/browser/module_test.go b/browser/module_test.go index 5724b149d..0a8f53a07 100644 --- a/browser/module_test.go +++ b/browser/module_test.go @@ -20,4 +20,5 @@ func TestModuleNew(t *testing.T) { require.NotNil(t, m.mod, "Module should be set") require.NotNil(t, m.mod.Browser, "Browser should be set") require.NotNil(t, m.mod.Devices, "Devices should be set") + require.NotNil(t, m.mod.NetworkProfiles, "Profiles should be set") } diff --git a/common/network_profile.go b/common/network_profile.go new file mode 100644 index 000000000..d21fa7e3d --- /dev/null +++ b/common/network_profile.go @@ -0,0 +1,7 @@ +package common + +// GetNetworkProfiles returns NetworkProfiles which are ready to be used to +// throttle the network with page.throttleNetwork. +func GetNetworkProfiles() map[string]NetworkProfile { + return map[string]NetworkProfile{} +} From 111a5d1f5da2111fb80066f61c3783618904eb81 Mon Sep 17 00:00:00 2001 From: ankur22 Date: Fri, 10 Nov 2023 17:01:54 +0000 Subject: [PATCH 2/6] Move NetworkProfile type to new file This type now feels like it should live closer to where the predefined network profiles have been defined. --- common/network_manager.go | 21 --------------------- common/network_profile.go | 21 +++++++++++++++++++++ 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/common/network_manager.go b/common/network_manager.go index f4fccefed..6327d11a0 100644 --- a/common/network_manager.go +++ b/common/network_manager.go @@ -28,27 +28,6 @@ import ( "github.com/dop251/goja" ) -// NetworkProfile is used in ThrottleNetwork. -type NetworkProfile struct { - // Minimum latency from request sent to response headers received (ms). - Latency float64 - - // Maximal aggregated download throughput (bytes/sec). -1 disables download throttling. - Download float64 - - // Maximal aggregated upload throughput (bytes/sec). -1 disables upload throttling. - Upload float64 -} - -// NewNetworkProfile creates a non-throttled network profile. -func NewNetworkProfile() NetworkProfile { - return NetworkProfile{ - Latency: 0, - Download: -1, - Upload: -1, - } -} - // Credentials holds HTTP authentication credentials. type Credentials struct { Username string `js:"username"` diff --git a/common/network_profile.go b/common/network_profile.go index d21fa7e3d..ec106e26d 100644 --- a/common/network_profile.go +++ b/common/network_profile.go @@ -1,5 +1,26 @@ package common +// NetworkProfile is used in ThrottleNetwork. +type NetworkProfile struct { + // Minimum latency from request sent to response headers received (ms). + Latency float64 + + // Maximal aggregated download throughput (bytes/sec). -1 disables download throttling. + Download float64 + + // Maximal aggregated upload throughput (bytes/sec). -1 disables upload throttling. + Upload float64 +} + +// NewNetworkProfile creates a non-throttled network profile. +func NewNetworkProfile() NetworkProfile { + return NetworkProfile{ + Latency: 0, + Download: -1, + Upload: -1, + } +} + // GetNetworkProfiles returns NetworkProfiles which are ready to be used to // throttle the network with page.throttleNetwork. func GetNetworkProfiles() map[string]NetworkProfile { From 021842cfcaae34c2700887ba2a1ec192babfc109 Mon Sep 17 00:00:00 2001 From: ankur22 Date: Fri, 10 Nov 2023 17:02:52 +0000 Subject: [PATCH 3/6] Add slow 3g and fast 3g network profiles These are common network profiles which are used in various chromium based browsers. It feels like it's a safe bet that these will be the most widely used network profiles. We intend to add more once we have a clearer idea of what. --- common/network_profile.go | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/common/network_profile.go b/common/network_profile.go index ec106e26d..5b93db66a 100644 --- a/common/network_profile.go +++ b/common/network_profile.go @@ -24,5 +24,16 @@ func NewNetworkProfile() NetworkProfile { // GetNetworkProfiles returns NetworkProfiles which are ready to be used to // throttle the network with page.throttleNetwork. func GetNetworkProfiles() map[string]NetworkProfile { - return map[string]NetworkProfile{} + return map[string]NetworkProfile{ + "Slow 3G": { + DownloadThroughput: ((500 * 1000) / 8) * 0.8, + UploadThroughput: ((500 * 1000) / 8) * 0.8, + Latency: 400 * 5, + }, + "Fast 3G": { + DownloadThroughput: ((1.6 * 1000 * 1000) / 8) * 0.9, + UploadThroughput: ((750 * 1000) / 8) * 0.9, + Latency: 150 * 3.75, + }, + } } From f2cd9dd50ec30f1fac465448daadeecbd37a1419 Mon Sep 17 00:00:00 2001 From: ankur22 Date: Fri, 10 Nov 2023 17:07:41 +0000 Subject: [PATCH 4/6] Refactor throttle.js to use slow 3g Instead of defining a custom network profile, use the predefined one (slow 3g). This serves as a good example as to how to work with predefined network profiles. --- common/network_profile.go | 12 ++++++------ examples/throttle.js | 10 +++------- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/common/network_profile.go b/common/network_profile.go index 5b93db66a..d7cc56368 100644 --- a/common/network_profile.go +++ b/common/network_profile.go @@ -26,14 +26,14 @@ func NewNetworkProfile() NetworkProfile { func GetNetworkProfiles() map[string]NetworkProfile { return map[string]NetworkProfile{ "Slow 3G": { - DownloadThroughput: ((500 * 1000) / 8) * 0.8, - UploadThroughput: ((500 * 1000) / 8) * 0.8, - Latency: 400 * 5, + Download: ((500 * 1000) / 8) * 0.8, + Upload: ((500 * 1000) / 8) * 0.8, + Latency: 400 * 5, }, "Fast 3G": { - DownloadThroughput: ((1.6 * 1000 * 1000) / 8) * 0.9, - UploadThroughput: ((750 * 1000) / 8) * 0.9, - Latency: 150 * 3.75, + Download: ((1.6 * 1000 * 1000) / 8) * 0.9, + Upload: ((750 * 1000) / 8) * 0.9, + Latency: 150 * 3.75, }, } } diff --git a/examples/throttle.js b/examples/throttle.js index 79b9a91ad..295589718 100644 --- a/examples/throttle.js +++ b/examples/throttle.js @@ -1,4 +1,4 @@ -import { browser } from 'k6/x/browser'; +import { browser, networkProfiles } from 'k6/x/browser'; export const options = { scenarios: { @@ -32,7 +32,7 @@ export const options = { }, thresholds: { 'browser_http_req_duration{scenario:normal}': ['p(99)<500'], - 'browser_http_req_duration{scenario:networkThrottled}': ['p(99)<1500'], + 'browser_http_req_duration{scenario:networkThrottled}': ['p(99)<3000'], 'iteration_duration{scenario:normal}': ['p(99)<4000'], 'iteration_duration{scenario:cpuThrottled}': ['p(99)<10000'], }, @@ -54,11 +54,7 @@ export async function networkThrottled() { const page = context.newPage(); try { - page.throttleNetwork({ - latency: 750, - download: 250, - upload: 250, - }); + page.throttleNetwork(networkProfiles['Slow 3G']); await page.goto('https://test.k6.io/', { waitUntil: 'networkidle' }); } finally { From 15f06c98219fad423c02034031e5e6cad028d72f Mon Sep 17 00:00:00 2001 From: ankur22 Date: Mon, 13 Nov 2023 17:42:21 +0000 Subject: [PATCH 5/6] Add no throttling network profile This will be useful when a user may want to disable the network throttling half way through a test. --- common/network_profile.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/common/network_profile.go b/common/network_profile.go index d7cc56368..c801f7d8f 100644 --- a/common/network_profile.go +++ b/common/network_profile.go @@ -25,6 +25,11 @@ func NewNetworkProfile() NetworkProfile { // throttle the network with page.throttleNetwork. func GetNetworkProfiles() map[string]NetworkProfile { return map[string]NetworkProfile{ + "No Throttling": { + Download: -1, + Upload: -1, + Latency: 0, + }, "Slow 3G": { Download: ((500 * 1000) / 8) * 0.8, Upload: ((500 * 1000) / 8) * 0.8, From 884e4b908e35f07fe63d33538e06f35c5d53641a Mon Sep 17 00:00:00 2001 From: ankur22 Date: Tue, 14 Nov 2023 13:24:08 +0000 Subject: [PATCH 6/6] Add comments on predefined profile numbers This was copied from https://stackoverflow.com/questions/48367042/in-chrome-dev-tools-what-is-the-speed-of-each-preset-option-for-network-throttl which outlined what the numbers mean when calculating the download and upload throughputs. We can use this to helps us create our own profiles when we need. --- common/network_profile.go | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/common/network_profile.go b/common/network_profile.go index c801f7d8f..d6a2dc275 100644 --- a/common/network_profile.go +++ b/common/network_profile.go @@ -31,14 +31,18 @@ func GetNetworkProfiles() map[string]NetworkProfile { Latency: 0, }, "Slow 3G": { + // (500 (Kb/s) * 1000 (to bits/s)) / 8 (to bytes/s)) * 0.8 (20% bandwidth loss) Download: ((500 * 1000) / 8) * 0.8, - Upload: ((500 * 1000) / 8) * 0.8, - Latency: 400 * 5, + // (500 (Kb/s) * 1000 (to bits/s)) / 8 (to bytes/s)) * 0.8 (20% bandwidth loss) + Upload: ((500 * 1000) / 8) * 0.8, + Latency: 400 * 5, }, "Fast 3G": { + // ((1.6 (Mb/s) * 1000 (to Kb/s) * 1000 (to bits/s)) / 8 (to bytes/s)) * 0.9 (10% bandwidth loss) Download: ((1.6 * 1000 * 1000) / 8) * 0.9, - Upload: ((750 * 1000) / 8) * 0.9, - Latency: 150 * 3.75, + // (750 (Kb/s) * 1000 (to bits/s)) / 8 (to bytes/s)) * 0.9 (10% bandwidth loss) + Upload: ((750 * 1000) / 8) * 0.9, + Latency: 150 * 3.75, }, } }