test: Fix Windows tests (#598)
* Prevent IntelliJ from making * imports * Move IntelliJ part of .gitnignore under .idea * Update IntelliJ part of .gitignore This setup is based on community using the IntelliJ and prevents quite o lot sensitive files or plugin-related configs from being committed. * Handle ACLs for Win in permission test * Also delete DELETE* ACLs permissions * Set isPosix before test from tempDir's FSmaster
parent
6fbb9175c1
commit
676fc3e26f
|
@ -9,8 +9,6 @@
|
||||||
*.iws
|
*.iws
|
||||||
/out/
|
/out/
|
||||||
.attach_*
|
.attach_*
|
||||||
# Allow-list for sharing some IntelliJ IDEA configurations
|
|
||||||
!.idea/
|
|
||||||
|
|
||||||
# Ignore Eclipse
|
# Ignore Eclipse
|
||||||
.project
|
.project
|
||||||
|
|
|
@ -1,27 +1,65 @@
|
||||||
# Docs on sharing your IntelliJ config are at
|
# Docs on sharing your IntelliJ config are at
|
||||||
# https://www.jetbrains.com/help/idea/creating-and-managing-projects.html#share-project-through-vcs
|
# https://www.jetbrains.com/help/idea/creating-and-managing-projects.html#share-project-through-vcs
|
||||||
|
# Based on https://www.toptal.com/developers/gitignore/api/intellij
|
||||||
|
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||||
|
|
||||||
# Workspace files. Universally agreed as user-specific and not-for-sharing.
|
# Workspace files. Universally agreed as user-specific and not-for-sharing.
|
||||||
workspace.xml
|
workspace.xml
|
||||||
*.iws
|
|
||||||
|
|
||||||
# Shelf is where it put changes you're not ready to share. (it's like git stash)
|
# User-specific stuff
|
||||||
/shelf
|
/**/workspace.xml
|
||||||
|
/**/tasks.xml
|
||||||
|
/**/usage.statistics.xml
|
||||||
|
/**/shelf
|
||||||
|
|
||||||
# Dictionaries: do not ignore!
|
# Generated files
|
||||||
# /dictionaries
|
/**/contentModel.xml
|
||||||
# Yes, it makes a new file for each user, but JetBrains product manager Dmitry Jemerov explains:
|
|
||||||
#
|
|
||||||
# > The dictionary is not in fact per-user; the spellchecker uses words from all users'
|
|
||||||
# > dictionaries for checking the spelling.
|
|
||||||
# — https://youtrack.jetbrains.com/issue/WI-45679#focus=streamItem-27-3457290.0-0
|
|
||||||
|
|
||||||
# managed by gradle sync
|
# Sensitive or high-churn files
|
||||||
/gradle.xml
|
/**/dataSources/
|
||||||
/libraries
|
/**/dataSources.ids
|
||||||
|
/**/dataSources.local.xml
|
||||||
|
/**/sqlDataSources.xml
|
||||||
|
/**/dynamic.xml
|
||||||
|
/**/uiDesigner.xml
|
||||||
|
/**/dbnavigator.xml
|
||||||
|
|
||||||
# generated by idea
|
# Gradle
|
||||||
|
/**/gradle.xml
|
||||||
|
/**/libraries
|
||||||
|
|
||||||
|
# Gradle and Maven with auto-import
|
||||||
|
# When using Gradle or Maven with auto-import, you should exclude module files,
|
||||||
|
# since they will be recreated, and may cause churn. Uncomment if using
|
||||||
|
# auto-import.
|
||||||
|
/artifacts
|
||||||
|
/compiler.xml
|
||||||
/jarRepositories.xml
|
/jarRepositories.xml
|
||||||
/uiDesigner.xml
|
|
||||||
/modules.xml
|
/modules.xml
|
||||||
/modules
|
/modules
|
||||||
|
|
||||||
|
# Sonarlint plugin
|
||||||
|
# https://plugins.jetbrains.com/plugin/7973-sonarlint
|
||||||
|
/**/sonarlint/
|
||||||
|
|
||||||
|
# SonarQube Plugin
|
||||||
|
# https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin
|
||||||
|
/**/sonarIssues.xml
|
||||||
|
|
||||||
|
# Markdown Navigator plugin
|
||||||
|
# https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced
|
||||||
|
/**/markdown-navigator.xml
|
||||||
|
/**/markdown-navigator-enh.xml
|
||||||
|
/**/markdown-navigator/
|
||||||
|
|
||||||
|
# Cache file creation bug
|
||||||
|
# See https://youtrack.jetbrains.com/issue/JBR-2257
|
||||||
|
/$CACHE_FILE$
|
||||||
|
|
||||||
|
# CodeStream plugin
|
||||||
|
# https://plugins.jetbrains.com/plugin/12206-codestream
|
||||||
|
/codestream.xml
|
||||||
|
|
||||||
|
# AWS toolkit plugin
|
||||||
|
#https://plugins.jetbrains.com/plugin/11349-aws-toolkit
|
||||||
|
/aws.xml
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
<component name="ProjectCodeStyleConfiguration">
|
||||||
|
<code_scheme name="Project" version="173">
|
||||||
|
<JavaCodeStyleSettings>
|
||||||
|
<option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="999" />
|
||||||
|
<option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="999" />
|
||||||
|
<option name="PACKAGES_TO_USE_IMPORT_ON_DEMAND">
|
||||||
|
<value />
|
||||||
|
</option>
|
||||||
|
</JavaCodeStyleSettings>
|
||||||
|
<JetCodeStyleSettings>
|
||||||
|
<option name="PACKAGES_TO_USE_STAR_IMPORTS">
|
||||||
|
<value>
|
||||||
|
<package name="java.util" alias="false" withSubpackages="false" />
|
||||||
|
<package name="kotlinx.android.synthetic" alias="false" withSubpackages="true" />
|
||||||
|
<package name="io.ktor" alias="false" withSubpackages="true" />
|
||||||
|
</value>
|
||||||
|
</option>
|
||||||
|
<option name="PACKAGES_IMPORT_LAYOUT">
|
||||||
|
<value>
|
||||||
|
<package name="" alias="false" withSubpackages="true" />
|
||||||
|
<package name="java" alias="false" withSubpackages="true" />
|
||||||
|
<package name="javax" alias="false" withSubpackages="true" />
|
||||||
|
<package name="kotlin" alias="false" withSubpackages="true" />
|
||||||
|
<package name="" alias="true" withSubpackages="true" />
|
||||||
|
</value>
|
||||||
|
</option>
|
||||||
|
</JetCodeStyleSettings>
|
||||||
|
</code_scheme>
|
||||||
|
</component>
|
|
@ -0,0 +1,5 @@
|
||||||
|
<component name="ProjectCodeStyleConfiguration">
|
||||||
|
<state>
|
||||||
|
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
|
||||||
|
</state>
|
||||||
|
</component>
|
|
@ -17,6 +17,7 @@
|
||||||
package org.terasology.launcher.util;
|
package org.terasology.launcher.util;
|
||||||
|
|
||||||
import org.hamcrest.Matchers;
|
import org.hamcrest.Matchers;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.io.TempDir;
|
import org.junit.jupiter.api.io.TempDir;
|
||||||
import org.spf4j.log.Level;
|
import org.spf4j.log.Level;
|
||||||
|
@ -28,8 +29,12 @@ import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.file.DirectoryNotEmptyException;
|
import java.nio.file.DirectoryNotEmptyException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.attribute.PosixFilePermissions;
|
import java.nio.file.attribute.AclEntry;
|
||||||
|
import java.nio.file.attribute.AclEntryPermission;
|
||||||
|
import java.nio.file.attribute.AclFileAttributeView;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipEntry;
|
||||||
import java.util.zip.ZipOutputStream;
|
import java.util.zip.ZipOutputStream;
|
||||||
|
@ -50,19 +55,42 @@ public class TestFileUtils {
|
||||||
|
|
||||||
@TempDir
|
@TempDir
|
||||||
public Path tempFolder;
|
public Path tempFolder;
|
||||||
|
boolean isPosix;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setup() {
|
||||||
|
isPosix = tempFolder.getFileSystem().supportedFileAttributeViews().contains("posix");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCannotCreateDirectory() {
|
public void testCannotCreateDirectory() throws IOException {
|
||||||
final Path directory = tempFolder.resolve(DIRECTORY_NAME);
|
final Path directory = tempFolder.resolve(DIRECTORY_NAME);
|
||||||
var tempFolderFile = tempFolder.toFile();
|
var tempFolderFile = tempFolder.toFile();
|
||||||
assert tempFolderFile.setWritable(false);
|
|
||||||
|
// Unfortunately, Win is not POSIX perms compatible, it uses own ACL system
|
||||||
|
List<AclEntry> originalAcl = null;
|
||||||
|
AclFileAttributeView view = null;
|
||||||
|
|
||||||
|
if (isPosix) {
|
||||||
|
assert tempFolderFile.setWritable(false);
|
||||||
|
} else {
|
||||||
|
view = Files.getFileAttributeView(directory.getParent(), AclFileAttributeView.class);
|
||||||
|
originalAcl = view.getAcl();
|
||||||
|
removeAclS(view, false);
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
assertThrows(IOException.class, () ->
|
assertThrows(IOException.class, () ->
|
||||||
FileUtils.ensureWritableDir(directory)
|
FileUtils.ensureWritableDir(directory)
|
||||||
);
|
);
|
||||||
} finally {
|
} finally {
|
||||||
assert tempFolderFile.setWritable(true); // so @TempDir can tidy up
|
// so @TempDir can tidy up
|
||||||
|
if (isPosix) {
|
||||||
|
assert tempFolderFile.setWritable(true);
|
||||||
|
} else {
|
||||||
|
assert view != null;
|
||||||
|
view.setAcl(originalAcl);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,7 +108,21 @@ public class TestFileUtils {
|
||||||
@Test
|
@Test
|
||||||
public void testNoPerms() throws IOException {
|
public void testNoPerms() throws IOException {
|
||||||
var directory = tempFolder.resolve(DIRECTORY_NAME);
|
var directory = tempFolder.resolve(DIRECTORY_NAME);
|
||||||
Files.createDirectory(directory, PosixFilePermissions.asFileAttribute(Collections.emptySet()));
|
Files.createDirectory(directory);
|
||||||
|
var d = directory.toFile();
|
||||||
|
|
||||||
|
// Unfortunately, Win is not POSIX perms compatible, it uses own ACL system
|
||||||
|
List<AclEntry> originalAcl = null;
|
||||||
|
AclFileAttributeView view = null;
|
||||||
|
|
||||||
|
if (isPosix) {
|
||||||
|
assert d.setReadable(false);
|
||||||
|
assert d.setWritable(false);
|
||||||
|
} else {
|
||||||
|
view = Files.getFileAttributeView(directory, AclFileAttributeView.class);
|
||||||
|
originalAcl = view.getAcl();
|
||||||
|
removeAclS(view, true);
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var exc = assertThrows(IOException.class, () ->
|
var exc = assertThrows(IOException.class, () ->
|
||||||
|
@ -89,9 +131,13 @@ public class TestFileUtils {
|
||||||
assertThat(exc.getMessage(), startsWith("Missing read or write permissions"));
|
assertThat(exc.getMessage(), startsWith("Missing read or write permissions"));
|
||||||
} finally {
|
} finally {
|
||||||
// oh no, @TempDir doesn't know how to delete this! make it writable again.
|
// oh no, @TempDir doesn't know how to delete this! make it writable again.
|
||||||
var d = directory.toFile();
|
if (isPosix) {
|
||||||
assert d.setReadable(true);
|
assert d.setReadable(true);
|
||||||
assert d.setWritable(true);
|
assert d.setWritable(true);
|
||||||
|
} else {
|
||||||
|
assert view != null;
|
||||||
|
view.setAcl(originalAcl);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,4 +281,28 @@ public class TestFileUtils {
|
||||||
assertEquals(file1Contents, Files.readAllLines(extractedFileInRoot).get(0));
|
assertEquals(file1Contents, Files.readAllLines(extractedFileInRoot).get(0));
|
||||||
assertEquals(file2Contents, Files.readAllLines(extractedFileInFolder).get(0));
|
assertEquals(file2Contents, Files.readAllLines(extractedFileInFolder).get(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void removeAclS(AclFileAttributeView view, boolean removeRead) throws IOException {
|
||||||
|
var entries = new ArrayList<AclEntry>();
|
||||||
|
for (var acl : view.getAcl()) {
|
||||||
|
var perms = new LinkedHashSet<>(acl.permissions());
|
||||||
|
perms.remove(AclEntryPermission.WRITE_DATA);
|
||||||
|
perms.remove(AclEntryPermission.APPEND_DATA);
|
||||||
|
perms.remove(AclEntryPermission.ADD_SUBDIRECTORY);
|
||||||
|
perms.remove(AclEntryPermission.DELETE);
|
||||||
|
perms.remove(AclEntryPermission.DELETE_CHILD);
|
||||||
|
if (removeRead) {
|
||||||
|
perms.remove(AclEntryPermission.READ_DATA);
|
||||||
|
}
|
||||||
|
var aclEntry = AclEntry.newBuilder()
|
||||||
|
.setType(acl.type())
|
||||||
|
.setPrincipal(acl.principal())
|
||||||
|
.setPermissions(perms)
|
||||||
|
.setFlags(acl.flags())
|
||||||
|
.build();
|
||||||
|
entries.add(aclEntry);
|
||||||
|
}
|
||||||
|
view.setAcl(entries);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue