blob: 5dbe2dd1ae768a42386d14d7a40bd0ff2e2a44e9 [file] [log] [blame]
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.util.io;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.*;
import java.net.URL;
import java.util.Locale;
import java.util.Set;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import static org.junit.Assert.*;
public class IoTestUtil {
private IoTestUtil() { }
@NotNull
public static File createSymLink(@NotNull String target, @NotNull String link) throws InterruptedException, IOException {
return createSymLink(target, link, true);
}
@NotNull
public static File createSymLink(@NotNull String target, @NotNull String link, boolean shouldExist) throws InterruptedException, IOException {
assertTrue(SystemInfo.isWindows || SystemInfo.isUnix);
final File targetFile = new File(FileUtil.toSystemDependentName(target));
final File linkFile = getFullLinkPath(link);
final ProcessBuilder command;
if (SystemInfo.isWindows) {
command = targetFile.isDirectory()
? new ProcessBuilder("cmd", "/C", "mklink", "/D", linkFile.getPath(), targetFile.getPath())
: new ProcessBuilder("cmd", "/C", "mklink", linkFile.getPath(), targetFile.getPath());
}
else {
command = new ProcessBuilder("ln", "-s", targetFile.getPath(), linkFile.getPath());
}
final int res = runCommand(command);
assertEquals(command.command().toString(), 0, res);
shouldExist |= SystemInfo.isWindows && SystemInfo.JAVA_VERSION.startsWith("1.6");
assertEquals("target=" + target + ", link=" + linkFile, shouldExist, linkFile.exists());
return linkFile;
}
@NotNull
public static File createHardLink(@NotNull String target, @NotNull String link) throws InterruptedException, IOException {
assertTrue(SystemInfo.isWindows || SystemInfo.isUnix);
final File targetFile = new File(FileUtil.toSystemDependentName(target));
final File linkFile = getFullLinkPath(link);
final ProcessBuilder command;
if (SystemInfo.isWindows) {
command = new ProcessBuilder("fsutil", "hardlink", "create", linkFile.getPath(), targetFile.getPath());
}
else {
command = new ProcessBuilder("ln", targetFile.getPath(), linkFile.getPath());
}
final int res = runCommand(command);
assertEquals(command.command().toString(), 0, res);
assertTrue("target=" + target + ", link=" + linkFile, linkFile.exists());
return linkFile;
}
@NotNull
public static File createJunction(@NotNull String target, @NotNull String junction) throws InterruptedException, IOException {
assertTrue(SystemInfo.isWindows);
final File targetFile = new File(FileUtil.toSystemDependentName(target));
assertTrue(targetFile.getPath(), targetFile.isDirectory());
final String exePath = getJunctionExePath();
final File junctionFile = getFullLinkPath(junction);
final ProcessBuilder command = new ProcessBuilder(exePath, junctionFile.getPath(), targetFile.getPath());
final int res = runCommand(command);
assertEquals(command.command().toString(), 0, res);
assertTrue("target=" + target + ", link=" + junctionFile, junctionFile.isDirectory());
return junctionFile;
}
@NotNull
public static File createSubst(@NotNull String target) throws InterruptedException, IOException {
assertTrue(SystemInfo.isWindows);
final File targetFile = new File(FileUtil.toSystemDependentName(target));
assertTrue(targetFile.getPath(), targetFile.isDirectory());
final String substRoot = getFirstFreeDriveLetter() + ":";
final ProcessBuilder command = new ProcessBuilder("subst", substRoot, targetFile.getPath());
final int res = runCommand(command);
assertEquals(command.command().toString(), 0, res);
final File rootFile = new File(substRoot + "\\");
assertTrue("target=" + target + ", subst=" + rootFile, rootFile.isDirectory());
return rootFile;
}
public static void deleteSubst(@NotNull String substRoot) throws InterruptedException, IOException {
runCommand(new ProcessBuilder("subst", StringUtil.trimEnd(substRoot, "\\"), "/d"));
}
private static char getFirstFreeDriveLetter() {
final Set<Character> roots = ContainerUtil.map2Set(File.listRoots(), new Function<File, Character>() {
@Override
public Character fun(File root) {
return root.getPath().toUpperCase(Locale.US).charAt(0);
}
});
char drive = 0;
for (char c = 'E'; c <= 'Z'; c++) {
if (!roots.contains(c)) {
drive = c;
break;
}
}
assertFalse("Occupied: " + roots.toString(), drive == 0);
return drive;
}
private static File getFullLinkPath(String link) {
File linkFile = new File(FileUtil.toSystemDependentName(link));
if (!linkFile.isAbsolute()) {
linkFile = new File(FileUtil.getTempDirectory(), link);
}
assertTrue(link, !linkFile.exists() || linkFile.delete());
final File parentDir = linkFile.getParentFile();
assertTrue("link=" + link + ", parent=" + parentDir, parentDir != null && (parentDir.isDirectory() || parentDir.mkdirs()));
return linkFile;
}
private static String getJunctionExePath() throws IOException, InterruptedException {
final URL url = IoTestUtil.class.getClassLoader().getResource("junction.exe");
assertNotNull(url);
final String path = url.getFile();
final File util = new File(path);
assertTrue(util.exists());
final ProcessBuilder command = new ProcessBuilder(path, "/acceptEULA");
final int res = runCommand(command);
assertEquals(command.command().toString(), -1, res);
return path;
}
private static int runCommand(final ProcessBuilder command) throws IOException, InterruptedException {
final Process process = command.start();
new Thread(new Runnable() {
@Override
public void run() {
try {
final BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
try {
//noinspection StatementWithEmptyBody
while (reader.readLine() != null);
}
finally {
reader.close();
}
}
catch (IOException e) {
throw new RuntimeException(e);
}
}
}).start();
return process.waitFor();
}
public static void assertTimestampsEqual(final long expected, final long actual) {
final long roundedExpected = (expected / 1000) * 1000;
final long roundedActual = (actual / 1000) * 1000;
assertEquals("expected: " + expected + ", actual: " + actual,
roundedExpected, roundedActual);
}
public static void assertTimestampsNotEqual(final long expected, final long actual) {
final long roundedExpected = (expected / 1000) * 1000;
final long roundedActual = (actual / 1000) * 1000;
assertTrue("(un)expected: " + expected + ", actual: " + actual,
roundedExpected != roundedActual);
}
@NotNull
public static File createTestJar() throws IOException {
File jarFile = FileUtil.createTempFile("test.", ".jar");
return createTestJar(jarFile);
}
@NotNull
public static File createTestJar(File jarFile) throws IOException {
return createTestJar(jarFile, JarFile.MANIFEST_NAME, "");
}
@NotNull
public static File createTestJar(@NotNull File jarFile, @NotNull String... data) throws IOException {
ZipOutputStream stream = new ZipOutputStream(new FileOutputStream(jarFile));
try {
for (int i = 0; i < data.length; i += 2) {
stream.putNextEntry(new ZipEntry(data[i]));
stream.write(data[i + 1].getBytes("UTF-8"));
stream.closeEntry();
}
}
finally {
stream.close();
}
return jarFile;
}
@NotNull
public static File createTestDir(@NotNull String name) {
return createTestDir(new File(FileUtil.getTempDirectory()), name);
}
@NotNull
public static File createTestDir(@NotNull File parent, @NotNull String name) {
File dir = new File(parent, name);
assertTrue(dir.getPath(), dir.mkdirs());
return dir;
}
@NotNull
public static File createTestFile(@NotNull String name) throws IOException {
return createTestFile(name, null);
}
@NotNull
public static File createTestFile(@NotNull String name, @Nullable String content) throws IOException {
return createTestFile(new File(FileUtil.getTempDirectory()), name, content);
}
@NotNull
public static File createTestFile(@NotNull File parent, @NotNull String name) throws IOException {
return createTestFile(parent, name, null);
}
@NotNull
public static File createTestFile(@NotNull File parent, @NotNull String name, @Nullable String content) throws IOException {
assertTrue(parent.getPath(), parent.isDirectory() || parent.mkdirs());
File file = new File(parent, name);
assertTrue(file.getPath(), file.createNewFile());
if (content != null) {
FileUtil.writeToFile(file, content);
}
return file;
}
public static void delete(File... files) {
for (File file : files) {
if (file != null) {
FileUtil.delete(file);
}
}
}
public static void setHidden(@NotNull String path, boolean hidden) throws IOException, InterruptedException {
assertTrue(SystemInfo.isWindows);
ProcessBuilder command = new ProcessBuilder("attrib", hidden ? "+H" : "-H", path);
int res = runCommand(command);
assertEquals(command.command().toString(), 0, res);
}
}