Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/trunk' into py_client_config_new
Browse files Browse the repository at this point in the history
Signed-off-by: Viet Nguyen Duc <[email protected]>

# Conflicts:
#	py/selenium/webdriver/remote/remote_connection.py
#	py/selenium/webdriver/remote/webdriver.py
  • Loading branch information
VietND96 committed Oct 24, 2024
2 parents 9f21342 + 833efa9 commit dbe23c5
Show file tree
Hide file tree
Showing 36 changed files with 4,889 additions and 1,251 deletions.
1 change: 1 addition & 0 deletions .github/workflows/ci-dotnet.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@ jobs:
java-version: 17
os: windows
run: |
fsutil 8dot3name set 0
bazel test //dotnet/test/common:ElementFindingTest-firefox //dotnet/test/common:ElementFindingTest-chrome --pin_browsers=true
1 change: 1 addition & 0 deletions .github/workflows/ci-java.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ jobs:
# https://github.com/bazelbuild/rules_jvm_external/issues/1046
java-version: 17
run: |
fsutil 8dot3name set 0
bazel test --flaky_test_attempts 3 //java/test/org/openqa/selenium/chrome:ChromeDriverFunctionalTest `
//java/test/org/openqa/selenium/federatedcredentialmanagement:FederatedCredentialManagementTest `
//java/test/org/openqa/selenium/firefox:FirefoxDriverBuilderTest `
Expand Down
4 changes: 2 additions & 2 deletions WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ rules_closure_toolchains()

http_archive(
name = "rules_rust",
integrity = "sha256-JLN47ZcAbx9wEr5Jiib4HduZATGLiDgK7oUi/fvotzU=",
urls = ["https://github.com/bazelbuild/rules_rust/releases/download/0.42.1/rules_rust-v0.42.1.tar.gz"],
integrity = "sha256-Zx3bP+Xrz53TTQUeynNS+68z+lO/Ye7Qt1pMNIKeVIA=",
urls = ["https://github.com/bazelbuild/rules_rust/releases/download/0.52.2/rules_rust-v0.52.2.tar.gz"],
)

load("@rules_rust//rust:repositories.bzl", "rules_rust_dependencies", "rust_register_toolchains")
Expand Down
Binary file modified common/extensions/webextensions-selenium-example.crx
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@
]
}
],
"permissions": [
"storage",
"scripting"
],
"host_permissions": [
"https://*/*",
"http://*/*"
],
"browser_specific_settings": {
"gecko": {
"id": "[email protected]"
Expand Down
2 changes: 1 addition & 1 deletion dotnet/src/webdriver/WebDriver.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@
</Target>

<Target Name="GenerateCdp" BeforeTargets="CoreCompile">
<Exec Command="bazel build //dotnet/src/webdriver/cdp:generate-v85 //dotnet/src/webdriver/cdp:generate-v127 //dotnet/src/webdriver/cdp:generate-v128 //dotnet/src/webdriver/cdp:generate-v129" WorkingDirectory="../../.." />
<Exec Command="bazel build //dotnet/src/webdriver/cdp/..." WorkingDirectory="../../.." />

<ItemGroup>
<Compile Include="..\..\..\bazel-bin\dotnet\src\webdriver\cdp\**\*.cs" LinkBase="DevTools\generated" />
Expand Down
7 changes: 1 addition & 6 deletions dotnet/src/webdriver/cdp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,4 @@ perform the following steps, where `<N>` is the major version of the protocol:
remove the entry for version `<N>` from the `SupportedDevToolsVersions` dictionary initialization.
3. Remove the version string (`v<N>`) from the `SUPPORTED_DEVTOOLS_VERSIONS` list in
[`//dotnet:selenium-dotnet-version.bzl`](https://github.com/SeleniumHQ/selenium/blob/trunk/dotnet/selenium-dotnet-version.bzl).
4. In [`//dotnet/src/webdriver:WebDriver.csproj.prebuild.cmd`](https://github.com/SeleniumHQ/selenium/blob/trunk/dotnet/src/webdriver/WebDriver.csproj.prebuild.cmd),
remove the `if not exist` block for version `<N>`.
5. In [`//dotnet/src/webdriver:WebDriver.csproj.prebuild.sh`](https://github.com/SeleniumHQ/selenium/blob/trunk/dotnet/src/webdriver/WebDriver.csproj.prebuild.sh),
remove the `if-fi` block for version `<N>`.
6. Commit the changes.

4. Commit the changes.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,13 @@

package org.openqa.selenium.grid.node;

import static java.net.HttpURLConnection.HTTP_INTERNAL_ERROR;
import static org.openqa.selenium.remote.HttpSessionId.getSessionId;
import static org.openqa.selenium.remote.http.Contents.asJson;

import com.google.common.collect.ImmutableMap;
import org.openqa.selenium.internal.Require;
import org.openqa.selenium.remote.SessionId;
import org.openqa.selenium.remote.http.HttpHandler;
import org.openqa.selenium.remote.http.HttpRequest;
import org.openqa.selenium.remote.http.HttpResponse;
Expand All @@ -30,8 +36,22 @@ class ForwardWebDriverCommand implements HttpHandler {
this.node = Require.nonNull("Node", node);
}

public boolean matches(HttpRequest req) {
return getSessionId(req.getUri())
.map(id -> node.isSessionOwner(new SessionId(id)))
.orElse(false);
}

@Override
public HttpResponse execute(HttpRequest req) {
return node.executeWebDriverCommand(req);
if (matches(req)) {
return node.executeWebDriverCommand(req);
}
return new HttpResponse()
.setStatus(HTTP_INTERNAL_ERROR)
.setContent(
asJson(
ImmutableMap.of(
"error", String.format("Session not found in node %s", node.getId()))));
}
}
2 changes: 1 addition & 1 deletion java/src/org/openqa/selenium/grid/node/Node.java
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ protected Node(
req ->
getSessionId(req.getUri())
.map(SessionId::new)
.map(this::isSessionOwner)
.map(sessionId -> this.getSession(sessionId) != null)
.orElse(false))
.to(() -> new ForwardWebDriverCommand(this))
.with(spanDecorator("node.forward_command")),
Expand Down
17 changes: 13 additions & 4 deletions java/src/org/openqa/selenium/grid/node/local/LocalNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,13 @@ protected LocalNode(
heartbeatPeriod.getSeconds(),
TimeUnit.SECONDS);

Runtime.getRuntime().addShutdownHook(new Thread(this::stopAllSessions));
Runtime.getRuntime()
.addShutdownHook(
new Thread(
() -> {
stopAllSessions();
drain();
}));
new JMXHelper().register(this);
}

Expand All @@ -316,7 +322,6 @@ private void stopTimedOutSession(RemovalNotification<SessionId, SessionSlot> not
}
// Attempt to stop the session
slot.stop();
this.sessionToDownloadsDir.invalidate(id);
// Decrement pending sessions if Node is draining
if (this.isDraining()) {
int done = pendingSessions.decrementAndGet();
Expand Down Expand Up @@ -473,8 +478,6 @@ public Either<WebDriverException, CreateSessionResponse> newSession(
sessionToDownloadsDir.put(session.getId(), uuidForSessionDownloads);
currentSessions.put(session.getId(), slotToUse);

checkSessionCount();

SessionId sessionId = session.getId();
Capabilities caps = session.getCapabilities();
SESSION_ID.accept(span, sessionId);
Expand Down Expand Up @@ -513,6 +516,8 @@ public Either<WebDriverException, CreateSessionResponse> newSession(
span.addEvent("Unable to create session with the driver", attributeMap);
return Either.left(possibleSession.left());
}
} finally {
checkSessionCount();
}
}

Expand Down Expand Up @@ -765,6 +770,10 @@ public HttpResponse uploadFile(HttpRequest req, SessionId id) {
public void stop(SessionId id) throws NoSuchSessionException {
Require.nonNull("Session ID", id);

if (sessionToDownloadsDir.getIfPresent(id) != null) {
sessionToDownloadsDir.invalidate(id);
}

SessionSlot slot = currentSessions.getIfPresent(id);
if (slot == null) {
throw new NoSuchSessionException("Cannot find session with id: " + id);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

package org.openqa.selenium.grid.node;

import static java.net.HttpURLConnection.HTTP_INTERNAL_ERROR;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.*;
import static org.openqa.selenium.remote.http.Contents.asJson;

import com.google.common.collect.ImmutableMap;
import java.util.UUID;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.grid.data.NodeId;
import org.openqa.selenium.remote.SessionId;
import org.openqa.selenium.remote.http.HttpRequest;
import org.openqa.selenium.remote.http.HttpResponse;

class ForwardWebDriverCommandTest {

private Node mockNode;
private ForwardWebDriverCommand command;

@BeforeEach
void setUp() {
mockNode = mock(Node.class);
when(mockNode.getId()).thenReturn(new NodeId(UUID.randomUUID()));
command = new ForwardWebDriverCommand(mockNode);
}

@Test
void testExecuteWithValidSessionOwner() {
HttpRequest mockRequest = mock(HttpRequest.class);
when(mockRequest.getUri()).thenReturn("/session/1234");

SessionId sessionId = new SessionId("1234");
when(mockNode.isSessionOwner(sessionId)).thenReturn(true);

HttpResponse expectedResponse = new HttpResponse();
when(mockNode.executeWebDriverCommand(mockRequest)).thenReturn(expectedResponse);

HttpResponse actualResponse = command.execute(mockRequest);
assertEquals(expectedResponse, actualResponse);
}

@Test
void testExecuteWithInvalidSessionOwner() {
HttpRequest mockRequest = mock(HttpRequest.class);
when(mockRequest.getUri()).thenReturn("/session/5678");

SessionId sessionId = new SessionId("5678");
when(mockNode.isSessionOwner(sessionId)).thenReturn(false);

HttpResponse actualResponse = command.execute(mockRequest);
HttpResponse expectResponse =
new HttpResponse()
.setStatus(HTTP_INTERNAL_ERROR)
.setContent(
asJson(
ImmutableMap.of(
"error", String.format("Session not found in node %s", mockNode.getId()))));
assertEquals(expectResponse.getStatus(), actualResponse.getStatus());
assertEquals(expectResponse.getContentEncoding(), actualResponse.getContentEncoding());
}
}
44 changes: 41 additions & 3 deletions java/test/org/openqa/selenium/grid/node/NodeTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.InstanceOfAssertFactories.MAP;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.openqa.selenium.json.Json.MAP_TYPE;
import static org.openqa.selenium.remote.http.Contents.string;
import static org.openqa.selenium.remote.http.HttpMethod.DELETE;
Expand Down Expand Up @@ -102,7 +104,9 @@ class NodeTest {
private Tracer tracer;
private EventBus bus;
private LocalNode local;
private LocalNode local2;
private Node node;
private Node node2;
private ImmutableCapabilities stereotype;
private ImmutableCapabilities caps;
private URI uri;
Expand Down Expand Up @@ -150,6 +154,7 @@ public HttpResponse execute(HttpRequest req) throws UncheckedIOException {
builder = builder.enableManagedDownloads(true).sessionTimeout(Duration.ofSeconds(1));
}
local = builder.build();
local2 = builder.build();

node =
new RemoteNode(
Expand All @@ -160,6 +165,16 @@ public HttpResponse execute(HttpRequest req) throws UncheckedIOException {
registrationSecret,
local.getSessionTimeout(),
ImmutableSet.of(caps));

node2 =
new RemoteNode(
tracer,
new PassthroughHttpClient.Factory(local2),
new NodeId(UUID.randomUUID()),
uri,
registrationSecret,
local2.getSessionTimeout(),
ImmutableSet.of(caps));
}

@Test
Expand Down Expand Up @@ -371,13 +386,36 @@ void shouldOnlyRespondToWebDriverCommandsForSessionsTheNodeOwns() {
assertThatEither(response).isRight();
Session session = response.right().getSession();

Either<WebDriverException, CreateSessionResponse> response2 =
node2.newSession(createSessionRequest(caps));
assertThatEither(response2).isRight();
Session session2 = response2.right().getSession();

// Assert that should respond to commands for sessions Node 1 owns
HttpRequest req = new HttpRequest(POST, String.format("/session/%s/url", session.getId()));
assertThat(local.matches(req)).isTrue();
assertThat(node.matches(req)).isTrue();

req = new HttpRequest(POST, String.format("/session/%s/url", UUID.randomUUID()));
assertThat(local.matches(req)).isFalse();
assertThat(node.matches(req)).isFalse();
// Assert that should respond to commands for sessions Node 2 owns
HttpRequest req2 = new HttpRequest(POST, String.format("/session/%s/url", session2.getId()));
assertThat(local2.matches(req2)).isTrue();
assertThat(node2.matches(req2)).isTrue();

// Assert that should not respond to commands for sessions Node 1 does not own
NoSuchSessionException exception =
assertThrows(NoSuchSessionException.class, () -> node.execute(req2));
assertTrue(
exception
.getMessage()
.startsWith(String.format("Cannot find session with id: %s", session2.getId())));

// Assert that should not respond to commands for sessions Node 2 does not own
NoSuchSessionException exception2 =
assertThrows(NoSuchSessionException.class, () -> node2.execute(req));
assertTrue(
exception2
.getMessage()
.startsWith(String.format("Cannot find session with id: %s", session.getId())));
}

@Test
Expand Down
Loading

0 comments on commit dbe23c5

Please sign in to comment.