Ещё фиксы от ИИ
All checks were successful
Build and Push Docker Images / build (src/LiquidCode.Tester.Gateway/Dockerfile, git.nullptr.top/liquidcode/liquidcode-tester-gateway-roman, gateway) (push) Successful in 57s
Build and Push Docker Images / build (src/LiquidCode.Tester.Worker/Dockerfile, git.nullptr.top/liquidcode/liquidcode-tester-worker-roman, worker) (push) Successful in 1m17s

This commit is contained in:
2025-11-05 22:15:50 +03:00
parent a8c0ec9ed3
commit 6ed26ae29b
6 changed files with 95 additions and 17 deletions

View File

@@ -61,8 +61,15 @@ public class CSharpExecutionServiceIsolate : IExecutionService
});
chmodProcess?.WaitForExit();
// Prepare output file in box
// Prepare input/output files inside the sandbox
var outputFilePath = Path.Combine(boxDir, "output.txt");
string? sandboxInputPath = null;
if (!string.IsNullOrEmpty(inputFilePath) && File.Exists(inputFilePath))
{
sandboxInputPath = Path.Combine(boxDir, "input.txt");
File.Copy(inputFilePath, sandboxInputPath, overwrite: true);
}
// Run in Isolate
var isolateResult = await _isolateService.RunAsync(new IsolateRunOptions
@@ -75,7 +82,7 @@ public class CSharpExecutionServiceIsolate : IExecutionService
StackLimitKb = 256 * 1024,
ProcessLimit = 1, // Single process for C#
EnableNetwork = false,
StdinFile = inputFilePath,
StdinFile = sandboxInputPath,
StdoutFile = outputFilePath,
WorkingDirectory = "/box"
});

View File

@@ -61,8 +61,15 @@ public class CppExecutionServiceIsolate : IExecutionService
});
chmodProcess?.WaitForExit();
// Prepare output file in box
// Prepare input/output files inside the sandbox
var outputFilePath = Path.Combine(boxDir, "output.txt");
string? sandboxInputPath = null;
if (!string.IsNullOrEmpty(inputFilePath) && File.Exists(inputFilePath))
{
sandboxInputPath = Path.Combine(boxDir, "input.txt");
File.Copy(inputFilePath, sandboxInputPath, overwrite: true);
}
// Run in Isolate
var isolateResult = await _isolateService.RunAsync(new IsolateRunOptions
@@ -75,7 +82,7 @@ public class CppExecutionServiceIsolate : IExecutionService
StackLimitKb = 256 * 1024, // 256 MB stack
ProcessLimit = 1, // Single process only
EnableNetwork = false, // No network access
StdinFile = inputFilePath,
StdinFile = sandboxInputPath,
StdoutFile = outputFilePath,
WorkingDirectory = "/box"
});

View File

@@ -1,3 +1,4 @@
using System;
using System.Diagnostics;
using System.Text;
@@ -157,17 +158,17 @@ public class IsolateService
// I/O redirection
if (!string.IsNullOrEmpty(options.StdinFile))
{
args.Add($"--stdin={options.StdinFile}");
args.Add($"--stdin={MapSandboxPath(options.StdinFile, options.BoxId)}");
}
if (!string.IsNullOrEmpty(options.StdoutFile))
{
args.Add($"--stdout={options.StdoutFile}");
args.Add($"--stdout={MapSandboxPath(options.StdoutFile, options.BoxId)}");
}
if (!string.IsNullOrEmpty(options.StderrFile))
{
args.Add($"--stderr={options.StderrFile}");
args.Add($"--stderr={MapSandboxPath(options.StderrFile, options.BoxId)}");
}
// Working directory
@@ -210,6 +211,25 @@ public class IsolateService
return string.Join(" ", args);
}
private static string MapSandboxPath(string path, int boxId)
{
if (string.IsNullOrEmpty(path))
{
return path;
}
var normalizedPath = Path.GetFullPath(path);
var boxRoot = Path.GetFullPath($"/var/local/lib/isolate/{boxId}/box");
if (normalizedPath.StartsWith(boxRoot, StringComparison.Ordinal))
{
var relative = normalizedPath.Substring(boxRoot.Length).TrimStart(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
return relative.Length == 0 ? "/box" : $"/box/{relative.Replace(Path.DirectorySeparatorChar, '/')}";
}
return normalizedPath;
}
/// <summary>
/// Parse isolate metadata file
/// </summary>
@@ -267,9 +287,6 @@ public class IsolateService
case "status":
result.Status = value;
result.TimeLimitExceeded = value == "TO";
result.MemoryLimitExceeded = value == "XX" || value == "MLE";
result.RuntimeError = value == "RE" || value == "SG";
break;
case "message":
@@ -282,7 +299,10 @@ public class IsolateService
case "cg-oom-killed":
result.CgroupOomKilled = value == "1";
result.MemoryLimitExceeded = true;
if (result.CgroupOomKilled)
{
result.MemoryLimitExceeded = true;
}
break;
case "csw-voluntary":
@@ -297,6 +317,29 @@ public class IsolateService
}
}
// Derive status-related flags after parsing all metadata
switch (result.Status)
{
case "TO":
result.TimeLimitExceeded = true;
break;
case "RE":
case "SG":
result.RuntimeError = true;
break;
case "XX":
// Internal error reported by isolate
result.RuntimeError = true;
break;
}
if (!result.MemoryLimitExceeded &&
!string.IsNullOrEmpty(result.Message) &&
result.Message.Contains("memory limit", StringComparison.OrdinalIgnoreCase))
{
result.MemoryLimitExceeded = true;
}
return result;
}

View File

@@ -57,8 +57,15 @@ public class JavaExecutionServiceIsolate : IExecutionService
File.Copy(file, destPath, overwrite: true);
}
// Prepare output file in box
// Prepare input/output files inside the sandbox
var outputFilePath = Path.Combine(boxDir, "output.txt");
string? sandboxInputPath = null;
if (!string.IsNullOrEmpty(inputFilePath) && File.Exists(inputFilePath))
{
sandboxInputPath = Path.Combine(boxDir, "input.txt");
File.Copy(inputFilePath, sandboxInputPath, overwrite: true);
}
// Run in Isolate
// Note: Java needs more memory for JVM overhead
@@ -75,7 +82,7 @@ public class JavaExecutionServiceIsolate : IExecutionService
StackLimitKb = 256 * 1024, // 256 MB stack
ProcessLimit = 64, // Java creates multiple threads
EnableNetwork = false,
StdinFile = inputFilePath,
StdinFile = sandboxInputPath,
StdoutFile = outputFilePath,
WorkingDirectory = "/box"
});

View File

@@ -52,8 +52,15 @@ public class KotlinExecutionServiceIsolate : IExecutionService
File.Copy(executablePath, boxJarPath, overwrite: true);
// Prepare output file in box
// Prepare input/output files inside the sandbox
var outputFilePath = Path.Combine(boxDir, "output.txt");
string? sandboxInputPath = null;
if (!string.IsNullOrEmpty(inputFilePath) && File.Exists(inputFilePath))
{
sandboxInputPath = Path.Combine(boxDir, "input.txt");
File.Copy(inputFilePath, sandboxInputPath, overwrite: true);
}
// Run in Isolate (Kotlin runs via Java)
var kotlinMemoryMb = Math.Max(memoryLimitMb, 128); // Minimum 128MB for JVM
@@ -69,7 +76,7 @@ public class KotlinExecutionServiceIsolate : IExecutionService
StackLimitKb = 256 * 1024,
ProcessLimit = 64, // JVM creates multiple threads
EnableNetwork = false,
StdinFile = inputFilePath,
StdinFile = sandboxInputPath,
StdoutFile = outputFilePath,
WorkingDirectory = "/box"
});

View File

@@ -55,8 +55,15 @@ public class PythonExecutionServiceIsolate : IExecutionService
File.Copy(executablePath, boxScriptPath, overwrite: true);
// Prepare output file in box
// Prepare input/output files inside the sandbox
var outputFilePath = Path.Combine(boxDir, "output.txt");
string? sandboxInputPath = null;
if (!string.IsNullOrEmpty(inputFilePath) && File.Exists(inputFilePath))
{
sandboxInputPath = Path.Combine(boxDir, "input.txt");
File.Copy(inputFilePath, sandboxInputPath, overwrite: true);
}
// Get Python executable from configuration
var pythonExecutable = _configuration["Python:Executable"] ?? "python3";
@@ -73,7 +80,7 @@ public class PythonExecutionServiceIsolate : IExecutionService
StackLimitKb = 256 * 1024,
ProcessLimit = 1, // Single process for Python
EnableNetwork = false,
StdinFile = inputFilePath,
StdinFile = sandboxInputPath,
StdoutFile = outputFilePath,
WorkingDirectory = "/box"
});