8344770: Switch jpackage unit tests to use JUnit5

Reviewed-by: almatvee
This commit is contained in:
Alexey Semenyuk 2024-11-27 12:42:34 +00:00
parent 494806286f
commit 4a22c1fefc
11 changed files with 769 additions and 766 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -31,17 +31,19 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.LinkedHashMap;
import org.junit.Assert;
import org.junit.Test;
import org.junit.Rule;
import org.junit.rules.TemporaryFolder;
import org.junit.function.ThrowingRunnable;
import java.util.stream.Stream;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrowsExactly;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
public class AppImageFileTest {
@Rule
public final TemporaryFolder tempFolder = new TemporaryFolder();
@Test
public void testIdentity() throws IOException {
Map<String, Object> params = new LinkedHashMap<>();
@ -51,7 +53,7 @@ public class AppImageFileTest {
params.put(Arguments.CLIOptions.DESCRIPTION.getId(), "Duck is the King");
AppImageFile aif = create(params);
Assert.assertEquals("Foo", aif.getLauncherName());
assertEquals("Foo", aif.getLauncherName());
}
@Test
@ -73,39 +75,59 @@ public class AppImageFileTest {
create(params);
}
@Test
public void testInavlidXml() throws IOException {
assertInvalid(() -> createFromXml("<foo/>"));
assertInvalid(() -> createFromXml("<jpackage-state/>"));
assertInvalid(() -> createFromXml(JPACKAGE_STATE_OPEN, "</jpackage-state>"));
assertInvalid(() -> createFromXml(
@ParameterizedTest
@MethodSource
public void testInavlidXml(String[] xmlData) throws IOException {
Exception ex = assertThrowsExactly(RuntimeException.class, () -> createFromXml(xmlData));
assertTrue(ex.getMessage().contains("generated by another jpackage version or malformed"));
assertTrue(ex.getMessage().endsWith(".jpackage.xml\""));
}
private static Stream<org.junit.jupiter.params.provider.Arguments> testInavlidXml() {
return Stream.of(
makeArguments((Object)new String[] {"<foo/>"}),
makeArguments((Object)new String[] {"<jpackage-state/>"}),
makeArguments((Object)new String[] {JPACKAGE_STATE_OPEN, "</jpackage-state>"}),
makeArguments((Object)new String[] {
JPACKAGE_STATE_OPEN,
"<main-launcher></main-launcher>",
"</jpackage-state>"));
assertInvalid(() -> createFromXml(
"</jpackage-state>"
}),
makeArguments((Object)new String[] {
JPACKAGE_STATE_OPEN,
"<main-launcher>Foo</main-launcher>",
"<main-class></main-class>",
"</jpackage-state>"));
assertInvalid(() -> createFromXml(
"</jpackage-state>"
}),
makeArguments((Object)new String[] {
JPACKAGE_STATE_OPEN,
"<launcher>A</launcher>",
"<launcher>B</launcher>",
"</jpackage-state>"));
"</jpackage-state>"
})
);
}
@Test
public void testValidXml() throws IOException {
Assert.assertEquals("Foo", (createFromXml(
@ParameterizedTest
@MethodSource
public void testValidXml(String expectedLauncherName, String xmlData[]) throws IOException {
var file = createFromXml(xmlData);
assertEquals(expectedLauncherName, file.getLauncherName());
assertTrue(file.getAddLaunchers().isEmpty());
}
private static Stream<org.junit.jupiter.params.provider.Arguments> testValidXml() {
return Stream.of(
makeArguments("Foo", List.of(
JPACKAGE_STATE_OPEN,
"<app-version>1.0</app-version>",
"<main-launcher>Foo</main-launcher>",
"<main-class>main.Class</main-class>",
"<signed>false</signed>",
"<app-store>false</app-store>",
"</jpackage-state>")).getLauncherName());
Assert.assertEquals("Boo", (createFromXml(
"</jpackage-state>").toArray(String[]::new)
),
makeArguments("Boo", List.of(
JPACKAGE_STATE_OPEN,
"<app-version>1.0</app-version>",
"<main-launcher>Boo</main-launcher>",
@ -113,20 +135,19 @@ public class AppImageFileTest {
"<main-class>main.Class</main-class>",
"<signed>false</signed>",
"<app-store>false</app-store>",
"</jpackage-state>")).getLauncherName());
var file = createFromXml(
"</jpackage-state>").toArray(String[]::new)
),
makeArguments("duke", List.of(
JPACKAGE_STATE_OPEN,
"<app-version>1.0</app-version>",
"<main-launcher>Foo</main-launcher>",
"<main-launcher>duke</main-launcher>",
"<main-class>main.Class</main-class>",
"<signed>false</signed>",
"<app-store>false</app-store>",
"<launcher></launcher>",
"</jpackage-state>");
Assert.assertEquals("Foo", file.getLauncherName());
Assert.assertEquals(0, file.getAddLaunchers().size());
"</jpackage-state>").toArray(String[]::new)
)
);
}
@Test
@ -137,7 +158,7 @@ public class AppImageFileTest {
params.put("description", "Duck App Description");
AppImageFile aif = create(params);
Assert.assertEquals("Foo", aif.getLauncherName());
assertEquals("Foo", aif.getLauncherName());
}
@Test
@ -148,7 +169,7 @@ public class AppImageFileTest {
params.put("description", "Duck App Description");
AppImageFile aif = create(params);
Assert.assertEquals("main.Class", aif.getMainClass());
assertEquals("main.Class", aif.getMainClass());
}
@Test
@ -160,7 +181,7 @@ public class AppImageFileTest {
params.put("mac-sign", Boolean.TRUE);
AppImageFile aif = create(params);
Assert.assertTrue(aif.isSigned());
assertTrue(aif.isSigned());
}
@Test
@ -172,10 +193,10 @@ public class AppImageFileTest {
params.put("mac-sign", Boolean.FALSE);
AppImageFile aif = create(params);
Assert.assertFalse(aif.isSigned());
assertFalse(aif.isSigned());
aif = aif.copyAsSigned();
Assert.assertTrue(aif.isSigned());
assertTrue(aif.isSigned());
}
@Test
@ -187,7 +208,7 @@ public class AppImageFileTest {
params.put("mac-app-store", Boolean.TRUE);
AppImageFile aif = create(params);
Assert.assertTrue(aif.isAppStore());
assertTrue(aif.isAppStore());
}
@Test
@ -210,32 +231,22 @@ public class AppImageFileTest {
AppImageFile aif = create(params);
List<AppImageFile.LauncherInfo> addLaunchers = aif.getAddLaunchers();
Assert.assertEquals(2, addLaunchers.size());
assertEquals(2, addLaunchers.size());
List<String> names = new ArrayList<>();
names.add(addLaunchers.get(0).getName());
names.add(addLaunchers.get(1).getName());
Assert.assertTrue(names.contains("Launcher2Name"));
Assert.assertTrue(names.contains("Launcher3Name"));
assertTrue(names.contains("Launcher2Name"));
assertTrue(names.contains("Launcher3Name"));
}
private AppImageFile create(Map<String, Object> params) throws IOException {
AppImageFile.save(tempFolder.getRoot().toPath(), params);
return AppImageFile.load(tempFolder.getRoot().toPath());
}
private void assertInvalid(ThrowingRunnable action) {
Exception ex = Assert.assertThrows(RuntimeException.class, action);
Assert.assertTrue(ex instanceof RuntimeException);
Assert.assertTrue(ex.getMessage()
.contains("generated by another jpackage version or malformed"));
Assert.assertTrue(ex.getMessage()
.endsWith(".jpackage.xml\""));
AppImageFile.save(tempFolder, params);
return AppImageFile.load(tempFolder);
}
private AppImageFile createFromXml(String... xmlData) throws IOException {
Path directory = tempFolder.getRoot().toPath();
Path path = AppImageFile.getPathInAppImage(directory);
Path path = AppImageFile.getPathInAppImage(tempFolder);
path.toFile().mkdirs();
Files.delete(path);
@ -246,11 +257,18 @@ public class AppImageFileTest {
Files.write(path, data, StandardOpenOption.CREATE,
StandardOpenOption.TRUNCATE_EXISTING);
AppImageFile image = AppImageFile.load(directory);
AppImageFile image = AppImageFile.load(tempFolder);
return image;
}
private final static String JPACKAGE_STATE_OPEN = String.format(
static org.junit.jupiter.params.provider.Arguments makeArguments(Object ... args) {
return org.junit.jupiter.params.provider.Arguments.of(args);
}
@TempDir
private Path tempFolder;
private static final String JPACKAGE_STATE_OPEN = String.format(
"<jpackage-state platform=\"%s\" version=\"%s\">",
AppImageFile.getPlatform(), AppImageFile.getVersion());

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -26,31 +26,44 @@ package jdk.jpackage.internal;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import org.junit.Test;
import org.junit.Rule;
import org.junit.rules.TemporaryFolder;
import static org.junit.Assert.assertTrue;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class ApplicationLayoutTest {
@Rule
public final TemporaryFolder tempFolder = new TemporaryFolder();
private Path newFolder(Path folderName, String ... extraFolderNames) throws IOException {
var path = tempFolder.resolve(folderName);
Files.createDirectories(path);
for (var extraFolderName : extraFolderNames) {
path = path.resolve(extraFolderName);
Files.createDirectories(path);
}
return path;
}
private Path newFile(Path fileName) throws IOException {
var path = tempFolder.resolve(fileName);
Files.createDirectories(path.getParent());
Files.createFile(path);
return path;
}
private void fillLinuxAppImage() throws IOException {
appImage = tempFolder.newFolder("Foo").toPath();
appImage = newFolder(Path.of("Foo"));
Path base = appImage.getFileName();
tempFolder.newFolder(base.toString(), "bin");
tempFolder.newFolder(base.toString(), "lib", "app", "mods");
tempFolder.newFolder(base.toString(), "lib", "runtime", "bin");
tempFolder.newFile(base.resolve("bin/Foo").toString());
tempFolder.newFile(base.resolve("lib/app/Foo.cfg").toString());
tempFolder.newFile(base.resolve("lib/app/hello.jar").toString());
tempFolder.newFile(base.resolve("lib/Foo.png").toString());
tempFolder.newFile(base.resolve("lib/libapplauncher.so").toString());
tempFolder.newFile(base.resolve("lib/runtime/bin/java").toString());
newFolder(base, "bin");
newFolder(base, "lib", "app", "mods");
newFolder(base, "lib", "runtime", "bin");
newFile(base.resolve("bin/Foo"));
newFile(base.resolve("lib/app/Foo.cfg"));
newFile(base.resolve("lib/app/hello.jar"));
newFile(base.resolve("lib/Foo.png"));
newFile(base.resolve("lib/libapplauncher.so"));
newFile(base.resolve("lib/runtime/bin/java"));
}
@Test
@ -84,5 +97,7 @@ public class ApplicationLayoutTest {
assertTrue(Files.isRegularFile(layout.runtimeDirectory().resolve("bin/java")));
}
@TempDir
private Path tempFolder;
private Path appImage;
}

View File

@ -1,111 +0,0 @@
/*
* Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.jpackage.internal;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import static org.junit.Assert.assertEquals;
@RunWith(Parameterized.class)
public class CompareDottedVersionTest {
public CompareDottedVersionTest(boolean greedy, String version1,
String version2, int result) {
this.version1 = version1;
this.version2 = version2;
this.expectedResult = result;
if (greedy) {
createTestee = DottedVersion::greedy;
} else {
createTestee = DottedVersion::lazy;
}
}
@Parameters
public static List<Object[]> data() {
List<Object[]> data = new ArrayList<>();
for (var greedy : List.of(true, false)) {
data.addAll(List.of(new Object[][] {
{ greedy, "00.0.0", "0", 0 },
{ greedy, "00.0.0", "0.000", 0 },
{ greedy, "0.035", "0.0035", 0 },
{ greedy, "0.035", "0.0035.0", 0 },
{ greedy, "1", "1", 0 },
{ greedy, "2", "2.0", 0 },
{ greedy, "2.00", "2.0", 0 },
{ greedy, "1.2.3.4", "1.2.3.4.5", -1 },
{ greedy, "1.2.3.4", "1.2.3.4.0.1", -1 },
{ greedy, "34", "33", 1 },
{ greedy, "34.0.78", "34.1.78", -1 }
}));
}
data.addAll(List.of(new Object[][] {
{ false, "", "1", -1 },
{ false, "", "0", 0 },
{ false, "0", "", 0 },
{ false, "1.2.4-R4", "1.2.4-R5", 0 },
{ false, "1.2.4.-R4", "1.2.4.R5", 0 },
{ false, "7+1", "7+4", 0 },
{ false, "2+14", "2-14", 0 },
{ false, "23.4.RC4", "23.3.RC10", 1 },
{ false, "77." + "9".repeat(1000), "77." + "9".repeat(1000 -1) + "8", 1 },
}));
return data;
}
@Test
public void testIt() {
int actualResult = compare(version1, version2);
assertEquals(expectedResult, actualResult);
int actualNegateResult = compare(version2, version1);
assertEquals(actualResult, -1 * actualNegateResult);
}
private int compare(String x, String y) {
int result = DottedVersion.compareComponents(createTestee.apply(x), createTestee.apply(y));
if (result < 0) {
return -1;
}
if (result > 0) {
return 1;
}
return 0;
}
private final String version1;
private final String version2;
private final int expectedResult;
private final Function<String, DottedVersion> createTestee;
}

View File

@ -22,21 +22,15 @@
*/
package jdk.jpackage.internal;
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
import static org.junit.jupiter.api.Assertions.assertThrowsExactly;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
public class DeployParamsTest {
@Rule
public final TemporaryFolder tempFolder = new TemporaryFolder();
@Rule
public final ExpectedException thrown = ExpectedException.none();
@Test
public void testValidAppName() throws PackagerException {
initParamsAppName();
@ -48,58 +42,13 @@ public class DeployParamsTest {
setAppNameAndValidate("Test - Name !!!");
}
@Test
public void testInvalidAppName() throws PackagerException {
initForInvalidAppNamePackagerException();
@ParameterizedTest
@ValueSource(strings = {"Test\nName", "Test\rName", "TestName\\", "Test \" Name"})
public void testInvalidAppName(String appName) throws PackagerException {
initParamsAppName();
setAppNameAndValidate("Test\nName");
}
var ex = assertThrowsExactly(PackagerException.class, () -> setAppNameAndValidate(appName));
@Test
public void testInvalidAppName2() throws PackagerException {
initForInvalidAppNamePackagerException();
initParamsAppName();
setAppNameAndValidate("Test\rName");
}
@Test
public void testInvalidAppName3() throws PackagerException {
initForInvalidAppNamePackagerException();
initParamsAppName();
setAppNameAndValidate("TestName\\");
}
@Test
public void testInvalidAppName4() throws PackagerException {
initForInvalidAppNamePackagerException();
initParamsAppName();
setAppNameAndValidate("Test \" Name");
}
private void initForInvalidAppNamePackagerException() {
thrown.expect(PackagerException.class);
String msg = "Error: Invalid Application name";
// Unfortunately org.hamcrest.core.StringStartsWith is not available
// with older junit, DIY
// thrown.expectMessage(startsWith("Error: Invalid Application name"));
thrown.expectMessage(new BaseMatcher() {
@Override
@SuppressWarnings("unchecked")
public boolean matches(Object o) {
if (o instanceof String) {
return ((String) o).startsWith(msg);
}
return false;
}
@Override
public void describeTo(Description d) {
d.appendText(msg);
}
});
assertTrue(ex.getMessage().startsWith("Error: Invalid Application name"));
}
// Returns deploy params initialized to pass all validation, except for

View File

@ -22,174 +22,224 @@
*/
package jdk.jpackage.internal;
import java.util.Collections;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Stream;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrowsExactly;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.EnumSource;
import org.junit.jupiter.params.provider.MethodSource;
@RunWith(Parameterized.class)
public class DottedVersionTest {
public DottedVersionTest(boolean greedy) {
this.greedy = greedy;
if (greedy) {
createTestee = DottedVersion::greedy;
} else {
createTestee = DottedVersion::lazy;
}
}
@Parameterized.Parameters
public static List<Object[]> data() {
return List.of(new Object[] { true }, new Object[] { false });
}
@Rule
public ExpectedException exceptionRule = ExpectedException.none();
private static class CtorTester {
CtorTester(String input, boolean greedy, String expectedSuffix,
public record TestConfig(String input,
Function<String, DottedVersion> createVersion, String expectedSuffix,
int expectedComponentCount, String expectedToComponent) {
this.input = input;
this.greedy = greedy;
this.expectedSuffix = expectedSuffix;
this.expectedComponentCount = expectedComponentCount;
this.expectedToComponent = expectedToComponent;
TestConfig(String input, Type type, int expectedComponentCount, String expectedToComponent) {
this(input, type.createVersion, "", expectedComponentCount, expectedToComponent);
}
CtorTester(String input, boolean greedy, int expectedComponentCount,
String expectedToComponent) {
this(input, greedy, "", expectedComponentCount, expectedToComponent);
TestConfig(String input, Type type, int expectedComponentCount) {
this(input, type.createVersion, "", expectedComponentCount, input);
}
CtorTester(String input, boolean greedy, int expectedComponentCount) {
this(input, greedy, "", expectedComponentCount, input);
static TestConfig greedy(String input, int expectedComponentCount, String expectedToComponent) {
return new TestConfig(input, Type.GREEDY.createVersion, "", expectedComponentCount, expectedToComponent);
}
static CtorTester greedy(String input, int expectedComponentCount,
String expectedToComponent) {
return new CtorTester(input, true, "", expectedComponentCount, expectedToComponent);
static TestConfig greedy(String input, int expectedComponentCount) {
return new TestConfig(input, Type.GREEDY.createVersion, "", expectedComponentCount, input);
}
static CtorTester greedy(String input, int expectedComponentCount) {
return new CtorTester(input, true, "", expectedComponentCount, input);
static TestConfig lazy(String input, String expectedSuffix, int expectedComponentCount, String expectedToComponent) {
return new TestConfig(input, Type.LAZY.createVersion, expectedSuffix, expectedComponentCount, expectedToComponent);
}
}
static CtorTester lazy(String input, String expectedSuffix, int expectedComponentCount,
String expectedToComponent) {
return new CtorTester(input, false, expectedSuffix, expectedComponentCount,
expectedToComponent);
@ParameterizedTest
@MethodSource
public void testValid(TestConfig cfg) {
var dv = cfg.createVersion.apply(cfg.input());
assertEquals(cfg.expectedSuffix(), dv.getUnprocessedSuffix());
assertEquals(cfg.expectedComponentCount(), dv.getComponents().length);
assertEquals(cfg.expectedToComponent(), dv.toComponentsString());
}
void run() {
DottedVersion dv;
if (greedy) {
dv = DottedVersion.greedy(input);
} else {
dv = DottedVersion.lazy(input);
private static List<TestConfig> testValid() {
List<TestConfig> data = new ArrayList<>();
for (var type : Type.values()) {
data.addAll(List.of(
new TestConfig("1.0", type, 2),
new TestConfig("1", type, 1),
new TestConfig("2.20034.045", type, 3, "2.20034.45"),
new TestConfig("2.234.0", type, 3),
new TestConfig("0", type, 1),
new TestConfig("0.1", type, 2),
new TestConfig("9".repeat(1000), type, 1),
new TestConfig("00.0.0", type, 3, "0.0.0")
));
}
assertEquals(expectedSuffix, dv.getUnprocessedSuffix());
assertEquals(expectedComponentCount, dv.getComponents().length);
assertEquals(expectedToComponent, dv.toComponentsString());
data.addAll(List.of(
TestConfig.lazy("1.-1", ".-1", 1, "1"),
TestConfig.lazy("5.", ".", 1, "5"),
TestConfig.lazy("4.2.", ".", 2, "4.2"),
TestConfig.lazy("3..2", "..2", 1, "3"),
TestConfig.lazy("3......2", "......2", 1, "3"),
TestConfig.lazy("2.a", ".a", 1, "2"),
TestConfig.lazy("a", "a", 0, ""),
TestConfig.lazy("2..a", "..a", 1, "2"),
TestConfig.lazy("0a", "a", 1, "0"),
TestConfig.lazy("120a", "a", 1, "120"),
TestConfig.lazy("120abc", "abc", 1, "120"),
TestConfig.lazy(".", ".", 0, ""),
TestConfig.lazy("....", "....", 0, ""),
TestConfig.lazy(" ", " ", 0, ""),
TestConfig.lazy(" 1", " 1", 0, ""),
TestConfig.lazy("678. 2", ". 2", 1, "678"),
TestConfig.lazy("+1", "+1", 0, ""),
TestConfig.lazy("-1", "-1", 0, ""),
TestConfig.lazy("-0", "-0", 0, ""),
TestConfig.lazy("+0", "+0", 0, "")
));
return data;
}
private final String input;
private final boolean greedy;
private final String expectedSuffix;
private final int expectedComponentCount;
private final String expectedToComponent;
@ParameterizedTest
@MethodSource
public void testInvalid(String str) {
assertThrowsExactly(IllegalArgumentException.class, () -> new DottedVersion(str));
}
@Test
public void testValid() {
final List<CtorTester> validStrings = List.of(
new CtorTester("1.0", greedy, 2),
new CtorTester("1", greedy, 1),
new CtorTester("2.20034.045", greedy, 3, "2.20034.45"),
new CtorTester("2.234.0", greedy, 3),
new CtorTester("0", greedy, 1),
new CtorTester("0.1", greedy, 2),
new CtorTester("9".repeat(1000), greedy, 1),
new CtorTester("00.0.0", greedy, 3, "0.0.0")
);
final List<CtorTester> validLazyStrings;
if (greedy) {
validLazyStrings = Collections.emptyList();
} else {
validLazyStrings = List.of(
CtorTester.lazy("1.-1", ".-1", 1, "1"),
CtorTester.lazy("5.", ".", 1, "5"),
CtorTester.lazy("4.2.", ".", 2, "4.2"),
CtorTester.lazy("3..2", "..2", 1, "3"),
CtorTester.lazy("3......2", "......2", 1, "3"),
CtorTester.lazy("2.a", ".a", 1, "2"),
CtorTester.lazy("a", "a", 0, ""),
CtorTester.lazy("2..a", "..a", 1, "2"),
CtorTester.lazy("0a", "a", 1, "0"),
CtorTester.lazy("120a", "a", 1, "120"),
CtorTester.lazy("120abc", "abc", 1, "120"),
CtorTester.lazy(".", ".", 0, ""),
CtorTester.lazy("....", "....", 0, ""),
CtorTester.lazy(" ", " ", 0, ""),
CtorTester.lazy(" 1", " 1", 0, ""),
CtorTester.lazy("678. 2", ". 2", 1, "678"),
CtorTester.lazy("+1", "+1", 0, ""),
CtorTester.lazy("-1", "-1", 0, ""),
CtorTester.lazy("-0", "-0", 0, ""),
CtorTester.lazy("+0", "+0", 0, "")
private static Stream<String> testInvalid() {
return Stream.of(
"1.-1",
"5.",
"4.2.",
"3..2",
"2.a",
"0a",
".",
" ",
" 1",
"1. 2",
"+1",
"-1",
"-0",
"+0"
);
}
Stream.concat(validStrings.stream(), validLazyStrings.stream()).forEach(CtorTester::run);
@ParameterizedTest
@EnumSource(Type.class)
public void testNull(Type type) {
assertThrowsExactly(NullPointerException.class, () -> type.createVersion.apply(null));
}
@Test
public void testNull() {
exceptionRule.expect(NullPointerException.class);
createTestee.apply(null);
public void testEmptyGreedy() {
assertThrowsExactly(IllegalArgumentException.class, () -> DottedVersion.greedy(""), "Version may not be empty string");
}
@Test
public void testEmpty() {
if (greedy) {
exceptionRule.expect(IllegalArgumentException.class);
exceptionRule.expectMessage("Version may not be empty string");
createTestee.apply("");
} else {
assertEquals(0, createTestee.apply("").getComponents().length);
}
public void testEmptyLazy() {
assertEquals(0, DottedVersion.lazy("").getComponents().length);
}
@Test
public void testEquals() {
DottedVersion dv = createTestee.apply("1.0");
@ParameterizedTest
@EnumSource(Type.class)
public void testEquals(Type type) {
DottedVersion dv = type.createVersion.apply("1.0");
assertFalse(dv.equals(null));
assertFalse(dv.equals(Integer.valueOf(1)));
assertFalse(dv.equals(1));
assertFalse(dv.equals(dv.toString()));
for (var ver : List.of("3", "3.4", "3.0.0")) {
DottedVersion a = createTestee.apply(ver);
DottedVersion b = createTestee.apply(ver);
DottedVersion a = type.createVersion.apply(ver);
DottedVersion b = type.createVersion.apply(ver);
assertTrue(a.equals(b));
assertTrue(b.equals(a));
}
if (!greedy) {
assertTrue(createTestee.apply("3.6+67").equals(createTestee.apply("3.6+67")));
assertFalse(createTestee.apply("3.6+67").equals(createTestee.apply("3.6+067")));
}
}
private final boolean greedy;
private final Function<String, DottedVersion> createTestee;
@Test
public void testEqualsLazy() {
assertTrue(DottedVersion.lazy("3.6+67").equals(DottedVersion.lazy("3.6+67")));
assertFalse(DottedVersion.lazy("3.6+67").equals(DottedVersion.lazy("3.6+067")));
}
private static List<Object[]> testCompare() {
List<Object[]> data = new ArrayList<>();
for (var type : Type.values()) {
data.addAll(List.of(new Object[][] {
{ type, "00.0.0", "0", 0 },
{ type, "00.0.0", "0.000", 0 },
{ type, "0.035", "0.0035", 0 },
{ type, "0.035", "0.0035.0", 0 },
{ type, "1", "1", 0 },
{ type, "2", "2.0", 0 },
{ type, "2.00", "2.0", 0 },
{ type, "1.2.3.4", "1.2.3.4.5", -1 },
{ type, "1.2.3.4", "1.2.3.4.0.1", -1 },
{ type, "34", "33", 1 },
{ type, "34.0.78", "34.1.78", -1 }
}));
}
data.addAll(List.of(new Object[][] {
{ Type.LAZY, "", "1", -1 },
{ Type.LAZY, "", "0", 0 },
{ Type.LAZY, "0", "", 0 },
{ Type.LAZY, "1.2.4-R4", "1.2.4-R5", 0 },
{ Type.LAZY, "1.2.4.-R4", "1.2.4.R5", 0 },
{ Type.LAZY, "7+1", "7+4", 0 },
{ Type.LAZY, "2+14", "2-14", 0 },
{ Type.LAZY, "23.4.RC4", "23.3.RC10", 1 },
{ Type.LAZY, "77." + "9".repeat(1000), "77." + "9".repeat(1000 -1) + "8", 1 },
}));
return data;
}
@ParameterizedTest
@MethodSource
public void testCompare(Type type, String version1, String version2, int expectedResult) {
final int actualResult = compare(type, version1, version2);
assertEquals(expectedResult, actualResult);
final int actualNegateResult = compare(type, version2, version1);
assertEquals(actualResult, -1 * actualNegateResult);
}
private int compare(Type type, String x, String y) {
int result = DottedVersion.compareComponents(type.createVersion.apply(x), type.createVersion.apply(y));
if (result < 0) {
return -1;
}
if (result > 0) {
return 1;
}
return 0;
}
public enum Type {
GREEDY(DottedVersion::greedy),
LAZY(DottedVersion::lazy);
Type(Function<String, DottedVersion> createVersion) {
this.createVersion = createVersion;
}
private final Function<String, DottedVersion> createVersion;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -23,30 +23,49 @@
package jdk.jpackage.internal;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import java.util.stream.Stream;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
public class EnquoterTest {
@Test
public void testForShellLiterals() {
var enquoter = Enquoter.forShellLiterals();
assertEquals(null, "''", enquoter.applyTo(""));
assertEquals(null, "'foo'", enquoter.applyTo("foo"));
assertEquals(null, "' foo '", enquoter.applyTo(" foo "));
assertEquals(null, "'foo bar'", enquoter.applyTo("foo bar"));
assertEquals(null, "'foo\\' bar'", enquoter.applyTo("foo' bar"));
@ParameterizedTest
@MethodSource
public void testForShellLiterals(String expected, String input) {
var actual = Enquoter.forShellLiterals().applyTo(input);
assertEquals(expected, actual);
}
@Test
public void testForPropertyValues() {
var enquoter = Enquoter.forPropertyValues();
@ParameterizedTest
@MethodSource
public void testForPropertyValues(String expected, String input) {
var actual = Enquoter.forPropertyValues().applyTo(input);
assertEquals(expected, actual);
}
assertEquals(null, "", enquoter.applyTo(""));
assertEquals(null, "foo", enquoter.applyTo("foo"));
assertEquals(null, "\" foo \"", enquoter.applyTo(" foo "));
assertEquals(null, "\"foo bar\"", enquoter.applyTo("foo bar"));
assertEquals(null, "\"foo' bar\"", enquoter.applyTo("foo' bar"));
private static Stream<org.junit.jupiter.params.provider.Arguments> testForShellLiterals() {
return Stream.of(
makeArguments("''", ""),
makeArguments("'foo'", "foo"),
makeArguments("' foo '", " foo "),
makeArguments("'foo bar'", "foo bar"),
makeArguments("'foo\\' bar'", "foo' bar")
);
}
private static Stream<org.junit.jupiter.params.provider.Arguments> testForPropertyValues() {
return Stream.of(
makeArguments("", ""),
makeArguments("foo", "foo"),
makeArguments("\" foo \"", " foo "),
makeArguments("\"foo bar\"", "foo bar"),
makeArguments("\"foo' bar\"", "foo' bar")
);
}
static org.junit.jupiter.params.provider.Arguments makeArguments(Object ... args) {
return org.junit.jupiter.params.provider.Arguments.of(args);
}
}

View File

@ -1,72 +0,0 @@
/*
* Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.jpackage.internal;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
@RunWith(Parameterized.class)
public class InvalidDottedVersionTest {
public InvalidDottedVersionTest(String version) {
this.version = version;
}
@Parameters
public static List<Object[]> data() {
return Stream.of(
"1.-1",
"5.",
"4.2.",
"3..2",
"2.a",
"0a",
".",
" ",
" 1",
"1. 2",
"+1",
"-1",
"-0",
"+0"
).map(version -> new Object[] { version }).collect(Collectors.toList());
}
@Rule
public ExpectedException exceptionRule = ExpectedException.none();
@Test
public void testIt() {
exceptionRule.expect(IllegalArgumentException.class);
new DottedVersion(version);
}
private final String version;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -23,60 +23,106 @@
package jdk.jpackage.internal;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Stream;
import jdk.internal.util.OperatingSystem;
import static jdk.jpackage.internal.OverridableResource.Source.DefaultResource;
import static jdk.jpackage.internal.OverridableResource.Source.ResourceDir;
import jdk.jpackage.internal.resources.ResourceLocator;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertThat;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.junit.jupiter.params.provider.ValueSource;
public class OverridableResourceTest {
@Rule
public final TemporaryFolder tempFolder = new TemporaryFolder();
@Test
public void testDefault() throws IOException {
byte[] actualBytes = saveToFile(new OverridableResource(DEFAULT_NAME));
try (InputStream is = ResourceLocator.class.getResourceAsStream(
DEFAULT_NAME)) {
assertArrayEquals(is.readAllBytes(), actualBytes);
private static String[] saveResource(ResourceWriter resourceWriter, Path dstPath) throws IOException {
switch (dstPath.getFileName().toString()) {
case "file" -> {
return resourceWriter.saveToFile(dstPath);
}
case "dir" -> {
return resourceWriter.saveInDir(dstPath);
}
default -> {
throw new IllegalArgumentException();
}
}
}
@Test
public void testDefaultWithSubstitution() throws IOException {
OverridableResource resource = new OverridableResource(DEFAULT_NAME);
private static String[] saveResource(
OverridableResource resource, Path dstPath, boolean dstFileOverwrite)
throws IOException {
return saveResource(buildResourceWriter(resource).dstFileOverwrite(dstFileOverwrite), dstPath);
}
List<String> linesBeforeSubstitution = convertToStringList(saveToFile(
resource));
private static List<Object[]> data() {
List<Object[]> data = new ArrayList<>();
for (var dstPath : List.of("file", "dir")) {
for (var dstFileOverwrite : List.of(true, false)) {
data.add(new Object[]{Path.of(dstPath), dstFileOverwrite});
}
}
for (var dstPath : List.of("dir/file", "dir/dir")) {
data.add(new Object[]{Path.of(dstPath), false});
}
return data;
}
@ParameterizedTest
@MethodSource("data")
public void testDefault(Path dstPath, boolean dstFileOverwrite,
@TempDir Path tempFolder) throws IOException {
final String[] content = saveResource(
new OverridableResource(DEFAULT_NAME), tempFolder.resolve(
dstPath), dstFileOverwrite);
try (var resource = ResourceLocator.class.getResourceAsStream(DEFAULT_NAME);
var isr = new InputStreamReader(resource, StandardCharsets.ISO_8859_1);
var br = new BufferedReader(isr)) {
assertArrayEquals(br.lines().toArray(String[]::new), content);
}
}
@ParameterizedTest
@MethodSource("data")
public void testDefaultWithSubstitution(Path dstPath, boolean dstFileOverwrite,
@TempDir Path tempFolder) throws IOException {
if (SUBSTITUTION_DATA.size() != 1) {
// Test setup issue
throw new IllegalArgumentException(
"Substitution map should contain only a single entry");
}
OverridableResource resource = new OverridableResource(DEFAULT_NAME);
var linesBeforeSubstitution = List.of(saveResource(resource, tempFolder.resolve(dstPath), dstFileOverwrite));
resource.setSubstitutionData(SUBSTITUTION_DATA);
List<String> linesAfterSubstitution = convertToStringList(saveToFile(
resource));
var linesAfterSubstitution = List.of(saveResource(resource, tempFolder.resolve(dstPath), dstFileOverwrite));
assertEquals(linesBeforeSubstitution.size(), linesAfterSubstitution.size());
@ -103,130 +149,239 @@ public class OverridableResourceTest {
assertTrue(linesMismatch);
}
@Test
public void testCustom() throws IOException {
testCustom(DEFAULT_NAME);
private static Stream<Object[]> dataWithResourceName() {
return data().stream().flatMap(origArgs -> {
return Stream.of(ResourceName.values()).map(defaultName -> {
Object[] args = new Object[origArgs.length + 1];
args[0] = defaultName;
System.arraycopy(origArgs, 0, args, 1, origArgs.length);
return args;
});
});
}
@Test
public void testCustomNoDefault() throws IOException {
testCustom(null);
}
private void testCustom(String defaultName) throws IOException {
@ParameterizedTest
@MethodSource("dataWithResourceName")
public void testResourceDir(ResourceName defaultName, Path dstPath,
boolean dstFileOverwrite, @TempDir Path tempFolder) throws IOException {
List<String> expectedResourceData = List.of("A", "B", "C");
Path customFile = createCustomFile("foo", expectedResourceData);
Path customFile = tempFolder.resolve("hello");
Files.write(customFile, expectedResourceData);
List<String> actualResourceData = convertToStringList(saveToFile(
new OverridableResource(defaultName)
final var actualResourceData = saveResource(buildResourceWriter(
new OverridableResource(defaultName.value)
.setPublicName(customFile.getFileName())
.setResourceDir(customFile.getParent())));
.setResourceDir(customFile.getParent())
).dstFileOverwrite(dstFileOverwrite).expectedSource(ResourceDir),
tempFolder.resolve(dstPath));
assertArrayEquals(expectedResourceData.toArray(String[]::new),
actualResourceData.toArray(String[]::new));
assertArrayEquals(expectedResourceData.toArray(String[]::new), actualResourceData);
}
@Test
public void testCustomtWithSubstitution() throws IOException {
testCustomtWithSubstitution(DEFAULT_NAME);
}
@Test
public void testCustomtWithSubstitutionNoDefault() throws IOException {
testCustomtWithSubstitution(null);
}
private void testCustomtWithSubstitution(String defaultName) throws IOException {
@ParameterizedTest
@MethodSource("dataWithResourceName")
public void testResourceDirWithSubstitution(ResourceName defaultName, Path dstPath,
boolean dstFileOverwrite, @TempDir Path tempFolder) throws IOException {
final List<String> resourceData = List.of("A", "[BB]", "C", "Foo", "Foo",
"GoodbyeHello", "_B");
final Path customFile = createCustomFile("foo", resourceData);
final Map<String, String> substitutionData = new HashMap(Map.of("B",
"Bar", "Foo", "B", "_B", "JJ"));
final Path customFile = tempFolder.resolve("hello");
Files.write(customFile, resourceData);
final Map<String, String> substitutionData = new HashMap<>(Map.of(
"B", "Bar",
"Foo", "B",
"_B", "JJ"));
substitutionData.put("Hello", null);
final List<String> expectedResourceData = List.of("A", "[BarBar]", "C",
"Bar", "Bar", "Goodbye", "JJ");
final List<String> actualResourceData = convertToStringList(saveToFile(
new OverridableResource(defaultName)
final var actualResourceData = saveResource(buildResourceWriter(
new OverridableResource(defaultName.value)
.setSubstitutionData(substitutionData)
.setPublicName(customFile.getFileName())
.setSubstitutionData(substitutionData)
.setResourceDir(customFile.getParent())));
assertArrayEquals(expectedResourceData.toArray(String[]::new),
actualResourceData.toArray(String[]::new));
// Don't call setPublicName()
final Path dstFile = tempFolder.newFolder().toPath().resolve(customFile.getFileName());
new OverridableResource(defaultName)
.setSubstitutionData(substitutionData)
.setResourceDir(customFile.getParent())
.saveToFile(dstFile);
assertArrayEquals(expectedResourceData.toArray(String[]::new),
convertToStringList(Files.readAllBytes(dstFile)).toArray(
String[]::new));
).dstFileOverwrite(dstFileOverwrite).expectedSource(ResourceDir),
tempFolder.resolve(dstPath));
// Verify setSubstitutionData() stores a copy of passed in data
Map<String, String> substitutionData2 = new HashMap(substitutionData);
var resource = new OverridableResource(defaultName)
assertArrayEquals(expectedResourceData.toArray(String[]::new), actualResourceData);
}
// Test it can derive a file in the resource dir from the name of the output file if the public name is not set
@ParameterizedTest
@ValueSource(booleans = {true, false})
public void testPublicNameNotSet(boolean namesMatch, @TempDir Path tempFolder) throws IOException {
final List<String> expectedResourceData = List.of("A", "B", "C");
final Path customFile = tempFolder.resolve("hello");
Files.write(customFile, expectedResourceData);
final Path outputDir = tempFolder.resolve("output");
var resourceWriter = buildResourceWriter(
new OverridableResource(null).setResourceDir(customFile.getParent()));
if (namesMatch) {
final var actualResourceData = resourceWriter
.expectedSource(ResourceDir)
.saveToFile(outputDir.resolve(customFile.getFileName()));
assertArrayEquals(expectedResourceData.toArray(String[]::new), actualResourceData);
} else {
final var actualResourceData = resourceWriter
.expectedSource(null)
.saveToFile(outputDir.resolve("another"));
assertNull(actualResourceData);
}
}
// Test setSubstitutionData() stores a copy of passed in data
@Test
public void testSubstitutionDataCopied(@TempDir Path tempFolder) throws IOException {
final Path customFile = tempFolder.resolve("hello");
Files.write(customFile, List.of("Hello"));
final Map<String, String> substitutionData = new HashMap<>(Map.of("Hello", "Goodbye"));
var resource = new OverridableResource(null)
.setSubstitutionData(substitutionData)
.setPublicName(customFile.getFileName())
.setResourceDir(customFile.getParent());
resource.setSubstitutionData(substitutionData2);
substitutionData2.clear();
Files.delete(dstFile);
resource.saveToFile(dstFile);
assertArrayEquals(expectedResourceData.toArray(String[]::new),
convertToStringList(Files.readAllBytes(dstFile)).toArray(
String[]::new));
final var resourceWriter = buildResourceWriter(resource).expectedSource(ResourceDir);
var contents = resourceWriter.saveToFile(tempFolder.resolve("output"));
assertArrayEquals(new String[] { "Goodbye" }, contents);
substitutionData.put("Hello", "Ciao");
contents = resourceWriter.saveToFile(tempFolder.resolve("output"));
assertArrayEquals(new String[] { "Goodbye" }, contents);
resource.setSubstitutionData(substitutionData);
contents = resourceWriter.saveToFile(tempFolder.resolve("output"));
assertArrayEquals(new String[] { "Ciao" }, contents);
}
@Test
public void testNoDefault() throws IOException {
Path dstFolder = tempFolder.newFolder().toPath();
Path dstFile = dstFolder.resolve(Path.of("foo", "bar"));
public void testNoDefault(@TempDir Path tempFolder) throws IOException {
var resourceWriter = buildResourceWriter(new OverridableResource(null)).expectedSource(null);
assertEquals(null, resourceWriter.saveInDir(tempFolder));
new OverridableResource(null).saveToFile(dstFile);
assertFalse(dstFile.toFile().exists());
var dstDir = tempFolder.resolve("foo");
assertEquals(null, resourceWriter.saveInDir(dstDir));
assertFalse(Files.exists(dstDir));
}
private final static String DEFAULT_NAME;
private final static Map<String, String> SUBSTITUTION_DATA;
enum ResourceName {
DEFAULT_NAME(OverridableResourceTest.DEFAULT_NAME),
NULL_NAME(null);
ResourceName(String value) {
this.value = value;
}
private final String value;
}
private static final String DEFAULT_NAME;
private static final Map<String, String> SUBSTITUTION_DATA;
static {
if (OperatingSystem.isWindows()) {
switch (OperatingSystem.current()) {
case WINDOWS -> {
DEFAULT_NAME = "WinLauncher.template";
SUBSTITUTION_DATA = Map.of("COMPANY_NAME", "Foo9090345");
} else if (OperatingSystem.isLinux()) {
}
case LINUX -> {
DEFAULT_NAME = "template.control";
SUBSTITUTION_DATA = Map.of("APPLICATION_PACKAGE", "Package1967");
} else if (OperatingSystem.isMacOS()) {
}
case MACOS -> {
DEFAULT_NAME = "Info-lite.plist.template";
SUBSTITUTION_DATA = Map.of("DEPLOY_BUNDLE_IDENTIFIER", "12345");
}
default -> {
throw new IllegalArgumentException("Unsupported platform: " + OperatingSystem.current());
}
}
}
static class ResourceWriter {
ResourceWriter(OverridableResource resource) {
this.resource = Objects.requireNonNull(resource);
}
ResourceWriter expectedSource(OverridableResource.Source v) {
expectedSource = v;
return this;
}
ResourceWriter dstFileOverwrite(boolean v) {
dstFileOverwrite = v;
return this;
}
String[] saveInDir(Path dstDir) throws IOException {
Path dstFile;
if (expectedSource != null) {
if (!Files.exists(dstDir)) {
Files.createDirectories(dstDir);
}
dstFile = Files.createTempFile(dstDir, null, null);
} else if (!Files.exists(dstDir)) {
dstFile = dstDir.resolve("nonexistant");
} else {
throw new IllegalArgumentException("Unknown platform: " + OperatingSystem.current());
dstFile = Files.createTempFile(dstDir, null, null);
Files.delete(dstFile);
}
return saveToFile(dstFile);
}
String[] saveToFile(Path dstFile) throws IOException {
saveResource(dstFile);
if (expectedSource == null) {
return null;
} else {
return Files.readAllLines(dstFile).toArray(String[]::new);
}
}
private byte[] saveToFile(OverridableResource resource) throws IOException {
Path dstFile = tempFolder.newFile().toPath();
resource.saveToFile(dstFile);
assertThat(0, is(not(dstFile.toFile().length())));
return Files.readAllBytes(dstFile);
private void saveResource(Path dstFile) throws IOException {
if (dstFileOverwrite && !Files.exists(dstFile)) {
Files.writeString(dstFile, "abcABC");
} else if (!dstFileOverwrite && Files.exists(dstFile)) {
Files.delete(dstFile);
}
private Path createCustomFile(String publicName, List<String> data) throws
IOException {
Path resourceFolder = tempFolder.newFolder().toPath();
Path customFile = resourceFolder.resolve(publicName);
Files.write(customFile, data);
return customFile;
final byte[] dstFileContent;
if (expectedSource == null && Files.exists(dstFile)) {
dstFileContent = Files.readAllBytes(dstFile);
} else {
dstFileContent = null;
}
private static List<String> convertToStringList(byte[] data) {
return List.of(new String(data, StandardCharsets.UTF_8).split("\\R"));
var actualSource = resource.saveToFile(dstFile);
assertEquals(expectedSource, actualSource);
if (actualSource != null) {
assertNotEquals(0, Files.size(dstFile));
} else if (dstFileContent == null) {
assertFalse(Files.exists(dstFile));
} else {
var actualDstFileContent = Files.readAllBytes(dstFile);
assertArrayEquals(dstFileContent, actualDstFileContent);
}
}
final OverridableResource resource;
OverridableResource.Source expectedSource = DefaultResource;
boolean dstFileOverwrite;
}
private static ResourceWriter buildResourceWriter(OverridableResource resource) {
return new ResourceWriter(resource);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -32,29 +32,24 @@ import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.UnaryOperator;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertThat;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrowsExactly;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
public class PathGroupTest {
@Rule
public final TemporaryFolder tempFolder = new TemporaryFolder();
@Test(expected = NullPointerException.class)
public void testNullId() {
new PathGroup(Map.of()).getPath(null);
assertThrowsExactly(NullPointerException.class, () -> new PathGroup(Map.of()).getPath(null));
}
@Test
@ -82,8 +77,10 @@ public class PathGroupTest {
@Test
public void testDuplicatedRoots() {
final PathGroup pg = new PathGroup(Map.of("main", PATH_FOO, "another",
PATH_FOO, "root", PATH_EMPTY));
final PathGroup pg = new PathGroup(Map.of(
"main", PATH_FOO,
"another", PATH_FOO,
"root", PATH_EMPTY));
List<Path> paths = pg.paths();
paths = paths.stream().sorted().toList();
@ -100,8 +97,10 @@ public class PathGroupTest {
@Test
public void testRoots() {
final PathGroup pg = new PathGroup(Map.of(1, Path.of("foo"), 2, Path.of(
"foo", "bar"), 3, Path.of("foo", "bar", "buz")));
final PathGroup pg = new PathGroup(Map.of(
1, Path.of("foo"),
2, Path.of("foo", "bar"),
3, Path.of("foo", "bar", "buz")));
List<Path> paths = pg.paths();
assertEquals(3, paths.size());
@ -116,13 +115,15 @@ public class PathGroupTest {
@Test
public void testResolveAt() {
final PathGroup pg = new PathGroup(Map.of(0, PATH_FOO, 1, PATH_BAR, 2,
PATH_EMPTY));
final PathGroup pg = new PathGroup(Map.of(
0, PATH_FOO,
1, PATH_BAR,
2, PATH_EMPTY));
final Path aPath = Path.of("a");
final PathGroup pg2 = pg.resolveAt(aPath);
assertThat(pg, not(equalTo(pg2)));
assertNotEquals(pg, pg2);
List<Path> paths = pg.paths();
assertEquals(3, paths.size());
@ -139,29 +140,31 @@ public class PathGroupTest {
assertEquals(aPath, pg2.roots().get(0));
}
@Test
public void testTransform() throws IOException {
for (var transform : TransformType.values()) {
testTransform(false, transform);
}
enum TransformType { COPY, MOVE, HANDLER };
private static Stream<Object[]> testTransform() {
return Stream.of(TransformType.values()).flatMap(transform -> {
return Stream.of(true, false).map(withExcludes -> {
return new Object[]{withExcludes,transform};
});
});
}
@Test
public void testTransformWithExcludes() throws IOException {
for (var transform : TransformType.values()) {
testTransform(true, transform);
}
}
@ParameterizedTest
@MethodSource("testTransform")
public void testTransform(boolean withExcludes, TransformType transform, @TempDir Path tempDir) throws IOException {
enum TransformType { Copy, Move, Handler };
final Path srcDir = tempDir.resolve("src");
Files.createDirectories(srcDir);
private void testTransform(boolean withExcludes, TransformType transform)
throws IOException {
final PathGroup pg = new PathGroup(Map.of(0, PATH_FOO, 1, PATH_BAR, 2,
PATH_EMPTY, 3, PATH_BAZ));
final Path dstDir = tempDir.resolve("dst");
Files.createDirectories(dstDir);
final Path srcDir = tempFolder.newFolder().toPath();
final Path dstDir = tempFolder.newFolder().toPath();
final PathGroup pg = new PathGroup(Map.of(
0, PATH_FOO,
1, PATH_BAR,
2, PATH_EMPTY,
3, PATH_BAZ));
Files.createDirectories(srcDir.resolve(PATH_FOO).resolve("a/b/c/d"));
Files.createFile(srcDir.resolve(PATH_FOO).resolve("a/b/c/file1"));
@ -181,7 +184,7 @@ public class PathGroupTest {
var srcFilesBeforeTransform = walkFiles(srcDir);
if (transform == TransformType.Handler) {
if (transform == TransformType.HANDLER) {
List<Map.Entry<Path, Path>> copyFile = new ArrayList<>();
List<Path> createDirectory = new ArrayList<>();
src.transform(dst, new PathGroup.TransformHandler() {
@ -231,9 +234,9 @@ public class PathGroupTest {
return;
}
if (transform == TransformType.Copy) {
if (transform == TransformType.COPY) {
src.copy(dst);
} else if (transform == TransformType.Move) {
} else if (transform == TransformType.MOVE) {
src.move(dst);
}
@ -248,30 +251,28 @@ public class PathGroupTest {
}
UnaryOperator<Path[]> removeExcludes = paths -> {
return Stream.of(paths)
.filter(path -> !excludedPaths.stream().anyMatch(
path::startsWith))
.collect(Collectors.toList()).toArray(Path[]::new);
.filter(path -> !excludedPaths.stream().anyMatch(path::startsWith))
.toArray(Path[]::new);
};
var dstFiles = walkFiles(dstDir);
assertArrayEquals(removeExcludes.apply(srcFilesBeforeTransform), dstFiles);
if (transform == TransformType.Copy) {
if (transform == TransformType.COPY) {
assertArrayEquals(dstFiles, removeExcludes.apply(walkFiles(srcDir)));
} else if (transform == TransformType.Move) {
} else if (transform == TransformType.MOVE) {
assertFalse(Files.exists(srcDir));
}
}
private static Path[] walkFiles(Path root) throws IOException {
try (var files = Files.walk(root)) {
return files.map(root::relativize).sorted().collect(
Collectors.toList()).toArray(Path[]::new);
return files.map(root::relativize).sorted().toArray(Path[]::new);
}
}
private final static Path PATH_FOO = Path.of("foo");
private final static Path PATH_BAR = Path.of("bar");
private final static Path PATH_BAZ = Path.of("baz");
private final static Path PATH_EMPTY = Path.of("");
private static final Path PATH_FOO = Path.of("foo");
private static final Path PATH_BAR = Path.of("bar");
private static final Path PATH_BAZ = Path.of("baz");
private static final Path PATH_EMPTY = Path.of("");
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -23,95 +23,76 @@
package jdk.jpackage.internal;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.lang.reflect.Method;
import static org.junit.Assert.assertEquals;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrowsExactly;
import static org.junit.jupiter.api.Assumptions.assumeTrue;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
@RunWith(Parameterized.class)
public class PlatformVersionTest {
public PlatformVersionTest(Function<String, DottedVersion> parser,
String version, boolean valid) {
this.parser = parser;
this.version = version;
this.valid = valid;
}
@Parameters
public static List<Object[]> data() {
List<Object[]> data = new ArrayList<>();
addTo(data, WIN_MSI_PRODUCT_VERSION_PARSER, true,
@ParameterizedTest
@ValueSource(strings = {
"0.0",
"255.255",
"0.0.0",
"255.255.65535",
"0.0.0.0",
"255.255.65535.999999"
);
})
public void testValidMsiProductVersion(String version) {
testImpl(PlatformVersion.WIN_MSI_PRODUCT_VERSION_CLASS, version, true);
}
addTo(data, WIN_MSI_PRODUCT_VERSION_PARSER, false,
@ParameterizedTest
@ValueSource(strings = {
"0",
"256.01",
"255.256",
"255.255.65536",
"1.2.3.4.5"
);
addTo(data, MAC_CFBUNDLE_VERSION_PARSER, true,
"1",
"1.2",
"1.2.3"
);
addTo(data, MAC_CFBUNDLE_VERSION_PARSER, false,
"0",
"0.1",
"1.2.3.4"
);
return data;
})
public void testInvalidMsiProductVersion(String version) {
testImpl(PlatformVersion.WIN_MSI_PRODUCT_VERSION_CLASS, version, false);
}
private static void addTo(List<Object[]> data,
Function<String, DottedVersion> parser, boolean valid,
String... values) {
if (parser != null) {
data.addAll(Stream.of(values).map(version -> new Object[]{parser,
version, valid}).collect(Collectors.toList()));
}
@ParameterizedTest
@ValueSource(strings = {"1", "1.2", "1.2.3"})
public void testValidCfBundleVersion(String version) {
testImpl(PlatformVersion.MAC_CFBUNDLE_VERSION_CLASS, version, true);
}
@Rule
public ExpectedException exceptionRule = ExpectedException.none();
@ParameterizedTest
@ValueSource(strings = {"0", "0.1", "1.2.3.4"})
public void testInvalidCfBundleVersion(String version) {
testImpl(PlatformVersion.MAC_CFBUNDLE_VERSION_CLASS, version, false);
}
@Test
public void testIt() {
private static void testImpl(PlatformVersion parser, String version, boolean valid) {
assumeTrue(parser.parser != null);
if (valid) {
assertEquals(parser.apply(version).toString(), version);
assertEquals(parser.parse(version).toString(), version);
} else {
exceptionRule.expect(IllegalArgumentException.class);
parser.apply(version);
assertThrowsExactly(IllegalArgumentException.class, () -> parser.parse(version));
}
}
private final Function<String, DottedVersion> parser;
private final String version;
private final boolean valid;
enum PlatformVersion {
MAC_CFBUNDLE_VERSION_CLASS("jdk.jpackage.internal.CFBundleVersion"),
WIN_MSI_PRODUCT_VERSION_CLASS("jdk.jpackage.internal.MsiVersion");
private final static Function<String, DottedVersion> MAC_CFBUNDLE_VERSION_PARSER = findParser(
"jdk.jpackage.internal.CFBundleVersion");
private final static Function<String, DottedVersion> WIN_MSI_PRODUCT_VERSION_PARSER = findParser(
"jdk.jpackage.internal.MsiVersion");
PlatformVersion(String className) {
parser = findParser(className);
}
DottedVersion parse(String versionString) {
return parser.apply(versionString);
}
private Function<String, DottedVersion> parser;
}
private static Function<String, DottedVersion> findParser(String className) {
try {
@ -124,8 +105,8 @@ public class PlatformVersionTest {
throw new RuntimeException(ex);
} catch (InvocationTargetException ex) {
Throwable causeEx = ex.getCause();
if (causeEx instanceof RuntimeException) {
throw (RuntimeException)causeEx;
if (causeEx instanceof RuntimeException rtEx) {
throw rtEx;
}
throw new RuntimeException(causeEx);
}
@ -136,4 +117,5 @@ public class PlatformVersionTest {
throw new IllegalArgumentException(ex);
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -25,12 +25,10 @@ package jdk.jpackage.internal;
import java.nio.file.Path;
import jdk.internal.util.OperatingSystem;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import org.junit.Test;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import org.junit.jupiter.api.Test;
public class ToolValidatorTest {
@ -70,11 +68,10 @@ public class ToolValidatorTest {
new DottedVersion("8")).setVersionParser(unused -> "10").validate());
}
private static void assertValidationFailure(ConfigException v,
boolean withCause) {
private static void assertValidationFailure(ConfigException v, boolean withCause) {
assertNotNull(v);
assertThat("", is(not(v.getMessage().strip())));
assertThat("", is(not(v.advice.strip())));
assertNotEquals("", v.getMessage().strip());
assertNotEquals("", v.getAdvice().strip());
if (withCause) {
assertNotNull(v.getCause());
} else {
@ -82,8 +79,8 @@ public class ToolValidatorTest {
}
}
private final static String TOOL_JAVA;
private final static String TOOL_UNKNOWN = Path.of(System.getProperty(
private static final String TOOL_JAVA;
private static final String TOOL_UNKNOWN = Path.of(System.getProperty(
"java.home"), "bin").toString();
static {