implements PR-05.7
This commit is contained in:
parent
0cc836246f
commit
6dacedb5ed
@ -6,5 +6,6 @@ enum CompatibilityError {
|
|||||||
HOSTCALL_INDEX_OUT_OF_BOUNDS,
|
HOSTCALL_INDEX_OUT_OF_BOUNDS,
|
||||||
UNUSED_SYSC_DECL,
|
UNUSED_SYSC_DECL,
|
||||||
MISSING_CAPABILITY,
|
MISSING_CAPABILITY,
|
||||||
|
RUNTIME_BACKED_REQUIRED,
|
||||||
RUNTIME_REJECTED,
|
RUNTIME_REJECTED,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,27 +11,39 @@ import java.util.List;
|
|||||||
final class RuntimeBackedCompatibilityAdapter implements RuntimeCompatibilityAdapter {
|
final class RuntimeBackedCompatibilityAdapter implements RuntimeCompatibilityAdapter {
|
||||||
private static final String DEFAULT_RUNTIME_LINE = "runtime-line-unknown";
|
private static final String DEFAULT_RUNTIME_LINE = "runtime-line-unknown";
|
||||||
private static final String FALLBACK_MODE = "local-fallback";
|
private static final String FALLBACK_MODE = "local-fallback";
|
||||||
|
private static final String STRICT_FLAG_ENV = "PROMETEU_GATE_I_STRICT";
|
||||||
|
|
||||||
private final RuntimeCompatibilityAdapter fallback;
|
private final RuntimeCompatibilityAdapter fallback;
|
||||||
private final Path runtimeRoot;
|
private final Path runtimeRoot;
|
||||||
private final String runtimeLine;
|
private final String runtimeLine;
|
||||||
private final String runtimeCheckCommand;
|
private final String runtimeCheckCommand;
|
||||||
|
private final boolean strictRuntimeBacked;
|
||||||
|
|
||||||
RuntimeBackedCompatibilityAdapter(final RuntimeCompatibilityAdapter fallback) {
|
RuntimeBackedCompatibilityAdapter(final RuntimeCompatibilityAdapter fallback) {
|
||||||
this(
|
this(
|
||||||
fallback == null ? new LocalRuntimeCompatibilityAdapter() : fallback,
|
fallback == null ? new LocalRuntimeCompatibilityAdapter() : fallback,
|
||||||
Path.of("../runtime"),
|
Path.of("../runtime"),
|
||||||
System.getenv("PROMETEU_RUNTIME_CHECK_CMD"));
|
System.getenv("PROMETEU_RUNTIME_CHECK_CMD"),
|
||||||
|
strictRuntimeBackedFromEnvironment());
|
||||||
}
|
}
|
||||||
|
|
||||||
RuntimeBackedCompatibilityAdapter(
|
RuntimeBackedCompatibilityAdapter(
|
||||||
final RuntimeCompatibilityAdapter fallback,
|
final RuntimeCompatibilityAdapter fallback,
|
||||||
final Path runtimeRoot,
|
final Path runtimeRoot,
|
||||||
final String runtimeCheckCommand) {
|
final String runtimeCheckCommand) {
|
||||||
|
this(fallback, runtimeRoot, runtimeCheckCommand, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
RuntimeBackedCompatibilityAdapter(
|
||||||
|
final RuntimeCompatibilityAdapter fallback,
|
||||||
|
final Path runtimeRoot,
|
||||||
|
final String runtimeCheckCommand,
|
||||||
|
final boolean strictRuntimeBacked) {
|
||||||
this.fallback = fallback == null ? new LocalRuntimeCompatibilityAdapter() : fallback;
|
this.fallback = fallback == null ? new LocalRuntimeCompatibilityAdapter() : fallback;
|
||||||
this.runtimeRoot = runtimeRoot == null ? Path.of("../runtime") : runtimeRoot;
|
this.runtimeRoot = runtimeRoot == null ? Path.of("../runtime") : runtimeRoot;
|
||||||
this.runtimeLine = readRuntimeLine(this.runtimeRoot);
|
this.runtimeLine = readRuntimeLine(this.runtimeRoot);
|
||||||
this.runtimeCheckCommand = runtimeCheckCommand == null ? "" : runtimeCheckCommand.trim();
|
this.runtimeCheckCommand = runtimeCheckCommand == null ? "" : runtimeCheckCommand.trim();
|
||||||
|
this.strictRuntimeBacked = strictRuntimeBacked;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -87,6 +99,14 @@ final class RuntimeBackedCompatibilityAdapter implements RuntimeCompatibilityAda
|
|||||||
private CompatibilityResult fallbackWithReason(
|
private CompatibilityResult fallbackWithReason(
|
||||||
final CompatibilityResult local,
|
final CompatibilityResult local,
|
||||||
final String reason) {
|
final String reason) {
|
||||||
|
if (strictRuntimeBacked) {
|
||||||
|
return new CompatibilityResult(
|
||||||
|
CompatibilityError.RUNTIME_BACKED_REQUIRED,
|
||||||
|
local.hostcallCount(),
|
||||||
|
runtimeLine,
|
||||||
|
FALLBACK_MODE,
|
||||||
|
"strict gate-i requires runtime-backed adapter: " + reason);
|
||||||
|
}
|
||||||
return new CompatibilityResult(
|
return new CompatibilityResult(
|
||||||
local.error(),
|
local.error(),
|
||||||
local.hostcallCount(),
|
local.hostcallCount(),
|
||||||
@ -134,4 +154,21 @@ final class RuntimeBackedCompatibilityAdapter implements RuntimeCompatibilityAda
|
|||||||
}
|
}
|
||||||
return output.substring(0, 160) + "...";
|
return output.substring(0, 160) + "...";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean strictRuntimeBackedFromEnvironment() {
|
||||||
|
if (isTruthy(System.getenv(STRICT_FLAG_ENV))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return isTruthy(System.getenv("CI"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isTruthy(final String value) {
|
||||||
|
if (value == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return switch (value.trim().toLowerCase()) {
|
||||||
|
case "1", "true", "yes", "on" -> true;
|
||||||
|
default -> false;
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -35,6 +35,49 @@ class RuntimeBackedCompatibilityAdapterTest {
|
|||||||
assertTrue(!result.runtimeLine().isBlank());
|
assertTrue(!result.runtimeLine().isBlank());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void checkMustFailInStrictModeWhenRuntimeCommandIsUnavailable() {
|
||||||
|
final var adapter = new RuntimeBackedCompatibilityAdapter(
|
||||||
|
new LocalRuntimeCompatibilityAdapter(),
|
||||||
|
Path.of("."),
|
||||||
|
"",
|
||||||
|
true);
|
||||||
|
final var module = moduleWithSingleRet();
|
||||||
|
|
||||||
|
final var result = adapter.check(module);
|
||||||
|
|
||||||
|
assertEquals(CompatibilityError.RUNTIME_BACKED_REQUIRED, result.error());
|
||||||
|
assertEquals("local-fallback", result.adapterMode());
|
||||||
|
assertTrue(result.reason().contains("strict gate-i requires runtime-backed adapter"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void checkMustPassInStrictModeWhenRuntimeCommandIsValid() {
|
||||||
|
final var adapter = new RuntimeBackedCompatibilityAdapter(
|
||||||
|
new LocalRuntimeCompatibilityAdapter(),
|
||||||
|
Path.of("."),
|
||||||
|
"echo runtime-check-ok",
|
||||||
|
true);
|
||||||
|
final var module = moduleWithSingleRet();
|
||||||
|
|
||||||
|
final var result = adapter.check(module);
|
||||||
|
|
||||||
|
assertEquals(CompatibilityError.NONE, result.error());
|
||||||
|
assertEquals("runtime-backed", result.adapterMode());
|
||||||
|
assertTrue(result.reason().contains("accepted artifact"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private BytecodeModule moduleWithSingleRet() {
|
||||||
|
return new BytecodeModule(
|
||||||
|
0,
|
||||||
|
ReadOnlyList.empty(),
|
||||||
|
ReadOnlyList.from(new BytecodeModule.FunctionMeta(0, 2, 0, 0, 0, 1)),
|
||||||
|
codeRet(),
|
||||||
|
null,
|
||||||
|
ReadOnlyList.empty(),
|
||||||
|
ReadOnlyList.empty());
|
||||||
|
}
|
||||||
|
|
||||||
private byte[] codeRet() {
|
private byte[] codeRet() {
|
||||||
final var out = ByteBuffer.allocate(2).order(ByteOrder.LITTLE_ENDIAN);
|
final var out = ByteBuffer.allocate(2).order(ByteOrder.LITTLE_ENDIAN);
|
||||||
out.putShort((short) 0x51);
|
out.putShort((short) 0x51);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user