public void InvalidDll_Throws() { var path = BaseDir.Combine("test.txt").WriteAllText("this is definitely not a valid dll"); File.Exists(path).ShouldBeTrue(); Should.Throw <PeVerifyException>(() => PeVerify.Verify(path)); }
public void MissingDll_Throws() { var badPath = GetType().Assembly.Location + ".xyzzy"; File.Exists(badPath).ShouldBeFalse(); Should.Throw <PeVerifyException>(() => PeVerify.Verify(badPath)); }
public void ValidDll_VerifiesClean() { var dllPath = typeof(TestAttribute).Assembly.Location; // pick nunit, why not File.Exists(dllPath).ShouldBeTrue(); Should.NotThrow(() => PeVerify.Verify(dllPath)); }
void Write(AssemblyDefinition assemblyToPatch, NPath assemblyToPatchPath, PatchOptions patchOptions = default) { // atomic write of file with backup // TODO: skip backup if existing file already patched. want the .orig to only be the unpatched file. // write to tmp and release the lock var tmpPath = assemblyToPatchPath.ChangeExtension(".tmp"); tmpPath.DeleteIfExists(); assemblyToPatch.Write(tmpPath); // $$$ , new WriterParameters { WriteSymbols = true }); see https://github.com/jbevain/cecil/issues/421 assemblyToPatch.Dispose(); // TODO: peverify obviously won't work with memory written streams. also needs all the dependencies. // solution is to create a temp folder, write the patched dll there as well as any of its direct dependencies, and run peverify if ((patchOptions & PatchOptions.SkipPeVerify) == 0) { PeVerify.Verify(tmpPath); } // move the actual file to backup, and move the tmp to actual var backupPath = ElevatedWeaver.GetPatchBackupPathFor(assemblyToPatchPath); File.Replace(tmpPath, assemblyToPatchPath, backupPath); }
protected NPath Compile(string testAssemblyName, string sourceCode, params string[] dependentAssemblyNames) { // prefix the assembly name because they are globally unique and don't want to ever collide var testAssemblyPath = BaseDir .Combine($"{TestContext.CurrentContext.GetFixtureName()}_{testAssemblyName}") .ChangeExtension(".dll"); // set up to compile var compiler = new Microsoft.CSharp.CSharpCodeProvider(); var compilerArgs = new CompilerParameters { OutputAssembly = testAssemblyPath, IncludeDebugInformation = true, CompilerOptions = "/o- /debug+ /warn:0" }; compilerArgs.ReferencedAssemblies.Add(typeof(int).Assembly.Location); // mscorlib // TODO: use typecache var assemblies = AppDomain.CurrentDomain .GetAssemblies() .Where(a => !a.IsDynamic) .ToDictionary(a => a.GetName().Name, a => a.Location.ToNPath(), StringComparer.OrdinalIgnoreCase); foreach (var dependentAssemblyName in dependentAssemblyNames) { // we may have already copied it in var path = BaseDir.Combine(dependentAssemblyName).ChangeExtension(".dll"); // if not, if (!path.Exists() && assemblies.TryGetValue(dependentAssemblyName, out path)) { path.Copy(BaseDir.Combine(path.FileName)); } compilerArgs.ReferencedAssemblies.Add(path); } // compile and handle errors var compilerResult = compiler.CompileAssemblyFromSource(compilerArgs, sourceCode); if (compilerResult.Errors.Count > 0) { var errorText = compilerResult.Errors .OfType <CompilerError>() .Select(e => $"({e.Line},{e.Column}): error {e.ErrorNumber}: {e.ErrorText}") .Prepend("Compiler errors:") .StringJoin("\n"); throw new Exception(errorText); } testAssemblyPath.ShouldBe(new NPath(compilerResult.PathToAssembly)); PeVerify.Verify(testAssemblyPath); // sanity check on what the compiler generated return(testAssemblyPath); }