Bind PackageServer to ephemeral port to avoid port conflicts (#227)

This is a comprehensive solution to the "flaky PackageServer tests"
problem. It rules out port conflicts and imposes no limits on test
parallelism. The same solution can be used for other test servers
in the future.

Major changes:
- Turn `PackageServer` from a singleton into a class that is
  instantiated per test class or test method.
- Start the server the first time its `port` property is read.
  Bind the server to an ephemeral port instead of port 12110.
- For every test that uses `PackageServer`, pass the server port to
  `--test-port`, `HttpClient.Builder.setTestPort`, the `CliBaseOptions`
  or `ExecutorOptions` constructor, or the Gradle plugin's `testPort` property.
  Wire all of these to `RequestRewritingClient`'s `testPort` constructor parameter.
- Enhance `RequestRewritingClient` to replace port 12110 with `testPort`
  in request URIs unless `testPort` is -1 (its default).
- Introduce `ExecutorOptions.Builder`.
  This makes executor options more comfortable to create
  and allows to hide options such as `testPort`.
- Deprecate the `ExecutorOptions` constructor to steer users towards the builder.
- Get rid of `ExecutorOptions2`, which is no longer needed.
- Clean up `EmbeddedExecutorTest` with the help of the builder.
This commit is contained in:
translatenix
2024-03-13 10:40:55 -07:00
committed by GitHub
parent 1e608b2aae
commit 014b3a8816
26 changed files with 756 additions and 581 deletions

View File

@@ -279,6 +279,8 @@ public class PklPlugin implements Plugin<Project> {
spec.getModuleCacheDir().set(IoUtils.getDefaultModuleCacheDir().toFile());
spec.getNoCache().convention(false);
spec.getTestPort().convention(-1);
}
private void configureCodeGenSpec(CodeGenSpec spec) {
@@ -421,6 +423,7 @@ public class PklPlugin implements Plugin<Project> {
task.getNoCache().set(spec.getNoCache());
task.getModuleCacheDir().set(spec.getModuleCacheDir());
task.getEvalTimeout().set(spec.getEvalTimeout());
task.getTestPort().set(spec.getTestPort());
}
private <T extends ModulesTask, S extends ModulesSpec> void configureModulesTask(T task, S spec) {

View File

@@ -48,4 +48,6 @@ public interface BasePklSpec {
// use same type (Duration) as Gradle's `Task.timeout`
Property<Duration> getEvalTimeout();
Property<Integer> getTestPort();
}

View File

@@ -123,6 +123,10 @@ public abstract class BasePklTask extends DefaultTask {
@Optional
public abstract Property<Duration> getEvalTimeout();
@Input
@Optional
public abstract Property<Integer> getTestPort();
@TaskAction
public void runTask() {
doRunTask();
@@ -153,6 +157,7 @@ public abstract class BasePklTask extends DefaultTask {
false,
false,
false,
getTestPort().getOrElse(-1),
Collections.emptyList());
}
return cachedOptions;

View File

@@ -178,6 +178,7 @@ public abstract class ModulesTask extends BasePklTask {
getOmitProjectSettings().getOrElse(false),
getNoProject().getOrElse(false),
false,
getTestPort().getOrElse(-1),
Collections.emptyList());
}
return cachedOptions;