Skip to content
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

Generate tests for code written in older .NET frameworks #323

Open
smhmhmd opened this issue May 16, 2024 · 4 comments
Open

Generate tests for code written in older .NET frameworks #323

smhmhmd opened this issue May 16, 2024 · 4 comments

Comments

@smhmhmd
Copy link

smhmhmd commented May 16, 2024

Hi @MchKosticyn

Nopcommerce-release-3.80 uses the older Windows-based .NET Framework (VS upgrades to .NET Framework 4.8), can VSharp generate tests for such code, I got this error while running VSharp from Visual Studio on Windows-10:

Unhandled exception: System.TypeLoadException: Could not load type 'System.Web.HttpResponseBase' from assembly 'System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.
   at System.RuntimeMethodHandle.GetMethodBody(IRuntimeMethodInfo method, RuntimeType declaringType)
   at System.Reflection.RuntimeMethodInfo.GetMethodBody()
   at VSharp.CSharpUtils.ReflectionUtils.<>c__DisplayClass1_0.<EnumerateExplorableMethods>b__0(MethodInfo m) in D:\Users\samiull\Documents\2023\cymbal-testgen\Cymbal-TestGen\VSharp\VSharp.CSharpUtils\ReflectionUtils.cs:line 23
   at System.Linq.Enumerable.WhereArrayIterator`1.MoveNext()
   at VSharp.CSharpUtils.ReflectionUtils.EnumerateExplorableMethods(Type type)+MoveNext() in D:\Users\samiull\Documents\2023\cymbal-testgen\Cymbal-TestGen\VSharp\VSharp.CSharpUtils\ReflectionUtils.cs:line 23
   at System.Linq.Enumerable.SelectManySingleSelectorIterator`2.MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at VSharp.TestGenerator.Cover(Assembly assembly, VSharpOptions options, Boolean renderSingleFile) in D:\Users\samiull\Documents\2023\cymbal-testgen\Cymbal-TestGen\VSharp\VSharp.API\VSharp.cs:line 455
   at VSharp.Runner.RunnerProgram.AllPublicMethodsHandler(FileInfo assemblyPath, Int32 timeout, Int32 solverTimeout, DirectoryInfo output, Boolean renderTests, Boolean runTests, SearchStrategy strat, Verbosity verbosity, UInt32 recursionThreshold, ExplorationMode explorationMode) in D:\Users\samiull\Documents\2023\cymbal-testgen\Cymbal-TestGen\VSharp\VSharp.Runner\RunnerProgram.cs:line 173
   at VSharp.Runner.RunnerProgram.<>c__DisplayClass9_0.<Main>b__9(InvocationContext context) in D:\Users\samiull\Documents\2023\cymbal-testgen\Cymbal-TestGen\VSharp\VSharp.Runner\RunnerProgram.cs:line 451
   at System.CommandLine.Invocation.AnonymousCommandHandler.Invoke(InvocationContext context)
   at System.CommandLine.Invocation.InvocationPipeline.<>c__DisplayClass4_0.<<BuildInvocationChain>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass17_0.<<UseParseErrorReporting>b__0>d.MoveNext()
--- End of stack trace from previous l

Command in Visual Studio is --all-public-methods D:\Users\samiull\Documents\2024\nopCommerce-release-3.80\src\Presentation\Nop.Web\bin\Nop.Core.dll -t 30 -o ..\out -v Trace

@smhmhmd
Copy link
Author

smhmhmd commented May 16, 2024

.NET Framework reference assemblies probably need to be added. If VSharp can have a command-line parameter to point to reference assemblies, that may help.

@smhmhmd
Copy link
Author

smhmhmd commented May 16, 2024

Getting method body does work with Mono.Cecil.

using System.Collections.Immutable;
using System.IO;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using System.Runtime.CompilerServices;
using Microsoft.Win32.SafeHandles;
using System.Reflection.PortableExecutable;
using System.Xml;
using System.Diagnostics;
using System.Xml.Linq;
using Mono.Cecil;
using Mono.Cecil.Cil;

class Program
{
    static void Main(string[] args)
    {

        var inputAssembly =
            @"D:\Users\samiull\Documents\2024\nopCommerce-release-3.80\src\Libraries\Nop.Core\bin\Debug\Nop.Core.dll";
        var path = Path.GetDirectoryName(inputAssembly);

        var assemblyResolver = new DefaultAssemblyResolver();
        var assemblyLocation = Path.GetDirectoryName(inputAssembly);
        assemblyResolver.AddSearchDirectory(assemblyLocation);

        var readerParameters = new ReaderParameters { AssemblyResolver = assemblyResolver };

        var assemblyDefinition = Mono.Cecil.AssemblyDefinition.ReadAssembly(
            @"D:\Users\samiull\Documents\2024\nopCommerce-release-3.80\src\Libraries\Nop.Core\bin\Debug\Nop.Core.dll",
            readerParameters);

        var module = assemblyDefinition.MainModule;
        foreach (var typeDefinition in module.Types)
        {
            Console.WriteLine("Type = " + typeDefinition.ToString());
        }

        var methods = assemblyDefinition.MainModule
            .GetTypes()
            .SelectMany(t => t.Methods
                .Where(m => m.HasBody)
                .Select(m =>  m ));

        foreach (var m in methods)
        {
            var count = m.Body.Instructions.Count;
            Console.WriteLine("Method " + m.Name + " has " + count + " instructions");
        }
    }
}

@MchKosticyn
Copy link
Member

Hi @smhmhmd

Before running V#, you should do dotnet publish --self-contained -r (RID) -c Release. You can find your RID in this paper https://learn.microsoft.com/ru-ru/dotnet/core/rid-catalog.
This command will create folder 'publish', in which all dependency assemblies will be.
Example of needed folder path: /Users/michael/Documents/Work/VSharp/VSharp.TestGenerator/bin/Release/net7.0/osx-arm64/publish/.
After that you need to use that path inside V# running command.
Example: --all-public-methods /Users/michael/Documents/Work/VSharp/VSharp.TestGenerator/bin/Release/net7.0/osx-arm64/publish/VSharp.TestGenerator.dll ....
This will help V# to find dependencies.

@smhmhmd
Copy link
Author

smhmhmd commented May 16, 2024

Hi @MchKosticyn

I published VSharp to a folder using Visual Studio and also published NopCommerce-3.80 to a folder.
The error is still there, will using Mono.Cecil instead of System.Reflection work better ?

samiull@DESKTOP-OS5I16B MINGW64 /d/Users/samiull/Documents/2024/vsharp-publish
$  dotnet VSharp.Runner.dll  --all-public-methods /d/Users/samiull/Documents/2024/nopcommerce-publish/bin/Nop.Web.dll -o ../out/ -t 30
Unhandled exception: System.TypeLoadException: Could not load type 'System.Web.HttpContextBase' from assembly 'System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.
   at System.RuntimeMethodHandle.GetMethodBody(IRuntimeMethodInfo method, RuntimeType declaringType)
   at System.Reflection.RuntimeMeth

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants