1 package com.pty4j; 2 3 import com.google.common.base.Function; 4 import com.pty4j.util.PtyUtil; 5 import com.sun.jna.Platform; 6 import com.sun.jna.platform.win32.Kernel32; 7 import jtermios.JTermios; 8 import org.apache.log4j.Logger; 9 import org.jetbrains.annotations.NotNull; 10 import org.jetbrains.annotations.Nullable; 11 12 import java.io.File; 13 import java.net.MalformedURLException; 14 import java.net.URISyntaxException; 15 import java.net.URL; 16 import java.nio.file.Path; 17 import java.nio.file.Paths; 18 import java.util.ArrayList; 19 import java.util.Arrays; 20 import java.util.List; 21 import java.util.Objects; 22 import java.util.regex.Pattern; 23 import java.util.stream.Collectors; 24 25 /** 26 * @author traff 27 */ 28 public class TestUtil { 29 getTestDataPath()30 public static @NotNull String getTestDataPath() { 31 return Paths.get("test/testData").toAbsolutePath().normalize().toString(); 32 } 33 34 @NotNull getJavaCommand(@otNull Class<?> aClass, String... args)35 public static String[] getJavaCommand(@NotNull Class<?> aClass, String... args) { 36 List<String> result = new ArrayList<>(); 37 result.add(getJavaExecutablePath()); 38 result.add("-cp"); 39 result.add(getJarPathForClasses(aClass, WinSize.class, Logger.class, JTermios.class, Platform.class, 40 Kernel32.class, Function.class)); 41 result.add(aClass.getName()); 42 result.addAll(Arrays.asList(args)); 43 return result.toArray(new String[0]); 44 } 45 46 @NotNull getJavaExecutablePath()47 private static String getJavaExecutablePath() { 48 return System.getProperty("java.home") + File.separator + "bin" 49 + File.separator + (Platform.isWindows() ? "java.exe" : "java"); 50 } 51 52 /** 53 * Copied from com.intellij.openapi.application.PathManager#getJarPathForClass. 54 */ 55 @NotNull getJarPathForClass(@otNull Class<?> aClass)56 private static String getJarPathForClass(@NotNull Class<?> aClass) { 57 String resourceRoot = getResourceRoot(aClass, "/" + aClass.getName().replace('.', '/') + ".class"); 58 return new File(Objects.requireNonNull(resourceRoot)).getAbsolutePath(); 59 } 60 getJarPathForClasses(@otNull Class<?>.... classes)61 private static String getJarPathForClasses(@NotNull Class<?>... classes) { 62 List<String> paths = Arrays.stream(classes).map(TestUtil::getJarPathForClass).collect(Collectors.toList()); 63 return String.join(Platform.isWindows() ? ";" : ":", paths); 64 } 65 66 @Nullable getResourceRoot(@otNull Class<?> context, @NotNull String path)67 private static String getResourceRoot(@NotNull Class<?> context, @NotNull String path) { 68 URL url = context.getResource(path); 69 if (url == null) { 70 url = ClassLoader.getSystemResource(path.substring(1)); 71 } 72 return url != null ? extractRoot(url, path) : null; 73 } 74 75 @NotNull extractRoot(@otNull URL resourceURL, @NotNull String resourcePath)76 private static String extractRoot(@NotNull URL resourceURL, @NotNull String resourcePath) { 77 if (!resourcePath.startsWith("/") && !resourcePath.startsWith("\\")) { 78 throw new IllegalStateException("precondition failed: " + resourcePath); 79 } 80 81 String resultPath = null; 82 String protocol = resourceURL.getProtocol(); 83 if ("file".equals(protocol)) { 84 String path = urlToFile(resourceURL).getPath(); 85 String testPath = path.replace('\\', '/'); 86 String testResourcePath = resourcePath.replace('\\', '/'); 87 if (testPath.endsWith(testResourcePath)) { 88 resultPath = path.substring(0, path.length() - resourcePath.length()); 89 } 90 } 91 else if ("jar".equals(protocol)) { 92 resultPath = getJarPath(resourceURL.getFile()); 93 } 94 95 if (resultPath == null) { 96 throw new IllegalStateException("Cannot extract '" + resourcePath + "' from '" + resourceURL + "', " + protocol); 97 } 98 return resultPath; 99 } 100 101 @NotNull urlToFile(@otNull URL url)102 private static File urlToFile(@NotNull URL url) { 103 try { 104 return new File(url.toURI().getSchemeSpecificPart()); 105 } 106 catch (URISyntaxException e) { 107 throw new IllegalArgumentException("URL='" + url.toString() + "'", e); 108 } 109 } 110 getJarPath(@otNull String urlFilePart)111 private static @Nullable String getJarPath(@NotNull String urlFilePart) { 112 int pivot = urlFilePart.indexOf("!/"); 113 if (pivot < 0) { 114 return null; 115 } 116 String fileUrlStr = urlFilePart.substring(0, pivot); 117 118 String filePrefix = "file:"; 119 if (!fileUrlStr.startsWith(filePrefix)) { 120 return fileUrlStr; 121 } 122 123 URL fileUrl; 124 try { 125 fileUrl = new URL(fileUrlStr); 126 } 127 catch (MalformedURLException e) { 128 return null; 129 } 130 131 File result = urlToFile(fileUrl); 132 return result.getPath().replace('\\', '/'); 133 } 134 135 @NotNull getBuiltNativeFolder()136 public static Path getBuiltNativeFolder() { 137 return Paths.get("os").toAbsolutePath().normalize(); 138 } 139 setLocalPtyLib()140 public static void setLocalPtyLib() { 141 if ("false".equals(System.getProperty(PtyUtil.PREFERRED_NATIVE_FOLDER_KEY))) { 142 System.clearProperty(PtyUtil.PREFERRED_NATIVE_FOLDER_KEY); 143 } 144 else { 145 System.setProperty(PtyUtil.PREFERRED_NATIVE_FOLDER_KEY, getBuiltNativeFolder().toString()); 146 } 147 } 148 assertConsoleExists()149 public static void assertConsoleExists() { 150 if (System.console() == null) { 151 System.err.println("Not a terminal"); 152 System.exit(1); 153 } 154 } 155 getTestWaitTimeoutSeconds()156 public static int getTestWaitTimeoutSeconds() { 157 String valueStr = System.getenv("PTY4J_TEST_TIMEOUT_SECONDS"); 158 if (valueStr != null) { 159 try { 160 int value = Integer.parseInt(valueStr); 161 if (value > 0) { 162 System.out.println("pty4j test timeout is set to " + value + " seconds"); 163 return value; 164 } 165 } 166 catch (NumberFormatException ignored) { 167 } 168 } 169 return 60; 170 } 171 findInPath(@otNull String fileName)172 public static @Nullable File findInPath(@NotNull String fileName) { 173 String pathValue = System.getenv("PATH"); 174 if (pathValue == null) { 175 return null; 176 } 177 List<String> dirPaths = getPathDirs(pathValue); 178 for (String dirPath : dirPaths) { 179 File dir = new File(dirPath); 180 if (dir.isAbsolute() && dir.isDirectory()) { 181 File exeFile = new File(dir, fileName); 182 if (exeFile.isFile() && exeFile.canExecute()) { 183 return exeFile; 184 } 185 } 186 } 187 return null; 188 } 189 getPathDirs(@otNull String pathEnvVarValue)190 private static @NotNull List<String> getPathDirs(@NotNull String pathEnvVarValue) { 191 return Arrays.asList(pathEnvVarValue.split(Pattern.quote(File.pathSeparator))); 192 } 193 } 194