예제 #1
0
        private void SimpleSymlinkInputCheck(DateTime symlinkWriteTime, DateTime targetWriteTime,
                                             DateTime outputWriteTime, bool expectedOutOfDate)
        {
            var inputs = new List <string>();

            var outputs = new List <string>();

            string inputTarget  = "NONEXISTENT_FILE";
            string inputSymlink = "NONEXISTENT_FILE";
            string outputTarget = "NONEXISTENT_FILE";

            try
            {
                inputTarget = FileUtilities.GetTemporaryFile();
                _testOutputHelper.WriteLine($"Created input file {inputTarget}");
                File.SetLastWriteTime(inputTarget, targetWriteTime);

                inputSymlink = FileUtilities.GetTemporaryFile(null, ".linkin", createFile: false);

                if (!CreateSymbolicLink(inputSymlink, inputTarget, 0))
                {
                    Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
                }

                // File.SetLastWriteTime on the symlink sets the target write time,
                // so set the symlink's write time the hard way
                using (SafeFileHandle handle =
                           NativeMethodsShared.CreateFile(
                               inputSymlink, NativeMethodsShared.GENERIC_READ | 0x100 /* FILE_WRITE_ATTRIBUTES */,
                               NativeMethodsShared.FILE_SHARE_READ, IntPtr.Zero, NativeMethodsShared.OPEN_EXISTING,
                               NativeMethodsShared.FILE_ATTRIBUTE_NORMAL | NativeMethodsShared.FILE_FLAG_OPEN_REPARSE_POINT,
                               IntPtr.Zero))
                {
                    if (handle.IsInvalid)
                    {
                        Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
                    }

                    long symlinkWriteTimeTicks = symlinkWriteTime.ToFileTimeUtc();

                    if (!SetFileTime(handle, ref symlinkWriteTimeTicks, ref symlinkWriteTimeTicks,
                                     ref symlinkWriteTimeTicks))
                    {
                        Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
                    }
                }

                _testOutputHelper.WriteLine($"Created input link {inputSymlink}");

                outputTarget = FileUtilities.GetTemporaryFile();
                _testOutputHelper.WriteLine($"Created output file {outputTarget}");
                File.SetLastWriteTime(outputTarget, outputWriteTime);

                inputs.Add(inputSymlink);
                outputs.Add(outputTarget);


                DependencyAnalysisLogDetail detail;
                Assert.Equal(expectedOutOfDate,
                             TargetUpToDateChecker.IsAnyOutOfDate(out detail, Directory.GetCurrentDirectory(), inputs, outputs));
            }
            finally
            {
                if (File.Exists(inputTarget))
                {
                    File.Delete(inputTarget);
                }
                if (File.Exists(inputSymlink))
                {
                    File.Delete(inputSymlink);
                }
                if (File.Exists(outputTarget))
                {
                    File.Delete(outputTarget);
                }
            }
        }