diff --git a/AltCover.Async/AltCover.Async.csproj b/AltCover.Async/AltCover.Async.csproj deleted file mode 100644 index 5dcd7b23e..000000000 --- a/AltCover.Async/AltCover.Async.csproj +++ /dev/null @@ -1,29 +0,0 @@ - - - AltCover.Async - False - net46 - false - false - false - - - 11.0 - True - - - - - - TRACE;DEBUG;CODE_ANALYSIS - CS1591 - - - TRACE - CS1591 - - - - - - \ No newline at end of file diff --git a/AltCover.Async/AltCover.Async.fsproj b/AltCover.Async/AltCover.Async.fsproj new file mode 100644 index 000000000..0d8e7e6e7 --- /dev/null +++ b/AltCover.Async/AltCover.Async.fsproj @@ -0,0 +1,31 @@ + + + + net46 + AltCover.Async + AltCover.Recorder + false + false + false + --keyfile:$(InfrastructureKey) + + + + TRACE + + + + + TRACE;DEBUG;CODE_ANALYSIS + + + + + + + + + + + + \ No newline at end of file diff --git a/AltCover.Async/Instance.cs b/AltCover.Async/Instance.cs deleted file mode 100644 index 3177ac51d..000000000 --- a/AltCover.Async/Instance.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System.Collections.Generic; -using System; -using System.Runtime.InteropServices; -using System.Threading; -using System.Runtime.Versioning; -using System.Diagnostics.CodeAnalysis; - -[assembly: CLSCompliant(true)] -[assembly: ComVisible(false)] - -namespace AltCover.Recorder; - -public static class Instance -{ - //internal static IEnumerable Modules - //{ - // get { return new string[] { "a", "b", "c", "d" }; } - //} - - public static class I - { - internal static class CallTrack - { - [SuppressMessage("Microsoft.Performance", - "CA1823:AvoidUnusedPrivateFields", - Justification = "Template code only")] - private static readonly TargetFrameworkAttribute attr = - new TargetFrameworkAttribute(".NETFramework,Version=v4.6"); - - private static readonly AsyncLocal> __value = new AsyncLocal>(); - - private static AsyncLocal> Value - { - [SuppressMessage("Microsoft.Performance", - "CA1811:AvoidUncalledPrivateCode", - Justification = "Template code only")] - get { return __value; } - } - - // no race conditions here - [SuppressMessage("Gendarme.Rules.Performance", - "AvoidUncalledPrivateCodeRule", - Justification = "Template code only")] - [SuppressMessage("Microsoft.Performance", - "CA1811:AvoidUncalledPrivateCode", - Justification = "Template code only")] - [SuppressMessage("Gendarme.Rules.Performance", - "AvoidRepetitiveCallsToPropertiesRule", - Justification = "Initialization")] - private static Stack Instance() - { - if (Value.Value == null) - Value.Value = new Stack(); - - return Value.Value; - } - } - } -} \ No newline at end of file diff --git a/AltCover.Base/AltCover.Base.csproj b/AltCover.Base/AltCover.Base.csproj deleted file mode 100644 index 273f0def2..000000000 --- a/AltCover.Base/AltCover.Base.csproj +++ /dev/null @@ -1,55 +0,0 @@ - - - - netstandard2.0 - AltCover - AltCover.Base - RUNNER;LITEVERSION - - - - TRACE;DEBUG;CODE_ANALYSIS;$(GlobalDefineConstants) - - - TRACE;$(GlobalDefineConstants) - - - - - - - - - - - - all - runtime; build; native; contentfiles; analyzers - - - - ..\ThirdParty\cecil\Mono.Cecil.dll - - - ..\ThirdParty\cecil\Mono.Cecil.Rocks.dll - - - ..\ThirdParty\cecil\Mono.Cecil.Mdb.dll - - - ..\ThirdParty\cecil\Mono.Cecil.Pdb.dll - - - - - - - ..\ThirdParty\Manatee.Json.dll - - - - - - - - \ No newline at end of file diff --git a/AltCover.Base/AssemblyInfo.cs b/AltCover.Base/AssemblyInfo.cs deleted file mode 100644 index e2e03c6fd..000000000 --- a/AltCover.Base/AssemblyInfo.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -[assembly: InternalsVisibleTo("AltCover.Engine, PublicKey=0024000004800000940000000602000000240000525341310004000001000100916443A2EE1D294E8CFA7666FB3F512D998D7CEAC4909E35EDB2AC1E104DE68890A93716D1D1931F7228AAC0523CACF50FD82CDB4CCF4FF4BF0DED95E3A383F4F371E3B82C45502CE74D7D572583495208C1905E0F1E8A3CCE66C4C75E4CA32E9A8F8DEE64E059C0DC0266E8D2CB6D7EBD464B47E062F80B63D390E389217FB7")] -[assembly: InternalsVisibleTo("AltCover.PowerShell, PublicKey=0024000004800000940000000602000000240000525341310004000001000100916443A2EE1D294E8CFA7666FB3F512D998D7CEAC4909E35EDB2AC1E104DE68890A93716D1D1931F7228AAC0523CACF50FD82CDB4CCF4FF4BF0DED95E3A383F4F371E3B82C45502CE74D7D572583495208C1905E0F1E8A3CCE66C4C75E4CA32E9A8F8DEE64E059C0DC0266E8D2CB6D7EBD464B47E062F80B63D390E389217FB7")] -[assembly: InternalsVisibleTo("AltCover.Toolkit, PublicKey=0024000004800000940000000602000000240000525341310004000001000100916443A2EE1D294E8CFA7666FB3F512D998D7CEAC4909E35EDB2AC1E104DE68890A93716D1D1931F7228AAC0523CACF50FD82CDB4CCF4FF4BF0DED95E3A383F4F371E3B82C45502CE74D7D572583495208C1905E0F1E8A3CCE66C4C75E4CA32E9A8F8DEE64E059C0DC0266E8D2CB6D7EBD464B47E062F80B63D390E389217FB7")] -[assembly: InternalsVisibleTo("AltCover, PublicKey=0024000004800000940000000602000000240000525341310004000001000100916443A2EE1D294E8CFA7666FB3F512D998D7CEAC4909E35EDB2AC1E104DE68890A93716D1D1931F7228AAC0523CACF50FD82CDB4CCF4FF4BF0DED95E3A383F4F371E3B82C45502CE74D7D572583495208C1905E0F1E8A3CCE66C4C75E4CA32E9A8F8DEE64E059C0DC0266E8D2CB6D7EBD464B47E062F80B63D390E389217FB7")] -#if DEBUG -// Self-test signing key -[assembly: InternalsVisibleTo("AltCover.Engine, PublicKey=002400000480000094000000060200000024000052534131000400000100010041C08339BC8FE3A8B847E3EC38CB1BB31A9B39855347761BAB7AC04E726FFB227B147DF92DE5C3D8BCE3B7CFC7C9AC8110AF2E22F5E35D9CB0EBF47C36890DF617BD83E211002A1979DAB26CC18743DE674CE6F34ABAC834F597364BC5598C133F192596FC2161A832A9BBD33835DBB44F3B924A6F736BE6217ECE42889ABBCF")] -[assembly: InternalsVisibleTo("AltCover.PowerShell, PublicKey=002400000480000094000000060200000024000052534131000400000100010041C08339BC8FE3A8B847E3EC38CB1BB31A9B39855347761BAB7AC04E726FFB227B147DF92DE5C3D8BCE3B7CFC7C9AC8110AF2E22F5E35D9CB0EBF47C36890DF617BD83E211002A1979DAB26CC18743DE674CE6F34ABAC834F597364BC5598C133F192596FC2161A832A9BBD33835DBB44F3B924A6F736BE6217ECE42889ABBCF")] -[assembly: InternalsVisibleTo("AltCover.Toolkit, PublicKey=002400000480000094000000060200000024000052534131000400000100010041C08339BC8FE3A8B847E3EC38CB1BB31A9B39855347761BAB7AC04E726FFB227B147DF92DE5C3D8BCE3B7CFC7C9AC8110AF2E22F5E35D9CB0EBF47C36890DF617BD83E211002A1979DAB26CC18743DE674CE6F34ABAC834F597364BC5598C133F192596FC2161A832A9BBD33835DBB44F3B924A6F736BE6217ECE42889ABBCF")] -[assembly: InternalsVisibleTo("AltCover, PublicKey=002400000480000094000000060200000024000052534131000400000100010041C08339BC8FE3A8B847E3EC38CB1BB31A9B39855347761BAB7AC04E726FFB227B147DF92DE5C3D8BCE3B7CFC7C9AC8110AF2E22F5E35D9CB0EBF47C36890DF617BD83E211002A1979DAB26CC18743DE674CE6F34ABAC834F597364BC5598C133F192596FC2161A832A9BBD33835DBB44F3B924A6F736BE6217ECE42889ABBCF")] -#endif -[assembly: CLSCompliant(true)] -[assembly: ComVisible(false)] -[assembly: System.Resources.NeutralResourcesLanguage("en-GB")] \ No newline at end of file diff --git a/AltCover.DataCollector/DataCollector.cs b/AltCover.DataCollector/DataCollector.cs index 09bfa0e6e..3e38efd5c 100644 --- a/AltCover.DataCollector/DataCollector.cs +++ b/AltCover.DataCollector/DataCollector.cs @@ -67,7 +67,7 @@ private void Supervise() RecorderInstance.ToList().ForEach( i => { - var supervision = i.GetField("supervision", + var supervision = i.GetProperty("supervision", BindingFlags.Static | BindingFlags.NonPublic); if (supervision == null) { diff --git a/AltCover.Engine/AltCover.Engine.fsproj b/AltCover.Engine/AltCover.Engine.fsproj index 978b48a99..cd9da9389 100644 --- a/AltCover.Engine/AltCover.Engine.fsproj +++ b/AltCover.Engine/AltCover.Engine.fsproj @@ -12,6 +12,7 @@ TRACE;$(GlobalDefineConstants) + @@ -25,7 +26,7 @@ - + @@ -66,10 +67,10 @@ Recorder.snk - + AltCover.Recorder.net20.dll - + AltCover.Async.net46.dll @@ -120,10 +121,6 @@ - - - - diff --git a/AltCover.Engine/Instrument.fs b/AltCover.Engine/Instrument.fs index c21713196..17685ed7b 100644 --- a/AltCover.Engine/Instrument.fs +++ b/AltCover.Engine/Instrument.fs @@ -1209,7 +1209,7 @@ module internal Instrument = let value = calltrack.Properties - |> Seq.find (fun m -> m.Name == "Value") + |> Seq.find (fun m -> m.Name == "value") let getValue = value.GetMethod @@ -1222,7 +1222,7 @@ module internal Instrument = GetValue = getValue Instance = calltrack.Methods - |> Seq.find (fun m -> m.Name == "Instance") + |> Seq.find (fun m -> m.Name == "instance") Field = field FieldType = field.FieldType :?> GenericInstanceType Maker = @@ -1336,7 +1336,7 @@ module internal Instrument = let getterDef = recorder.MainModule.GetTypes() |> Seq.collect _.Methods - |> Seq.filter (fun m -> m.Name == "get_Modules") + |> Seq.filter (fun m -> m.Name == "get_modules") |> Seq.head let body = getterDef.Body @@ -1363,13 +1363,15 @@ module internal Instrument = [ worker.Create(OpCodes.Dup) worker.Create(OpCodes.Ldc_I4, i) worker.Create(OpCodes.Ldstr, k) - worker.Create(OpCodes.Stelem_Ref) ] + worker.Create(OpCodes.Stelem_Any, stringtype) ] bulkInsertBefore worker head addElement true |> ignore) - let ret = [ worker.Create OpCodes.Ret ] - bulkInsertBefore worker head ret true |> ignore + let store = + [ worker.Create(OpCodes.Stsfld, head.Operand :?> FieldReference) ] + + bulkInsertBefore worker head store true |> ignore let recorderFileName = (extractName state.RecordingAssembly) + ".dll" diff --git a/AltCover.Engine/PostProcess.fs b/AltCover.Engine/PostProcess.fs index f6d02eeca..3d9d4c6a5 100644 --- a/AltCover.Engine/PostProcess.fs +++ b/AltCover.Engine/PostProcess.fs @@ -181,7 +181,7 @@ module internal PostProcess = |> Seq.head let vc = - (lookUpVisitsByToken token dict).Total + (lookUpVisitsByToken token dict).Total() mp |> Seq.iter (fun m -> @@ -226,7 +226,7 @@ module internal PostProcess = tracks.[index].Tracks |> Seq.map (fun t -> match t with - | :? Time as tx -> sprintf "%d" tx.Value + | Time tx -> sprintf "%d" tx | _ -> String.Empty) // never happens |> Seq.filter (fun s -> s.Length > 0) diff --git a/AltCover.Engine/Runner.fs b/AltCover.Engine/Runner.fs index 1d5dc1ce4..4632c595f 100644 --- a/AltCover.Engine/Runner.fs +++ b/AltCover.Engine/Runner.fs @@ -1026,12 +1026,12 @@ module internal Runner = id, strike, match enum tag with - | Tag.Time -> (Time <| formatter.ReadInt64()) :> Track - | Tag.Call -> (Call <| formatter.ReadInt32()) :> Track + | Tag.Time -> Time <| formatter.ReadInt64() + | Tag.Call -> Call <| formatter.ReadInt32() | Tag.Both -> let time = formatter.ReadInt64() let call = formatter.ReadInt32() - Both(Pair.Create(time, call)) + Both { Time = time; Call = call } | Tag.Table -> let t = Dictionary>() @@ -1057,7 +1057,7 @@ module internal Runner = if p |> t.[m].ContainsKey |> not then t.[m].Add(p, PointVisit.Create()) - let mutable pv = t.[m].[p] + let pv = t.[m].[p] pv.Count <- pv.Count + n // [] @@ -1075,7 +1075,7 @@ module internal Runner = pv.Tracks.Add( let time = formatter.ReadInt64() let call = formatter.ReadInt32() - Both(Pair.Create(time, call)) + Both { Time = time; Call = call } ) tracking () @@ -1090,7 +1090,7 @@ module internal Runner = ``module`` () Table t - | _ -> Null() + | _ -> Null ) with :? EndOfStreamException -> None @@ -1104,7 +1104,8 @@ module internal Runner = key |> String.IsNullOrWhiteSpace |> not || ((String.IsNullOrEmpty key) && hitPointId = 0 - && visit.GetType() = typeof) + && visit.GetType().ToString() + == "AltCover.Track+Table") then if hits.ContainsKey key |> not @@ -1112,7 +1113,7 @@ module internal Runner = then hits.Add(key, Dictionary()) - Counter.AddVisit(hits, key, hitPointId, visit) + Counter.addVisit hits key hitPointId visit else 0L @@ -1189,11 +1190,11 @@ module internal Runner = let internal extractTracks tracks = tracks - |> Seq.map (fun (t: Track) -> + |> Seq.map (fun t -> match t with - | :? Time as x -> (Some x.Value, None) - | :? Both as b -> (Some b.Value.Time, Some b.Value.Call) - | :? Call as y -> (None, Some y.Value) + | Time x -> (Some x, None) + | Both b -> (Some b.Time, Some b.Call) + | Call y -> (None, Some y) | _ -> (None, None)) |> Seq.toList |> List.unzip @@ -1225,7 +1226,7 @@ module internal Runner = entrypoint.Tracks |> Seq.iter (fun t -> match t with - | :? Time as tx -> tx.Value |> NativeJson.fromTracking |> m.Entry.Add + | Time tx -> tx |> NativeJson.fromTracking |> m.Entry.Add | _ -> ()) let e3, exits = hits.TryGetValue Track.Exit @@ -1238,7 +1239,7 @@ module internal Runner = exitpoint.Tracks |> Seq.iter (fun t -> match t with - | :? Time as tx -> tx.Value |> NativeJson.fromTracking |> m.Exit.Add + | Time tx -> tx |> NativeJson.fromTracking |> m.Exit.Add | _ -> ()) let fillTracks tracks calls = @@ -1278,7 +1279,7 @@ module internal Runner = let calls = calls' |> Seq.choose id { sp with - VC = (int <| count.Total) + Math.Max(0, sp.VC) + VC = (int <| count.Total()) + Math.Max(0, sp.VC) Tracks = fillTracks sp.Tracks calls Times = fillTimes sp.Times times } else @@ -1302,7 +1303,7 @@ module internal Runner = let calls = calls' |> Seq.choose id { bp with - Hits = (int <| count.Total) + Math.Max(0, bp.Hits) + Hits = (int <| count.Total()) + Math.Max(0, bp.Hits) Tracks = fillTracks bp.Tracks calls Times = fillTimes bp.Times times } else @@ -1391,15 +1392,14 @@ module internal Runner = | _ -> new MemoryStream() :> Stream let result = - AltCover.Counter.DoFlushStream( - (postProcess hits format), - pointProcess, - true, - hits, - format, - file, + AltCover.Counter.doFlushStream + (postProcess hits format) + pointProcess + true + hits + format + file outputFile - ) match arg with | None -> () diff --git a/AltCover.Monitor/Monitor.cs b/AltCover.Monitor/Monitor.cs index bbf4bc0e9..47a815638 100644 --- a/AltCover.Monitor/Monitor.cs +++ b/AltCover.Monitor/Monitor.cs @@ -222,16 +222,16 @@ public static bool TryGetVisitTotals(out PointCount totals) var found = false; foreach (var t in counter) { - var temp = (Int64)t.GetField("branchVisits", + var temp = (Int64)t.GetProperty("branchVisits", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public | - System.Reflection.BindingFlags.Static).GetValue(null); + System.Reflection.BindingFlags.Static).GetValue(null, Type.EmptyTypes); totals.Branch = (int)temp; - temp = (Int64)t.GetField("totalVisits", + temp = (Int64)t.GetProperty("totalVisits", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public | - System.Reflection.BindingFlags.Static).GetValue(null); + System.Reflection.BindingFlags.Static).GetValue(null, Type.EmptyTypes); totals.Code = (int)temp - totals.Branch; found = true; diff --git a/AltCover.Recorder.Tests/Adapter.fs b/AltCover.Recorder.Tests/Adapter.fs new file mode 100644 index 000000000..eb3e7a9c1 --- /dev/null +++ b/AltCover.Recorder.Tests/Adapter.fs @@ -0,0 +1,197 @@ +namespace AltCover.Recorder + +open System.Collections.Generic + +#if DEBUG +[] +module Adapter = + let DoPause () = Instance.I.doPause + let DoResume () = Instance.I.doResume + let DoUnload () = Instance.I.doUnload + let DoExit () = Instance.I.doExit + + let VisitsClear () = + Instance.I.clear () + Counter.branchVisits <- 0L + Counter.totalVisits <- 0L + + let SamplesClear () = + Instance.I.samples <- Instance.I.makeSamples () + + let private reset () = + Instance.I.isRunner <- false + VisitsClear() + SamplesClear() + + let ModuleReset (m: string array) = + Instance.modules <- m + reset () + + let HardReset () = + Instance.modules <- [| System.String.Empty |] + reset () + + let internal prepareName name = + if name |> Instance.I.visits.ContainsKey |> not then + let entry = Dictionary() + Instance.I.visits.Add(name, entry) + + let internal init (n, l) = + let tmp = + { PointVisit.Create() with Count = n } + + tmp.Tracks.AddRange l + tmp + + let VisitsAdd (name, line, number) = + prepareName name + let v = init (number, []) + Instance.I.visits.[name].Add(line, v) + + let VisitsAddTrack (name, line, number) = + prepareName name + let v1 = init (number, [ Call 17; Call 42 ]) + Instance.I.visits.[name].Add(line, v1) + + let v2 = + init ( + (number + 1L), + [ Time 17L + Both { Time = 42L; Call = 23 } ] + ) + + Instance.I.visits.[name].Add(line + 1, v2) + + let VisitsSeq () = Instance.I.visits |> Seq.cast + + let VisitsEntrySeq key = + Instance.I.visits.[key] |> Seq.cast + + let VisitCount (key, key2) = (Instance.I.visits.[key].[key2]).Count + let Lock = Instance.I.visits :> obj + + let VisitImplNone (moduleId, hitPointId) = + Instance.I.visitImpl moduleId hitPointId Track.Null + + let VisitImplMethod (moduleId, hitPointId, mId) = + Instance.I.visitImpl moduleId hitPointId (Call mId) + //let internal VisitImpl (a, b, c) = + // Instance.I.visitImpl a b c + + let internal addSample (moduleId, hitPointId, context) = + Instance.I.takeSample Sampling.Single moduleId hitPointId context + + let internal addSampleUnconditional (moduleId, hitPointId, context) = + Instance.I.takeSample Sampling.All moduleId hitPointId context + + let internal newBoth (time, call) = Both { Time = time; Call = call } + + let internal asCall track = Call track + let internal time at = Time at + + let internal untime at = + let r = List() + + match at with + | Time t -> r.Add(t) + | _ -> () + + r + + let internal asNull () = Null + let internal table t = Table t + + let internal untable t = + let r = List() + + match t with + | (n, p, Table d) -> + r.Add(n) + r.Add(p) + r.Add(d) + | _ -> () + + r + + let internal doFlush (visits, format, report, output) = + let output' = + if System.String.IsNullOrEmpty output then + None + else + Some output + + Counter.doFlushFile ignore (fun _ _ -> ()) true visits format report output' + + let internal updateReport (counts, format, coverageFile, outputFile) = + Counter.I.updateReport + ignore + (fun _ _ -> ()) + true + counts + format + coverageFile + outputFile + + let internal payloadSelector x = Instance.I.payloadSelector (fun _ -> x) + + let internal payloadControl (x, y) = + Instance.I.payloadControl (fun _ -> x) (fun _ -> y) + + let internal payloadSelection (x, y, z) = + Instance.I.payloadSelection (fun _ -> x) (fun _ -> y) (fun _ -> z) + + let internal makeNullTrace name = + { Tracer = name + Stream = null + Formatter = null + Runner = false + Definitive = false } + + let internal makeStreamTrace s1 = + { Tracer = null + Stream = new System.IO.MemoryStream() + Formatter = new System.IO.BinaryWriter(s1) + Runner = true + Definitive = false } + + let internal invokeIssue71Wrapper<'T when 'T :> System.Exception> + ((unique: string), (called: bool array)) + = + let constructor = + typeof<'T> + .GetConstructor([| typeof |]) + + let pitcher = + fun _ _ _ _ -> + constructor.Invoke([| unique |]) :?> System.Exception + |> raise + + let catcher = + fun _ _ _ (x: System.Exception) -> + called.[0] <- true + + called.[1] <- + match x with + | :? System.ArgumentNullException as ane -> ane.ParamName = unique + | _ -> x.Message = unique + + Instance.I.issue71Wrapper () () () () catcher pitcher + + let internal invokeCurriedIssue71Wrapper<'T when 'T :> System.Exception> + (unique: string) + = + let constructor = + typeof<'T> + .GetConstructor([| typeof |]) + + let pitcher = + fun _ _ _ _ -> + constructor.Invoke([| unique |]) :?> System.Exception + |> raise + + Instance.I.curriedIssue71Wrapper "a" "b" "c" "d" pitcher + + let internal tracePush (a, b, c) = Instance.I.trace.Push a b c +//let LogException (a, b, c, d) = Instance.I.logException a b c d +//let FindIndexFromUspid (a,b) = Counter.I.findIndexFromUspid a b +#endif \ No newline at end of file diff --git a/AltCover.Recorder.Tests/AltCover.Recorder.Tests.fsproj b/AltCover.Recorder.Tests/AltCover.Recorder.Tests.fsproj index 3a8a34a7d..fa936df94 100644 --- a/AltCover.Recorder.Tests/AltCover.Recorder.Tests.fsproj +++ b/AltCover.Recorder.Tests/AltCover.Recorder.Tests.fsproj @@ -1,7 +1,7 @@  - net8.0;net472 + net8.0;net472;net20 false AltCover.Recorder.Tests false @@ -23,11 +23,10 @@ AssemblyVersion.fs - + - @@ -58,13 +57,19 @@ - + - + + contentfiles - + + + + + + \ No newline at end of file diff --git a/AltCover.Recorder.Tests/Base.Tests.fs b/AltCover.Recorder.Tests/Base.Tests.fs deleted file mode 100644 index f33032591..000000000 --- a/AltCover.Recorder.Tests/Base.Tests.fs +++ /dev/null @@ -1,102 +0,0 @@ -#if RUNNER_TESTS -namespace Tests -#else -#if !NET472 -#if NET20 -namespace Tests.Recorder.Clr2 -#else -namespace Tests.Recorder.Core -#endif -#else -namespace Tests.Recorder.Clr4 -#endif -#endif - -open System - -#if RUNNER_TESTS -open AltCover -#else -open AltCover.Recorder -open NUnit.Framework -#endif - -module BaseTests = - [] - let ExerciseBoth () = - let b = Both(Pair.Create(0L, 0)) - let b1 = Both(Pair.Create(0L, 0)) - let b2 = Both(Pair.Create(1L, 2)) - Assert.That(b1.Equals(b)) - Assert.That(not <| b2.Equals(b)) - Assert.That(not <| b2.Equals(String.Empty)) - Assert.That(not <| b2.Value.Equals(String.Empty)) - Assert.That(b.GetHashCode(), Is.EqualTo <| b1.GetHashCode()) - Assert.That(b.ToString(), Is.EqualTo("AltCover.Both : AltCover.Pair(Time=0, Call=0)")) - - [] - let ExerciseCall () = - let b = Call(0) - let b1 = Call(0) - let b2 = Call(2) - Assert.That(b1.Equals(b)) - Assert.That(not <| b2.Equals(b)) - Assert.That(not <| b2.Equals(String.Empty)) - Assert.That(b.GetHashCode(), Is.EqualTo <| b1.GetHashCode()) - Assert.That(b.ToString(), Is.EqualTo("AltCover.Call : 0")) - - [] - let ExerciseTime () = - let b = Time(0l) - let b1 = Time(0l) - let b2 = Time(2l) - Assert.That(b1.Equals(b)) - Assert.That(not <| b2.Equals(b)) - Assert.That(not <| b2.Equals(String.Empty)) - Assert.That(b.GetHashCode(), Is.EqualTo <| b1.GetHashCode()) - Assert.That(b.ToString(), Is.EqualTo("AltCover.Time : 0")) - - [] - let ExerciseNull () = - let b = Null() - let b1 = Null() - Assert.That(b1.Equals(b)) - Assert.That(not <| b.Equals(String.Empty)) - Assert.That(b.GetHashCode(), Is.EqualTo <| b1.GetHashCode()) - Assert.That(b.ToString(), Is.EqualTo("AltCover.Null")) - - [] - let ExercisePointVisit () = - let p = PointVisit.Create() - let p1 = PointVisit.Create() - Assert.That(p1.Equals(p)) - Assert.That(not <| p.Equals(String.Empty)) - Assert.That(p.GetHashCode(), Is.EqualTo <| p1.GetHashCode()) - Assert.That(p.ToString(), Is.EqualTo("AltCover.PointVisit : Count = 0 Tracks = ''")) - p.Track(Null()) - p1.Track(Null()) - Assert.That(p1.Equals(p)) - Assert.That(p.GetHashCode(), Is.EqualTo <| p1.GetHashCode()) - - Assert.That( - p.ToString(), - Is.EqualTo("AltCover.PointVisit : Count = 0 Tracks = 'AltCover.Null'") - ) - - p.Step() - Assert.That(p1.Equals(p) |> not) - p1.Step() - Assert.That(p1.Equals(p)) - Assert.That(p.GetHashCode(), Is.EqualTo <| p1.GetHashCode()) - p.Track(Both(Pair.Create(1L, 2))) - Assert.That(p1.Equals(p) |> not) - - Assert.That( - p.ToString(), - Is.EqualTo( - "AltCover.PointVisit : Count = 1 Tracks = 'AltCover.Null; AltCover.Both : AltCover.Pair(Time=1, Call=2)'" - ) - ) - - p1.Track(Time(2l)) - Assert.That(p1.Equals(p) |> not) \ No newline at end of file diff --git a/AltCover.Recorder.Tests/Recorder.Tests.fs b/AltCover.Recorder.Tests/Recorder.Tests.fs index 78d49a1e9..9bfeb4657 100644 --- a/AltCover.Recorder.Tests/Recorder.Tests.fs +++ b/AltCover.Recorder.Tests/Recorder.Tests.fs @@ -16,6 +16,7 @@ open System.IO open System.IO.Compression open System.Reflection open System.Runtime.CompilerServices +open System.Threading open System.Xml open AltCover.Recorder @@ -35,42 +36,31 @@ module AltCoverTests = // printfn "%s %s" tag //#endif -#if RECORDER2 let resource = - "AltCover.Recorder2.Tests.SimpleCoverage.xml" + Assembly + .GetExecutingAssembly() + .GetManifestResourceNames() + |> Seq.find (fun n -> n.EndsWith("SimpleCoverage.xml", StringComparison.Ordinal)) - let resource2 = - "AltCover.Recorder2.Tests.Sample1WithModifiedOpenCover.xml" + let private updateReport a b = + Adapter.updateReport (a, ReportFormat.NCover, b, b) + |> ignore - let resource3 = - "AltCover.Recorder2.Tests.Sample2NCoverage.xml" -#else - let resource = - "AltCover.Recorder.Tests.SimpleCoverage.xml" + let private pointVisitInit a b = Adapter.init (a, b) let resource2 = - "AltCover.Recorder.Tests.Sample1WithModifiedOpenCover.xml" + Assembly + .GetExecutingAssembly() + .GetManifestResourceNames() + |> Seq.find (fun n -> + n.EndsWith("Sample1WithModifiedOpenCover.xml", StringComparison.Ordinal)) let resource3 = - "AltCover.Recorder.Tests.Sample2NCoverage.xml" -#endif - - let internal updateReport0 (counts, format, coverageFile, outputFile) = - Counter.I.UpdateReport( - ignore, - (fun _ _ -> ()), - true, - counts, - format, - coverageFile, - outputFile - ) - - let private updateReport a b = - updateReport0 (a, ReportFormat.NCover, b, b) - |> ignore - - let private pointVisitInit a b = AltCoverCoreTests.init (a, b) + Assembly + .GetExecutingAssembly() + .GetManifestResourceNames() + |> Seq.find (fun n -> + n.EndsWith("Sample2NCoverage.xml", StringComparison.Ordinal)) [] let ShouldCoverTrivalClass () = @@ -86,7 +76,7 @@ module AltCoverTests = let ShouldFailXmlDataForNativeJson () = Assert.Throws(fun () -> ReportFormat.NativeJson - |> Counter.I.XmlByFormat + |> Counter.I.xmlByFormat |> ignore) |> ignore @@ -97,9 +87,9 @@ module AltCoverTests = [] let DefaultAccessorsBehaveAsExpected () = let v1 = DateTime.UtcNow.Ticks - let probe = Instance.I.Clock() + let probe = Instance.I.clock () let v2 = DateTime.UtcNow.Ticks - Assert.True(Instance.I.Granularity() = 0L) + Assert.True(Instance.I.granularity () = 0L) Assert.True(probe >= v1) Assert.True(probe <= v2) @@ -107,132 +97,113 @@ module AltCoverTests = let ShouldBeLinkingTheCorrectCopyOfThisCode () = getMyMethodName "=>" - let tracer = Tracer.Create String.Empty + let tracer = + Adapter.makeNullTrace String.Empty // whitelist test not recorder.g let n = tracer.GetType().Assembly.GetName().Name - +#if RECORDERMODERN + Assert.That(n, Is.EqualTo "AltCover.RecorderModern") +#else Assert.That(n, Is.EqualTo "AltCover.Recorder") - +#endif getMyMethodName "<=" - let internal addSample (moduleId, hitPointId, context) = - Instance.I.TakeSample(Sampling.Single, moduleId, hitPointId, context) - - let internal addSampleUnconditional (moduleId, hitPointId, context) = - Instance.I.TakeSample(Sampling.All, moduleId, hitPointId, context) - [] let OnlyNewIdPairShouldBeSampled () = getMyMethodName "=>" - lock Instance.I.visits (fun () -> + lock Adapter.Lock (fun () -> try - AltCoverCoreTests.ModuleReset [| "module"; "newmodule" |] - let n = Null() :> Track + Adapter.ModuleReset [| "module"; "newmodule" |] - Assert.True(addSample ("module", 23, n), "Test 1") - Assert.True(addSample ("module", 24, n), "Test 2") - Assert.True(addSample ("newmodule", 23, n), "Test 3") - Assert.True(addSample ("module", 23, n) |> not, "Test 4") - Assert.True(addSampleUnconditional ("module", 23, n), "Test 5") - Assert.True(addSample ("module", 23, Call 1), "Test 6") - Assert.True(addSample ("module", 23, Time 0L), "Test 7") - Assert.True(addSample ("module", 23, Time 1L), "Test 7a") - Assert.True(addSample ("module", 23, Time 0L) |> not, "Test 7b") + Assert.True(Adapter.addSample ("module", 23, Null), "Test 1") + Assert.True(Adapter.addSample ("module", 24, Null), "Test 2") + Assert.True(Adapter.addSample ("newmodule", 23, Null), "Test 3") + Assert.True(Adapter.addSample ("module", 23, Null) |> not, "Test 4") + Assert.True(Adapter.addSampleUnconditional ("module", 23, Null), "Test 5") + Assert.True(Adapter.addSample ("module", 23, Call 1), "Test 6") + Assert.True(Adapter.addSample ("module", 23, Time 0L), "Test 7") - Assert.True(addSample ("module", 24, new Both(Pair.Create(0, 1))), "Test 8") + Assert.True( + Adapter.addSample ("module", 24, Both { Call = 1; Time = 0L }), + "Test 8" + ) - Assert.True(addSample ("module", 25, new Both(Pair.Create(0, 1))), "Test 9") + Assert.True( + Adapter.addSample ("module", 25, Both { Call = 1; Time = 0L }), + "Test 9" + ) - Assert.True(addSample ("module", 25, Call 1) |> not, "Test 10") - Assert.True(addSample ("module", 25, Call 1) |> not, "Test 11") - Assert.True(addSample ("module", 25, n) |> not, "Test 12") + Assert.True(Adapter.addSample ("module", 25, Call 1) |> not, "Test 10") + Assert.True(Adapter.addSample ("module", 25, Call 1) |> not, "Test 11") + Assert.True(Adapter.addSample ("module", 25, Null) |> not, "Test 12") // out of band example - Assert.True(addSample ("nonesuch", 25, n) |> not, "Test 12a") + Assert.True(Adapter.addSample ("nonesuch", 25, Null) |> not, "Test 12a") Assert.Throws(fun () -> - addSample ("module", 23, Table null) |> ignore) + Adapter.addSample ("module", 23, Table null) + |> ignore) |> ignore finally - AltCoverCoreTests.HardReset()) + Adapter.HardReset()) getMyMethodName "<=" - let VisitsEntrySeq key = - Instance.I.visits.[key] - |> Seq.cast> - - let VisitCount (key, key2) = (Instance.I.visits.[key].[key2]).Count - [] let RealIdShouldIncrementCount () = getMyMethodName "=>" - lock Instance.I.visits (fun () -> - let save = Instance.I.Trace + lock Adapter.Lock (fun () -> + let save = Instance.I.trace try let key = " " - AltCoverCoreTests.ModuleReset [| key |] - Instance.I.Trace <- Tracer.Create null + Adapter.ModuleReset [| key |] + Instance.I.trace <- Adapter.makeNullTrace null - Instance.I.Recording <- false - Instance.Visit("key", 17) - Instance.I.Recording <- true + Instance.I.recording <- false + Instance.Visit "key" 17 + Instance.I.recording <- true Instance.CoverageFormat <- ReportFormat.NCover - Instance.Visit(key, -23) + Instance.Visit key -23 Instance.CoverageFormat <- ReportFormat.OpenCover ||| ReportFormat.WithTracking - Instance.Visit(key, -23) + Instance.Visit key -23 + + let vs = Adapter.VisitsSeq() + Assert.True(vs |> Seq.length = 3, sprintf "Adapter.VisitsSeq() = %A" vs) - let vs = AltCoverCoreTests.VisitsSeq() + let vesk = Adapter.VisitsEntrySeq key Assert.True( - vs |> Seq.length = 3, - sprintf "AltCoverCoreTests.VisitsSeq() = %A" vs + vesk |> Seq.length = 1, + sprintf "Adapter.VisitsEntrySeq %A = %A" key vesk ) - let vesk = VisitsEntrySeq key - - Assert.True(vesk |> Seq.length = 1, sprintf "VisitsEntrySeq %A = %A" key vesk) - - Assert.That(VisitCount(key, -23), Is.EqualTo 2L) + Assert.True(Adapter.VisitCount(key, -23) = 2L) Assert.That(Counter.totalVisits, Is.EqualTo 1L) Assert.That(Counter.branchVisits, Is.EqualTo 1L) finally Instance.CoverageFormat <- ReportFormat.NCover - Instance.I.Recording <- true - AltCoverCoreTests.HardReset() - Instance.I.Trace <- save) + Instance.I.recording <- true + Adapter.HardReset() + Instance.I.trace <- save) getMyMethodName "<=" - let internal payloadSelector x = Instance.I.PayloadSelector(fun _ -> x) - - let internal payloadControl (x, y) = - Instance.I.PayloadControl((fun _ -> x), (fun _ -> y)) - - let internal payloadSelection (x, y, z) = - Instance.I.PayloadSelection((fun _ -> x), (fun _ -> y), (fun _ -> z)) - - let internal untime (at: Track) = - match at with - | :? Time as t -> Some t.Value - | _ -> None - [] let JunkUspidGivesNegativeIndex () = let key = " " let index = - Counter.I.FindIndexFromUspid(0, key) + Counter.I.findIndexFromUspid 0 key Assert.True(index < 0) @@ -245,56 +216,59 @@ module AltCoverTests = ReportFormat.OpenCover ||| ReportFormat.WithTracking - Assert.False(Instance.I.CallerId.HasValue) - Assert.That(payloadSelector false, Is.EqualTo <| Null()) - Assert.That(payloadSelector true, Is.EqualTo <| Null()) + Assert.True(Instance.I.callerId () |> Option.isNone) + Assert.True(Adapter.payloadSelector false = Adapter.asNull ()) + Assert.True(Adapter.payloadSelector true = Adapter.asNull ()) Instance.Push 4321 - Assert.That(payloadSelector false, Is.EqualTo <| Null()) - Assert.That(payloadSelector true, Is.EqualTo <| (Call 4321)) + Assert.True(Adapter.payloadSelector false = Adapter.asNull ()) + Assert.True(Adapter.payloadSelector true = (Adapter.asCall 4321)) try Instance.Push 6789 // 0x1234123412341234 == 1311693406324658740 let result = - payloadSelection (1311693406324658740L, 1000L, true) + Adapter.payloadSelection (1311693406324658740L, 1000L, true) let expected = - AltCoverCoreTests.newBoth (1311693406324658000L, 6789) + Adapter.newBoth (1311693406324658000L, 6789) Assert.True((result = expected)) finally Instance.Pop() - Assert.That(payloadSelector true, Is.EqualTo(Call 4321)) + Assert.True((Adapter.payloadSelector true = (Adapter.asCall 4321))) finally Instance.Pop() Instance.CoverageFormat <- ReportFormat.NCover let result2 = - payloadSelection (1311693406324658740L, 1000L, true) + Adapter.payloadSelection (1311693406324658740L, 1000L, true) - let expected2 = Time 1311693406324658000L + let expected2 = + Adapter.time 1311693406324658000L Assert.True((result2 = expected2)) let v1 = DateTime.UtcNow.Ticks - let probed = payloadControl (1000L, true) + let probed = + Adapter.payloadControl (1000L, true) let v2 = DateTime.UtcNow.Ticks - Assert.True(Null() |> untime |> Option.isNone) + Assert.True(Adapter.asNull () |> Adapter.untime |> Seq.isEmpty) - let probe = (untime probed).Value + let [ probe ] = + Adapter.untime probed |> Seq.toList Assert.True(probe % 1000L = 0L) Assert.True(probe <= v2) Assert.True(probe >= (1000L * (v1 / 1000L))) - Assert.True(Instance.I.CallerId.HasValue |> not) + Assert.True(Instance.I.callerId () |> Option.isNone) Instance.Pop() - Assert.True(Instance.I.CallerId.HasValue |> not) + Assert.True(Instance.I.callerId () |> Option.isNone) [] let PayloadWithEntryExitGeneratedIsAsExpected () = - AltCoverCoreTests.ModuleReset [||] + Adapter.ModuleReset [||] try Instance.I.isRunner <- true @@ -303,55 +277,58 @@ module AltCoverTests = ReportFormat.OpenCover ||| ReportFormat.WithTracking - AltCoverCoreTests.VisitsClear() + Adapter.VisitsClear() - Assert.True(Instance.I.CallerId.HasValue |> not) - Assert.That(payloadSelector false, Is.EqualTo <| Null()) - Assert.That(payloadSelector true, Is.EqualTo <| Null()) + Assert.True(Instance.I.callerId () |> Option.isNone) + Assert.True(Adapter.payloadSelector false = Adapter.asNull ()) + Assert.True(Adapter.payloadSelector true = Adapter.asNull ()) Instance.Push 4321 - Assert.That(payloadSelector false, Is.EqualTo <| Null()) - Assert.That(payloadSelector true, Is.EqualTo(Call 4321)) + Assert.True(Adapter.payloadSelector false = Adapter.asNull ()) + Assert.True(Adapter.payloadSelector true = (Adapter.asCall 4321)) try Instance.Push 6789 // 0x1234123412341234 == 1311693406324658740 let result = - payloadSelection (1311693406324658740L, 1000L, true) + Adapter.payloadSelection (1311693406324658740L, 1000L, true) let expected = - AltCoverCoreTests.newBoth (1311693406324658000L, 6789) + Adapter.newBoth (1311693406324658000L, 6789) Assert.True((result = expected)) finally Instance.Pop() - Assert.That(payloadSelector true, Is.EqualTo(Call 4321)) + Assert.True((Adapter.payloadSelector true = (Adapter.asCall 4321))) finally Instance.Pop() Instance.I.isRunner <- false Instance.CoverageFormat <- ReportFormat.NCover let result2 = - payloadSelection (1311693406324658740L, 1000L, true) + Adapter.payloadSelection (1311693406324658740L, 1000L, true) - let expected2 = Time 1311693406324658000L + let expected2 = + Adapter.time 1311693406324658000L Assert.True((result2 = expected2)) let v1 = DateTime.UtcNow.Ticks - let probed = payloadControl (1000L, true) + let probed = + Adapter.payloadControl (1000L, true) let v2 = DateTime.UtcNow.Ticks - Assert.True(Null() |> untime |> Option.isNone) + Assert.True(Adapter.asNull () |> Adapter.untime |> Seq.isEmpty) - let probe = (untime probed).Value + let [ probe ] = + Adapter.untime probed |> Seq.toList Assert.True(probe % 1000L = 0L) Assert.True(probe <= v2) Assert.True(probe >= (1000L * (v1 / 1000L))) - Assert.True(Instance.I.CallerId.HasValue |> not) + Assert.True(Instance.I.callerId () |> Option.isNone) Instance.Pop() - Assert.True(Instance.I.CallerId.HasValue |> not) + Assert.True(Instance.I.callerId () |> Option.isNone) Assert.That(Instance.I.visits.Keys, Is.EquivalentTo [ Track.Entry; Track.Exit ]) @@ -383,38 +360,38 @@ module AltCoverTests = Assert.That(d.Tracks |> Seq.length, Is.EqualTo 1) let a2 = - (a.Tracks |> Seq.head |> untime).Value + a.Tracks |> Seq.head |> Adapter.untime |> Seq.head let b2 = - (b.Tracks |> Seq.head |> untime).Value + b.Tracks |> Seq.head |> Adapter.untime |> Seq.head Assert.That(b2 >= a2) let c2 = - (c.Tracks |> Seq.head |> untime).Value + c.Tracks |> Seq.head |> Adapter.untime |> Seq.head Assert.That(c2 >= b2) let d2 = - (d.Tracks |> Seq.head |> untime).Value + d.Tracks |> Seq.head |> Adapter.untime |> Seq.head Assert.That(d2 >= c2, sprintf "%A >= %A" d2 c2) - AltCoverCoreTests.HardReset() + Adapter.HardReset() [] let RealIdShouldIncrementCountSynchronously () = getMyMethodName "=>" lock Instance.I.visits (fun () -> - let save = Instance.I.Trace + let save = Instance.I.trace let key = " " - AltCoverCoreTests.ModuleReset [| key |] + Adapter.ModuleReset [| key |] try - Instance.I.Trace <- Tracer.Create null + Instance.I.trace <- Adapter.makeNullTrace null - Instance.I.VisitSelection(Null(), key, 23) + Instance.I.visitSelection (Adapter.asNull ()) key 23 Assert.That( Instance.I.visits.Keys, @@ -431,8 +408,8 @@ module AltCoverTests = Assert.That(Instance.I.visits.[key].[23].Count, Is.EqualTo 1) Assert.That(Instance.I.visits.[key].[23].Tracks, Is.Empty) finally - AltCoverCoreTests.HardReset() - Instance.I.Trace <- save) + Adapter.HardReset() + Instance.I.trace <- save) getMyMethodName "<=" @@ -442,51 +419,6 @@ module AltCoverTests = Assert.That(all.Contains x) all.Remove x |> ignore) - let internal invokeCurriedIssue71Wrapper<'T when 'T :> System.Exception> - (unique: string) - = - let constructor = - typeof<'T> - .GetConstructor([| typeof |]) - - let pitcher = - fun _ _ _ _ -> - constructor.Invoke([| unique |]) :?> System.Exception - |> raise - - Instance.I.CurriedIssue71Wrapper( - "a", - "b", - "c", - "d", - pitcher - ) - |> ignore - - let internal invokeIssue71Wrapper<'T when 'T :> System.Exception> - ((unique: string), (called: bool array)) - = - let constructor = - typeof<'T> - .GetConstructor([| typeof |]) - - let pitcher = - fun _ _ _ _ -> - constructor.Invoke([| unique |]) :?> System.Exception - |> raise - - let catcher = - fun _ _ _ (x: System.Exception) -> - called.[0] <- true - - called.[1] <- - match x with - | :? System.ArgumentNullException as ane -> ane.ParamName = unique - | _ -> x.Message = unique - - Instance.I.Issue71Wrapper((), (), (), (), catcher, pitcher) - |> ignore - [] let StripWorks () = let b1 = [ "1" ] @@ -509,7 +441,7 @@ module AltCoverTests = let before = Directory.GetFiles(where, "*.exn") - Instance.I.LogException("a", "b", "c", "ex") + Instance.I.logException "a" "b" "c" "ex" let after = Directory.GetFiles(where, "*.exn") @@ -526,9 +458,9 @@ module AltCoverTests = lines |> Seq.take 4 |> Seq.zip - [ "ModuleId = a" - "hitPointId = b" - "context = c" + [ "ModuleId = \"a\"" + "hitPointId = \"b\"" + "context = \"c\"" "exception = ex" ] |> Seq.iter (fun (a, b) -> Assert.That(a, Is.EqualTo b)) @@ -550,7 +482,7 @@ module AltCoverTests = let unique = System.Guid.NewGuid().ToString() - invokeCurriedIssue71Wrapper unique + Adapter.invokeCurriedIssue71Wrapper unique let after = Directory.GetFiles(where, "*.exn") @@ -567,9 +499,9 @@ module AltCoverTests = lines |> Seq.take 4 |> Seq.zip - [ "ModuleId = b" - "hitPointId = c" - "context = d" + [ "ModuleId = \"b\"" + "hitPointId = \"c\"" + "context = \"d\"" "exception = System.NullReferenceException: " + unique ] |> Seq.iter (fun (a, b) -> Assert.That(b, Is.EqualTo a)) @@ -586,7 +518,7 @@ module AltCoverTests = let unique = System.Guid.NewGuid().ToString() - invokeIssue71Wrapper (unique, pair) + Adapter.invokeIssue71Wrapper (unique, pair) Assert.That(pair |> Seq.head, Is.True) Assert.That(pair |> Seq.last, Is.True) @@ -597,7 +529,7 @@ module AltCoverTests = let unique = System.Guid.NewGuid().ToString() - invokeIssue71Wrapper (unique, pair) + Adapter.invokeIssue71Wrapper (unique, pair) Assert.That(pair |> Seq.head, Is.True) Assert.That(pair |> Seq.last, Is.True) @@ -608,7 +540,7 @@ module AltCoverTests = let unique = System.Guid.NewGuid().ToString() - invokeIssue71Wrapper (unique, pair) + Adapter.invokeIssue71Wrapper (unique, pair) Assert.That(pair |> Seq.head, Is.True) Assert.That(pair |> Seq.last, Is.True) @@ -621,7 +553,7 @@ module AltCoverTests = let exn = Assert.Throws(fun () -> - invokeIssue71Wrapper (unique, pair)) + Adapter.invokeIssue71Wrapper (unique, pair)) Assert.That(pair |> Seq.head, Is.False) Assert.That(pair |> Seq.last, Is.False) @@ -646,7 +578,7 @@ module AltCoverTests = let before = Directory.GetFiles(where, "*.exn") - Instance.I.VisitImpl(key, 23, Null()) + Instance.I.visitImpl key 23 (Adapter.asNull ()) let after = Directory.GetFiles(where, "*.exn") @@ -664,11 +596,11 @@ module AltCoverTests = lines |> Seq.take 4 |> Seq.zip - [ "ModuleId = " + [ "ModuleId = \" \"" "hitPointId = 23" - "context = AltCover.Null" + "context = Null" "exception = System.NullReferenceException: Object reference not set to an instance of an object." ] - |> Seq.iter (fun (a, b) -> Assert.That(a, Is.EqualTo(b))) + |> Seq.iter (fun (a, b) -> Assert.True((a = b))) let third = Directory.GetFiles(where, "*.exn") @@ -688,16 +620,16 @@ module AltCoverTests = lock Instance.I.visits (fun () -> try let key = " " - AltCoverCoreTests.ModuleReset [| key; "key" |] - Instance.I.VisitImpl(key, 23, Null()) - Instance.I.VisitImpl("key", 42, Null()) + Adapter.ModuleReset [| key; "key" |] + Instance.I.visitImpl key 23 (Adapter.asNull ()) + Instance.I.visitImpl "key" 42 (Adapter.asNull ()) Assert.That( Instance.I.visits.Keys, Is.EquivalentTo [ key; "key"; Track.Entry; Track.Exit ] ) finally - AltCoverCoreTests.HardReset()) + Adapter.HardReset()) getMyMethodName "<=" @@ -708,9 +640,9 @@ module AltCoverTests = lock Instance.I.visits (fun () -> try let key = " " - AltCoverCoreTests.ModuleReset [| key |] - Instance.I.VisitImpl(key, 23, Null()) - Instance.I.VisitImpl(key, 42, Null()) + Adapter.ModuleReset [| key |] + Instance.I.visitImpl key 23 (Adapter.asNull ()) + Instance.I.visitImpl key 42 (Adapter.asNull ()) Assert.That( Instance.I.visits.Keys, @@ -719,7 +651,7 @@ module AltCoverTests = Assert.That(Instance.I.visits.[key].Count, Is.EqualTo 2) finally - AltCoverCoreTests.HardReset()) + Adapter.HardReset()) getMyMethodName "<=" @@ -729,15 +661,15 @@ module AltCoverTests = lock Instance.I.visits (fun () -> let key = " " - AltCoverCoreTests.ModuleReset [| key |] + Adapter.ModuleReset [| key |] try - Instance.I.VisitImpl(key, 23, Null()) - Instance.I.VisitImpl(key, 23, Null()) + Instance.I.visitImpl key 23 (Adapter.asNull ()) + Instance.I.visitImpl key 23 (Adapter.asNull ()) Assert.That(Instance.I.visits.[key].[23].Count, Is.EqualTo 2) Assert.That(Instance.I.visits.[key].[23].Tracks, Is.Empty) finally - AltCoverCoreTests.HardReset()) + Adapter.HardReset()) getMyMethodName "<=" @@ -747,17 +679,18 @@ module AltCoverTests = lock Instance.I.visits (fun () -> let key = " " - AltCoverCoreTests.ModuleReset [| key |] + Adapter.ModuleReset [| key |] try - let payload = Time DateTime.UtcNow.Ticks + let payload = + Adapter.time DateTime.UtcNow.Ticks - Instance.I.VisitImpl(key, 23, Null()) - Instance.I.VisitImpl(key, 23, payload) + Instance.I.visitImpl key 23 (Adapter.asNull ()) + Instance.I.visitImpl key 23 payload Assert.That(Instance.I.visits.[key].[23].Count, Is.EqualTo 1) Assert.That(Instance.I.visits.[key].[23].Tracks, Is.EquivalentTo [ payload ]) finally - AltCoverCoreTests.HardReset()) + Adapter.HardReset()) getMyMethodName "<=" @@ -1209,12 +1142,13 @@ module AltCoverTests = let after = XmlDocument() after.Load worker - let join (x: string seq) = String.Join(" ", x) + let join (x: string array) = String.Join(" ", x) Assert.That( after.SelectNodes("//seqpnt") |> Seq.cast |> Seq.map (fun x -> x.GetAttribute("visitcount")) + |> Seq.toArray |> join, Is.EqualTo "0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 2 1 1 1" @@ -1255,7 +1189,7 @@ module AltCoverTests = item.Add("7C-CD-66-29-A3-6C-6D-5F-A7-65-71-0E-22-7D-B2-61-B5-1F-65-9A", payload) - updateReport0 (item, ReportFormat.OpenCover, worker, worker) + Adapter.updateReport (item, ReportFormat.OpenCover, worker, worker) |> ignore worker.Position <- 0L @@ -1292,17 +1226,17 @@ module AltCoverTests = let EmptyFlushLeavesNoTrace () = getMyMethodName "=>" - lock Instance.I.visits (fun () -> + lock Adapter.Lock (fun () -> let saved = Console.Out try - AltCoverCoreTests.VisitsClear() + Adapter.VisitsClear() use stdout = new StringWriter() Console.SetOut stdout Instance.FlushFinish() Assert.That(stdout.ToString(), Is.Empty) finally - AltCoverCoreTests.VisitsClear() + Adapter.VisitsClear() Console.SetOut saved) getMyMethodName "<=" @@ -1342,21 +1276,11 @@ module AltCoverTests = trywithrelease (fun () -> InvalidOperationException() |> raise) - let internal makeStreamTrace s1 = - let mutable t = Tracer.Create(null) - // fsharplint:disable-next-line RedundantNewKeyword - t.Stream <- new System.IO.MemoryStream() - // fsharplint:disable-next-line RedundantNewKeyword - t.Formatter <- new System.IO.BinaryWriter(s1) - t.Runner <- true - t.Definitive <- false - t - [] let PauseLeavesExpectedTraces () = getMyMethodName "=>" - lock Instance.I.visits (fun () -> + lock Adapter.Lock (fun () -> trywithrelease (fun () -> let saved = Console.Out let here = Directory.GetCurrentDirectory() @@ -1368,17 +1292,17 @@ module AltCoverTests = let unique = Path.Combine(where, Guid.NewGuid().ToString()) - let save = Instance.I.Trace + let save = Instance.I.trace use s = new MemoryStream() let s1 = new Compression.DeflateStream(s, CompressionMode.Compress) - Instance.I.Trace <- makeStreamTrace s1 + Instance.I.trace <- Adapter.makeStreamTrace s1 try Instance.I.isRunner <- true - AltCoverCoreTests.VisitsClear() + Adapter.VisitsClear() use stdout = new StringWriter() Console.SetOut stdout @@ -1406,16 +1330,16 @@ module AltCoverTests = [ 0..9 ] |> Seq.iter (fun i -> - AltCoverCoreTests.VisitsAdd( + Adapter.VisitsAdd( "f6e3edb3-fb20-44b3-817d-f69d1a22fc2f", i, (int64 (i + 1)) )) - let nullObj: obj = null - Instance.I.doPause.Invoke(nullObj, null) + Adapter.DoPause().Invoke(null, null) - AltCoverCoreTests.VisitsSeq() + Adapter.VisitsSeq() + |> Seq.cast>> |> Seq.iter (fun v -> Assert.That(v.Value, Is.Empty, sprintf "Unexpected write %A" v)) @@ -1445,9 +1369,9 @@ module AltCoverTests = "-1" ] ) finally - Instance.I.Trace <- save + Instance.I.trace <- save AltCoverCoreTests.maybeDeleteFile Instance.ReportFilePath - AltCoverCoreTests.VisitsClear() + Adapter.VisitsClear() Instance.I.isRunner <- false Console.SetOut saved Directory.SetCurrentDirectory(here) @@ -1459,7 +1383,7 @@ module AltCoverTests = let ResumeLeavesExpectedTraces () = getMyMethodName "=>" - lock Instance.I.visits (fun () -> + lock Adapter.Lock (fun () -> trywithrelease (fun () -> let saved = Console.Out let here = Directory.GetCurrentDirectory() @@ -1471,7 +1395,7 @@ module AltCoverTests = let unique = Path.Combine(where, Guid.NewGuid().ToString()) - let save = Instance.I.Trace + let save = Instance.I.trace let tag = unique + ".xml.acv" do @@ -1482,8 +1406,8 @@ module AltCoverTests = let key = "f6e3edb3-fb20-44b3-817d-f69d1a22fc2f" - AltCoverCoreTests.ModuleReset [| key |] - Instance.I.Trace <- Tracer.Create(tag) + Adapter.ModuleReset [| key |] + Instance.I.trace <- Tracer.Create(tag) use stdout = new StringWriter() Console.SetOut stdout @@ -1510,17 +1434,17 @@ module AltCoverTests = () [ 0..9 ] - |> Seq.iter (fun i -> AltCoverCoreTests.VisitsAdd(key, i, (int64 (i + 1)))) + |> Seq.iter (fun i -> Adapter.VisitsAdd(key, i, (int64 (i + 1)))) - let nullObj: obj = null - Instance.I.doResume.Invoke(nullObj, null) + Adapter.DoResume().Invoke(null, null) - AltCoverCoreTests.VisitsSeq() + Adapter.VisitsSeq() + |> Seq.cast>> |> Seq.iter (fun v -> Assert.That(v.Value, Is.Empty, sprintf "Visits should be cleared %A" v)) Assert.That( - Object.ReferenceEquals(Instance.I.Trace, save), + Object.ReferenceEquals(Instance.I.trace, save), Is.False, "trace should be replaced" ) @@ -1551,10 +1475,10 @@ module AltCoverTests = "-1" ] ) finally - AltCoverCoreTests.HardReset() - Instance.I.Trace <- save + Adapter.HardReset() + Instance.I.trace <- save AltCoverCoreTests.maybeDeleteFile Instance.ReportFilePath - AltCoverCoreTests.VisitsClear() + Adapter.VisitsClear() Console.SetOut saved Directory.SetCurrentDirectory(here) File.Delete tag @@ -1566,7 +1490,7 @@ module AltCoverTests = let FlushLeavesExpectedTraces () = getMyMethodName "=>" - lock Instance.I.visits (fun () -> + lock Adapter.Lock (fun () -> Instance.I.isRunner <- false trywithrelease (fun () -> @@ -1580,11 +1504,11 @@ module AltCoverTests = let unique = Path.Combine(where, Guid.NewGuid().ToString()) - let save = Instance.I.Trace - Instance.I.Trace <- Tracer.Create null + let save = Instance.I.trace + Instance.I.trace <- Adapter.makeNullTrace null try - AltCoverCoreTests.VisitsClear() + Adapter.VisitsClear() use stdout = new StringWriter() Console.SetOut stdout Directory.CreateDirectory(unique) |> ignore @@ -1611,14 +1535,13 @@ module AltCoverTests = [ 0..9 ] |> Seq.iter (fun i -> - AltCoverCoreTests.VisitsAdd( + Adapter.VisitsAdd( "f6e3edb3-fb20-44b3-817d-f69d1a22fc2f", i, (int64 (i + 1)) )) - let nullObj: obj = null - Instance.I.doExit.Invoke(nullObj, null) + Adapter.DoExit().Invoke(null, null) let head = "Coverage statistics flushing took " @@ -1660,9 +1583,9 @@ module AltCoverTests = "1" ] ) finally - Instance.I.Trace <- save + Instance.I.trace <- save AltCoverCoreTests.maybeDeleteFile Instance.ReportFilePath - AltCoverCoreTests.VisitsClear() + Adapter.VisitsClear() Console.SetOut saved Directory.SetCurrentDirectory(here) AltCoverCoreTests.maybeIOException (fun () -> Directory.Delete(unique)))) @@ -1673,7 +1596,7 @@ module AltCoverTests = let SupervisedFlushLeavesExpectedTraces () = getMyMethodName "=>" - lock Instance.I.visits (fun () -> + lock Adapter.Lock (fun () -> trywithrelease (fun () -> let saved = Console.Out let here = Directory.GetCurrentDirectory() @@ -1685,13 +1608,13 @@ module AltCoverTests = let unique = Path.Combine(where, Guid.NewGuid().ToString()) - let save = Instance.I.Trace - Instance.I.Trace <- Tracer.Create null + let save = Instance.I.trace + Instance.I.trace <- Adapter.makeNullTrace null Instance.supervision <- true try - AltCoverCoreTests.VisitsClear() + Adapter.VisitsClear() use stdout = new StringWriter() Console.SetOut stdout Directory.CreateDirectory(unique) |> ignore @@ -1718,14 +1641,13 @@ module AltCoverTests = [ 0..9 ] |> Seq.iter (fun i -> - AltCoverCoreTests.VisitsAdd( + Adapter.VisitsAdd( "f6e3edb3-fb20-44b3-817d-f69d1a22fc2f", i, (int64 (i + 1)) )) - let nullObj: obj = null - Instance.I.doUnload.Invoke(nullObj, null) + Adapter.DoUnload().Invoke(null, null) let head = "Coverage statistics flushing took " @@ -1760,25 +1682,16 @@ module AltCoverTests = "-1" ] ) finally - Instance.I.Trace <- save + Instance.I.trace <- save Instance.supervision <- false AltCoverCoreTests.maybeDeleteFile Instance.ReportFilePath - AltCoverCoreTests.VisitsClear() + Adapter.VisitsClear() Console.SetOut saved Directory.SetCurrentDirectory(here) AltCoverCoreTests.maybeIOException (fun () -> Directory.Delete(unique)))) getMyMethodName "<=" - let internal doFlush (visits, format, report, output) = - let output' = - if System.String.IsNullOrEmpty output then - null - else - output - - Counter.DoFlushFile(ignore, (fun _ _ -> ()), true, visits, format, report, output') - [] let FlushLeavesExpectedTracesWhenDiverted () = let saved = Console.Out @@ -1832,7 +1745,7 @@ module AltCoverTests = visits.["f6e3edb3-fb20-44b3-817d-f69d1a22fc2f"] <- payload - doFlush (visits, ReportFormat.NCover, reportFile, outputFile) + Adapter.doFlush (visits, ReportFormat.NCover, reportFile, outputFile) |> ignore use worker' = @@ -1916,7 +1829,7 @@ module AltCoverTests = visits.["f6e3edb3-fb20-44b3-817d-f69d1a22fc2f"] <- payload - doFlush (visits, ReportFormat.NCover, reportFile, outputFile) + Adapter.doFlush (visits, ReportFormat.NCover, reportFile, outputFile) |> ignore use worker' = @@ -1991,7 +1904,7 @@ module AltCoverTests = visits.["f6e3edb3-fb20-44b3-817d-f69d1a22fc2f"] <- payload - doFlush ( + Adapter.doFlush ( visits, ReportFormat.NCover ||| ReportFormat.Zipped, reportFile, @@ -2082,7 +1995,7 @@ module AltCoverTests = visits.["f6e3edb3-fb20-44b3-817d-f69d1a22fc2f"] <- payload - doFlush ( + Adapter.doFlush ( visits, ReportFormat.NCover ||| ReportFormat.Zipped, reportFile, @@ -2155,7 +2068,12 @@ module AltCoverTests = visits.["f6e3edb3-fb20-44b3-817d-f69d1a22fc2f"] <- payload - doFlush (visits, ReportFormat.NCover ||| ReportFormat.Zipped, reportFile, null) + Adapter.doFlush ( + visits, + ReportFormat.NCover ||| ReportFormat.Zipped, + reportFile, + null + ) |> ignore Assert.That(reportFile |> File.Exists |> not) @@ -2172,7 +2090,7 @@ module AltCoverTests = let ZipFlushLeavesExpectedTraces () = getMyMethodName "=>" - lock Instance.I.visits (fun () -> + lock Adapter.Lock (fun () -> Instance.I.isRunner <- false Instance.CoverageFormat <- ReportFormat.NCover ||| ReportFormat.Zipped @@ -2187,11 +2105,11 @@ module AltCoverTests = let unique = Path.Combine(where, Guid.NewGuid().ToString()) - let save = Instance.I.Trace - Instance.I.Trace <- Tracer.Create null + let save = Instance.I.trace + Instance.I.trace <- Adapter.makeNullTrace null try - AltCoverCoreTests.VisitsClear() + Adapter.VisitsClear() use stdout = new StringWriter() Console.SetOut stdout Directory.CreateDirectory(unique) |> ignore @@ -2226,14 +2144,13 @@ module AltCoverTests = [ 0..9 ] |> Seq.iter (fun i -> - AltCoverCoreTests.VisitsAdd( + Adapter.VisitsAdd( "f6e3edb3-fb20-44b3-817d-f69d1a22fc2f", i, (int64 (i + 1)) )) - let nullObj: obj = null - Instance.I.doExit.Invoke(nullObj, null) + Adapter.DoExit().Invoke(null, null) let head = "Coverage statistics flushing took " @@ -2281,10 +2198,10 @@ module AltCoverTests = "1" ] ) finally - Instance.I.Trace <- save + Instance.I.trace <- save AltCoverCoreTests.maybeDeleteFile Instance.ReportFilePath AltCoverCoreTests.maybeDeleteFile (Instance.ReportFilePath + ".zip") - AltCoverCoreTests.VisitsClear() + Adapter.VisitsClear() Console.SetOut saved Directory.SetCurrentDirectory(here) AltCoverCoreTests.maybeIOException (fun () -> Directory.Delete(unique)))) diff --git a/AltCover.Recorder.Tests/Tracer.Tests.fs b/AltCover.Recorder.Tests/Tracer.Tests.fs index 97b572fa8..920a9c4e5 100644 --- a/AltCover.Recorder.Tests/Tracer.Tests.fs +++ b/AltCover.Recorder.Tests/Tracer.Tests.fs @@ -37,89 +37,6 @@ module AltCoverCoreTests = g () reraise () - let internal init (n, l) = - let tmp = PointVisit.Create() - tmp.Count <- n - - tmp.Tracks.AddRange l - tmp - - let internal newBoth (time, call) = Both(Pair.Create(time, call)) - - let VisitsClear () = - Instance.I.Clear() - Counter.branchVisits <- 0L - Counter.totalVisits <- 0L - - let SamplesClear () = - Instance.I.samples <- Instance.I.MakeSamples() - - let private reset () = - Instance.I.isRunner <- false - VisitsClear() - SamplesClear() - - let ModuleReset (m: string array) = - Instance.Modules <- m - reset () - - let HardReset () = - Instance.Modules <- [| System.String.Empty |] - reset () - - let VisitsSeq () = - Instance.I.visits - |> Seq.cast>> - - let VisitImplMethod (moduleId, hitPointId, mId) = - Instance.I.VisitImpl(moduleId, hitPointId, (Call mId)) - - let internal prepareName name = - if name |> Instance.I.visits.ContainsKey |> not then - let entry = Dictionary() - Instance.I.visits.Add(name, entry) - - let VisitsAdd (name, line, number) = - prepareName name - let v = init (number, []) - Instance.I.visits.[name].Add(line, v) - - let VisitsAddTrack (name, line, number) = - prepareName name - let v1 = init (number, [ Call 17; Call 42 ]) - Instance.I.visits.[name].Add(line, v1) - - let v2 = - init ( - (number + 1L), - [ Time(17L) - Both(Pair.Create(42L, 23)) ] - ) - - Instance.I.visits.[name].Add(line + 1, v2) - - type Untable = - | Name of string - | Place of int - | Token of Track - - let internal untable t = - let r = List() - //let r = System.Collections.ArrayList() - - let n, p, (t': Track) = t - - match t' with - | :? Table as d -> - r.Add(Untable.Name n) |> ignore - r.Add(Untable.Place p) |> ignore - r.Add(Untable.Token d) |> ignore - | _ -> () - - r - - //======================================= - [] let ExcerciseItAll () = let where = @@ -189,7 +106,9 @@ module AltCoverCoreTests = (id, strike, match enum tag with - | Tag.Call -> (Call <| formatter.ReadInt32()) :> Track + //| Tag.Time -> Adapter.Time <| formatter.ReadInt64() + | Tag.Call -> Adapter.asCall <| formatter.ReadInt32() + //| Tag.Both -> Adapter.NewBoth((formatter.ReadInt64()), (formatter.ReadInt32())) | Tag.Table -> Assert.True((id = String.Empty)) Assert.True((strike = 0)) @@ -212,7 +131,7 @@ module AltCoverCoreTests = if pts > 0 then let p = formatter.ReadInt32() let n = formatter.ReadInt64() - let pv = init (n, []) + let pv = Adapter.init (n, []) t.[m].Add(p, pv) // [] @@ -221,14 +140,17 @@ module AltCoverCoreTests = match enum track with | Tag.Time -> - pv.Tracks.Add(Time <| formatter.ReadInt64()) + pv.Tracks.Add(Adapter.time <| formatter.ReadInt64()) tracking () | Tag.Call -> - pv.Tracks.Add(Call <| formatter.ReadInt32()) + pv.Tracks.Add(Adapter.asCall <| formatter.ReadInt32()) tracking () | Tag.Both -> pv.Tracks.Add( - newBoth ((formatter.ReadInt64()), (formatter.ReadInt32())) + Adapter.newBoth ( + (formatter.ReadInt64()), + (formatter.ReadInt32()) + ) ) tracking () @@ -242,8 +164,8 @@ module AltCoverCoreTests = sequencePoint points ``module`` () - Table t - | _ -> Null()) + Adapter.table t + | _ -> Adapter.asNull ()) |> hits.Add sink ()) @@ -253,7 +175,7 @@ module AltCoverCoreTests = [] let VisitShouldSignal () = - let save = Instance.I.Trace + let save = Instance.I.trace let where = Assembly.GetExecutingAssembly().Location @@ -265,7 +187,7 @@ module AltCoverCoreTests = let tag = unique + ".acv" let expected = - [ ("name", 23, Null() :> Track) ] + [ ("name", 23, Adapter.asNull ()) ] do use stream = File.Create tag @@ -275,16 +197,16 @@ module AltCoverCoreTests = let mutable client = Tracer.Create tag try - HardReset() - Instance.I.Trace <- client.OnStart() - Assert.True(Instance.I.Trace.IsConnected, "connection failed") + Adapter.HardReset() + Instance.I.trace <- client.OnStart() + Assert.True(Instance.I.trace.IsConnected, "connection failed") Instance.I.isRunner <- true - Instance.I.VisitImpl("name", 23, Null()) + Adapter.VisitImplNone("name", 23) finally - Instance.I.Trace.Close() - Instance.I.Trace.Close() - Instance.I.Trace.Close() - Instance.I.Trace <- save + Instance.I.trace.Close() + Instance.I.trace.Close() + Instance.I.trace.Close() + Instance.I.trace <- save use stream = // fsharplint:disable-next-line RedundantNewKeyword new DeflateStream(File.OpenRead(unique + ".0.acv"), CompressionMode.Decompress) @@ -292,23 +214,25 @@ module AltCoverCoreTests = let results = readResults stream |> Seq.toList - VisitsSeq() + Adapter.VisitsSeq() + |> Seq.cast>> |> Seq.iter (fun v -> Assert.That(v.Value, Is.Empty, sprintf "Unexpected local write %A" v)) Assert.That( - VisitsSeq() |> Seq.length, + Adapter.VisitsSeq() |> Seq.length, Is.EqualTo 3, - sprintf "unexpected local write %A" <| VisitsSeq() + sprintf "unexpected local write %A" + <| Adapter.VisitsSeq() ) Assert.True((results = expected), sprintf "unexpected result %A" results) finally - HardReset() + Adapter.HardReset() [] let VisitShouldSignalTrack () = - let save = Instance.I.Trace + let save = Instance.I.trace let where = Assembly.GetExecutingAssembly().Location @@ -325,18 +249,18 @@ module AltCoverCoreTests = t.["name"] <- Dictionary() let expect23 = - [ Call 17; Call 42 ] |> Seq.cast + [ Adapter.asCall 17; Adapter.asCall 42 ] let expect24 = - [ (Time 17L) :> Track - (newBoth (42L, 23)) :> Track ] + [ Adapter.time 17L + Adapter.newBoth (42L, 23) ] - t.["name"].[23] <- init (1L, expect23) - t.["name"].[24] <- init (2L, expect24) + t.["name"].[23] <- Adapter.init (1L, expect23) + t.["name"].[24] <- Adapter.init (2L, expect24) let expected = - [ (String.Empty, 0, (Table t) :> Track) - ("name", 23, Call 5) ] + [ (String.Empty, 0, Adapter.table t) + ("name", 23, Adapter.asCall 5) ] do use stream = File.Create tag @@ -346,34 +270,39 @@ module AltCoverCoreTests = let mutable client = Tracer.Create tag try - Instance.I.Trace <- client.OnStart() - Assert.True(Instance.I.Trace.IsConnected, "connection failed") + Instance.I.trace <- client.OnStart() + Assert.True(Instance.I.trace.IsConnected, "connection failed") Instance.I.isRunner <- true - HardReset() - VisitsAddTrack("name", 23, 1L) - VisitImplMethod("name", 23, 5) + Adapter.HardReset() + Adapter.VisitsAddTrack("name", 23, 1L) + Adapter.VisitImplMethod("name", 23, 5) finally Instance.I.isRunner <- false - Instance.I.Trace.Close() - Instance.I.Trace <- save + Instance.I.trace.Close() + Instance.I.trace <- save use stream = // fsharplint:disable-next-line RedundantNewKeyword new DeflateStream(File.OpenRead(unique + ".0.acv"), CompressionMode.Decompress) let results = readResults stream - Assert.True(("no", 0, Null()) |> untable |> Seq.isEmpty) + Assert.True( + ("no", 0, Adapter.asNull ()) + |> Adapter.untable + |> Seq.isEmpty + ) - VisitsSeq() + Adapter.VisitsSeq() |> Seq.cast>> |> Seq.iter (fun v -> Assert.That(v.Value, Is.Empty, sprintf "Unexpected local write %A" v)) Assert.That( - VisitsSeq() |> Seq.length, + Adapter.VisitsSeq() |> Seq.length, Is.EqualTo 3, - sprintf "unexpected local write %A" <| VisitsSeq() + sprintf "unexpected local write %A" + <| Adapter.VisitsSeq() ) Assert.True(results.Count = 2) @@ -384,19 +313,16 @@ module AltCoverCoreTests = ) let [ n'; p'; d' ] = - results |> Seq.head |> untable |> Seq.toList - - let n = - match n' with - | Untable.Name x -> x + results + |> Seq.head + |> Adapter.untable + |> Seq.toList - let p = - match p' with - | Untable.Place x -> x + let n = n' :?> String + let p = p' :?> int let d = - match d' with - | Untable.Token x -> (x :?> Table).Value + d' :?> Dictionary> Assert.True(n |> Seq.isEmpty) Assert.True((p = 0)) @@ -441,11 +367,11 @@ module AltCoverCoreTests = Assert.True((left2 = right2)) finally - HardReset() + Adapter.HardReset() [] let FlushShouldTidyUp () = // also throw a bone to OpenCover 615 - let save = Instance.I.Trace + let save = Instance.I.trace let where = Assembly.GetExecutingAssembly().Location @@ -464,22 +390,25 @@ module AltCoverCoreTests = let client = Tracer.Create unique let expected = - [ ("name", client.GetHashCode(), Null() :> Track) ] + [ ("name", client.GetHashCode(), Adapter.asNull ()) ] try - HardReset() - Instance.I.Trace <- client.OnStart() - Assert.That(Instance.I.Trace.Equals client, Is.False) - Assert.That(Instance.I.Trace.Equals expected, Is.False) - Assert.True(Instance.I.Trace.IsConnected, "connection failed") + Adapter.HardReset() + Instance.I.trace <- client.OnStart() + Assert.That(Instance.I.trace.Equals client, Is.False) + Assert.That(Instance.I.trace.Equals expected, Is.False) + Assert.True(Instance.I.trace.IsConnected, "connection failed") + + let formatter = + System.Runtime.Serialization.Formatters.Binary.BinaryFormatter() let (a, b, c) = expected |> Seq.head - Instance.I.Trace.Push(a, b, c) + Adapter.tracePush (a, b, c) Instance.FlushFinish() finally - Instance.I.Trace.Close() + Instance.I.trace.Close() System.Threading.Thread.Sleep 100 - Instance.I.Trace <- save + Instance.I.trace <- save use stream = // fsharplint:disable-next-line RedundantNewKeyword new DeflateStream(File.OpenRead(root + ".0.acv"), CompressionMode.Decompress) @@ -487,17 +416,18 @@ module AltCoverCoreTests = let results = stream |> readResults |> Seq.toList - VisitsSeq() + Adapter.VisitsSeq() |> Seq.cast>> |> Seq.iter (fun v -> Assert.That(v.Value, Is.Empty, sprintf "Unexpected local write %A" v)) Assert.That( - VisitsSeq() |> Seq.length, + Adapter.VisitsSeq() |> Seq.length, Is.EqualTo 3, - sprintf "unexpected local write %A" <| VisitsSeq() + sprintf "unexpected local write %A" + <| Adapter.VisitsSeq() ) Assert.True((results = expected), sprintf "unexpected result %A" results) finally - VisitsClear() \ No newline at end of file + Adapter.VisitsClear() \ No newline at end of file diff --git a/AltCover.Recorder.sln b/AltCover.Recorder.sln index d6ea40bd9..d4934cae6 100644 --- a/AltCover.Recorder.sln +++ b/AltCover.Recorder.sln @@ -42,9 +42,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build Items", "Build Items" Build\targets.fs = Build\targets.fs EndProjectSection EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample25", "D:\Github\altcover\Samples\Sample25\Sample25.csproj", "{16FCCC18-F3EE-4783-B548-50B011D03B5F}" +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "Sample25", "Samples\Sample25\Sample25.fsproj", "{54E57C76-339C-496E-B6EF-832534C7D545}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AltCover.Async", "D:\Github\altcover\AltCover.Async\AltCover.Async.csproj", "{882812A5-4DA4-4B6D-8054-EC14979EE4A3}" +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "AltCover.Async", "AltCover.Async\AltCover.Async.fsproj", "{9E8E72B3-FA30-4B09-8577-B9A1BB4F3126}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -62,14 +62,13 @@ Global {25BF9131-91CD-41CA-87F7-041E40426B5C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {25BF9131-91CD-41CA-87F7-041E40426B5C}.Debug|Any CPU.Build.0 = Debug|Any CPU {25BF9131-91CD-41CA-87F7-041E40426B5C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {16FCCC18-F3EE-4783-B548-50B011D03B5F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {16FCCC18-F3EE-4783-B548-50B011D03B5F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {16FCCC18-F3EE-4783-B548-50B011D03B5F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {16FCCC18-F3EE-4783-B548-50B011D03B5F}.Release|Any CPU.Build.0 = Release|Any CPU - {882812A5-4DA4-4B6D-8054-EC14979EE4A3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {882812A5-4DA4-4B6D-8054-EC14979EE4A3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {882812A5-4DA4-4B6D-8054-EC14979EE4A3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {882812A5-4DA4-4B6D-8054-EC14979EE4A3}.Release|Any CPU.Build.0 = Release|Any CPU + {54E57C76-339C-496E-B6EF-832534C7D545}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {54E57C76-339C-496E-B6EF-832534C7D545}.Debug|Any CPU.Build.0 = Debug|Any CPU + {54E57C76-339C-496E-B6EF-832534C7D545}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9E8E72B3-FA30-4B09-8577-B9A1BB4F3126}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9E8E72B3-FA30-4B09-8577-B9A1BB4F3126}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9E8E72B3-FA30-4B09-8577-B9A1BB4F3126}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9E8E72B3-FA30-4B09-8577-B9A1BB4F3126}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/AltCover.Recorder/AltCover.Recorder.csproj b/AltCover.Recorder/AltCover.Recorder.fsproj similarity index 66% rename from AltCover.Recorder/AltCover.Recorder.csproj rename to AltCover.Recorder/AltCover.Recorder.fsproj index dd036b0c2..6addc5613 100644 --- a/AltCover.Recorder/AltCover.Recorder.csproj +++ b/AltCover.Recorder/AltCover.Recorder.fsproj @@ -8,23 +8,28 @@ false false RECORDER - CS1591 - --keyfile:$(InfrastructureKey) TRACE;$(DefineConstants) + --keyfile:$(InfrastructureKey) --standalone --staticlink:ICSharpCode.SharpZipLib TRACE;DEBUG;CODE_ANALYSIS;$(DefineConstants) + --keyfile:$(InfrastructureKey) - - - - + + + + + + + + + AltCover.Recorder.Strings.resources @@ -33,10 +38,12 @@ + all runtime; build; native; contentfiles; analyzers + diff --git a/AltCover.Recorder/AssemblyInfo.cs b/AltCover.Recorder/AssemblyInfo.cs deleted file mode 100644 index d412f9a95..000000000 --- a/AltCover.Recorder/AssemblyInfo.cs +++ /dev/null @@ -1,6 +0,0 @@ -using System; -using System.Runtime.InteropServices; - -[assembly: CLSCompliant(true)] -[assembly: ComVisible(false)] -[assembly: System.Resources.NeutralResourcesLanguageAttribute("en-GB")] \ No newline at end of file diff --git a/AltCover.Recorder/Base.cs b/AltCover.Recorder/Base.cs deleted file mode 100644 index 881b5393d..000000000 --- a/AltCover.Recorder/Base.cs +++ /dev/null @@ -1,922 +0,0 @@ -#if RUNNER - -namespace AltCover -#else - -namespace AltCover.Recorder -#endif -{ - using System; - using System.Collections.Generic; - using System.Diagnostics.CodeAnalysis; - using System.Globalization; - using System.IO; - using System.Xml; - -#if !RUNNER - - using ICSharpCode.SharpZipLib.Zip; - - [AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = false)] - internal sealed class ExcludeFromCodeCoverageAttribute : Attribute - { } - -#endif - - [Flags] - [SuppressMessage("Gendarme.Rules.Design", - "FlagsShouldNotDefineAZeroValueRule", - Justification = "Zero is meaningful")] - [SuppressMessage("Gendarme.Rules.Naming", - "UsePluralNameInEnumFlagsRule", - Justification = "Not meaningful to do so")] - [Serializable] - internal enum ReportFormat - { - NCover = 0, - OpenCover = 1, - NativeJson = 2, - TrackMask = 63, - WithTracking = 64, - ZipMask = 127, - Zipped = 128, - }; - - [SuppressMessage("Gendarme.Rules.Performance", - "AvoidUncalledPrivateCodeRule", - Justification = "Internals Visible To")] - [SuppressMessage("Gendarme.Rules.Performance", - "AvoidUninstantiatedInternalClassesRule", - Justification = "Internals Visible To")] - [Serializable] - internal enum Sampling - { - All = 0, - Single = 1, - }; - - [SuppressMessage("Gendarme.Rules.Performance", - "AvoidUncalledPrivateCodeRule", - Justification = "Internals Visible To")] - [SuppressMessage("Gendarme.Rules.Performance", - "AvoidUninstantiatedInternalClassesRule", - Justification = "Internals Visible To")] - [Serializable] - internal enum Tag - { - Null = 0, - Time = 1, - Call = 2, - Both = 3, - Table = 4, - } - - [ExcludeFromCodeCoverage] - [SuppressMessage("Gendarme.Rules.Performance", - "ImplementEqualsTypeRule", - Justification = "No use case")] - [SuppressMessage("Gendarme.Rules.Design", - "OperatorEqualsShouldBeOverloadedRule", - Justification = "No use case")] - [SuppressMessage("Gendarme.Rules.Performance", - "OverrideValueTypeDefaultsRule", - Justification = "You what, mate?")] - internal struct Pair - { - public long Time; - public int Call; - - [SuppressMessage("Gendarme.Rules.Performance", - "AvoidUncalledPrivateCodeRule", - Justification = "Internals Visible To")] - public static Pair Create(long time, int call) - { - return new Pair { Time = time, Call = call }; - } - - public override string ToString() - { - return "AltCover.Pair(Time=" + Time.ToString(CultureInfo.InvariantCulture) - + ", Call=" + Call.ToString(CultureInfo.InvariantCulture) + ")"; - } - - public override bool Equals(object obj) - { - if (obj is Pair b) - { - return Call == b.Call - && Time == b.Time; - } - - return false; - } - - public override int GetHashCode() - { - return Call.GetHashCode() ^ Time.GetHashCode(); - } - } - - [SuppressMessage("Gendarme.Rules.Performance", - "ImplementEqualsTypeRule", - Justification = "abstract type, No use case")] - [SuppressMessage("Gendarme.Rules.Design", - "ConsiderUsingStaticTypeRule", - Justification = "Base class of union")] - internal abstract class Track - { - internal const string Entry = "\u2611"; // BALLOT BOX WITH CHECK - internal const string Exit = "\u2612"; // BALLOT BOX WITH X - } - - [SuppressMessage("Gendarme.Rules.Performance", - "ImplementEqualsTypeRule", - Justification = "No use case")] - internal sealed class Null : Track - { - public override string ToString() - { - return "AltCover.Null"; - } - - public override bool Equals(object obj) - { - return obj is Null; - } - - public override int GetHashCode() - { - return string.Empty.GetHashCode(); - } - } - - [SuppressMessage("Gendarme.Rules.Performance", - "ImplementEqualsTypeRule", - Justification = "No use case")] - internal sealed class Time : Track - { - public readonly long Value; - - public Time(long time) - { - Value = time; - } - - public override bool Equals(object obj) - { - if (obj is Time t) - { - return Value == t.Value; - } - - return false; - } - - public override int GetHashCode() - { - return Value.GetHashCode(); - } - - public override string ToString() - { - return "AltCover.Time : " + Value.ToString(CultureInfo.InvariantCulture); - } - } - - [SuppressMessage("Gendarme.Rules.Performance", - "ImplementEqualsTypeRule", - Justification = "No use case")] - internal sealed class Call : Track - { - public readonly int Value; - - public Call(int call) - { - Value = call; - } - - public override bool Equals(object obj) - { - if (obj is Call c) - { - return Value == c.Value; - } - - return false; - } - - public override int GetHashCode() - { - return Value.GetHashCode(); - } - - public override string ToString() - { - return "AltCover.Call : " + Value.ToString(CultureInfo.InvariantCulture); - } - } - - [SuppressMessage("Gendarme.Rules.Performance", - "ImplementEqualsTypeRule", - Justification = "No use case")] - internal sealed class Both : Track - { - public readonly Pair Value; - - public Both(Pair both) - { - Value = both; - } - - public override bool Equals(object obj) - { - if (obj is Both b) - { - var ok = Value.Equals(b.Value); - return ok; - } - - return false; - } - - public override int GetHashCode() - { - return Value.GetHashCode(); - } - - public override string ToString() - { - return "AltCover.Both : " + Value.ToString(); - } - } - - internal sealed class Table : Track - { - public readonly Dictionary> Value; - - public Table(Dictionary> table) - { - Value = table; - } - } - - [SuppressMessage("Gendarme.Rules.Performance", - "ImplementEqualsTypeRule", - Justification = "No use case")] - internal sealed class PointVisit - { - public long Count; - public readonly List Tracks; - - public override bool Equals(object obj) - { - if (obj is PointVisit b) - { - var ok = Count == b.Count && Tracks.Count == b.Tracks.Count; - for (var i = 0; ok && i < Tracks.Count; i++) - { - ok = ok && Tracks[i].Equals(b.Tracks[i]); - } - - return ok; - } - - return false; - } - - public override int GetHashCode() - { - return Count.GetHashCode(); - } - - public override string ToString() - { - var tracks = new string[Tracks.Count]; - for (int i = 0; i < Tracks.Count; ++i) - tracks[i] = Tracks[i].ToString(); - - return "AltCover.PointVisit : Count = " + Count.ToString(CultureInfo.InvariantCulture) + - " Tracks = '" + String.Join("; ", tracks) + "'"; - } - - private PointVisit(long count) - { - Count = count; - Tracks = new List(); - } - - internal static PointVisit Create() - { - return new PointVisit(0); - } - - internal void Step() - { - System.Threading.Interlocked.Increment(ref this.Count); - } - - internal void Track(Track something) - { - lock (this.Tracks) - { - this.Tracks.Add(something); - } - } - - internal long Total - { - get { return this.Count + this.Tracks.Count; } - } - } - - [SuppressMessage("Gendarme.Rules.Smells", - "AvoidLongParameterListsRule", - Justification = "Stable code")] - internal static class Counter - { - [SuppressMessage("Gendarme.Rules.Design.Generic", - "AvoidDeclaringCustomDelegatesRule", - Justification = "Net Framework 2.0")] - public delegate void PointProcessor(XmlElement doc, IEnumerable tracking); - - // - // The time at which coverage run began - // - internal static DateTime startTime = DateTime.UtcNow; - - // - // The finishing time taken of the coverage run - // - internal static DateTime measureTime = DateTime.UtcNow; - - // - // The offset flag for branch counts - // - internal const int branchFlag = unchecked((int)0x80000000); - - internal const int branchMask = unchecked((int)0x7FFFFFFF); - - internal static long totalVisits = 0; - - internal static long branchVisits = 0; - -#if DEBUG - - internal static class I -#else - - private static class I -#endif - { - [SuppressMessage("Gendarme.Rules.Performance", - "AvoidLargeStructureRule", - Justification = "No premature work")] - [SuppressMessage("Gendarme.Rules.Performance", - "OverrideValueTypeDefaultsRule", - Justification = "You what, mate?")] - internal struct CoverXml - { - internal string m; - internal string i; - internal string m2; - internal Dictionary s; - internal string v; - } - - internal static readonly CoverXml openCoverXml = - new CoverXml() - { - m = "//Module", - i = "hash", - m2 = "Classes/Class/Methods/Method", - s = new Dictionary { { "SequencePoints/SequencePoint", 0 }, - { "BranchPoints/BranchPoint", branchFlag } - }, - v = "vc" - }; - - internal static readonly CoverXml nCoverXml = - new CoverXml() - { - m = "//module", - i = "moduleId", - m2 = "method", - s = new Dictionary { { "seqpnt", 0 } }, - v = "visitcount" - }; - - internal static CoverXml XmlByFormat(ReportFormat format) - { - switch (format & ReportFormat.TrackMask) - { - case ReportFormat.OpenCover: return openCoverXml; - case ReportFormat.NCover: return nCoverXml; - default: throw new NotSupportedException(format.ToString()); - } - } - - internal static DateTime MinTime(DateTime t1, DateTime t2) - { - return t1 < t2 ? t1 : t2; - } - - internal static DateTime MaxTime(DateTime t1, DateTime t2) - { - return t1 > t2 ? t1 : t2; - } - - internal static int FindIndexFromUspid(int flag, string uspid) - { - var f = Int32.TryParse( - uspid, - NumberStyles.Integer, - CultureInfo.InvariantCulture, - out int c); - return f ? (c | flag) : -1; - } - - internal static void EnsurePoint(Dictionary counts, int hitPointId) - { - if (!counts.ContainsKey(hitPointId)) - { - lock (counts) - { - if (!counts.ContainsKey(hitPointId)) - { - System.Threading.Interlocked.Increment(ref Counter.totalVisits); - - if (hitPointId < 0) - { System.Threading.Interlocked.Increment(ref Counter.branchVisits); } - - counts.Add(hitPointId, PointVisit.Create()); - } - } - } - } - -#if RUNNER - - [SuppressMessage("Gendarme.Rules.Performance", - "AvoidUncalledPrivateCodeRule", - Justification = "Internals Visible To")] - internal static long AddTable( - Dictionary> counts, - Dictionary> t - ) - { - long hitcount = 0; - - foreach (var key in t.Keys) - { - if (!counts.ContainsKey(key)) - { - counts.Add(key, new Dictionary()); - var next = counts[key]; - var here = t[key]; - - foreach (var p in here.Keys) - { - EnsurePoint(next, p); - var v = next[p]; - var add = here[p]; - hitcount += add.Total; - lock (v) - { - v.Count += add.Count; - v.Tracks.AddRange(add.Tracks); - } - } - } - } - return hitcount; - } - -#endif - - // TODO inline in release if possible - internal static IEnumerable SelectNodes(XmlNode node, string name) - { - var result = new List(); - foreach (var x in node.SelectNodes(name)) - result.Add(x as XmlElement); - return result; - } - - // - // Load the XDocument - // - // The XML file to load - // Idiom to work with CA2202; we still double dispose the stream, but elude the rule. - // If this is ever a problem, we will need mutability and two streams, with explicit - // stream disposal if and only if the reader or writer doesn't take ownership - // Approved way is ugly -- https://docs.microsoft.com/en-us/visualstudio/code-quality/ca2202?view=vs-2019 - // Also, this rule is deprecated - // - private static XmlDocument ReadXDocument(Stream stream) - { - var doc = new XmlDocument(); - - try - { doc.Load(stream); } - catch (XmlException) - { doc.LoadXml(""); } - - return doc; - } - - // - // Write the XDocument - // - // The XML document to write - // The XML file to write to - // Idiom to work with CA2202 as above - private static void WriteXDocument(XmlDocument coverageDocument, Stream stream) - { coverageDocument.Save(stream); } - - [SuppressMessage("Gendarme.Rules.Smells", - "AvoidLongMethodsRule", - Justification = "Well tested code")] - [SuppressMessage("Gendarme.Rules.Smells", - "AvoidLongParameterListsRule", - Justification = "Stable code")] - [SuppressMessage("Microsoft.Usage", - "CA1806:DoNotIgnoreMethodResults", - Justification = "TryParse fails safe")] - public static DateTime UpdateReport( - Action postProcess, - PointProcessor pointProcess, - bool own, - Dictionary> counts, - ReportFormat format, - Stream coverageFile, - Stream outputFile - ) - { - var flushStart = DateTime.UtcNow; - var xmlformat = XmlByFormat(format);// throw early on unsupported - - var coverageDocument = ReadXDocument(coverageFile); - - var root = coverageDocument.DocumentElement; - - var startTimeNode = root.GetAttributeNode("startTime"); - - if ((format == ReportFormat.NCover) && startTimeNode is object) - { - var startTimeAttr = startTimeNode.Value; - var measureTimeAttr = root.GetAttribute("measureTime"); - var oldStartTime = DateTime.ParseExact(startTimeAttr, "o", null); - var oldMeasureTime = DateTime.ParseExact(measureTimeAttr, "o", null); - - var st = MinTime(startTime, oldStartTime); - startTime = st.ToUniversalTime(); // Min - var mt = MaxTime(measureTime, oldMeasureTime); - measureTime = mt.ToUniversalTime(); // Max - - root.SetAttribute( - "startTime", - startTime.ToString("o", System.Globalization.CultureInfo.InvariantCulture) - ); - - root.SetAttribute( - "measureTime", - measureTime.ToString("o", System.Globalization.CultureInfo.InvariantCulture) - ); - - root.SetAttribute( - "driverVersion", - "AltCover.Recorder " - + System.Diagnostics.FileVersionInfo - .GetVersionInfo( - System.Reflection.Assembly - .GetExecutingAssembly() - .Location - ) - .FileVersion - ); - } - - //let moduleNodes = - // selectNodes coverageDocument m - var moduleNodes = SelectNodes(coverageDocument, xmlformat.m); - - //moduleNodes - //|> Seq.cast < XmlElement > - foreach (var el in moduleNodes) - { - //|> Seq.map(fun el->el.GetAttribute(i), el) - var k = el.GetAttribute(xmlformat.i); - - // |> Seq.filter(fun(k, _)->counts.ContainsKey k) - if (!counts.ContainsKey(k)) continue; - - // let moduleHits = counts.[k] - var moduleHits = counts[k]; - - // Don't do this in one leap like -- - // affectedModule.Descendants(XName.Get("seqpnt")) - // Get the methods, then flip their - // contents before concatenating - // let nn = selectNodes affectedModule m' - var nn = SelectNodes(el, xmlformat.m2); - - //nn - //|> Seq.cast < XmlElement > - //|> Seq.collect(fun(method: XmlElement)-> - var nodes = new List>(); - foreach (var method in nn) - { - // s - //|> Seq.collect(fun(name, flag)-> - foreach (var nameflag in xmlformat.s) - { - // let nodes = selectNodes method name - - // nodes - // |> Seq.cast - var nodes1 = new List>(); - foreach (var node in SelectNodes(method, nameflag.Key)) - { - // |> Seq.map(fun x-> (x, flag)) - // |> Seq.toList - // |> List.rev)) - nodes1.Insert(0, new KeyValuePair(node, nameflag.Value)); - } - - nodes.AddRange(nodes1); - } - } - - int counter = -1; - foreach (var node in nodes) - { - ++counter; - var index = counter; - if ((format & ReportFormat.TrackMask) == - ReportFormat.OpenCover) - { - index = FindIndexFromUspid(node.Value, node.Key.GetAttribute("uspid")); - } - - if (moduleHits.TryGetValue(index, out PointVisit value)) - { - var pt = node.Key; - - Int64.TryParse( - pt.GetAttribute(xmlformat.v), - NumberStyles.Integer, - CultureInfo.InvariantCulture, - out var vc - ); - - // Treat -ve visit counts (an exemption added in analysis) as zero - var count = value; - var visits = Math.Max(vc, 0) + count.Total; - pt.SetAttribute(xmlformat.v, visits.ToString(CultureInfo.InvariantCulture)); - pointProcess(pt, count.Tracks); - } - } - } - - postProcess(coverageDocument); - - // Save modified xml to a file - outputFile.Seek(0L, SeekOrigin.Begin); - outputFile.SetLength(0); - - if (own) - - { - WriteXDocument(coverageDocument, outputFile); - } - - return flushStart; - } - - [SuppressMessage("Gendarme.Rules.Smells", - "AvoidLongParameterListsRule", - Justification = "Stable code")] - public static TimeSpan DoFlush( - Action postProcess, - PointProcessor pointProcess, - bool own, - Dictionary> counts, - ReportFormat format, - Stream coverageFile, - Stream outputFile - ) - { - var flushStart = - UpdateReport(postProcess, pointProcess, own, counts, format, coverageFile, outputFile); - - return new TimeSpan(DateTime.UtcNow.Ticks - flushStart.Ticks); - } - } - - // "Public" API - [SuppressMessage("Gendarme.Rules.Maintainability", - "AvoidUnnecessarySpecializationRule", - Justification = "No speculative generalization")] - internal static void AddSingleVisit( - Dictionary> counts, - string moduleId, - int hitPointId, - Track context - ) - { - if (counts.TryGetValue(moduleId, out Dictionary value)) - { - var next = value; - I.EnsurePoint(next, hitPointId); - var v = next[hitPointId]; - if (context is Null) - { v.Step(); } - else { v.Track(context); } - } - } - -#if RUNNER - - [SuppressMessage("Gendarme.Rules.Performance", - "AvoidUncalledPrivateCodeRule", - Justification = "Internals Visible To")] - internal static long AddVisit( - Dictionary> counts, - string moduleId, - int hitPointId, - Track context - ) - { - if (context is Table t) - { - return I.AddTable(counts, t.Value); - } - - AddSingleVisit(counts, moduleId, hitPointId, context); - return 1; - } - - [SuppressMessage("Gendarme.Rules.Performance", - "AvoidUncalledPrivateCodeRule", - Justification = "Internals Visible To")] - [SuppressMessage("Gendarme.Rules.Smells", - "AvoidLongParameterListsRule", - Justification = "Stable code")] - public static TimeSpan DoFlushStream( - Action postProcess, - PointProcessor pointProcess, - bool own, - Dictionary> counts, - ReportFormat format, - Stream coverageFile, - Stream outputFile - ) - { - return I.DoFlush(postProcess, pointProcess, own, counts, format, coverageFile, outputFile); - } - -#else - - [SuppressMessage("Microsoft.Reliability", - "CA2000:Dispose objects before losing scope", - Justification = "MemoryStream is 'use'd if created")] - internal static TimeSpan DoFlushStream( - Action postProcess, - PointProcessor pointProcess, - bool own, - Dictionary> counts, - ReportFormat format, - Stream coverageFile, - string output) // option - { - using (var target = string.IsNullOrEmpty(output) ? - new MemoryStream() as Stream : - new FileStream( - output, - FileMode.OpenOrCreate, - FileAccess.Write, - FileShare.None, - 4096, - FileOptions.SequentialScan - )) - { - var outputFile = string.IsNullOrEmpty(output) ? - coverageFile : target; - return I.DoFlush(postProcess, pointProcess, own, counts, format, coverageFile, outputFile); - } - } - - [SuppressMessage("Gendarme.Rules.Correctness", - "EnsureLocalDisposalRule", - Justification = "'zip' owns 'container' and is 'Close()'d")] - [SuppressMessage("Microsoft.Reliability", - "CA2000:Dispose objects before losing scope", - Justification = "'zip' owns 'container' and is 'Close()'d")] - internal static TimeSpan DoFlushFile( - Action postProcess, - PointProcessor pointProcess, - bool own, - Dictionary> counts, - ReportFormat format, - string report, - string output // option - ) - { - var zipped = (format & ReportFormat.Zipped) != 0; - if (!zipped) - { - using (var coverageFile = new FileStream( - report, - FileMode.Open, - FileAccess.ReadWrite, - FileShare.None, - 4096, - FileOptions.SequentialScan - )) - return DoFlushStream(postProcess, pointProcess, own, counts, format, coverageFile, output); - } - else - { - var container = - new FileStream( - report + ".zip", - FileMode.Open, - FileAccess.ReadWrite, - FileShare.None, - 4096, - FileOptions.SequentialScan - ); - using (var target = string.IsNullOrEmpty(output) ? - new MemoryStream() as Stream : - new FileStream( - output, - FileMode.OpenOrCreate, - FileAccess.Write, - FileShare.None, - 4096, - FileOptions.SequentialScan - )) - { - try - { - ZipConstants.DefaultCodePage = 65001; //UTF-8 as System.IO.Compression.ZipFile uses internally - var zip = new ZipFile(container); - - try - { - var entryName = Path.GetFileName(report); - var entry = zip.GetEntry(entryName); - - var result = new TimeSpan(0); - using (var reader = zip.GetInputStream(entry)) - { - result = I.DoFlush(postProcess, pointProcess, own, counts, format, reader, target); - } - - if (string.IsNullOrEmpty(output)) - { - zip.BeginUpdate(); - zip.Delete(entry); - target.Seek(0L, SeekOrigin.Begin); //|> ignore - - zip.Add(new Source(target), entryName); - zip.CommitUpdate(); - } - return result; - } - finally { zip.Close(); } - } - catch (ZipException) - { - using (var reader = new MemoryStream()) - { return I.DoFlush(postProcess, pointProcess, own, counts, format, reader, target); } - } - } - } - } - -#if !RUNNER - - internal sealed class Source : IStaticDataSource - { - private readonly Stream _target; - - public Source(Stream t) - { - _target = t; - } - - [SuppressMessage("Gendarme.Rules.Design", - "ConsiderConvertingMethodToPropertyRule", - Justification = "Third party interface")] - public Stream GetSource() - { - return _target; - } - } - -#endif - -#endif // !RUNNER - } -} \ No newline at end of file diff --git a/AltCover.Recorder/Base.fs b/AltCover.Recorder/Base.fs index 2180d94eb..1335a70b1 100644 --- a/AltCover.Recorder/Base.fs +++ b/AltCover.Recorder/Base.fs @@ -11,6 +11,80 @@ open System.Globalization open System.IO open System.Xml +[] +[] +[] +type internal ReportFormat = + | NCover = 0 + | OpenCover = 1 + | NativeJson = 2 + | TrackMask = 63 + | WithTracking = 64 + | ZipMask = 127 + | Zipped = 128 + +#if !RUNNER +open ICSharpCode.SharpZipLib.Zip + +[] +[] +[] +type internal ExcludeFromCodeCoverageAttribute() = + inherit Attribute() +#endif + +type internal Sampling = + | All = 0 + | Single = 1 + +// TODO isolate where +#if RUNNER +[] +#endif +type internal Tag = + | Null = 0 + | Time = 1 + | Call = 2 + | Both = 3 + | Table = 4 + +[] +[] +type internal Pair = { Time: int64; Call: int } + +[] +[] +type internal Track = + | Null + | Time of int64 + | Call of int + | Both of Pair + | Table of Dictionary> + static member internal Entry = "\u2611" // BALLOT BOX WITH CHECK + static member internal Exit = "\u2612" // BALLOT BOX WITH X + +and [] internal PointVisit = + { mutable Count: int64 + Tracks: List } + static member internal Create() = { Count = 0L; Tracks = List() } + + member internal self.Step() = + System.Threading.Interlocked.Increment(&self.Count) + |> ignore + + member internal self.Track something = + lock self.Tracks (fun () -> self.Tracks.Add something) + + member internal self.Total() = self.Count + int64 self.Tracks.Count + [] module internal Counter = type System.NotSupportedException with @@ -256,7 +330,7 @@ module internal Counter = |> snd // Treat -ve visit counts (an exemption added in analysis) as zero let count = moduleHits.[counter] - let visits = (max 0L vc) + count.Total + let visits = (max 0L vc) + count.Total() pt.SetAttribute(v, visits.ToString(CultureInfo.InvariantCulture)) pointProcess pt count.Tracks)) @@ -302,9 +376,9 @@ module internal Counter = here.Keys |> Seq.iter (fun p -> ensurePoint next p - let mutable v = next.[p] + let v = next.[p] let add = here.[p] - hitcount <- hitcount + add.Total + hitcount <- hitcount + add.Total() lock v (fun () -> v.Count <- v.Count + add.Count @@ -326,7 +400,7 @@ module internal Counter = (counts: Dictionary>) moduleId hitPointId - (context: Track) + context = if counts.ContainsKey moduleId then let next = counts.[moduleId] @@ -335,7 +409,7 @@ module internal Counter = let v = next.[hitPointId] match context with - | :? Null -> v.Step() + | Null -> v.Step() | something -> v.Track something #if RUNNER @@ -343,10 +417,10 @@ module internal Counter = (counts: Dictionary>) moduleId hitPointId - (context: Track) + context = match context with - | :? Table as t -> I.addTable counts t.Value + | Table t -> I.addTable counts t | _ -> addSingleVisit counts moduleId hitPointId context 1L diff --git a/AltCover.Recorder/InstrumentationAttribute.cs b/AltCover.Recorder/InstrumentationAttribute.cs deleted file mode 100644 index e33310541..000000000 --- a/AltCover.Recorder/InstrumentationAttribute.cs +++ /dev/null @@ -1,27 +0,0 @@ -namespace AltCover.Recorder -{ - using System; - - /// - /// An attribute to label an instrumented assembly by provenance - /// - [AttributeUsage(AttributeTargets.Assembly)] - public sealed class InstrumentationAttribute : Attribute - { - /// - /// SHA-256 hash of the original assembly - /// - public string Assembly { get; set; } - - /// - /// SHA-256 hash of instrumentation parameters - /// - public string Configuration { get; set; } - - public InstrumentationAttribute() - { - Assembly = "AltCover.Recorder.g!"; - Configuration = "Uninstrumented!!"; - } - } -} \ No newline at end of file diff --git a/AltCover.Recorder/Recorder.cs b/AltCover.Recorder/Recorder.cs deleted file mode 100644 index d7c35a4d3..000000000 --- a/AltCover.Recorder/Recorder.cs +++ /dev/null @@ -1,900 +0,0 @@ -using System.Diagnostics.CodeAnalysis; - -[assembly: SuppressMessage("Gendarme.Rules.Performance", - "AvoidUnneededFieldInitializationRule", - Scope = "member", // MethodDefinition - Target = "AltCover.Recorder.Instance::.cctor()", - Justification = "Compiler generated")] - -namespace AltCover.Recorder -{ - using System; - using System.Collections.Generic; - using System.Diagnostics; - using System.IO; - using System.Reflection; - - using System.Resources; - using System.Runtime.CompilerServices; - using System.Threading; - - public static class Instance - { - // Public "fields" - - /// - /// Gets the location of coverage xml file - /// This property's IL code is modified to store the actual file location - /// - public static string ReportFile - { - [MethodImpl(MethodImplOptions.NoInlining)] - get { return "Coverage.Default.xml"; } - } - - public static string ReportFilePath - { - get - { - return CanonicalPath(Path.Combine( - Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), - ReportFile)); - } - } - - internal static string CanonicalPath(string path) - // Mono+Linux barfs at a path of "/_" without the "file://" prefix - { - var u = new Uri("file://" + Path.GetFullPath(path), UriKind.Absolute); - return u.LocalPath; - } - - /// - /// Gets whether to defer output until process exit - /// This property's IL code is modified to store the actual value - /// - public static bool Defer - { - [MethodImpl(MethodImplOptions.NoInlining)] - get { return false; } - } - - /// - /// Gets the style of the associated report - /// This property's IL code is modified to store the user chosen override if applicable - /// - private static ReportFormat __coverageFormat = ReportFormat.NCover; - - internal static ReportFormat CoverageFormat - { -#if DEBUG - [SuppressMessage("Gendarme.Rules.Performance", - "AvoidUncalledPrivateCodeRule", - Justification = "Test interface")] - set { __coverageFormat = value; } -#endif - [MethodImpl(MethodImplOptions.NoInlining)] - get { return __coverageFormat; } - } - - /// - /// Gets the frequency of time sampling - /// This property's IL code is modified to store the user chosen override if applicable - /// - public static long Timer - { - [MethodImpl(MethodImplOptions.NoInlining)] - get { return 0; } - } - - /// - /// Gets the sampling strategy - /// This property's IL code is modified to store the user chosen override if applicable - /// - internal static Sampling Sample - { - [MethodImpl(MethodImplOptions.NoInlining)] - get { return Sampling.All; } - } - - /// - /// Gets the unique token for this Instance - /// This property's IL code is modified to store a GUID-based token - /// - public static string Token - { - [MethodImpl(MethodImplOptions.NoInlining)] - get { return "AltCover"; } - } - - /// - /// Gets the indexed module tokens - /// This property's IL code is modified to store instrumentation results - /// - private static string[] __modules = new string[] { string.Empty }; - - [SuppressMessage("Gendarme.Rules.Performance", - "AvoidReturningArraysOnPropertiesRule", - Justification = "Controlled use")] - internal static string[] Modules - { -#if DEBUG - [SuppressMessage("Gendarme.Rules.Performance", - "AvoidUncalledPrivateCodeRule", - Justification = "Test interface")] - set { __modules = value; } -#endif - [MethodImpl(MethodImplOptions.NoInlining)] - get { return __modules; } - } - - [SuppressMessage("Gendarme.Rules.Design", - "ConsiderConvertingMethodToPropertyRule", - Justification = "A bit big for that")] - private static bool IsSupervised() - { - bool maybe = false; - foreach (var a in AppDomain.CurrentDomain.GetAssemblies()) - { - var n = a.GetName(); - maybe = maybe || - n.Name == "AltCover.DataCollector" - && n.FullName.EndsWith("PublicKeyToken=c02b1a9f5b7cade8", StringComparison.Ordinal); - } - - return maybe && !Token.Equals("AltCover", StringComparison.Ordinal); - } - - //Assembly.GetExecutingAssembly().GetName().Name = "AltCover.Recorder.g" && - internal static bool supervision = IsSupervised(); - - [SuppressMessage("Gendarme.Rules.Smells", - "AvoidCodeDuplicatedInSiblingClassesRule", - Justification = "Too trivial")] - internal abstract class Sampled - { - [SuppressMessage("Gendarme.Rules.Maintainability", - "VariableNamesShouldNotMatchFieldNamesRule", - Justification = "too trivial")] - protected Sampled(int visit) - { - this.visit = visit; - } - - public readonly int visit; - } - - [SuppressMessage("Gendarme.Rules.Performance", - "ImplementEqualsTypeRule", - Justification = "No use case")] - internal sealed class SimpleVisit : Sampled - { - public SimpleVisit(int visit) : base(visit) - { - } - - public override bool Equals(object obj) - { - if (obj is SimpleVisit visit1) - { - return visit == visit1.visit; - } - return false; - } - - public override int GetHashCode() - { - return visit.GetHashCode(); - } - } - - [SuppressMessage("Gendarme.Rules.Performance", - "ImplementEqualsTypeRule", - Justification = "No use case")] - internal sealed class CallVisit : Sampled - { - public readonly int call; - - [SuppressMessage("Gendarme.Rules.Maintainability", - "VariableNamesShouldNotMatchFieldNamesRule", - Justification = "too trivial")] - public CallVisit(int visit, int call) : base(visit) - { - this.call = call; - } - - public override bool Equals(object obj) - { - if (obj is CallVisit visit1) - { - return (visit == visit1.visit) && (call == visit1.call); - } - return false; - } - - public override int GetHashCode() - { - return visit.GetHashCode() ^ call.GetHashCode(); - } - } - - [SuppressMessage("Gendarme.Rules.Performance", - "ImplementEqualsTypeRule", - Justification = "No use case")] - internal sealed class TimeVisit : Sampled - { - public readonly long time; - - [SuppressMessage("Gendarme.Rules.Maintainability", - "VariableNamesShouldNotMatchFieldNamesRule", - Justification = "too trivial")] - public TimeVisit(int visit, long time) : base(visit) - { - this.time = time; - } - - public override bool Equals(object obj) - { - if (obj is TimeVisit visit1) - { - return (visit == visit1.visit) && (time == visit1.time); - } - return false; - } - - public override int GetHashCode() - { - return visit.GetHashCode() ^ time.GetHashCode(); - } - } - -#if DEBUG - - [SuppressMessage("Gendarme.Rules.Smells", - "AvoidLargeClassesRule", - Justification = "No. Go away.")] - [SuppressMessage("Gendarme.Rules.Smells", - "AvoidLongParameterListsRule", - Justification = "Stable code")] - internal static class I -#else - - private static class I -#endif - { - internal static readonly ResourceManager resources = - new ResourceManager("AltCover.Recorder.Strings", Assembly.GetExecutingAssembly()); - - internal static string GetResource(string s) - { - var cc = System.Globalization.CultureInfo.CurrentUICulture; - var names = new string[] { cc.Name, cc.Parent.Name, "en" }; - string result = null; - foreach (var name in names) - { - result = resources.GetString(s + "." + name); - if (!string.IsNullOrEmpty(result)) - break; - } - - return result; - } - - private static Dictionary> MakeVisits() - { - var d = new Dictionary> - { - { Track.Entry, new Dictionary() }, - { Track.Exit, new Dictionary() } - }; - foreach (var item in Modules) - { - d.Add(item, new Dictionary()); - } - return d; - } - - /// - /// Accumulation of visit records - /// - internal static Dictionary> visits = MakeVisits(); - - internal static Dictionary> MakeSamples() - { - var d = new Dictionary>(); - foreach (var item in Modules) - { - d.Add(item, new Dictionary()); - } - return d; - } - - internal static Dictionary> samples = MakeSamples(); - - internal static bool isRunner = false; - - internal static readonly object synchronize = new Object(); - -#if NET20 - - // class needed for "[ThreadStatic] static val mutable" - private sealed class AsyncLocal - { - [ThreadStatic] - private static T item; - - static AsyncLocal() - { - item = default; - } - - public T Value - { - [SuppressMessage("Gendarme.Rules.Correctness", - "MethodCanBeMadeStaticRule", - Justification = "Whole point of the exercise")] - get { return item; } - [SuppressMessage("Gendarme.Rules.Correctness", - "MethodCanBeMadeStaticRule", - Justification = "Whole point of the exercise")] - [SuppressMessage("Gendarme.Rules.Concurrency", - "WriteStaticFieldFromInstanceMethodRule", - Justification = "Whole point of the exercise")] - set { item = value; } - } - } - -#endif - - /// - /// Gets or sets the current test method - /// - private static class CallTrack - { - private static readonly AsyncLocal> __value = new AsyncLocal>(); - - private static AsyncLocal> Value - { - get { return __value; } - } - - // no race conditions here - private static Stack Instance() - { - if (Value.Value == null) - Value.Value = new Stack(); - - return Value.Value; - } - - public static Nullable Peek() - { - var i = Instance(); - return (i.Count > 0) ? (Nullable)i.Peek() : null; - } - - public static void Push(int x) - { - Instance().Push(x); - } - - public static Nullable Pop() - { - var i = Instance(); - return (i.Count > 0) ? (Nullable)i.Pop() : null; - } - } - - internal static Nullable CallerId - { - get { return CallTrack.Peek(); } - } - - internal static void Push(int i) - { - CallTrack.Push(i); - } - - internal static Nullable Pop() - { return CallTrack.Pop(); } - - /// - /// Serialize access to the report file across AppDomains for the classic mode - /// - internal static readonly Mutex mutex = new Mutex(false, Token + ".mutex"); - - internal static string SignalFile - { - get { return ReportFilePath + ".acv"; } - } - - /// - /// Reporting back to the mother-ship - /// - private static Tracer __trace = Tracer.Create(SignalFile); - - internal static Tracer Trace - { - set { __trace = value; } - [MethodImpl(MethodImplOptions.NoInlining)] - get { return __trace; } - } - - [SuppressMessage("Gendarme.Rules.Design.Generic", - "AvoidDeclaringCustomDelegatesRule", - Justification = "Net Framework 2.0")] - internal delegate void MutexHandler(bool own); - - internal static void WithMutex(MutexHandler f) - { - var own = mutex.WaitOne(1000); - - try - { - f(own); - } - finally - { - if (own) mutex.ReleaseMutex(); - } - } - - internal static void InitialiseTrace(Tracer t) - { - WithMutex( - x => - { - Trace = t.OnStart(); - isRunner = isRunner || Trace.IsConnected; - } - ); - } - - internal static FileSystemWatcher watcher = new FileSystemWatcher(); - - private static bool __recording = true; - - internal static bool Recording - { - set { __recording = value; } - [MethodImpl(MethodImplOptions.NoInlining)] - get { return __recording; } - } - - internal static void Clear() - { - visits = MakeVisits(); - Counter.branchVisits = 0; - Counter.totalVisits = 0; - } - - /// - /// This method flushes hit count buffers. - /// - [SuppressMessage("Gendarme.Rules.Performance", - "AvoidUnusedParametersRule", - Justification = "Tidying later perhaps")] - internal static void FlushAll(Close _) - { - var counts = visits; - Clear(); - - Trace.OnConnected( - () => Trace.OnFinish(counts), - () => - { - var any = false; - foreach (var n in counts.Values) - { - if (n.Count > 0) - { - any = true; - break; - } - } - - if (!any) return; - - WithMutex(own => - { - var delta = - Counter.DoFlushFile( - x => { return; }, - (x, y) => { return; }, - own, - counts, - CoverageFormat, - ReportFilePath, - null - ); - - var message = GetResource("Coverage statistics flushing took {0:N} seconds"); - if (!string.IsNullOrEmpty(message)) - Console.Out.WriteLine(message, delta.TotalSeconds); - }); - } - ); - } - - internal static void FlushPause() - { - var message = GetResource("PauseHandler"); - if (!string.IsNullOrEmpty(message)) - Console.Out.WriteLine(message); - - Recording = false; - FlushAll(Close.Pause); - Trace = Tracer.Create(SignalFile); - } - - internal static void FlushResume() - { - var message = GetResource("ResumeHandler"); - if (!string.IsNullOrEmpty(message)) - Console.Out.WriteLine(message); - - var wasConnected = isRunner; - InitialiseTrace(Trace); - - if (wasConnected != isRunner) - { - samples = MakeSamples(); - Clear(); - } - - Recording = true; - } - - internal static void TraceVisit(string moduleId, int hitPointId, Track context) - { - lock (synchronize) - { - var counts = visits; - //if counts.Values |> Seq.sumBy (fun x -> x.Count) > 0 then - foreach (var item in counts.Values) - { - if (item.Count > 0) - { - Clear(); - break; - } - } - - Trace.OnVisit(counts, moduleId, hitPointId, context); - } - } - - [SuppressMessage("Gendarme.Rules.Globalization", - "PreferIFormatProviderOverrideRule", - Justification = "later, perhaps")] - [SuppressMessage("Microsoft.Globalization", - "CA1305:SpecifyIFormatProvider", - Justification = "later, perhaps")] - internal static void LogException(T1 moduleId, T2 hitPointId, T3 context, T4 x) - { - var text = new string[] { - String.Format("ModuleId = {0}", moduleId), - String.Format("hitPointId = {0}", hitPointId), - String.Format("context = {0}", context), - String.Format("exception = {0}", x.ToString()), - (new StackTrace()).ToString() - }; - - var stamp = DateTime.UtcNow.Ticks.ToString(); - var filename = ReportFilePath + "." + stamp + ".exn"; - using (var file = File.Open(filename, FileMode.OpenOrCreate, FileAccess.Write)) - using (var writer = new StreamWriter(file)) - { - foreach (var line in text) - writer.WriteLine(line); - } - } - - [SuppressMessage("Gendarme.Rules.Design.Generic", - "AvoidDeclaringCustomDelegatesRule", - Justification = "Net Framework 2.0")] - internal delegate void HandlerFunction(T1 a, T2 b, T3 c, Exception x); - - [SuppressMessage("Gendarme.Rules.Design.Generic", - "AvoidDeclaringCustomDelegatesRule", - Justification = "Net Framework 2.0")] - internal delegate void Adder(T1 a, T2 b, T3 c, T4 d); - - internal static void Issue71Wrapper(T1 visitsIn, T2 moduleId, T3 hitPointId, - T4 context, HandlerFunction handler, Adder add) - { - try - { - add(visitsIn, moduleId, hitPointId, context); - } - catch (Exception x) - { - if (x is KeyNotFoundException || x is NullReferenceException || x is ArgumentNullException) - { - handler(moduleId, hitPointId, context, x); - } - else throw; - } - } - - internal static void CurriedIssue71Wrapper(T1 visitsIn, T2 moduleId, - T3 hitPointId, - T4 context, Adder add) - { - Issue71Wrapper(visitsIn, moduleId, hitPointId, context, LogException, add); - } - - internal static void AddVisit(string moduleId, int hitPointId, Track context) - { - CurriedIssue71Wrapper(visits, moduleId, hitPointId, context, Counter.AddSingleVisit); - } - - internal static bool TakeSample(Sampling strategy, string moduleId, int hitPointId, Track context) - { - if (strategy == Sampling.All) - return true; - - Sampled[] sampleds; - if (context is Null) - sampleds = new Sampled[] { new SimpleVisit(hitPointId) }; - else if (context is Time t) - sampleds = new Sampled[] { new SimpleVisit(hitPointId), - new TimeVisit(hitPointId, t.Value)}; - else if (context is Call c) - sampleds = new Sampled[] { new SimpleVisit(hitPointId), - new CallVisit(hitPointId, c.Value)}; - else if (context is Both b) - { - sampleds = new Sampled[] { new SimpleVisit(hitPointId), - new TimeVisit(hitPointId, b.Value.Time), - new CallVisit(hitPointId, b.Value.Call)}; - } - else throw new InvalidDataException(context.ToString()); - - var wanted = false; - foreach (var sample in sampleds) - { - if (!samples.ContainsKey(moduleId)) - continue; - var next = samples[moduleId]; - var hasPointKey = next.ContainsKey(sample); - if (!hasPointKey) - { - lock (next) - { - hasPointKey = next.ContainsKey(sample); - if (!hasPointKey) - { - next.Add(sample, true); - } - } - - wanted = wanted || !hasPointKey; - } - } - - return wanted; - } - - /// - /// This method is executed from instrumented assemblies. - /// - /// Assembly being visited - /// Sequence Point identifier - /// What sort of visit - internal static void VisitImpl(string moduleId, int hitPointId, Track context) - { - if - (Sample == Sampling.All - || TakeSample(Sample, moduleId, hitPointId, context)) - { - if (Defer || supervision || !Trace.IsConnected) - { - AddVisit(moduleId, hitPointId, context); - } - else - { - TraceVisit(moduleId, hitPointId, context); - } - } - } - - internal static bool IsTracking - { - get { return (CoverageFormat & ReportFormat.WithTracking) != 0; } - } - - [SuppressMessage("Gendarme.Rules.Design", - "ConsiderConvertingMethodToPropertyRule", - Justification = "No use case")] - internal static bool IsTrackingRunner() - { - return IsTracking && isRunner; - } - - internal static long Granularity() - { - return Timer; - } - - internal static long Clock() - { - return DateTime.UtcNow.Ticks; - } - - [SuppressMessage("Gendarme.Rules.Design.Generic", - "AvoidDeclaringCustomDelegatesRule", - Justification = "Net Framework 2.0")] - internal delegate long ClockProvider(); - - [SuppressMessage("Gendarme.Rules.Design.Generic", - "AvoidDeclaringCustomDelegatesRule", - Justification = "Net Framework 2.0")] - internal delegate long FrequencyProvider(); - - [SuppressMessage("Gendarme.Rules.Design.Generic", - "AvoidDeclaringCustomDelegatesRule", - Justification = "Net Framework 2.0")] - internal delegate bool PayloadProvider(); - - [SuppressMessage("Gendarme.Rules.Performance", - "AvoidRepetitiveCallsToPropertiesRule", - Justification = "Separate branches")] - internal static Track PayloadSelection(ClockProvider clock, - FrequencyProvider frequency, PayloadProvider wantPayload) - { - if (wantPayload()) - { - var f = frequency(); - var id = CallerId; - if (f == 0) - { - return id.HasValue ? - (Track)new Call(id.Value) : - new Null(); - } - else - { - var t = f * (clock() / f); - return id.HasValue ? - (Track)new Both(Pair.Create(t, id.Value)) : - new Time(t); - } - } - return new Null(); - } - - internal static Track PayloadControl(FrequencyProvider frequency, PayloadProvider wantPayload) - { - return PayloadSelection(Clock, frequency, wantPayload); - } - - internal static Track PayloadSelector(PayloadProvider enable) - { - return PayloadControl(Granularity, enable); - } - - internal static void VisitSelection(Track track, string moduleId, int hitPointId) - { - VisitImpl(moduleId, hitPointId, track); - } - - internal static void FlushCounter(Close finish, EventArgs _) - { - switch (finish) - { - case Close.Resume: - FlushResume(); break; - case Close.Pause: - FlushPause(); break; - default: - Recording = false; - if (!supervision) - FlushAll(finish); - break; - } - } - - // Register event handling - internal static FileSystemEventHandler doPause = PauseHandler; - - internal static void PauseHandler(object sender, FileSystemEventArgs e) - { - FlushCounter(Close.Pause, e); - } - - internal static FileSystemEventHandler doResume = ResumeHandler; - - internal static void ResumeHandler(object sender, FileSystemEventArgs e) - { - FlushCounter(Close.Resume, e); - } - - [SuppressMessage("Gendarme.Rules.Correctness", - "DeclareEventsExplicitlyRule", - Justification = "Wrong use case")] - internal static EventHandler doUnload = UnloadHandler; - - internal static void UnloadHandler(object sender, EventArgs e) - { - FlushCounter(Close.DomainUnload, e); - } - - [SuppressMessage("Gendarme.Rules.Correctness", - "DeclareEventsExplicitlyRule", - Justification = "Wrong use case")] - internal static EventHandler doExit = ExitHandler; - - internal static void ExitHandler(object sender, EventArgs e) - { - FlushCounter(Close.ProcessExit, e); - } - - internal static void StartWatcher() - { - var s = SignalFile; - watcher.Path = Path.GetDirectoryName(s); - watcher.Filter = Path.GetFileName(s); - watcher.Created += doResume; - watcher.Deleted += doPause; - watcher.EnableRaisingEvents = !String.IsNullOrEmpty(watcher.Path); - } - - [SuppressMessage("Gendarme.Rules.Performance", - "AvoidUnneededFieldInitializationRule", - Justification = "Simpler this way")] - [SuppressMessage("Gendarme.Rules.Performance", - "AvoidRepetitiveCallsToPropertiesRule", - Justification = "You what, mate?")] - [SuppressMessage("Microsoft.Performance", - "CA1810:InitializeReferenceTypeStaticFieldsInline", - Justification = "Simpler this way")] - static I() - { - AppDomain.CurrentDomain.DomainUnload += doUnload; - AppDomain.CurrentDomain.ProcessExit += doExit; - StartWatcher(); - InitialiseTrace( - Tracer.Create(SignalFile) - ); - } - } - - // Public API - public static void Visit(string moduleId, int hitPointId) - { - if (I.Recording) - { - var track = I.IsTracking ? - I.PayloadSelector(I.IsTrackingRunner) : - new Null(); - I.VisitSelection(track, moduleId, hitPointId); - } - } - - //// The moduleId strings are not the hash or guids normally found there - public static void Push(int caller) - { - I.Push(caller); - - if (I.IsTrackingRunner()) - I.VisitSelection(new Time(DateTime.UtcNow.Ticks), Track.Entry, caller); - } - - public static void Pop() - { - var caller = I.Pop(); - - if (I.IsTrackingRunner() && caller.HasValue) - I.VisitSelection(new Time(DateTime.UtcNow.Ticks), Track.Exit, caller.Value); - } - - [SuppressMessage("Gendarme.Rules.Performance", - "AvoidUncalledPrivateCodeRule", - Justification = "Internals Visible To")] - public static void FlushFinish() - { - I.FlushAll(Close.ProcessExit); - } - } -} \ No newline at end of file diff --git a/AltCover.Recorder/Tracer.cs b/AltCover.Recorder/Tracer.cs deleted file mode 100644 index 2ff0b4154..000000000 --- a/AltCover.Recorder/Tracer.cs +++ /dev/null @@ -1,206 +0,0 @@ -namespace AltCover.Recorder -{ - using System; - using System.Collections.Generic; - using System.Diagnostics.CodeAnalysis; - using System.Drawing; - using System.IO; - using System.IO.Compression; - using System.Runtime.Remoting.Contexts; - using System.Runtime.Serialization; - using System.Text.RegularExpressions; - - //using AltCover.Shared; - - [Serializable] - internal enum Close - { - DomainUnload, - ProcessExit, - Pause, - Resume, - } - - [SuppressMessage("Gendarme.Rules.Performance", - "OverrideValueTypeDefaultsRule", - Justification = "Not actually used/NoComparison")] - internal struct Tracer - { - public string TracerName; - public bool Runner; - public bool Definitive; - public System.IO.Stream Stream; - public System.IO.BinaryWriter Formatter; - - private Tracer(string name) - { - TracerName = name; - Runner = false; - Definitive = false; - Stream = null; - Formatter = null; - } - - internal static Tracer Create(string name) - { - return new Tracer(name); - } - - internal bool IsConnected - { - get - { - return (this.Stream != null) && this.Runner; - } - } - - [SuppressMessage("Gendarme.Rules.Correctness", - "EnsureLocalDisposalRule", - Justification = "s, fs : Closed as recording ends")] - [SuppressMessage("Microsoft.Reliability", - "CA2000:Dispose objects before losing scope", - Justification = "s, fs : Closed as recording ends")] - private Tracer MakeConnection(string f) - { - var fs = File.OpenWrite(f); - - var s = - new DeflateStream(fs, CompressionMode.Compress); - - Stream = s; - Formatter = new BinaryWriter(s); - Runner = true; - - return this; - } - - internal Tracer Connect() - { - if (File.Exists(this.TracerName)) - { - for (var i = 0; true; ++i) - { - var extension = i.ToString(System.Globalization.CultureInfo.InvariantCulture); - var path = Path.ChangeExtension(this.TracerName, "." + extension + ".acv"); - if (File.Exists(path)) { continue; } - MakeConnection(path); - return this; - } - } - else - { return this; } - } - - internal void Close() - { - try - { - this.Stream.Flush(); - - this.Formatter.Close(); - } - catch (ObjectDisposedException) { } - catch (NullReferenceException) { } - } - - [SuppressMessage("Gendarme.Rules.Smells", - "AvoidLongMethodsRule", - Justification = "Well tested code")] - private void PushContext(Track context) - { - if (context is Null) - Formatter.Write((byte)Tag.Null); - else if (context is Time t) - { - Formatter.Write((byte)Tag.Time); - Formatter.Write(t.Value); - } - else if (context is Call c) - { - Formatter.Write((byte)Tag.Call); - Formatter.Write(c.Value); - } - else if (context is Both b) - { - Formatter.Write((byte)Tag.Both); - Formatter.Write(b.Value.Time); - Formatter.Write(b.Value.Call); - } - else - { - var tx = ((Table)context).Value; - Formatter.Write((byte)Tag.Table); - foreach (var key in tx.Keys) - { - if (tx[key].Count == 0) - continue; - Formatter.Write(key); - Formatter.Write(tx[key].Count); - - foreach (var p in tx[key].Keys) - { - Formatter.Write(p); - var v = tx[key][p]; - Formatter.Write(v.Count); - foreach (var x in v.Tracks) - PushContext(x); - PushContext(new Null()); - } - } - Formatter.Write(String.Empty); - } - } - - internal void Push(string moduleId, int hitPointId, Track context) - { - this.Formatter.Write(moduleId); - this.Formatter.Write(hitPointId); - this.PushContext(context); - } - - internal void CatchUp(Dictionary> visits) - { - foreach (var item in visits.Values) - { - if (item.Count > 0) - { - Push(String.Empty, 0, new Table(visits)); - return; - } - } - } - - internal Tracer OnStart() - { - var running = Connect(); - running.Definitive = true; - return running; - } - - [SuppressMessage("Gendarme.Rules.Design.Generic", - "AvoidDeclaringCustomDelegatesRule", - Justification = "Net Framework 2.0")] - public delegate void Act(); - - //member internal this.OnConnected f g = if this.IsConnected then f () else g () - internal void OnConnected(Act f, Act g) - { - if (IsConnected) f(); else g(); - } - - internal void OnFinish(Dictionary> visits) - { - CatchUp(visits); - Close(); - } - - internal void OnVisit(Dictionary> visits, - string moduleId, int hitPointId, Track context) - { - CatchUp(visits); - Push(moduleId, hitPointId, context); - Formatter.Flush(); - Stream.Flush(); - } - } -} \ No newline at end of file diff --git a/AltCover.Recorder2.Tests/AltCover.Recorder2.Tests.fsproj b/AltCover.Recorder2.Tests/AltCover.Recorder2.Tests.fsproj index 425492cfc..36ff8c123 100644 --- a/AltCover.Recorder2.Tests/AltCover.Recorder2.Tests.fsproj +++ b/AltCover.Recorder2.Tests/AltCover.Recorder2.Tests.fsproj @@ -25,12 +25,11 @@ AssemblyVersion.fs - + - @@ -47,6 +46,7 @@ contentfiles + diff --git a/AltCover.RecorderModern.Tests/AltCover.RecorderModern.Tests.fsproj b/AltCover.RecorderModern.Tests/AltCover.RecorderModern.Tests.fsproj new file mode 100644 index 000000000..bcbe02614 --- /dev/null +++ b/AltCover.RecorderModern.Tests/AltCover.RecorderModern.Tests.fsproj @@ -0,0 +1,56 @@ + + + + net472 + false + AltCover.RecorderModern.Tests + false + NU1702, 3559 + NU1702 + --keyfile:$(InfrastructureKey) + RECORDERMODERN + + + + TRACE;DEBUG;ALTCOVER_TEST;$(ExtraDefines) + + + TRACE;RELEASE;ALTCOVER_TEST;$(ExtraDefines) + + + + + + + + AssemblyVersion.fs + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + contentfiles + + + + + + + + + \ No newline at end of file diff --git a/AltCover.RecorderModern/AltCover.RecorderModern.fsproj b/AltCover.RecorderModern/AltCover.RecorderModern.fsproj new file mode 100644 index 000000000..a5819e901 --- /dev/null +++ b/AltCover.RecorderModern/AltCover.RecorderModern.fsproj @@ -0,0 +1,56 @@ + + + + net472 + AltCover.RecorderModern + AltCover.Recorder + false + false + false + RECORDER + + + + TRACE;$(DefineConstants) + --keyfile:$(InfrastructureKey) + + + + TRACE;DEBUG;CODE_ANALYSIS;$(DefineConstants) + --keyfile:$(InfrastructureKey) + + + + + + + + + + + + + + + AltCover.Recorder.Strings.resources + + + + + + + all + runtime; build; native; contentfiles; analyzers + + + contentfiles + + + + + + ..\ThirdParty\ziplib.net20\ICSharpCode.SharpZipLib.dll + + + + \ No newline at end of file diff --git a/AltCover.Tests/AltCover.Tests.fsproj b/AltCover.Tests/AltCover.Tests.fsproj index fe2611d7c..51cefad13 100644 --- a/AltCover.Tests/AltCover.Tests.fsproj +++ b/AltCover.Tests/AltCover.Tests.fsproj @@ -27,7 +27,6 @@ - @@ -106,13 +105,12 @@ - + AltCover.Recorder.net20.dll - diff --git a/AltCover.Tests/Expecto.fs b/AltCover.Tests/Expecto.fs index 79b726e95..594fca6df 100644 --- a/AltCover.Tests/Expecto.fs +++ b/AltCover.Tests/Expecto.fs @@ -12,11 +12,6 @@ module ExpectoTestManifest = let simpleTests () = [| #endif - Tests.BaseTests.ExerciseBoth, "BaseTests.ExerciseBoth" - Tests.BaseTests.ExerciseTime, "BaseTests.ExerciseTime" - Tests.BaseTests.ExerciseCall, "BaseTests.ExerciseCall" - Tests.BaseTests.ExerciseNull, "BaseTests.ExerciseNull" - Tests.BaseTests.ExercisePointVisit, "BaseTests.ExercisePointVisit" Tests.TestCommonTests.TestMultiple, "Tests.TestCommonTests.TestMultiple" Tests.TestCommonTests.TestIgnoredTests, "TestCommonTests.TestIgnoredTests" Tests.TestCommonTests.ExerciseItAll, "TestCommonTests.ExerciseItAll" diff --git a/AltCover.Tests/Runner.Tests.fs b/AltCover.Tests/Runner.Tests.fs index 70541acd5..15063c871 100644 --- a/AltCover.Tests/Runner.Tests.fs +++ b/AltCover.Tests/Runner.Tests.fs @@ -16,7 +16,6 @@ open Microsoft.FSharp.Reflection open Mono.Options #nowarn "25" // partial pattern match -#nowarn "3559" // TODO module AltCoverUsage = let internal usageText = @@ -59,32 +58,32 @@ module AltCoverRunnerTests = [] let ShouldFailXmlDataForNativeJson () = Assert.Throws(fun () -> - ignore (ReportFormat.NativeJson |> Counter.I.XmlByFormat)) + ignore (ReportFormat.NativeJson |> Counter.I.xmlByFormat)) |> ignore [] let MaxTimeFirst () = let now = DateTime.Now let ago = now - TimeSpan(1, 0, 0, 0) - test <@ (Counter.I.MaxTime(now, ago)) = now @> + test <@ (Counter.I.maxTime now ago) = now @> [] let MaxTimeLast () = let now = DateTime.Now let ago = now - TimeSpan(1, 0, 0, 0) - test <@ (Counter.I.MaxTime(ago, now)) = now @> + test <@ (Counter.I.maxTime ago now) = now @> [] let MinTimeFirst () = let now = DateTime.Now let ago = now - TimeSpan(1, 0, 0, 0) - test <@ (Counter.I.MinTime(ago, now)) = ago @> + test <@ (Counter.I.minTime ago now) = ago @> [] let MinTimeLast () = let now = DateTime.Now let ago = now - TimeSpan(1, 0, 0, 0) - test <@ (Counter.I.MinTime(now, ago)) = ago @> + test <@ (Counter.I.minTime now ago) = ago @> [] let JunkUspidGivesNegativeIndex () = @@ -92,7 +91,7 @@ module AltCoverRunnerTests = let key = " " let index = - Counter.I.FindIndexFromUspid(0, key) + Counter.I.findIndexFromUspid 0 key test <@ index < 0 @> @@ -106,10 +105,7 @@ module AltCoverRunnerTests = visits.Add(" ", Dictionary()) let key = " " - - let v1 = - Counter.AddVisit(visits, key, 23, new Null()) - + let v1 = Counter.addVisit visits key 23 Null Assert.That(v1, Is.EqualTo 1) Assert.That(visits.Count, Is.EqualTo 1) Assert.That(visits.[key].Count, Is.EqualTo 1) @@ -130,7 +126,7 @@ module AltCoverRunnerTests = let payload = Time DateTime.UtcNow.Ticks let v2 = - Counter.AddVisit(visits, key, 23, payload) + Counter.addVisit visits key 23 payload Assert.That(v2, Is.EqualTo 1) Assert.That(visits.Count, Is.EqualTo 1) @@ -150,14 +146,11 @@ module AltCoverRunnerTests = visits.Add("key", Dictionary()) let key = " " - - let v3 = - Counter.AddVisit(visits, key, 23, new Null()) - + let v3 = Counter.addVisit visits key 23 Null Assert.That(v3, Is.EqualTo 1) let v4 = - Counter.AddVisit(visits, "key", 42, new Null()) + Counter.addVisit visits "key" 42 Null Assert.That(visits.Count, Is.EqualTo 2) Assert.That(v4, Is.EqualTo 1) @@ -172,15 +165,9 @@ module AltCoverRunnerTests = visits.Add(" ", Dictionary()) let key = " " - - let v5 = - Counter.AddVisit(visits, key, 23, new Null()) - + let v5 = Counter.addVisit visits key 23 Null Assert.That(v5, Is.EqualTo 1) - - let v6 = - Counter.AddVisit(visits, key, 42, new Null()) - + let v6 = Counter.addVisit visits key 42 Null Assert.That(v6, Is.EqualTo 1) Assert.That(visits.Count, Is.EqualTo 1) Assert.That(visits.[key].Count, Is.EqualTo 2) @@ -195,15 +182,9 @@ module AltCoverRunnerTests = visits.Add(" ", Dictionary()) let key = " " - - let v7 = - Counter.AddVisit(visits, key, 23, new Null()) - + let v7 = Counter.addVisit visits key 23 Null Assert.That(v7, Is.EqualTo 1) - - let v8 = - Counter.AddVisit(visits, key, 23, new Null()) - + let v8 = Counter.addVisit visits key 23 Null Assert.That(v8, Is.EqualTo 1) let x = visits.[key].[23] Assert.That(x.Count, Is.EqualTo 2) @@ -220,14 +201,11 @@ module AltCoverRunnerTests = let key = " " let payload = Time DateTime.UtcNow.Ticks - - let v9 = - Counter.AddVisit(visits, key, 23, new Null()) - + let v9 = Counter.addVisit visits key 23 Null Assert.That(v9, Is.EqualTo 1) let v10 = - Counter.AddVisit(visits, key, 23, payload) + Counter.addVisit visits key 23 payload Assert.That(v10, Is.EqualTo 1) let x = visits.[key].[23] @@ -247,8 +225,9 @@ module AltCoverRunnerTests = |> Seq.find _.EndsWith("Sample1WithOpenCover.xml", StringComparison.Ordinal) let internal init n l = - let mutable tmp = PointVisit.Create() - tmp.Count <- n + let tmp = + { PointVisit.Create() with Count = n } + tmp.Tracks.AddRange l tmp @@ -284,15 +263,14 @@ module AltCoverRunnerTests = item.Add("7C-CD-66-29-A3-6C-6D-5F-A7-65-71-0E-22-7D-B2-61-B5-1F-65-9A", payload) - Counter.I.UpdateReport( - ignore, - (fun _ _ -> ()), - true, - item, - ReportFormat.OpenCover, - worker, + Counter.I.updateReport + ignore + (fun _ _ -> ()) + true + item + ReportFormat.OpenCover + worker worker2 - ) |> ignore worker2.Position <- 0L @@ -2598,7 +2576,7 @@ module AltCoverRunnerTests = [ 0..9 ] |> Seq.iter (fun i -> for j = 1 to i + 1 do - hits.Add("f6e3edb3-fb20-44b3-817d-f69d1a22fc2f", i, new Null()) + hits.Add("f6e3edb3-fb20-44b3-817d-f69d1a22fc2f", i, Null) ignore j) let counts = @@ -2609,7 +2587,7 @@ module AltCoverRunnerTests = if counts.ContainsKey moduleId |> not then counts.Add(moduleId, Dictionary()) - AltCover.Counter.AddVisit(counts, moduleId, hitPointId, hit) + AltCover.Counter.addVisit counts moduleId hitPointId hit |> ignore) // degenerate case @@ -2708,11 +2686,11 @@ module AltCoverRunnerTests = stream.CopyTo worker - let tracks t : Track array = - [| Null() :> Track - Call(0) :> Track - Time(t) :> Track - Both(Pair.Create(t, 0)) |] + let tracks t = + [| Null + Call 0 + Time t + Both { Time = t; Call = 0 } |] let t0 = tracks 0L @@ -2732,7 +2710,7 @@ module AltCoverRunnerTests = if counts.ContainsKey moduleId |> not then counts.Add(moduleId, Dictionary()) - AltCover.Counter.AddVisit(counts, moduleId, hitPointId, hit) + AltCover.Counter.addVisit counts moduleId hitPointId hit |> ignore) let entries = Dictionary() @@ -2845,7 +2823,7 @@ module AltCoverRunnerTests = [ 0..9 ] |> Seq.iter (fun i -> for j = 1 to i + 1 do - hits.Add("f6e3edb3-fb20-44b3-817d-f69d1a22fc2f", i, new Null()) + hits.Add("f6e3edb3-fb20-44b3-817d-f69d1a22fc2f", i, Null) ignore j) let counts = @@ -2856,7 +2834,7 @@ module AltCoverRunnerTests = if counts.ContainsKey moduleId |> not then counts.Add(moduleId, Dictionary()) - AltCover.Counter.AddVisit(counts, moduleId, hitPointId, hit) + AltCover.Counter.addVisit counts moduleId hitPointId hit |> ignore) // degenerate case 1 @@ -3006,11 +2984,11 @@ module AltCoverRunnerTests = Zip.save (stream.CopyTo) reportFile true // fsharplint:disable-line - let tracks t : Track array = - [| Null() :> Track - Call(0) :> Track - Time(t) :> Track - Both(Pair.Create(t, 0)) |] + let tracks t = + [| Null + Call 0 + Time t + Both { Time = t; Call = 0 } |] let t0 = tracks 0L @@ -3030,7 +3008,7 @@ module AltCoverRunnerTests = if counts.ContainsKey moduleId |> not then counts.Add(moduleId, Dictionary()) - AltCover.Counter.AddVisit(counts, moduleId, hitPointId, hit) + AltCover.Counter.addVisit counts moduleId hitPointId hit |> ignore) let entries = Dictionary() @@ -3164,7 +3142,7 @@ module AltCoverRunnerTests = [ 0..9 ] |> Seq.iter (fun i -> for j = 1 to i + 1 do - hits.Add("f6e3edb3-fb20-44b3-817d-f69d1a22fc2f", i, new Null()) + hits.Add("f6e3edb3-fb20-44b3-817d-f69d1a22fc2f", i, Null) ignore j) let counts = @@ -3175,7 +3153,7 @@ module AltCoverRunnerTests = if counts.ContainsKey moduleId |> not then counts.Add(moduleId, Dictionary()) - AltCover.Counter.AddVisit(counts, moduleId, hitPointId, hit) + AltCover.Counter.addVisit counts moduleId hitPointId hit |> ignore) // degenerate case @@ -3278,11 +3256,11 @@ module AltCoverRunnerTests = stream.CopyTo worker - let tracks t : Track array = - [| Null() :> Track - Call(0) :> Track - Time(t) :> Track - Both(Pair.Create(t, 0)) |] + let tracks t = + [| Null + Call 0 + Time t + Both { Time = t; Call = 0 } |] let t0 = tracks 0L @@ -3302,7 +3280,7 @@ module AltCoverRunnerTests = if counts.ContainsKey moduleId |> not then counts.Add(moduleId, Dictionary()) - AltCover.Counter.AddVisit(counts, moduleId, hitPointId, hit) + AltCover.Counter.addVisit counts moduleId hitPointId hit |> ignore) let entries = Dictionary() @@ -3427,7 +3405,7 @@ module AltCoverRunnerTests = [ 0..9 ] |> Seq.iter (fun i -> for j = 1 to i + 1 do - hits.Add("f6e3edb3-fb20-44b3-817d-f69d1a22fc2f", i, new Null()) + hits.Add("f6e3edb3-fb20-44b3-817d-f69d1a22fc2f", i, Null) ignore j) let counts = @@ -3438,7 +3416,7 @@ module AltCoverRunnerTests = if counts.ContainsKey moduleId |> not then counts.Add(moduleId, Dictionary()) - AltCover.Counter.AddVisit(counts, moduleId, hitPointId, hit) + AltCover.Counter.addVisit counts moduleId hitPointId hit |> ignore) // degenerate case 1 @@ -3596,11 +3574,11 @@ module AltCoverRunnerTests = Zip.save (stream.CopyTo) reportFile true // fsharplint:disable-line - let tracks t : Track array = - [| Null() :> Track - Call(0) :> Track - Time(t) :> Track - Both(Pair.Create(t, 0)) |] + let tracks t = + [| Null + Call 0 + Time t + Both { Time = t; Call = 0 } |] let t0 = tracks 0L @@ -3620,7 +3598,7 @@ module AltCoverRunnerTests = if counts.ContainsKey moduleId |> not then counts.Add(moduleId, Dictionary()) - AltCover.Counter.AddVisit(counts, moduleId, hitPointId, hit) + AltCover.Counter.addVisit counts moduleId hitPointId hit |> ignore) let entries = Dictionary() @@ -3875,7 +3853,7 @@ module AltCoverRunnerTests = let formatter = System.Runtime.Serialization.DataContractSerializer( - typeof> + typeof> ) let r = @@ -3895,7 +3873,7 @@ module AltCoverRunnerTests = l |> List.mapi (fun i x -> - formatter.WriteObject(pipe, (x, i, DateTime.UtcNow)) + formatter.WriteObject(pipe, (x, i, Null, DateTime.UtcNow)) x) |> List.length) [ "a"; "b"; String.Empty; "c" ] @@ -3919,12 +3897,12 @@ module AltCoverRunnerTests = Path.Combine(where, Guid.NewGuid().ToString()) let payloads0 = - [ Null() :> Track - Call(17) :> Track - Time(23L) :> Track - Both(Pair.Create(5, 42)) :> Track - Time(42L) :> Track - Call(5) :> Track ] + [ Null + Call 17 + Time 23L + Both { Time = 5L; Call = 42 } + Time 42L + Call 5 ] let pv = init 42L (payloads0 |> List.tail) @@ -3933,9 +3911,7 @@ module AltCoverRunnerTests = table.Add("Extra", Dictionary()) table.["Extra"].Add(3, pv) - - let payloads = - ((Table table) :> Track) :: payloads0 + let payloads = (Table table) :: payloads0 let inputs = [ String.Empty @@ -3966,44 +3942,44 @@ module AltCoverRunnerTests = formatter.Write i match y with - | :? Null -> formatter.Write(Tag.Null |> byte) - | :? Time as t -> + | Null -> formatter.Write(Tag.Null |> byte) + | Time t -> formatter.Write(Tag.Time |> byte) - formatter.Write(t.Value) - | :? Call as t -> + formatter.Write(t) + | Call t -> formatter.Write(Tag.Call |> byte) - formatter.Write(t.Value) - | :? Both as b -> + formatter.Write(t) + | Both b -> formatter.Write(Tag.Both |> byte) - formatter.Write(b.Value.Time) - formatter.Write(b.Value.Call) - | :? Table as t -> + formatter.Write(b.Time) + formatter.Write(b.Call) + | Table t -> formatter.Write(Tag.Table |> byte) - t.Value.Keys + t.Keys |> Seq.iter (fun m -> formatter.Write m - formatter.Write t.Value.[m].Keys.Count + formatter.Write t.[m].Keys.Count - t.Value.[m].Keys + t.[m].Keys |> Seq.iter (fun p -> formatter.Write p - let v = t.Value.[m].[p] + let v = t.[m].[p] formatter.Write v.Count v.Tracks |> Seq.iter (fun tx -> match tx with - | :? Time as t -> + | Time t -> formatter.Write(Tag.Time |> byte) - formatter.Write(t.Value) - | :? Call as t -> + formatter.Write(t) + | Call t -> formatter.Write(Tag.Call |> byte) - formatter.Write(t.Value) - | :? Both as b -> + formatter.Write(t) + | Both b -> formatter.Write(Tag.Both |> byte) - formatter.Write(b.Value.Time) - formatter.Write(b.Value.Call) + formatter.Write(b.Time) + formatter.Write(b.Call) //| _ -> tx |> (sprintf "%A") |> Assert.Fail ) @@ -4036,7 +4012,7 @@ module AltCoverRunnerTests = let d = Dictionary() - d.Add(4, (0L, [ Both(Pair.Create(5, 42)) ])) + d.Add(4, (0L, [ Both { Time = 5L; Call = 42 } ])) let e = Dictionary() @@ -4083,12 +4059,12 @@ module AltCoverRunnerTests = let root = x.DocumentElement let hits = - [ Null() :> Track - Call(17) :> Track - Time(23L) :> Track - Both(Pair.Create(5, 42)) :> Track - Time(42L) :> Track - Time(5L) :> Track ] + [ Null + Call 17 + Time 23L + Both { Time = 5L; Call = 42 } + Time 42L + Time 5L ] Runner.J.pointProcess root hits @@ -5719,7 +5695,7 @@ module AltCoverRunnerTests = Assert.That(r, Is.EqualTo(0, 0, String.Empty)) let result = File.ReadAllText unique - //printfn "%s" result + printfn "%s" result let resource2 = Assembly @@ -5924,7 +5900,7 @@ module AltCoverRunnerTests = Assert.That(r, Is.EqualTo(0, 0, String.Empty)) let result = File.ReadAllText unique - //printfn "%s" result + printfn "%s" result let resource2 = Assembly diff --git a/AltCover.Tests/Tests.fs b/AltCover.Tests/Tests.fs index 24e4e4631..ed73bf739 100644 --- a/AltCover.Tests/Tests.fs +++ b/AltCover.Tests/Tests.fs @@ -3346,8 +3346,8 @@ module AltCoverTests = "set_CoverageFormat" "get_Sample" "set_Sample" - "get_Modules" - "set_Modules" + "get_modules" + "set_modules" "ToList" "#ctor" "#ctor" @@ -3401,8 +3401,8 @@ module AltCoverTests = "System.Void AltCover.Sample3.Class3+Class4.set_CoverageFormat(System.Int32)" "System.Int32 AltCover.Sample3.Class3+Class4.get_Sample()" "System.Void AltCover.Sample3.Class3+Class4.set_Sample(System.Int32)" - "System.String[] AltCover.Sample3.Class3+Class4.get_Modules()" - "System.Void AltCover.Sample3.Class3+Class4.set_Modules(System.String[])" + "System.String[] AltCover.Sample3.Class3+Class4.get_modules()" + "System.Void AltCover.Sample3.Class3+Class4.set_modules(System.String[])" "System.Collections.Generic.List`1 AltCover.Sample3.Class3+Class4.ToList(T)" "System.Void AltCover.Sample3.Class3+Class4.#ctor()" "System.String AltCover.Recorder.InstrumentationAttribute.get_Assembly()" diff --git a/AltCover.Tests/XTests.fs b/AltCover.Tests/XTests.fs index b740966f0..2bc99d5de 100644 --- a/AltCover.Tests/XTests.fs +++ b/AltCover.Tests/XTests.fs @@ -1427,7 +1427,7 @@ module AltCoverXTests = t1.GetNestedType("CallTrack", BindingFlags.NonPublic) let p = - t2.GetProperty("Value", BindingFlags.NonPublic ||| BindingFlags.Static) + t2.GetProperty("value", BindingFlags.NonPublic ||| BindingFlags.Static) let v = p.GetValue(nullObject) @@ -1435,7 +1435,7 @@ module AltCoverXTests = test <@ v.GetType() = typeof>> @> let m = - t2.GetMethod("Instance", BindingFlags.NonPublic ||| BindingFlags.Static) + t2.GetMethod("instance", BindingFlags.NonPublic ||| BindingFlags.Static) let v2 = m.Invoke(nullObject, [||]) diff --git a/AltCover.Visualizer.Tests/AltCover.Visualizer.Tests.fsproj b/AltCover.Visualizer.Tests/AltCover.Visualizer.Tests.fsproj index f650d4061..7e9837aab 100644 --- a/AltCover.Visualizer.Tests/AltCover.Visualizer.Tests.fsproj +++ b/AltCover.Visualizer.Tests/AltCover.Visualizer.Tests.fsproj @@ -14,7 +14,7 @@ TRACE;$(GlobalDefineConstants) - + 988 diff --git a/AltCover.sln b/AltCover.sln index 07440fce1..840107075 100644 --- a/AltCover.sln +++ b/AltCover.sln @@ -3,10 +3,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00 VisualStudioVersion = 17.0.31903.59 MinimumVisualStudioVersion = 15.0.26124.0 Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "AltCover.Engine", "AltCover.Engine\AltCover.Engine.fsproj", "{26C01B27-9A3E-4460-BB43-5383C8E818FB}" - ProjectSection(ProjectDependencies) = postProject - {5D4A7DFE-688D-4D1B-804C-A06743FFC4BC} = {5D4A7DFE-688D-4D1B-804C-A06743FFC4BC} - {79E50E5A-381F-4C9A-8F1D-3603CE9247BB} = {79E50E5A-381F-4C9A-8F1D-3603CE9247BB} - EndProjectSection EndProject Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "AltCover.PowerShell", "AltCover.PowerShell\AltCover.PowerShell.fsproj", "{208B8925-5626-4E5D-A00B-6A993D850524}" EndProject @@ -145,20 +141,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample0", "Samples\Sample0\ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample32", "Samples\Sample32\Sample32.csproj", "{349B2983-FB15-4D72-B7F6-04FD36C81B90}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AltCover.Async", "AltCover.Async\AltCover.Async.csproj", "{A81EDA11-9C1A-4BFA-9CC6-511C5447B167}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample25", "Samples\Sample25\Sample25.csproj", "{3349AD8B-577C-471D-93E7-E99D88CB883D}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AltCover.Recorder", "AltCover.Recorder\AltCover.Recorder.csproj", "{5D4A7DFE-688D-4D1B-804C-A06743FFC4BC}" -EndProject -Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "AltCover.Recorder.Tests", "AltCover.Recorder.Tests\AltCover.Recorder.Tests.fsproj", "{6DCDCA5E-3174-4C0B-996A-F7E4E455F889}" -EndProject -Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "AltCover.Recorder2.Tests", "AltCover.Recorder2.Tests\AltCover.Recorder2.Tests.fsproj", "{2079F388-81AE-4A76-9428-3C8D7F86825B}" - ProjectSection(ProjectDependencies) = postProject - {5D4A7DFE-688D-4D1B-804C-A06743FFC4BC} = {5D4A7DFE-688D-4D1B-804C-A06743FFC4BC} - EndProjectSection +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "AltCover.RecorderModern", "AltCover.RecorderModern\AltCover.RecorderModern.fsproj", "{219B0218-3289-44DD-9C22-6C14A3D7B5A7}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AltCover.Base", "AltCover.Base\AltCover.Base.csproj", "{79E50E5A-381F-4C9A-8F1D-3603CE9247BB}" +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "AltCover.RecorderModern.Tests", "AltCover.RecorderModern.Tests\AltCover.RecorderModern.Tests.fsproj", "{4B905582-3295-463B-A645-7FA6D0844035}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -361,43 +346,21 @@ Global {349B2983-FB15-4D72-B7F6-04FD36C81B90}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {349B2983-FB15-4D72-B7F6-04FD36C81B90}.Debug|Any CPU.Build.0 = Debug|Any CPU {349B2983-FB15-4D72-B7F6-04FD36C81B90}.Debug|x86.ActiveCfg = Debug|Any CPU + {349B2983-FB15-4D72-B7F6-04FD36C81B90}.Debug|x86.Build.0 = Debug|Any CPU {349B2983-FB15-4D72-B7F6-04FD36C81B90}.Release|Any CPU.ActiveCfg = Release|Any CPU {349B2983-FB15-4D72-B7F6-04FD36C81B90}.Release|Any CPU.Build.0 = Release|Any CPU {349B2983-FB15-4D72-B7F6-04FD36C81B90}.Release|x86.ActiveCfg = Release|Any CPU - {A81EDA11-9C1A-4BFA-9CC6-511C5447B167}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A81EDA11-9C1A-4BFA-9CC6-511C5447B167}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A81EDA11-9C1A-4BFA-9CC6-511C5447B167}.Debug|x86.ActiveCfg = Debug|Any CPU - {A81EDA11-9C1A-4BFA-9CC6-511C5447B167}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A81EDA11-9C1A-4BFA-9CC6-511C5447B167}.Release|Any CPU.Build.0 = Release|Any CPU - {A81EDA11-9C1A-4BFA-9CC6-511C5447B167}.Release|x86.ActiveCfg = Release|Any CPU - {3349AD8B-577C-471D-93E7-E99D88CB883D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {3349AD8B-577C-471D-93E7-E99D88CB883D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {3349AD8B-577C-471D-93E7-E99D88CB883D}.Debug|x86.ActiveCfg = Debug|Any CPU - {3349AD8B-577C-471D-93E7-E99D88CB883D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {3349AD8B-577C-471D-93E7-E99D88CB883D}.Release|Any CPU.Build.0 = Release|Any CPU - {3349AD8B-577C-471D-93E7-E99D88CB883D}.Release|x86.ActiveCfg = Release|Any CPU - {5D4A7DFE-688D-4D1B-804C-A06743FFC4BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5D4A7DFE-688D-4D1B-804C-A06743FFC4BC}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5D4A7DFE-688D-4D1B-804C-A06743FFC4BC}.Debug|x86.ActiveCfg = Debug|Any CPU - {5D4A7DFE-688D-4D1B-804C-A06743FFC4BC}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5D4A7DFE-688D-4D1B-804C-A06743FFC4BC}.Release|Any CPU.Build.0 = Release|Any CPU - {5D4A7DFE-688D-4D1B-804C-A06743FFC4BC}.Release|x86.ActiveCfg = Release|Any CPU - {6DCDCA5E-3174-4C0B-996A-F7E4E455F889}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6DCDCA5E-3174-4C0B-996A-F7E4E455F889}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6DCDCA5E-3174-4C0B-996A-F7E4E455F889}.Debug|x86.ActiveCfg = Debug|Any CPU - {6DCDCA5E-3174-4C0B-996A-F7E4E455F889}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6DCDCA5E-3174-4C0B-996A-F7E4E455F889}.Release|x86.ActiveCfg = Release|Any CPU - {2079F388-81AE-4A76-9428-3C8D7F86825B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2079F388-81AE-4A76-9428-3C8D7F86825B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2079F388-81AE-4A76-9428-3C8D7F86825B}.Debug|x86.ActiveCfg = Debug|Any CPU - {2079F388-81AE-4A76-9428-3C8D7F86825B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2079F388-81AE-4A76-9428-3C8D7F86825B}.Release|x86.ActiveCfg = Release|Any CPU - {79E50E5A-381F-4C9A-8F1D-3603CE9247BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {79E50E5A-381F-4C9A-8F1D-3603CE9247BB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {79E50E5A-381F-4C9A-8F1D-3603CE9247BB}.Debug|x86.ActiveCfg = Debug|Any CPU - {79E50E5A-381F-4C9A-8F1D-3603CE9247BB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {79E50E5A-381F-4C9A-8F1D-3603CE9247BB}.Release|Any CPU.Build.0 = Release|Any CPU - {79E50E5A-381F-4C9A-8F1D-3603CE9247BB}.Release|x86.ActiveCfg = Release|Any CPU + {349B2983-FB15-4D72-B7F6-04FD36C81B90}.Release|x86.Build.0 = Release|Any CPU + {219B0218-3289-44DD-9C22-6C14A3D7B5A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {219B0218-3289-44DD-9C22-6C14A3D7B5A7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {219B0218-3289-44DD-9C22-6C14A3D7B5A7}.Debug|x86.ActiveCfg = Debug|Any CPU + {219B0218-3289-44DD-9C22-6C14A3D7B5A7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {219B0218-3289-44DD-9C22-6C14A3D7B5A7}.Release|x86.ActiveCfg = Release|Any CPU + {4B905582-3295-463B-A645-7FA6D0844035}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4B905582-3295-463B-A645-7FA6D0844035}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4B905582-3295-463B-A645-7FA6D0844035}.Debug|x86.ActiveCfg = Debug|Any CPU + {4B905582-3295-463B-A645-7FA6D0844035}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4B905582-3295-463B-A645-7FA6D0844035}.Release|x86.ActiveCfg = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -426,7 +389,6 @@ Global {F56DE54A-ABD6-42F7-B61E-7BAFCCF2D787} = {97367D43-64EF-48E1-B6B4-D951C783E6E1} {19CE63CE-3622-409A-974D-3EA01388317E} = {2837CE07-B91F-4B8A-89B5-E7BE39A8F340} {349B2983-FB15-4D72-B7F6-04FD36C81B90} = {2837CE07-B91F-4B8A-89B5-E7BE39A8F340} - {3349AD8B-577C-471D-93E7-E99D88CB883D} = {2837CE07-B91F-4B8A-89B5-E7BE39A8F340} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {C31111CF-68A2-403F-9B06-9625FCBD48E3} diff --git a/Build/actions.fs b/Build/actions.fs index 92d37f5ff..b62592e3e 100644 --- a/Build/actions.fs +++ b/Build/actions.fs @@ -110,6 +110,9 @@ open System.Runtime.CompilerServices [] [] [] +[] +[] +[] [] #else [] @@ -124,11 +127,7 @@ using System.Runtime.CompilerServices; #if DEBUG [assembly: AssemblyConfiguration("Debug {0}")] -[assembly: InternalsVisibleTo("AltCover.Tests, PublicKey={1}")] -[assembly: InternalsVisibleTo("AltCover.Api.Tests, PublicKey={1}")] [assembly: InternalsVisibleTo("AltCover.Monitor.Tests, PublicKey={1}")] -[assembly: InternalsVisibleTo("AltCover.Recorder.Tests, PublicKey={1}")] -[assembly: InternalsVisibleTo("AltCover.Recorder2.Tests, PublicKey={1}")] #else [assembly: AssemblyConfiguration("Release {0}")] #endif""" diff --git a/Build/targets.fs b/Build/targets.fs index 9054eca17..82bc8692b 100644 --- a/Build/targets.fs +++ b/Build/targets.fs @@ -935,16 +935,15 @@ module Targets = printfn "%A" x reraise ()) + let BuildRecorder = + (fun () -> msbuildDebug MSBuildPath "./AltCover.Recorder.sln") + + let BuildReleaseRecorder = + (fun () -> msbuildRelease MSBuildPath "./AltCover.Recorder.sln") + let BuildDebug = (fun () -> Directory.ensure "./_SourceLink" - Directory.ensure "./_Repack" - - let repackdir = - ("./_Repack" |> Path.getFullName) - - Shell.cleanDir repackdir - Shell.copyFile "./_SourceLink/Class2.cs" "./Samples/Sample14/Sample14/Class2.txt" (if Environment.isWindows then @@ -956,39 +955,9 @@ module Targets = "./Samples/Sample14/Sample14/Class3.txt" // net20 and such - dotnetBuildRelease "./AltCover.Recorder/AltCover.Recorder.csproj" - dotnetBuildRelease "./AltCover.Async/AltCover.Async.csproj" - - Shell.copyFile - (Path.Join(repackdir, "AltCover.Async.dll")) - ("./_Binaries/AltCover.Async/Release+AnyCPU/net46/AltCover.Async.dll" - |> Path.getFullName) - - let ilrepack = - ("./packages/" - + (packageVersion "ILRepack") - + "/tools/ILRepack.exe") - |> Path.getFullName - - let keyfile = - "./Build/Infrastructure.snk" |> Path.getFullName - - let cmd = - [ "/keyfile:" + keyfile - "/ver:" - + (String.Join(".", VersionTemplate.Split('.') |> Seq.take 2)) - + ".0.0" - "/target:library" - "/targetplatform:v2" - "/internalize" - "/out:" - + Path.Join(repackdir, "AltCover.Recorder.dll") - "./_Binaries/AltCover.Recorder/Release+AnyCPU/net20/AltCover.Recorder.dll" - |> Path.getFullName - "./_Binaries/AltCover.Recorder/Release+AnyCPU/net20/ICSharpCode.SharpZipLib.dll" - |> Path.getFullName ] - - Actions.Run (ilrepack, ".", cmd) "ILRepack failed" + [ msbuildDebug MSBuildPath + msbuildRelease MSBuildPath ] + |> List.iter (fun f -> f "./AltCover.Recorder.sln") [ "./AltCover.sln" "./AltCover.Visualizer.sln" @@ -1140,8 +1109,7 @@ module Targets = Directory.ensure "./_Reports" [ ("./Build/common-rules.xml", - [ "_Binaries/AltCover.Engine/Debug+AnyCPU/netstandard2.0/AltCover.Engine.dll" - "_Binaries/AltCover.Base/Debug+AnyCPU/netstandard2.0/AltCover.Base.dll" ]) + [ "_Binaries/AltCover.Engine/Debug+AnyCPU/netstandard2.0/AltCover.Engine.dll" ]) ("./Build/build-rules.xml", [ "$Binaries/Setup/Debug+AnyCPU/net8.0/Setup.dll" "$Binaries/Build/Debug+AnyCPU/net8.0/Build.dll" ]) @@ -1407,8 +1375,7 @@ module Targets = defaultRules) (dixon, Option.get refdir, - [ "_Binaries/AltCover.Base/Debug+AnyCPU/netstandard2.0/AltCover.Base.dll" - "_Binaries/AltCover.Engine/Debug+AnyCPU/netstandard2.0/AltCover.Engine.dll" ], + [ "_Binaries/AltCover.Engine/Debug+AnyCPU/netstandard2.0/AltCover.Engine.dll" ], [], List.concat [ defaultRules @@ -1723,6 +1690,15 @@ module Targets = Actions.Run (nunitConsole, ".", recArgs) "Recorder NUnit failed" + let rec2Args = + [ "--noheader" + "--work=." + "--result=./_Reports/JustRecorder2UnitTestReport.xml" + Path.getFullName + "_Binaries/AltCover.Recorder.Tests/Debug+AnyCPU/net20/AltCover.Recorder.Tests.dll" ] + + Actions.Run (nunitConsole, ".", rec2Args) "Recorder NUnit failed" + with x -> printfn "%A" x reraise ()) @@ -1757,6 +1733,15 @@ module Targets = Actions.Run (nunitConsole, ".", recArgs) "Recorder NUnit failed" + let rec2Args = + [ "--noheader" + "--work=." + "--result=./_Reports/Recorder2UnitTestReport.xml" + Path.getFullName + "_Binaries/AltCover.Recorder.Tests/Debug+AnyCPU/net20/AltCover.Recorder.Tests.dll" ] + + Actions.Run (nunitConsole, ".", rec2Args) "Recorder NUnit failed" + with x -> printfn "%A" x reraise ()) @@ -1771,6 +1756,13 @@ module Targets = :: p.Properties DoRestore = true } + let msbuildDebug = doMSBuild withTagDebug + msbuildDebug MSBuildPath "./AltCover.Recorder.Tests/AltCover.Recorder.Tests.fsproj" + + msbuildDebug + MSBuildPath + "./AltCover.Recorder2.Tests/AltCover.Recorder2.Tests.fsproj" + let buildIt = DotNet.build (fun p -> { p.WithCommon dotnetOptions with @@ -1778,9 +1770,9 @@ module Targets = Framework = Some "net8.0" } |> (buildWithCLITaggedArguments "UnitTestDotNet")) - !!(@"./*Test*/*Tests.fsproj") |> Seq.iter buildIt - - !!(@"./*Test*/*Tests.csproj") |> Seq.iter buildIt + !!(@"./*Test*/*Tests.fsproj") + |> Seq.filter (_.Contains("Recorder") >> not) // net20 + |> Seq.iter buildIt !!(@"./*.Valid*/*Valid*.fsproj") |> Seq.iter buildIt) @@ -1821,10 +1813,16 @@ module Targets = :: p.Properties DoRestore = true } + let msbuildDebug = doMSBuild withTagDebug + + msbuildDebug MSBuildPath "./AltCover.Recorder.Tests/AltCover.Recorder.Tests.fsproj" + + msbuildDebug + MSBuildPath + "./AltCover.Recorder2.Tests/AltCover.Recorder2.Tests.fsproj" + [ Path.getFullName "./AltCover.Expecto.Tests/AltCover.Expecto.Tests.fsproj" Path.getFullName "./AltCover.Api.Tests/AltCover.Api.Tests.fsproj" - Path.getFullName "./AltCover.Recorder.Tests/AltCover.Recorder.Tests.fsproj" - Path.getFullName "./AltCover.Recorder2.Tests/AltCover.Recorder2.Tests.fsproj" //Path.getFullName "./AltCover.Monitor.Tests/AltCover.Monitor.Tests.fsproj" Path.getFullName "./AltCover.ValidateGendarmeEmulation/AltCover.ValidateGendarmeEmulation.fsproj" @@ -1949,6 +1947,9 @@ module Targets = let recorder4Files = !!(@"_Binaries/*Tests/Debug+AnyCPU/net472/*Recorder.Tests.dll") + let recorderFiles = + !!(@"_Binaries/*Tests/Debug+AnyCPU/net20/AltCover*Test*.dll") + let visualizerFiles = !!(@"_Binaries/AltCover.Visualizer.Tests/Debug+AnyCPU/net472/AltCover.Test*.dll") @@ -2003,6 +2004,24 @@ module Targets = (String.Join(" ", testFiles) + " --result=./_Reports/UnitTestWithOpenCoverReport.xml") + OpenCover.run + (fun p -> + { p with + WorkingDir = "." + ExePath = openCoverConsole + TestRunnerExePath = nunitConsole // OK, not on Linux + Filter = + "+[AltCover.Recorder]* +[AltCover.Recorder.Tests]* -[*]ICSharpCode.* -[*]System.* -[AltCover.*]*StartupCode*SolutionRoot" + MergeByHash = true + ReturnTargetCode = + Fake.DotNet.Testing.OpenCover.ReturnTargetCodeType.Yes + OptionalArguments = + "-excludebyattribute:*ExcludeFromCodeCoverageAttribute;*ProgIdAttribute" + Register = OpenCover.RegisterType.RegisterUser // Path64 doesn't work on my machine + Output = scoverage }) + (String.Join(" ", recorderFiles) + + " --result=./_Reports/RecorderTestWithOpenCoverReport.xml") + OpenCover.run (fun p -> { p with @@ -2106,7 +2125,8 @@ module Targets = apiDir (*; visDir ; monitorDir*) |] OutputDirectories = [| "./__UnitTestWithAltCover" - weakDir @@ "__VGEWithAltCover" + weakDir + @@ "__ValidateGendarmeEmulationWithAltCover" recorder4Dir @@ "__RecorderTestWithAltCover" apiDir @@ "__ApiTestWithAltCover" (*visDir @@ "__VisualizerTestWithAltCover"; monitorDir @@ "__MonitorTestWithAltCover"*) |] @@ -2144,9 +2164,8 @@ module Targets = Path.getFullName "_Binaries/AltCover.Api.Tests/Debug+AnyCPU/net472/__ApiTestWithAltCover/AltCover.Api.Tests.dll" Path.getFullName - "_Binaries/AltCover.ValidateGendarmeEmulation/Debug+AnyCPU/net472/__VGEWithAltCover/AltCover.ValidateGendarmeEmulation.dll" - Path.getFullName - "_Binaries/AltCover.Recorder.Tests/Debug+AnyCPU/net472/__RecorderTestWithAltCover/AltCover.Recorder.Tests.dll" + "_Binaries/AltCover.ValidateGendarmeEmulation/Debug+AnyCPU/net472/__ValidateGendarmeEmulationWithAltCover/AltCover.ValidateGendarmeEmulation.dll" + //Path.getFullName "_Binaries/AltCover.Recorder.Tests/Debug+AnyCPU/net472/__RecorderTestWithAltCover/AltCover.Recorder.Tests.dll" Path.getFullName "_Binaries/AltCover.Tests/Debug+AnyCPU/net472/__UnitTestWithAltCover/Sample2.dll" ] @@ -2155,6 +2174,90 @@ module Targets = printfn "UnitTestWithAltCover caught %A" x reraise () + printfn "Instrument the net20 Recorder tests" + + let recorderDir = + Path.getFullName "_Binaries/AltCover.Recorder.Tests/Debug+AnyCPU/net20" + + let recorderReport = + reports @@ "RecorderTestWithAltCover.xml" + + let prep = + AltCover.PrepareOptions.Primitive( + { Primitive.PrepareOptions.Create() with + Report = recorderReport + OutputDirectories = [| "./__RecorderTestWithAltCover" |] + StrongNameKey = shadowkeyfile + ReportFormat = "NCover" + InPlace = false + Save = false } + |> AltCoverFilter + ) + |> AltCoverCommand.Prepare + + { AltCoverCommand.Options.Create prep with + ToolPath = altcover + ToolType = frameworkAltcover + WorkingDirectory = recorderDir } + |> AltCoverCommand.run + + printfn "Execute the net20 Recorder tests" + + // !!("_Binaries/AltCover.Recorder.Tests/Debug+AnyCPU/net20/__RecorderTestWithAltCover/Alt*.Test*.dll") + // |> NUnitRetry + // (fun p -> + // { p with + // ToolPath = nunitConsole + // WorkingDir = "." }) + // "./_Reports/RecorderTestWithAltCoverReport.xml" + + let recArgs = + [ "--noheader" + "--work=." + "--result=./_Reports/RecorderTestWithAltCoverReport.xml" + Path.getFullName + "_Binaries/AltCover.Recorder.Tests/Debug+AnyCPU/net20/__RecorderTestWithAltCover/AltCover.Recorder.Tests.dll" ] + + Actions.Run (nunitConsole, ".", recArgs) "Recorder net20 NUnit failed" + + printfn "Instrument the net472 Recorder tests" + + let recorder472Dir = + Path.getFullName "_Binaries/AltCover.Recorder.Tests/Debug+AnyCPU/net472" + + let recorder472Report = + reports @@ "Recorder472TestWithAltCover.xml" + + let prep = + AltCover.PrepareOptions.Primitive( + { Primitive.PrepareOptions.Create() with + Report = recorder472Report + OutputDirectories = [| "./__Recorder472TestWithAltCover" |] + StrongNameKey = shadowkeyfile + ReportFormat = "NCover" + InPlace = false + Save = false } + |> AltCoverFilter + ) + |> AltCoverCommand.Prepare + + { AltCoverCommand.Options.Create prep with + ToolPath = altcover + ToolType = frameworkAltcover + WorkingDirectory = recorder472Dir } + |> AltCoverCommand.run + + printfn "Execute the net472 Recorder tests" + + let rec4Args = + [ "--noheader" + "--work=." + "--result=./_Reports/Recorder4TestWithAltCoverReport.xml" + Path.getFullName + "_Binaries/AltCover.Recorder.Tests/Debug+AnyCPU/net472/__Recorder472TestWithAltCover/AltCover.Recorder.Tests.dll" ] + + Actions.Run (nunitConsole, ".", rec4Args) "Recorder net472 NUnit failed" + ReportGenerator.generateReports (fun p -> { p with @@ -2163,7 +2266,9 @@ module Targets = [ ReportGenerator.ReportType.Html ReportGenerator.ReportType.XmlSummary ] TargetDir = "_Reports/_UnitTestWithAltCover" }) - [ altReport ] + [ altReport + recorderReport + recorder472Report ] uncovered @"_Reports/_UnitTestWithAltCover/Summary.xml" |> List.map fst @@ -2225,11 +2330,11 @@ module Targets = keyfile) (Path.getFullName "_Binaries/AltCover.ValidateGendarmeEmulation/Debug+AnyCPU/net472", - "./__VGEWithAltCoverRunner", + "./__ValidateGendarmeEmulationWithAltCoverRunner", "ValidateGendarmeEmulationWithAltCoverRunner.xml", "./_Reports/ValidateGendarmeEmulationWithAltCoverRunnerReport.xml", [ Path.getFullName - "_Binaries/AltCover.ValidateGendarmeEmulation/Debug+AnyCPU/net472/__VGEWithAltCoverRunner/AltCover.ValidateGendarmeEmulation.dll" ], + "_Binaries/AltCover.ValidateGendarmeEmulation/Debug+AnyCPU/net472/__ValidateGendarmeEmulationWithAltCoverRunner/AltCover.ValidateGendarmeEmulation.dll" ], // only use // (* >> (fun x -> { x with AssemblyExcludeFilter = TypeSafe.Filters [] }) *), AltCoverFilterXTypeSafe, keyfile) @@ -2240,6 +2345,19 @@ module Targets = [ Path.getFullName "_Binaries/AltCover.Recorder.Tests/Debug+AnyCPU/net472/__RecorderTestWithAltCoverRunner/AltCover.Recorder.Tests.dll" ], baseFilter, + shadowkeyfile) + (Path.getFullName "_Binaries/AltCover.Recorder.Tests/Debug+AnyCPU/net20", + "./__RecorderTest2WithAltCoverRunner", + "RecorderTest2WithAltCoverRunner.xml", + "./_Reports/RecorderTest2WithAltCoverRunnerReport.xml", + [ Path.getFullName + "_Binaries/AltCover.Recorder.Tests/Debug+AnyCPU/net20/__RecorderTest2WithAltCoverRunner/AltCover.Recorder.Tests.dll" ], + baseFilter + >> (fun p -> + { p with + AttributeFilter = + [ TypeSafe.Raw "EntryPoint" ] + |> p.AttributeFilter.Join }), shadowkeyfile) ] tests @@ -2614,11 +2732,23 @@ module Targets = AltCover.CollectOptions.Primitive <| Primitive.CollectOptions.Create() + if proj.Contains("Recorder") then + doMSBuild + (withDebug + >> fun p -> + { p with + Properties = + ("AltCoverTag", "UnitTestWithCoreRunner_") + :: p.Properties + Verbosity = Some MSBuildVerbosity.Minimal }) + MSBuildPath + newproj + DotNet.test (fun to' -> { to'.WithCommon(withWorkingDirectoryVM testdir) with Framework = Some "net8.0" - NoBuild = false } + NoBuild = proj.Contains("Recorder") } .WithAltCoverOptions prep coll @@ -3839,9 +3969,6 @@ module Targets = let altCover = Path.getFullName "_Binaries/AltCover/Release+AnyCPU/net472/AltCover.exe" - let abase = - Path.getFullName "_Binaries/AltCover/Release+AnyCPU/net472/AltCover.Base.dll" - let engine = Path.getFullName "_Binaries/AltCover/Release+AnyCPU/net472/AltCover.Engine.dll" @@ -3902,7 +4029,6 @@ module Targets = let applicationFiles = [ (altCover, Some "tools/net472", None) - (abase, Some "tools/net472", None) (engine, Some "tools/net472", None) (config, Some "tools/net472", None) (monitor, Some "lib/net20", None) @@ -3917,7 +4043,6 @@ module Targets = let apiFiles = [ (altCover, Some "lib/net472", None) - (abase, Some "lib/net472", None) (engine, Some "lib/net472", None) (config, Some "lib/net472", None) (monitor, Some "lib/net472", None) @@ -4488,8 +4613,7 @@ module Targets = ((packageVersionPart "PowerShellStandard.Library") + "System.Management.Automation.dll") - [ "AltCover.Base" - "AltCover.Cake" + [ "AltCover.Cake" "AltCover.DotNet" "AltCover.Engine" // beware static linkage -- maybe copy from debug? "AltCover.Monitor" @@ -4576,7 +4700,6 @@ module Targets = "AltCover.Monitor" "AltCover.Fake" "AltCover.Cake" - "AltCover.Base" "Recorder" "Mono" "DataCollector" @@ -5769,8 +5892,10 @@ module Targets = sprintf "Bad tracked method list %A" trackedFormat ) + //let trackedTimes = methods |> List.filter _.Value.TId.HasValue + // |> List.collect (fun m -> let first = m.Value.Entry |> List.iter (fun m -> let first = m.Value.Entry @@ -5789,7 +5914,10 @@ module Targets = test <@ from <= first @> test <@ first <= second @> test <@ second <= Actions.ticksNow () @>) - + // [first; second]) + // Assert.That + // (x.ToString().Replace("\r\n", "\n"), + // Is.EqualTo <| tracked.Replace("\r\n", "\n"))) ??? printfn "Tracked OK" let trackedVisits = @@ -8222,6 +8350,8 @@ module Targets = _Target "SetVersion" SetVersion _Target "Compilation" ignore _Target "BuildRelease" BuildRelease + _Target "BuildRecorder" BuildRecorder + _Target "BuildReleaseRecorder" BuildReleaseRecorder _Target "BuildDebug" BuildDebug _Target "BuildMonoSamples" BuildMonoSamples _Target "BuildSample31" BuildSample31 @@ -8313,6 +8443,9 @@ module Targets = "Preparation" ==> "BuildDebug" |> ignore + "BuildRecorder" ==> "JustRecorderUnitTest" + |> ignore + "BuildDebug" ==> "BuildRelease" ==> "Compilation" |> ignore diff --git a/Samples/Sample25/Library.fs b/Samples/Sample25/Library.fs new file mode 100644 index 000000000..da8734307 --- /dev/null +++ b/Samples/Sample25/Library.fs @@ -0,0 +1,43 @@ +namespace Sample25 + +module Say = + let hello name = printfn "Hello %s" name + +#if IDEMPOTENT_INSTRUMENT +[ - - Sample25 - False - net20 - - - 11.0 - True - - - - - - - - - \ No newline at end of file diff --git a/Samples/Sample25/Sample25.fsproj b/Samples/Sample25/Sample25.fsproj new file mode 100644 index 000000000..70a39c504 --- /dev/null +++ b/Samples/Sample25/Sample25.fsproj @@ -0,0 +1,32 @@ + + + + net20 + Sample25 + Sample25 + --keyfile:$(InfrastructureKey) + + + + TRACE + + + + TRACE;DEBUG;CODE_ANALYSIS + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Samples/Sample25/Say.cs b/Samples/Sample25/Say.cs deleted file mode 100644 index c112d60f2..000000000 --- a/Samples/Sample25/Say.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; - -namespace Sample25; - -public static class Say -{ - public static void Hello(string name) - { - Console.WriteLine("hello"); - } -} \ No newline at end of file diff --git a/Samples/Sample3/Class1.cs b/Samples/Sample3/Class1.cs index 6547b79a4..37333de0c 100644 --- a/Samples/Sample3/Class1.cs +++ b/Samples/Sample3/Class1.cs @@ -52,7 +52,7 @@ public List ToList(T item) public int Sample { get; set; } public Int64 Timer { get; set; } public bool Defer { get; set; } - public static string[] Modules { get; set; } + public static string[] modules { get; set; } } private static List> log = new List>(); diff --git a/rework failure list.txt b/rework failure list.txt deleted file mode 100644 index 7ecc9b049..000000000 --- a/rework failure list.txt +++ /dev/null @@ -1,28 +0,0 @@ -WindowsPowerShell, Pester -missing methods -Void AltCover.LCov.convertReport -XDocument AltCover.Cobertura.convertReport -Void AltCover.CoverageParameters.set_theReportFormat -Void AltCover.PostProcess.action -String AltCover.Json.xmlToJson - -UnitTestWithAltCoverCoreRunner - AltCover.Recorder -> C:\Users\email\Documents\Github\altcover\_Binaries\UnitTestWithCoreRunner_AltCover - .Recorder\Debug+AnyCPU\net46\AltCover.Recorder.dll -C:\Program Files\dotnet\sdk\8.0.303\FSharp\Microsoft.FSharp.Targets(332,9): error MSB6004: The specified -task executable location "C:\Program Files\dotnet\sdk\8.0.303\FSharp\fsc.exe" is invalid. [C:\Users\email -\Documents\Github\altcover\__AltCover.Recorder.Tests\AltCover.Recorder.Tests.fsproj::TargetFramework=net4 -72] -C:\Program Files\dotnet\sdk\8.0.303\FSharp\Microsoft.FSharp.Targets(332,9): error MSB6004: The specified -task executable location "C:\Program Files\dotnet\sdk\8.0.303\FSharp\fsc.exe" is invalid. [C:\Users\email -\Documents\Github\altcover\__AltCover.Recorder.Tests\AltCover.Recorder.Tests.fsproj::TargetFramework=net8 -.0] -Finished (Failed) 'ReplayUnitTestWithAltCoverCoreRunner' in 00:01:55.4040158 - - -Pester 00:00:00 (skipped) -Deployment 00:00:00 (skipped) -UnitTestWithAltCoverCoreRunner 00:00:00 (skipped) -UnitTest 00:00:00 (skipped) -BulkReport 00:00:00 (skipped) -All 00:00:00 (skipped)