diff --git a/pkg/scalers/selenium_grid_scaler.go b/pkg/scalers/selenium_grid_scaler.go index bb18d7c9762..b26eb52c45b 100644 --- a/pkg/scalers/selenium_grid_scaler.go +++ b/pkg/scalers/selenium_grid_scaler.go @@ -33,12 +33,12 @@ type seleniumGridScalerMetadata struct { Username string `keda:"name=username, order=authParams;resolvedEnv, optional"` Password string `keda:"name=password, order=authParams;resolvedEnv, optional"` AccessToken string `keda:"name=accessToken, order=authParams;resolvedEnv, optional"` - BrowserName string `keda:"name=browserName, order=triggerMetadata"` + BrowserName string `keda:"name=browserName, order=triggerMetadata, optional"` SessionBrowserName string `keda:"name=sessionBrowserName, order=triggerMetadata, optional"` + BrowserVersion string `keda:"name=browserVersion, order=triggerMetadata, optional"` + PlatformName string `keda:"name=platformName, order=triggerMetadata, default=linux"` ActivationThreshold int64 `keda:"name=activationThreshold, order=triggerMetadata, optional"` - BrowserVersion string `keda:"name=browserVersion, order=triggerMetadata, default=latest"` UnsafeSsl bool `keda:"name=unsafeSsl, order=triggerMetadata, default=false"` - PlatformName string `keda:"name=platformName, order=triggerMetadata, default=linux"` NodeMaxSessions int64 `keda:"name=nodeMaxSessions, order=triggerMetadata, default=1"` TargetValue int64 @@ -96,9 +96,9 @@ type Slot struct { } type Capability struct { - BrowserName string `json:"browserName"` - BrowserVersion string `json:"browserVersion"` - PlatformName string `json:"platformName"` + BrowserName string `json:"browserName,omitempty"` + BrowserVersion string `json:"browserVersion,omitempty"` + PlatformName string `json:"platformName,omitempty"` } type Stereotypes []struct { @@ -106,10 +106,6 @@ type Stereotypes []struct { Stereotype Capability `json:"stereotype"` } -const ( - DefaultBrowserVersion string = "latest" -) - func NewSeleniumGridScaler(config *scalersconfig.ScalerConfig) (Scaler, error) { metricType, err := GetMetricTargetType(config) if err != nil { @@ -227,22 +223,22 @@ func (s *seleniumGridScaler) getSessionsQueueLength(ctx context.Context, logger return newRequestNodes, onGoingSession, nil } -func countMatchingSlotsStereotypes(stereotypes Stereotypes, request Capability, browserName string, browserVersion string, sessionBrowserName string, platformName string) int64 { +func countMatchingSlotsStereotypes(stereotypes Stereotypes, browserName string, browserVersion string, sessionBrowserName string, platformName string) int64 { var matchingSlots int64 for _, stereotype := range stereotypes { - if checkCapabilitiesMatch(stereotype.Stereotype, request, browserName, browserVersion, sessionBrowserName, platformName) { + if checkStereotypeCapabilitiesMatch(stereotype.Stereotype, browserName, browserVersion, sessionBrowserName, platformName) { matchingSlots += stereotype.Slots } } return matchingSlots } -func countMatchingSessions(sessions Sessions, request Capability, browserName string, browserVersion string, sessionBrowserName string, platformName string, logger logr.Logger) int64 { +func countMatchingSessions(sessions Sessions, browserName string, browserVersion string, sessionBrowserName string, platformName string, logger logr.Logger) int64 { var matchingSessions int64 for _, session := range sessions { var capability = Capability{} - if err := json.Unmarshal([]byte(session.Capabilities), &capability); err == nil { - if checkCapabilitiesMatch(capability, request, browserName, browserVersion, sessionBrowserName, platformName) { + if err := json.Unmarshal([]byte(session.Slot.Stereotype), &capability); err == nil { + if checkStereotypeCapabilitiesMatch(capability, browserName, browserVersion, sessionBrowserName, platformName) { matchingSessions++ } } else { @@ -252,27 +248,40 @@ func countMatchingSessions(sessions Sessions, request Capability, browserName st return matchingSessions } -func checkCapabilitiesMatch(capability Capability, requestCapability Capability, browserName string, browserVersion string, sessionBrowserName string, platformName string) bool { - // Ensure the logic should be aligned with DefaultSlotMatcher in Selenium Grid - SeleniumHQ/selenium/java/src/org/openqa/selenium/grid/data/DefaultSlotMatcher.java - // A browserName matches when one of the following conditions is met: - // 1. `browserName` in capability matches with `browserName` or `sessionBrowserName` in scaler metadata - // 2. `browserName` in request capability is empty or not provided - var browserNameMatches = strings.EqualFold(capability.BrowserName, browserName) || strings.EqualFold(capability.BrowserName, sessionBrowserName) || - requestCapability.BrowserName == "" - // A browserVersion matches when one of the following conditions is met: - // 1. `browserVersion` in request capability is empty or not provided or `stable` - // 2. `browserVersion` in capability matches with prefix of the scaler metadata `browserVersion` - // 3. `browserVersion` in scaler metadata is `latest` - var browserVersionMatches = requestCapability.BrowserVersion == "" || requestCapability.BrowserVersion == "stable" || - strings.HasPrefix(capability.BrowserVersion, browserVersion) || browserVersion == DefaultBrowserVersion - // A platformName matches when one of the following conditions is met: - // 1. `platformName` in request capability is empty or not provided - // 2. `platformName` in capability is empty or not provided - // 3. `platformName` in capability matches with the scaler metadata `platformName` - // 4. `platformName` in scaler metadata is empty or not provided - var platformNameMatches = requestCapability.PlatformName == "" || capability.PlatformName == "" || - strings.EqualFold(capability.PlatformName, platformName) || platformName == "" - return browserNameMatches && browserVersionMatches && platformNameMatches +// This function checks if the request capabilities match the scaler metadata +func checkRequestCapabilitiesMatch(request Capability, browserName string, browserVersion string, _ string, platformName string) bool { + // Check if browserName matches + browserNameMatch := request.BrowserName == "" && browserName == "" || + strings.EqualFold(browserName, request.BrowserName) + + // Check if browserVersion matches + browserVersionMatch := (request.BrowserVersion == "" && browserVersion == "") || + (request.BrowserVersion == "stable" && browserVersion == "") || + (strings.HasPrefix(browserVersion, request.BrowserVersion) && request.BrowserVersion != "" && browserVersion != "") + + // Check if platformName matches + platformNameMatch := request.PlatformName == "" && platformName == "" || + strings.EqualFold(platformName, request.PlatformName) + + return browserNameMatch && browserVersionMatch && platformNameMatch +} + +// This function checks if Node stereotypes or ongoing sessions match the scaler metadata +func checkStereotypeCapabilitiesMatch(capability Capability, browserName string, browserVersion string, sessionBrowserName string, platformName string) bool { + // Check if browserName matches + browserNameMatch := capability.BrowserName == "" && browserName == "" || + strings.EqualFold(browserName, capability.BrowserName) || + strings.EqualFold(sessionBrowserName, capability.BrowserName) + + // Check if browserVersion matches + browserVersionMatch := capability.BrowserVersion == "" && browserVersion == "" || + (strings.HasPrefix(browserVersion, capability.BrowserVersion) && capability.BrowserVersion != "" && browserVersion != "") + + // Check if platformName matches + platformNameMatch := capability.PlatformName == "" && platformName == "" || + strings.EqualFold(platformName, capability.PlatformName) + + return browserNameMatch && browserVersionMatch && platformNameMatch } func checkNodeReservedSlots(reservedNodes []ReservedNodes, nodeID string, availableSlots int64) int64 { @@ -318,7 +327,7 @@ func getCountFromSeleniumResponse(b []byte, browserName string, browserVersion s var isRequestMatched bool var requestCapability = Capability{} if err := json.Unmarshal([]byte(sessionQueueRequest), &requestCapability); err == nil { - if checkCapabilitiesMatch(requestCapability, requestCapability, browserName, browserVersion, sessionBrowserName, platformName) { + if checkRequestCapabilitiesMatch(requestCapability, browserName, browserVersion, sessionBrowserName, platformName) { queueSlots++ isRequestMatched = true } @@ -326,28 +335,24 @@ func getCountFromSeleniumResponse(b []byte, browserName string, browserVersion s logger.Error(err, fmt.Sprintf("Error when unmarshaling sessionQueueRequest capability: %s", err)) } - // Skip the request if the capability does not match the scaler parameters - if !isRequestMatched { - continue - } - var isRequestReserved bool - var sumOfCurrentSessionsMatch int64 // Check if the matched request can be assigned to available slots of existing Nodes in the Grid for _, node := range nodes { - // Count ongoing sessions that match the request capability and scaler metadata - var currentSessionsMatch = countMatchingSessions(node.Sessions, requestCapability, browserName, browserVersion, sessionBrowserName, platformName, logger) - sumOfCurrentSessionsMatch += currentSessionsMatch // Check if node is UP and has available slots (maxSession > sessionCount) - if strings.EqualFold(node.Status, "UP") && checkNodeReservedSlots(reservedNodes, node.ID, node.MaxSession-node.SessionCount) > 0 { + if isRequestMatched && strings.EqualFold(node.Status, "UP") && checkNodeReservedSlots(reservedNodes, node.ID, node.MaxSession-node.SessionCount) > 0 { var stereotypes = Stereotypes{} var availableSlotsMatch int64 if err := json.Unmarshal([]byte(node.Stereotypes), &stereotypes); err == nil { // Count available slots that match the request capability and scaler metadata - availableSlotsMatch += countMatchingSlotsStereotypes(stereotypes, requestCapability, browserName, browserVersion, sessionBrowserName, platformName) + availableSlotsMatch += countMatchingSlotsStereotypes(stereotypes, browserName, browserVersion, sessionBrowserName, platformName) } else { logger.Error(err, fmt.Sprintf("Error when unmarshaling node stereotypes: %s", err)) } + if availableSlotsMatch == 0 { + continue + } + // Count ongoing sessions that match the request capability and scaler metadata + var currentSessionsMatch = countMatchingSessions(node.Sessions, browserName, browserVersion, sessionBrowserName, platformName, logger) // Count remaining available slots can be reserved for this request var availableSlotsCanBeReserved = checkNodeReservedSlots(reservedNodes, node.ID, node.MaxSession-node.SessionCount) // Reserve one available slot for the request if available slots match is greater than current sessions match @@ -359,11 +364,8 @@ func getCountFromSeleniumResponse(b []byte, browserName string, browserVersion s } } } - if sumOfCurrentSessionsMatch > onGoingSessions { - onGoingSessions = sumOfCurrentSessionsMatch - } // Check if the matched request can be assigned to available slots of new Nodes will be scaled up, since the scaler parameter `nodeMaxSessions` can be greater than 1 - if !isRequestReserved { + if isRequestMatched && !isRequestReserved { for _, newRequestNode := range newRequestNodes { if newRequestNode.SlotCount > 0 { newRequestNodes = updateOrAddReservedNode(newRequestNodes, newRequestNode.ID, newRequestNode.SlotCount-1, nodeMaxSessions) @@ -373,10 +375,15 @@ func getCountFromSeleniumResponse(b []byte, browserName string, browserVersion s } } // Check if a new Node should be scaled up to reserve for the matched request - if !isRequestReserved { + if isRequestMatched && !isRequestReserved { newRequestNodes = updateOrAddReservedNode(newRequestNodes, string(rune(requestIndex)), nodeMaxSessions-1, nodeMaxSessions) } } + // Count ongoing sessions across all nodes that match the scaler metadata + for _, node := range nodes { + onGoingSessions += countMatchingSessions(node.Sessions, browserName, browserVersion, sessionBrowserName, platformName, logger) + } + return int64(len(newRequestNodes)), onGoingSessions, nil } diff --git a/pkg/scalers/selenium_grid_scaler_test.go b/pkg/scalers/selenium_grid_scaler_test.go index 6613be242ca..0860a1e5b38 100644 --- a/pkg/scalers/selenium_grid_scaler_test.go +++ b/pkg/scalers/selenium_grid_scaler_test.go @@ -63,6 +63,7 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { browserName: "", }, wantNewRequestNodes: 0, + wantOnGoingSessions: 0, wantErr: false, }, { @@ -99,14 +100,15 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { `), browserName: "chrome", sessionBrowserName: "chrome", - browserVersion: "latest", + browserVersion: "", platformName: "linux", }, wantNewRequestNodes: 4, + wantOnGoingSessions: 0, wantErr: false, }, { - name: "2 sessionQueueRequests and 1 available nodeStereotypes with matching browserName firefox should return count as 1", + name: "2_sessionQueueRequests_and_1_available_nodeStereotypes_with_matching_browserName_firefox_should_return_count_as_1", args: args{ b: []byte(`{ "data": { @@ -123,14 +125,14 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { "sessionCount": 1, "maxSession": 1, "slotCount": 1, - "stereotypes": "[\n {\n \"slots\": 1,\n \"stereotype\": {\n \"browserName\": \"chrome\",\n \"browserVersion\": \"128.0\",\n \"goog:chromeOptions\": {\n \"binary\": \"\\u002fusr\\u002fbin\\u002fchromium\"\n },\n \"platformName\": \"linux\",\n \"se:containerName\": \"my-chrome-name-m5n8z-4br6x\",\n \"se:downloadsEnabled\": true,\n \"se:noVncPort\": 7900,\n \"se:vncEnabled\": true\n }\n }\n]", + "stereotypes": "[\n {\n \"slots\": 1,\n \"stereotype\": {\n \"browserName\": \"chrome\",\n \"browserVersion\": \"\",\n \"goog:chromeOptions\": {\n \"binary\": \"\\u002fusr\\u002fbin\\u002fchromium\"\n },\n \"platformName\": \"linux\",\n \"se:containerName\": \"my-chrome-name-m5n8z-4br6x\",\n \"se:downloadsEnabled\": true,\n \"se:noVncPort\": 7900,\n \"se:vncEnabled\": true\n }\n }\n]", "sessions": [ { "id": "reserved", "capabilities": "{\n \"browserName\": \"chrome\",\n \"browserVersion\": \"128.0\",\n \"goog:chromeOptions\": {\n \"binary\": \"\\u002fusr\\u002fbin\\u002fchromium\"\n },\n \"platformName\": \"linux\",\n \"se:containerName\": \"my-chrome-name-m5n8z-4br6x\",\n \"se:downloadsEnabled\": true,\n \"se:noVncPort\": 7900,\n \"se:vncEnabled\": true\n}", "slot": { "id": "83c9d9f5-f79d-4dea-bc9b-ce61bf2bc01c", - "stereotype": "{\n \"browserName\": \"chrome\",\n \"browserVersion\": \"128.0\",\n \"goog:chromeOptions\": {\n \"binary\": \"\\u002fusr\\u002fbin\\u002fchromium\"\n },\n \"platformName\": \"linux\",\n \"se:containerName\": \"my-chrome-name-m5n8z-4br6x\",\n \"se:downloadsEnabled\": true,\n \"se:noVncPort\": 7900,\n \"se:vncEnabled\": true\n}" + "stereotype": "{\n \"browserName\": \"chrome\",\n \"browserVersion\": \"\",\n \"goog:chromeOptions\": {\n \"binary\": \"\\u002fusr\\u002fbin\\u002fchromium\"\n },\n \"platformName\": \"linux\",\n \"se:containerName\": \"my-chrome-name-m5n8z-4br6x\",\n \"se:downloadsEnabled\": true,\n \"se:noVncPort\": 7900,\n \"se:vncEnabled\": true\n}" } } ] @@ -141,14 +143,14 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { "sessionCount": 1, "maxSession": 1, "slotCount": 1, - "stereotypes": "[\n {\n \"slots\": 1,\n \"stereotype\": {\n \"browserName\": \"firefox\",\n \"browserVersion\": \"130.0\",\n \"moz:firefoxOptions\": {\n \"binary\": \"\\u002fusr\\u002fbin\\u002ffirefox\"\n },\n \"platformName\": \"linux\",\n \"se:containerName\": \"my-firefox-name-s2gq6-82lwb\",\n \"se:downloadsEnabled\": true,\n \"se:noVncPort\": 7900,\n \"se:vncEnabled\": true\n }\n }\n]", + "stereotypes": "[\n {\n \"slots\": 1,\n \"stereotype\": {\n \"browserName\": \"firefox\",\n \"browserVersion\": \"\",\n \"moz:firefoxOptions\": {\n \"binary\": \"\\u002fusr\\u002fbin\\u002ffirefox\"\n },\n \"platformName\": \"linux\",\n \"se:containerName\": \"my-firefox-name-s2gq6-82lwb\",\n \"se:downloadsEnabled\": true,\n \"se:noVncPort\": 7900,\n \"se:vncEnabled\": true\n }\n }\n]", "sessions": [ { "id": "reserved", "capabilities": "{\n \"browserName\": \"firefox\",\n \"browserVersion\": \"130.0\",\n \"moz:firefoxOptions\": {\n \"binary\": \"\\u002fusr\\u002fbin\\u002ffirefox\"\n },\n \"platformName\": \"linux\",\n \"se:containerName\": \"my-firefox-name-s2gq6-82lwb\",\n \"se:downloadsEnabled\": true,\n \"se:noVncPort\": 7900,\n \"se:vncEnabled\": true\n}", "slot": { "id": "b03b80c0-95f8-4b9c-ba06-bebd2568ce3d", - "stereotype": "{\n \"browserName\": \"firefox\",\n \"browserVersion\": \"130.0\",\n \"moz:firefoxOptions\": {\n \"binary\": \"\\u002fusr\\u002fbin\\u002ffirefox\"\n },\n \"platformName\": \"linux\",\n \"se:containerName\": \"my-firefox-name-s2gq6-82lwb\",\n \"se:downloadsEnabled\": true,\n \"se:noVncPort\": 7900,\n \"se:vncEnabled\": true\n}" + "stereotype": "{\n \"browserName\": \"firefox\",\n \"browserVersion\": \"\",\n \"moz:firefoxOptions\": {\n \"binary\": \"\\u002fusr\\u002fbin\\u002ffirefox\"\n },\n \"platformName\": \"linux\",\n \"se:containerName\": \"my-firefox-name-s2gq6-82lwb\",\n \"se:downloadsEnabled\": true,\n \"se:noVncPort\": 7900,\n \"se:vncEnabled\": true\n}" } } ] @@ -159,7 +161,7 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { "sessionCount": 0, "maxSession": 1, "slotCount": 1, - "stereotypes": "[\n {\n \"slots\": 1,\n \"stereotype\": {\n \"browserName\": \"chrome\",\n \"browserVersion\": \"128.0\",\n \"goog:chromeOptions\": {\n \"binary\": \"\\u002fusr\\u002fbin\\u002fchromium\"\n },\n \"platformName\": \"linux\",\n \"se:containerName\": \"my-chrome-name-xh95p-9c2cl\",\n \"se:downloadsEnabled\": true,\n \"se:noVncPort\": 7900,\n \"se:vncEnabled\": true\n }\n }\n]", + "stereotypes": "[\n {\n \"slots\": 1,\n \"stereotype\": {\n \"browserName\": \"chrome\",\n \"browserVersion\": \"\",\n \"goog:chromeOptions\": {\n \"binary\": \"\\u002fusr\\u002fbin\\u002fchromium\"\n },\n \"platformName\": \"linux\",\n \"se:containerName\": \"my-chrome-name-xh95p-9c2cl\",\n \"se:downloadsEnabled\": true,\n \"se:noVncPort\": 7900,\n \"se:vncEnabled\": true\n }\n }\n]", "sessions": [] }, { @@ -168,14 +170,14 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { "sessionCount": 1, "maxSession": 1, "slotCount": 1, - "stereotypes": "[\n {\n \"slots\": 1,\n \"stereotype\": {\n \"browserName\": \"chrome\",\n \"browserVersion\": \"128.0\",\n \"goog:chromeOptions\": {\n \"binary\": \"\\u002fusr\\u002fbin\\u002fchromium\"\n },\n \"platformName\": \"linux\",\n \"se:containerName\": \"my-chrome-name-j2xbn-lq76c\",\n \"se:downloadsEnabled\": true,\n \"se:noVncPort\": 7900,\n \"se:vncEnabled\": true\n }\n }\n]", + "stereotypes": "[\n {\n \"slots\": 1,\n \"stereotype\": {\n \"browserName\": \"chrome\",\n \"browserVersion\": \"\",\n \"goog:chromeOptions\": {\n \"binary\": \"\\u002fusr\\u002fbin\\u002fchromium\"\n },\n \"platformName\": \"linux\",\n \"se:containerName\": \"my-chrome-name-j2xbn-lq76c\",\n \"se:downloadsEnabled\": true,\n \"se:noVncPort\": 7900,\n \"se:vncEnabled\": true\n }\n }\n]", "sessions": [ { "id": "reserved", "capabilities": "{\n \"browserName\": \"chrome\",\n \"browserVersion\": \"128.0\",\n \"goog:chromeOptions\": {\n \"binary\": \"\\u002fusr\\u002fbin\\u002fchromium\"\n },\n \"platformName\": \"linux\",\n \"se:containerName\": \"my-chrome-name-j2xbn-lq76c\",\n \"se:downloadsEnabled\": true,\n \"se:noVncPort\": 7900,\n \"se:vncEnabled\": true\n}", "slot": { "id": "9d91cd87-b443-4a0c-93e7-eea8c4661207", - "stereotype": "{\n \"browserName\": \"chrome\",\n \"browserVersion\": \"128.0\",\n \"goog:chromeOptions\": {\n \"binary\": \"\\u002fusr\\u002fbin\\u002fchromium\"\n },\n \"platformName\": \"linux\",\n \"se:containerName\": \"my-chrome-name-j2xbn-lq76c\",\n \"se:downloadsEnabled\": true,\n \"se:noVncPort\": 7900,\n \"se:vncEnabled\": true\n}" + "stereotype": "{\n \"browserName\": \"chrome\",\n \"browserVersion\": \"\",\n \"goog:chromeOptions\": {\n \"binary\": \"\\u002fusr\\u002fbin\\u002fchromium\"\n },\n \"platformName\": \"linux\",\n \"se:containerName\": \"my-chrome-name-j2xbn-lq76c\",\n \"se:downloadsEnabled\": true,\n \"se:noVncPort\": 7900,\n \"se:vncEnabled\": true\n}" } } ] @@ -186,14 +188,14 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { "sessionCount": 1, "maxSession": 1, "slotCount": 1, - "stereotypes": "[\n {\n \"slots\": 1,\n \"stereotype\": {\n \"browserName\": \"firefox\",\n \"browserVersion\": \"130.0\",\n \"moz:firefoxOptions\": {\n \"binary\": \"\\u002fusr\\u002fbin\\u002ffirefox\"\n },\n \"platformName\": \"linux\",\n \"se:containerName\": \"my-firefox-name-xk6mm-2m6jh\",\n \"se:downloadsEnabled\": true,\n \"se:noVncPort\": 7900,\n \"se:vncEnabled\": true\n }\n }\n]", + "stereotypes": "[\n {\n \"slots\": 1,\n \"stereotype\": {\n \"browserName\": \"firefox\",\n \"browserVersion\": \"\",\n \"moz:firefoxOptions\": {\n \"binary\": \"\\u002fusr\\u002fbin\\u002ffirefox\"\n },\n \"platformName\": \"linux\",\n \"se:containerName\": \"my-firefox-name-xk6mm-2m6jh\",\n \"se:downloadsEnabled\": true,\n \"se:noVncPort\": 7900,\n \"se:vncEnabled\": true\n }\n }\n]", "sessions": [ { "id": "reserved", "capabilities": "{\n \"browserName\": \"firefox\",\n \"browserVersion\": \"130.0\",\n \"moz:firefoxOptions\": {\n \"binary\": \"\\u002fusr\\u002fbin\\u002ffirefox\"\n },\n \"platformName\": \"linux\",\n \"se:containerName\": \"my-firefox-name-xk6mm-2m6jh\",\n \"se:downloadsEnabled\": true,\n \"se:noVncPort\": 7900,\n \"se:vncEnabled\": true\n}", "slot": { "id": "2c1fc5c4-881a-48fd-9b9e-b4d3ecbc1bd8", - "stereotype": "{\n \"browserName\": \"firefox\",\n \"browserVersion\": \"130.0\",\n \"moz:firefoxOptions\": {\n \"binary\": \"\\u002fusr\\u002fbin\\u002ffirefox\"\n },\n \"platformName\": \"linux\",\n \"se:containerName\": \"my-firefox-name-xk6mm-2m6jh\",\n \"se:downloadsEnabled\": true,\n \"se:noVncPort\": 7900,\n \"se:vncEnabled\": true\n}" + "stereotype": "{\n \"browserName\": \"firefox\",\n \"browserVersion\": \"\",\n \"moz:firefoxOptions\": {\n \"binary\": \"\\u002fusr\\u002fbin\\u002ffirefox\"\n },\n \"platformName\": \"linux\",\n \"se:containerName\": \"my-firefox-name-xk6mm-2m6jh\",\n \"se:downloadsEnabled\": true,\n \"se:noVncPort\": 7900,\n \"se:vncEnabled\": true\n}" } } ] @@ -204,14 +206,14 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { "sessionCount": 1, "maxSession": 1, "slotCount": 1, - "stereotypes": "[\n {\n \"slots\": 1,\n \"stereotype\": {\n \"browserName\": \"firefox\",\n \"browserVersion\": \"130.0\",\n \"moz:firefoxOptions\": {\n \"binary\": \"\\u002fusr\\u002fbin\\u002ffirefox\"\n },\n \"platformName\": \"linux\",\n \"se:containerName\": \"my-firefox-name-bvq59-6dh6q\",\n \"se:downloadsEnabled\": true,\n \"se:noVncPort\": 7900,\n \"se:vncEnabled\": true\n }\n }\n]", + "stereotypes": "[\n {\n \"slots\": 1,\n \"stereotype\": {\n \"browserName\": \"firefox\",\n \"browserVersion\": \"\",\n \"moz:firefoxOptions\": {\n \"binary\": \"\\u002fusr\\u002fbin\\u002ffirefox\"\n },\n \"platformName\": \"linux\",\n \"se:containerName\": \"my-firefox-name-bvq59-6dh6q\",\n \"se:downloadsEnabled\": true,\n \"se:noVncPort\": 7900,\n \"se:vncEnabled\": true\n }\n }\n]", "sessions": [ { "id": "reserved", "capabilities": "{\n \"browserName\": \"firefox\",\n \"browserVersion\": \"130.0\",\n \"moz:firefoxOptions\": {\n \"binary\": \"\\u002fusr\\u002fbin\\u002ffirefox\"\n },\n \"platformName\": \"linux\",\n \"se:containerName\": \"my-firefox-name-bvq59-6dh6q\",\n \"se:downloadsEnabled\": true,\n \"se:noVncPort\": 7900,\n \"se:vncEnabled\": true\n}", "slot": { "id": "5f8f9ba0-0f61-473e-b367-b68d9368dc24", - "stereotype": "{\n \"browserName\": \"firefox\",\n \"browserVersion\": \"130.0\",\n \"moz:firefoxOptions\": {\n \"binary\": \"\\u002fusr\\u002fbin\\u002ffirefox\"\n },\n \"platformName\": \"linux\",\n \"se:containerName\": \"my-firefox-name-bvq59-6dh6q\",\n \"se:downloadsEnabled\": true,\n \"se:noVncPort\": 7900,\n \"se:vncEnabled\": true\n}" + "stereotype": "{\n \"browserName\": \"firefox\",\n \"browserVersion\": \"\",\n \"moz:firefoxOptions\": {\n \"binary\": \"\\u002fusr\\u002fbin\\u002ffirefox\"\n },\n \"platformName\": \"linux\",\n \"se:containerName\": \"my-firefox-name-bvq59-6dh6q\",\n \"se:downloadsEnabled\": true,\n \"se:noVncPort\": 7900,\n \"se:vncEnabled\": true\n}" } } ] @@ -222,7 +224,7 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { "sessionCount": 0, "maxSession": 1, "slotCount": 1, - "stereotypes": "[\n {\n \"slots\": 1,\n \"stereotype\": {\n \"browserName\": \"firefox\",\n \"browserVersion\": \"130.0\",\n \"moz:firefoxOptions\": {\n \"binary\": \"\\u002fusr\\u002fbin\\u002ffirefox\"\n },\n \"platformName\": \"linux\",\n \"se:containerName\": \"my-firefox-name-42xbf-zpdd4\",\n \"se:downloadsEnabled\": true,\n \"se:noVncPort\": 7900,\n \"se:vncEnabled\": true\n }\n }\n]", + "stereotypes": "[\n {\n \"slots\": 1,\n \"stereotype\": {\n \"browserName\": \"firefox\",\n \"browserVersion\": \"\",\n \"moz:firefoxOptions\": {\n \"binary\": \"\\u002fusr\\u002fbin\\u002ffirefox\"\n },\n \"platformName\": \"linux\",\n \"se:containerName\": \"my-firefox-name-42xbf-zpdd4\",\n \"se:downloadsEnabled\": true,\n \"se:noVncPort\": 7900,\n \"se:vncEnabled\": true\n }\n }\n]", "sessions": [] }, { @@ -231,14 +233,14 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { "sessionCount": 1, "maxSession": 1, "slotCount": 1, - "stereotypes": "[\n {\n \"slots\": 1,\n \"stereotype\": {\n \"browserName\": \"firefox\",\n \"browserVersion\": \"130.0\",\n \"moz:firefoxOptions\": {\n \"binary\": \"\\u002fusr\\u002fbin\\u002ffirefox\"\n },\n \"platformName\": \"linux\",\n \"se:containerName\": \"my-firefox-name-qt9z2-6xx86\",\n \"se:downloadsEnabled\": true,\n \"se:noVncPort\": 7900,\n \"se:vncEnabled\": true\n }\n }\n]", + "stereotypes": "[\n {\n \"slots\": 1,\n \"stereotype\": {\n \"browserName\": \"firefox\",\n \"browserVersion\": \"\",\n \"moz:firefoxOptions\": {\n \"binary\": \"\\u002fusr\\u002fbin\\u002ffirefox\"\n },\n \"platformName\": \"linux\",\n \"se:containerName\": \"my-firefox-name-qt9z2-6xx86\",\n \"se:downloadsEnabled\": true,\n \"se:noVncPort\": 7900,\n \"se:vncEnabled\": true\n }\n }\n]", "sessions": [ { "id": "reserved", "capabilities": "{\n \"browserName\": \"firefox\",\n \"browserVersion\": \"130.0\",\n \"moz:firefoxOptions\": {\n \"binary\": \"\\u002fusr\\u002fbin\\u002ffirefox\"\n },\n \"platformName\": \"linux\",\n \"se:containerName\": \"my-firefox-name-qt9z2-6xx86\",\n \"se:downloadsEnabled\": true,\n \"se:noVncPort\": 7900,\n \"se:vncEnabled\": true\n}", "slot": { "id": "38bd0b09-ffe0-46e9-8983-bd208270c8da", - "stereotype": "{\n \"browserName\": \"firefox\",\n \"browserVersion\": \"130.0\",\n \"moz:firefoxOptions\": {\n \"binary\": \"\\u002fusr\\u002fbin\\u002ffirefox\"\n },\n \"platformName\": \"linux\",\n \"se:containerName\": \"my-firefox-name-qt9z2-6xx86\",\n \"se:downloadsEnabled\": true,\n \"se:noVncPort\": 7900,\n \"se:vncEnabled\": true\n}" + "stereotype": "{\n \"browserName\": \"firefox\",\n \"browserVersion\": \"\",\n \"moz:firefoxOptions\": {\n \"binary\": \"\\u002fusr\\u002fbin\\u002ffirefox\"\n },\n \"platformName\": \"linux\",\n \"se:containerName\": \"my-firefox-name-qt9z2-6xx86\",\n \"se:downloadsEnabled\": true,\n \"se:noVncPort\": 7900,\n \"se:vncEnabled\": true\n}" } } ] @@ -249,14 +251,14 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { "sessionCount": 1, "maxSession": 1, "slotCount": 1, - "stereotypes": "[\n {\n \"slots\": 1,\n \"stereotype\": {\n \"browserName\": \"chrome\",\n \"browserVersion\": \"128.0\",\n \"goog:chromeOptions\": {\n \"binary\": \"\\u002fusr\\u002fbin\\u002fchromium\"\n },\n \"platformName\": \"linux\",\n \"se:containerName\": \"my-chrome-name-v7nrv-xsfkb\",\n \"se:downloadsEnabled\": true,\n \"se:noVncPort\": 7900,\n \"se:vncEnabled\": true\n }\n }\n]", + "stereotypes": "[\n {\n \"slots\": 1,\n \"stereotype\": {\n \"browserName\": \"chrome\",\n \"browserVersion\": \"\",\n \"goog:chromeOptions\": {\n \"binary\": \"\\u002fusr\\u002fbin\\u002fchromium\"\n },\n \"platformName\": \"linux\",\n \"se:containerName\": \"my-chrome-name-v7nrv-xsfkb\",\n \"se:downloadsEnabled\": true,\n \"se:noVncPort\": 7900,\n \"se:vncEnabled\": true\n }\n }\n]", "sessions": [ { "id": "reserved", - "capabilities": "{\n \"browserName\": \"chrome\",\n \"browserVersion\": \"128.0\",\n \"goog:chromeOptions\": {\n \"binary\": \"\\u002fusr\\u002fbin\\u002fchromium\"\n },\n \"platformName\": \"linux\",\n \"se:containerName\": \"my-chrome-name-v7nrv-xsfkb\",\n \"se:downloadsEnabled\": true,\n \"se:noVncPort\": 7900,\n \"se:vncEnabled\": true\n}", + "capabilities": "{\n \"browserName\": \"chrome\",\n \"browserVersion\": \"\",\n \"goog:chromeOptions\": {\n \"binary\": \"\\u002fusr\\u002fbin\\u002fchromium\"\n },\n \"platformName\": \"linux\",\n \"se:containerName\": \"my-chrome-name-v7nrv-xsfkb\",\n \"se:downloadsEnabled\": true,\n \"se:noVncPort\": 7900,\n \"se:vncEnabled\": true\n}", "slot": { "id": "43b992cc-39bb-4b0f-92b6-99603a543459", - "stereotype": "{\n \"browserName\": \"chrome\",\n \"browserVersion\": \"128.0\",\n \"goog:chromeOptions\": {\n \"binary\": \"\\u002fusr\\u002fbin\\u002fchromium\"\n },\n \"platformName\": \"linux\",\n \"se:containerName\": \"my-chrome-name-v7nrv-xsfkb\",\n \"se:downloadsEnabled\": true,\n \"se:noVncPort\": 7900,\n \"se:vncEnabled\": true\n}" + "stereotype": "{\n \"browserName\": \"chrome\",\n \"browserVersion\": \"\",\n \"goog:chromeOptions\": {\n \"binary\": \"\\u002fusr\\u002fbin\\u002fchromium\"\n },\n \"platformName\": \"linux\",\n \"se:containerName\": \"my-chrome-name-v7nrv-xsfkb\",\n \"se:downloadsEnabled\": true,\n \"se:noVncPort\": 7900,\n \"se:vncEnabled\": true\n}" } } ] @@ -274,15 +276,15 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { `), browserName: "firefox", sessionBrowserName: "firefox", - browserVersion: "latest", + browserVersion: "", platformName: "linux", }, - wantNewRequestNodes: 1, + wantNewRequestNodes: 0, wantOnGoingSessions: 4, wantErr: false, }, { - name: "1 sessionQueueRequests and 1 available nodeStereotypes with matching browserName chrome should return count as 0", + name: "1_sessionQueueRequests_and_1_available_nodeStereotypes_with_matching_browserName_chrome_should_return_count_as_0", args: args{ b: []byte(`{ "data": { @@ -324,14 +326,15 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { `), browserName: "chrome", sessionBrowserName: "chrome", - browserVersion: "latest", + browserVersion: "", platformName: "linux", }, - wantNewRequestNodes: 0, + wantNewRequestNodes: 1, + wantOnGoingSessions: 0, wantErr: false, }, { - name: "1 sessionQueueRequests Linux and 1 available nodeStereotypes Windows with matching browserName chrome should return count as 1", + name: `Given_2_requests_with_explicit_name_version_platform_When_2_existing_node_with_platform_not_matching_And_scaler_metadata_with_browser_version_as_latest_Then_scaler_should_not_scale_up_and_return_0`, args: args{ b: []byte(`{ "data": { @@ -373,14 +376,15 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { `), browserName: "chrome", sessionBrowserName: "chrome", - browserVersion: "latest", + browserVersion: "", platformName: "linux", }, - wantNewRequestNodes: 1, + wantNewRequestNodes: 0, + wantOnGoingSessions: 0, wantErr: false, }, { - name: "scaler browserVersion is latest, 2 sessionQueueRequests wihtout browserVersion, 2 available nodeStereotypes with different versions and platforms, should return count as 1", + name: "scaler_browserVersion_is_latest,_2_sessionQueueRequests_without_browserVersion,_2_available_nodeStereotypes_with_different_versions_and_platforms,_should_return_count_as_1", args: args{ b: []byte(`{ "data": { @@ -397,7 +401,7 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { "sessionCount": 0, "maxSession": 1, "slotCount": 1, - "stereotypes": "[{\"slots\": 1, \"stereotype\": {\"browserName\": \"chrome\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}}]", + "stereotypes": "[{\"slots\": 1, \"stereotype\": {\"browserName\": \"chrome\", \"browserVersion\": \"\", \"platformName\": \"linux\"}}]", "sessions": [] }, { @@ -406,7 +410,7 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { "sessionCount": 0, "maxSession": 1, "slotCount": 1, - "stereotypes": "[{\"slots\": 1, \"stereotype\": {\"browserName\": \"chrome\", \"browserVersion\": \"92.0\", \"platformName\": \"Windows 11\"}}]", + "stereotypes": "[{\"slots\": 1, \"stereotype\": {\"browserName\": \"chrome\", \"browserVersion\": \"\", \"platformName\": \"Windows 11\"}}]", "sessions": [] } ] @@ -421,14 +425,15 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { }`), browserName: "chrome", sessionBrowserName: "chrome", - browserVersion: "latest", + browserVersion: "", platformName: "linux", }, wantNewRequestNodes: 1, + wantOnGoingSessions: 0, wantErr: false, }, { - name: "scaler browserVersion is latest, 5 sessionQueueRequests wihtout browserVersion also 1 different platformName, 1 available nodeStereotypes with 3 slots Linux and 1 node Windows, should return count as 1", + name: "scaler_browserVersion_is_latest,_5_sessionQueueRequests_wihtout_browserVersion_also_1_different_platformName,_1_available_nodeStereotypes_with_3_slots_Linux_and_1_node_Windows,_should_return_count_as_1", args: args{ b: []byte(`{ "data": { @@ -445,7 +450,7 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { "sessionCount": 0, "maxSession": 3, "slotCount": 3, - "stereotypes": "[{\"slots\": 3, \"stereotype\": {\"browserName\": \"chrome\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}}]", + "stereotypes": "[{\"slots\": 3, \"stereotype\": {\"browserName\": \"chrome\", \"browserVersion\": \"\", \"platformName\": \"linux\"}}]", "sessions": [] }, { @@ -454,7 +459,7 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { "sessionCount": 0, "maxSession": 3, "slotCount": 3, - "stereotypes": "[{\"slots\": 3, \"stereotype\": {\"browserName\": \"chrome\", \"browserVersion\": \"92.0\", \"platformName\": \"Windows 11\"}}]", + "stereotypes": "[{\"slots\": 3, \"stereotype\": {\"browserName\": \"chrome\", \"browserVersion\": \"\", \"platformName\": \"Windows 11\"}}]", "sessions": [] } ] @@ -472,10 +477,11 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { }`), browserName: "chrome", sessionBrowserName: "chrome", - browserVersion: "latest", + browserVersion: "", platformName: "linux", }, wantNewRequestNodes: 1, + wantOnGoingSessions: 0, wantErr: false, }, { @@ -500,7 +506,11 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { "sessions": [ { "id": "session-1", - "capabilities": "{\"browserName\": \"firefox\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}" + "capabilities": "{\"browserName\": \"firefox\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"firefox\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}" + } } ] } @@ -519,6 +529,7 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { platformName: "linux", }, wantNewRequestNodes: 1, + wantOnGoingSessions: 0, wantErr: false, }, { @@ -543,7 +554,11 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { "sessions": [ { "id": "session-1", - "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}" + "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"chrome\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}" + } } ] }, @@ -557,7 +572,11 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { "sessions": [ { "id": "session-2", - "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}" + "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"chrome\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}" + } } ] } @@ -625,6 +644,7 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { platformName: "linux", }, wantNewRequestNodes: 0, + wantOnGoingSessions: 0, wantErr: false, }, { @@ -649,7 +669,11 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { "sessions": [ { "id": "session-1", - "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}" + "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"chrome\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}" + } } ] }, @@ -663,7 +687,11 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { "sessions": [ { "id": "session-2", - "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}" + "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"chrome\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}" + } } ] } @@ -708,11 +736,19 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { "sessions": [ { "id": "session-1", - "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}" + "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"chrome\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}" + } }, { "id": "session-2", - "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}" + "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"chrome\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}" + } } ] } @@ -756,7 +792,11 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { "sessions": [ { "id": "session-1", - "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}" + "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"chrome\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}" + } } ] }, @@ -770,7 +810,11 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { "sessions": [ { "id": "session-2", - "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}" + "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"chrome\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}" + } } ] } @@ -795,7 +839,7 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { wantErr: false, }, { - name: "3 queue requests with browserName browserVersion and platformName but 2 running nodes are busy with different versions should return count as 3", + name: "Given_3_requests_explicit_name_version_platform_When_2_existing_nodes_not_available_And_scaler_metadate_with_browserVersion_as_latest_Then_scaler_should_not_scale_up_and_return_2_on_going_session", args: args{ b: []byte(`{ "data": { @@ -816,7 +860,11 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { "sessions": [ { "id": "session-1", - "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}" + "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"chrome\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}" + } } ] }, @@ -830,7 +878,11 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { "sessions": [ { "id": "session-2", - "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}" + "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"chrome\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}" + } } ] } @@ -847,11 +899,79 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { }`), browserName: "chrome", sessionBrowserName: "chrome", - browserVersion: "latest", + browserVersion: "", platformName: "linux", }, - wantNewRequestNodes: 3, - wantOnGoingSessions: 2, + wantNewRequestNodes: 0, + wantOnGoingSessions: 0, + wantErr: false, + }, + { + name: "Given_3_requests_explicit_name_version_platform_When_2_existing_nodes_not_available_And_scaler_metadate_with_browserVersion_92.0_Then_scaler_should_scale_up_1_and_return_0_on_going_session", + args: args{ + b: []byte(`{ + "data": { + "grid": { + "sessionCount": 2, + "maxSession": 2, + "totalSlots": 2 + }, + "nodesInfo": { + "nodes": [ + { + "id": "node-1", + "status": "UP", + "sessionCount": 1, + "maxSession": 1, + "slotCount": 1, + "stereotypes": "[{\"slots\": 1, \"stereotype\": {\"browserName\": \"chrome\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}}]", + "sessions": [ + { + "id": "session-1", + "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"chrome\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}" + } + } + ] + }, + { + "id": "node-2", + "status": "UP", + "sessionCount": 1, + "maxSession": 1, + "slotCount": 1, + "stereotypes": "[{\"slots\": 1, \"stereotype\": {\"browserName\": \"chrome\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}}]", + "sessions": [ + { + "id": "session-2", + "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"chrome\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}" + } + } + ] + } + ] + }, + "sessionsInfo": { + "sessionQueueRequests": [ + "{\"browserName\": \"chrome\", \"browserVersion\": \"90.0\", \"platformName\": \"linux\"}", + "{\"browserName\": \"chrome\", \"browserVersion\": \"92.0\", \"platformName\": \"linux\"}", + "{\"browserName\": \"chrome\", \"browserVersion\": \"93.0\", \"platformName\": \"linux\"}" + ] + } + } + }`), + browserName: "chrome", + sessionBrowserName: "chrome", + browserVersion: "92.0", + platformName: "linux", + }, + wantNewRequestNodes: 1, + wantOnGoingSessions: 0, wantErr: false, }, { @@ -876,7 +996,11 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { "sessions": [ { "id": "session-1", - "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}" + "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"chrome\", \"platformName\": \"linux\"}" + } } ] }, @@ -890,7 +1014,11 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { "sessions": [ { "id": "session-2", - "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}" + "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"chrome\", \"platformName\": \"linux\"}" + } } ] } @@ -907,7 +1035,7 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { }`), browserName: "chrome", sessionBrowserName: "chrome", - browserVersion: "latest", + browserVersion: "", platformName: "linux", }, wantNewRequestNodes: 3, @@ -936,7 +1064,11 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { "sessions": [ { "id": "session-1", - "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}" + "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"chrome\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}" + } } ] } @@ -960,7 +1092,7 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { wantErr: false, }, { - name: "1 request without browserName and browserVersion stable can be match any available node should return count as 0", + name: "1_request_without_browserVersion_can_be_match_any_available_node_should_return_count_as_0", args: args{ b: []byte(`{ "data": { @@ -984,21 +1116,22 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { }, "sessionsInfo": { "sessionQueueRequests": [ - "{\"browserVersion\": \"stable\", \"platformName\": \"linux\"}" + "{\"browserName\": \"chrome\", \"browserVersion\": \"\", \"platformName\": \"linux\"}" ] } } }`), browserName: "chrome", sessionBrowserName: "chrome", - browserVersion: "latest", + browserVersion: "", platformName: "linux", }, - wantNewRequestNodes: 0, + wantNewRequestNodes: 1, + wantOnGoingSessions: 0, wantErr: false, }, { - name: "1 request without browserName and browserVersion stable should return count as 1", + name: "1 request without platformName and browserVersion should return count as 1", args: args{ b: []byte(`{ "data": { @@ -1015,11 +1148,15 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { "sessionCount": 1, "maxSession": 1, "slotCount": 1, - "stereotypes": "[{\"slots\": 1, \"stereotype\": {\"browserName\": \"chrome\", \"browserVersion\": \"v128.0\", \"platformName\": \"linux\"}}]", + "stereotypes": "[{\"slots\": 1, \"stereotype\": {\"browserName\": \"chrome\", \"browserVersion\": \"128.0\", \"platformName\": \"linux\"}}]", "sessions": [ { "id": "session-1", - "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"v128.0\", \"platformName\": \"linux\"}" + "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"128.0\", \"platformName\": \"linux\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"chrome\", \"browserVersion\": \"128.0\", \"platformName\": \"linux\"}" + } } ] } @@ -1027,18 +1164,18 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { }, "sessionsInfo": { "sessionQueueRequests": [ - "{\"browserVersion\": \"stable\", \"platformName\": \"linux\"}" + "{\"browserName\": \"chrome\", \"browserVersion\": \"\", \"platformName\": \"\"}" ] } } }`), browserName: "chrome", sessionBrowserName: "chrome", - browserVersion: "latest", - platformName: "linux", + browserVersion: "", + platformName: "", }, wantNewRequestNodes: 1, - wantOnGoingSessions: 1, + wantOnGoingSessions: 0, wantErr: false, }, { @@ -1063,7 +1200,11 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { "sessions": [ { "id": "session-1", - "capabilities": "{\"browserName\": \"msedge\", \"browserVersion\": \"dev\", \"platformName\": \"linux\"}" + "capabilities": "{\"browserName\": \"msedge\", \"browserVersion\": \"dev\", \"platformName\": \"linux\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"msedge\", \"browserVersion\": \"dev\", \"platformName\": \"linux\"}" + } } ] } @@ -1108,7 +1249,11 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { "sessions": [ { "id": "session-1", - "capabilities": "{\"browserName\": \"msedge\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}" + "capabilities": "{\"browserName\": \"msedge\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"msedge\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}" + } } ] } @@ -1168,9 +1313,10 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { platformName: "linux", }, wantNewRequestNodes: 1, + wantOnGoingSessions: 0, wantErr: false, }, { - name: "2 queue requests with platformName and without platformName and node with 1 slot available should return count as 1", + name: "2_queue_requests_with_platformName_and_without_platformName_and_node_with_1_slot_available_should_return_count_as_1", args: args{ b: []byte(`{ "data": { @@ -1191,7 +1337,11 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { "sessions": [ { "id": "session-1", - "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"91.0\", \"platformName\": \"Windows 11\"}" + "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"91.0\", \"platformName\": \"Windows 11\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"chrome\", \"browserVersion\": \"91.0\", \"platformName\": \"Windows 11\"}" + } } ] } @@ -1210,7 +1360,7 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { browserVersion: "91.0", platformName: "Windows 11", }, - wantNewRequestNodes: 1, + wantNewRequestNodes: 0, wantOnGoingSessions: 1, wantErr: false, }, @@ -1236,7 +1386,11 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { "sessions": [ { "id": "session-1", - "capabilities": "{\"browserName\": \"msedge\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}" + "capabilities": "{\"browserName\": \"msedge\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"msedge\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}" + } } ] } @@ -1252,10 +1406,11 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { }`), browserName: "chrome", sessionBrowserName: "chrome", - browserVersion: "latest", + browserVersion: "", platformName: "linux", }, wantNewRequestNodes: 2, + wantOnGoingSessions: 0, wantErr: false, }, { @@ -1280,7 +1435,11 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { "sessions": [ { "id": "session-1", - "capabilities": "{\"browserName\": \"msedge\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}" + "capabilities": "{\"browserName\": \"msedge\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"msedge\", \"browserVersion\": \"91.0\", \"platformName\": \"linux\"}" + } } ] } @@ -1297,14 +1456,15 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { }`), browserName: "chrome", sessionBrowserName: "chrome", - browserVersion: "latest", + browserVersion: "", platformName: "linux", }, wantNewRequestNodes: 3, + wantOnGoingSessions: 0, wantErr: false, }, { - name: "session request with matching browsername and no specific platformName should return count as 2", + name: "Given_2_requests_with_1_matching_browser_name_and_1_mismatch_platformName_When_no_node_available_Then_scaler_should_return_1_for_matching_request_and_0_ongoing_session", args: args{ b: []byte(`{ "data": { @@ -1326,14 +1486,15 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { }`), browserName: "chrome", sessionBrowserName: "chrome", - browserVersion: "latest", + browserVersion: "", platformName: "", }, - wantNewRequestNodes: 2, + wantNewRequestNodes: 1, + wantOnGoingSessions: 0, wantErr: false, }, { - name: "2 queue requests with 1 matching browsername and platformName and 1 existing slot is available should return count as 0", + name: "2_queue_requests_with_1_matching_browsername_and_platformName_and_1_existing_slot_is_available_should_return_count_as_1", args: args{ b: []byte(`{ "data": { @@ -1365,14 +1526,15 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { }`), browserName: "chrome", sessionBrowserName: "chrome", - browserVersion: "latest", + browserVersion: "", platformName: "Windows 11", }, - wantNewRequestNodes: 0, + wantNewRequestNodes: 1, + wantOnGoingSessions: 0, wantErr: false, }, { - name: "2 queue requests with 1 request matching browserName and platformName but 1 existing node is busy should return count as 1", + name: "Given_2_requests_without_browserVersion_When_scaler_metadata_explicit_name_version_platform_Then_scaler_should_not_scale_up_and_return_1_on_going_session", args: args{ b: []byte(`{ "data": { @@ -1389,15 +1551,23 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { "sessionCount": 2, "maxSession": 2, "slotCount": 2, - "stereotypes": "[\n {\n \"slots\": 2,\n \"stereotype\": {\n \"browserName\": \"chrome\",\n \"browserVersion\": \"128.0\",\n \"goog:chromeOptions\": {\n \"binary\": \"\\u002fusr\\u002fbin\\u002fchromium\"\n },\n \"se:containerName\": \"my-chrome-name-m5n8z-4br6x\",\n \"se:downloadsEnabled\": true,\n \"se:noVncPort\": 7900,\n \"se:vncEnabled\": true\n }\n }\n]", + "stereotypes": "[\n {\n \"slots\": 2,\n \"stereotype\": {\n \"browserName\": \"chrome\",\n \"browserVersion\": \"91.0\",\n \"browserPlatform\": \"Windows 11\",\n \"goog:chromeOptions\": {\n \"binary\": \"\\u002fusr\\u002fbin\\u002fchromium\"\n },\n \"se:containerName\": \"my-chrome-name-m5n8z-4br6x\",\n \"se:downloadsEnabled\": true,\n \"se:noVncPort\": 7900,\n \"se:vncEnabled\": true\n }\n }\n]", "sessions": [ { "id": "0f9c5a941aa4d755a54b84be1f6535b1", - "capabilities": "{\"browserName\": \"chrome\", \"platformName\": \"Windows 11\", \"browserVersion\": \"91.0\"}" + "capabilities": "{\"browserName\": \"chrome\", \"platformName\": \"Windows 11\", \"browserVersion\": \"91.0\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"chrome\", \"platformName\": \"Windows 11\", \"browserVersion\": \"91.0\"}" + } }, { "id": "0f9c5a941aa4d755a54b84be1f6535b1", - "capabilities": "{\"browserName\": \"chrome\", \"platformName\": \"linux\", \"browserVersion\": \"91.0\"}" + "capabilities": "{\"browserName\": \"chrome\", \"platformName\": \"Windows 11\", \"browserVersion\": \"91.0\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"chrome\", \"platformName\": \"Windows 11\", \"browserVersion\": \"91.0\"}" + } } ] } @@ -1416,12 +1586,12 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { browserVersion: "91.0", platformName: "Windows 11", }, - wantNewRequestNodes: 1, - wantOnGoingSessions: 1, + wantNewRequestNodes: 0, + wantOnGoingSessions: 2, wantErr: false, }, { - name: "5 queue requests with scaler parameter nodeMaxSessions is 2 should return count as 3", + name: "Given_5_requests_explicit_name_version_platform_When_scaler_metadata_set_browserVersion_as_latest_Then_scaler_should_not_scale_up_for_those_request_and_return_0", args: args{ b: []byte(`{ "data": { @@ -1447,15 +1617,16 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { `), browserName: "chrome", sessionBrowserName: "chrome", - browserVersion: "latest", + browserVersion: "", platformName: "linux", nodeMaxSessions: 2, }, - wantNewRequestNodes: 3, + wantNewRequestNodes: 0, + wantOnGoingSessions: 0, wantErr: false, }, { - name: "5 queue requests with scaler parameter nodeMaxSessions is 3 should return count as 2", + name: "Given_5_requests_explicit_name_version_platform_When_scaler_metadata_set_browserVersion_as_latest_Then_scaler_should_not_scale_up_for_those_requests_and_return_0", args: args{ b: []byte(`{ "data": { @@ -1481,15 +1652,16 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { `), browserName: "chrome", sessionBrowserName: "chrome", - browserVersion: "latest", + browserVersion: "", platformName: "linux", nodeMaxSessions: 3, }, - wantNewRequestNodes: 2, + wantNewRequestNodes: 0, + wantOnGoingSessions: 0, wantErr: false, }, { - name: "5 queue requests with request matching browserName and platformName and scaler param nodeMaxSessions is 3 and existing node with 1 available slot should return count as 2", + name: "Given_5_requests_without_browserVersion_When_scaler_metadata_explicit_name_version_platform_Then_scaler_should_not_scaler_up_for_those_requests_and_return_0", args: args{ b: []byte(`{ "data": { @@ -1510,11 +1682,19 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { "sessions": [ { "id": "0f9c5a941aa4d755a54b84be1f6535b1", - "capabilities": "{\"browserName\": \"chrome\", \"platformName\": \"Linux\", \"browserVersion\": \"91.0\"}" + "capabilities": "{\"browserName\": \"chrome\", \"platformName\": \"Linux\", \"browserVersion\": \"91.0\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"chrome\", \"platformName\": \"Linux\", \"browserVersion\": \"91.0\"}" + } }, { "id": "0f9c5a941aa4d755a54b84be1f6535b1", - "capabilities": "{\"browserName\": \"chrome\", \"platformName\": \"linux\", \"browserVersion\": \"91.0\"}" + "capabilities": "{\"browserName\": \"chrome\", \"platformName\": \"linux\", \"browserVersion\": \"91.0\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"chrome\", \"platformName\": \"Linux\", \"browserVersion\": \"91.0\"}" + } } ] } @@ -1537,7 +1717,7 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { platformName: "linux", nodeMaxSessions: 3, }, - wantNewRequestNodes: 2, + wantNewRequestNodes: 0, wantOnGoingSessions: 2, wantErr: false, }, @@ -1575,10 +1755,11 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { }`), browserName: "chrome", sessionBrowserName: "chrome", - browserVersion: "latest", + browserVersion: "", platformName: "linux", }, wantNewRequestNodes: 0, + wantOnGoingSessions: 0, wantErr: false, }, { @@ -1617,10 +1798,11 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { }`), browserName: "chrome", sessionBrowserName: "chrome", - browserVersion: "latest", + browserVersion: "", platformName: "linux", }, wantNewRequestNodes: 2, + wantOnGoingSessions: 0, wantErr: false, }, { @@ -1648,15 +1830,16 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { }`), browserName: "chrome", sessionBrowserName: "chrome", - browserVersion: "latest", + browserVersion: "", platformName: "linux", nodeMaxSessions: 2, }, wantNewRequestNodes: 2, + wantOnGoingSessions: 0, wantErr: false, }, { - name: "sessions requests and active sessions with 1 matching browsername, platformName and sessionBrowserVersion should return count as 1", + name: "Given_2_requests_include_1_without_browserVersion_When_scaler_metadata_explicit_name_version_platform_Then_scaler_should_scale_up_for_1_request_has_browserVersion_and_return_0_ongoing_sessions", args: args{ b: []byte(`{ "data": { @@ -1678,12 +1861,20 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { { "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" + "nodeId": "d44dcbc5-0b2c-4d5e-abf4-6f6aa5e0983c", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\":\"chrome\",\"platformName\":\"linux\"}" + } }, { "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" + "nodeId": "d44dcbc5-0b2c-4d5e-abf4-6f6aa5e0983c", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\":\"chrome\",\"platformName\":\"linux\"}" + } } ] } @@ -1692,7 +1883,7 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { "sessionsInfo": { "sessionQueueRequests": [ "{\n \"browserName\": \"chrome\",\n \"platformName\": \"linux\"\n}", - "{\n \"browserName\": \"chrome\",\n \"platformName\": \"Windows 11\",\n \"browserVersion\": \"91.0\"\n}" + "{\n \"browserName\": \"chrome\",\n \"platformName\": \"linux\",\n \"browserVersion\": \"91.0\"\n}" ] } } @@ -1703,81 +1894,978 @@ func Test_getCountFromSeleniumResponse(t *testing.T) { platformName: "linux", }, wantNewRequestNodes: 1, - wantOnGoingSessions: 2, + wantOnGoingSessions: 0, wantErr: false, }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - newRequestNodes, onGoingSessions, err := getCountFromSeleniumResponse(tt.args.b, tt.args.browserName, tt.args.browserVersion, tt.args.sessionBrowserName, tt.args.platformName, tt.args.nodeMaxSessions, logr.Discard()) - if (err != nil) != tt.wantErr { - t.Errorf("getCountFromSeleniumResponse() error = %v, wantErr %v", err, tt.wantErr) - return - } - if !reflect.DeepEqual(newRequestNodes, tt.wantNewRequestNodes) || !reflect.DeepEqual(onGoingSessions, tt.wantOnGoingSessions) { - t.Errorf("getCountFromSeleniumResponse() = [%v, %v], want [%v, %v]", newRequestNodes, onGoingSessions, tt.wantNewRequestNodes, tt.wantOnGoingSessions) - } - }) - } -} - -func Test_parseSeleniumGridScalerMetadata(t *testing.T) { - type args struct { - config *scalersconfig.ScalerConfig - } - tests := []struct { - name string - args args - want *seleniumGridScalerMetadata - wantErr bool - }{ - { - name: "invalid url string should throw error", - args: args{ - config: &scalersconfig.ScalerConfig{ - TriggerMetadata: map[string]string{}, - }, - }, - wantErr: true, - }, { - name: "invalid browsername string should throw error", + name: "Given_2_requests_include_1_without_browserVersion_When_scaler_metadata_without_browserVersion_Then_scaler_should_scale_up_for_1_request_has_browserVersion_and_return_2_ongoing_sessions", args: args{ - config: &scalersconfig.ScalerConfig{ - TriggerMetadata: map[string]string{ - "url": "", - }, - }, + b: []byte(`{ + "data": { + "grid": { + "sessionCount": 2, + "maxSession": 2, + "totalSlots": 2 + }, + "nodesInfo": { + "nodes": [ + { + "id": "d44dcbc5-0b2c-4d5e-abf4-6f6aa5e0983c", + "status": "UP", + "sessionCount": 2, + "maxSession": 2, + "slotCount": 2, + "stereotypes":"[{\"slots\":2,\"stereotype\":{\"browserName\":\"chrome\",\"platformName\":\"linux\"}}]", + "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", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\":\"chrome\",\"platformName\":\"linux\"}" + } + }, + { + "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", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\":\"chrome\",\"platformName\":\"linux\"}" + } + } + ] + } + ] + }, + "sessionsInfo": { + "sessionQueueRequests": [ + "{\n \"browserName\": \"chrome\",\n \"platformName\": \"linux\"\n}", + "{\n \"browserName\": \"chrome\",\n \"platformName\": \"linux\",\n \"browserVersion\": \"91.0\"\n}" + ] + } + } + }`), + browserName: "chrome", + sessionBrowserName: "chrome", + browserVersion: "", + platformName: "linux", }, - wantErr: true, + wantNewRequestNodes: 1, + wantOnGoingSessions: 2, + wantErr: false, }, { - name: "valid url and browsername should return metadata", + name: `Given_3_requests_include_1_without_browserVersion_ + When_4_existing_nodes_with_different_stereotypes_browserVersion_ + And_scaler_metadata_set_browserVersion_as_latest_ + Then_return_1_new_scale_and_4_ongoing`, args: args{ - config: &scalersconfig.ScalerConfig{ - TriggerMetadata: map[string]string{ - "url": "http://selenium-hub:4444/graphql", - "browserName": "chrome", - }, - }, - }, - wantErr: false, - want: &seleniumGridScalerMetadata{ - URL: "http://selenium-hub:4444/graphql", - BrowserName: "chrome", - SessionBrowserName: "chrome", - TargetValue: 1, - BrowserVersion: "latest", - PlatformName: "linux", - NodeMaxSessions: 1, + b: []byte(`{ + "data": { + "grid": { + "sessionCount": 4, + "maxSession": 4, + "totalSlots": 4 + }, + "nodesInfo": { + "nodes": [ + { + "id": "node-131", + "status": "UP", + "sessionCount": 1, + "maxSession": 1, + "slotCount": 1, + "stereotypes": "[{\"slots\": 1, \"stereotype\": {\"browserName\": \"chrome\", \"browserVersion\": \"131.0\", \"platformName\": \"linux\"}}]", + "sessions": [ + { + "id": "session-1", + "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"131.0\", \"platformName\": \"linux\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"chrome\", \"browserVersion\": \"131.0\", \"platformName\": \"linux\"}" + } + } + ] + }, + { + "id": "node-130", + "status": "UP", + "sessionCount": 1, + "maxSession": 1, + "slotCount": 1, + "stereotypes": "[{\"slots\": 1, \"stereotype\": {\"browserName\": \"chrome\", \"browserVersion\": \"130.0\", \"platformName\": \"linux\"}}]", + "sessions": [ + { + "id": "session-1", + "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"130.0\", \"platformName\": \"linux\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"chrome\", \"browserVersion\": \"130.0\", \"platformName\": \"linux\"}" + } + } + ] + }, + { + "id": "node-129", + "status": "UP", + "sessionCount": 1, + "maxSession": 1, + "slotCount": 1, + "stereotypes": "[{\"slots\": 1, \"stereotype\": {\"browserName\": \"chrome\", \"browserVersion\": \"129.0\", \"platformName\": \"linux\"}}]", + "sessions": [ + { + "id": "session-2", + "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"129.0\", \"platformName\": \"linux\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"chrome\", \"browserVersion\": \"129.0\", \"platformName\": \"linux\"}" + } + } + ] + }, + { + "id": "node-128", + "status": "UP", + "sessionCount": 1, + "maxSession": 1, + "slotCount": 1, + "stereotypes": "[{\"slots\": 1, \"stereotype\": {\"browserName\": \"chrome\", \"browserVersion\": \"128.0\", \"platformName\": \"linux\"}}]", + "sessions": [ + { + "id": "session-1", + "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"128.0\", \"platformName\": \"linux\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"chrome\", \"browserVersion\": \"128.0\", \"platformName\": \"linux\"}" + } + } + ] + } + ] + }, + "sessionsInfo": { + "sessionQueueRequests": [ + "{\"browserName\": \"chrome\", \"platformName\": \"linux\"}", + "{\"browserName\": \"chrome\", \"platformName\": \"linux\", \"browserVersion\": \"131\"}", + "{\"browserName\": \"chrome\", \"platformName\": \"linux\", \"browserVersion\": \"130\"}" + ] + } + } + }`), + browserName: "chrome", + sessionBrowserName: "chrome", + browserVersion: "", + platformName: "linux", }, + wantNewRequestNodes: 1, + wantOnGoingSessions: 0, + wantErr: false, }, { - name: "valid url, browsername, and sessionbrowsername should return metadata", + name: `Given_3_requests_include_1_without_browserVersion_ + When_4_existing_nodes_with_different_stereotypes_browserVersion_ + And_scaler_metadata_set_browserVersion_131.0_ + Then_return_1_new_scale_and_1_ongoing`, args: args{ - config: &scalersconfig.ScalerConfig{ - TriggerMetadata: map[string]string{ - "url": "http://selenium-hub:4444/graphql", + b: []byte(`{ + "data": { + "grid": { + "sessionCount": 4, + "maxSession": 4, + "totalSlots": 4 + }, + "nodesInfo": { + "nodes": [ + { + "id": "node-131", + "status": "UP", + "sessionCount": 1, + "maxSession": 1, + "slotCount": 1, + "stereotypes": "[{\"slots\": 1, \"stereotype\": {\"browserName\": \"chrome\", \"browserVersion\": \"131.0\", \"platformName\": \"linux\"}}]", + "sessions": [ + { + "id": "session-1", + "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"131.0\", \"platformName\": \"linux\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"chrome\", \"browserVersion\": \"131.0\", \"platformName\": \"linux\"}" + } + } + ] + }, + { + "id": "node-130", + "status": "UP", + "sessionCount": 1, + "maxSession": 1, + "slotCount": 1, + "stereotypes": "[{\"slots\": 1, \"stereotype\": {\"browserName\": \"chrome\", \"browserVersion\": \"130.0\", \"platformName\": \"linux\"}}]", + "sessions": [ + { + "id": "session-1", + "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"130.0\", \"platformName\": \"linux\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"chrome\", \"browserVersion\": \"130.0\", \"platformName\": \"linux\"}" + } + } + ] + }, + { + "id": "node-129", + "status": "UP", + "sessionCount": 1, + "maxSession": 1, + "slotCount": 1, + "stereotypes": "[{\"slots\": 1, \"stereotype\": {\"browserName\": \"chrome\", \"browserVersion\": \"129.0\", \"platformName\": \"linux\"}}]", + "sessions": [ + { + "id": "session-2", + "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"129.0\", \"platformName\": \"linux\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"chrome\", \"browserVersion\": \"129.0\", \"platformName\": \"linux\"}" + } + } + ] + }, + { + "id": "node-128", + "status": "UP", + "sessionCount": 1, + "maxSession": 1, + "slotCount": 1, + "stereotypes": "[{\"slots\": 1, \"stereotype\": {\"browserName\": \"chrome\", \"browserVersion\": \"128.0\", \"platformName\": \"linux\"}}]", + "sessions": [ + { + "id": "session-1", + "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"128.0\", \"platformName\": \"linux\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"chrome\", \"browserVersion\": \"128.0\", \"platformName\": \"linux\"}" + } + } + ] + } + ] + }, + "sessionsInfo": { + "sessionQueueRequests": [ + "{\"browserName\": \"chrome\", \"platformName\": \"linux\"}", + "{\"browserName\": \"chrome\", \"platformName\": \"linux\", \"browserVersion\": \"131\"}", + "{\"browserName\": \"chrome\", \"platformName\": \"linux\", \"browserVersion\": \"130\"}" + ] + } + } + }`), + browserName: "chrome", + sessionBrowserName: "chrome", + browserVersion: "131.0", + platformName: "linux", + }, + wantNewRequestNodes: 1, + wantOnGoingSessions: 1, + wantErr: false, + }, + { + name: `Given_3_requests_include_1_without_browserVersion_ + When_4_existing_nodes_with_different_stereotypes_browserVersion_ + And_scaler_metadata_set_browserVersion_130.0_ + Then_return_1_new_scale_and_1_ongoing`, + args: args{ + b: []byte(`{ + "data": { + "grid": { + "sessionCount": 4, + "maxSession": 4, + "totalSlots": 4 + }, + "nodesInfo": { + "nodes": [ + { + "id": "node-131", + "status": "UP", + "sessionCount": 1, + "maxSession": 1, + "slotCount": 1, + "stereotypes": "[{\"slots\": 1, \"stereotype\": {\"browserName\": \"chrome\", \"browserVersion\": \"131.0\", \"platformName\": \"linux\"}}]", + "sessions": [ + { + "id": "session-1", + "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"131.0\", \"platformName\": \"linux\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"chrome\", \"browserVersion\": \"131.0\", \"platformName\": \"linux\"}" + } + } + ] + }, + { + "id": "node-130", + "status": "UP", + "sessionCount": 1, + "maxSession": 1, + "slotCount": 1, + "stereotypes": "[{\"slots\": 1, \"stereotype\": {\"browserName\": \"chrome\", \"browserVersion\": \"130.0\", \"platformName\": \"linux\"}}]", + "sessions": [ + { + "id": "session-1", + "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"130.0\", \"platformName\": \"linux\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"chrome\", \"browserVersion\": \"130.0\", \"platformName\": \"linux\"}" + } + } + ] + }, + { + "id": "node-129", + "status": "UP", + "sessionCount": 1, + "maxSession": 1, + "slotCount": 1, + "stereotypes": "[{\"slots\": 1, \"stereotype\": {\"browserName\": \"chrome\", \"browserVersion\": \"129.0\", \"platformName\": \"linux\"}}]", + "sessions": [ + { + "id": "session-2", + "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"129.0\", \"platformName\": \"linux\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"chrome\", \"browserVersion\": \"129.0\", \"platformName\": \"linux\"}" + } + } + ] + }, + { + "id": "node-128", + "status": "UP", + "sessionCount": 1, + "maxSession": 1, + "slotCount": 1, + "stereotypes": "[{\"slots\": 1, \"stereotype\": {\"browserName\": \"chrome\", \"browserVersion\": \"128.0\", \"platformName\": \"linux\"}}]", + "sessions": [ + { + "id": "session-1", + "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"128.0\", \"platformName\": \"linux\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"chrome\", \"browserVersion\": \"128.0\", \"platformName\": \"linux\"}" + } + } + ] + } + ] + }, + "sessionsInfo": { + "sessionQueueRequests": [ + "{\"browserName\": \"chrome\", \"platformName\": \"linux\"}", + "{\"browserName\": \"chrome\", \"platformName\": \"linux\", \"browserVersion\": \"131\"}", + "{\"browserName\": \"chrome\", \"platformName\": \"linux\", \"browserVersion\": \"130\"}" + ] + } + } + }`), + browserName: "chrome", + sessionBrowserName: "chrome", + browserVersion: "130.0", + platformName: "linux", + }, + wantNewRequestNodes: 1, + wantOnGoingSessions: 1, + wantErr: false, + }, + { + name: `Given_3_requests_include_1_without_browserVersion_ + When_4_existing_nodes_with_different_stereotypes_browserVersion_and_1_available_ + And_scaler_metadata_set_browserVersion_as_latest_ + Then_return_0_new_scale_and_0_ongoing`, + args: args{ + b: []byte(`{ + "data": { + "grid": { + "sessionCount": 3, + "maxSession": 4, + "totalSlots": 4 + }, + "nodesInfo": { + "nodes": [ + { + "id": "node-131", + "status": "UP", + "sessionCount": 1, + "maxSession": 1, + "slotCount": 1, + "stereotypes": "[{\"slots\": 1, \"stereotype\": {\"browserName\": \"chrome\", \"browserVersion\": \"131.0\", \"platformName\": \"linux\"}}]", + "sessions": [ + { + "id": "session-1", + "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"131.0\", \"platformName\": \"linux\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"chrome\", \"browserVersion\": \"131.0\", \"platformName\": \"linux\"}" + } + } + ] + }, + { + "id": "node-130", + "status": "UP", + "sessionCount": 0, + "maxSession": 1, + "slotCount": 1, + "stereotypes": "[{\"slots\": 1, \"stereotype\": {\"browserName\": \"chrome\", \"browserVersion\": \"\", \"platformName\": \"linux\"}}]", + "sessions": [] + }, + { + "id": "node-129", + "status": "UP", + "sessionCount": 1, + "maxSession": 1, + "slotCount": 1, + "stereotypes": "[{\"slots\": 1, \"stereotype\": {\"browserName\": \"chrome\", \"browserVersion\": \"129.0\", \"platformName\": \"linux\"}}]", + "sessions": [ + { + "id": "session-1", + "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"129.0\", \"platformName\": \"linux\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"chrome\", \"browserVersion\": \"129.0\", \"platformName\": \"linux\"}" + } + } + ] + }, + { + "id": "node-128", + "status": "UP", + "sessionCount": 1, + "maxSession": 1, + "slotCount": 1, + "stereotypes": "[{\"slots\": 1, \"stereotype\": {\"browserName\": \"chrome\", \"browserVersion\": \"128.0\", \"platformName\": \"linux\"}}]", + "sessions": [ + { + "id": "session-1", + "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"128.0\", \"platformName\": \"linux\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"chrome\", \"browserVersion\": \"128.0\", \"platformName\": \"linux\"}" + } + } + ] + } + ] + }, + "sessionsInfo": { + "sessionQueueRequests": [ + "{\"browserName\": \"chrome\", \"platformName\": \"linux\"}", + "{\"browserName\": \"chrome\", \"platformName\": \"linux\", \"browserVersion\": \"131\"}", + "{\"browserName\": \"chrome\", \"platformName\": \"linux\", \"browserVersion\": \"130\"}" + ] + } + } + }`), + browserName: "chrome", + sessionBrowserName: "chrome", + browserVersion: "", + platformName: "linux", + }, + wantNewRequestNodes: 0, + wantOnGoingSessions: 0, + wantErr: false, + }, + { + name: `Given_3_requests_include_1_without_browserVersion_ + When_4_existing_nodes_with_different_stereotypes_browserVersion_and_1_available_ + And_scaler_metadata_set_browserVersion_131.0_ + Then_return_0_new_scale_and_0_ongoing`, + args: args{ + b: []byte(`{ + "data": { + "grid": { + "sessionCount": 3, + "maxSession": 4, + "totalSlots": 4 + }, + "nodesInfo": { + "nodes": [ + { + "id": "node-131", + "status": "UP", + "sessionCount": 0, + "maxSession": 1, + "slotCount": 1, + "stereotypes": "[{\"slots\": 1, \"stereotype\": {\"browserName\": \"chrome\", \"browserVersion\": \"131.0\", \"platformName\": \"linux\"}}]", + "sessions": [] + }, + { + "id": "node-130", + "status": "UP", + "sessionCount": 1, + "maxSession": 1, + "slotCount": 1, + "stereotypes": "[{\"slots\": 1, \"stereotype\": {\"browserName\": \"chrome\", \"browserVersion\": \"130.0\", \"platformName\": \"linux\"}}]", + "sessions": [ + { + "id": "session-1", + "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"130.0\", \"platformName\": \"linux\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"chrome\", \"browserVersion\": \"130.0\", \"platformName\": \"linux\"}" + } + } + ] + }, + { + "id": "node-129", + "status": "UP", + "sessionCount": 1, + "maxSession": 1, + "slotCount": 1, + "stereotypes": "[{\"slots\": 1, \"stereotype\": {\"browserName\": \"chrome\", \"browserVersion\": \"129.0\", \"platformName\": \"linux\"}}]", + "sessions": [ + { + "id": "session-1", + "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"129.0\", \"platformName\": \"linux\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"chrome\", \"browserVersion\": \"129.0\", \"platformName\": \"linux\"}" + } + } + ] + }, + { + "id": "node-128", + "status": "UP", + "sessionCount": 1, + "maxSession": 1, + "slotCount": 1, + "stereotypes": "[{\"slots\": 1, \"stereotype\": {\"browserName\": \"chrome\", \"browserVersion\": \"128.0\", \"platformName\": \"linux\"}}]", + "sessions": [ + { + "id": "session-1", + "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"128.0\", \"platformName\": \"linux\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"chrome\", \"browserVersion\": \"128.0\", \"platformName\": \"linux\"}" + } + } + ] + } + ] + }, + "sessionsInfo": { + "sessionQueueRequests": [ + "{\"browserName\": \"chrome\", \"platformName\": \"linux\"}", + "{\"browserName\": \"chrome\", \"platformName\": \"linux\", \"browserVersion\": \"131\"}", + "{\"browserName\": \"chrome\", \"platformName\": \"linux\", \"browserVersion\": \"130\"}" + ] + } + } + }`), + browserName: "chrome", + sessionBrowserName: "chrome", + browserVersion: "131.0", + platformName: "linux", + }, + wantNewRequestNodes: 0, + wantOnGoingSessions: 0, + wantErr: false, + }, + { + name: `Given_3_requests_include_1_without_browserVersion_ + When_4_existing_nodes_with_different_stereotypes_browserVersion_and_1_available_ + And_scaler_metadata_set_browserVersion_130.0_ + Then_return_0_new_scale_and_0_ongoing`, + args: args{ + b: []byte(`{ + "data": { + "grid": { + "sessionCount": 3, + "maxSession": 4, + "totalSlots": 4 + }, + "nodesInfo": { + "nodes": [ + { + "id": "node-131", + "status": "UP", + "sessionCount": 1, + "maxSession": 1, + "slotCount": 1, + "stereotypes": "[{\"slots\": 1, \"stereotype\": {\"browserName\": \"chrome\", \"browserVersion\": \"131.0\", \"platformName\": \"linux\"}}]", + "sessions": [ + { + "id": "session-1", + "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"131.0\", \"platformName\": \"linux\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"chrome\", \"browserVersion\": \"131.0\", \"platformName\": \"linux\"}" + } + } + ] + }, + { + "id": "node-130", + "status": "UP", + "sessionCount": 0, + "maxSession": 1, + "slotCount": 1, + "stereotypes": "[{\"slots\": 1, \"stereotype\": {\"browserName\": \"chrome\", \"browserVersion\": \"130.0\", \"platformName\": \"linux\"}}]", + "sessions": [] + }, + { + "id": "node-129", + "status": "UP", + "sessionCount": 1, + "maxSession": 1, + "slotCount": 1, + "stereotypes": "[{\"slots\": 1, \"stereotype\": {\"browserName\": \"chrome\", \"browserVersion\": \"129.0\", \"platformName\": \"linux\"}}]", + "sessions": [ + { + "id": "session-1", + "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"129.0\", \"platformName\": \"linux\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"chrome\", \"browserVersion\": \"129.0\", \"platformName\": \"linux\"}" + } + } + ] + }, + { + "id": "node-128", + "status": "UP", + "sessionCount": 1, + "maxSession": 1, + "slotCount": 1, + "stereotypes": "[{\"slots\": 1, \"stereotype\": {\"browserName\": \"chrome\", \"browserVersion\": \"128.0\", \"platformName\": \"linux\"}}]", + "sessions": [ + { + "id": "session-1", + "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"128.0\", \"platformName\": \"linux\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"chrome\", \"browserVersion\": \"128.0\", \"platformName\": \"linux\"}" + } + } + ] + } + ] + }, + "sessionsInfo": { + "sessionQueueRequests": [ + "{\"browserName\": \"chrome\", \"platformName\": \"linux\"}", + "{\"browserName\": \"chrome\", \"platformName\": \"linux\", \"browserVersion\": \"131\"}", + "{\"browserName\": \"chrome\", \"platformName\": \"linux\", \"browserVersion\": \"130\"}" + ] + } + } + }`), + browserName: "chrome", + sessionBrowserName: "chrome", + browserVersion: "130.0", + platformName: "linux", + }, + wantNewRequestNodes: 0, + wantOnGoingSessions: 0, + wantErr: false, + }, + { + name: `Given_3_requests_include_1_without_browserVersion_ + When_5_existing_nodes_with_different_stereotypes_browserVersion_ + And_scaler_metadata_set_browserVersion_as_empty_ + Then_return_1_new_scale_and_1_ongoing`, + args: args{ + b: []byte(`{ + "data": { + "grid": { + "sessionCount": 4, + "maxSession": 5, + "totalSlots": 5 + }, + "nodesInfo": { + "nodes": [ + { + "id": "node-131", + "status": "UP", + "sessionCount": 1, + "maxSession": 1, + "slotCount": 1, + "stereotypes": "[{\"slots\": 1, \"stereotype\": {\"browserName\": \"chrome\", \"browserVersion\": \"131.0\", \"platformName\": \"linux\"}}]", + "sessions": [ + { + "id": "session-1", + "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"131.0\", \"platformName\": \"linux\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"chrome\", \"browserVersion\": \"131.0\", \"platformName\": \"linux\"}" + } + } + ] + }, + { + "id": "node-130", + "status": "UP", + "sessionCount": 0, + "maxSession": 1, + "slotCount": 1, + "stereotypes": "[{\"slots\": 1, \"stereotype\": {\"browserName\": \"chrome\", \"browserVersion\": \"130.0\", \"platformName\": \"linux\"}}]", + "sessions": [] + }, + { + "id": "node-129", + "status": "UP", + "sessionCount": 1, + "maxSession": 1, + "slotCount": 1, + "stereotypes": "[{\"slots\": 1, \"stereotype\": {\"browserName\": \"chrome\", \"browserVersion\": \"129.0\", \"platformName\": \"linux\"}}]", + "sessions": [ + { + "id": "session-1", + "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"129.0\", \"platformName\": \"linux\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"chrome\", \"browserVersion\": \"129.0\", \"platformName\": \"linux\"}" + } + } + ] + }, + { + "id": "node-128", + "status": "UP", + "sessionCount": 1, + "maxSession": 1, + "slotCount": 1, + "stereotypes": "[{\"slots\": 1, \"stereotype\": {\"browserName\": \"chrome\", \"browserVersion\": \"128.0\", \"platformName\": \"linux\"}}]", + "sessions": [ + { + "id": "session-1", + "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"128.0\", \"platformName\": \"linux\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"chrome\", \"browserVersion\": \"128.0\", \"platformName\": \"linux\"}" + } + } + ] + }, + { + "id": "node-any", + "status": "UP", + "sessionCount": 1, + "maxSession": 1, + "slotCount": 1, + "stereotypes": "[{\"slots\": 1, \"stereotype\": {\"browserName\": \"chrome\", \"browserVersion\": \"\", \"platformName\": \"linux\"}}]", + "sessions": [ + { + "id": "session-1", + "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"128.0\", \"platformName\": \"linux\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"chrome\", \"browserVersion\": \"\", \"platformName\": \"linux\"}" + } + } + ] + } + ] + }, + "sessionsInfo": { + "sessionQueueRequests": [ + "{\"browserName\": \"chrome\", \"platformName\": \"linux\"}", + "{\"browserName\": \"chrome\", \"platformName\": \"linux\", \"browserVersion\": \"131\"}", + "{\"browserName\": \"chrome\", \"platformName\": \"linux\", \"browserVersion\": \"130\"}" + ] + } + } + }`), + browserName: "chrome", + sessionBrowserName: "chrome", + browserVersion: "", + platformName: "linux", + }, + wantNewRequestNodes: 1, + wantOnGoingSessions: 1, + wantErr: false, + }, + { + name: `Given_3_requests_include_1_without_browserVersion_ + When_4_existing_nodes_with_different_stereotypes_browserVersion_ + And_scaler_metadata_set_browserVersion_130.0_ + Then_return_1_new_scale_and_0_ongoing`, + args: args{ + b: []byte(`{ + "data": { + "grid": { + "sessionCount": 4, + "maxSession": 4, + "totalSlots": 4 + }, + "nodesInfo": { + "nodes": [ + { + "id": "node-131", + "status": "UP", + "sessionCount": 1, + "maxSession": 1, + "slotCount": 1, + "stereotypes": "[{\"slots\": 1, \"stereotype\": {\"browserName\": \"chrome\", \"browserVersion\": \"131.0\", \"platformName\": \"linux\"}}]", + "sessions": [ + { + "id": "session-1", + "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"131.0\", \"platformName\": \"linux\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"chrome\", \"browserVersion\": \"131.0\", \"platformName\": \"linux\"}" + } + } + ] + }, + { + "id": "node-129", + "status": "UP", + "sessionCount": 1, + "maxSession": 1, + "slotCount": 1, + "stereotypes": "[{\"slots\": 1, \"stereotype\": {\"browserName\": \"chrome\", \"browserVersion\": \"129.0\", \"platformName\": \"linux\"}}]", + "sessions": [ + { + "id": "session-1", + "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"129.0\", \"platformName\": \"linux\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"chrome\", \"browserVersion\": \"129.0\", \"platformName\": \"linux\"}" + } + } + ] + }, + { + "id": "node-128", + "status": "UP", + "sessionCount": 1, + "maxSession": 1, + "slotCount": 1, + "stereotypes": "[{\"slots\": 1, \"stereotype\": {\"browserName\": \"chrome\", \"browserVersion\": \"128.0\", \"platformName\": \"linux\"}}]", + "sessions": [ + { + "id": "session-1", + "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"128.0\", \"platformName\": \"linux\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"chrome\", \"browserVersion\": \"128.0\", \"platformName\": \"linux\"}" + } + } + ] + }, + { + "id": "node-any", + "status": "UP", + "sessionCount": 1, + "maxSession": 1, + "slotCount": 1, + "stereotypes": "[{\"slots\": 1, \"stereotype\": {\"browserName\": \"chrome\", \"browserVersion\": \"\", \"platformName\": \"linux\"}}]", + "sessions": [ + { + "id": "session-1", + "capabilities": "{\"browserName\": \"chrome\", \"browserVersion\": \"128.0\", \"platformName\": \"linux\"}", + "slot": { + "id": "9ce1edba-72fb-465e-b311-ee473d8d7b64", + "stereotype": "{\"browserName\": \"chrome\", \"browserVersion\": \"\", \"platformName\": \"linux\"}" + } + } + ] + } + ] + }, + "sessionsInfo": { + "sessionQueueRequests": [ + "{\"browserName\": \"chrome\", \"platformName\": \"linux\"}", + "{\"browserName\": \"chrome\", \"platformName\": \"linux\", \"browserVersion\": \"131\"}", + "{\"browserName\": \"chrome\", \"platformName\": \"linux\", \"browserVersion\": \"130\"}" + ] + } + } + }`), + browserName: "chrome", + sessionBrowserName: "chrome", + browserVersion: "130.0", + platformName: "linux", + }, + wantNewRequestNodes: 1, + wantOnGoingSessions: 0, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + newRequestNodes, onGoingSessions, err := getCountFromSeleniumResponse(tt.args.b, tt.args.browserName, tt.args.browserVersion, tt.args.sessionBrowserName, tt.args.platformName, tt.args.nodeMaxSessions, logr.Discard()) + if (err != nil) != tt.wantErr { + t.Errorf("getCountFromSeleniumResponse() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(newRequestNodes, tt.wantNewRequestNodes) || !reflect.DeepEqual(onGoingSessions, tt.wantOnGoingSessions) { + t.Errorf("getCountFromSeleniumResponse() = [%v, %v], want [%v, %v]", newRequestNodes, onGoingSessions, tt.wantNewRequestNodes, tt.wantOnGoingSessions) + } + }) + } +} + +func Test_parseSeleniumGridScalerMetadata(t *testing.T) { + type args struct { + config *scalersconfig.ScalerConfig + } + tests := []struct { + name string + args args + want *seleniumGridScalerMetadata + wantErr bool + }{ + { + name: "invalid url string should throw error", + args: args{ + config: &scalersconfig.ScalerConfig{ + TriggerMetadata: map[string]string{}, + }, + }, + wantErr: true, + }, + { + name: "invalid browsername string should throw error", + args: args{ + config: &scalersconfig.ScalerConfig{ + TriggerMetadata: map[string]string{ + "url": "", + }, + }, + }, + wantErr: true, + }, + { + name: "valid url and browsername should return metadata", + args: args{ + config: &scalersconfig.ScalerConfig{ + TriggerMetadata: map[string]string{ + "url": "http://selenium-hub:4444/graphql", + "browserName": "chrome", + }, + }, + }, + wantErr: false, + want: &seleniumGridScalerMetadata{ + URL: "http://selenium-hub:4444/graphql", + BrowserName: "chrome", + SessionBrowserName: "chrome", + TargetValue: 1, + BrowserVersion: "", + PlatformName: "linux", + NodeMaxSessions: 1, + }, + }, + { + name: "valid url, browsername, and sessionbrowsername should return metadata", + args: args{ + config: &scalersconfig.ScalerConfig{ + TriggerMetadata: map[string]string{ + "url": "http://selenium-hub:4444/graphql", "browserName": "MicrosoftEdge", "sessionBrowserName": "msedge", }, @@ -1789,7 +2877,28 @@ func Test_parseSeleniumGridScalerMetadata(t *testing.T) { BrowserName: "MicrosoftEdge", SessionBrowserName: "msedge", TargetValue: 1, - BrowserVersion: "latest", + BrowserVersion: "", + PlatformName: "linux", + NodeMaxSessions: 1, + }, + }, + { + name: "can input browserName as empty", + args: args{ + config: &scalersconfig.ScalerConfig{ + TriggerMetadata: map[string]string{ + "url": "http://selenium-hub:4444/graphql", + "browserName": "", + }, + }, + }, + wantErr: false, + want: &seleniumGridScalerMetadata{ + URL: "http://selenium-hub:4444/graphql", + BrowserName: "", + SessionBrowserName: "", + TargetValue: 1, + BrowserVersion: "", PlatformName: "linux", NodeMaxSessions: 1, }, @@ -1817,7 +2926,7 @@ func Test_parseSeleniumGridScalerMetadata(t *testing.T) { BrowserName: "MicrosoftEdge", SessionBrowserName: "msedge", TargetValue: 1, - BrowserVersion: "latest", + BrowserVersion: "", PlatformName: "linux", NodeMaxSessions: 1, }, @@ -1843,7 +2952,7 @@ func Test_parseSeleniumGridScalerMetadata(t *testing.T) { BrowserName: "MicrosoftEdge", SessionBrowserName: "msedge", TargetValue: 1, - BrowserVersion: "latest", + BrowserVersion: "", PlatformName: "linux", Username: "username", Password: "password", diff --git a/tests/scalers/selenium/selenium_test.go b/tests/scalers/selenium/selenium_test.go index e540b1f74c8..6b68db82ad0 100644 --- a/tests/scalers/selenium/selenium_test.go +++ b/tests/scalers/selenium/selenium_test.go @@ -137,8 +137,11 @@ spec: spec: containers: - name: selenium-chrome-node - image: selenium/node-chrome:latest + image: selenium/node-chrome:nightly imagePullPolicy: IfNotPresent + env: + - name: SE_NODE_BROWSER_VERSION + value: '' envFrom: - configMapRef: name: selenium-event-bus-config @@ -255,8 +258,11 @@ spec: spec: containers: - name: selenium-firefox-node - image: selenium/node-firefox:latest + image: selenium/node-firefox:nightly imagePullPolicy: IfNotPresent + env: + - name: SE_NODE_BROWSER_VERSION + value: '' envFrom: - configMapRef: name: selenium-event-bus-config @@ -346,8 +352,11 @@ spec: spec: containers: - name: selenium-edge-node - image: selenium/node-edge:latest + image: selenium/node-edge:nightly imagePullPolicy: IfNotPresent + env: + - name: SE_NODE_BROWSER_VERSION + value: '' envFrom: - configMapRef: name: selenium-event-bus-config