Skip to content

Commit

Permalink
Unit test writing Mono built assemby
Browse files Browse the repository at this point in the history
  -- fix longtime bug in same as revealed by the test
  • Loading branch information
SteveGilham committed Dec 28, 2017
1 parent 0489634 commit f61f951
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 3 deletions.
4 changes: 2 additions & 2 deletions AltCover/Instrument.fs
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,8 @@ module Instrument =
let pkey = Mono.Cecil.WriterParameters()
pkey.WriteSymbols <- true
pkey.SymbolWriterProvider <- match Path.GetExtension (Option.getOrElse String.Empty (ProgramDatabase.GetPdbWithFallback assembly)) with
| ".mdb" -> Mono.Cecil.Mdb.MdbWriterProvider() :> ISymbolWriterProvider
| _ -> Mono.Cecil.Pdb.PdbWriterProvider() :> ISymbolWriterProvider
| ".pdb" -> Mono.Cecil.Pdb.PdbWriterProvider() :> ISymbolWriterProvider
| _ -> Mono.Cecil.Mdb.MdbWriterProvider() :> ISymbolWriterProvider
KnownKey assembly.Name
|> Option.iter (fun key -> pkey.StrongNameKeyPair <- key)
assembly.Write(path, pkey)
Expand Down
15 changes: 15 additions & 0 deletions Build/build.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,21 @@ Target "BuildMonoSamples" (fun _ ->
let symbols = System.IO.File.ReadAllBytes("./_Mono/Sample1/Sample1.exe.mdb")
mvid|> Array.iteri (fun i x -> symbols.[i+16] <- x)
System.IO.File.WriteAllBytes("./_Mono/Sample1/Sample1.exe.mdb", symbols)

ensureDirectory "./_Mono/Sample3"
let mcs = findToolInSubPath "mcs.exe" ".."
let result = ExecProcess (fun info -> info.FileName <- mcs
info.WorkingDirectory <- "."
info.Arguments <- (@"-target:library -debug -out:./_Mono/Sample3/Sample3.dll .\Sample3\Class1.cs")) (TimeSpan.FromMinutes 5.0)
if result <> 0 then failwith "Mono compilation failed"

// Fix up symbol file to have the MVId emitted by the System.Reflection.Emit code
let assembly = System.Reflection.Assembly.ReflectionOnlyLoadFrom (FullName "./_Mono/Sample3/Sample3.dll")
let mvid = assembly.ManifestModule.ModuleVersionId.ToByteArray();
let symbols = System.IO.File.ReadAllBytes("./_Mono/Sample3/Sample3.dll.mdb")
mvid|> Array.iteri (fun i x -> symbols.[i+16] <- x)
System.IO.File.WriteAllBytes("./_Mono/Sample3/Sample3.dll.mdb", symbols)

)

let SimpleInstrumentingRun (samplePath:string) (binaryPath:string) (reportSigil:string) =
Expand Down
49 changes: 48 additions & 1 deletion Tests/Tests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -998,6 +998,7 @@ type AltCoverTests() = class
Visitor.reportPath <- Some unique
let prepared = Instrument.PrepareAssembly path
Instrument.WriteAssembly prepared outputdll
Assert.That (File.Exists (outputdll.Replace(".dll",".pdb")))
let raw = Mono.Cecil.AssemblyDefinition.ReadAssembly outputdll
Assert.That raw.Name.HasPublicKey

Expand All @@ -1022,6 +1023,53 @@ type AltCoverTests() = class
finally
Visitor.keys.Clear()

[<Test>]
member self.ShouldWriteMonoAssemblyOK () =
try
Visitor.keys.Clear()
let where = Assembly.GetExecutingAssembly().Location
let path = Path.Combine(where.Substring(0, where.IndexOf("_Binaries")), "_Mono/Sample3/Sample3.dll")
let unique = Guid.NewGuid().ToString()
let output = Path.GetTempFileName()
let outputdll = output + ".dll"
let save = Visitor.reportPath
use stream = typeof<AltCover.Node>.Assembly.GetManifestResourceStream("AltCover.Recorder.snk")
use buffer = new MemoryStream()
stream.CopyTo(buffer)
let key = StrongNameKeyPair(buffer.ToArray())
Visitor.defaultStrongNameKey <- Some key
Visitor.Add key
try
Visitor.reportPath <- Some unique
let prepared = Instrument.PrepareAssembly path
let symbols = ProgramDatabase.GetPdbWithFallback prepared
Instrument.WriteAssembly prepared outputdll
Assert.That (File.Exists (outputdll + ".mdb"))
let raw = Mono.Cecil.AssemblyDefinition.ReadAssembly outputdll
Assert.That raw.Name.HasPublicKey

// Assert.That (Option.isSome <| Instrument.KnownKey raw.Name) <- not needed
let token' = String.Join(String.Empty, raw.Name.PublicKeyToken|> Seq.map (fun x -> x.ToString("x2")))
Assert.That (token', Is.EqualTo("4ebffcaabf10ce6a"))

let setup = AppDomainSetup()
setup.ApplicationBase <- Path.GetDirectoryName(where)
let ad = AppDomain.CreateDomain("ShouldGetNewFilePathFromPreparedAssembly", null, setup)
try
let proxyObject = ad.CreateInstanceFromAndUnwrap(typeof<ProxyObject>.Assembly.Location,"Tests.ProxyObject") :?> ProxyObject
proxyObject.InstantiateObject(outputdll,"Sample3.Class3+Class4",[||])
let report = proxyObject.InvokeMethod("get_ReportFile",[||]).ToString()
Assert.That (report, Is.EqualTo (Path.GetFullPath unique))
finally
AppDomain.Unload(ad)
finally
Visitor.reportPath <- save
File.Delete output
if File.Exists outputdll then File.Delete outputdll
finally
Visitor.keys.Clear()
Visitor.defaultStrongNameKey <- None

[<Test>]
member self.ShouldUpdateHandlerOK ([<Range(0,31)>] selection) =
let where = Assembly.GetExecutingAssembly().Location;
Expand Down Expand Up @@ -1097,7 +1145,6 @@ type AltCoverTests() = class
subject.SubstituteInstructionOperand i
Assert.That (i.Operand, Is.SameAs before))


// work around weird compiler error with array indexing
member private self.AsIArray (x:obj) (i:int)=
(x :?> Instruction[])
Expand Down

0 comments on commit f61f951

Please sign in to comment.