Injects ProcessRunner to simplify testing, tests conda
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package com.github.gtache.autosubtitle.setup.conda;
|
||||
|
||||
import com.github.gtache.autosubtitle.impl.OS;
|
||||
import com.github.gtache.autosubtitle.process.ProcessRunner;
|
||||
import com.github.gtache.autosubtitle.setup.SetupException;
|
||||
import com.github.gtache.autosubtitle.setup.SetupStatus;
|
||||
import com.github.gtache.autosubtitle.setup.impl.AbstractSetupManager;
|
||||
@@ -31,8 +32,8 @@ public class CondaSetupManager extends AbstractSetupManager {
|
||||
private final CondaSetupConfiguration configuration;
|
||||
|
||||
@Inject
|
||||
CondaSetupManager(final CondaSetupConfiguration configuration, final HttpClient httpClient) {
|
||||
super(httpClient);
|
||||
CondaSetupManager(final CondaSetupConfiguration configuration, final ProcessRunner processRunner, final HttpClient httpClient) {
|
||||
super(processRunner, httpClient);
|
||||
this.configuration = requireNonNull(configuration);
|
||||
}
|
||||
|
||||
@@ -71,31 +72,28 @@ public class CondaSetupManager extends AbstractSetupManager {
|
||||
switch (configuration.os()) {
|
||||
case OS.WINDOWS -> installWindows();
|
||||
case OS.MAC, OS.LINUX -> installLinux();
|
||||
default -> throw new SetupException("Unsupported OS: " + configuration.os());
|
||||
}
|
||||
}
|
||||
|
||||
private void installLinux() throws SetupException {
|
||||
try {
|
||||
final var installerPath = configuration.condaInstallerPath();
|
||||
final var rootPath = configuration.condaRootPath();
|
||||
logger.info("Installing conda using {}", installerPath);
|
||||
final var result = run(List.of("bash", installerPath.toString(), "-b", "-p", rootPath.toString()), Duration.ofMinutes(15));
|
||||
if (result.exitCode() == 0) {
|
||||
logger.info("Installed conda to {}", rootPath);
|
||||
} else {
|
||||
throw new SetupException("Error installing conda: " + result);
|
||||
}
|
||||
} catch (final IOException e) {
|
||||
throw new SetupException(e);
|
||||
}
|
||||
final var installerPath = configuration.condaInstallerPath();
|
||||
final var rootPath = configuration.condaRootPath();
|
||||
installArgs(List.of("bash", installerPath.toString(), "-b", "-p", rootPath.toString()));
|
||||
}
|
||||
|
||||
private void installWindows() throws SetupException {
|
||||
final var installerPath = configuration.condaInstallerPath();
|
||||
final var rootPath = configuration.condaRootPath();
|
||||
installArgs(List.of(installerPath.toString(), "/InstallationType=JustMe", "/RegisterPython=0", "/S", "/D=" + rootPath));
|
||||
}
|
||||
|
||||
private void installArgs(final List<String> args) throws SetupException {
|
||||
try {
|
||||
final var installerPath = configuration.condaInstallerPath();
|
||||
final var rootPath = configuration.condaRootPath();
|
||||
logger.info("Installing conda using {}", installerPath);
|
||||
final var result = run(List.of(installerPath.toString(), "/InstallationType=JustMe", "/RegisterPython=0", "/S", "/D=" + rootPath.toString()), Duration.ofMinutes(15));
|
||||
final var result = processRunner().run(args, Duration.ofMinutes(15));
|
||||
if (result.exitCode() == 0) {
|
||||
logger.info("Installed conda to {}", rootPath);
|
||||
} else {
|
||||
@@ -111,6 +109,7 @@ public class CondaSetupManager extends AbstractSetupManager {
|
||||
case OS.WINDOWS -> downloadCondaWindows();
|
||||
case OS.MAC -> downloadCondaMac();
|
||||
case OS.LINUX -> downloadCondaLinux();
|
||||
default -> throw new SetupException("Unsupported OS: " + configuration.os());
|
||||
}
|
||||
logger.info("Downloaded conda to {}", configuration.condaInstallerPath());
|
||||
}
|
||||
@@ -154,7 +153,7 @@ public class CondaSetupManager extends AbstractSetupManager {
|
||||
@Override
|
||||
public void update() throws SetupException {
|
||||
try {
|
||||
final var result = run(List.of(getCondaPath().toString(), "update", "-y", "conda"), Duration.ofMinutes(15));
|
||||
final var result = processRunner().run(List.of(getCondaPath().toString(), "update", "-y", "conda"), Duration.ofMinutes(15));
|
||||
if (result.exitCode() == 0) {
|
||||
logger.info("Conda updated");
|
||||
} else {
|
||||
@@ -169,7 +168,7 @@ public class CondaSetupManager extends AbstractSetupManager {
|
||||
final var args = Stream.concat(Stream.of(getCondaPath().toString(), "create", "-y", "-p", path.toString(), "python=" + pythonVersion), Arrays.stream(packages)).toList();
|
||||
try {
|
||||
logger.info("Creating venv {}", path);
|
||||
final var result = run(args, Duration.ofMinutes(15));
|
||||
final var result = processRunner().run(args, Duration.ofMinutes(15));
|
||||
if (result.exitCode() == 0) {
|
||||
logger.info("Created venv {}", path);
|
||||
} else {
|
||||
@@ -181,6 +180,7 @@ public class CondaSetupManager extends AbstractSetupManager {
|
||||
try (final var files = Files.find(sourceFolder, 1, (p, a) -> p.getFileName().toString().contains("libcrypto") || p.getFileName().toString().contains("libssl"))) {
|
||||
final var fileList = files.toList();
|
||||
final var targetFolder = path.resolve("DLLs");
|
||||
Files.createDirectories(targetFolder);
|
||||
for (final var s : fileList) {
|
||||
Files.copy(s, targetFolder.resolve(s.getFileName()));
|
||||
}
|
||||
@@ -202,7 +202,7 @@ public class CondaSetupManager extends AbstractSetupManager {
|
||||
|
||||
private boolean isSystemCondaInstalled() throws SetupException {
|
||||
try {
|
||||
final var result = run(List.of(configuration.condaSystemPath().toString(), "--version"), Duration.ofSeconds(5));
|
||||
final var result = processRunner().run(List.of(configuration.condaSystemPath().toString(), "--version"), Duration.ofSeconds(5));
|
||||
if (result.exitCode() == 0) {
|
||||
final var output = result.output().getFirst();
|
||||
final var versionString = output.substring(output.indexOf(' ') + 1);
|
||||
@@ -212,7 +212,7 @@ public class CondaSetupManager extends AbstractSetupManager {
|
||||
final var minor = Integer.parseInt(version[1]);
|
||||
return major >= configuration.condaMinimumMajorVersion() && minor >= configuration.condaMinimumMinorVersion();
|
||||
} else {
|
||||
throw new SetupException("Unexpected python version: " + versionString);
|
||||
throw new SetupException("Unexpected conda version: " + versionString);
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
package com.github.gtache.autosubtitle.modules.setup.conda;
|
||||
|
||||
import com.github.gtache.autosubtitle.impl.Architecture;
|
||||
import com.github.gtache.autosubtitle.impl.OS;
|
||||
import com.github.gtache.autosubtitle.setup.conda.CondaSetupConfiguration;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
class TestCondaSetupModule {
|
||||
|
||||
@Test
|
||||
void testCondaSetupConfiguration() {
|
||||
final var rootPath = Paths.get("root");
|
||||
final var systemPath = Paths.get("system");
|
||||
final var bundledPath = Paths.get("bundled");
|
||||
final var condaMinimumMajorVersion = 24;
|
||||
final var condaMinimumMinorVersion = 5;
|
||||
final var condaInstallerPath = Paths.get("installer");
|
||||
final var os = OS.WINDOWS;
|
||||
final var architecture = Architecture.X86_64;
|
||||
final var expected = new CondaSetupConfiguration(rootPath, systemPath, bundledPath, condaMinimumMajorVersion, condaMinimumMinorVersion, condaInstallerPath, os, architecture);
|
||||
assertEquals(expected, CondaSetupModule.providesCondaSetupConfiguration(systemPath, bundledPath, condaMinimumMajorVersion, condaMinimumMinorVersion, condaInstallerPath, rootPath, os, architecture));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testProvidesCondaSystemPath() {
|
||||
assertEquals(Paths.get("conda.bat"), CondaSetupModule.providesCondaSystemPath(OS.WINDOWS));
|
||||
assertEquals(Paths.get("conda"), CondaSetupModule.providesCondaSystemPath(OS.LINUX));
|
||||
assertEquals(Paths.get("conda"), CondaSetupModule.providesCondaSystemPath(OS.MAC));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCondaBundledPath() {
|
||||
final var root = Paths.get("root");
|
||||
final var expectedWindows = root.resolve("condabin").resolve(Paths.get("conda.bat"));
|
||||
final var expectedOther = root.resolve("condabin").resolve(Paths.get("conda"));
|
||||
assertEquals(expectedWindows, CondaSetupModule.providesCondaBundledPath(root, OS.WINDOWS));
|
||||
assertEquals(expectedOther, CondaSetupModule.providesCondaBundledPath(root, OS.MAC));
|
||||
assertEquals(expectedOther, CondaSetupModule.providesCondaBundledPath(root, OS.LINUX));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCondaMinimumMajorVersion() {
|
||||
assertEquals(24, CondaSetupModule.providesCondaMinimumMajorVersion());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCondaMinimumMinorVersion() {
|
||||
assertEquals(5, CondaSetupModule.providesCondaMinimumMinorVersion());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCondaRootPath() {
|
||||
final var root = Paths.get("root");
|
||||
final var expected = root.resolve("miniconda3");
|
||||
assertEquals(expected, CondaSetupModule.providesCondaRootPath(root));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCondaInstallerPath() {
|
||||
final var root = Paths.get("root");
|
||||
final var expectedWindows = root.resolve("conda-install.exe");
|
||||
final var expectedOther = root.resolve("conda-install.sh");
|
||||
assertEquals(expectedWindows, CondaSetupModule.providesCondaInstallerPath(root, OS.WINDOWS));
|
||||
assertEquals(expectedOther, CondaSetupModule.providesCondaInstallerPath(root, OS.MAC));
|
||||
assertEquals(expectedOther, CondaSetupModule.providesCondaInstallerPath(root, OS.LINUX));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.github.gtache.autosubtitle.setup.conda;
|
||||
|
||||
import com.github.gtache.autosubtitle.impl.Architecture;
|
||||
import com.github.gtache.autosubtitle.impl.OS;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class TestCondaSetupConfiguration {
|
||||
|
||||
private final Path condaRootPath;
|
||||
private final Path condaSystemPath;
|
||||
private final Path condaBundledPath;
|
||||
private final int condaMinimumMajorVersion;
|
||||
private final int condaMinimumMinorVersion;
|
||||
private final Path condaInstallerPath;
|
||||
private final OS os;
|
||||
private final Architecture architecture;
|
||||
|
||||
TestCondaSetupConfiguration(@Mock final Path condaRootPath, @Mock final Path condaSystemPath,
|
||||
@Mock final Path condaBundledPath, @Mock final Path condaInstallerPath,
|
||||
@Mock final OS os, @Mock final Architecture architecture) {
|
||||
this.condaRootPath = Objects.requireNonNull(condaRootPath);
|
||||
this.condaSystemPath = Objects.requireNonNull(condaSystemPath);
|
||||
this.condaBundledPath = Objects.requireNonNull(condaBundledPath);
|
||||
this.condaMinimumMajorVersion = 3;
|
||||
this.condaMinimumMinorVersion = 4;
|
||||
this.condaInstallerPath = Objects.requireNonNull(condaInstallerPath);
|
||||
this.os = Objects.requireNonNull(os);
|
||||
this.architecture = Objects.requireNonNull(architecture);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCondaSetupConfiguration() {
|
||||
final var configuration = new CondaSetupConfiguration(condaRootPath, condaSystemPath, condaBundledPath, condaMinimumMajorVersion, condaMinimumMinorVersion, condaInstallerPath, os, architecture);
|
||||
assertEquals(condaRootPath, configuration.condaRootPath());
|
||||
assertEquals(condaSystemPath, configuration.condaSystemPath());
|
||||
assertEquals(condaBundledPath, configuration.condaBundledPath());
|
||||
assertEquals(condaMinimumMajorVersion, configuration.condaMinimumMajorVersion());
|
||||
assertEquals(condaMinimumMinorVersion, configuration.condaMinimumMinorVersion());
|
||||
assertEquals(condaInstallerPath, configuration.condaInstallerPath());
|
||||
assertEquals(os, configuration.os());
|
||||
assertEquals(architecture, configuration.architecture());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIllegal() {
|
||||
assertThrows(NullPointerException.class, () -> new CondaSetupConfiguration(null, condaSystemPath, condaBundledPath, condaMinimumMajorVersion, condaMinimumMinorVersion, condaInstallerPath, os, architecture));
|
||||
assertThrows(NullPointerException.class, () -> new CondaSetupConfiguration(condaRootPath, null, condaBundledPath, condaMinimumMajorVersion, condaMinimumMinorVersion, condaInstallerPath, os, architecture));
|
||||
assertThrows(NullPointerException.class, () -> new CondaSetupConfiguration(condaRootPath, condaSystemPath, null, condaMinimumMajorVersion, condaMinimumMinorVersion, condaInstallerPath, os, architecture));
|
||||
assertThrows(IllegalArgumentException.class, () -> new CondaSetupConfiguration(condaRootPath, condaSystemPath, condaBundledPath, 0, condaMinimumMinorVersion, condaInstallerPath, os, architecture));
|
||||
assertThrows(IllegalArgumentException.class, () -> new CondaSetupConfiguration(condaRootPath, condaSystemPath, condaBundledPath, condaMinimumMajorVersion, -1, condaInstallerPath, os, architecture));
|
||||
assertThrows(NullPointerException.class, () -> new CondaSetupConfiguration(condaRootPath, condaSystemPath, condaBundledPath, condaMinimumMajorVersion, condaMinimumMinorVersion, null, os, architecture));
|
||||
assertThrows(NullPointerException.class, () -> new CondaSetupConfiguration(condaRootPath, condaSystemPath, condaBundledPath, condaMinimumMajorVersion, condaMinimumMinorVersion, condaInstallerPath, null, architecture));
|
||||
assertThrows(NullPointerException.class, () -> new CondaSetupConfiguration(condaRootPath, condaSystemPath, condaBundledPath, condaMinimumMajorVersion, condaMinimumMinorVersion, condaInstallerPath, os, null));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,513 @@
|
||||
package com.github.gtache.autosubtitle.setup.conda;
|
||||
|
||||
import com.github.gtache.autosubtitle.impl.Architecture;
|
||||
import com.github.gtache.autosubtitle.impl.OS;
|
||||
import com.github.gtache.autosubtitle.process.ProcessResult;
|
||||
import com.github.gtache.autosubtitle.process.ProcessRunner;
|
||||
import com.github.gtache.autosubtitle.setup.SetupException;
|
||||
import com.github.gtache.autosubtitle.setup.SetupStatus;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.http.HttpClient;
|
||||
import java.net.http.HttpRequest;
|
||||
import java.net.http.HttpResponse;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class TestCondaSetupManager {
|
||||
private static final String PYTHON_VERSION = "3.3";
|
||||
private static final String[] PACKAGES = {"p1", "p2"};
|
||||
|
||||
|
||||
private final CondaSetupConfiguration configuration;
|
||||
private final ProcessRunner processRunner;
|
||||
private final HttpClient httpClient;
|
||||
private final CondaSetupManager condaSetupManager;
|
||||
private final ProcessResult systemProcessResult;
|
||||
private final Path systemPath;
|
||||
private final HttpResponse<Path> response;
|
||||
|
||||
TestCondaSetupManager(@Mock final CondaSetupConfiguration configuration, @Mock final ProcessRunner processRunner,
|
||||
@Mock final HttpClient httpClient, @Mock final ProcessResult systemProcessResult, @Mock final HttpResponse<Path> response) throws IOException, InterruptedException {
|
||||
this.configuration = requireNonNull(configuration);
|
||||
this.processRunner = requireNonNull(processRunner);
|
||||
this.httpClient = requireNonNull(httpClient);
|
||||
this.condaSetupManager = new CondaSetupManager(configuration, processRunner, httpClient);
|
||||
this.systemProcessResult = requireNonNull(systemProcessResult);
|
||||
this.systemPath = Paths.get("system");
|
||||
this.response = requireNonNull(response);
|
||||
when(response.statusCode()).thenReturn(200);
|
||||
when(configuration.condaSystemPath()).thenReturn(systemPath);
|
||||
when(systemProcessResult.output()).thenReturn(List.of("conda 99.99.99"));
|
||||
when(systemProcessResult.exitCode()).thenReturn(0);
|
||||
when(processRunner.run(List.of(systemPath.toString(), "--version"), Duration.ofSeconds(5))).thenReturn(systemProcessResult);
|
||||
when(httpClient.send(any(HttpRequest.class), any(HttpResponse.BodyHandler.class))).thenReturn(response);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testName() {
|
||||
assertEquals("conda", condaSetupManager.name());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetStatusIsSystemInstalled() throws SetupException {
|
||||
assertEquals(SetupStatus.SYSTEM_INSTALLED, condaSetupManager.getStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetStatusIsBundledInstalled(@TempDir final Path tempDir) throws SetupException, IOException {
|
||||
final var path = tempDir.resolve("conda");
|
||||
Files.createFile(path);
|
||||
when(configuration.condaBundledPath()).thenReturn(path);
|
||||
when(systemProcessResult.exitCode()).thenReturn(1);
|
||||
|
||||
assertEquals(SetupStatus.BUNDLE_INSTALLED, condaSetupManager.getStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetStatusNotInstalled() throws SetupException {
|
||||
final var path = Paths.get("conda");
|
||||
when(configuration.condaBundledPath()).thenReturn(path);
|
||||
when(systemProcessResult.exitCode()).thenReturn(1);
|
||||
assertEquals(SetupStatus.NOT_INSTALLED, condaSetupManager.getStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInstallIsInstalledSystem() {
|
||||
assertDoesNotThrow(condaSetupManager::install);
|
||||
verifyNoInteractions(httpClient);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInstallIsInstalledBundled(@TempDir final Path tempDir) throws IOException {
|
||||
final var path = tempDir.resolve("conda");
|
||||
Files.createFile(path);
|
||||
when(configuration.condaBundledPath()).thenReturn(path);
|
||||
when(systemProcessResult.exitCode()).thenReturn(1);
|
||||
assertDoesNotThrow(condaSetupManager::install);
|
||||
verifyNoInteractions(httpClient);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInstallDownloadWindows(@TempDir final Path tempDir) throws IOException, InterruptedException {
|
||||
final var installerPath = tempDir.resolve("conda");
|
||||
when(configuration.condaInstallerPath()).thenReturn(installerPath);
|
||||
when(configuration.condaBundledPath()).thenReturn(tempDir);
|
||||
when(configuration.os()).thenReturn(OS.WINDOWS);
|
||||
when(systemProcessResult.exitCode()).thenReturn(1);
|
||||
when(configuration.condaRootPath()).thenReturn(tempDir);
|
||||
|
||||
final var args = List.of(installerPath.toString(), "/InstallationType=JustMe", "/RegisterPython=0", "/S", "/D=" + tempDir);
|
||||
final var result = mock(ProcessResult.class);
|
||||
when(result.exitCode()).thenReturn(0);
|
||||
when(processRunner.run(args, Duration.ofMinutes(15))).thenReturn(result);
|
||||
|
||||
assertDoesNotThrow(condaSetupManager::install);
|
||||
final var requestCapture = ArgumentCaptor.forClass(HttpRequest.class);
|
||||
verify(httpClient).send(requestCapture.capture(), any(HttpResponse.BodyHandler.class));
|
||||
final var request = requestCapture.getValue();
|
||||
assertEquals("https://repo.anaconda.com/miniconda/Miniconda3-latest-Windows-x86_64.exe", request.uri().toString());
|
||||
verify(processRunner).run(args, Duration.ofMinutes(15));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInstallDownloadLinuxAMD64(@TempDir final Path tempDir) throws IOException, InterruptedException {
|
||||
final var installerPath = tempDir.resolve("conda");
|
||||
when(configuration.condaInstallerPath()).thenReturn(installerPath);
|
||||
when(configuration.condaBundledPath()).thenReturn(tempDir);
|
||||
when(configuration.os()).thenReturn(OS.LINUX);
|
||||
when(configuration.architecture()).thenReturn(Architecture.AMD64);
|
||||
when(systemProcessResult.exitCode()).thenReturn(1);
|
||||
when(configuration.condaRootPath()).thenReturn(tempDir);
|
||||
|
||||
final var args = List.of("bash", installerPath.toString(), "-b", "-p", tempDir.toString());
|
||||
final var result = mock(ProcessResult.class);
|
||||
when(result.exitCode()).thenReturn(0);
|
||||
when(processRunner.run(args, Duration.ofMinutes(15))).thenReturn(result);
|
||||
|
||||
assertDoesNotThrow(condaSetupManager::install);
|
||||
final var requestCapture = ArgumentCaptor.forClass(HttpRequest.class);
|
||||
verify(httpClient).send(requestCapture.capture(), any(HttpResponse.BodyHandler.class));
|
||||
final var request = requestCapture.getValue();
|
||||
assertEquals("https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh", request.uri().toString());
|
||||
verify(processRunner).run(args, Duration.ofMinutes(15));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInstallDownloadLinuxARM64(@TempDir final Path tempDir) throws IOException, InterruptedException {
|
||||
final var installerPath = tempDir.resolve("conda");
|
||||
when(configuration.condaInstallerPath()).thenReturn(installerPath);
|
||||
when(configuration.condaBundledPath()).thenReturn(tempDir);
|
||||
when(configuration.os()).thenReturn(OS.LINUX);
|
||||
when(configuration.architecture()).thenReturn(Architecture.ARM64);
|
||||
when(systemProcessResult.exitCode()).thenReturn(1);
|
||||
when(configuration.condaRootPath()).thenReturn(tempDir);
|
||||
|
||||
final var args = List.of("bash", installerPath.toString(), "-b", "-p", tempDir.toString());
|
||||
final var result = mock(ProcessResult.class);
|
||||
when(result.exitCode()).thenReturn(0);
|
||||
when(processRunner.run(args, Duration.ofMinutes(15))).thenReturn(result);
|
||||
|
||||
assertDoesNotThrow(condaSetupManager::install);
|
||||
final var requestCapture = ArgumentCaptor.forClass(HttpRequest.class);
|
||||
verify(httpClient).send(requestCapture.capture(), any(HttpResponse.BodyHandler.class));
|
||||
final var request = requestCapture.getValue();
|
||||
assertEquals("https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-aarch64.sh", request.uri().toString());
|
||||
verify(processRunner).run(args, Duration.ofMinutes(15));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInstallDownloadLinuxUnsupported(@TempDir final Path tempDir) throws IOException {
|
||||
final var installerPath = tempDir.resolve("conda");
|
||||
when(configuration.condaInstallerPath()).thenReturn(installerPath);
|
||||
when(configuration.condaBundledPath()).thenReturn(tempDir);
|
||||
when(configuration.os()).thenReturn(OS.LINUX);
|
||||
when(configuration.architecture()).thenReturn(Architecture.ARM32);
|
||||
when(systemProcessResult.exitCode()).thenReturn(1);
|
||||
when(configuration.condaRootPath()).thenReturn(tempDir);
|
||||
|
||||
assertThrows(SetupException.class, condaSetupManager::install);
|
||||
verifyNoInteractions(httpClient);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInstallDownloadMacAMD64(@TempDir final Path tempDir) throws IOException, InterruptedException {
|
||||
final var installerPath = tempDir.resolve("conda");
|
||||
when(configuration.condaInstallerPath()).thenReturn(installerPath);
|
||||
when(configuration.condaBundledPath()).thenReturn(tempDir);
|
||||
when(configuration.os()).thenReturn(OS.MAC);
|
||||
when(configuration.architecture()).thenReturn(Architecture.AMD64);
|
||||
when(systemProcessResult.exitCode()).thenReturn(1);
|
||||
when(configuration.condaRootPath()).thenReturn(tempDir);
|
||||
|
||||
final var args = List.of("bash", installerPath.toString(), "-b", "-p", tempDir.toString());
|
||||
final var result = mock(ProcessResult.class);
|
||||
when(result.exitCode()).thenReturn(0);
|
||||
when(processRunner.run(args, Duration.ofMinutes(15))).thenReturn(result);
|
||||
|
||||
assertDoesNotThrow(condaSetupManager::install);
|
||||
final var requestCapture = ArgumentCaptor.forClass(HttpRequest.class);
|
||||
verify(httpClient).send(requestCapture.capture(), any(HttpResponse.BodyHandler.class));
|
||||
final var request = requestCapture.getValue();
|
||||
assertEquals("https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-x86_64.sh", request.uri().toString());
|
||||
verify(processRunner).run(args, Duration.ofMinutes(15));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInstallDownloadMacARM64(@TempDir final Path tempDir) throws IOException, InterruptedException {
|
||||
final var installerPath = tempDir.resolve("conda");
|
||||
when(configuration.condaInstallerPath()).thenReturn(installerPath);
|
||||
when(configuration.condaBundledPath()).thenReturn(tempDir);
|
||||
when(configuration.os()).thenReturn(OS.MAC);
|
||||
when(configuration.architecture()).thenReturn(Architecture.ARM64);
|
||||
when(systemProcessResult.exitCode()).thenReturn(1);
|
||||
when(configuration.condaRootPath()).thenReturn(tempDir);
|
||||
|
||||
final var args = List.of("bash", installerPath.toString(), "-b", "-p", tempDir.toString());
|
||||
final var result = mock(ProcessResult.class);
|
||||
when(result.exitCode()).thenReturn(0);
|
||||
when(processRunner.run(args, Duration.ofMinutes(15))).thenReturn(result);
|
||||
|
||||
assertDoesNotThrow(condaSetupManager::install);
|
||||
final var requestCapture = ArgumentCaptor.forClass(HttpRequest.class);
|
||||
verify(httpClient).send(requestCapture.capture(), any(HttpResponse.BodyHandler.class));
|
||||
final var request = requestCapture.getValue();
|
||||
assertEquals("https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-arm64.sh", request.uri().toString());
|
||||
verify(processRunner).run(args, Duration.ofMinutes(15));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInstallDownloadMacUnsupported(@TempDir final Path tempDir) throws IOException {
|
||||
final var installerPath = tempDir.resolve("conda");
|
||||
when(configuration.condaInstallerPath()).thenReturn(installerPath);
|
||||
when(configuration.condaBundledPath()).thenReturn(tempDir);
|
||||
when(configuration.os()).thenReturn(OS.MAC);
|
||||
when(configuration.architecture()).thenReturn(Architecture.ARM32);
|
||||
when(systemProcessResult.exitCode()).thenReturn(1);
|
||||
when(configuration.condaRootPath()).thenReturn(tempDir);
|
||||
|
||||
assertThrows(SetupException.class, condaSetupManager::install);
|
||||
verifyNoInteractions(httpClient);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInstallDownloadUnsupported(@TempDir final Path tempDir) throws IOException {
|
||||
final var installerPath = tempDir.resolve("conda");
|
||||
when(configuration.condaInstallerPath()).thenReturn(installerPath);
|
||||
when(configuration.condaBundledPath()).thenReturn(tempDir);
|
||||
when(configuration.os()).thenReturn(OS.UNKNOWN);
|
||||
when(systemProcessResult.exitCode()).thenReturn(1);
|
||||
when(configuration.condaRootPath()).thenReturn(tempDir);
|
||||
|
||||
assertThrows(SetupException.class, condaSetupManager::install);
|
||||
verifyNoInteractions(httpClient);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void testInstallInstallerWindows(@TempDir final Path tempDir) throws IOException {
|
||||
final var installerPath = tempDir.resolve("conda");
|
||||
Files.createFile(installerPath);
|
||||
when(configuration.condaInstallerPath()).thenReturn(installerPath);
|
||||
when(configuration.condaBundledPath()).thenReturn(tempDir);
|
||||
when(configuration.os()).thenReturn(OS.WINDOWS);
|
||||
when(systemProcessResult.exitCode()).thenReturn(1);
|
||||
when(configuration.condaRootPath()).thenReturn(tempDir);
|
||||
|
||||
final var args = List.of(installerPath.toString(), "/InstallationType=JustMe", "/RegisterPython=0", "/S", "/D=" + tempDir.toString());
|
||||
final var result = mock(ProcessResult.class);
|
||||
when(result.exitCode()).thenReturn(0);
|
||||
when(processRunner.run(args, Duration.ofMinutes(15))).thenReturn(result);
|
||||
|
||||
assertDoesNotThrow(condaSetupManager::install);
|
||||
verify(processRunner).run(args, Duration.ofMinutes(15));
|
||||
verifyNoInteractions(httpClient);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void testInstallInstallerLinux(@TempDir final Path tempDir) throws IOException {
|
||||
final var installerPath = tempDir.resolve("conda");
|
||||
Files.createFile(installerPath);
|
||||
when(configuration.condaInstallerPath()).thenReturn(installerPath);
|
||||
when(configuration.condaBundledPath()).thenReturn(tempDir);
|
||||
when(configuration.os()).thenReturn(OS.LINUX);
|
||||
when(systemProcessResult.exitCode()).thenReturn(1);
|
||||
when(configuration.condaRootPath()).thenReturn(tempDir);
|
||||
|
||||
final var args = List.of("bash", installerPath.toString(), "-b", "-p", tempDir.toString());
|
||||
final var result = mock(ProcessResult.class);
|
||||
when(result.exitCode()).thenReturn(0);
|
||||
when(processRunner.run(args, Duration.ofMinutes(15))).thenReturn(result);
|
||||
|
||||
assertDoesNotThrow(condaSetupManager::install);
|
||||
verify(processRunner).run(args, Duration.ofMinutes(15));
|
||||
verifyNoInteractions(httpClient);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInstallInstallerLinuxIOException(@TempDir final Path tempDir) throws IOException {
|
||||
final var installerPath = tempDir.resolve("conda");
|
||||
Files.createFile(installerPath);
|
||||
when(configuration.condaInstallerPath()).thenReturn(installerPath);
|
||||
when(configuration.condaBundledPath()).thenReturn(tempDir);
|
||||
when(configuration.os()).thenReturn(OS.LINUX);
|
||||
when(systemProcessResult.exitCode()).thenReturn(1);
|
||||
when(configuration.condaRootPath()).thenReturn(tempDir);
|
||||
|
||||
final var args = List.of("bash", installerPath.toString(), "-b", "-p", tempDir.toString());
|
||||
when(processRunner.run(args, Duration.ofMinutes(15))).thenThrow(IOException.class);
|
||||
|
||||
assertThrows(SetupException.class, condaSetupManager::install);
|
||||
verify(processRunner).run(args, Duration.ofMinutes(15));
|
||||
verifyNoInteractions(httpClient);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInstallInstallerLinuxBadExitCode(@TempDir final Path tempDir) throws IOException {
|
||||
final var installerPath = tempDir.resolve("conda");
|
||||
Files.createFile(installerPath);
|
||||
when(configuration.condaInstallerPath()).thenReturn(installerPath);
|
||||
when(configuration.condaBundledPath()).thenReturn(tempDir);
|
||||
when(configuration.os()).thenReturn(OS.LINUX);
|
||||
when(systemProcessResult.exitCode()).thenReturn(1);
|
||||
when(configuration.condaRootPath()).thenReturn(tempDir);
|
||||
|
||||
final var args = List.of("bash", installerPath.toString(), "-b", "-p", tempDir.toString());
|
||||
final var result = mock(ProcessResult.class);
|
||||
when(result.exitCode()).thenReturn(1);
|
||||
when(processRunner.run(args, Duration.ofMinutes(15))).thenReturn(result);
|
||||
|
||||
assertThrows(SetupException.class, condaSetupManager::install);
|
||||
verify(processRunner).run(args, Duration.ofMinutes(15));
|
||||
verifyNoInteractions(httpClient);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void testInstallInstallerUnknown(@TempDir final Path tempDir) throws IOException {
|
||||
final var installerPath = tempDir.resolve("conda");
|
||||
Files.createFile(installerPath);
|
||||
when(configuration.condaInstallerPath()).thenReturn(installerPath);
|
||||
when(configuration.condaBundledPath()).thenReturn(tempDir);
|
||||
when(configuration.os()).thenReturn(OS.UNKNOWN);
|
||||
when(systemProcessResult.exitCode()).thenReturn(1);
|
||||
|
||||
assertThrows(SetupException.class, condaSetupManager::install);
|
||||
verifyNoInteractions(httpClient);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUninstall(@TempDir final Path tempDir) throws IOException {
|
||||
when(configuration.condaRootPath()).thenReturn(tempDir);
|
||||
Files.createDirectories(tempDir.resolve("sub"));
|
||||
Files.createFile(tempDir.resolve("sub").resolve("conda"));
|
||||
Files.createFile(tempDir.resolve("python"));
|
||||
assertDoesNotThrow(condaSetupManager::uninstall);
|
||||
assertFalse(Files.isDirectory(tempDir));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUpdateBundled() throws IOException {
|
||||
final var path = Path.of("test");
|
||||
final var args = List.of(path.toString(), "update", "-y", "conda");
|
||||
final var duration = Duration.ofMinutes(15);
|
||||
when(configuration.condaBundledPath()).thenReturn(path);
|
||||
when(systemProcessResult.exitCode()).thenReturn(1);
|
||||
final var processResult = mock(ProcessResult.class);
|
||||
when(processResult.exitCode()).thenReturn(0);
|
||||
when(processRunner.run(args, duration)).thenReturn(processResult);
|
||||
assertDoesNotThrow(condaSetupManager::update);
|
||||
verify(processRunner).run(args, duration);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUpdateSystemInstalled() throws IOException {
|
||||
final var args = List.of(systemPath.toString(), "update", "-y", "conda");
|
||||
final var duration = Duration.ofMinutes(15);
|
||||
final var processResult = mock(ProcessResult.class);
|
||||
when(processResult.exitCode()).thenReturn(0);
|
||||
when(processRunner.run(args, duration)).thenReturn(processResult);
|
||||
assertDoesNotThrow(condaSetupManager::update);
|
||||
verify(processRunner).run(args, duration);
|
||||
verify(processRunner).run(List.of(systemPath.toString(), "--version"), Duration.ofSeconds(5));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUpdateSystemIOException() throws IOException {
|
||||
when(processRunner.run(List.of(systemPath.toString(), "--version"), Duration.ofSeconds(5))).thenThrow(IOException.class);
|
||||
assertThrows(SetupException.class, condaSetupManager::update);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUpdateSystemBadVersion() {
|
||||
final var path = Path.of("test");
|
||||
when(systemProcessResult.output()).thenReturn(List.of("conda 9"));
|
||||
when(configuration.condaBundledPath()).thenReturn(path);
|
||||
when(configuration.condaSystemPath()).thenReturn(systemPath);
|
||||
assertThrows(SetupException.class, condaSetupManager::update);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void testUpdateBundleBadResultCode() throws IOException {
|
||||
final var path = Path.of("test");
|
||||
final var args = List.of(path.toString(), "update", "-y", "conda");
|
||||
final var duration = Duration.ofMinutes(15);
|
||||
when(systemProcessResult.exitCode()).thenReturn(1);
|
||||
when(configuration.condaBundledPath()).thenReturn(path);
|
||||
when(processRunner.run(args, duration)).thenReturn(systemProcessResult);
|
||||
when(systemProcessResult.exitCode()).thenReturn(1);
|
||||
assertThrows(SetupException.class, condaSetupManager::update);
|
||||
verify(processRunner).run(args, duration);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUpdateBundleIOException() throws IOException {
|
||||
final var path = Path.of("test");
|
||||
final var args = List.of(path.toString(), "update", "-y", "conda");
|
||||
final var duration = Duration.ofMinutes(15);
|
||||
when(systemProcessResult.exitCode()).thenReturn(1);
|
||||
when(configuration.condaBundledPath()).thenReturn(path);
|
||||
when(processRunner.run(args, duration)).thenThrow(IOException.class);
|
||||
assertThrows(SetupException.class, condaSetupManager::update);
|
||||
verify(processRunner).run(args, duration);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCreateVenv() throws IOException {
|
||||
final var path = Paths.get("test");
|
||||
final var args = List.of(systemPath.toString(), "create", "-y", "-p", path.toString(), "python=" + PYTHON_VERSION, "p1", "p2");
|
||||
final var result = mock(ProcessResult.class);
|
||||
when(result.exitCode()).thenReturn(0);
|
||||
when(configuration.os()).thenReturn(OS.LINUX);
|
||||
when(processRunner.run(args, Duration.ofMinutes(15))).thenReturn(result);
|
||||
assertDoesNotThrow(() -> condaSetupManager.createVenv(path, PYTHON_VERSION, PACKAGES));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCreateVenvWindows(@TempDir final Path tempDir) throws IOException {
|
||||
final var path = tempDir.resolve("test");
|
||||
final var bin = path.resolve("Library").resolve("bin");
|
||||
Files.createDirectories(bin);
|
||||
final var crypto1 = bin.resolve("libcrypto-1.1.dll");
|
||||
final var crypto2 = bin.resolve("libcrypto-2.sdf");
|
||||
final var ssl1 = bin.resolve("libssl-1.1.dll");
|
||||
final var ssl2 = bin.resolve("libssl-2.sdf");
|
||||
final var other = bin.resolve("other.dll");
|
||||
final var dlls = path.resolve("DLLs");
|
||||
for (final var path1 : List.of(crypto1, crypto2, ssl1, ssl2, other)) {
|
||||
Files.createFile(path1);
|
||||
}
|
||||
final var args = List.of(systemPath.toString(), "create", "-y", "-p", path.toString(), "python=" + PYTHON_VERSION, "p1", "p2");
|
||||
final var result = mock(ProcessResult.class);
|
||||
when(result.exitCode()).thenReturn(0);
|
||||
when(configuration.os()).thenReturn(OS.WINDOWS);
|
||||
when(processRunner.run(args, Duration.ofMinutes(15))).thenReturn(result);
|
||||
assertDoesNotThrow(() -> condaSetupManager.createVenv(path, PYTHON_VERSION, PACKAGES));
|
||||
for (final var path1 : List.of(crypto1, crypto2, ssl1, ssl2)) {
|
||||
assertTrue(Files.exists(dlls.resolve(path1.getFileName())));
|
||||
}
|
||||
assertFalse(Files.exists(dlls.resolve(other.getFileName())));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCreateVenvIOException() throws IOException {
|
||||
final var path = Paths.get("test");
|
||||
final var args = List.of(systemPath.toString(), "create", "-y", "-p", path.toString(), "python=" + PYTHON_VERSION, "p1", "p2");
|
||||
when(processRunner.run(args, Duration.ofMinutes(15))).thenThrow(IOException.class);
|
||||
assertThrows(SetupException.class, () -> condaSetupManager.createVenv(path, PYTHON_VERSION, PACKAGES));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCreateVenvBadResultCode() throws IOException {
|
||||
final var path = Paths.get("test");
|
||||
final var args = List.of(systemPath.toString(), "create", "-y", "-p", path.toString(), "python=" + PYTHON_VERSION, "p1", "p2");
|
||||
final var result = mock(ProcessResult.class);
|
||||
when(result.exitCode()).thenReturn(1);
|
||||
when(processRunner.run(args, Duration.ofMinutes(15))).thenReturn(result);
|
||||
assertThrows(SetupException.class, () -> condaSetupManager.createVenv(path, PYTHON_VERSION, PACKAGES));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testVenvExists(@TempDir final Path tempDirectory) throws IOException {
|
||||
assertFalse(condaSetupManager.venvExists(tempDirectory));
|
||||
Files.createDirectories(tempDirectory.resolve("bin"));
|
||||
|
||||
when(configuration.os()).thenReturn(OS.WINDOWS);
|
||||
Files.createFile(tempDirectory.resolve("bin").resolve("python.exe"));
|
||||
assertTrue(condaSetupManager.venvExists(tempDirectory));
|
||||
|
||||
when(configuration.os()).thenReturn(OS.LINUX);
|
||||
assertFalse(condaSetupManager.venvExists(tempDirectory));
|
||||
|
||||
Files.createFile(tempDirectory.resolve("bin").resolve("python"));
|
||||
assertTrue(condaSetupManager.venvExists(tempDirectory));
|
||||
|
||||
when(configuration.os()).thenReturn(OS.MAC);
|
||||
assertTrue(condaSetupManager.venvExists(tempDirectory));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIllegal() {
|
||||
assertThrows(NullPointerException.class, () -> new CondaSetupManager(null, processRunner, httpClient));
|
||||
assertThrows(NullPointerException.class, () -> new CondaSetupManager(configuration, null, httpClient));
|
||||
assertThrows(NullPointerException.class, () -> new CondaSetupManager(configuration, processRunner, null));
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user