2023-07-20 08:52:19 +00:00
|
|
|
|
using DistTestCore;
|
2023-07-20 11:37:11 +00:00
|
|
|
|
using DistTestCore.Codex;
|
2023-07-20 08:52:19 +00:00
|
|
|
|
using KubernetesWorkflow;
|
|
|
|
|
|
2023-07-20 11:37:11 +00:00
|
|
|
|
namespace ContinuousTests
|
2023-07-20 08:52:19 +00:00
|
|
|
|
{
|
|
|
|
|
public class ContinuousLogDownloader
|
|
|
|
|
{
|
|
|
|
|
private readonly TestLifecycle lifecycle;
|
2023-07-20 11:37:11 +00:00
|
|
|
|
private readonly CodexDeployment deployment;
|
|
|
|
|
private readonly string outputPath;
|
|
|
|
|
private readonly CancellationToken cancelToken;
|
2023-07-20 08:52:19 +00:00
|
|
|
|
|
2023-07-20 11:37:11 +00:00
|
|
|
|
public ContinuousLogDownloader(TestLifecycle lifecycle, CodexDeployment deployment, string outputPath, CancellationToken cancelToken)
|
2023-07-20 08:52:19 +00:00
|
|
|
|
{
|
|
|
|
|
this.lifecycle = lifecycle;
|
2023-07-20 11:37:11 +00:00
|
|
|
|
this.deployment = deployment;
|
|
|
|
|
this.outputPath = outputPath;
|
|
|
|
|
this.cancelToken = cancelToken;
|
2023-07-20 08:52:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Run()
|
|
|
|
|
{
|
2023-07-20 11:37:11 +00:00
|
|
|
|
while (!cancelToken.IsCancellationRequested)
|
2023-07-20 08:52:19 +00:00
|
|
|
|
{
|
|
|
|
|
UpdateLogs();
|
|
|
|
|
|
2023-07-20 11:37:11 +00:00
|
|
|
|
cancelToken.WaitHandle.WaitOne(TimeSpan.FromSeconds(15));
|
2023-07-20 08:52:19 +00:00
|
|
|
|
}
|
2023-07-21 07:00:07 +00:00
|
|
|
|
|
|
|
|
|
// After testing has stopped, we wait a little bit and fetch the logs one more time.
|
|
|
|
|
// If our latest fetch was not recent, interesting test-related log activity might
|
|
|
|
|
// not have been captured yet.
|
|
|
|
|
Thread.Sleep(TimeSpan.FromSeconds(10));
|
|
|
|
|
UpdateLogs();
|
2023-07-20 08:52:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void UpdateLogs()
|
|
|
|
|
{
|
2023-07-20 11:37:11 +00:00
|
|
|
|
foreach (var container in deployment.CodexContainers)
|
2023-07-20 08:52:19 +00:00
|
|
|
|
{
|
|
|
|
|
UpdateLog(container);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void UpdateLog(RunningContainer container)
|
|
|
|
|
{
|
2023-07-20 11:37:11 +00:00
|
|
|
|
var filepath = Path.Combine(outputPath, GetLogName(container));
|
|
|
|
|
if (!File.Exists(filepath))
|
|
|
|
|
{
|
|
|
|
|
File.WriteAllLines(filepath, new[] { container.Name });
|
|
|
|
|
}
|
2023-07-20 08:52:19 +00:00
|
|
|
|
|
|
|
|
|
var appender = new LogAppender(filepath);
|
|
|
|
|
|
|
|
|
|
lifecycle.CodexStarter.DownloadLog(container, appender);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static string GetLogName(RunningContainer container)
|
|
|
|
|
{
|
|
|
|
|
return container.Name
|
2023-07-20 11:37:11 +00:00
|
|
|
|
.Replace("<", "")
|
2023-07-20 08:52:19 +00:00
|
|
|
|
.Replace(">", "")
|
|
|
|
|
+ ".log";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class LogAppender : ILogHandler
|
|
|
|
|
{
|
|
|
|
|
private readonly string filename;
|
|
|
|
|
|
|
|
|
|
public LogAppender(string filename)
|
|
|
|
|
{
|
|
|
|
|
this.filename = filename;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Log(Stream log)
|
|
|
|
|
{
|
|
|
|
|
using var reader = new StreamReader(log);
|
2023-07-20 11:37:11 +00:00
|
|
|
|
var lines = File.ReadAllLines(filename);
|
|
|
|
|
var lastLine = lines.Last();
|
|
|
|
|
var recording = lines.Length < 3;
|
2023-07-20 08:52:19 +00:00
|
|
|
|
var line = reader.ReadLine();
|
|
|
|
|
while (line != null)
|
|
|
|
|
{
|
2023-07-20 11:37:11 +00:00
|
|
|
|
if (recording)
|
|
|
|
|
{
|
|
|
|
|
File.AppendAllLines(filename, new[] { line });
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
recording = line == lastLine;
|
|
|
|
|
}
|
2023-07-20 08:52:19 +00:00
|
|
|
|
|
2023-07-20 11:37:11 +00:00
|
|
|
|
line = reader.ReadLine();
|
2023-07-20 08:52:19 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|