Skip to content

Commit

Permalink
Merge pull request #63 from zebrunner/develop
Browse files Browse the repository at this point in the history
2.0 rc1
  • Loading branch information
vdelendik authored Jan 24, 2022
2 parents 2883942 + d6723e2 commit a133e21
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 15 deletions.
6 changes: 2 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
FROM openjdk:11
LABEL authors=Zebrunner

#========================
# Selenium Configuration
#========================

EXPOSE 4444

# STF integration
ENV STF_URL ""
ENV STF_TOKEN ""
ENV STF_TIMEOUT 3600
ENV HTTP_CLIENT_RETRY_COUNT 1

# Grid settings
# As integer, maps to "maxSession"
ENV GRID_MAX_SESSION 5
# As a boolean, maps to "throwOnCapabilityNotPresent"
Expand Down
15 changes: 15 additions & 0 deletions src/main/java/com/zebrunner/mcloud/grid/MobileRemoteProxy.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import org.apache.commons.lang3.StringUtils;
import org.openqa.grid.common.RegistrationRequest;
import org.openqa.grid.common.exception.CapabilityNotPresentOnTheGridException;
import org.openqa.grid.internal.GridRegistry;
import org.openqa.grid.internal.TestSession;
import org.openqa.grid.internal.TestSlot;
Expand Down Expand Up @@ -95,6 +96,20 @@ public TestSession getNewSession(Map<String, Object> requestedCapability) {
return null;
}

@Override
public boolean hasCapability(Map<String, Object> requestedCapability) {
// verify that required STF connection can be established trying to init STF client
try {
getSTFClient(requestedCapability); // temp STFClient to test authorization
} catch (Exception e) {
// as we have enabled GRID_THROW_ON_CAPABILITY_NOT_PRESENT by default we could raise exception without waiting 4 minutes
// Confirmed by testing that raising CapabilityNotPresentOnTheGridException is applicable only inside hasCapability method!
throw new CapabilityNotPresentOnTheGridException(e.getMessage());
}

return super.hasCapability(requestedCapability);
}

@Override
public void beforeSession(TestSession session) {
String sessionId = getExternalSessionId(session);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,11 @@ public class STFClient {

private String serviceURL;
private String authToken;
private User user;
private long timeout;

private boolean isConnected = false;
private boolean isOwned = false;

public STFClient(String serviceURL, String authToken, long timeout) {
this.serviceURL = serviceURL;
Expand All @@ -56,20 +58,20 @@ public STFClient(String serviceURL, String authToken, long timeout) {
int status = response.getStatus();
if (status == 200) {
LOGGER.fine("STF connection successfully established.");
User user = (User) response.getObject();
if (user.getSuccess()) {
String msg = String.format("User (privilege is '%s') %s (%s) was sucessfully logged in.", user.getUser()
this.user = (User) response.getObject();
if (this.user.getSuccess()) {
String msg = String.format("User (privilege is '%s') %s (%s) was sucessfully logged in.", this.user.getUser()
.getPrivilege(),
user.getUser().getName(), user.getUser().getEmail());
this.user.getUser().getName(), this.user.getUser().getEmail());
LOGGER.fine(msg);
} else {
LOGGER.log(Level.SEVERE, String.format("Not authenticated at STF successfully! URL: '%s'; Token: '%s';", serviceURL, authToken));
throw new RuntimeException("Not authenticated at STF!");
throw new RuntimeException("Not authenticated at STF! Error code: " + status);
}
} else {
LOGGER.log(Level.SEVERE, String.format("Required STF connection not established! URL: '%s'; Token: '%s'; Error code: %d",
serviceURL, authToken, status));
throw new RuntimeException("Unable to connect to STF!");
throw new RuntimeException("Unable to connect to STF! Error code: " + status);
}
} else {
LOGGER.fine("STF integration disabled.");
Expand Down Expand Up @@ -99,8 +101,25 @@ public boolean isDeviceAvailable(String udid) {
if (rs.getStatus() == 200) {
for (STFDevice device : rs.getObject().getDevices()) {
if (udid.equals(device.getSerial())) {
available = device.getPresent() && device.getReady() && !device.getUsing()
&& device.getOwner() == null;
LOGGER.log(Level.FINE, "this.user.getUser().getName(): " + this.user.getUser().getName());

LOGGER.log(Level.FINE, "device.getPresent(): " + device.getPresent());
LOGGER.log(Level.FINE, "device.getReady(): " + device.getReady());
LOGGER.log(Level.FINE, "device.getOwner(): " + device.getOwner());

boolean isAccessible = false;
if (device.getOwner() == null) {
isAccessible = true;
} else {
// #54 try to check usage ownership by token to allow automation launch over occupied devices
LOGGER.log(Level.FINE, "device.getOwner().getName(): " + device.getOwner().getName());
// isOwned should be true if the same STF user occupied device
this.isOwned = this.user.getUser().getName().equals(device.getOwner().getName());
}
LOGGER.log(Level.FINE, "isAccessible: " + isAccessible);
LOGGER.log(Level.FINE, "this.isOwned: " + this.isOwned);

available = device.getPresent() && device.getReady() && (isAccessible || this.isOwned);
break;
}
}
Expand Down Expand Up @@ -194,6 +213,10 @@ private HttpClient.Response<Devices> getAllDevices() {
}

private boolean reserveDevice(String serial) {
if (this.isOwned) {
LOGGER.log(Level.INFO, "already reserved manually by the same user");
return true;
}
Map<String, Object> entity = new HashMap<>();
entity.put("serial", serial);
entity.put("timeout", TimeUnit.SECONDS.toMillis(this.timeout)); // 3600 sec by default
Expand All @@ -205,6 +228,10 @@ private boolean reserveDevice(String serial) {
}

private boolean returnDevice(String serial) {
if (this.isOwned) {
LOGGER.log(Level.INFO, "no need to return device as it was reserved manually");
return true;
}
HttpClient.Response response = HttpClient.uri(Path.STF_USER_DEVICES_BY_ID_PATH, serviceURL, serial)
.withAuthorization(buildAuthToken(authToken))
.delete(Void.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public class STFDevice {
private String model;
private Network network;
private Object operator;
private Object owner;
private STFUser owner;
private Phone phone;
private String platform;
private String presenceChangedAt;
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/zebrunner/mcloud/grid/util/HttpClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public class HttpClient {
private static final Integer CONNECT_TIMEOUT = 60000;
private static final Integer READ_TIMEOUT = 60000;
private static final Integer RETRY_DELAY = 10000;
private static final Integer MAX_RETRY_COUNT = 3;
private static final Integer HTTP_CLIENT_RETRY_COUNT = Integer.parseInt(System.getenv("HTTP_CLIENT_RETRY_COUNT"));

private static Client client;

Expand Down Expand Up @@ -146,7 +146,7 @@ private void initHeaders(String authToken) {
private <R> Response<R> execute(Class<R> responseClass, Function<WebResource.Builder, ClientResponse> methodBuilder) {
RetryPolicy<Object> retryPolicy = new RetryPolicy<>()
.withDelay(Duration.ofMillis(RETRY_DELAY))
.withMaxRetries(MAX_RETRY_COUNT)
.withMaxRetries(HTTP_CLIENT_RETRY_COUNT)
.handleResultIf(result -> result != null && ((Response<R>) result).getStatus() / 100 != 2)
.onRetry(e -> LOGGER.log(
Level.SEVERE,
Expand Down

0 comments on commit a133e21

Please sign in to comment.