mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-27 02:30:06 +00:00
8377897: jpackage: make jdk.jpackage.internal.MockUtils available from other packages
Reviewed-by: almatvee
This commit is contained in:
parent
1ae2fee007
commit
acde30e0ab
@ -30,6 +30,7 @@ import static jdk.jpackage.internal.LinuxPackagingPipeline.APPLICATION_LAYOUT;
|
||||
import static jdk.jpackage.internal.cli.StandardBundlingOperation.CREATE_LINUX_APP_IMAGE;
|
||||
import static jdk.jpackage.internal.cli.StandardBundlingOperation.CREATE_LINUX_DEB;
|
||||
import static jdk.jpackage.internal.cli.StandardBundlingOperation.CREATE_LINUX_RPM;
|
||||
import static jdk.jpackage.internal.util.MemoizingSupplier.runOnce;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
@ -25,6 +25,7 @@
|
||||
package jdk.jpackage.internal;
|
||||
|
||||
import static java.util.stream.Collectors.toMap;
|
||||
import static jdk.jpackage.internal.util.MemoizingSupplier.runOnce;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
@ -36,7 +37,6 @@ import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Consumer;
|
||||
@ -50,6 +50,7 @@ import jdk.jpackage.internal.model.Application;
|
||||
import jdk.jpackage.internal.model.BundlingOperationDescriptor;
|
||||
import jdk.jpackage.internal.model.JPackageException;
|
||||
import jdk.jpackage.internal.model.Package;
|
||||
import jdk.jpackage.internal.util.MemoizingSupplier;
|
||||
import jdk.jpackage.internal.util.PathUtils;
|
||||
import jdk.jpackage.internal.util.Result;
|
||||
|
||||
@ -66,7 +67,7 @@ class DefaultBundlingEnvironment implements CliBundlingEnvironment {
|
||||
return runOnce(e.getValue());
|
||||
}));
|
||||
|
||||
this.defaultOperationSupplier = Objects.requireNonNull(defaultOperationSupplier).map(DefaultBundlingEnvironment::runOnce);
|
||||
this.defaultOperationSupplier = Objects.requireNonNull(defaultOperationSupplier).map(MemoizingSupplier::runOnce);
|
||||
}
|
||||
|
||||
|
||||
@ -110,10 +111,6 @@ class DefaultBundlingEnvironment implements CliBundlingEnvironment {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
static <T> Supplier<T> runOnce(Supplier<T> supplier) {
|
||||
return new CachingSupplier<>(supplier);
|
||||
}
|
||||
|
||||
static <T extends SystemEnvironment> Supplier<Result<Consumer<Options>>> createBundlerSupplier(
|
||||
Supplier<Result<T>> sysEnvResultSupplier, BiConsumer<Options, T> bundler) {
|
||||
Objects.requireNonNull(sysEnvResultSupplier);
|
||||
@ -223,25 +220,6 @@ class DefaultBundlingEnvironment implements CliBundlingEnvironment {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private static final class CachingSupplier<T> implements Supplier<T> {
|
||||
|
||||
CachingSupplier(Supplier<T> getter) {
|
||||
this.getter = Objects.requireNonNull(getter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T get() {
|
||||
return cachedValue.updateAndGet(v -> {
|
||||
return Optional.ofNullable(v).orElseGet(getter);
|
||||
});
|
||||
}
|
||||
|
||||
private final Supplier<T> getter;
|
||||
private final AtomicReference<T> cachedValue = new AtomicReference<>();
|
||||
}
|
||||
|
||||
|
||||
private final Map<BundlingOperationDescriptor, Supplier<Result<Consumer<Options>>>> bundlers;
|
||||
private final Optional<Supplier<Optional<BundlingOperationDescriptor>>> defaultOperationSupplier;
|
||||
}
|
||||
|
||||
@ -49,7 +49,7 @@ import jdk.jpackage.internal.util.CommandOutputControl.Result;
|
||||
import jdk.jpackage.internal.util.RetryExecutor;
|
||||
import jdk.jpackage.internal.util.function.ExceptionBox;
|
||||
|
||||
final class Executor {
|
||||
public final class Executor {
|
||||
|
||||
static Executor of(String... cmdline) {
|
||||
return of(List.of(cmdline));
|
||||
@ -78,118 +78,118 @@ final class Executor {
|
||||
mapper = other.mapper;
|
||||
}
|
||||
|
||||
Executor saveOutput(boolean v) {
|
||||
public Executor saveOutput(boolean v) {
|
||||
commandOutputControl.saveOutput(v);
|
||||
return this;
|
||||
}
|
||||
|
||||
Executor saveOutput() {
|
||||
public Executor saveOutput() {
|
||||
return saveOutput(true);
|
||||
}
|
||||
|
||||
Executor saveFirstLineOfOutput() {
|
||||
public Executor saveFirstLineOfOutput() {
|
||||
commandOutputControl.saveFirstLineOfOutput();
|
||||
return this;
|
||||
}
|
||||
|
||||
Executor charset(Charset v) {
|
||||
public Executor charset(Charset v) {
|
||||
commandOutputControl.charset(v);
|
||||
return this;
|
||||
}
|
||||
|
||||
Executor storeOutputInFiles(boolean v) {
|
||||
public Executor storeOutputInFiles(boolean v) {
|
||||
commandOutputControl.storeOutputInFiles(v);
|
||||
return this;
|
||||
}
|
||||
|
||||
Executor storeOutputInFiles() {
|
||||
public Executor storeOutputInFiles() {
|
||||
return storeOutputInFiles(true);
|
||||
}
|
||||
|
||||
Executor binaryOutput(boolean v) {
|
||||
public Executor binaryOutput(boolean v) {
|
||||
commandOutputControl.binaryOutput(v);
|
||||
return this;
|
||||
}
|
||||
|
||||
Executor binaryOutput() {
|
||||
public Executor binaryOutput() {
|
||||
return binaryOutput(true);
|
||||
}
|
||||
|
||||
Executor discardStdout(boolean v) {
|
||||
public Executor discardStdout(boolean v) {
|
||||
commandOutputControl.discardStdout(v);
|
||||
return this;
|
||||
}
|
||||
|
||||
Executor discardStdout() {
|
||||
public Executor discardStdout() {
|
||||
return discardStdout(true);
|
||||
}
|
||||
|
||||
Executor discardStderr(boolean v) {
|
||||
public Executor discardStderr(boolean v) {
|
||||
commandOutputControl.discardStderr(v);
|
||||
return this;
|
||||
}
|
||||
|
||||
Executor discardStderr() {
|
||||
public Executor discardStderr() {
|
||||
return discardStderr(true);
|
||||
}
|
||||
|
||||
Executor timeout(long v, TimeUnit unit) {
|
||||
public Executor timeout(long v, TimeUnit unit) {
|
||||
return timeout(Duration.of(v, unit.toChronoUnit()));
|
||||
}
|
||||
|
||||
Executor timeout(Duration v) {
|
||||
public Executor timeout(Duration v) {
|
||||
timeout = v;
|
||||
return this;
|
||||
}
|
||||
|
||||
Executor toolProvider(ToolProvider v) {
|
||||
public Executor toolProvider(ToolProvider v) {
|
||||
toolProvider = Objects.requireNonNull(v);
|
||||
processBuilder = null;
|
||||
return this;
|
||||
}
|
||||
|
||||
Optional<ToolProvider> toolProvider() {
|
||||
public Optional<ToolProvider> toolProvider() {
|
||||
return Optional.ofNullable(toolProvider);
|
||||
}
|
||||
|
||||
Executor processBuilder(ProcessBuilder v) {
|
||||
public Executor processBuilder(ProcessBuilder v) {
|
||||
processBuilder = Objects.requireNonNull(v);
|
||||
toolProvider = null;
|
||||
return this;
|
||||
}
|
||||
|
||||
Optional<ProcessBuilder> processBuilder() {
|
||||
public Optional<ProcessBuilder> processBuilder() {
|
||||
return Optional.ofNullable(processBuilder);
|
||||
}
|
||||
|
||||
Executor args(List<String> v) {
|
||||
public Executor args(List<String> v) {
|
||||
args.addAll(v);
|
||||
return this;
|
||||
}
|
||||
|
||||
Executor args(String... args) {
|
||||
public Executor args(String... args) {
|
||||
return args(List.of(args));
|
||||
}
|
||||
|
||||
List<String> args() {
|
||||
public List<String> args() {
|
||||
return args;
|
||||
}
|
||||
|
||||
Executor setQuiet(boolean v) {
|
||||
public Executor setQuiet(boolean v) {
|
||||
quietCommand = v;
|
||||
return this;
|
||||
}
|
||||
|
||||
Executor mapper(UnaryOperator<Executor> v) {
|
||||
public Executor mapper(UnaryOperator<Executor> v) {
|
||||
mapper = v;
|
||||
return this;
|
||||
}
|
||||
|
||||
Optional<UnaryOperator<Executor>> mapper() {
|
||||
public Optional<UnaryOperator<Executor>> mapper() {
|
||||
return Optional.ofNullable(mapper);
|
||||
}
|
||||
|
||||
Executor copy() {
|
||||
public Executor copy() {
|
||||
return new Executor(this);
|
||||
}
|
||||
|
||||
@ -261,7 +261,7 @@ final class Executor {
|
||||
});
|
||||
}
|
||||
|
||||
List<String> commandLine() {
|
||||
public List<String> commandLine() {
|
||||
if (processBuilder != null) {
|
||||
return Stream.of(processBuilder.command(), args).flatMap(Collection::stream).toList();
|
||||
} else if (toolProvider != null) {
|
||||
|
||||
@ -25,9 +25,9 @@
|
||||
package jdk.jpackage.internal;
|
||||
|
||||
@FunctionalInterface
|
||||
interface ExecutorFactory {
|
||||
public interface ExecutorFactory {
|
||||
|
||||
Executor executor();
|
||||
|
||||
static final ExecutorFactory DEFAULT = Executor::new;
|
||||
public static final ExecutorFactory DEFAULT = Executor::new;
|
||||
}
|
||||
|
||||
@ -33,17 +33,17 @@ public final class Globals {
|
||||
private Globals() {
|
||||
}
|
||||
|
||||
Globals objectFactory(ObjectFactory v) {
|
||||
public Globals objectFactory(ObjectFactory v) {
|
||||
checkMutable();
|
||||
objectFactory = Optional.ofNullable(v).orElse(ObjectFactory.DEFAULT);
|
||||
return this;
|
||||
}
|
||||
|
||||
ObjectFactory objectFactory() {
|
||||
public ObjectFactory objectFactory() {
|
||||
return objectFactory;
|
||||
}
|
||||
|
||||
Globals executorFactory(ExecutorFactory v) {
|
||||
public Globals executorFactory(ExecutorFactory v) {
|
||||
return objectFactory(ObjectFactory.build(objectFactory).executorFactory(v).create());
|
||||
}
|
||||
|
||||
|
||||
@ -28,38 +28,38 @@ import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import jdk.jpackage.internal.util.CompositeProxy;
|
||||
|
||||
interface ObjectFactory extends ExecutorFactory, RetryExecutorFactory {
|
||||
public interface ObjectFactory extends ExecutorFactory, RetryExecutorFactory {
|
||||
|
||||
static ObjectFactory.Builder build() {
|
||||
public static ObjectFactory.Builder build() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
static ObjectFactory.Builder build(ObjectFactory from) {
|
||||
public static ObjectFactory.Builder build(ObjectFactory from) {
|
||||
return build().initFrom(from);
|
||||
}
|
||||
|
||||
static final class Builder {
|
||||
public static final class Builder {
|
||||
private Builder() {
|
||||
}
|
||||
|
||||
ObjectFactory create() {
|
||||
public ObjectFactory create() {
|
||||
return CompositeProxy.build().invokeTunnel(CompositeProxyTunnel.INSTANCE).create(
|
||||
ObjectFactory.class,
|
||||
Optional.ofNullable(executorFactory).orElse(ExecutorFactory.DEFAULT),
|
||||
Optional.ofNullable(retryExecutorFactory).orElse(RetryExecutorFactory.DEFAULT));
|
||||
}
|
||||
|
||||
Builder initFrom(ObjectFactory of) {
|
||||
public Builder initFrom(ObjectFactory of) {
|
||||
Objects.requireNonNull(of);
|
||||
return executorFactory(of).retryExecutorFactory(of);
|
||||
}
|
||||
|
||||
Builder executorFactory(ExecutorFactory v) {
|
||||
public Builder executorFactory(ExecutorFactory v) {
|
||||
executorFactory = v;
|
||||
return this;
|
||||
}
|
||||
|
||||
Builder retryExecutorFactory(RetryExecutorFactory v) {
|
||||
public Builder retryExecutorFactory(RetryExecutorFactory v) {
|
||||
retryExecutorFactory = v;
|
||||
return this;
|
||||
}
|
||||
@ -68,5 +68,5 @@ interface ObjectFactory extends ExecutorFactory, RetryExecutorFactory {
|
||||
private RetryExecutorFactory retryExecutorFactory;
|
||||
}
|
||||
|
||||
static final ObjectFactory DEFAULT = build().create();
|
||||
public static final ObjectFactory DEFAULT = build().create();
|
||||
}
|
||||
|
||||
@ -27,9 +27,9 @@ package jdk.jpackage.internal;
|
||||
import jdk.jpackage.internal.util.RetryExecutor;
|
||||
|
||||
@FunctionalInterface
|
||||
interface RetryExecutorFactory {
|
||||
public interface RetryExecutorFactory {
|
||||
|
||||
<T, E extends Exception> RetryExecutor<T, E> retryExecutor(Class<? extends E> exceptionType);
|
||||
|
||||
static final RetryExecutorFactory DEFAULT = RetryExecutor::new;
|
||||
public static final RetryExecutorFactory DEFAULT = RetryExecutor::new;
|
||||
}
|
||||
|
||||
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2026, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.util;
|
||||
|
||||
import jdk.jpackage.internal.util.function.ExceptionBox;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.FutureTask;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public final class MemoizingSupplier<T> implements Supplier<T> {
|
||||
|
||||
public MemoizingSupplier(Supplier<T> supplier) {
|
||||
this.future = new FutureTask<>(Objects.requireNonNull(supplier)::get);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T get() {
|
||||
try {
|
||||
future.run();
|
||||
return future.get();
|
||||
} catch (InterruptedException ex) {
|
||||
throw ExceptionBox.toUnchecked(ex);
|
||||
} catch (ExecutionException ex) {
|
||||
throw ExceptionBox.toUnchecked(ExceptionBox.unbox(ex.getCause()));
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> Supplier<T> runOnce(Supplier<T> supplier) {
|
||||
return new MemoizingSupplier<>(supplier);
|
||||
}
|
||||
|
||||
private final FutureTask<T> future;
|
||||
}
|
||||
@ -29,6 +29,7 @@ import static jdk.jpackage.internal.WinPackagingPipeline.APPLICATION_LAYOUT;
|
||||
import static jdk.jpackage.internal.cli.StandardBundlingOperation.CREATE_WIN_APP_IMAGE;
|
||||
import static jdk.jpackage.internal.cli.StandardBundlingOperation.CREATE_WIN_EXE;
|
||||
import static jdk.jpackage.internal.cli.StandardBundlingOperation.CREATE_WIN_MSI;
|
||||
import static jdk.jpackage.internal.util.MemoizingSupplier.runOnce;
|
||||
|
||||
import jdk.jpackage.internal.cli.Options;
|
||||
|
||||
|
||||
@ -21,18 +21,27 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package jdk.jpackage.internal;
|
||||
package jdk.jpackage.test.stdmock;
|
||||
|
||||
import static jdk.jpackage.internal.util.MemoizingSupplier.runOnce;
|
||||
import static jdk.jpackage.internal.util.function.ThrowingSupplier.toSupplier;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.function.UnaryOperator;
|
||||
import java.util.spi.ToolProvider;
|
||||
import java.util.stream.Collectors;
|
||||
import jdk.internal.util.OperatingSystem;
|
||||
import jdk.jpackage.internal.Executor;
|
||||
import jdk.jpackage.internal.ExecutorFactory;
|
||||
import jdk.jpackage.internal.Globals;
|
||||
import jdk.jpackage.internal.ObjectFactory;
|
||||
import jdk.jpackage.internal.cli.CliBundlingEnvironment;
|
||||
import jdk.jpackage.internal.cli.Main;
|
||||
import jdk.jpackage.internal.util.function.ExceptionBox;
|
||||
@ -41,11 +50,11 @@ import jdk.jpackage.test.mock.ToolProviderCommandMock;
|
||||
import jdk.jpackage.test.mock.VerbatimCommandMock;
|
||||
|
||||
/**
|
||||
* Bridges "jdk.jpackage.internal" and "jdk.jpackage.test.mock" packages.
|
||||
* Utilities to create jpackage mock.
|
||||
*/
|
||||
public final class MockUtils {
|
||||
public final class JPackageMockUtils {
|
||||
|
||||
private MockUtils() {
|
||||
private JPackageMockUtils() {
|
||||
}
|
||||
|
||||
public static JPackageToolProviderBuilder buildJPackage() {
|
||||
@ -58,30 +67,23 @@ public final class MockUtils {
|
||||
return createJPackageToolProvider(os(), createObjectFactory());
|
||||
}
|
||||
|
||||
public Consumer<Globals> createGlobalsMutator() {
|
||||
var objectFactory = createObjectFactory();
|
||||
return globals -> {
|
||||
globals.objectFactory(objectFactory);
|
||||
};
|
||||
}
|
||||
|
||||
public void applyToGlobals() {
|
||||
createGlobalsMutator().accept(Globals.instance());
|
||||
Globals.instance().objectFactory(createObjectFactory());
|
||||
}
|
||||
|
||||
ExecutorFactory createExecutorFactory() {
|
||||
var commandMocksExecutorFactory = Optional.ofNullable(script).map(MockUtils::withCommandMocks).map(mapper -> {
|
||||
public ExecutorFactory createExecutorFactory() {
|
||||
var commandMocksExecutorFactory = Optional.ofNullable(script).map(JPackageMockUtils::withCommandMocks).map(mapper -> {
|
||||
return mapper.apply(ExecutorFactory.DEFAULT);
|
||||
}).orElse(ExecutorFactory.DEFAULT);
|
||||
|
||||
var recordingExecutorFactory = Optional.ofNullable(listener).map(MockUtils::withCommandListener).map(mapper -> {
|
||||
var recordingExecutorFactory = Optional.ofNullable(listener).map(JPackageMockUtils::withCommandListener).map(mapper -> {
|
||||
return mapper.apply(commandMocksExecutorFactory);
|
||||
}).orElse(commandMocksExecutorFactory);
|
||||
|
||||
return recordingExecutorFactory;
|
||||
}
|
||||
|
||||
ObjectFactory createObjectFactory() {
|
||||
public ObjectFactory createObjectFactory() {
|
||||
var executorFactory = createExecutorFactory();
|
||||
if (executorFactory == ExecutorFactory.DEFAULT) {
|
||||
return ObjectFactory.DEFAULT;
|
||||
@ -125,6 +127,31 @@ public final class MockUtils {
|
||||
return createJPackageToolProvider(OperatingSystem.current(), script);
|
||||
}
|
||||
|
||||
public static Map<OperatingSystem, Supplier<CliBundlingEnvironment>> availableBundlingEnvironments() {
|
||||
return Map.ofEntries(
|
||||
Map.entry(OperatingSystem.WINDOWS, "WinBundlingEnvironment"),
|
||||
Map.entry(OperatingSystem.LINUX, "LinuxBundlingEnvironment"),
|
||||
Map.entry(OperatingSystem.MACOS, "MacBundlingEnvironment")
|
||||
).entrySet().stream().map(e -> {
|
||||
Constructor<?> ctor;
|
||||
try {
|
||||
ctor = Class.forName("jdk.jpackage.internal." + e.getValue()).getConstructor();
|
||||
} catch (NoSuchMethodException | SecurityException ex) {
|
||||
throw ExceptionBox.toUnchecked(ex);
|
||||
} catch (ClassNotFoundException ex) {
|
||||
return Optional.<Map.Entry<OperatingSystem, Supplier<CliBundlingEnvironment>>>empty();
|
||||
}
|
||||
return Optional.of(Map.entry(e.getKey(), toSupplier(() -> {
|
||||
return (CliBundlingEnvironment)ctor.newInstance();
|
||||
})));
|
||||
}).flatMap(Optional::stream).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
||||
}
|
||||
|
||||
public static CliBundlingEnvironment createBundlingEnvironment(OperatingSystem os) {
|
||||
Objects.requireNonNull(os);
|
||||
return Objects.requireNonNull(availableBundlingEnvironments().get(os)).get();
|
||||
}
|
||||
|
||||
private static UnaryOperator<ExecutorFactory> withCommandListener(Consumer<List<String>> listener) {
|
||||
Objects.requireNonNull(listener);
|
||||
return executorFactory -> {
|
||||
@ -180,39 +207,11 @@ public final class MockUtils {
|
||||
};
|
||||
}
|
||||
|
||||
public static CliBundlingEnvironment createBundlingEnvironment(OperatingSystem os) {
|
||||
Objects.requireNonNull(os);
|
||||
|
||||
String bundlingEnvironmentClassName;
|
||||
switch (os) {
|
||||
case WINDOWS -> {
|
||||
bundlingEnvironmentClassName = "WinBundlingEnvironment";
|
||||
}
|
||||
case LINUX -> {
|
||||
bundlingEnvironmentClassName = "LinuxBundlingEnvironment";
|
||||
}
|
||||
case MACOS -> {
|
||||
bundlingEnvironmentClassName = "MacBundlingEnvironment";
|
||||
}
|
||||
default -> {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
return toSupplier(() -> {
|
||||
var ctor = Class.forName(String.join(".",
|
||||
DefaultBundlingEnvironment.class.getPackageName(),
|
||||
bundlingEnvironmentClassName
|
||||
)).getConstructor();
|
||||
return (CliBundlingEnvironment)ctor.newInstance();
|
||||
}).get();
|
||||
}
|
||||
|
||||
static ToolProvider createJPackageToolProvider(OperatingSystem os, ObjectFactory of) {
|
||||
private static ToolProvider createJPackageToolProvider(OperatingSystem os, ObjectFactory of) {
|
||||
Objects.requireNonNull(os);
|
||||
Objects.requireNonNull(of);
|
||||
|
||||
var impl = new Main.Provider(DefaultBundlingEnvironment.runOnce(() -> {
|
||||
var impl = new Main.Provider(runOnce(() -> {
|
||||
return createBundlingEnvironment(os);
|
||||
}));
|
||||
|
||||
@ -37,6 +37,7 @@ import jdk.jpackage.test.mock.CommandActionSpecs;
|
||||
import jdk.jpackage.test.mock.CommandMockExit;
|
||||
import jdk.jpackage.test.mock.CommandMockSpec;
|
||||
import jdk.jpackage.test.mock.Script;
|
||||
import jdk.jpackage.test.stdmock.JPackageMockUtils;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
@ -137,7 +138,7 @@ public class LinuxPackageArchTest {
|
||||
|
||||
Globals.main(() -> {
|
||||
|
||||
MockUtils.buildJPackage().script(script).applyToGlobals();
|
||||
JPackageMockUtils.buildJPackage().script(script).applyToGlobals();
|
||||
|
||||
Result<LinuxPackageArch> arch = LinuxPackageArch.create(pkgType);
|
||||
|
||||
|
||||
@ -34,6 +34,7 @@ import jdk.jpackage.test.mock.CommandActionSpecs;
|
||||
import jdk.jpackage.test.mock.CommandMockExit;
|
||||
import jdk.jpackage.test.mock.CommandMockSpec;
|
||||
import jdk.jpackage.test.mock.Script;
|
||||
import jdk.jpackage.test.stdmock.JPackageMockUtils;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
@ -86,7 +87,7 @@ public class LinuxSystemEnvironmentTest {
|
||||
|
||||
Globals.main(() -> {
|
||||
|
||||
MockUtils.buildJPackage().script(script).applyToGlobals();
|
||||
JPackageMockUtils.buildJPackage().script(script).applyToGlobals();
|
||||
|
||||
var actual = LinuxSystemEnvironment.detectNativePackageType();
|
||||
|
||||
|
||||
@ -36,9 +36,9 @@
|
||||
* @requires (os.family == "linux")
|
||||
* @library /test/jdk/tools/jpackage/helpers
|
||||
* @build jdk.jpackage.test.mock.*
|
||||
* @build jdk.jpackage.test.stdmock.*
|
||||
* @compile/module=jdk.jpackage -Xlint:all -Werror
|
||||
* jdk/jpackage/internal/LinuxSystemEnvironmentTest.java
|
||||
* ../../share/jdk.jpackage/jdk/jpackage/internal/MockUtils.java
|
||||
* @run junit jdk.jpackage/jdk.jpackage.internal.LinuxSystemEnvironmentTest
|
||||
*/
|
||||
|
||||
@ -57,8 +57,8 @@
|
||||
* @requires (os.family == "linux")
|
||||
* @library /test/jdk/tools/jpackage/helpers
|
||||
* @build jdk.jpackage.test.mock.*
|
||||
* @build jdk.jpackage.test.stdmock.*
|
||||
* @compile/module=jdk.jpackage -Xlint:all -Werror
|
||||
* jdk/jpackage/internal/LinuxPackageArchTest.java
|
||||
* ../../share/jdk.jpackage/jdk/jpackage/internal/MockUtils.java
|
||||
* @run junit jdk.jpackage/jdk.jpackage.internal.LinuxPackageArchTest
|
||||
*/
|
||||
|
||||
@ -56,6 +56,7 @@ import jdk.jpackage.test.mock.CommandMockSpec;
|
||||
import jdk.jpackage.test.mock.MockIllegalStateException;
|
||||
import jdk.jpackage.test.mock.ScriptSpec;
|
||||
import jdk.jpackage.test.mock.ScriptSpecInDir;
|
||||
import jdk.jpackage.test.stdmock.JPackageMockUtils;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
@ -240,7 +241,7 @@ public class MacDmgPackagerTest {
|
||||
|
||||
var script = dir(Objects.requireNonNull(workDir)).create();
|
||||
|
||||
ExecutorFactory executorFactory = MockUtils.buildJPackage()
|
||||
ExecutorFactory executorFactory = JPackageMockUtils.buildJPackage()
|
||||
.script(script).listener(System.out::println).createExecutorFactory();
|
||||
|
||||
var objectFactory = ObjectFactory.build()
|
||||
@ -406,14 +407,14 @@ public class MacDmgPackagerTest {
|
||||
}
|
||||
}
|
||||
|
||||
private final static BiConsumer<Path, Consumer<Path>> EXPAND_PATH = (path, sink) -> {
|
||||
private static final BiConsumer<Path, Consumer<Path>> EXPAND_PATH = (path, sink) -> {
|
||||
do {
|
||||
sink.accept(path);
|
||||
path = path.getParent();
|
||||
} while (path != null);
|
||||
};
|
||||
|
||||
private final static List<Path> DMG_ICON_FILES = Stream.of(
|
||||
private static final List<Path> DMG_ICON_FILES = Stream.of(
|
||||
".VolumeIcon.icns",
|
||||
".background/background.tiff"
|
||||
).map(Path::of).collect(Collectors.toUnmodifiableList());
|
||||
|
||||
@ -32,11 +32,11 @@ import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
import jdk.jpackage.internal.util.RetryExecutor;
|
||||
import jdk.jpackage.test.mock.CommandActionSpecs;
|
||||
import jdk.jpackage.test.mock.CommandMockExit;
|
||||
import jdk.jpackage.test.mock.CommandMockSpec;
|
||||
import jdk.jpackage.test.mock.Script;
|
||||
import jdk.jpackage.test.stdmock.JPackageMockUtils;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
@ -143,7 +143,7 @@ public class MacDmgSystemEnvironmentTest {
|
||||
}).createSequence();
|
||||
|
||||
Globals.main(() -> {
|
||||
MockUtils.buildJPackage().script(script).applyToGlobals();
|
||||
JPackageMockUtils.buildJPackage().script(script).applyToGlobals();
|
||||
|
||||
var actual = MacDmgSystemEnvironment.findSetFileUtility();
|
||||
|
||||
|
||||
@ -36,9 +36,9 @@
|
||||
* @requires (os.family == "mac")
|
||||
* @library /test/jdk/tools/jpackage/helpers
|
||||
* @build jdk.jpackage.test.mock.*
|
||||
* @build jdk.jpackage.test.stdmock.*
|
||||
* @compile/module=jdk.jpackage -Xlint:all -Werror
|
||||
* jdk/jpackage/internal/MacDmgSystemEnvironmentTest.java
|
||||
* ../../share/jdk.jpackage/jdk/jpackage/internal/MockUtils.java
|
||||
* @run junit jdk.jpackage/jdk.jpackage.internal.MacDmgSystemEnvironmentTest
|
||||
*/
|
||||
|
||||
@ -47,8 +47,8 @@
|
||||
* @requires (os.family == "mac")
|
||||
* @library /test/jdk/tools/jpackage/helpers
|
||||
* @build jdk.jpackage.test.mock.*
|
||||
* @build jdk.jpackage.test.stdmock.*
|
||||
* @compile/module=jdk.jpackage -Xlint:all -Werror
|
||||
* jdk/jpackage/internal/MacDmgPackagerTest.java
|
||||
* ../../share/jdk.jpackage/jdk/jpackage/internal/MockUtils.java
|
||||
* @run junit jdk.jpackage/jdk.jpackage.internal.MacDmgPackagerTest
|
||||
*/
|
||||
|
||||
@ -54,6 +54,7 @@ import jdk.jpackage.test.mock.CommandActionSpecs;
|
||||
import jdk.jpackage.test.mock.CommandMock;
|
||||
import jdk.jpackage.test.mock.CommandMockExit;
|
||||
import jdk.jpackage.test.mock.Script;
|
||||
import jdk.jpackage.test.stdmock.JPackageMockUtils;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
||||
@ -96,7 +97,7 @@ public class DefaultBundlingEnvironmentTest extends JUnitAdapter {
|
||||
|
||||
var script = createMockScript(op);
|
||||
|
||||
ToolProvider jpackage = MockUtils.buildJPackage()
|
||||
ToolProvider jpackage = JPackageMockUtils.buildJPackage()
|
||||
.os(op.os())
|
||||
.script(script)
|
||||
.listener(executedCommands::add).create();
|
||||
|
||||
@ -50,7 +50,6 @@ import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import jdk.internal.util.OperatingSystem;
|
||||
import jdk.jpackage.internal.Globals;
|
||||
import jdk.jpackage.internal.MockUtils;
|
||||
import jdk.jpackage.internal.model.ConfigException;
|
||||
import jdk.jpackage.internal.model.ExecutableAttributesWithCapturedOutput;
|
||||
import jdk.jpackage.internal.model.JPackageException;
|
||||
@ -67,6 +66,7 @@ import jdk.jpackage.test.TKit;
|
||||
import jdk.jpackage.test.mock.CommandActionSpecs;
|
||||
import jdk.jpackage.test.mock.Script;
|
||||
import jdk.jpackage.test.mock.VerbatimCommandMock;
|
||||
import jdk.jpackage.test.stdmock.JPackageMockUtils;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
@ -124,9 +124,8 @@ public class MainTest extends JUnitAdapter {
|
||||
var jpackageToolProviderMock = new ToolProvider() {
|
||||
@Override
|
||||
public int run(PrintWriter out, PrintWriter err, String... args) {
|
||||
var globalsMutator = MockUtils.buildJPackage().script(script).createGlobalsMutator();
|
||||
return Globals.main(() -> {
|
||||
globalsMutator.accept(Globals.instance());
|
||||
return Globals.main(() -> {
|
||||
JPackageMockUtils.buildJPackage().script(script).applyToGlobals();
|
||||
|
||||
var result = ExecutionResult.create(args);
|
||||
|
||||
|
||||
@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Copyright (c) 2026, 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.util;
|
||||
|
||||
import static jdk.jpackage.internal.util.function.ThrowingRunnable.toRunnable;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrowsExactly;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.IntStream;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
||||
class MemoizingSupplierTest {
|
||||
|
||||
@Test
|
||||
void test() {
|
||||
var supplier = count(() -> "foo");
|
||||
var runOnceSupplier = MemoizingSupplier.runOnce(supplier);
|
||||
|
||||
assertEquals(0, supplier.counter());
|
||||
|
||||
assertEquals("foo", runOnceSupplier.get());
|
||||
assertEquals("foo", runOnceSupplier.get());
|
||||
|
||||
assertEquals(1, supplier.counter());
|
||||
}
|
||||
|
||||
@Test
|
||||
void test_null() {
|
||||
CountingSupplier<String> supplier = count(() -> null);
|
||||
var runOnceSupplier = MemoizingSupplier.runOnce(supplier);
|
||||
|
||||
assertEquals(0, supplier.counter());
|
||||
|
||||
assertEquals(null, runOnceSupplier.get());
|
||||
assertEquals(null, runOnceSupplier.get());
|
||||
|
||||
assertEquals(1, supplier.counter());
|
||||
}
|
||||
|
||||
@Test
|
||||
void test_throws_Exception() {
|
||||
CountingSupplier<String> supplier = count(() -> {
|
||||
throw new IllegalStateException("Kaput!");
|
||||
});
|
||||
var runOnceSupplier = MemoizingSupplier.runOnce(supplier);
|
||||
|
||||
assertEquals(0, supplier.counter());
|
||||
|
||||
assertThrowsExactly(IllegalStateException.class, () -> {
|
||||
runOnceSupplier.get();
|
||||
});
|
||||
|
||||
assertThrowsExactly(IllegalStateException.class, () -> {
|
||||
runOnceSupplier.get();
|
||||
});
|
||||
|
||||
assertEquals(1, supplier.counter());
|
||||
}
|
||||
|
||||
@Test
|
||||
void test_throws_Error() {
|
||||
CountingSupplier<String> supplier = count(() -> {
|
||||
throw new Error("Grand kaput!");
|
||||
});
|
||||
var runOnceSupplier = MemoizingSupplier.runOnce(supplier);
|
||||
|
||||
assertEquals(0, supplier.counter());
|
||||
|
||||
assertThrowsExactly(Error.class, () -> {
|
||||
runOnceSupplier.get();
|
||||
});
|
||||
|
||||
assertThrowsExactly(Error.class, () -> {
|
||||
runOnceSupplier.get();
|
||||
});
|
||||
|
||||
assertEquals(1, supplier.counter());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAsync() throws InterruptedException {
|
||||
var supplier = count(() -> "foo");
|
||||
var runOnceSupplier = MemoizingSupplier.runOnce(supplier);
|
||||
|
||||
final var supplierCount = 100;
|
||||
final var supplierExecutor = Executors.newVirtualThreadPerTaskExecutor();
|
||||
|
||||
// Schedule invoking "runOnceSupplier.get()" in a separate virtual threads.
|
||||
// Start and suspend threads, waiting until all scheduled threads have started.
|
||||
// After all scheduled threads start, resume them.
|
||||
// This should result in multiple simultaneous "runOnceSupplier.get()" calls.
|
||||
|
||||
var readyLatch = new CountDownLatch(supplierCount);
|
||||
var startLatch = new CountDownLatch(1);
|
||||
|
||||
var futures = IntStream.range(0, supplierCount).mapToObj(_ -> {
|
||||
return CompletableFuture.runAsync(toRunnable(() -> {
|
||||
readyLatch.countDown();
|
||||
startLatch.await();
|
||||
runOnceSupplier.get();
|
||||
|
||||
}), supplierExecutor);
|
||||
}).toList();
|
||||
|
||||
readyLatch.await();
|
||||
startLatch.countDown();
|
||||
|
||||
CompletableFuture.allOf(futures.toArray(CompletableFuture[]::new)).join();
|
||||
|
||||
assertEquals(1, supplier.counter());
|
||||
}
|
||||
|
||||
private static <T> CountingSupplier<T> count(Supplier<T> supplier) {
|
||||
return new CountingSupplier<>(supplier);
|
||||
}
|
||||
|
||||
private static final class CountingSupplier<T> implements Supplier<T> {
|
||||
|
||||
CountingSupplier(Supplier<T> impl) {
|
||||
this.impl = Objects.requireNonNull(impl);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T get() {
|
||||
counter++;
|
||||
return impl.get();
|
||||
}
|
||||
|
||||
int counter() {
|
||||
return counter;
|
||||
}
|
||||
|
||||
private int counter;
|
||||
private final Supplier<T> impl;
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user