Skip to content

Commit eba0b8e

Browse files
bonigarciaaguspe
authored andcommitted
[java] Copy SM binary to cache folder and use it from there (SeleniumHQ#11359) (SeleniumHQ#12539)
* [java] Copy SM binary to cache folder and use it from there * [java] Read cache path from the config file and as env * [java] Read cache-path as env only * [java] Use BuildInfo class to get current Selenium version * [java] if cache path is not writable, SM will be extracted to a temporal folder * [java] Include shutdown hook again to delete binary when stored in tmp folder
1 parent f08f96a commit eba0b8e

File tree

1 file changed

+54
-50
lines changed

1 file changed

+54
-50
lines changed

Diff for: java/src/org/openqa/selenium/manager/SeleniumManager.java

+54-50
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,14 @@
1616
// under the License.
1717
package org.openqa.selenium.manager;
1818

19-
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
2019
import static org.openqa.selenium.Platform.MAC;
2120
import static org.openqa.selenium.Platform.WINDOWS;
2221

2322
import java.io.IOException;
2423
import java.io.InputStream;
25-
import java.nio.file.FileVisitResult;
2624
import java.nio.file.Files;
2725
import java.nio.file.Path;
2826
import java.nio.file.Paths;
29-
import java.nio.file.SimpleFileVisitor;
30-
import java.nio.file.attribute.BasicFileAttributes;
3127
import java.time.Duration;
3228
import java.util.ArrayList;
3329
import java.util.Arrays;
@@ -36,6 +32,7 @@
3632
import java.util.logging.Level;
3733
import java.util.logging.Logger;
3834
import org.openqa.selenium.Beta;
35+
import org.openqa.selenium.BuildInfo;
3936
import org.openqa.selenium.Capabilities;
4037
import org.openqa.selenium.MutableCapabilities;
4138
import org.openqa.selenium.Platform;
@@ -63,20 +60,31 @@ public class SeleniumManager {
6360
private static final Logger LOG = Logger.getLogger(SeleniumManager.class.getName());
6461

6562
private static final String SELENIUM_MANAGER = "selenium-manager";
63+
private static final String DEFAULT_CACHE_PATH = "~/.cache/selenium";
64+
private static final String BINARY_PATH_FORMAT = "/manager/%s/%s";
65+
private static final String HOME = "~";
66+
private static final String CACHE_PATH_ENV = "SE_CACHE_PATH";
67+
private static final String BETA_PREFIX = "0.";
68+
private static final String EXE = ".exe";
6669

6770
private static volatile SeleniumManager manager;
68-
6971
private final String managerPath = System.getenv("SE_MANAGER_PATH");
7072
private Path binary = managerPath == null ? null : Paths.get(managerPath);
73+
private String seleniumManagerVersion;
74+
private boolean binaryInTemporalFolder = false;
7175

7276
/** Wrapper for the Selenium Manager binary. */
7377
private SeleniumManager() {
78+
BuildInfo info = new BuildInfo();
79+
String releaseLabel = info.getReleaseLabel();
80+
int lastDot = releaseLabel.lastIndexOf(".");
81+
seleniumManagerVersion = BETA_PREFIX + releaseLabel.substring(0, lastDot);
7482
if (managerPath == null) {
7583
Runtime.getRuntime()
7684
.addShutdownHook(
7785
new Thread(
7886
() -> {
79-
if (binary != null && Files.exists(binary)) {
87+
if (binaryInTemporalFolder && binary != null && Files.exists(binary)) {
8088
try {
8189
Files.delete(binary);
8290
} catch (IOException e) {
@@ -161,23 +169,27 @@ private static Result runCommand(Path binary, List<String> arguments) {
161169
*/
162170
private synchronized Path getBinary() {
163171
if (binary == null) {
164-
Platform current = Platform.getCurrent();
165-
String folder = "linux";
166-
String extension = "";
167-
if (current.is(WINDOWS)) {
168-
extension = ".exe";
169-
folder = "windows";
170-
} else if (current.is(MAC)) {
171-
folder = "macos";
172-
}
173-
String binaryPath = String.format("%s/%s%s", folder, SELENIUM_MANAGER, extension);
174-
try (InputStream inputStream = this.getClass().getResourceAsStream(binaryPath)) {
175-
Path tmpPath = Files.createTempDirectory(SELENIUM_MANAGER + System.nanoTime());
172+
try {
173+
Platform current = Platform.getCurrent();
174+
String folder = "linux";
175+
String extension = "";
176+
if (current.is(WINDOWS)) {
177+
extension = EXE;
178+
folder = "windows";
179+
} else if (current.is(MAC)) {
180+
folder = "macos";
181+
}
176182

177-
deleteOnExit(tmpPath);
183+
binary = getBinaryInCache(SELENIUM_MANAGER + extension);
184+
if (!binary.toFile().exists()) {
185+
String binaryPathInJar = String.format("%s/%s%s", folder, SELENIUM_MANAGER, extension);
186+
try (InputStream inputStream = this.getClass().getResourceAsStream(binaryPathInJar)) {
187+
binary.getParent().toFile().mkdirs();
188+
Files.copy(inputStream, binary);
189+
}
190+
binary.toFile().setExecutable(true);
191+
}
178192

179-
binary = tmpPath.resolve(SELENIUM_MANAGER + extension);
180-
Files.copy(inputStream, binary, REPLACE_EXISTING);
181193
} catch (Exception e) {
182194
throw new WebDriverException("Unable to obtain Selenium Manager Binary", e);
183195
}
@@ -192,35 +204,6 @@ private synchronized Path getBinary() {
192204
return binary;
193205
}
194206

195-
private void deleteOnExit(Path tmpPath) {
196-
Runtime.getRuntime()
197-
.addShutdownHook(
198-
new Thread(
199-
() -> {
200-
try {
201-
Files.walkFileTree(
202-
tmpPath,
203-
new SimpleFileVisitor<Path>() {
204-
@Override
205-
public FileVisitResult postVisitDirectory(Path dir, IOException exc)
206-
throws IOException {
207-
Files.delete(dir);
208-
return FileVisitResult.CONTINUE;
209-
}
210-
211-
@Override
212-
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
213-
throws IOException {
214-
Files.delete(file);
215-
return FileVisitResult.CONTINUE;
216-
}
217-
});
218-
} catch (IOException e) {
219-
// Do nothing. We're just tidying up.
220-
}
221-
}));
222-
}
223-
224207
/**
225208
* Returns the browser binary path when present in the vendor options
226209
*
@@ -319,4 +302,25 @@ private Level getLogLevel() {
319302
}
320303
return level;
321304
}
305+
306+
private Path getBinaryInCache(String binaryName) throws IOException {
307+
String cachePath = DEFAULT_CACHE_PATH.replace(HOME, System.getProperty("user.home"));
308+
309+
// Look for cache path as env
310+
String cachePathEnv = System.getenv(CACHE_PATH_ENV);
311+
if (cachePathEnv != null) {
312+
cachePath = cachePathEnv;
313+
}
314+
315+
// If cache path is not writable, SM will be extracted to a temporal folder
316+
Path cacheParent = Paths.get(cachePath);
317+
if (!Files.isWritable(cacheParent)) {
318+
cacheParent = Files.createTempDirectory(SELENIUM_MANAGER);
319+
binaryInTemporalFolder = true;
320+
}
321+
322+
return Paths.get(
323+
cacheParent.toString(),
324+
String.format(BINARY_PATH_FORMAT, seleniumManagerVersion, binaryName));
325+
}
322326
}

0 commit comments

Comments
 (0)