Skip to content

Fixes and logging #1771

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions utbot-rd/src/main/rdgen/org/utbot/rd/models/CSharpModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,6 @@ object VSharpModel: Ext(CSharpRoot) {
init {
call("generate", generateArguments, generateResults).async
signal("ping", PredefinedType.string).async
signal("log", PredefinedType.string).async
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,39 +44,47 @@ public class VSharpModel : RdExtBase
//public fields
[NotNull] public RdCall<GenerateArguments, GenerateResults> Generate => _Generate;
[NotNull] public ISignal<string> Ping => _Ping;
[NotNull] public ISignal<string> Log => _Log;

//private fields
[NotNull] private readonly RdCall<GenerateArguments, GenerateResults> _Generate;
[NotNull] private readonly RdSignal<string> _Ping;
[NotNull] private readonly RdSignal<string> _Log;

//primary constructor
private VSharpModel(
[NotNull] RdCall<GenerateArguments, GenerateResults> generate,
[NotNull] RdSignal<string> ping
[NotNull] RdSignal<string> ping,
[NotNull] RdSignal<string> log
)
{
if (generate == null) throw new ArgumentNullException("generate");
if (ping == null) throw new ArgumentNullException("ping");
if (log == null) throw new ArgumentNullException("log");

_Generate = generate;
_Ping = ping;
_Log = log;
_Generate.Async = true;
_Ping.Async = true;
_Log.Async = true;
BindableChildren.Add(new KeyValuePair<string, object>("generate", _Generate));
BindableChildren.Add(new KeyValuePair<string, object>("ping", _Ping));
BindableChildren.Add(new KeyValuePair<string, object>("log", _Log));
}
//secondary constructor
private VSharpModel (
) : this (
new RdCall<GenerateArguments, GenerateResults>(GenerateArguments.Read, GenerateArguments.Write, GenerateResults.Read, GenerateResults.Write),
new RdSignal<string>(JetBrains.Rd.Impl.Serializers.ReadString, JetBrains.Rd.Impl.Serializers.WriteString),
new RdSignal<string>(JetBrains.Rd.Impl.Serializers.ReadString, JetBrains.Rd.Impl.Serializers.WriteString)
) {}
//deconstruct trait
//statics



protected override long SerializationHash => -2362293640438957269L;
protected override long SerializationHash => -5982678710127900748L;

protected override Action<ISerializers> Register => RegisterDeclaredTypesSerializers;
public static void RegisterDeclaredTypesSerializers(ISerializers serializers)
Expand Down Expand Up @@ -104,6 +112,7 @@ public override void Print(PrettyPrinter printer)
using (printer.IndentCookie()) {
printer.Print("generate = "); _Generate.PrintEx(printer); printer.Println();
printer.Print("ping = "); _Ping.PrintEx(printer); printer.Println();
printer.Print("log = "); _Log.PrintEx(printer); printer.Println();
}
printer.Print(")");
}
Expand Down
31 changes: 26 additions & 5 deletions utbot-rider/src/dotnet/UtBot/UtBot.VSharp/VSharpMain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.IO;
using System.Reflection;
using System.Runtime.Loader;
using System.Text;
using JetBrains.Collections.Viewable;
using JetBrains.Lifetimes;
using JetBrains.Rd;
Expand All @@ -13,16 +14,35 @@
using UtBot.Rd;
using UtBot.Rd.Generated;
using VSharp;
using VSharp.System;
using VSharp.TestRenderer;
using Thread = System.Threading.Thread;

namespace UtBot.VSharp;

public static class VSharpMain
{
public static readonly string VSharpProcessName = "VSharp";

private class SignalWriter : TextWriter
{
private readonly ISignal<string> _signal;
public SignalWriter(ISignal<string> signal)
{
_signal = signal;
}

public override void Write(string value)
{
_signal.Fire(value);
}

public override void WriteLine(string value)
{
Write(value);
}

public override Encoding Encoding => Encoding.Default;
}

private static GenerateResults GenerateImpl(GenerateArguments arguments)
{
var (assemblyPath, projectCsprojPath, solutionFilePath,
Expand All @@ -40,15 +60,14 @@ private static GenerateResults GenerateImpl(GenerateArguments arguments)
if (methodInfo?.Name != descriptor.MethodName)
throw new InvalidDataException(
$"cannot find method - ${descriptor.MethodName} for type - ${descriptor.TypeName}");
var stat = TestGenerator.Cover(methodInfo, generationTimeout);
var stat = TestGenerator.Cover(methodInfo, generationTimeout, verbosity:Verbosity.Info);
var targetProject = new FileInfo(projectCsprojPath);
var solution = new FileInfo(solutionFilePath);
var declaringType = methodInfo.DeclaringType;
Debug.Assert(declaringType != null);
var (generatedProject, renderedFiles) =
Renderer.Render(stat.Results(), targetProject, declaringType, assemblyLoadContext, solution, targetFramework);
return new GenerateResults(true, generatedProject.FullName, renderedFiles.ToArray(), null);
;
}

public static void Main(string[] args)
Expand All @@ -65,6 +84,8 @@ public static void Main(string[] args)
scheduler.Queue(() =>
{
var vSharpModel = new VSharpModel(ldef.Lifetime, protocol);
// Configuring V# logger: messages will be send via RD to UTBot plugin process
Logger.ConfigureWriter(new SignalWriter(vSharpModel.Log));
vSharpModel.Generate.Set((_, arguments) =>
{
try
Expand Down Expand Up @@ -94,4 +115,4 @@ public static void Main(string[] args)
// Thread.Sleep(1000);
ldef.Terminate();
}
}
}
43 changes: 27 additions & 16 deletions utbot-rider/src/dotnet/UtBot/UtBot/ProcessWithRdServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Net;
using JetBrains.Annotations;
using JetBrains.Application.Threading;
using JetBrains.Collections.Viewable;
using JetBrains.Lifetimes;
Expand All @@ -11,6 +12,7 @@
using JetBrains.Threading;
using JetBrains.Util;
using JetBrains.Util.Logging;
using UtBot.Rd;
using UtBot.Rd.Generated;

namespace UtBot;
Expand All @@ -20,14 +22,14 @@ public class ProcessWithRdServer
{
public Lifetime Lifetime => _ldef.Lifetime;
public Protocol Protocol;
public VSharpModel VSharpModel { get; private set; }
[CanBeNull] public VSharpModel VSharpModel { get; private set; }

private readonly LifetimeDefinition _ldef;
private Process _process;
private ILogger _logger = Logger.GetLogger<ProcessWithRdServer>();
[CanBeNull] private Process _process;

public ProcessWithRdServer(string name, string workingDir, int port, string exePath, IShellLocks shellLocks, Lifetime? parent = null)
public ProcessWithRdServer(string name, string workingDir, int port, string exePath, IShellLocks shellLocks, Lifetime? parent = null, [CanBeNull] ILogger logger = null)
{
logger ??= Logger.GetLogger<ProcessWithRdServer>();
using var blockingCollection = new BlockingCollection<String>(2);
shellLocks.AssertNonMainThread();
_ldef = (parent ?? Lifetime.Eternal).CreateNested();
Expand All @@ -41,9 +43,11 @@ public ProcessWithRdServer(string name, string workingDir, int port, string exeP
var wire = new SocketWire.Server(Lifetime, scheduler, socket);
var serializers = new Serializers();
var identities = new Identities(IdKind.Server);
var startInfo = new ProcessStartInfo("dotnet", $"\"{exePath}\" {port}");

startInfo.WorkingDirectory = workingDir;
var startInfo = new ProcessStartInfo("dotnet", $"\"{exePath}\" {port}")
{
WorkingDirectory = workingDir
};

Protocol = new Protocol(name, serializers, identities, scheduler, wire, Lifetime);
scheduler.Queue(() =>
{
Expand All @@ -55,6 +59,7 @@ public ProcessWithRdServer(string name, string workingDir, int port, string exeP
blockingCollection.TryAdd(s);
}
});
VSharpModel.Log.Advise(Lifetime, s => logger.Info($"V#: {s}"));
});
_process = new Process();
_process.StartInfo = startInfo;
Expand All @@ -64,20 +69,26 @@ public ProcessWithRdServer(string name, string workingDir, int port, string exeP
else
_ldef.Terminate();
});
if (_process?.HasExited == false)

if (_process?.HasExited == true) return;

SpinWaitEx.SpinUntil(pingLdef.Lifetime, () =>
{
SpinWaitEx.SpinUntil(pingLdef.Lifetime, () =>
if (_process?.HasExited == true)
{
VSharpModel?.Ping.Fire("UtBot");
return blockingCollection.TryTake(out _);
});
pingLdef.Terminate();
}
VSharpModel = null;
_ldef.Terminate();
}

VSharpModel?.Ping.Fire(RdUtil.MainProcessName);
return blockingCollection.TryTake(out _);
});
pingLdef.Terminate();
}
catch (Exception)
{
_ldef.Terminate();
throw;
}
}
}
}
19 changes: 10 additions & 9 deletions utbot-rider/src/dotnet/UtBot/UtBot/UnitTestBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -118,17 +118,18 @@ private void Generate(IBackgroundProgressIndicator progressIndicator, IProject p

_logger.Catch(() =>
{
var name = VSharpMain.VSharpProcessName;
var workingDir = project.ProjectFileLocation.Directory.FullPath;
var port = NetworkUtil.GetFreePort();
var proc = new ProcessWithRdServer(VSharpMain.VSharpProcessName, project.ProjectFileLocation.FullPath, port, vsharpRunner.FullPath,
project.Locks,
_lifetime);
var runnerPath = vsharpRunner.FullPath;
var proc = new ProcessWithRdServer(name, workingDir, port, runnerPath, project.Locks, _lifetime, _logger);
var projectCsprojPath = project.ProjectFileLocation.FullPath;
var vsharpProjectTarget = calculateTestProjectTarget(tfm);
var vSharpProjectTarget = calculateTestProjectTarget(tfm);
var args = new GenerateArguments(assemblyPath.FullPath, projectCsprojPath, solutionFilePath, descriptor,
GenerationTimeout, vsharpProjectTarget);
var result = proc.VSharpModel.Generate.Sync(args, RpcTimeouts.Maximal);
GenerationTimeout, vSharpProjectTarget);
var result = proc.VSharpModel?.Generate.Sync(args, RpcTimeouts.Maximal);
_logger.Info("Result acquired");
if (result.IsGenerated)
if (result is { IsGenerated: true })
{
_shellLocks.ExecuteOrQueue(_lifetime, "UnitTestBuilder::Generate", () =>
{
Expand All @@ -142,8 +143,8 @@ private void Generate(IBackgroundProgressIndicator progressIndicator, IProject p
}
else
{
_logger.Info(
$"Could not generate tests for ${currentGeneratedItem}, exception - ${result.ExceptionMessage}");
var ex = result == null ? "Could not start V#" : result.ExceptionMessage;
_logger.Info($"Could not generate tests for ${currentGeneratedItem}, exception - {ex}");
}
});

Expand Down