Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ name: "Code Scanning - Action"

on:
push:
branches: [master, 1.1.0_master, 1.1.0_dev]
pull_request:
branches: [master, 1.1.0_master, 1.1.0_dev]
schedule:
# ┌───────────── minute (0 - 59)
# │ ┌───────────── hour (0 - 23)
Expand Down
8 changes: 4 additions & 4 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,12 @@
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.10.0</version>
<version>2.11.0</version>
</dependency>
<dependency>
<groupId>net.jodah</groupId>
<artifactId>failsafe</artifactId>
<version>2.4.0</version>
<version>2.4.2</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
Expand Down Expand Up @@ -168,7 +168,7 @@
<dependency>
<groupId>org.apache.maven.scm</groupId>
<artifactId>maven-scm-provider-gitexe</artifactId>
<version>1.11.2</version>
<version>1.11.3</version>
</dependency>
<dependency>
<groupId>codes.dylanlacey</groupId>
Expand All @@ -180,7 +180,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-scm-plugin</artifactId>
<version>1.11.2</version>
<version>1.11.3</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
Expand Down
8 changes: 8 additions & 0 deletions src/main/java/com/saucelabs/saucerest/ErrorExplainers.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,12 @@ static String LogNotFound() {
" * A error occurred where the job was created on Sauce Labs but no test were executed."
);
}

static String TunnelNotFound() {
return String.join(System.lineSeparator(),
" * Tunnel id could not be found. Possible reasons:",
" * The tunnel id requested does not exist in this data center. Ensure the data center endpoint is correct.",
" * A tunnel with this id never existed."
);
}
}
10 changes: 10 additions & 0 deletions src/main/java/com/saucelabs/saucerest/SauceException.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,16 @@ public NotAuthorized() {
}
}

public static class NotFound extends SauceException {

public NotFound(String message) {
super(message);
}

public NotFound() {
}
}

public static class TooManyRequests extends SauceException {
}

Expand Down
34 changes: 26 additions & 8 deletions src/main/java/com/saucelabs/saucerest/SauceREST.java
Original file line number Diff line number Diff line change
Expand Up @@ -1173,8 +1173,8 @@ private BufferedInputStream downloadFileData(String jobId, URL restEndpoint) thr
return new BufferedInputStream(stream);
}

private HttpURLConnection setConnection(String jobId, URL restEndpoint) throws IOException {
HttpURLConnection connection = openConnection("GET", restEndpoint);
private HttpURLConnection setConnection(String jobId, URL restEndpoint, String method) throws IOException {
HttpURLConnection connection = openConnection(method, restEndpoint);

int responseCode = connection.getResponseCode();
logger.log(Level.FINEST, "{0} - {1} for: {2}", new Object[] { responseCode, restEndpoint, jobId });
Expand All @@ -1189,6 +1189,9 @@ private HttpURLConnection setConnection(String jobId, URL restEndpoint) throws I
errorDetails = ErrorExplainers.HARMissing();
} else if (path.endsWith("log") || path.endsWith("json")) {
errorDetails = ErrorExplainers.LogNotFound();
} else if (path.contains("tunnels")) {
errorDetails = ErrorExplainers.TunnelNotFound();
throw new SauceException.NotFound(String.join(System.lineSeparator(), errorDetails));
}

String error = ErrorExplainers.resourceMissing();
Expand Down Expand Up @@ -1228,6 +1231,14 @@ private HttpURLConnection setConnection(String jobId, URL restEndpoint) throws I
return connection;
}

private HttpURLConnection setConnection(String jobId, URL restEndpoint) throws IOException {
return setConnection(jobId, restEndpoint, "GET");
}

private HttpURLConnection setConnection(URL restEndpoint, String method) throws IOException {
return setConnection("", restEndpoint, method);
}

private boolean saveAsset(String jobId, String assetName, String location, String fileName) {
return handleErrorAtDownloadGracefully(() -> saveAssetOrThrowException(jobId, assetName, location, fileName));
}
Expand Down Expand Up @@ -1613,19 +1624,26 @@ protected String encodeAuthentication() {
* Invokes the Sauce REST API to delete a tunnel.
*
* @param tunnelId Identifier of the tunnel to delete
* @return BufferedInputStream with response from server
*/
public void deleteTunnel(String tunnelId) {

public BufferedInputStream deleteTunnel(String tunnelId) throws IOException {
HttpURLConnection connection = null;
try {
URL restEndpoint = buildURL(username + "/tunnels/" + tunnelId);
connection = openConnection("DELETE", restEndpoint);
connection.getOutputStream().write("".getBytes());
connection = setConnection(restEndpoint, "DELETE");
} catch (IOException e) {
logger.log(Level.WARNING, "Error stopping Sauce Job", e);
Throwable throwable = e.getCause();

if (throwable instanceof SauceException.NotAuthorized) {
throw (SauceException.NotAuthorized) throwable;
} else if (throwable instanceof SauceException.NotFound) {
throw (SauceException.NotFound) throwable;
}
logger.log(Level.WARNING, "Error deleting tunnel", e);
}

closeInputStream(connection);
InputStream stream = connection.getInputStream();
return new BufferedInputStream(stream);
}

/**
Expand Down
28 changes: 28 additions & 0 deletions src/test/java/com/saucelabs/saucerest/SauceRESTTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,34 @@ void testGetTunnelInformation() {
assertEquals(this.urlConnection.getRealURL().getPath(), "/rest/v1/" + this.sauceREST.getUsername() + "/tunnels/1234-1234-1231-123-123");
}

@Test
void testDeleteTunnel() throws Exception {
urlConnection.setResponseCode(401);
urlConnection.setInputStream(new ByteArrayInputStream("Not authorized".getBytes(StandardCharsets.UTF_8)));
assertThrows(SauceException.NotAuthorized.class, () -> sauceREST.deleteTunnel("1234"));

urlConnection.setResponseCode(404);
urlConnection.setInputStream(new ByteArrayInputStream("Not found".getBytes(StandardCharsets.UTF_8)));
assertThrows(SauceException.NotFound.class, () -> sauceREST.deleteTunnel("1234"));

urlConnection.setResponseCode(200);
urlConnection.setInputStream(new ByteArrayInputStream("{\"result\": true, \"id\": \"1234\", \"jobs_running\": 0}".getBytes(StandardCharsets.UTF_8)));

String results;
try (BufferedInputStream stream = sauceREST.deleteTunnel("1234")) {
assertEquals("/rest/v1/" + sauceREST.getUsername() + "/tunnels/1234",
urlConnection.getRealURL().getPath());

results = IOUtils.toString(stream, StandardCharsets.UTF_8);
}
JSONObject jsonObject = new JSONObject(results);

assertTrue(jsonObject.getBoolean("result"));
assertEquals("1234", jsonObject.getString("id"));
assertEquals(0, jsonObject.getInt("jobs_running"));
assertFalse(jsonObject.isEmpty());
}

@Test
void testGetActivity() {
urlConnection.setResponseCode(200);
Expand Down