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

Fix tests #188

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
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
10 changes: 9 additions & 1 deletion build/Program.fs
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,17 @@ let init args =
Target.create "Build" (fun _ -> DotNet.build id "")

let testTFM tfm =
exec "dotnet" $"test --blame --blame-hang-timeout 60s --no-build --framework {tfm} --logger trx --logger GitHubActions -c Release .\\test\\Ionide.ProjInfo.Tests\\Ionide.ProjInfo.Tests.fsproj" "."
exec
"dotnet"
$"test --blame --blame-hang-timeout 2m --no-build --framework {tfm} --logger trx --logger GitHubActions -c Release -v n .\\test\\Ionide.ProjInfo.Tests\\Ionide.ProjInfo.Tests.fsproj -- Expecto.debug=true Expecto.parallel=false"
"."
|> ignore

let testTFM tfm =
exec "dotnet" $"run --framework {tfm} -c Release --project .\\test\\Ionide.ProjInfo.Tests\\Ionide.ProjInfo.Tests.fsproj" "."
|> ignore


Target.create "Test" DoNothing

Target.create "Test:net6.0" (fun _ -> testTFM "net6.0")
Expand Down
10 changes: 9 additions & 1 deletion src/Ionide.ProjInfo/FsLibLog.fs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// As of commit 599e765db64ba5bcde23a589f427453c52fdb132
// As of commit 1fe15c95c008567db63e00e823ca8768155e85c6
namespace Ionide.ProjInfo.Logging

open System.Text.RegularExpressions
Expand Down Expand Up @@ -772,10 +772,13 @@ module Providers =
static member Create() =
let createLogger =
let factoryType = getLogFactoryType.Value

let createLoggerMethodInfo = factoryType.GetMethod("CreateLogger", [| typedefof<string> |])

let instanceParam = Expression.Parameter(typedefof<ILoggerFactory>)
let nameParam = Expression.Parameter(typedefof<string>)
let instanceCast = Expression.Convert(instanceParam, factoryType)

let createLoggerMethodExp = Expression.Call(instanceCast, createLoggerMethodInfo, nameParam)

let createLogger =
Expand All @@ -801,7 +804,9 @@ module Providers =
Type.GetType("Microsoft.Extensions.Logging.LoggerExtensions, Microsoft.Extensions.Logging.Abstractions")

let loggerType = Type.GetType("Microsoft.Extensions.Logging.ILogger, Microsoft.Extensions.Logging.Abstractions")

let logEventLevelType = Type.GetType("Microsoft.Extensions.Logging.LogLevel, Microsoft.Extensions.Logging.Abstractions")

let instanceParam = Expression.Parameter(typedefof<ILogger>)

let instanceCast = Expression.Convert(instanceParam, loggerType)
Expand All @@ -811,6 +816,7 @@ module Providers =

let isEnabled =
let isEnabledMethodInfo = loggerType.GetMethod("IsEnabled", [| logEventLevelType |])

let isEnabledMethodCall = Expression.Call(instanceCast, isEnabledMethodInfo, levelCast)


Expand Down Expand Up @@ -907,6 +913,7 @@ module Providers =
let beginScopeMethodInfo = loggerType.GetMethod("BeginScope").MakeGenericMethod(typedefof<obj>)

let stateParam = Expression.Parameter(typedefof<obj>)

let beginScopeMethodCall = Expression.Call(instanceCast, beginScopeMethodInfo, stateParam)

Expression
Expand Down Expand Up @@ -973,6 +980,7 @@ module Providers =
| Some factory ->
// Create bogus logger that will propagate to a real logger later
let logger = factoryGateway.Value.CreateLogger factory (Guid.NewGuid().ToString())

loggerGateway.Value.BeginScope logger (box message)

let create () = MicrosoftProvider() :> ILogProvider
Expand Down
50 changes: 40 additions & 10 deletions src/Ionide.ProjInfo/Library.fs
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,7 @@ type BinaryLogGeneration =
/// </summary>
module ProjectLoader =


type LoadedProject = internal LoadedProject of ProjectInstance

[<RequireQualifiedAccess>]
Expand All @@ -337,11 +338,14 @@ module ProjectLoader =
| Success of LoadedProject
| Error of string

let internal logger (writer: StringWriter) =
let internal stringWriterLogger (writer: StringWriter) =
{ new ILogger with
member this.Initialize(eventSource: IEventSource) : unit =
// eventSource.ErrorRaised.Add(fun t -> writer.WriteLine t.Message) //Only log errors
eventSource.AnyEventRaised.Add(fun t -> writer.WriteLine t.Message)
eventSource.AnyEventRaised.Add(fun t ->
let message = t.Message
writer.WriteLine message
)

member this.Parameters: string = ""

Expand All @@ -355,6 +359,28 @@ module ProjectLoader =
with set (v: LoggerVerbosity): unit = ()
}


let msBuildToLogProvider () =
let msBuildLogger = LogProvider.getLoggerByName "MsBuild"

{ new ILogger with
member this.Initialize(eventSource: IEventSource) : unit =
eventSource.ErrorRaised.Add(fun t -> msBuildLogger.error (Log.setMessage t.Message))
eventSource.WarningRaised.Add(fun t -> msBuildLogger.warn (Log.setMessage t.Message))

eventSource.AnyEventRaised.Add(fun t -> msBuildLogger.info (Log.setMessage t.Message))

member this.Parameters
with get (): string = ""
and set (v: string): unit = ()

member this.Shutdown() : unit = ()

member this.Verbosity
with get (): LoggerVerbosity = LoggerVerbosity.Diagnostic
and set (v: LoggerVerbosity): unit = ()
}

let getTfm (path: string) readingProps isLegacyFrameworkProj =
let pi = ProjectInstance(path, globalProperties = readingProps, toolsVersion = null)

Expand All @@ -379,15 +405,19 @@ module ProjectLoader =
Some tfm

let createLoggers (paths: string seq) (binaryLogs: BinaryLogGeneration) (sw: StringWriter) =
let logger = logger (sw)
let swLogger = stringWriterLogger (sw)
let msbuildLogger = msBuildToLogProvider ()

let logFilePath (dir: DirectoryInfo, projectPath: string) =
let projectFileName = Path.GetFileName projectPath
let logFileName = Path.ChangeExtension(projectFileName, ".binlog")
Path.Combine(dir.FullName, logFileName)

match binaryLogs with
| BinaryLogGeneration.Off -> [ logger ]
| BinaryLogGeneration.Off -> [
swLogger
msbuildLogger
]
| BinaryLogGeneration.Within dir ->
let loggers =
paths
Expand All @@ -397,7 +427,8 @@ module ProjectLoader =
)

[
logger
msbuildLogger
swLogger
yield! loggers
]

Expand Down Expand Up @@ -851,6 +882,7 @@ type WorkspaceLoaderViaProjectGraph private (toolsPath, ?globalProperties: (stri
let (ToolsPath toolsPath) = toolsPath
let globalProperties = defaultArg globalProperties []
let logger = LogProvider.getLoggerFor<WorkspaceLoaderViaProjectGraph> ()

let loadingNotification = new Event<Types.WorkspaceProjectState>()

let handleProjectGraphFailures f =
Expand Down Expand Up @@ -1041,10 +1073,7 @@ type WorkspaceLoaderViaProjectGraph private (toolsPath, ?globalProperties: (stri

allProjectOptions
|> Seq.iter (fun po ->
logger.info (
Log.setMessage "Project loaded {project}"
>> Log.addContextDestructured "project" po.ProjectFileName
)
logger.info (Log.setMessageI $"Project loaded {po.ProjectFileName:project}")

loadingNotification.Trigger(
WorkspaceProjectState.Loaded(
Expand Down Expand Up @@ -1157,7 +1186,8 @@ type WorkspaceLoader private (toolsPath: ToolsPath, ?globalProperties: (string *
| Error msg when msg.Contains "The operation cannot be completed because a build is already in progress." ->
//Try to load project again
Threading.Thread.Sleep(50)
loadProject p
// loadProject p
[], None
| Error msg ->
loadingNotification.Trigger(WorkspaceProjectState.Failed(p, GenericError(p, msg)))
[], None
Expand Down
86 changes: 86 additions & 0 deletions test/Ionide.ProjInfo.Tests/FsLibLog.Expecto.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
namespace FsLibLog.Providers.Expecto

open System
open Ionide.ProjInfo.Logging

module EMsg = Expecto.Logging.Message
type ELL = Expecto.Logging.LogLevel

module internal Helpers =
let addExnOpt exOpt msg =
match exOpt with
| None -> msg
| Some ex ->
msg
|> EMsg.addExn ex

let addValues (items: obj[]) msg =
(msg,
items
|> Seq.mapi (fun i item -> i, item))
||> Seq.fold (fun msg (i, item) ->
msg
|> EMsg.setField (string i) item
)

let getLogLevel: LogLevel -> Expecto.Logging.LogLevel =
function
| LogLevel.Debug -> ELL.Debug
| LogLevel.Error -> ELL.Error
| LogLevel.Fatal -> ELL.Fatal
| LogLevel.Info -> ELL.Info
| LogLevel.Trace -> ELL.Verbose
| LogLevel.Warn -> ELL.Warn
| _ -> ELL.Warn

open Helpers

// Naive implementation, not that important, just need logging to actually work
type ExpectoLogProvider() =
let propertyStack = System.Collections.Generic.Stack<string * obj>()


let addProp key value =
propertyStack.Push(key, value)

{ new IDisposable with
member __.Dispose() =
propertyStack.Pop()
|> ignore
}

interface ILogProvider with
override __.GetLogger(name: string) : Logger =
let logger = Expecto.Logging.Log.create name

fun ll mt exnOpt values ->
match mt with
| Some f ->
let ll = getLogLevel ll

logger.log
ll
(fun ll ->
let message = f ()
let mutable msg = Expecto.Logging.Message.eventX message ll

for (propertyName, propertyValue) in (Seq.rev propertyStack) do
msg <- Expecto.Logging.Message.setField propertyName propertyValue msg

match exnOpt with
| None -> msg
| Some ex ->
msg
|> Expecto.Logging.Message.addExn ex
|> addValues values
)
|> Async.RunSynchronously

true
| None -> false

override __.OpenMappedContext (key: string) (value: obj) (b: bool) = addProp key value
override __.OpenNestedContext name = addProp "NDC" name

module ExpectoLogProvider =
let create () = ExpectoLogProvider() :> ILogProvider
10 changes: 3 additions & 7 deletions test/Ionide.ProjInfo.Tests/Ionide.ProjInfo.Tests.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
<GenerateProgramFile>false</GenerateProgramFile>
</PropertyGroup>
<ItemGroup>
<Compile Include="FsLibLog.Expecto.fs" />
<Compile Include="FileUtils.fs" />
<Compile Include="TestAssets.fs" />
<Compile Include="Tests.fs" />
Expand All @@ -20,17 +21,12 @@
<ProjectReference
Include="..\..\src\Ionide.ProjInfo.ProjectSystem\Ionide.ProjInfo.ProjectSystem.fsproj" />
</ItemGroup>

<!-- This is a workaround for the test framework using Microsoft.Build dependencies and our
project uses it's own set of Microsoft.Build dependencies which causes loading conflicts -->
<Target
Name="PostBuild"
AfterTargets="PostBuildEvent">
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Copy
SourceFiles="$([System.IO.Directory]::GetParent($(BundledRuntimeIdentifierGraphFile)))\NuGet.Frameworks.dll"
DestinationFolder="$(OutputPath)"
ContinueOnError="false" />
DestinationFolder="$(OutputPath)" ContinueOnError="false" />
</Target>

<Import Project="..\..\.paket\Paket.Restore.targets" />
</Project>
3 changes: 3 additions & 0 deletions test/Ionide.ProjInfo.Tests/Program.fs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,15 @@ open Ionide.ProjInfo.ProjectSystem
open Expecto
open Expecto.Impl
open Expecto.Logging
open FsLibLog.Providers.Expecto

let toolsPath = Init.init (IO.DirectoryInfo Environment.CurrentDirectory) None

[<Tests>]
let tests = Tests.tests toolsPath

Ionide.ProjInfo.Logging.LogProvider.setLoggerProvider (ExpectoLogProvider())


[<EntryPoint>]
let main argv =
Expand Down
Loading