diff --git a/Makefile b/Makefile index 18b732a21..32ef9cc2f 100644 --- a/Makefile +++ b/Makefile @@ -948,7 +948,7 @@ chart_test_autoscaling_deployment: ./tests/charts/make/chart_test.sh DeploymentAutoscaling chart_test_autoscaling_job_https: - PLATFORMS=$(PLATFORMS) TEST_EXISTING_KEDA=true RELEASE_NAME=selenium CHART_ENABLE_BASIC_AUTH=true SELENIUM_GRID_MONITORING=false TEST_PATCHED_KEDA=$(TEST_PATCHED_KEDA) \ + PLATFORMS=$(PLATFORMS) TEST_EXISTING_KEDA=true RELEASE_NAME=selenium CHART_ENABLE_BASIC_AUTH=true SELENIUM_GRID_MONITORING=false TEST_PATCHED_KEDA=$(TEST_PATCHED_KEDA) TEST_MULTIPLE_PLATFORMS=true \ SECURE_CONNECTION_SERVER=true SELENIUM_GRID_PROTOCOL=https SELENIUM_GRID_PORT=443 SUB_PATH=/ \ MAX_SESSIONS_FIREFOX=1 MAX_SESSIONS_EDGE=2 MAX_SESSIONS_CHROME=3 TEST_NAME_OVERRIDE=true \ VERSION=$(TAG_VERSION) VIDEO_TAG=$(FFMPEG_TAG_VERSION)-$(BUILD_DATE) KEDA_BASED_NAME=$(KEDA_BASED_NAME) KEDA_BASED_TAG=$(KEDA_BASED_TAG) NAMESPACE=$(NAMESPACE) BINDING_VERSION=$(BINDING_VERSION) BASE_VERSION=$(BASE_VERSION) EXTERNAL_UPLOADER_CONFIG=true \ @@ -956,7 +956,7 @@ chart_test_autoscaling_job_https: ./tests/charts/make/chart_test.sh JobAutoscaling chart_test_autoscaling_job_hostname: - PLATFORMS=$(PLATFORMS) CHART_ENABLE_TRACING=true CHART_ENABLE_BASIC_AUTH=true BASIC_AUTH_EMBEDDED_URL=true TEST_PATCHED_KEDA=$(TEST_PATCHED_KEDA) \ + PLATFORMS=$(PLATFORMS) CHART_ENABLE_TRACING=true CHART_ENABLE_BASIC_AUTH=true BASIC_AUTH_EMBEDDED_URL=true TEST_PATCHED_KEDA=$(TEST_PATCHED_KEDA) TEST_MULTIPLE_PLATFORMS=true \ SECURE_INGRESS_ONLY_DEFAULT=true SECURE_USE_EXTERNAL_CERT=true SELENIUM_GRID_PROTOCOL=https SELENIUM_GRID_HOST=$$(hostname -I | cut -d' ' -f1) SELENIUM_GRID_PORT=443 \ VERSION=$(TAG_VERSION) VIDEO_TAG=$(FFMPEG_TAG_VERSION)-$(BUILD_DATE) KEDA_BASED_NAME=$(KEDA_BASED_NAME) KEDA_BASED_TAG=$(KEDA_BASED_TAG) NAMESPACE=$(NAMESPACE) BINDING_VERSION=$(BINDING_VERSION) BASE_VERSION=$(BASE_VERSION) \ TEMPLATE_OUTPUT_FILENAME="k8s_enableTracing_basicAuth_secureIngress_externalCerts_ingressPublicIP_autoScaling_originKEDA_scaledJob_subPath.yaml" \ @@ -977,7 +977,7 @@ chart_test_autoscaling_job: ./tests/charts/make/chart_test.sh JobAutoscaling chart_test_autoscaling_playwright_connect_grid: - PLATFORMS=$(PLATFORMS) CHART_FULL_DISTRIBUTED_MODE=true CHART_ENABLE_BASIC_AUTH=true TEST_EXTERNAL_DATASTORE=redis MATRIX_TESTS=CDPTests TEST_PATCHED_KEDA=$(TEST_PATCHED_KEDA) \ + PLATFORMS=$(PLATFORMS) CHART_FULL_DISTRIBUTED_MODE=true CHART_ENABLE_BASIC_AUTH=true TEST_EXTERNAL_DATASTORE=redis MATRIX_TESTS=CDPTests TEST_PATCHED_KEDA=$(TEST_PATCHED_KEDA) TEST_MULTIPLE_PLATFORMS=true \ BASIC_AUTH_USERNAME=docker-selenium BASIC_AUTH_PASSWORD=2NMI4jdBi6k7bENoeUfV25295VvzwAE9chM24a+2VL95uOHozo \ SECURE_INGRESS_ONLY_DEFAULT=true SECURE_USE_EXTERNAL_CERT=true SELENIUM_GRID_PROTOCOL=https SELENIUM_GRID_HOST=$$(hostname -I | cut -d' ' -f1) SELENIUM_GRID_PORT=443 \ VERSION=$(TAG_VERSION) VIDEO_TAG=$(FFMPEG_TAG_VERSION)-$(BUILD_DATE) KEDA_BASED_NAME=$(KEDA_BASED_NAME) KEDA_BASED_TAG=$(KEDA_BASED_TAG) NAMESPACE=$(NAMESPACE) BINDING_VERSION=$(BINDING_VERSION) BASE_VERSION=$(BASE_VERSION) \ @@ -993,7 +993,7 @@ test_k8s_autoscaling_job_count_strategy_default_with_node_max_sessions: make test_k8s_autoscaling_job_count_strategy_default test_k8s_autoscaling_job_count_strategy_default: - MATRIX_TESTS=$(or $(MATRIX_TESTS), "AutoscalingTestsScaleUp") SCALING_STRATEGY=$(or $(SCALING_STRATEGY), "default") \ + MATRIX_TESTS=$(or $(MATRIX_TESTS), "AutoscalingTestsScaleUp") SCALING_STRATEGY=$(or $(SCALING_STRATEGY), "default") TEST_MULTIPLE_PLATFORMS=true \ PLATFORMS=$(PLATFORMS) RELEASE_NAME=selenium TEST_PATCHED_KEDA=$(TEST_PATCHED_KEDA) SELENIUM_GRID_PROTOCOL=http SELENIUM_GRID_HOST=localhost SELENIUM_GRID_PORT=80 \ SELENIUM_GRID_MONITORING=false CLEAR_POD_HISTORY=true SET_MAX_REPLICAS=100 ENABLE_VIDEO_RECORDER=false \ VERSION=$(TAG_VERSION) VIDEO_TAG=$(FFMPEG_TAG_VERSION)-$(BUILD_DATE) KEDA_BASED_NAME=$(KEDA_BASED_NAME) KEDA_BASED_TAG=$(KEDA_BASED_TAG) NAMESPACE=$(NAMESPACE) BINDING_VERSION=$(BINDING_VERSION) BASE_VERSION=$(BASE_VERSION) \ @@ -1008,7 +1008,7 @@ test_k8s_autoscaling_deployment_count_with_node_max_sessions: make test_k8s_autoscaling_deployment_count test_k8s_autoscaling_deployment_count: - MATRIX_TESTS=$(or $(MATRIX_TESTS), "AutoscalingTestsScaleUp") \ + MATRIX_TESTS=$(or $(MATRIX_TESTS), "AutoscalingTestsScaleUp") TEST_MULTIPLE_PLATFORMS=true \ PLATFORMS=$(PLATFORMS) RELEASE_NAME=selenium TEST_PATCHED_KEDA=$(TEST_PATCHED_KEDA) SELENIUM_GRID_PROTOCOL=http SELENIUM_GRID_HOST=localhost SELENIUM_GRID_PORT=80 \ SELENIUM_GRID_MONITORING=false CLEAR_POD_HISTORY=true SET_MAX_REPLICAS=100 ENABLE_VIDEO_RECORDER=false \ VERSION=$(TAG_VERSION) VIDEO_TAG=$(FFMPEG_TAG_VERSION)-$(BUILD_DATE) KEDA_BASED_NAME=$(KEDA_BASED_NAME) KEDA_BASED_TAG=$(KEDA_BASED_TAG) NAMESPACE=$(NAMESPACE) BINDING_VERSION=$(BINDING_VERSION) BASE_VERSION=$(BASE_VERSION) \ diff --git a/charts/selenium-grid/CONFIGURATION.md b/charts/selenium-grid/CONFIGURATION.md index 785a459af..ba32f6f0e 100644 --- a/charts/selenium-grid/CONFIGURATION.md +++ b/charts/selenium-grid/CONFIGURATION.md @@ -423,10 +423,10 @@ A Helm chart for creating a Selenium Grid Server in Kubernetes | chromeNode.scaledOptions | string | `nil` | Override the scaled options for chrome nodes | | chromeNode.scaledJobOptions | string | `nil` | Override the scaledJobOptions for chrome nodes | | chromeNode.scaledObjectOptions | string | `nil` | Override the scaledObjectOptions for chrome nodes | -| chromeNode.hpa.browserName | string | `"chrome"` | browserName from the capability | +| chromeNode.hpa.browserName | string | `"chrome"` | browserName should match with Node stereotype and request capability is scaled by this scaler | | chromeNode.hpa.sessionBrowserName | string | `"chrome"` | sessionBrowserName if the browserName is different from the sessionBrowserName | -| chromeNode.hpa.browserVersion | string | `""` | browserVersion from the capability | -| chromeNode.hpa.platformName | string | `"Linux"` | platformName from the capability | +| chromeNode.hpa.browserVersion | string | `""` | browserVersion should match with Node stereotype and request capability is scaled by this scaler | +| chromeNode.hpa.platformName | string | `""` | platformName should match with Node stereotype and request capability is scaled by this scaler | | chromeNode.hpa.unsafeSsl | string | `"{{ template \"seleniumGrid.graphqlURL.unsafeSsl\" . }}"` | Skip check SSL when connecting to the Graphql endpoint | | chromeNode.initContainers | list | `[]` | It is used to add initContainers in the same pod of the browser node. It should be set using the --set-json option | | chromeNode.sidecars | list | `[]` | It is used to add sidecars proxy in the same pod of the browser node. It means it will add a new container to the deployment itself. It should be set using the --set-json option | @@ -475,10 +475,10 @@ A Helm chart for creating a Selenium Grid Server in Kubernetes | firefoxNode.scaledOptions | string | `nil` | Override the scaled options for firefox nodes | | firefoxNode.scaledJobOptions | string | `nil` | Override the scaledJobOptions for firefox nodes | | firefoxNode.scaledObjectOptions | string | `nil` | Override the scaledObjectOptions for firefox nodes | -| firefoxNode.hpa.browserName | string | `"firefox"` | browserName from the capability | +| firefoxNode.hpa.browserName | string | `"firefox"` | browserName should match with Node stereotype and request capability is scaled by this scaler | | firefoxNode.hpa.sessionBrowserName | string | `"firefox"` | sessionBrowserName if the browserName is different from the sessionBrowserName | -| firefoxNode.hpa.browserVersion | string | `""` | browserVersion from the capability | -| firefoxNode.hpa.platformName | string | `"Linux"` | platformName from the capability | +| firefoxNode.hpa.browserVersion | string | `""` | browserVersion should match with Node stereotype and request capability is scaled by this scaler | +| firefoxNode.hpa.platformName | string | `""` | platformName should match with Node stereotype and request capability is scaled by this scaler | | firefoxNode.hpa.unsafeSsl | string | `"{{ template \"seleniumGrid.graphqlURL.unsafeSsl\" . }}"` | Skip check SSL when connecting to the Graphql endpoint | | firefoxNode.initContainers | list | `[]` | It is used to add initContainers in the same pod of the browser node. It should be set using the --set-json option | | firefoxNode.sidecars | list | `[]` | It is used to add sidecars proxy in the same pod of the browser node. It means it will add a new container to the deployment itself. It should be set using the --set-json option | @@ -527,10 +527,10 @@ A Helm chart for creating a Selenium Grid Server in Kubernetes | edgeNode.scaledOptions | string | `nil` | Override the scaled options for edge nodes | | edgeNode.scaledJobOptions | string | `nil` | Override the scaledJobOptions for edge nodes | | edgeNode.scaledObjectOptions | string | `nil` | Override the scaledObjectOptions for edge nodes | -| edgeNode.hpa.browserName | string | `"MicrosoftEdge"` | browserName from the capability | +| edgeNode.hpa.browserName | string | `"MicrosoftEdge"` | browserName should match with Node stereotype and request capability is scaled by this scaler | | edgeNode.hpa.sessionBrowserName | string | `"msedge"` | sessionBrowserName if the browserName is different from the sessionBrowserName | -| edgeNode.hpa.browserVersion | string | `""` | browserVersion from the capability | -| edgeNode.hpa.platformName | string | `"Linux"` | platformName from the capability | +| edgeNode.hpa.browserVersion | string | `""` | browserVersion should match with Node stereotype and request capability is scaled by this scaler | +| edgeNode.hpa.platformName | string | `""` | platformName should match with Node stereotype and request capability is scaled by this scaler | | edgeNode.hpa.unsafeSsl | string | `"{{ template \"seleniumGrid.graphqlURL.unsafeSsl\" . }}"` | Skip check SSL when connecting to the Graphql endpoint | | edgeNode.initContainers | list | `[]` | It is used to add initContainers in the same pod of the browser node. It should be set using the --set-json option | | edgeNode.sidecars | list | `[]` | It is used to add sidecars proxy in the same pod of the browser node. It means it will add a new container to the deployment itself. It should be set using the --set-json option | @@ -579,10 +579,10 @@ A Helm chart for creating a Selenium Grid Server in Kubernetes | relayNode.scaledOptions | string | `nil` | Override the scaled options for relay nodes | | relayNode.scaledJobOptions | string | `nil` | Override the scaledJobOptions for relay nodes | | relayNode.scaledObjectOptions | string | `nil` | Override the scaledObjectOptions for relay nodes | -| relayNode.hpa.browserName | string | `"chrome"` | browserName from the capability | +| relayNode.hpa.browserName | string | `"chrome"` | browserName should match with Node stereotype and request capability is scaled by this scaler | | relayNode.hpa.sessionBrowserName | string | `""` | sessionBrowserName if the browserName is different from the sessionBrowserName | -| relayNode.hpa.platformName | string | `"Android"` | platformName from the capability | -| relayNode.hpa.browserVersion | string | `""` | browserVersion from the capability | +| relayNode.hpa.browserVersion | string | `""` | browserVersion should match with Node stereotype and request capability is scaled by this scaler | +| relayNode.hpa.platformName | string | `"Android"` | platformName should match with Node stereotype and request capability is scaled by this scaler | | relayNode.hpa.unsafeSsl | string | `"{{ template \"seleniumGrid.graphqlURL.unsafeSsl\" . }}"` | Skip check SSL when connecting to the Graphql endpoint | | relayNode.initContainers | list | `[]` | It is used to add initContainers in the same pod of the browser node. It should be set using the --set-json option | | relayNode.sidecars | list | `[]` | It is used to add sidecars proxy in the same pod of the browser node. It means it will add a new container to the deployment itself. It should be set using the --set-json option | diff --git a/charts/selenium-grid/README.md b/charts/selenium-grid/README.md index b72d9ebff..b7936bd51 100644 --- a/charts/selenium-grid/README.md +++ b/charts/selenium-grid/README.md @@ -15,6 +15,7 @@ This chart enables the creation of a Selenium Grid Server in Kubernetes. * [Settings common for both `job` and `deployment` scalingType](#settings-common-for-both-job-and-deployment-scalingtype) * [Settings when scalingType with `deployment`](#settings-when-scalingtype-with-deployment-) * [Settings when scalingType with `job`](#settings-when-scalingtype-with-job) + * [Scaler trigger configuration](#scaler-trigger-configuration) * [Settings fixed-sized thread pool for the Distributor to create new sessions](#settings-fixed-sized-thread-pool-for-the-distributor-to-create-new-sessions) * [Updating Selenium-Grid release](#updating-selenium-grid-release) * [Uninstalling Selenium Grid release](#uninstalling-selenium-grid-release) @@ -210,6 +211,141 @@ autoscaling: Settings that KEDA [ScaledJob spec](https://keda.sh/docs/latest/concepts/scaling-jobs/#scaledjob-spec) supports can be set via `autoscaling.scaledJobOptions`. +Expected that with default configuration in KEDA resource, autoscaling behavior should be correct. Hence, in chart values, we keep the config key `autoscaling.scaledJobOptions.scalingStrategy.strategy` is `default`. + +### Scaler trigger configuration + +From KEDA core `v2.16.1+`, the trigger metadata `browserVersion`, `platformName` is recommended to be set explicitly to have the correct scaling behavior (especially when your Grid includes autoscaling Nodes, non-autoscaling Nodes, relay Nodes, etc.). Besides that, in client binding, it is also recommended to set the `browserVersion`, `platformName` to align with the trigger metadata. Please see below examples for more details. + +Understand list trigger parameters + +- `url` - Graphql url of your Selenium Grid. If endpoint requires authentication, you can use `TriggerAuthentication` to provide the credentials instead of embedding in the URL. +- `browserName` - browserName should match with Node stereotype and request capability is scaled by this scaler. (Default: ``, Optional) +- `sessionBrowserName` - sessionBrowserName if the browserName is different from the sessionBrowserName. (Default: ``, Optional) +- `browserVersion` - browserVersion should match with Node stereotype and request capability is scaled by this scaler. (Default: ``, Optional) +- `platformName` - platformName should match with Node stereotype and request capability is scaled by this scaler. (Default: ``, Optional) +- `unsafeSsl` - Skip certificate validation when connecting over HTTPS. (Default: `false`, Optional) +- `activationThreshold` - Target value for activating the scaler. Learn more about activation [here](./../concepts/scaling-deployments.md#activating-and-scaling-thresholds). (Default: `0`, Optional) +- `nodeMaxSessions` - Number of maximum sessions that can run in parallel on a Node. Update this parameter align with node config `--max-sessions` (`SE_NODE_MAX_SESSIONS`) to have the correct scaling behavior. (Default: `1`, Optional). + +Understand list trigger authentication + +- `username` - Username for basic authentication in GraphQL endpoint instead of embedding in the URL. (Optional) +- `password` - Password for basic authentication in GraphQL endpoint instead of embedding in the URL. (Optional) +- `authType` - Type of authentication to be used. This can be set to `Bearer` or `OAuth2` in case Selenium Grid behind an Ingress proxy with other authentication types. (Optional) +- `accessToken` - Access token. This is required when `authType` is set a value. (Optional) + +In each Node, trigger parameters value will be set under config key `hpa`. In template, those will be added spec of ScaledObject/ScaledJob. + +In chart values, by default, `browserName`, `sessionBrowserName` are set for corresponding node browser. Parameters `browserVersion`, `platformName` are not set, leave them as empty by default. The default scaler metadata looks like + +```yaml + triggers: + - type: selenium-grid + metadata: + url: 'http://selenium-hub:4444/graphql' + browserName: 'chrome' + browserVersion: '' + platformName: '' +``` + +In this case, the scaler will be triggered by below request (example in Python client, common use case that most users get started) + +```python +options = ChromeOptions() +driver = webdriver.Remote(options=options, command_executor=SELENIUM_GRID_URL) +``` + +With above script, the request is sent to Grid. Via GraphQL response, it looks like + +```json +{ + "data": { + "grid": { + "sessionCount": 0, + "maxSession": 0, + "totalSlots": 0 + }, + "nodesInfo": { + "nodes": [] + }, + "sessionsInfo": { + "sessionQueueRequests": [ + "{\"browserName\": \"chrome\"}" + ] + } + } +} +``` + +Scaler will trigger to scale up the Node with stereotypes matched to pick up the request in the queue. Via GraphQL response, it looks like + +```json +{ + "data": { + "grid": { + "sessionCount": 0, + "maxSession": 1, + "totalSlots": 1 + }, + "nodesInfo": { + "nodes": [ + { + "id": "UUID", + "status": "UP", + "sessionCount": 0, + "maxSession": 1, + "slotCount": 1, + "stereotypes": "[{\"slots\": 1, \"stereotype\": {\"browserName\": \"chrome\", \"browserVersion\": \"\", \"platformName\": \"\"}}]", + "sessions": [] + } + ] + }, + "sessionsInfo": { + "sessionQueueRequests": [ + "{\"browserName\": \"chrome\"}" + ] + } + } +} +``` + +In Node deployment spec, there is environment variable `SE_NODE_BROWSER_VERSION` which is able to unset `browserVersion` in Node stereotypes (it is setting short browser build number by default e.g `131.0`) or any custom value is up to you, which is expected to match with the request capabilities in queue and scaler trigger metadata. +Similarly, `SE_NODE_PLATFORM_NAME` is used to unset the `platformName` in Node stereotypes if needed. Noted, update to newer image tag if these 2 env variables doesn't take effect for you. + +For another example, where your Grid with multiple scalers have different metadata, one of them looks like + +```yaml + triggers: + - type: selenium-grid + metadata: + url: 'http://selenium-hub:4444/graphql' + browserName: 'chrome' + browserVersion: '131.0' + platformName: 'Linux' +``` + + +The request to trigger this corresponds to the following Python script + +```python +options = ChromeOptions() +options.set_capability('platformName', 'Linux') +options.set_capability('browserVersion', '131.0') +driver = webdriver.Remote(options=options, command_executor=SELENIUM_GRID_URL) +``` + +### Define multiple scalers with different trigger parameters. +When deploying the chart, you can define multiple scalers with different trigger parameters to scale up different Node stereotypes against different request capabilities. + +Under config key `crossBrowsers`, in corresponding browser node, you can define array of item with structure same as that node, via `nameOverride` to set unique name for each scaler to avoid resources collision. + +For example [multiple-nodes-platform.yaml](./multiple-nodes-platform.yaml) file, it defines 2 scalers per browser node to scale against requests with and without `platformName` capability. + +For example [multiple-nodes-platform-version.yaml](./multiple-nodes-platform-version.yaml) file, it defines multiple scalers with `platformName: 'Linux'` and last few previous stable versions per browser node to scale against requests with `browserVersion` and `platformName` capabilities. + +While deploying the chart, you can quickly use these extra values files by passing the file via `--values` flag to apply. + ### Settings fixed-sized thread pool for the Distributor to create new sessions When enabling autoscaling, the Distributor might be under a high workload with parallelism tests, which are many requests incoming and nodes scaling up simultaneously. (Refer to: [SeleniumHQ/selenium#13723](https://github.com/SeleniumHQ/selenium/issues/13723)). diff --git a/charts/selenium-grid/cross-browsers-values.yaml b/charts/selenium-grid/multiple-nodes-platform-version.yaml similarity index 63% rename from charts/selenium-grid/cross-browsers-values.yaml rename to charts/selenium-grid/multiple-nodes-platform-version.yaml index 4de496387..f58437d14 100644 --- a/charts/selenium-grid/cross-browsers-values.yaml +++ b/charts/selenium-grid/multiple-nodes-platform-version.yaml @@ -1,72 +1,97 @@ +# Specify both platformName: 'Linux' and browserVersion in scaler metadata if the Grid deployment with +# multiple Nodes autoscaling require different trigger metadata and non-autoscaling Nodes in different stereotypes +# +# For example: below incoming requests will be scaled by one scaler which is matched. +# options = ChromeOptions() +# options.set_capability('platformName', 'Linux') +# options.set_capability('browserVersion', '131.0') +# driver = webdriver.Remote(options=options, command_executor=SELENIUM_GRID_URL) crossBrowsers: chromeNode: # Keep the first iteration with latest version of Chrome - - nameOverride: + - nameOverride: '{{ $.Release.Name }}-node-chrome-latest' hpa: + platformName: 'Linux' browserVersion: '' - nameOverride: '{{ $.Release.Name }}-node-chrome-131' imageTag: '131.0' hpa: + platformName: 'Linux' browserVersion: '131.0' - nameOverride: '{{ $.Release.Name }}-node-chrome-130' imageTag: '130.0' hpa: + platformName: 'Linux' browserVersion: '130.0' - nameOverride: '{{ $.Release.Name }}-node-chrome-129' imageTag: '129.0' hpa: + platformName: 'Linux' browserVersion: '129.0' - nameOverride: '{{ $.Release.Name }}-node-chrome-128' imageTag: '128.0' hpa: + platformName: 'Linux' browserVersion: '128.0' firefoxNode: # Keep the first iteration with latest version of Firefox - - nameOverride: + - nameOverride: '{{ $.Release.Name }}-node-firefox-latest' hpa: + platformName: 'Linux' browserVersion: '' - nameOverride: '{{ $.Release.Name }}-node-firefox-133' imageTag: '133.0' hpa: + platformName: 'Linux' browserVersion: '133.0' - nameOverride: '{{ $.Release.Name }}-node-firefox-132' imageTag: '132.0' hpa: + platformName: 'Linux' browserVersion: '132.0' - nameOverride: '{{ $.Release.Name }}-node-firefox-131' imageTag: '131.0' hpa: + platformName: 'Linux' browserVersion: '131.0' - nameOverride: '{{ $.Release.Name }}-node-firefox-130' imageTag: '130.0' hpa: + platformName: 'Linux' browserVersion: '130.0' - nameOverride: '{{ $.Release.Name }}-node-firefox-129' imageTag: '129.0' hpa: + platformName: 'Linux' browserVersion: '129.0' - nameOverride: '{{ $.Release.Name }}-node-firefox-128' imageTag: '128.0' hpa: + platformName: 'Linux' browserVersion: '128.0' edgeNode: # Keep the first iteration with latest version of Edge - - nameOverride: + - nameOverride: '{{ $.Release.Name }}-node-edge-latest' hpa: + platformName: 'Linux' browserVersion: '' - nameOverride: '{{ $.Release.Name }}-node-edge-131' imageTag: '131.0' hpa: + platformName: 'Linux' browserVersion: '131.0' - nameOverride: '{{ $.Release.Name }}-node-edge-130' imageTag: '130.0' hpa: + platformName: 'Linux' browserVersion: '130.0' - nameOverride: '{{ $.Release.Name }}-node-edge-129' imageTag: '129.0' hpa: + platformName: 'Linux' browserVersion: '129.0' - nameOverride: '{{ $.Release.Name }}-node-edge-128' imageTag: '128.0' hpa: + platformName: 'Linux' browserVersion: '128.0' diff --git a/charts/selenium-grid/multiple-nodes-platform.yaml b/charts/selenium-grid/multiple-nodes-platform.yaml new file mode 100644 index 000000000..b6e83424b --- /dev/null +++ b/charts/selenium-grid/multiple-nodes-platform.yaml @@ -0,0 +1,39 @@ +# In this case, each browser node has 2 scaler triggers, one for any platform and one for specific Linux. +# +# For example: +# Below incoming request will only trigger the scaler platform any. +# options = ChromeOptions() +# driver = webdriver.Remote(options=options, command_executor=SELENIUM_GRID_URL) +# +# Below incoming request will only trigger the scaler platform Linux. +# options = ChromeOptions() +# options.set_capability('platformName', 'Linux') +# driver = webdriver.Remote(options=options, command_executor=SELENIUM_GRID_URL) +crossBrowsers: + chromeNode: + - nameOverride: '{{ $.Release.Name }}-node-chrome-platform-any' + hpa: + platformName: '' + browserVersion: '' + - nameOverride: '{{ $.Release.Name }}-node-chrome-platform-linux' + hpa: + platformName: 'Linux' + browserVersion: '' + firefoxNode: + - nameOverride: '{{ $.Release.Name }}-node-chrome-platform-any' + hpa: + platformName: '' + browserVersion: '' + - nameOverride: '{{ $.Release.Name }}-node-firefox-platform-linux' + hpa: + platformName: 'Linux' + browserVersion: '' + edgeNode: + - nameOverride: '{{ $.Release.Name }}-node-edge-platform-any' + hpa: + platformName: '' + browserVersion: '' + - nameOverride: '{{ $.Release.Name }}-node-edge-platform-linux' + hpa: + platformName: 'Linux' + browserVersion: '' diff --git a/charts/selenium-grid/values.yaml b/charts/selenium-grid/values.yaml index 97bcc0fb4..0dfe3be98 100644 --- a/charts/selenium-grid/values.yaml +++ b/charts/selenium-grid/values.yaml @@ -975,15 +975,15 @@ crossBrowsers: # -- Additional chrome nodes, array of objects with the same structure as `chromeNode` chromeNode: - nameOverride: - # - Refer to file `cross-browsers-values.yaml` to configure additional nodes + # - Refer to file `multiple-nodes-platform-version.yaml` to configure additional nodes # -- Additional firefox nodes, array of objects with the same structure as `firefoxNode` firefoxNode: - nameOverride: - # - Refer to file `cross-browsers-values.yaml` to configure additional node browsers + # - Refer to file `multiple-nodes-platform-version.yaml` to configure additional node browsers # -- Additional edge nodes, array of objects with the same structure as `edgeNode` edgeNode: - nameOverride: - # - Refer to file `cross-browsers-values.yaml` to configure additional node browsers + # - Refer to file `multiple-nodes-platform-version.yaml` to configure additional node browsers # -- Additional release nodes, array of objects with the same structure as `relayNode` relayNode: - nameOverride: @@ -1150,14 +1150,14 @@ chromeNode: # -- Override the scaledObjectOptions for chrome nodes scaledObjectOptions: hpa: - # -- browserName from the capability + # -- browserName should match with Node stereotype and request capability is scaled by this scaler browserName: "chrome" # -- sessionBrowserName if the browserName is different from the sessionBrowserName sessionBrowserName: "chrome" - # -- browserVersion from the capability + # -- browserVersion should match with Node stereotype and request capability is scaled by this scaler browserVersion: "" - # -- platformName from the capability - platformName: "Linux" + # -- platformName should match with Node stereotype and request capability is scaled by this scaler + platformName: "" # browserVersion: '91.0' # Optional. Only required when supporting multiple versions of browser in your Selenium Grid. # -- Skip check SSL when connecting to the Graphql endpoint unsafeSsl: '{{ template "seleniumGrid.graphqlURL.unsafeSsl" . }}' # Optional @@ -1335,14 +1335,14 @@ firefoxNode: # -- Override the scaledObjectOptions for firefox nodes scaledObjectOptions: hpa: - # -- browserName from the capability + # -- browserName should match with Node stereotype and request capability is scaled by this scaler browserName: "firefox" # -- sessionBrowserName if the browserName is different from the sessionBrowserName sessionBrowserName: "firefox" - # -- browserVersion from the capability + # -- browserVersion should match with Node stereotype and request capability is scaled by this scaler browserVersion: "" - # -- platformName from the capability - platformName: "Linux" + # -- platformName should match with Node stereotype and request capability is scaled by this scaler + platformName: "" # -- Skip check SSL when connecting to the Graphql endpoint unsafeSsl: '{{ template "seleniumGrid.graphqlURL.unsafeSsl" . }}' # Optional @@ -1519,14 +1519,14 @@ edgeNode: # -- Override the scaledObjectOptions for edge nodes scaledObjectOptions: hpa: - # -- browserName from the capability + # -- browserName should match with Node stereotype and request capability is scaled by this scaler browserName: "MicrosoftEdge" # -- sessionBrowserName if the browserName is different from the sessionBrowserName sessionBrowserName: "msedge" - # -- browserVersion from the capability + # -- browserVersion should match with Node stereotype and request capability is scaled by this scaler browserVersion: "" - # -- platformName from the capability - platformName: "Linux" + # -- platformName should match with Node stereotype and request capability is scaled by this scaler + platformName: "" # -- Skip check SSL when connecting to the Graphql endpoint unsafeSsl: '{{ template "seleniumGrid.graphqlURL.unsafeSsl" . }}' # Optional @@ -1703,15 +1703,14 @@ relayNode: # -- Override the scaledObjectOptions for relay nodes scaledObjectOptions: hpa: - # -- browserName from the capability + # -- browserName should match with Node stereotype and request capability is scaled by this scaler browserName: "chrome" # -- sessionBrowserName if the browserName is different from the sessionBrowserName sessionBrowserName: "" - # -- platformName from the capability - platformName: "Android" - # -- browserVersion from the capability + # -- browserVersion should match with Node stereotype and request capability is scaled by this scaler browserVersion: "" - # browserVersion: '91.0' # Optional. Only required when supporting multiple versions of browser in your Selenium Grid. + # -- platformName should match with Node stereotype and request capability is scaled by this scaler + platformName: "Android" # -- Skip check SSL when connecting to the Graphql endpoint unsafeSsl: '{{ template "seleniumGrid.graphqlURL.unsafeSsl" . }}' # Optional diff --git a/tests/SeleniumTests/__init__.py b/tests/SeleniumTests/__init__.py index aee7d5b26..9fcb5f6dd 100644 --- a/tests/SeleniumTests/__init__.py +++ b/tests/SeleniumTests/__init__.py @@ -32,9 +32,11 @@ TEST_ADD_CAPS_RECORD_VIDEO = os.environ.get('TEST_ADD_CAPS_RECORD_VIDEO', 'true').lower() == 'true' TEST_CUSTOM_SPECIFIC_NAME = os.environ.get('TEST_CUSTOM_SPECIFIC_NAME', 'false').lower() == 'true' TEST_MULTIPLE_VERSIONS = os.environ.get('TEST_MULTIPLE_VERSIONS', 'false').lower() == 'true' +TEST_MULTIPLE_PLATFORMS = os.environ.get('TEST_MULTIPLE_PLATFORMS', 'false').lower() == 'true' TEST_MULTIPLE_VERSIONS_EXPLICIT = os.environ.get('TEST_MULTIPLE_VERSIONS_EXPLICIT', 'true').lower() == 'true' LIST_CHROMIUM_VERSIONS = ['130.0', '129.0', '128.0'] LIST_FIREFOX_VERSIONS = ['132.0', '131.0', '130.0', '129.0', '128.0'] +LIST_PLATFORMS = ['Linux', None] if not TEST_MULTIPLE_VERSIONS_EXPLICIT: LIST_CHROMIUM_VERSIONS.append(None) @@ -165,6 +167,7 @@ def setUp(self): browser_version = random.choice(LIST_CHROMIUM_VERSIONS) if browser_version: options.set_capability('browserVersion', browser_version) + options.set_capability('platformName', 'Linux') if TEST_NODE_RELAY == 'Android': options.set_capability('platformName', TEST_NODE_RELAY) options.set_capability('appium:platformVersion', TEST_ANDROID_PLATFORM_API) @@ -176,8 +179,10 @@ def setUp(self): options.set_capability('appium:appWaitDuration', 120000) options.set_capability('appium:suppressKillServer', True) options.set_capability('appium:allowDelayAdb', False) - else: - options.set_capability('platformName', 'Linux') + if TEST_MULTIPLE_PLATFORMS: + platform_name = random.choice(LIST_PLATFORMS) + if platform_name: + options.set_capability('platformName', platform_name) start_time = time.time() self.driver = webdriver.Remote( options=options, @@ -211,7 +216,11 @@ def setUp(self): browser_version = random.choice(LIST_CHROMIUM_VERSIONS) if browser_version: options.set_capability('browserVersion', browser_version) - options.set_capability('platformName', 'Linux') + options.set_capability('platformName', 'Linux') + if TEST_MULTIPLE_PLATFORMS: + platform_name = random.choice(LIST_PLATFORMS) + if platform_name: + options.set_capability('platformName', platform_name) start_time = time.time() self.driver = webdriver.Remote( options=options, @@ -250,7 +259,11 @@ def setUp(self): browser_version = random.choice(LIST_FIREFOX_VERSIONS) if browser_version: options.set_capability('browserVersion', browser_version) - options.set_capability('platformName', 'Linux') + options.set_capability('platformName', 'Linux') + if TEST_MULTIPLE_PLATFORMS: + platform_name = random.choice(LIST_PLATFORMS) + if platform_name: + options.set_capability('platformName', platform_name) start_time = time.time() self.driver = webdriver.Remote( options=options, diff --git a/tests/charts/bootstrap.sh b/tests/charts/bootstrap.sh index 60f3aacc0..653342bf2 100755 --- a/tests/charts/bootstrap.sh +++ b/tests/charts/bootstrap.sh @@ -18,7 +18,6 @@ helm package charts/selenium-grid --version 1.0.0-SNAPSHOT -d tests/tests RELEASE_NAME="selenium" helm template ${RELEASE_NAME} --values tests/charts/templates/render/dummy.yaml \ - --values charts/selenium-grid/cross-browsers-values.yaml \ --set-file 'nodeConfigMap.extraScripts.setFromCommand\.sh=tests/charts/templates/render/dummy_external.sh' \ --set-file 'recorderConfigMap.extraScripts.setFromCommand\.sh=tests/charts/templates/render/dummy_external.sh' \ --set-file 'uploaderConfigMap.extraScripts.setFromCommand\.sh=tests/charts/templates/render/dummy_external.sh' \ @@ -38,7 +37,6 @@ helm package tests/charts/umbrella-charts --version 1.0.0-SNAPSHOT -d tests/test RELEASE_NAME="test" helm template ${RELEASE_NAME} --values tests/charts/templates/render/dummy_solution.yaml \ - --values charts/selenium-grid/cross-browsers-values.yaml \ --set-file 'selenium-grid.nodeConfigMap.extraScripts.setFromCommand\.sh=tests/charts/templates/render/dummy_external.sh' \ --set-file 'selenium-grid.recorderConfigMap.extraScripts.setFromCommand\.sh=tests/charts/templates/render/dummy_external.sh' \ --set-file 'selenium-grid.uploaderConfigMap.extraScripts.setFromCommand\.sh=tests/charts/templates/render/dummy_external.sh' \ diff --git a/tests/charts/make/chart_test.sh b/tests/charts/make/chart_test.sh index 55fdddde4..5535610be 100755 --- a/tests/charts/make/chart_test.sh +++ b/tests/charts/make/chart_test.sh @@ -65,6 +65,7 @@ SELENIUM_GRID_MONITORING=${SELENIUM_GRID_MONITORING:-"true"} TEST_EXISTING_PTS=${TEST_EXISTING_PTS:-"false"} TEST_MULTIPLE_VERSIONS=${TEST_MULTIPLE_VERSIONS:-"false"} TEST_MULTIPLE_VERSIONS_EXPLICIT=${TEST_MULTIPLE_VERSIONS_EXPLICIT:-"true"} +TEST_MULTIPLE_PLATFORMS=${TEST_MULTIPLE_PLATFORMS:-"false"} cleanup() { # Get the list of pods @@ -390,7 +391,11 @@ fi if [ "${TEST_MULTIPLE_VERSIONS}" = "true" ]; then HELM_COMMAND_SET_BASE_VALUES="${HELM_COMMAND_SET_BASE_VALUES} \ - --values ${CHART_PATH}/cross-browsers-values.yaml \ + --values ${CHART_PATH}/multiple-nodes-platform-version.yaml \ + " +elif [ "${TEST_MULTIPLE_PLATFORMS}" = "true" ]; then + HELM_COMMAND_SET_BASE_VALUES="${HELM_COMMAND_SET_BASE_VALUES} \ + --values ${CHART_PATH}/multiple-nodes-platform.yaml \ " fi @@ -470,6 +475,7 @@ export TEST_NODE_MAX_SESSIONS=${TEST_NODE_MAX_SESSIONS} export TEST_AUTOSCALING_ITERATIONS=${TEST_AUTOSCALING_ITERATIONS:-"20"} export TEST_MULTIPLE_VERSIONS=${TEST_MULTIPLE_VERSIONS} export TEST_MULTIPLE_VERSIONS_EXPLICIT=${TEST_MULTIPLE_VERSIONS_EXPLICIT} +export TEST_MULTIPLE_PLATFORMS=${TEST_MULTIPLE_PLATFORMS} if [ "${MATRIX_BROWSER}" = "NoAutoscaling" ]; then ./tests/bootstrap.sh NodeFirefox if [ "${TEST_PLATFORMS}" = "linux/amd64" ]; then