From 5492fa53ad5eca579c12725bc91a55ae76f94249 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Hanzl=C3=ADk?= Date: Wed, 16 Oct 2024 18:53:59 +0200 Subject: [PATCH] add sessionsPerNode and setSessionsFromHub parameters to selenium-grid scaler (#6055) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add sessionsPerNode and setSessionsFromHub parameters to selenium-grid scaler, add tests and changelog Signed-off-by: Hanzlik, Robert (MONETA) * fix tests Signed-off-by: Hanzlik, Robert (MONETA) * fix json Signed-off-by: Hanzlik, Robert (MONETA) * fix json Signed-off-by: Hanzlik, Robert (MONETA) * fix tests Signed-off-by: Hanzlik, Robert (MONETA) * fix metadata tests Signed-off-by: Hanzlik, Robert (MONETA) * fix syntax Signed-off-by: Hanzlik, Robert (MONETA) * link Issue to Changelog Signed-off-by: Hanzlik, Robert (MONETA) * fix link to issue Signed-off-by: Hanzlik, Robert (MONETA) * add sessionBrowserVersion and tests Signed-off-by: Hanzlik, Robert (MONETA) * add metadata tests Signed-off-by: Hanzlik, Robert (MONETA) * Update CHANGELOG.md Co-authored-by: Jorge Turrado Ferrero Signed-off-by: Robert Hanzlík Signed-off-by: Hanzlik, Robert (MONETA) * make cyclomatic complexity smaller Signed-off-by: Hanzlik, Robert (MONETA) --------- Signed-off-by: Hanzlik, Robert (MONETA) Signed-off-by: Robert Hanzlík Signed-off-by: Jorge Turrado Ferrero Co-authored-by: Jorge Turrado Ferrero --- CHANGELOG.md | 1 + pkg/scalers/selenium_grid_scaler.go | 83 ++++++- pkg/scalers/selenium_grid_scaler_test.go | 302 ++++++++++++++++++----- 3 files changed, 319 insertions(+), 67 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index deab8a04db4..bea05c1a683 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -77,6 +77,7 @@ Here is an overview of all new **experimental** features: - **Kafka**: Fix logic to scale to zero on invalid offset even with earliest offsetResetPolicy ([#5689](https://github.com/kedacore/keda/issues/5689)) - **RabbitMQ Scaler**: Add connection name for AMQP ([#5958](https://github.com/kedacore/keda/issues/5958)) - **Selenium Scaler**: Add Support for Username and Password Authentication ([#6144](https://github.com/kedacore/keda/issues/6144)) +- **Selenium Scaler**: Introduce new parameters setSessionsFromHub, sessionsPerNode and sessionBrowserVersion. ([#6080](https://github.com/kedacore/keda/issues/6080)) - TODO ([#XXX](https://github.com/kedacore/keda/issues/XXX)) ### Fixes diff --git a/pkg/scalers/selenium_grid_scaler.go b/pkg/scalers/selenium_grid_scaler.go index 09f0adfd319..3cba72fbc9e 100644 --- a/pkg/scalers/selenium_grid_scaler.go +++ b/pkg/scalers/selenium_grid_scaler.go @@ -29,13 +29,16 @@ type seleniumGridScaler struct { type seleniumGridScalerMetadata struct { triggerIndex int - URL string `keda:"name=url, order=triggerMetadata;authParams"` - BrowserName string `keda:"name=browserName, order=triggerMetadata"` - SessionBrowserName string `keda:"name=sessionBrowserName, order=triggerMetadata, optional"` - ActivationThreshold int64 `keda:"name=activationThreshold, order=triggerMetadata, optional"` - BrowserVersion string `keda:"name=browserVersion, order=triggerMetadata, optional, default=latest"` - UnsafeSsl bool `keda:"name=unsafeSsl, order=triggerMetadata, optional, default=false"` - PlatformName string `keda:"name=platformName, order=triggerMetadata, optional, default=linux"` + URL string `keda:"name=url, order=triggerMetadata;authParams"` + BrowserName string `keda:"name=browserName, order=triggerMetadata"` + SessionBrowserName string `keda:"name=sessionBrowserName, order=triggerMetadata, optional"` + ActivationThreshold int64 `keda:"name=activationThreshold, order=triggerMetadata, optional"` + BrowserVersion string `keda:"name=browserVersion, order=triggerMetadata, optional, default=latest"` + UnsafeSsl bool `keda:"name=unsafeSsl, order=triggerMetadata, optional, default=false"` + PlatformName string `keda:"name=platformName, order=triggerMetadata, optional, default=linux"` + SessionsPerNode int64 `keda:"name=sessionsPerNode, order=triggerMetadata, optional, default=1"` + SetSessionsFromHub bool `keda:"name=setSessionsFromHub, order=triggerMetadata, optional, default=false"` + SessionBrowserVersion string `keda:"name=sessionBrowserVersion, order=triggerMetadata, optional"` // auth Username string `keda:"name=username, order=authParams;resolvedEnv;triggerMetadata, optional"` @@ -50,6 +53,7 @@ type seleniumResponse struct { type data struct { Grid grid `json:"grid"` + NodesInfo nodesInfo `json:"nodesInfo"` SessionsInfo sessionsInfo `json:"sessionsInfo"` } @@ -75,6 +79,19 @@ type capability struct { PlatformName string `json:"platformName"` } +type nodesInfo struct { + Nodes []nodes `json:"nodes"` +} + +type nodes struct { + Stereotypes string `json:"stereotypes"` +} + +type stereotype struct { + Slots int64 `json:"slots"` + Stereotype capability `json:"stereotype"` +} + const ( DefaultBrowserVersion string = "latest" DefaultPlatformName string = "linux" @@ -118,6 +135,9 @@ func parseSeleniumGridScalerMetadata(config *scalersconfig.ScalerConfig) (*selen if meta.SessionBrowserName == "" { meta.SessionBrowserName = meta.BrowserName } + if meta.SessionBrowserVersion == "" { + meta.SessionBrowserVersion = meta.BrowserVersion + } return meta, nil } @@ -156,7 +176,7 @@ func (s *seleniumGridScaler) GetMetricSpecForScaling(context.Context) []v2.Metri func (s *seleniumGridScaler) getSessionsCount(ctx context.Context, logger logr.Logger) (int64, error) { body, err := json.Marshal(map[string]string{ - "query": "{ grid { maxSession, nodeCount }, sessionsInfo { sessionQueueRequests, sessions { id, capabilities, nodeId } } }", + "query": "{ grid { maxSession, nodeCount }, nodesInfo { nodes { stereotypes } }, sessionsInfo { sessionQueueRequests, sessions { id, capabilities, nodeId } } }", }) if err != nil { @@ -186,21 +206,26 @@ func (s *seleniumGridScaler) getSessionsCount(ctx context.Context, logger logr.L if err != nil { return -1, err } - v, err := getCountFromSeleniumResponse(b, s.metadata.BrowserName, s.metadata.BrowserVersion, s.metadata.SessionBrowserName, s.metadata.PlatformName, logger) + v, err := getCountFromSeleniumResponse(b, s.metadata.BrowserName, s.metadata.BrowserVersion, s.metadata.SessionBrowserName, s.metadata.PlatformName, s.metadata.SessionsPerNode, s.metadata.SetSessionsFromHub, s.metadata.SessionBrowserVersion, logger) if err != nil { return -1, err } return v, nil } -func getCountFromSeleniumResponse(b []byte, browserName string, browserVersion string, sessionBrowserName string, platformName string, logger logr.Logger) (int64, error) { +func getCountFromSeleniumResponse(b []byte, browserName string, browserVersion string, sessionBrowserName string, platformName string, sessionsPerNode int64, setSessionsFromHub bool, sessionBrowserVersion string, logger logr.Logger) (int64, error) { var count int64 + var slots int64 var seleniumResponse = seleniumResponse{} if err := json.Unmarshal(b, &seleniumResponse); err != nil { return 0, err } + if setSessionsFromHub { + slots = getSlotsFromSeleniumResponse(seleniumResponse, browserName, browserVersion, platformName, logger) + } + var sessionQueueRequests = seleniumResponse.Data.SessionsInfo.SessionQueueRequests for _, sessionQueueRequest := range sessionQueueRequests { var capability = capability{} @@ -224,7 +249,7 @@ func getCountFromSeleniumResponse(b []byte, browserName string, browserVersion s if err := json.Unmarshal([]byte(session.Capabilities), &capability); err == nil { var platformNameMatches = capability.PlatformName == "" || strings.EqualFold(capability.PlatformName, platformName) if capability.BrowserName == sessionBrowserName { - if strings.HasPrefix(capability.BrowserVersion, browserVersion) && platformNameMatches { + if strings.HasPrefix(capability.BrowserVersion, sessionBrowserVersion) && platformNameMatches { count++ } else if browserVersion == DefaultBrowserVersion && platformNameMatches { count++ @@ -238,10 +263,44 @@ func getCountFromSeleniumResponse(b []byte, browserName string, browserVersion s var gridMaxSession = int64(seleniumResponse.Data.Grid.MaxSession) var gridNodeCount = int64(seleniumResponse.Data.Grid.NodeCount) - if gridMaxSession > 0 && gridNodeCount > 0 { + if setSessionsFromHub { + if slots == 0 { + slots = sessionsPerNode + } + var floatCount = float64(count) / float64(slots) + count = int64(math.Ceil(floatCount)) + } else if gridMaxSession > 0 && gridNodeCount > 0 { // Get count, convert count to next highest int64 var floatCount = float64(count) / (float64(gridMaxSession) / float64(gridNodeCount)) count = int64(math.Ceil(floatCount)) } + return count, nil } + +func getSlotsFromSeleniumResponse(seleniumResponse seleniumResponse, browserName string, browserVersion string, platformName string, logger logr.Logger) int64 { + var slots int64 + + var nodes = seleniumResponse.Data.NodesInfo.Nodes +slots: + for _, node := range nodes { + var stereotypes = []stereotype{} + if err := json.Unmarshal([]byte(node.Stereotypes), &stereotypes); err == nil { + for _, stereotype := range stereotypes { + if stereotype.Stereotype.BrowserName == browserName { + var platformNameMatches = stereotype.Stereotype.PlatformName == "" || strings.EqualFold(stereotype.Stereotype.PlatformName, platformName) + if strings.HasPrefix(stereotype.Stereotype.BrowserVersion, browserVersion) && platformNameMatches { + slots = stereotype.Slots + break slots + } else if len(strings.TrimSpace(stereotype.Stereotype.BrowserVersion)) == 0 && browserVersion == DefaultBrowserVersion && platformNameMatches { + slots = stereotype.Slots + break slots + } + } + } + } else { + logger.Error(err, fmt.Sprintf("Error when unmarshalling stereotypes: %s", err)) + } + } + return slots +} diff --git a/pkg/scalers/selenium_grid_scaler_test.go b/pkg/scalers/selenium_grid_scaler_test.go index 557861b357e..85321118c6f 100644 --- a/pkg/scalers/selenium_grid_scaler_test.go +++ b/pkg/scalers/selenium_grid_scaler_test.go @@ -11,11 +11,14 @@ import ( func Test_getCountFromSeleniumResponse(t *testing.T) { type args struct { - b []byte - browserName string - sessionBrowserName string - browserVersion string - platformName string + b []byte + browserName string + sessionBrowserName string + browserVersion string + platformName string + sessionsPerNode int64 + setSessionsFromHub bool + sessionBrowserVersion string } tests := []struct { name string @@ -50,6 +53,9 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { "maxSession": 0, "nodeCount": 0 }, + "nodesInfo": { + "nodes": [] + }, "sessionsInfo": { "sessionQueueRequests": [], "sessions": [] @@ -70,6 +76,9 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { "maxSession": 1, "nodeCount": 1 }, + "nodesInfo": { + "nodes": [] + }, "sessionsInfo": { "sessionQueueRequests": ["{\n \"browserName\": \"chrome\"\n}","{\n \"browserName\": \"chrome\"\n}"], "sessions": [ @@ -99,6 +108,9 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { "maxSession": 1, "nodeCount": 1 }, + "nodesInfo": { + "nodes": [] + }, "sessionsInfo": { "sessionQueueRequests": ["{\n \"browserName\": \"chrome\"\n}","{\n \"browserName\": \"chrome\"\n}"], "sessions": [] @@ -122,6 +134,9 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { "maxSession": 4, "nodeCount": 2 }, + "nodesInfo": { + "nodes": [] + }, "sessionsInfo": { "sessionQueueRequests": ["{\n \"browserName\": \"chrome\",\n \"browserVersion\": \"91.0\"\n}","{\n \"browserName\": \"chrome\"\n}","{\n \"browserName\": \"chrome\"\n}"] } @@ -144,6 +159,9 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { "maxSession": 4, "nodeCount": 1 }, + "nodesInfo": { + "nodes": [] + }, "sessionsInfo": { "sessionQueueRequests": ["{\n \"browserName\": \"chrome\",\n \"browserVersion\": \"91.0\"\n}","{\n \"browserName\": \"chrome\"\n}","{\n \"browserName\": \"chrome\"\n}"], "sessions": [ @@ -178,6 +196,9 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { "maxSession": 3, "nodeCount": 1 }, + "nodesInfo": { + "nodes": [] + }, "sessionsInfo": { "sessionQueueRequests": ["{\n \"browserName\": \"chrome\",\n \"browserVersion\": \"91.0\"\n}","{\n \"browserName\": \"chrome\"\n}"], "sessions": [ @@ -212,6 +233,9 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { "maxSession": 2, "nodeCount": 2 }, + "nodesInfo": { + "nodes": [] + }, "sessionsInfo": { "sessionQueueRequests": ["{\n \"browserName\": \"chrome\",\n \"browserVersion\": \"91.0\"\n}","{\n \"browserName\": \"chrome\",\n \"browserVersion\": \"91.0\"\n}","{\n \"browserName\": \"chrome\",\n \"browserVersion\": \"91.0\"\n}"], "sessions": [ @@ -246,6 +270,9 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { "maxSession": 2, "nodeCount": 2 }, + "nodesInfo": { + "nodes": [] + }, "sessionsInfo": { "sessionQueueRequests": ["{\n \"browserName\": \"chrome\",\n \"browserVersion\": \"91.0\"\n}","{\n \"browserName\": \"chrome\",\n \"browserVersion\": \"91.0\"\n}","{\n \"browserName\": \"chrome\",\n \"browserVersion\": \"91.0\"\n}"], "sessions": [ @@ -280,6 +307,9 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { "maxSession": 2, "nodeCount": 2 }, + "nodesInfo": { + "nodes": [] + }, "sessionsInfo": { "sessionQueueRequests": ["{\n \"browserName\": \"chrome\"}","{\n \"browserName\": \"chrome\"}","{\n \"browserName\": \"chrome\"}"], "sessions": [ @@ -314,6 +344,9 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { "maxSession": 1, "nodeCount": 1 }, + "nodesInfo": { + "nodes": [] + }, "sessionsInfo": { "sessionQueueRequests": ["{\n \"browserName\": \"chrome\",\n \"browserVersion\": \"91.0\"\n}","{\n \"browserName\": \"chrome\"\n}"], "sessions": [ @@ -343,6 +376,9 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { "maxSession": 1, "nodeCount": 1 }, + "nodesInfo": { + "nodes": [] + }, "sessionsInfo": { "sessionQueueRequests": ["{\n \"browserName\": \"MicrosoftEdge\",\n \"browserVersion\": \"91.0\"\n}","{\n \"browserName\": \"MicrosoftEdge\",\n \"browserVersion\": \"91.0\"\n}"], "sessions": [ @@ -372,6 +408,9 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { "maxSession": 1, "nodeCount": 1 }, + "nodesInfo": { + "nodes": [] + }, "sessionsInfo": { "sessionQueueRequests": ["{\n \"browserName\": \"chrome\"\n}","{\n \"browserName\": \"chrome\"\n}"], "sessions": [ @@ -401,6 +440,9 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { "maxSession": 3, "nodeCount": 1 }, + "nodesInfo": { + "nodes": [] + }, "sessionsInfo": { "sessionQueueRequests": ["{\n \"browserName\": \"chrome\"\n}","{\n \"browserName\": \"chrome\"\n}","{\n \"browserName\": \"chrome\"\n}"], "sessions": [ @@ -430,6 +472,9 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { "maxSession": 1, "nodeCount": 1 }, + "nodesInfo": { + "nodes": [] + }, "sessionsInfo": { "sessionQueueRequests": ["{\n \"browserName\": \"chrome\"\n}","{\n \"browserName\": \"chrome\",\n \"platformName\": \"Windows 11\"\n}"], "sessions": [] @@ -453,6 +498,9 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { "maxSession": 1, "nodeCount": 1 }, + "nodesInfo": { + "nodes": [] + }, "sessionsInfo": { "sessionQueueRequests": ["{\n \"browserName\": \"chrome\",\n \"platformName\": \"linux\"\n}","{\n \"browserName\": \"chrome\",\n \"platformName\": \"Windows 11\"\n}"], "sessions": [] @@ -467,6 +515,96 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { want: 1, wantErr: false, }, + { + name: "sessions requests with matching browsername and platformName when setSessionsFromHub turned on and node with 2 slots matches should return count as 1", + args: args{ + b: []byte(`{ + "data": { + "grid":{ + "maxSession": 1, + "nodeCount": 1 + }, + "nodesInfo": { + "nodes": [ + { + "stereotypes":"[{\"slots\":1,\"stereotype\":{\"browserName\":\"chrome\",\"platformName\":\"linux\"}}]" + } + ] + }, + "sessionsInfo": { + "sessionQueueRequests": ["{\n \"browserName\": \"chrome\",\n \"platformName\": \"linux\"\n}","{\n \"browserName\": \"chrome\",\n \"platformName\": \"Windows 11\"\n}"], + "sessions": [] + } + } + }`), + browserName: "chrome", + sessionBrowserName: "chrome", + browserVersion: "latest", + platformName: "linux", + setSessionsFromHub: true, + }, + want: 1, + wantErr: false, + }, + { + name: "4 sessions requests with matching browsername and platformName when setSessionsFromHub turned on and node with 2 slots matches should return count as 2", + args: args{ + b: []byte(`{ + "data": { + "grid":{ + "maxSession": 1, + "nodeCount": 1 + }, + "nodesInfo": { + "nodes": [ + { + "stereotypes":"[{\"slots\":2,\"stereotype\":{\"browserName\":\"chrome\",\"platformName\":\"linux\"}}]" + } + ] + }, + "sessionsInfo": { + "sessionQueueRequests": ["{\n \"browserName\": \"chrome\",\n \"platformName\": \"linux\"\n}","{\n \"browserName\": \"chrome\",\n \"platformName\": \"linux\"\n}","{\n \"browserName\": \"chrome\",\n \"platformName\": \"linux\"\n}","{\n \"browserName\": \"chrome\",\n \"platformName\": \"linux\"\n}","{\n \"browserName\": \"chrome\",\n \"platformName\": \"Windows 11\"\n}"], + "sessions": [] + } + } + }`), + browserName: "chrome", + sessionBrowserName: "chrome", + browserVersion: "latest", + platformName: "linux", + setSessionsFromHub: true, + }, + want: 2, + wantErr: false, + }, + { + name: "4 sessions requests with matching browsername and platformName when setSessionsFromHub turned on, no nodes and sessionsPerNode=2 matches should return count as 2", + args: args{ + b: []byte(`{ + "data": { + "grid":{ + "maxSession": 1, + "nodeCount": 1 + }, + "nodesInfo": { + "nodes": [] + }, + "sessionsInfo": { + "sessionQueueRequests": ["{\n \"browserName\": \"chrome\",\n \"platformName\": \"linux\"\n}","{\n \"browserName\": \"chrome\",\n \"platformName\": \"linux\"\n}","{\n \"browserName\": \"chrome\",\n \"platformName\": \"linux\"\n}","{\n \"browserName\": \"chrome\",\n \"platformName\": \"linux\"\n}","{\n \"browserName\": \"chrome\",\n \"platformName\": \"Windows 11\"\n}"], + "sessions": [] + } + } + }`), + browserName: "chrome", + sessionBrowserName: "chrome", + browserVersion: "latest", + platformName: "linux", + setSessionsFromHub: true, + sessionsPerNode: 2, + }, + want: 2, + wantErr: false, + }, { name: "sessions requests and active sessions with matching browsername and platformName should return count as 2", args: args{ @@ -476,6 +614,9 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { "maxSession": 1, "nodeCount": 1 }, + "nodesInfo": { + "nodes": [] + }, "sessionsInfo": { "sessionQueueRequests": ["{\n \"browserName\": \"chrome\",\n \"platformName\": \"linux\"\n}","{\n \"browserName\": \"chrome\",\n \"platformName\": \"Windows 11\",\n \"browserVersion\": \"91.0\"\n}"], "sessions": [ @@ -501,10 +642,47 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { want: 2, wantErr: false, }, + { + name: "sessions requests and active sessions with matching browsername, platformName and sessionBrowserVersion should return count as 3", + args: args{ + b: []byte(`{ + "data": { + "grid":{ + "maxSession": 1, + "nodeCount": 1 + }, + "nodesInfo": { + "nodes": [] + }, + "sessionsInfo": { + "sessionQueueRequests": ["{\n \"browserName\": \"chrome\",\n \"platformName\": \"linux\"\n}","{\n \"browserName\": \"chrome\",\n \"platformName\": \"Windows 11\",\n \"browserVersion\": \"91.0\"\n}"], + "sessions": [ + { + "id": "0f9c5a941aa4d755a54b84be1f6535b1", + "capabilities": "{\n \"acceptInsecureCerts\": false,\n \"browserName\": \"chrome\",\n \"browserVersion\": \"91.0.4472.114\",\n \"chrome\": {\n \"chromedriverVersion\": \"91.0.4472.101 (af52a90bf87030dd1523486a1cd3ae25c5d76c9b-refs\\u002fbranch-heads\\u002f4472@{#1462})\",\n \"userDataDir\": \"\\u002ftmp\\u002f.com.google.Chrome.DMqx9m\"\n },\n \"goog:chromeOptions\": {\n \"debuggerAddress\": \"localhost:35839\"\n },\n \"networkConnectionEnabled\": false,\n \"pageLoadStrategy\": \"normal\",\n \"platformName\": \"linux\",\n \"proxy\": {\n },\n \"se:cdp\": \"http:\\u002f\\u002flocalhost:35839\",\n \"se:cdpVersion\": \"91.0.4472.114\",\n \"se:vncEnabled\": true,\n \"se:vncLocalAddress\": \"ws:\\u002f\\u002flocalhost:7900\\u002fwebsockify\",\n \"setWindowRect\": true,\n \"strictFileInteractability\": false,\n \"timeouts\": {\n \"implicit\": 0,\n \"pageLoad\": 300000,\n \"script\": 30000\n },\n \"unhandledPromptBehavior\": \"dismiss and notify\",\n \"webauthn:extension:largeBlob\": true,\n \"webauthn:virtualAuthenticators\": true\n}", + "nodeId": "d44dcbc5-0b2c-4d5e-abf4-6f6aa5e0983c" + }, + { + "id": "0f9c5a941aa4d755a54b84be1f6535b1", + "capabilities": "{\n \"acceptInsecureCerts\": false,\n \"browserName\": \"chrome\",\n \"browserVersion\": \"91.0.4472.114\",\n \"chrome\": {\n \"chromedriverVersion\": \"91.0.4472.101 (af52a90bf87030dd1523486a1cd3ae25c5d76c9b-refs\\u002fbranch-heads\\u002f4472@{#1462})\",\n \"userDataDir\": \"\\u002ftmp\\u002f.com.google.Chrome.DMqx9m\"\n },\n \"goog:chromeOptions\": {\n \"debuggerAddress\": \"localhost:35839\"\n },\n \"networkConnectionEnabled\": false,\n \"pageLoadStrategy\": \"normal\",\n \"platformName\": \"linux\",\n \"proxy\": {\n },\n \"se:cdp\": \"http:\\u002f\\u002flocalhost:35839\",\n \"se:cdpVersion\": \"91.0.4472.114\",\n \"se:vncEnabled\": true,\n \"se:vncLocalAddress\": \"ws:\\u002f\\u002flocalhost:7900\\u002fwebsockify\",\n \"setWindowRect\": true,\n \"strictFileInteractability\": false,\n \"timeouts\": {\n \"implicit\": 0,\n \"pageLoad\": 300000,\n \"script\": 30000\n },\n \"unhandledPromptBehavior\": \"dismiss and notify\",\n \"webauthn:extension:largeBlob\": true,\n \"webauthn:virtualAuthenticators\": true\n}", + "nodeId": "d44dcbc5-0b2c-4d5e-abf4-6f6aa5e0983c" + } + ] + } + } + }`), + browserName: "chrome", + sessionBrowserName: "chrome", + sessionBrowserVersion: "91.0.4472.114", + platformName: "linux", + }, + want: 3, + wantErr: false, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := getCountFromSeleniumResponse(tt.args.b, tt.args.browserName, tt.args.browserVersion, tt.args.sessionBrowserName, tt.args.platformName, logr.Discard()) + got, err := getCountFromSeleniumResponse(tt.args.b, tt.args.browserName, tt.args.browserVersion, tt.args.sessionBrowserName, tt.args.platformName, tt.args.sessionsPerNode, tt.args.setSessionsFromHub, tt.args.sessionBrowserVersion, logr.Discard()) if (err != nil) != tt.wantErr { t.Errorf("getCountFromSeleniumResponse() error = %v, wantErr %v", err, tt.wantErr) return @@ -558,12 +736,14 @@ func Test_parseSeleniumGridScalerMetadata(t *testing.T) { }, wantErr: false, want: &seleniumGridScalerMetadata{ - URL: "http://selenium-hub:4444/graphql", - BrowserName: "chrome", - SessionBrowserName: "chrome", - TargetValue: 1, - BrowserVersion: "latest", - PlatformName: "linux", + URL: "http://selenium-hub:4444/graphql", + BrowserName: "chrome", + SessionBrowserName: "chrome", + TargetValue: 1, + BrowserVersion: "latest", + PlatformName: "linux", + SessionsPerNode: 1, + SessionBrowserVersion: "latest", }, }, { @@ -579,12 +759,14 @@ func Test_parseSeleniumGridScalerMetadata(t *testing.T) { }, wantErr: false, want: &seleniumGridScalerMetadata{ - URL: "http://selenium-hub:4444/graphql", - BrowserName: "MicrosoftEdge", - SessionBrowserName: "msedge", - TargetValue: 1, - BrowserVersion: "latest", - PlatformName: "linux", + URL: "http://selenium-hub:4444/graphql", + BrowserName: "MicrosoftEdge", + SessionBrowserName: "msedge", + TargetValue: 1, + BrowserVersion: "latest", + PlatformName: "linux", + SessionsPerNode: 1, + SessionBrowserVersion: "latest", }, }, { @@ -602,12 +784,14 @@ func Test_parseSeleniumGridScalerMetadata(t *testing.T) { }, wantErr: false, want: &seleniumGridScalerMetadata{ - URL: "http://user:password@selenium-hub:4444/graphql", - BrowserName: "MicrosoftEdge", - SessionBrowserName: "msedge", - TargetValue: 1, - BrowserVersion: "latest", - PlatformName: "linux", + URL: "http://user:password@selenium-hub:4444/graphql", + BrowserName: "MicrosoftEdge", + SessionBrowserName: "msedge", + TargetValue: 1, + BrowserVersion: "latest", + PlatformName: "linux", + SessionsPerNode: 1, + SessionBrowserVersion: "latest", }, }, { @@ -651,13 +835,15 @@ func Test_parseSeleniumGridScalerMetadata(t *testing.T) { }, wantErr: false, want: &seleniumGridScalerMetadata{ - URL: "http://selenium-hub:4444/graphql", - BrowserName: "chrome", - SessionBrowserName: "chrome", - TargetValue: 1, - BrowserVersion: "91.0", - UnsafeSsl: false, - PlatformName: "linux", + URL: "http://selenium-hub:4444/graphql", + BrowserName: "chrome", + SessionBrowserName: "chrome", + TargetValue: 1, + BrowserVersion: "91.0", + UnsafeSsl: false, + PlatformName: "linux", + SessionsPerNode: 1, + SessionBrowserVersion: "91.0", }, }, { @@ -675,14 +861,16 @@ func Test_parseSeleniumGridScalerMetadata(t *testing.T) { }, wantErr: false, want: &seleniumGridScalerMetadata{ - URL: "http://selenium-hub:4444/graphql", - BrowserName: "chrome", - SessionBrowserName: "chrome", - TargetValue: 1, - ActivationThreshold: 10, - BrowserVersion: "91.0", - UnsafeSsl: true, - PlatformName: "linux", + URL: "http://selenium-hub:4444/graphql", + BrowserName: "chrome", + SessionBrowserName: "chrome", + TargetValue: 1, + ActivationThreshold: 10, + BrowserVersion: "91.0", + UnsafeSsl: true, + PlatformName: "linux", + SessionsPerNode: 1, + SessionBrowserVersion: "91.0", }, }, { @@ -715,14 +903,16 @@ func Test_parseSeleniumGridScalerMetadata(t *testing.T) { }, wantErr: false, want: &seleniumGridScalerMetadata{ - URL: "http://selenium-hub:4444/graphql", - BrowserName: "chrome", - SessionBrowserName: "chrome", - TargetValue: 1, - ActivationThreshold: 10, - BrowserVersion: "91.0", - UnsafeSsl: true, - PlatformName: "linux", + URL: "http://selenium-hub:4444/graphql", + BrowserName: "chrome", + SessionBrowserName: "chrome", + TargetValue: 1, + ActivationThreshold: 10, + BrowserVersion: "91.0", + UnsafeSsl: true, + PlatformName: "linux", + SessionsPerNode: 1, + SessionBrowserVersion: "91.0", }, }, { @@ -741,14 +931,16 @@ func Test_parseSeleniumGridScalerMetadata(t *testing.T) { }, wantErr: false, want: &seleniumGridScalerMetadata{ - URL: "http://selenium-hub:4444/graphql", - BrowserName: "chrome", - SessionBrowserName: "chrome", - TargetValue: 1, - ActivationThreshold: 10, - BrowserVersion: "91.0", - UnsafeSsl: true, - PlatformName: "Windows 11", + URL: "http://selenium-hub:4444/graphql", + BrowserName: "chrome", + SessionBrowserName: "chrome", + TargetValue: 1, + ActivationThreshold: 10, + BrowserVersion: "91.0", + UnsafeSsl: true, + PlatformName: "Windows 11", + SessionsPerNode: 1, + SessionBrowserVersion: "91.0", }, }, }