コード例 #1
0
        public async Task CheckProcessTreeTimoutOnNestedChildProcessTimeoutWhenRootProcessExitedAsync()
        {
            var processInfo = CreateProcessInfoWithKextConnection(Operation.Echo("hi"));

            processInfo.NestedProcessTerminationTimeout = TimeSpan.FromMilliseconds(100);

            // Set the last enqueue time to now
            s_connection.MinReportQueueEnqueueTime = Sandbox.GetMachAbsoluteTime();

            var process = CreateAndStartSandboxedProcess(processInfo);
            var taskCancelationSource = new CancellationTokenSource();

            var time = Sandbox.GetMachAbsoluteTime();

            var childProcessPath = "/dummy/exe2";
            var instructions     = new List <ReportInstruction>()
            {
                new ReportInstruction()
                {
                    Process   = process,
                    Operation = FileOperation.OpProcessStart,
                    Stats     = new Sandbox.AccessReportStatistics()
                    {
                        EnqueueTime = time + ((ulong)TimeSpan.FromSeconds(1).Ticks * 100),
                        DequeueTime = time + ((ulong)TimeSpan.FromSeconds(2).Ticks * 100),
                    },
                    Pid     = 1235,
                    Path    = childProcessPath,
                    Allowed = true
                },
                new ReportInstruction()
                {
                    Process   = process,
                    Operation = FileOperation.OpProcessExit,
                    Stats     = new Sandbox.AccessReportStatistics()
                    {
                        EnqueueTime = time + ((ulong)TimeSpan.FromSeconds(3).Ticks * 100),
                        DequeueTime = time + ((ulong)TimeSpan.FromSeconds(4).Ticks * 100),
                    },
                    Pid     = process.ProcessId,
                    Path    = "/dummy/exe",
                    Allowed = true
                },
                new ReportInstruction()
                {
                    Process   = process,
                    Operation = FileOperation.OpKAuthCreateDir,
                    Stats     = new Sandbox.AccessReportStatistics()
                    {
                        EnqueueTime = time + ((ulong)TimeSpan.FromSeconds(5).Ticks * 100),
                        DequeueTime = time + ((ulong)TimeSpan.FromSeconds(6).Ticks * 100),
                    },
                    Pid     = 1235,
                    Path    = childProcessPath,
                    Allowed = true
                },
            };

            ContinouslyPostAccessReports(process, taskCancelationSource.Token, instructions);
            var result = await process.GetResultAsync();

            taskCancelationSource.Cancel();

            XAssert.IsTrue(result.Killed, "Expected process to have been killed");
            XAssert.IsFalse(result.TimedOut, "Didn't expect process to have timed out");
            XAssert.IsNotNull(result.SurvivingChildProcesses, "Expected surviving child processes");
            XAssert.IsTrue(result.SurvivingChildProcesses.Any(p => p.Path == childProcessPath),
                           $"Expected surviving child processes to contain {childProcessPath}; " +
                           $"instead it contains: {string.Join(", ", result.SurvivingChildProcesses.Select(p => p.Path))}");
        }
コード例 #2
0
ファイル: PipQueueTest.cs プロジェクト: SpellarBot/BuildXL
        public async Task Stress()
        {
            const int N              = 5;
            const int M              = N * N;
            var       context        = BuildXLContext.CreateInstanceForTesting();
            var       loggingContext = CreateLoggingContextForTest();
            var       pathTable      = context.PathTable;

            using (var tempFiles = new TempFileStorage(canGetFileNames: true))
            {
                var config = ConfigHelpers.CreateDefault(pathTable, tempFiles.GetUniqueFileName(), tempFiles);

                using (var pipTable = new PipTable(
                           context.PathTable,
                           context.SymbolTable,
                           initialBufferSize: 1024,
                           maxDegreeOfParallelism: (Environment.ProcessorCount + 2) / 3,
                           debug: false))
                {
                    var executionEnvironment = new PipQueueTestExecutionEnvironment(context, config, pipTable, GetSandboxedKextConnection());

                    Func <RunnablePip, Task <PipResult> > taskFactory = async(runnablePip) =>
                    {
                        PipResult result;
                        var       operationTracker = new OperationTracker(runnablePip.LoggingContext);
                        var       pip = runnablePip.Pip;
                        using (var operationContext = operationTracker.StartOperation(PipExecutorCounter.PipRunningStateDuration, pip.PipId, pip.PipType, runnablePip.LoggingContext))
                        {
                            result = await TestPipExecutor.ExecuteAsync(operationContext, executionEnvironment, pip);
                        }

                        executionEnvironment.MarkExecuted(pip);
                        return(result);
                    };

                    string       executable         = CmdHelper.OsShellExe;
                    FileArtifact executableArtifact = FileArtifact.CreateSourceFile(AbsolutePath.Create(pathTable, executable));

                    // This is the only file artifact we reference without a producer. Rather than scheduling a hashing pip, let's just invent one (so fingerprinting can succeed).
                    executionEnvironment.AddWellKnownFile(executableArtifact, WellKnownContentHashes.UntrackedFile);

                    using (var phase1PipQueue = new PipQueue(executionEnvironment.Configuration.Schedule))
                    {
                        // phase 1: create some files
                        var baseFileArtifacts = new List <FileArtifact>();
                        for (int i = 0; i < N; i++)
                        {
                            string       destination             = tempFiles.GetUniqueFileName();
                            AbsolutePath destinationAbsolutePath = AbsolutePath.Create(pathTable, destination);
                            FileArtifact destinationArtifact     = FileArtifact.CreateSourceFile(destinationAbsolutePath).CreateNextWrittenVersion();
                            baseFileArtifacts.Add(destinationArtifact);

                            PipData contents = PipDataBuilder.CreatePipData(
                                context.StringTable,
                                " ",
                                PipDataFragmentEscaping.CRuntimeArgumentRules,
                                i.ToString(CultureInfo.InvariantCulture));

                            var writeFile = new WriteFile(destinationArtifact, contents, WriteFileEncoding.Utf8, ReadOnlyArray <StringId> .Empty, PipProvenance.CreateDummy(context));
                            var pipId     = pipTable.Add((uint)(i + 1), writeFile);

                            var contentHash = ContentHashingUtilities.HashString(contents.ToString(pathTable));
                            executionEnvironment.AddExpectedWrite(writeFile, destinationArtifact, contentHash);

                            var runnable = RunnablePip.Create(loggingContext, executionEnvironment, pipId, pipTable.GetPipType(pipId), 0, taskFactory, 0);
                            runnable.Start(new OperationTracker(loggingContext), loggingContext);
                            runnable.SetDispatcherKind(DispatcherKind.IO);
                            phase1PipQueue.Enqueue(runnable);
                        }

                        phase1PipQueue.SetAsFinalized();
                        phase1PipQueue.DrainQueues();
                        await Task.WhenAll(
                            Enumerable.Range(0, 2).Select(
                                async range =>
                        {
                            using (var phase2PipQueue = new PipQueue(executionEnvironment.Configuration.Schedule))
                            {
                                // phase 2: do some more with those files
                                var pips         = new ConcurrentDictionary <PipId, Tuple <string, int> >();
                                var checkerTasks = new ConcurrentQueue <Task>();
                                Action <PipId, Task <PipResult> > callback =
                                    (id, task) =>
                                {
                                    XAssert.IsTrue(task.Status == TaskStatus.RanToCompletion);
                                    XAssert.IsFalse(task.Result.Status.IndicatesFailure());
                                    Tuple <string, int> t;
                                    if (!pips.TryRemove(id, out t))
                                    {
                                        XAssert.Fail();
                                    }

                                    checkerTasks.Enqueue(
                                        Task.Run(
                                            () =>
                                    {
                                        string actual = File.ReadAllText(t.Item1).Trim();

                                        // TODO: Make this async
                                        XAssert.AreEqual(actual, t.Item2.ToString());
                                    }));
                                };
                                var r = new Random(0);
                                for (int i = 0; i < M; i++)
                                {
                                    int sourceIndex             = r.Next(baseFileArtifacts.Count);
                                    FileArtifact sourceArtifact = baseFileArtifacts[sourceIndex];

                                    string destination = tempFiles.GetUniqueFileName();
                                    AbsolutePath destinationAbsolutePath = AbsolutePath.Create(pathTable, destination);
                                    FileArtifact destinationArtifact     = FileArtifact.CreateSourceFile(destinationAbsolutePath).CreateNextWrittenVersion();
                                    Pip pip;

                                    DispatcherKind queueKind;
                                    switch (r.Next(2))
                                    {
                                    case 0:
                                        pip       = new CopyFile(sourceArtifact, destinationArtifact, ReadOnlyArray <StringId> .Empty, PipProvenance.CreateDummy(context));
                                        queueKind = DispatcherKind.IO;
                                        executionEnvironment.AddExpectedWrite(pip, destinationArtifact, executionEnvironment.GetExpectedContent(sourceArtifact));
                                        break;

                                    case 1:
                                        string workingDirectory =
                                            OperatingSystemHelper.IsUnixOS ? "/tmp" :
                                            Environment.GetFolderPath(Environment.SpecialFolder.Windows);

                                        AbsolutePath workingDirectoryAbsolutePath = AbsolutePath.Create(pathTable, workingDirectory);

                                        var pipData = OperatingSystemHelper.IsUnixOS ?
                                                      PipDataBuilder.CreatePipData(pathTable.StringTable, " ", PipDataFragmentEscaping.CRuntimeArgumentRules, "-c", "'", "cp", sourceArtifact, destinationArtifact, "'") :
                                                      PipDataBuilder.CreatePipData(pathTable.StringTable, " ", PipDataFragmentEscaping.CRuntimeArgumentRules, "/d", "/c", "copy", "/B", sourceArtifact, destinationArtifact);

                                        queueKind = DispatcherKind.CPU;
                                        pip       = new Process(
                                            executableArtifact,
                                            workingDirectoryAbsolutePath,
                                            pipData,
                                            FileArtifact.Invalid,
                                            PipData.Invalid,
                                            ReadOnlyArray <EnvironmentVariable> .Empty,
                                            FileArtifact.Invalid,
                                            FileArtifact.Invalid,
                                            FileArtifact.Invalid,
                                            tempFiles.GetUniqueDirectory(pathTable),
                                            null,
                                            null,
                                            ReadOnlyArray <FileArtifact> .FromWithoutCopy(executableArtifact, sourceArtifact),
                                            ReadOnlyArray <FileArtifactWithAttributes> .FromWithoutCopy(destinationArtifact.WithAttributes()),
                                            ReadOnlyArray <DirectoryArtifact> .Empty,
                                            ReadOnlyArray <DirectoryArtifact> .Empty,
                                            ReadOnlyArray <PipId> .Empty,
                                            ReadOnlyArray <AbsolutePath> .From(CmdHelper.GetCmdDependencies(pathTable)),
                                            ReadOnlyArray <AbsolutePath> .From(CmdHelper.GetCmdDependencyScopes(pathTable)),
                                            ReadOnlyArray <StringId> .Empty,
                                            ReadOnlyArray <int> .Empty,
                                            ReadOnlyArray <ProcessSemaphoreInfo> .Empty,
                                            provenance: PipProvenance.CreateDummy(context),
                                            toolDescription: StringId.Invalid,
                                            additionalTempDirectories: ReadOnlyArray <AbsolutePath> .Empty);
                                        executionEnvironment.AddExpectedWrite(pip, destinationArtifact, executionEnvironment.GetExpectedContent(sourceArtifact));
                                        break;

                                    default:
                                        Contract.Assert(false);
                                        continue;
                                    }

                                    var pipId = pipTable.Add((uint)((range *M) + N + i + 1), pip);

                                    Func <RunnablePip, Task> taskFactoryWithCallback = async(runnablePip) =>
                                    {
                                        var task      = taskFactory(runnablePip);
                                        var pipResult = await task;
                                        callback(pipId, task);
                                    };

                                    var runnable = RunnablePip.Create(loggingContext, executionEnvironment, pipId, pipTable.GetPipType(pipId), 0, taskFactoryWithCallback, 0);
                                    runnable.Start(new OperationTracker(loggingContext), loggingContext);
                                    runnable.SetDispatcherKind(queueKind);
                                    phase2PipQueue.Enqueue(runnable);

                                    if (!pips.TryAdd(pipId, Tuple.Create(destination, sourceIndex)))
                                    {
                                        Contract.Assert(false);
                                    }
                                }

                                phase2PipQueue.SetAsFinalized();
                                phase2PipQueue.DrainQueues();
                                XAssert.AreEqual(0, pips.Count);
                                await Task.WhenAll(checkerTasks);
                            }
                        }));
                    }
                }
            }
        }
コード例 #3
0
        public async Task CheckProcessTreeTimoutOnNestedChildProcessTimeoutWhenRootProcessExitedAsync()
        {
            var processInfo = CreateProcessInfoWithSandboxConnection(Operation.Echo("hi"));

            processInfo.NestedProcessTerminationTimeout = TimeSpan.FromMilliseconds(10);

            // Set the last enqueue time to now
            s_connection.MinReportQueueEnqueueTime = Sandbox.GetMachAbsoluteTime();

            using (var process = CreateAndStartSandboxedProcess(processInfo))
            {
                var time             = s_connection.MinReportQueueEnqueueTime;
                var childProcessPath = "/dummy/exe2";
                var childProcessPid  = process.ProcessId + 1;

                // first post some reports indicating that
                //   - a child process was spawned
                //   - the main process exited
                // (not posting that the child process exited)
                var postTask1 = GetContinuouslyPostAccessReportsTask(process, new List <ReportInstruction>
                {
                    new ReportInstruction()
                    {
                        Process   = process,
                        Operation = FileOperation.OpProcessStart,
                        Stats     = new Sandbox.AccessReportStatistics()
                        {
                            EnqueueTime = time + ((ulong)TimeSpan.FromMilliseconds(100).Ticks * 100),
                            DequeueTime = time + ((ulong)TimeSpan.FromMilliseconds(200).Ticks * 100),
                        },
                        Pid     = childProcessPid,
                        Path    = childProcessPath,
                        Allowed = true
                    },
                    new ReportInstruction()
                    {
                        Process   = process,
                        Operation = FileOperation.OpProcessExit,
                        Stats     = new Sandbox.AccessReportStatistics()
                        {
                            EnqueueTime = time + ((ulong)TimeSpan.FromMilliseconds(300).Ticks * 100),
                            DequeueTime = time + ((ulong)TimeSpan.FromMilliseconds(400).Ticks * 100),
                        },
                        Pid     = process.ProcessId,
                        Path    = "/dummy/exe",
                        Allowed = true
                    },
                    new ReportInstruction()
                    {
                        Process   = process,
                        Operation = FileOperation.OpKAuthCreateDir,
                        Stats     = new Sandbox.AccessReportStatistics()
                        {
                            EnqueueTime = time + ((ulong)TimeSpan.FromMilliseconds(500).Ticks * 100),
                            DequeueTime = time + ((ulong)TimeSpan.FromMilliseconds(600).Ticks * 100),
                        },
                        Pid     = childProcessPid,
                        Path    = childProcessPath,
                        Allowed = true
                    },
                });

                // SandboxedProcessMac should decide to kill the process because its child survived;
                // when it does that, it will call this callback.  When that happens, we must post
                // OpProcessTreeCompleted because SandboxedProcessMac will keep waiting for it.
                s_connection.ProcessTerminated += (pipId, pid) =>
                {
                    postTask1.GetAwaiter().GetResult();
                    ContinuouslyPostAccessReports(process, new List <ReportInstruction>
                    {
                        new ReportInstruction()
                        {
                            Process   = process,
                            Operation = FileOperation.OpProcessTreeCompleted,
                            Stats     = new Sandbox.AccessReportStatistics()
                            {
                                EnqueueTime = time + ((ulong)TimeSpan.FromMilliseconds(900).Ticks * 100),
                                DequeueTime = time + ((ulong)TimeSpan.FromMilliseconds(1000).Ticks * 100),
                            },
                            Pid     = process.ProcessId,
                            Path    = "/dummy/exe",
                            Allowed = true
                        }
                    });
                };

                var result = await process.GetResultAsync();

                await postTask1; // await here as well just to make AsyncFixer happy

                XAssert.IsTrue(result.Killed, "Expected process to have been killed");
                XAssert.IsFalse(result.TimedOut, "Didn't expect process to have timed out");
                XAssert.IsNotNull(result.SurvivingChildProcesses, "Expected surviving child processes");
                XAssert.IsTrue(result.SurvivingChildProcesses.Any(p => p.Path == childProcessPath),
                               $"Expected surviving child processes to contain {childProcessPath}; " +
                               $"instead it contains: {string.Join(", ", result.SurvivingChildProcesses.Select(p => p.Path))}");
            }
        }
コード例 #4
0
        private void AssertDirectoryEmpty(string directoryPath)
        {
            DirectoryInfo di = new DirectoryInfo(directoryPath);

            XAssert.IsFalse(di.EnumerateFileSystemInfos().Any(), "Directory was not cleaned");
        }
コード例 #5
0
        public void TryCreate()
        {
            var          pt = new PathTable();
            AbsolutePath p;

            XAssert.IsTrue(AbsolutePath.TryCreate(pt, @"C:\AAA\CCC", out p));
            XAssert.AreEqual(@"C:\AAA\CCC", p.ToString(pt));
            XAssert.IsTrue(AbsolutePath.TryCreate(pt, @"C:\..", out p));
            XAssert.AreEqual(@"C:\", p.ToString(pt));
            XAssert.IsTrue(AbsolutePath.TryCreate(pt, @"C:\..\..\..\..", out p));
            XAssert.AreEqual(@"C:\", p.ToString(pt));
            XAssert.IsTrue(AbsolutePath.TryCreate(pt, @"C:\a\..\b.txt", out p));
            XAssert.AreEqual(@"C:\b.txt", p.ToString(pt));
            XAssert.IsTrue(AbsolutePath.TryCreate(pt, @"C:\a\..\..\..\..\b.txt", out p));
            XAssert.AreEqual(@"C:\b.txt", p.ToString(pt));


            XAssert.IsFalse(AbsolutePath.TryCreate(pt, @"C\::AAA", out p));
            XAssert.IsFalse(AbsolutePath.TryCreate(pt, @"AAA:", out p));
            XAssert.IsFalse(AbsolutePath.TryCreate(pt, @":AAA", out p));
            XAssert.IsFalse(AbsolutePath.TryCreate(pt, @"..", out p));
            XAssert.IsFalse(AbsolutePath.TryCreate(pt, @".", out p));
            XAssert.IsFalse(AbsolutePath.TryCreate(pt, @"C:\:", out p));
            XAssert.IsFalse(AbsolutePath.TryCreate(pt, @"1:\", out p));

            p = AbsolutePath.Create(pt, @"C:/");
            XAssert.AreEqual(@"C:\", p.ToString(pt));

            p = AbsolutePath.Create(pt, @"C:\");
            XAssert.AreEqual(@"C:\", p.ToString(pt));

            p = AbsolutePath.Create(pt, @"C:\.");
            XAssert.AreEqual(@"C:\", p.ToString(pt));

            p = AbsolutePath.Create(pt, @"C:\BBB");
            XAssert.AreEqual(@"C:\BBB", p.ToString(pt));

            p = AbsolutePath.Create(pt, @"C:\BBB\.");
            XAssert.AreEqual(@"C:\BBB", p.ToString(pt));

            p = AbsolutePath.Create(pt, @"C:\BBB\..");
            XAssert.AreEqual(@"C:\", p.ToString(pt));

            p = AbsolutePath.Create(pt, @"C:\BBB\CCC\..");
            XAssert.AreEqual(@"C:\BBB", p.ToString(pt));

            // now test out UNC paths
            XAssert.IsTrue(AbsolutePath.TryCreate(pt, @"\\srv\AAA\CCC", out p));
            XAssert.AreEqual(@"\\srv\AAA\CCC", p.ToString(pt));

            XAssert.IsFalse(AbsolutePath.TryCreate(pt, @"\\srv\..", out p));
            XAssert.IsFalse(AbsolutePath.TryCreate(pt, @"\\srv\..\..", out p));
            XAssert.IsFalse(AbsolutePath.TryCreate(pt, @"\\srv\:", out p));

            p = AbsolutePath.Create(pt, @"\\srv\");
            XAssert.AreEqual(@"\\srv", p.ToString(pt));

            p = AbsolutePath.Create(pt, @"\\srv\.");
            XAssert.AreEqual(@"\\srv", p.ToString(pt));

            p = AbsolutePath.Create(pt, @"\\srv\BBB");
            XAssert.AreEqual(@"\\srv\BBB", p.ToString(pt));

            p = AbsolutePath.Create(pt, @"\\srv\BBB\.");
            XAssert.AreEqual(@"\\srv\BBB", p.ToString(pt));

            p = AbsolutePath.Create(pt, @"\\srv\BBB\..");
            XAssert.AreEqual(@"\\srv", p.ToString(pt));

            p = AbsolutePath.Create(pt, @"\\srv\BBB\CCC\..");
            XAssert.AreEqual(@"\\srv\BBB", p.ToString(pt));
        }
コード例 #6
0
        public void MissAugmentedWeakFingerprintIsClassifiedAsPathSetMissButAlwaysPostCacheExecution()
        {
            Configuration.Cache.AugmentWeakFingerprintPathSetThreshold = 2;

            var directory  = CreateUniqueDirectoryArtifact();
            var sourceFile = CreateSourceFile(directory.Path);
            var readFileA  = CreateSourceFile(directory.Path);
            var readFileB  = CreateSourceFile(directory.Path);
            var readFileC  = CreateSourceFile(directory.Path);
            var readFileD  = CreateSourceFile(directory.Path);

            var sealedDirectory = CreateAndScheduleSealDirectoryArtifact(
                directory.Path,
                global::BuildXL.Pips.Operations.SealDirectoryKind.SourceAllDirectories);

            var builder = CreatePipBuilder(new[]
            {
                Operation.ReadFileFromOtherFile(sourceFile, doNotInfer: true),
                Operation.WriteFile(CreateOutputFileArtifact())
            });

            builder.AddInputDirectory(sealedDirectory);
            var process = SchedulePipBuilder(builder).Process;

            // Pip will read file source and file A.
            // Two-phase cache will contain mapping
            //     wp => (#{source, A}, sp1)
            File.WriteAllText(ArtifactToString(sourceFile), ArtifactToString(readFileA));
            RunScheduler().AssertCacheMiss(process.PipId);

            // Pip will read file source and file B.
            // Two-phase cache will contain mapping
            //     wp => (#{source, B}, sp2), (#{source, A}, sp1)
            File.WriteAllText(ArtifactToString(sourceFile), ArtifactToString(readFileB));
            RunScheduler().AssertCacheMiss(process.PipId);

            // Pip will read file source and file C.
            // Two-phase cache will contain mappings
            //     wp      => (#{source}, aug_marker), (#{source, B}, sp2), (#{source, A}, sp1)
            //     aug_wp1 => (#{source, C}, sp3)
            //
            // Fingerprint store contains mapping
            //     pip  => (wp, #{source, C}, sp3)
            File.WriteAllText(ArtifactToString(sourceFile), ArtifactToString(readFileC));
            var result = RunScheduler().AssertCacheMiss(process.PipId);

            // Modify source to point to file D.
            File.WriteAllText(ArtifactToString(sourceFile), ArtifactToString(readFileD));

            RunScheduler(m_testHooks).AssertCacheMiss(process.PipId);

            XAssert.IsTrue(m_testHooks.FingerprintStoreTestHooks.TryGetCacheMiss(process.PipId, out var cacheMiss));
            XAssert.AreEqual(CacheMissAnalysisResult.PathSetHashMismatch, cacheMiss.DetailAndResult.Result);

            // Cache miss analysis wasn't performed post cache look-up because at that time
            // fingerprint store has "pip => (wp, #{source, C}, sp3)" mapping, and none of
            // the strong fingerprint computation data has #{source, C} as pathset hash.
            // Note that the list of strong fingerprint computation data won't include #{source, C}
            // form aug_wp1 mapping because of miss augmented weak fingerprint.
            XAssert.IsFalse(cacheMiss.IsFromCacheLookUp);
        }
コード例 #7
0
        public void ReportedFileAccessCreate()
        {
            var          pathTable = new PathTable();
            AbsolutePath file1     = AbsolutePath.Create(pathTable, A("t", "file1.txt"));

            var process = new ReportedProcess(0, string.Empty);

            ReportedFileAccess rfa1 = ReportedFileAccess.Create(
                ReportedFileOperation.CreateFile,
                process,
                RequestedAccess.Read,
                FileAccessStatus.Allowed,
                true,
                0,
                ReportedFileAccess.NoUsn,
                DesiredAccess.GENERIC_READ,
                ShareMode.FILE_SHARE_NONE,
                CreationDisposition.OPEN_ALWAYS,
                FlagsAndAttributes.FILE_ATTRIBUTE_NORMAL,
                file1);

            XAssert.AreEqual(rfa1.Status, FileAccessStatus.Allowed);
            XAssert.AreEqual(rfa1.ManifestPath, file1);
            XAssert.AreEqual(rfa1.Path, null);
            XAssert.AreEqual(A("t", "file1.txt"), rfa1.GetPath(pathTable));
            XAssert.AreEqual(rfa1.OpenedFileOrDirectoryAttributes, (FlagsAndAttributes)FlagsAndAttributesConstants.InvalidFileAttributes);
            XAssert.IsFalse(rfa1.IsOpenedHandleDirectory());

            ReportedFileAccess rfa2 = ReportedFileAccess.Create(
                ReportedFileOperation.CreateFile,
                process,
                RequestedAccess.Read,
                FileAccessStatus.CannotDeterminePolicy,
                true,
                0,
                new Usn(0),
                DesiredAccess.GENERIC_READ,
                ShareMode.FILE_SHARE_NONE,
                CreationDisposition.OPEN_ALWAYS,
                FlagsAndAttributes.FILE_ATTRIBUTE_NORMAL,
                FlagsAndAttributes.FILE_ATTRIBUTE_DIRECTORY,
                pathTable,
                A("t", "file1.txt"));

            XAssert.AreEqual(rfa2.Status, FileAccessStatus.CannotDeterminePolicy);
            XAssert.AreEqual(rfa2.ManifestPath, file1);
            XAssert.AreEqual(rfa2.Path, null);
            XAssert.AreEqual(A("t", "file1.txt"), rfa2.GetPath(pathTable));
            XAssert.AreEqual(rfa2.OpenedFileOrDirectoryAttributes, FlagsAndAttributes.FILE_ATTRIBUTE_DIRECTORY);
            XAssert.IsTrue(rfa2.IsOpenedHandleDirectory());

            ReportedFileAccess rfa3 = ReportedFileAccess.Create(
                ReportedFileOperation.CreateFile,
                process,
                RequestedAccess.Read,
                FileAccessStatus.Denied,
                true,
                0,
                ReportedFileAccess.NoUsn,
                DesiredAccess.GENERIC_READ,
                ShareMode.FILE_SHARE_NONE,
                CreationDisposition.OPEN_ALWAYS,
                FlagsAndAttributes.FILE_ATTRIBUTE_NORMAL,
                FlagsAndAttributes.FILE_ATTRIBUTE_NORMAL,
                pathTable,
                A("t", "file2.txt"));

            XAssert.AreEqual(rfa3.Status, FileAccessStatus.Denied);
            XAssert.AreEqual(rfa3.ManifestPath, AbsolutePath.Invalid);
            XAssert.AreEqual(rfa3.Path, A("t", "file2.txt"));
            XAssert.AreEqual(A("t", "file2.txt"), rfa3.GetPath(pathTable));
            XAssert.AreEqual(rfa3.OpenedFileOrDirectoryAttributes, FlagsAndAttributes.FILE_ATTRIBUTE_NORMAL);
            XAssert.IsFalse(rfa3.IsOpenedHandleDirectory());
        }
コード例 #8
0
ファイル: Program.cs プロジェクト: microsoft/BuildXL
        private static async Task <bool> CreateAndRunPip(
            PipProgram program,
            string tempDirectory,
            string outFile,
            IEnumerable <string> restInstructions,
            bool is64Bit)
        {
            Contract.Requires(restInstructions != null);
            Contract.Requires(tempDirectory != null);
            Contract.Requires(!string.IsNullOrEmpty(outFile));

            BuildXLContext context = BuildXLContext.CreateInstanceForTesting();

            using (var fileAccessListener = new FileAccessListener(Events.Log))
            {
                fileAccessListener.RegisterEventSource(BuildXL.Processes.ETWLogger.Log);

                var loggingContext   = BuildXLTestBase.CreateLoggingContextForTest();
                var fileContentTable = FileContentTable.CreateNew(loggingContext);
                var config           = ConfigurationHelpers.GetDefaultForTesting(context.PathTable, AbsolutePath.Create(context.PathTable, Path.Combine(tempDirectory, "config.dc")));
                config.Sandbox.LogObservedFileAccesses = true;

                Pip pip = null;

                var instructions = restInstructions as string[] ?? restInstructions.ToArray();

                switch (program)
                {
                case PipProgram.Cmd:
                    pip = CreateCmdPip(context, tempDirectory, outFile, is64Bit);
                    break;

                case PipProgram.Self:
                    pip = CreateSelfPip(context, tempDirectory, outFile, instructions, is64Bit);
                    break;
                }

                Contract.Assume(pip != null);

                var isSubstUsed = FileUtilities.TryGetSubstSourceAndTarget(tempDirectory, out var substSource, out var substTarget, out var errorMessage);
                XAssert.IsFalse(!isSubstUsed && errorMessage != null, errorMessage);

                PipResult executeResult = await Execute(
                    context,
                    fileContentTable,
                    config,
                    pip,
                    isSubstUsed
                    ?(substSource, substTarget)
                    : default((string, string)?));

                bool valid = false;

                switch (program)
                {
                case PipProgram.Cmd:
                    valid = ValidateCmd(fileAccessListener.FileAccesses, outFile, is64Bit);
                    break;

                case PipProgram.Self:
                    valid = ValidateSelf(
                        fileAccessListener.FileAccesses,
                        instructions.Length > 0 ? instructions[0] : string.Empty,
                        outFile,
                        is64Bit);
                    break;
                }

                return(executeResult.Status == PipResultStatus.Succeeded && valid);
            }
        }
コード例 #9
0
        public void ChildProcessCanBreakawayWhenConfigured(bool letInfiniteWaiterSurvive)
        {
            // Skip this test if running on .NET Framework with vstest
            // Reason: when this is the case and code coverage is turned on, launching breakaway
            //         processes here causes the code coverage monitoring process to hang.
            if (!OperatingSystemHelper.IsDotNetCore && IsRunningInVsTestTestHost())
            {
                return;
            }

            // We use InfiniteWaiter (a process that waits forever) as a long-living process that we can actually check it can
            // escape the job object
            var fam = new FileAccessManifest(
                Context.PathTable,
                childProcessesToBreakawayFromSandbox: letInfiniteWaiterSurvive ? new[] { InfiniteWaiterToolName } : null)
            {
                FailUnexpectedFileAccesses = false
            };

            // We instruct the regular test process to spawn InfiniteWaiter as a child
            var info = ToProcessInfo(
                ToProcess(
                    Operation.SpawnExe(
                        Context.PathTable,
                        CreateFileArtifactWithName(InfiniteWaiterToolName, TestDeploymentDir))),
                fileAccessManifest: fam);

            // Let's shorten the default time to wait for nested processes, since we are spawning
            // a process that never ends and we don't want this test to wait for that long
            info.NestedProcessTerminationTimeout = TimeSpan.FromMilliseconds(10);

            var result = RunProcess(info).GetAwaiter().GetResult();

            XAssert.AreEqual(0, result.ExitCode);

            if (!letInfiniteWaiterSurvive)
            {
                // If we didn't let infinite waiter escape, we should have killed it when the job object was finalized
                XAssert.IsTrue(result.Killed);
                XAssert.Contains(
                    result.SurvivingChildProcesses.Select(p => p?.Path).Where(p => p != null).Select(p => System.IO.Path.GetFileName(p).ToUpperInvariant()),
                    InfiniteWaiterToolName.ToUpperInvariant());
            }
            else
            {
                // If we did let it escape, then nothing should have been killed (nor tried to survive and later killed, from the job object point of view)
                XAssert.IsFalse(result.Killed);
                if (result.SurvivingChildProcesses != null && result.SurvivingChildProcesses.Any())
                {
                    var survivors = string.Join(
                        ", ",
                        result.SurvivingChildProcesses.Select(p => p?.Path != null ? System.IO.Path.GetFileName(p.Path) : "<unknown>"));
                    XAssert.Fail($"Unexpected {result.SurvivingChildProcesses.Count()} surviving child processes: {survivors}");
                }

                // Let's retrieve the child process and confirm it survived
                var infiniteWaiterInfo = RetrieveChildProcessesCreatedBySpawnExe(result).Single();
                // The fact that this does not throw confirms survival
                var dummyWaiter = Process.GetProcessById(infiniteWaiterInfo.pid);
                // Just being protective, let's make sure we are talking about the same process
                XAssert.AreEqual(infiniteWaiterInfo.processName, dummyWaiter.ProcessName);

                // Now let's kill the surviving process, since we don't want it to linger around unnecessarily
                dummyWaiter.Kill();
            }
        }
コード例 #10
0
        private static void AssertCannotScheduleSealPartialDirectory(TestEnv env, AbsolutePath path, params FileArtifact[] contents)
        {
            bool result = TryScheduleSealDirectory(env, path, SealDirectoryKind.Partial, contents: contents, outputDirectoryContents: CollectionUtilities.EmptyArray <DirectoryArtifact>(), out _);

            XAssert.IsFalse(result, "Unexpectedly succedeeded at sealing a partial directory at " + env.Paths.Expand(path));
        }
コード例 #11
0
        public void IsValid()
        {
            AbsolutePath path = AbsolutePath.Invalid;

            XAssert.IsFalse(path.IsValid);
        }
コード例 #12
0
        public void LazyWriteFileMaterializationCopyTest()
        {
            var sourceFile = CreateSourceFile();

            WriteSourceFile(sourceFile);

            // Graph:
            // W <- C <- C <- P

            var writeFileOutputContent        = "WriteFileOutput";
            var lazyWriteFileOutputToBeCopied = WriteFile(CreateOutputFileArtifact(), writeFileOutputContent);

            var lazyCopyWriteFileOutput = CopyFile(lazyWriteFileOutputToBeCopied, CreateOutputFileArtifact(), tags: new[] { "copy1" });

            var lazyCopyWriteFileOutput2 = CopyFile(lazyCopyWriteFileOutput, CreateOutputFileArtifact(), tags: new[] { "copy2" });

            // ...........PIP A...........
            var builderA = CreatePipBuilder(new Operation[]
            {
                Operation.ReadFile(lazyCopyWriteFileOutput2),
                Operation.ReadFile(sourceFile),
                Operation.WriteFile(CreateOutputFileArtifact())
            });

            builderA.AddTags(Context.StringTable, "pipA");

            var pipA = SchedulePipBuilder(builderA);

            //// ...........Setting Modes...........
            Configuration.Schedule.EnableLazyOutputMaterialization    = true;
            Configuration.Schedule.EnableLazyWriteFileMaterialization = true;

            // run scheduler and assert cache miss
            RunScheduler().AssertCacheMiss(pipA.Process.PipId);// nothing in cache

            // Exist since pipA must run and the write file output is an input
            XAssert.IsTrue(Exists(lazyCopyWriteFileOutput2));

            // Now just run against pip A
            // those pips exist in cache and then there is no reason to run
            // those pips (in this case pipA)
            Configuration.Filter = "tag='pipA'";

            // Delete these files on disk
            Delete(lazyWriteFileOutputToBeCopied);
            Delete(lazyCopyWriteFileOutput);
            Delete(lazyCopyWriteFileOutput2);

            // Run scheduler but grab artificats from cache (should be there from last run)...
            RunScheduler().AssertCacheHit(pipA.Process.PipId);

            // Does not exist since pipA had cache hit and since lazy materialization
            // is on there is not need to materialize the artifacts from the write file pip
            XAssert.IsFalse(Exists(lazyWriteFileOutputToBeCopied));
            XAssert.IsFalse(Exists(lazyCopyWriteFileOutput));
            XAssert.IsFalse(Exists(lazyCopyWriteFileOutput2));

            // Clear the cache so no outputs can be retrieved from cache
            ClearArtifactCache();

            // Delete these files on disk
            Delete(lazyWriteFileOutputToBeCopied);
            Delete(lazyCopyWriteFileOutput);
            Delete(lazyCopyWriteFileOutput2);

            // Write source file to force cache miss
            WriteSourceFile(sourceFile);

            // run scheduler and assert cache hit
            RunScheduler().AssertCacheMiss(pipA.Process.PipId);

            // Write file output should exist (needed to materialize copy file)
            XAssert.IsTrue(Exists(lazyWriteFileOutputToBeCopied));

            // Intermediate copy should not exist
            XAssert.IsFalse(Exists(lazyCopyWriteFileOutput));

            // Final copy should exist on disk since its required by pipA
            XAssert.IsTrue(Exists(lazyCopyWriteFileOutput2));
        }
コード例 #13
0
        public void LazyWriteFileMaterializationTest()
        {
            // setting up the output dir for the pips
            string       writeFileOutput     = Path.Combine(ObjectRoot, @"write\writeFile.txt");
            AbsolutePath writeFileOutputPath = AbsolutePath.Create(Context.PathTable, writeFileOutput);

            var sourceFile = CreateSourceFile();

            WriteSourceFile(sourceFile);

            // Graph:
            // W <- P

            var writeFileOutputContent = "WriteFileOutput";
            var lazyWriteFileOutput    = WriteFile(writeFileOutputPath, writeFileOutputContent);

            // ...........PIP A...........
            var builderA = CreatePipBuilder(new Operation[]
            {
                Operation.ReadFile(lazyWriteFileOutput),
                Operation.ReadFile(sourceFile),
                Operation.WriteFile(CreateOutputFileArtifact())
            });

            builderA.AddTags(Context.StringTable, "pipA");

            var pipA = SchedulePipBuilder(builderA);

            //// ...........Setting Modes...........
            Configuration.Schedule.EnableLazyOutputMaterialization    = true;
            Configuration.Schedule.EnableLazyWriteFileMaterialization = true;

            // run scheduler and assert cache miss
            RunScheduler().AssertCacheMiss(pipA.Process.PipId);// nothing in cache

            // Exist since pipA must run and the write file output is an input
            XAssert.IsTrue(Exists(lazyWriteFileOutput));

            // Now just run against pip A
            // those pips exist in cache and then there is no reason to run
            // those pips (in this case pipA)
            Configuration.Filter = "tag='pipA'";

            // Delete these files on disk
            Delete(lazyWriteFileOutput);

            // Run scheduler but grab artificats from cache (should be there from last run)...
            RunScheduler().AssertCacheHit(pipA.Process.PipId);

            // Does not exist since pipA had cache hit and since lazy materialization
            // is on there is not need to materialize the artifacts from the write file pip
            XAssert.IsFalse(Exists(lazyWriteFileOutput));

            // Clear the cache so no outputs can be retrieved from cache
            ClearArtifactCache();

            // Write source file to force cache miss
            WriteSourceFile(sourceFile);

            // run scheduler and assert cache hit
            RunScheduler().AssertCacheMiss(pipA.Process.PipId);

            // Write file output must be materialized as its an input to the pip
            XAssert.IsTrue(Exists(lazyWriteFileOutput));
        }
コード例 #14
0
ファイル: ScheduleRunResult.cs プロジェクト: uilit/BuildXL
 public ScheduleRunResult AssertFailure()
 {
     XAssert.IsFalse(Success, "Expected scheduler to run with at least one pip failing");
     return(this);
 }
コード例 #15
0
        public void RetryDeleteDirectoryContentsIfContentsPendingDelete()
        {
            try
            {
                // Need to disable POSIX delete to reproduce the Windows pending deletion state,
                // which does not exist in POSIX
                FileUtilities.PosixDeleteMode = PosixDeleteMode.NoRun;

                string dir = Path.Combine(TemporaryDirectory, "dir");
                Directory.CreateDirectory(dir);

                string nestedFile = Path.Combine(dir, "nestedFile");
                File.WriteAllText(nestedFile, "asdf");

                SafeFileHandle nestedFileHandle;
                FileUtilities.TryCreateOrOpenFile(
                    nestedFile,
                    FileDesiredAccess.GenericWrite,
                    FileShare.ReadWrite | FileShare.Delete,
                    FileMode.Open,
                    FileFlagsAndAttributes.None,
                    out nestedFileHandle);

                // Hold open a handle to \file, but allow all file sharing permissions
                using (nestedFileHandle)
                {
                    // Sanity check that pending delete doesn't always return true
                    XAssert.IsFalse(FileUtilities.IsPendingDelete(nestedFileHandle));

                    Exception exception = null;
                    try
                    {
                        // Fails because of the open file that cannot be deleted
                        FileUtilities.DeleteDirectoryContents(dir, true);
                    }
                    catch (BuildXLException e)
                    {
                        exception = e;
                        XAssert.IsTrue(e.Message.StartsWith(FileUtilitiesMessages.DeleteDirectoryContentsFailed + NormalizeDirectoryPath(dir)));

                        // Rebuild the exception message using StringBuilder to handle breaklines
                        StringBuilder builder = new StringBuilder();
                        builder.AppendLine(NormalizeDirectoryPath(nestedFile));
                        builder.AppendLine(FileUtilitiesMessages.NoProcessesUsingHandle);
                        builder.AppendLine(FileUtilitiesMessages.PathMayBePendingDeletion);
                        XAssert.IsTrue(e.Message.Contains(builder.ToString()));
                    }

                    XAssert.IsTrue(exception != null);

                    // Check the open handle forced the file to be placed on the Windows pending deletion queue
                    XAssert.IsTrue(FileUtilities.IsPendingDelete(nestedFileHandle));
                }

                // After the file handle is closed, the delete goes through
                XAssert.IsFalse(File.Exists(nestedFile));

                // Check for retries and ERROR_DIR_NOT_EMPTY
                AssertVerboseEventLogged(EventId.RetryOnFailureException, Helpers.DefaultNumberOfAttempts);
                string logs       = EventListener.GetLog();
                var    numMatches = Regex.Matches(logs, Regex.Escape("Native: RemoveDirectoryW for RemoveDirectory failed (0x91: The directory is not empty")).Count;
                XAssert.AreEqual(Helpers.DefaultNumberOfAttempts, numMatches);
            }
            finally
            {
                // Re-enable POSIX delete for the remainder of tests
                FileUtilities.PosixDeleteMode = PosixDeleteMode.RunFirst;
            }
        }
コード例 #16
0
        public Task BigStrings()
        {
            var harness = new StringTableTestHarness();
            var st      = harness.StringTable;

            var s1 = new string('x', StringTable.BytesPerBuffer - 1);
            var s2 = new string('y', StringTable.BytesPerBuffer);
            var s3 = new string('z', StringTable.BytesPerBuffer + 1);

            StringId id1 = harness.AddString(s1);
            StringId id2 = harness.AddString(s2);
            StringId id3 = harness.AddString(s3);

            harness.AddString(s3 + "繙");

            XAssert.AreEqual(s1.Length, st.GetLength(id1));
            XAssert.AreEqual(s2.Length, st.GetLength(id2));
            XAssert.AreEqual(s3.Length, st.GetLength(id3));

            var buf = new char[StringTable.BytesPerBuffer + 1];

            st.CopyString(id1, buf, 0);
            for (int j = 0; j < s1.Length; j++)
            {
                XAssert.AreEqual(s1[j], buf[j]);
            }

            st.CopyString(id2, buf, 0);
            for (int j = 0; j < s2.Length; j++)
            {
                XAssert.AreEqual(s2[j], buf[j]);
            }

            st.CopyString(id3, buf, 0);
            for (int j = 0; j < s3.Length; j++)
            {
                XAssert.AreEqual(s3[j], buf[j]);
            }

            XAssert.IsTrue(st.CaseInsensitiveEquals(id1, st.AddString(s1)));
            XAssert.IsTrue(st.CaseInsensitiveEquals(id2, st.AddString(s2)));
            XAssert.IsTrue(st.CaseInsensitiveEquals(id3, st.AddString(s3)));

            XAssert.IsTrue(st.Equals(s1, id1));
            XAssert.IsTrue(st.Equals(s2, id2));
            XAssert.IsTrue(st.Equals(s3, id3));

            XAssert.IsFalse(st.CaseInsensitiveEquals(id1, st.AddString(s2)));
            XAssert.IsFalse(st.CaseInsensitiveEquals(id1, st.AddString(s3)));
            XAssert.IsFalse(st.CaseInsensitiveEquals(id2, st.AddString(s1)));
            XAssert.IsFalse(st.CaseInsensitiveEquals(id2, st.AddString(s3)));
            XAssert.IsFalse(st.CaseInsensitiveEquals(id3, st.AddString(s1)));
            XAssert.IsFalse(st.CaseInsensitiveEquals(id3, st.AddString(s2)));

            XAssert.IsFalse(st.Equals(s2, id1));
            XAssert.IsFalse(st.Equals(s3, id1));
            XAssert.IsFalse(st.Equals(s1, id2));
            XAssert.IsFalse(st.Equals(s3, id2));
            XAssert.IsFalse(st.Equals(s1, id3));
            XAssert.IsFalse(st.Equals(s2, id3));

            return(harness.RunCommonTestsAsync());
        }
コード例 #17
0
        public void FailToFindAllOpenHandlesPendingDeletion()
        {
            string dir = Path.Combine(TemporaryDirectory, "dir");

            Directory.CreateDirectory(dir);

            string file = Path.Combine(dir, "file");

            File.WriteAllText(file, "asdf");

            SafeFileHandle fileHandle;

            FileUtilities.TryCreateOrOpenFile(
                file,
                FileDesiredAccess.GenericWrite,
                FileShare.ReadWrite | FileShare.Delete,
                FileMode.Open,
                FileFlagsAndAttributes.None,
                out fileHandle);

            // Hold open a handle to \file, but allow all file sharing permissions
            using (fileHandle)
            {
                XAssert.IsFalse(FileUtilities.IsPendingDelete(fileHandle));

                // This will succeed without throwing an exception
                File.Delete(file);

                // But the open handle forces the file to be placed on a pending deletion queue
                XAssert.IsTrue(FileUtilities.IsPendingDelete(fileHandle));

                // Fail to detect open handles for files pending deletion
                HashSet <string> deletedPaths = new HashSet <string>()
                {
                    file
                };
                string openHandles = FileUtilities.FindAllOpenHandlesInDirectory(TemporaryDirectory, pathsPossiblyPendingDelete: deletedPaths);
                // Rebuild the exception message using StringBuilder to handle breaklines
                StringBuilder builder = new StringBuilder();
                builder.AppendLine(file);
                builder.AppendLine(FileUtilitiesMessages.NoProcessesUsingHandle);
                builder.AppendLine(FileUtilitiesMessages.PathMayBePendingDeletion);
                // Before Windows 10 Version 1903, attempting to create a file handle to a file pending deletion would throw an access exception, including calling File.Exists
                // With Windows 10 Version 1903 and later, creating handles to files on the pending deletion queue does not throw exceptions and pending deletion files are considered deleted by File.Exists
                // This change in behavior is NOT true for directories, see testing below for the directory behavior
                XAssert.IsTrue(openHandles.Contains(builder.ToString()) || /* Check for Windows 10 Version 1903 and later */ !File.Exists(file));
                XAssert.IsFalse(openHandles.Contains(FileUtilitiesMessages.ActiveHandleUsage + file));
            }

            XAssert.IsFalse(File.Exists(file));

            SafeFileHandle dirHandle;

            FileUtilities.TryCreateOrOpenFile(
                dir,
                FileDesiredAccess.GenericWrite,
                FileShare.ReadWrite | FileShare.Delete,
                FileMode.Open,
                FileFlagsAndAttributes.FileFlagBackupSemantics,
                out dirHandle);

            // Hold open a handle to \dir, but allow all sharing permissions
            using (dirHandle)
            {
                XAssert.IsFalse(FileUtilities.IsPendingDelete(dirHandle));

                // This will succeed without throwing an exception
                Directory.Delete(dir);

                // But the open handle forces the directory to be placed on a pending deletion queue
                XAssert.IsTrue(FileUtilities.IsPendingDelete(dirHandle));

                // Fail to detect open handles for dirs pending deletion
                HashSet <string> deletedPaths = new HashSet <string>()
                {
                    dir
                };
                string openHandles = FileUtilities.FindAllOpenHandlesInDirectory(TemporaryDirectory, pathsPossiblyPendingDelete: deletedPaths);
                // Rebuild the exception message using StringBuilder to handle breaklines
                StringBuilder builder = new StringBuilder();
                builder.AppendLine(dir);
                builder.AppendLine(FileUtilitiesMessages.NoProcessesUsingHandle);
                builder.AppendLine(FileUtilitiesMessages.PathMayBePendingDeletion);
                XAssert.IsTrue(openHandles.Contains(builder.ToString()));
                XAssert.IsFalse(openHandles.Contains(FileUtilitiesMessages.ActiveHandleUsage + dir));
            }

            XAssert.IsFalse(Directory.Exists(dir));
        }
コード例 #18
0
        public void TestSemaphoreSet()
        {
            SemaphoreSet <int> semaphores = new SemaphoreSet <int>();

            int[] limits = new int[] { 1, 2, 3, 10 };
            int   originalLimitsLength = limits.Length;

            for (int i = 0; i < limits.Length; i++)
            {
                int semaphoreIndex = semaphores.CreateSemaphore(i, limits[i]);
                XAssert.AreEqual(i, semaphoreIndex);
            }

            for (int i = 0; i < limits.Length; i++)
            {
                var limit = limits[i];
                for (int usage = 1; usage <= limit + 1; usage++)
                {
                    int semaphoreIndex = semaphores.CreateSemaphore(i, limits[i]);
                    XAssert.AreEqual(i, semaphoreIndex);
                    var semaphoreIncrements = new int[i + 1];
                    semaphoreIncrements[i] = 1;
                    bool acquired       = semaphores.TryAcquireResources(ItemResources.Create(semaphoreIncrements));
                    bool expectAcquired = usage <= limit;
                    XAssert.AreEqual(expectAcquired, acquired);
                }
            }

            // Now verify semaphores can be acquired in the copy
            var copiedSemaphores = semaphores.CreateSharingCopy();

            for (int i = 0; i < limits.Length; i++)
            {
                var limit = limits[i];
                for (int usage = 1; usage <= limit + 1; usage++)
                {
                    var semaphoreIncrements = new int[i + 1];
                    semaphoreIncrements[i] = 1;
                    bool acquired       = copiedSemaphores.TryAcquireResources(ItemResources.Create(semaphoreIncrements));
                    bool expectAcquired = usage <= limit;
                    XAssert.AreEqual(expectAcquired, acquired);
                }
            }

            limits = limits.Concat(new int[] { 6, 8 }).ToArray();

            // Create new semaphores in the copy and verify that semaphores can be used in original
            for (int i = 0; i < limits.Length; i++)
            {
                int semaphoreIndex = copiedSemaphores.CreateSemaphore(i, limits[i]);
                XAssert.AreEqual(i, semaphoreIndex);
            }

            for (int i = originalLimitsLength; i < limits.Length; i++)
            {
                var limit = limits[i];
                for (int usage = 1; usage <= limit + 1; usage++)
                {
                    var semaphoreIncrements = new int[i + 1];
                    semaphoreIncrements[i] = 1;
                    bool acquired       = semaphores.TryAcquireResources(ItemResources.Create(semaphoreIncrements));
                    bool expectAcquired = usage <= limit;
                    XAssert.AreEqual(expectAcquired, acquired);
                }
            }

            // Now verify new semaphores can be acquired in the copy
            for (int i = originalLimitsLength; i < limits.Length; i++)
            {
                var limit = limits[i];
                for (int usage = 1; usage <= limit + 1; usage++)
                {
                    var semaphoreIncrements = new int[i + 1];
                    semaphoreIncrements[i] = 1;
                    bool acquired       = copiedSemaphores.TryAcquireResources(ItemResources.Create(semaphoreIncrements));
                    bool expectAcquired = usage <= limit;
                    XAssert.AreEqual(expectAcquired, acquired);
                }
            }

            // Now release the resources in the copy
            for (int i = 0; i < limits.Length; i++)
            {
                var limit = limits[i];
                for (int usage = 1; usage <= limit; usage++)
                {
                    var semaphoreIncrements = new int[i + 1];
                    semaphoreIncrements[i] = 1;
                    copiedSemaphores.ReleaseResources(ItemResources.Create(semaphoreIncrements));
                }
            }

            // Verify that resources still can't be acquired on original
            for (int i = 0; i < limits.Length; i++)
            {
                var semaphoreIncrements = new int[i + 1];
                semaphoreIncrements[i] = 1;
                bool acquired = semaphores.TryAcquireResources(ItemResources.Create(semaphoreIncrements));
                XAssert.IsFalse(acquired);
            }
        }
コード例 #19
0
ファイル: AsyncFileTests.cs プロジェクト: kittinap/kunnjae
        public async Task ReadFileRandomAccess()
        {
            const int NumberOfReads        = 16;
            const int NumberOfWordsPerRead = 64 * 1024;
            const int NumberOfBytesPerRead = NumberOfWordsPerRead * 4;
            const int NumberOfWords        = NumberOfWordsPerRead * NumberOfReads;
            const int TotalSize            = NumberOfWords * 4;

            string path = GetFullPath("file");

            using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Delete))
            {
                using (var writer = new BinaryWriter(fs, Encoding.UTF8, leaveOpen: true))
                {
                    for (int i = 0; i < NumberOfWords; i++)
                    {
                        writer.Write((int)i);
                    }
                }
            }

#if !FEATURE_CORECLR
            using (var io = new IOCompletionManager())
#else
            IIOCompletionManager io = null;
#endif
            {
                using (
                    IAsyncFile file = AsyncFileFactory.CreateOrOpen(
                        path,
                        FileDesiredAccess.GenericRead,
                        FileShare.Read | FileShare.Delete,
                        FileMode.Open,
                        FileFlagsAndAttributes.None,
                        io))
                {
                    XAssert.IsTrue(file.CanRead);
                    XAssert.IsFalse(file.CanWrite);

                    var readBuffer = new byte[TotalSize];
                    var readTasks  = new Task[NumberOfReads];
                    for (int i = 0; i < readTasks.Length; i++)
                    {
                        int offset = NumberOfBytesPerRead * i;
                        readTasks[i] = Task.Run(
                            async() =>
                        {
                            byte[] localBuffer = new byte[NumberOfBytesPerRead];
                            int readSoFar      = 0;
                            while (readSoFar < NumberOfBytesPerRead)
                            {
                                FileAsyncIOResult result =
                                    await file.ReadAsync(localBuffer, bytesToRead: NumberOfBytesPerRead - readSoFar, fileOffset: offset + readSoFar);
                                XAssert.AreEqual(FileAsyncIOStatus.Succeeded, result.Status);
                                XAssert.IsTrue(result.BytesTransferred > 0);
                                XAssert.IsTrue(readSoFar + result.BytesTransferred <= NumberOfBytesPerRead);

                                Buffer.BlockCopy(localBuffer, 0, readBuffer, offset + readSoFar, result.BytesTransferred);
                                readSoFar += result.BytesTransferred;
                            }

                            Contract.Assert(readSoFar == NumberOfBytesPerRead);
                        });
                    }

                    for (int i = 0; i < readTasks.Length; i++)
                    {
                        await readTasks[i];
                    }

                    using (var reader = new BinaryReader(new MemoryStream(readBuffer, writable: false), Encoding.UTF8, leaveOpen: false))
                    {
                        for (int i = 0; i < NumberOfWords; i++)
                        {
                            XAssert.AreEqual(i, reader.ReadInt32());
                        }
                    }
                }
            }
        }
コード例 #20
0
        public void ErrorAndWarningListener()
        {
            string text;

            using (var writer = new StringWriter(CultureInfo.InvariantCulture))
            {
                using (var listener = new ErrorAndWarningEventListener(Events.Log, writer, DateTime.UtcNow, true, false, warningNumber => WarningState.AsWarning))
                {
                    Events log = Events.Log;

                    // should be captured
                    log.CriticalEvent("Cookie 1 ");
                    log.ErrorEvent("Cookie 2 ");

                    // shouldn't be captured
                    log.WarningEvent("Cookie 3 ");
                    log.AlwaysEvent("Cookie 4 ");
                    log.InfoEvent("Cookie 5 ");
                    log.VerboseEvent("Cookie 6 ");
                }

                text = writer.ToString();
            }

            XAssert.IsTrue(Regex.IsMatch(text, ".*Cookie 1 .*"));
            XAssert.IsTrue(Regex.IsMatch(text, ".*Cookie 2 .*"));
            XAssert.IsFalse(Regex.IsMatch(text, ".*Cookie 3 .*"));
            XAssert.IsFalse(Regex.IsMatch(text, ".*Cookie 4 .*"));
            XAssert.IsFalse(Regex.IsMatch(text, ".*Cookie 5 .*"));
            XAssert.IsFalse(Regex.IsMatch(text, ".*Cookie 6 .*"));

            using (var writer = new StringWriter(CultureInfo.InvariantCulture))
            {
                using (var listener = new ErrorAndWarningEventListener(Events.Log, writer, DateTime.UtcNow, false, true, warningNumber => WarningState.AsWarning))
                {
                    Events log = Events.Log;

                    // should be captured
                    log.WarningEvent("Cookie 3 ");

                    // shouldn't be captured
                    log.CriticalEvent("Cookie 1 ");
                    log.ErrorEvent("Cookie 2 ");
                    log.AlwaysEvent("Cookie 4 ");
                    log.InfoEvent("Cookie 5 ");
                    log.VerboseEvent("Cookie 6 ");
                }

                text = writer.ToString();
            }

            XAssert.IsFalse(Regex.IsMatch(text, ".*Cookie 1 .*"));
            XAssert.IsFalse(Regex.IsMatch(text, ".*Cookie 2 .*"));
            XAssert.IsTrue(Regex.IsMatch(text, ".*Cookie 3 .*"));
            XAssert.IsFalse(Regex.IsMatch(text, ".*Cookie 4 .*"));
            XAssert.IsFalse(Regex.IsMatch(text, ".*Cookie 5 .*"));
            XAssert.IsFalse(Regex.IsMatch(text, ".*Cookie 6 .*"));

            // repeat the same tests, but now suppress the warning message (i.e., emulate /noWarn:10002 (EventId.WarningEvent))
            // WarningMapper applies only to warning-level events, so we can check only that one
            // since the warning is being suppressed, nothing should be captured
            using (var writer = new StringWriter(CultureInfo.InvariantCulture))
            {
                using (var listener = new ErrorAndWarningEventListener(Events.Log, writer, DateTime.UtcNow, true, false, warningNumber => WarningState.Suppressed))
                {
                    Events log = Events.Log;

                    log.WarningEvent("Cookie 3 ");
                }

                text = writer.ToString();
            }

            XAssert.IsFalse(Regex.IsMatch(text, ".*Cookie 3 .*"));

            using (var writer = new StringWriter(CultureInfo.InvariantCulture))
            {
                using (var listener = new ErrorAndWarningEventListener(Events.Log, writer, DateTime.UtcNow, false, true, warningNumber => WarningState.Suppressed))
                {
                    Events log = Events.Log;

                    log.WarningEvent("Cookie 3 ");
                }

                text = writer.ToString();
            }

            XAssert.IsFalse(Regex.IsMatch(text, ".*Cookie 3 .*"));
        }
コード例 #21
0
ファイル: PipDataTests.cs プロジェクト: kittinap/kunnjae
 private void VerifyPipDataFromCursorEnd(PipData.FragmentEnumerator enumerator)
 {
     XAssert.IsFalse(enumerator.MoveNext());
 }
コード例 #22
0
        public void TrackingEventListener()
        {
            const int NumVerbose  = 9;
            const int NumInfo     = 8;
            const int NumWarning  = 7;
            const int NumError    = 6;
            const int NumCritical = 5;
            const int NumAlways   = 4;

            using (var listener = new TrackingEventListener(Events.Log))
            {
                Events log = Events.Log;

                for (int i = 0; i < NumVerbose; i++)
                {
                    log.VerboseEvent("1");
                }

                for (int i = 0; i < NumInfo; i++)
                {
                    log.InfoEvent("1");
                }

                for (int i = 0; i < NumWarning; i++)
                {
                    log.WarningEvent("1");
                }

                for (int i = 0; i < NumError; i++)
                {
                    log.ErrorEvent("1");
                }

                for (int i = 0; i < NumCritical; i++)
                {
                    log.CriticalEvent("1");
                }

                for (int i = 0; i < NumAlways; i++)
                {
                    log.AlwaysEvent("1");
                }

                XAssert.AreEqual(listener.VerboseCount, NumVerbose);
                XAssert.AreEqual(listener.InformationalCount, NumInfo);
                XAssert.AreEqual(listener.WarningCount, NumWarning);
                XAssert.AreEqual(listener.TotalErrorCount, NumError + NumCritical);
                XAssert.AreEqual(listener.CriticalCount, NumCritical);
                XAssert.AreEqual(listener.AlwaysCount, NumAlways);
                XAssert.IsTrue(listener.HasFailures);
                XAssert.IsTrue(listener.HasFailuresOrWarnings);
            }

            using (var listener = new TrackingEventListener(Events.Log))
            {
                Events log = Events.Log;

                XAssert.IsFalse(listener.HasFailures);
                XAssert.IsFalse(listener.HasFailuresOrWarnings);

                log.WarningEvent("1");

                XAssert.IsFalse(listener.HasFailures);
                XAssert.IsTrue(listener.HasFailuresOrWarnings);

                log.ErrorEvent("1");
                XAssert.IsTrue(listener.HasFailures);
                XAssert.IsTrue(listener.HasFailuresOrWarnings);
            }

            using (var listener = new TrackingEventListener(Events.Log))
            {
                Events log = Events.Log;

                log.CriticalEvent("1");

                XAssert.IsTrue(listener.HasFailures);
                XAssert.IsTrue(listener.HasFailuresOrWarnings);
            }

            using (var listener = new TrackingEventListener(Events.Log, warningMapper: _ => WarningState.AsError))
            {
                Events log = Events.Log;

                log.WarningEvent("1");

                XAssert.AreEqual(1, listener.TotalErrorCount);
                XAssert.IsTrue(listener.HasFailures);
                XAssert.IsTrue(listener.HasFailuresOrWarnings);
            }
        }
コード例 #23
0
        public void ScrubFilesNotInContentsWhenFullySealDir(bool shouldScrub)
        {
            // simulating two builds here,
            // the second build should scrub the stray files
            // if they are in a fully sealed directory
            var sourceDir    = DirectoryArtifact.CreateWithZeroPartialSealId(CreateUniqueDirectory());
            var sourceDirStr = ArtifactToString(sourceDir);
            var file1        = CreateOutputFileArtifact(sourceDirStr);
            var file1Str     = ArtifactToString(file1);
            var file2        = CreateOutputFileArtifact(sourceDirStr);
            var file2Str     = ArtifactToString(file2);

            var sealDir       = DirectoryArtifact.CreateWithZeroPartialSealId(CreateUniqueDirectory());
            var sealDirStr    = ArtifactToString(sealDir);
            var nestedDir1    = AbsolutePath.Create(Context.PathTable, Path.Combine(sealDirStr, "nested1"));
            var nestedDir1Str = nestedDir1.ToString(Context.PathTable);
            var nestedDir2    = AbsolutePath.Create(Context.PathTable, Path.Combine(sealDirStr, "nested2"));
            var nestedDir2Str = nestedDir2.ToString(Context.PathTable);
            var sealFile1     = CreateOutputFileArtifact(nestedDir1Str);
            var sealFile1Str  = ArtifactToString(sealFile1);
            var sealFile2     = CreateOutputFileArtifact(nestedDir2Str);
            var sealFile2Str  = ArtifactToString(sealFile2);

            // the first build depends on file1 and file2
            var builderA = CreatePipBuilder(new Operation[]
            {
                Operation.WriteFile(file1, "First build write file1"),
                Operation.WriteFile(file2, "First build write file2"),
            });

            SchedulePipBuilder(builderA);

            var builderB = CreatePipBuilder(new Operation[]
            {
                Operation.CopyFile(file1, sealFile1),
                Operation.CopyFile(file2, sealFile2),
            });

            SchedulePipBuilder(builderB);
            SealDirectory(sealDir, SealDirectoryKind.Full, true, sealFile1, sealFile2);
            RunScheduler().AssertSuccess();

            XAssert.IsTrue(File.Exists(sealFile1Str), $"File in the content list when seal was supposed to exist: {sealFile1Str}");
            XAssert.IsTrue(File.Exists(sealFile2Str), $"File in the content list when seal was supposed to exist: {sealFile2Str}");

            ResetPipGraphBuilder();

            // the second build only depends on file1
            var builderC = CreatePipBuilder(new Operation[]
            {
                Operation.WriteFile(file1, "Second build write file1"),
            });

            SchedulePipBuilder(builderC);

            var builderD = CreatePipBuilder(new Operation[]
            {
                Operation.CopyFile(file1, sealFile1),
            });

            SchedulePipBuilder(builderD);
            SealDirectory(sealDir, SealDirectoryKind.Full, shouldScrub, sealFile1);

            var opslist = new List <Operation>();

            opslist.Add(Operation.ReadFile(sealFile1));
            opslist.Add(Operation.WriteFile(CreateOutputFileArtifact()));

            if (!shouldScrub)
            {
                opslist.Add(Operation.ReadFile(sealFile2, true));
            }

            var builderE = CreatePipBuilder(opslist);

            SchedulePipBuilder(builderE);

            XAssert.IsTrue(File.Exists(sealFile1Str), $"File in the content list when seal was supposed to exist: {sealFile1Str}");
            if (shouldScrub)
            {
                RunScheduler().AssertSuccess();
                XAssert.IsFalse(Directory.Exists(nestedDir2Str), $"unseal directory wasn't supposed to exist: {nestedDir2Str}");
                XAssert.IsFalse(File.Exists(sealFile2Str), $"File not in the content list when seal wasn't supposed to exist: {sealFile2Str}");
            }
            else
            {
                RunScheduler().AssertFailure();
                AssertErrorEventLogged(EventId.FileMonitoringError);
                AssertVerboseEventLogged(EventId.PipProcessDisallowedFileAccess);
                AssertWarningEventLogged(EventId.ProcessNotStoredToCacheDueToFileMonitoringViolations);
                XAssert.IsTrue(Directory.Exists(nestedDir2Str), $"unseal directory was supposed to exist: {nestedDir2Str}");
                XAssert.IsTrue(File.Exists(sealFile2Str), $"File not in the content list when seal was supposed to exist: {sealFile2Str}");
            }
        }
コード例 #24
0
        private void ExpectHashUnknown(FileContentTable table, AbsolutePath path)
        {
            VersionedFileIdentityAndContentInfo?maybeKnownHash = table.TryGetKnownContentHash(path.ToString(m_pathTable));

            XAssert.IsFalse(maybeKnownHash.HasValue, "Loaded table has an unexpected entry for {0}", path.ToString(m_pathTable));
        }
コード例 #25
0
        public void SerializeSandboxedProcessInfo(bool useNullFileStorage, bool useRootJail)
        {
            var pt  = new PathTable();
            var fam =
                new FileAccessManifest(pt, CreateDirectoryTranslator())
            {
                FailUnexpectedFileAccesses   = false,
                IgnoreCodeCoverage           = false,
                ReportFileAccesses           = false,
                ReportUnexpectedFileAccesses = false,
                MonitorChildProcesses        = false
            };

            var vac = new ValidationDataCreator(fam, pt);

            vac.AddScope(A("C", "Users", "AppData"), FileAccessPolicy.AllowAll);
            vac.AddPath(A("C", "Source", "source.txt"), FileAccessPolicy.AllowReadAlways);
            vac.AddPath(A("C", "Out", "out.txt"), FileAccessPolicy.AllowAll);

            SandboxedProcessStandardFiles standardFiles = null;
            ISandboxedProcessFileStorage  fileStorage;

            if (useNullFileStorage)
            {
                fileStorage = null;
            }
            else
            {
                standardFiles = new SandboxedProcessStandardFiles(A("C", "pip", "pip.out"), A("C", "pip", "pip.err"));
                fileStorage   = new StandardFileStorage(standardFiles);
            }

            var envVars = new Dictionary <string, string>()
            {
                ["Var1"] = "Val1",
                ["Var2"] = "Val2",
            };
            IBuildParameters buildParameters = BuildParameters.GetFactory().PopulateFromDictionary(envVars);

            var sidebandLogFile = A("C", "engine-cache", "sideband-logs", "log-1");
            var loggerRootDirs  = new[] { A("C", "out", "dir1"), A("C", "out", "dir2") };

            var sharedOpaqueOutputLogger = new SidebandWriter(DefaultSidebandMetadata, sidebandLogFile, loggerRootDirs);

            SandboxedProcessInfo info = new SandboxedProcessInfo(
                pt,
                fileStorage,
                A("C", "tool", "tool.exe"),
                fam,
                true,
                null,
                LoggingContext,
                sidebandWriter: sharedOpaqueOutputLogger)
            {
                Arguments            = @"/arg1:val1 /arg2:val2",
                WorkingDirectory     = A("C", "Source"),
                RootJailInfo         = useRootJail ? (RootJailInfo?)new RootJailInfo(A("C", "RootJail"), 123, 234) : null,
                EnvironmentVariables = buildParameters,
                Timeout              = TimeSpan.FromMinutes(15),
                PipSemiStableHash    = 0x12345678,
                PipDescription       = nameof(SerializeSandboxedProcessInfo),
                TimeoutDumpDirectory = A("C", "Timeout"),
                SandboxKind          = global::BuildXL.Utilities.Configuration.SandboxKind.Default,
                AllowedSurvivingChildProcessNames = new[] { "conhost.exe", "mspdbsrv.exe" },
                NestedProcessTerminationTimeout   = SandboxedProcessInfo.DefaultNestedProcessTerminationTimeout,
                StandardInputSourceInfo           = StandardInputInfo.CreateForData("Data"),
                StandardObserverDescriptor        = new SandboxObserverDescriptor()
                {
                    WarningRegex = new ExpandedRegexDescriptor("*warn", System.Text.RegularExpressions.RegexOptions.Compiled)
                },
            };

            // Serialize and deserialize.
            SandboxedProcessInfo readInfo = null;

            using (var stream = new MemoryStream())
            {
                info.Serialize(stream);
                stream.Position = 0;
                readInfo        = SandboxedProcessInfo.Deserialize(
                    stream,
                    new global::BuildXL.Utilities.Instrumentation.Common.LoggingContext("Test"),
                    null);
            }

            using (readInfo.SidebandWriter)
            {
                // Verify.
                XAssert.AreEqual(info.FileName, readInfo.FileName);
                XAssert.AreEqual(info.Arguments, readInfo.Arguments);
                XAssert.AreEqual(info.WorkingDirectory, readInfo.WorkingDirectory);
                XAssert.AreEqual(info.RootJailInfo?.RootJail, readInfo.RootJailInfo?.RootJail);
                XAssert.AreEqual(info.RootJailInfo?.UserId, readInfo.RootJailInfo?.UserId);
                XAssert.AreEqual(info.RootJailInfo?.GroupId, readInfo.RootJailInfo?.GroupId);
                var readEnvVars = readInfo.EnvironmentVariables.ToDictionary();
                XAssert.AreEqual(envVars.Count, readEnvVars.Count);
                foreach (var kvp in envVars)
                {
                    XAssert.AreEqual(kvp.Value, readEnvVars[kvp.Key]);
                }

                XAssert.AreEqual(info.Timeout, readInfo.Timeout);
                XAssert.AreEqual(info.PipSemiStableHash, readInfo.PipSemiStableHash);
                XAssert.AreEqual(info.PipDescription, readInfo.PipDescription);
                XAssert.AreEqual(info.TimeoutDumpDirectory, readInfo.TimeoutDumpDirectory);
                XAssert.AreEqual(info.SandboxKind, readInfo.SandboxKind);

                XAssert.AreEqual(info.AllowedSurvivingChildProcessNames.Length, readInfo.AllowedSurvivingChildProcessNames.Length);
                for (int i = 0; i < info.AllowedSurvivingChildProcessNames.Length; ++i)
                {
                    XAssert.AreEqual(info.AllowedSurvivingChildProcessNames[i], readInfo.AllowedSurvivingChildProcessNames[i]);
                }

                XAssert.AreEqual(info.NestedProcessTerminationTimeout, readInfo.NestedProcessTerminationTimeout);
                XAssert.AreEqual(info.StandardInputSourceInfo, readInfo.StandardInputSourceInfo);

                if (useNullFileStorage)
                {
                    XAssert.IsNull(readInfo.SandboxedProcessStandardFiles);
                    XAssert.IsNull(readInfo.FileStorage);
                }
                else
                {
                    XAssert.IsNotNull(readInfo.SandboxedProcessStandardFiles);
                    XAssert.AreEqual(standardFiles.StandardOutput, readInfo.SandboxedProcessStandardFiles.StandardOutput);
                    XAssert.AreEqual(standardFiles.StandardError, readInfo.SandboxedProcessStandardFiles.StandardError);
                    XAssert.AreEqual(standardFiles.StandardOutput, readInfo.FileStorage.GetFileName(SandboxedProcessFile.StandardOutput));
                    XAssert.AreEqual(standardFiles.StandardError, readInfo.FileStorage.GetFileName(SandboxedProcessFile.StandardError));
                }

                XAssert.IsFalse(readInfo.ContainerConfiguration.IsIsolationEnabled);

                XAssert.AreEqual(sidebandLogFile, readInfo.SidebandWriter.SidebandLogFile);
                XAssert.ArrayEqual(loggerRootDirs, readInfo.SidebandWriter.RootDirectories.ToArray());

                if (!OperatingSystemHelper.IsUnixOS)
                {
                    // this validator examines serialized FAM bytes using the same Windows-only native parser used by Detours
                    ValidationDataCreator.TestManifestRetrieval(vac.DataItems, readInfo.FileAccessManifest, false);
                }
            }
        }
コード例 #26
0
        public void TestConcurrentBigMapOperations()
        {
            var map = new ConcurrentBigMap <int, string>();

            XAssert.IsTrue(map.TryAdd(0, "value"));
            XAssert.IsFalse(map.TryAdd(0, "not added value"));
            XAssert.AreEqual("value", map[0]);
            map[0] = "newValue";
            map[1] = "value1";

            var value0 = "newValue";

            XAssert.AreEqual(value0, map[0]);
            XAssert.IsTrue(map.ContainsKey(0));
            XAssert.IsTrue(map.ContainsKey(1));
            XAssert.IsFalse(map.ContainsKey(12));

            XAssert.AreEqual(2, map.Count);

            // Test TryGetValue
            string value1;

            XAssert.IsTrue(map.TryGetValue(1, out value1));
            XAssert.AreEqual("value1", value1);
            string value31;

            XAssert.IsFalse(map.TryGetValue(31, out value31));

            // Test update
            XAssert.IsFalse(map.TryUpdate(1, "notUpdatedValue1", "notActualValue1"));
            XAssert.AreEqual("value1", map[1]);
            XAssert.IsTrue(map.TryUpdate(1, "updatedValue1", "value1"));
            value1 = map[1];
            XAssert.AreEqual("updatedValue1", value1);

            // Test remove
            int    beforeFailedRemoveCount = map.Count;
            string value23;

            XAssert.IsFalse(map.TryRemove(23, out value23));
            XAssert.AreEqual(beforeFailedRemoveCount, map.Count);
            map.Add(23, "value23");
            XAssert.AreEqual(beforeFailedRemoveCount + 1, map.Count);
            XAssert.IsTrue(map.TryRemove(23, out value23));
            XAssert.AreEqual("value23", value23);
            XAssert.AreEqual(beforeFailedRemoveCount, map.Count);

            Assert.Equal(new int[] { 0, 1 }, map.Keys.ToArray());
            Assert.Equal(new string[] { value0, value1 }, map.Values.ToArray());

            XAssert.AreEqual(2, map.Count);

            string addedData    = "added data";
            string notAddedData = "not added data";
            var    result       = map.GetOrAdd(2, addedData, (key, data0) => data0);

            XAssert.IsFalse(result.IsFound);
            XAssert.AreEqual(addedData, result.Item.Value);
            XAssert.AreEqual(addedData, map[2]);

            // Ensure entry is not updated for get or add
            result = map.GetOrAdd(2, notAddedData, (key, data0) => data0);
            XAssert.IsTrue(result.IsFound);
            XAssert.AreEqual(addedData, result.Item.Value);
            XAssert.AreEqual(addedData, map[2]);

            Func <int, string, string, string> updateFunction =
                (key, data0, currentValue) => "updated " + currentValue;

            var updatedData = updateFunction(2, notAddedData, addedData);

            result = map.AddOrUpdate(2, notAddedData, (key, data0) => data0, updateFunction);
            XAssert.IsTrue(result.IsFound);
            XAssert.AreEqual(addedData, result.OldItem.Value);
            XAssert.AreEqual(updatedData, result.Item.Value);
            XAssert.AreEqual(updatedData, map[2]);

            result = map.AddOrUpdate(3, addedData, (key, data0) => data0, updateFunction);
            XAssert.IsFalse(result.IsFound);
            XAssert.AreEqual(addedData, result.Item.Value);
            XAssert.AreEqual(addedData, map[3]);

            TestOperationsHelper(parallel: false);
        }
コード例 #27
0
        /// <summary>
        /// Asserts that a file relative to <see cref="TemporaryStorageTestBase.TemporaryDirectory" /> exists.
        /// </summary>
        protected void AssertFileDoesNotExist(string relPath)
        {
            string path = GetFullPath(relPath);

            XAssert.IsFalse(File.Exists(path), "Expected path {0} to be absent", path);
        }
コード例 #28
0
        public void TestRedirectUserProfileDirectory()
        {
            // first run to create all necessary directories leading to obj directory
            SetupTestData();
            RunEngine();

            string currentUserProfile = SpecialFolderUtilities.GetFolderPath(Environment.SpecialFolder.UserProfile);
            string junctionPath       = Path.Combine(Configuration.Layout.ObjectDirectory.ToString(Context.PathTable), "buildXLUserProfile");
            bool   specialFolderInitializerWasCalled = false;
            var    translatedDirectory = new List <TranslateDirectoryData>();
            var    properties          = new Dictionary <string, string>();
            var    expectedProperties  = new Dictionary <string, string>
            {
                { "APPDATA", Path.Combine(junctionPath, "AppData", "Roaming") },
                { "LOCALAPPDATA", Path.Combine(junctionPath, "AppData", "Local") },
                { "USERPROFILE", junctionPath },
                { "USERNAME", "buildXLUserProfile" },
                { "HOMEDRIVE", Path.GetPathRoot(junctionPath).TrimEnd('\\') },
                { "HOMEPATH", junctionPath.Substring(Path.GetPathRoot(junctionPath).TrimEnd('\\').Length) },
                { "INTERNETCACHE", Path.Combine(junctionPath, "AppData", "Local", "Microsoft", "Windows", "INetCache") },
                { "INTERNETHISTORY", Path.Combine(junctionPath, "AppData", "Local", "Microsoft", "Windows", "History") },
                { "INETCOOKIES", Path.Combine(junctionPath, "AppData", "Local", "Microsoft", "Windows", "INetCookies") },
                { "LOCALLOW", Path.Combine(junctionPath, "AppData", "LocalLow") },
            };

            // add the variables to the dictionary, so we can verify that the method overrides the existing values
            foreach (var envVar in expectedProperties.Keys)
            {
                properties.Add(envVar, string.Empty);
            }

            try
            {
                var success = BuildXLEngine.RedirectUserProfileDirectory(
                    Configuration.Layout.ObjectDirectory,
                    translatedDirectory,
                    properties,
                    dict => { specialFolderInitializerWasCalled = true; },
                    true,
                    Context.PathTable,
                    LoggingContext);

                // must have finished successfully
                XAssert.IsTrue(success);

                // verify the env block is properly populated
                XAssert.AreSetsEqual(expectedProperties.Keys, properties.Keys, true);
                XAssert.IsFalse(expectedProperties.Any(kvp => properties[kvp.Key] != kvp.Value));

                XAssert.IsTrue(specialFolderInitializerWasCalled);

                // verify junction
                var openResult = FileUtilities.TryOpenDirectory(junctionPath, FileDesiredAccess.FileReadAttributes, FileShare.ReadWrite, FileFlagsAndAttributes.FileFlagOpenReparsePoint, out var handle);
                XAssert.IsTrue(openResult.Succeeded);

                using (handle)
                {
                    var possibleTarget = FileUtilities.TryGetReparsePointTarget(handle, junctionPath);
                    XAssert.IsTrue(possibleTarget.Succeeded);
                    XAssert.AreEqual(FileSystemWin.NtPathPrefix + currentUserProfile, possibleTarget.Result);
                }

                // verify that we added a new directory translation
                AbsolutePath.TryCreate(Context.PathTable, currentUserProfile, out var fromPath);
                AbsolutePath.TryCreate(Context.PathTable, junctionPath, out var toPath);
                XAssert.IsTrue(translatedDirectory.Count == 1);
                XAssert.IsTrue(translatedDirectory[0].FromPath == fromPath && translatedDirectory[0].ToPath == toPath);
            }
            finally
            {
                // clean the junction after the test
                var possibleProbe = FileUtilities.TryProbePathExistence(junctionPath, false);
                if (possibleProbe.Succeeded && possibleProbe.Result != PathExistence.Nonexistent)
                {
                    // we attempt to delete the junction, but we do not care if we failed to do
                    FileUtilities.TryRemoveDirectory(junctionPath, out int errCode);
                }
            }
        }
コード例 #29
0
        public async Task TestGcBasic()
        {
            string cacheConfig         = TestType.NewCache(nameof(TestGcBasic), true);
            BasicFilesystemCache cache = (await InitializeCacheAsync(cacheConfig).SuccessAsync()) as BasicFilesystemCache;

            XAssert.IsNotNull(cache, "Failed to create cache for GC tests!");

            // Verify that we don't have prior content in the cache
            XAssert.AreEqual(0, new CacheEntries(cache).Count, "Test cache did not start out empty!");

            PipDefinition[] pipsSession1 =
            {
                new PipDefinition("Pip1", pipSize: 3),
                new PipDefinition("Pip2", pipSize: 4),
                new PipDefinition("Pip3", pipSize: 5)
            };

            CacheEntries session1Files = await BuildPipsAndGetCacheEntries(cache, "Session1", pipsSession1);

            // Nothing should change on this GC since the files and are all referenced
            FullGc(cache);
            session1Files.AssertExists();

            session1Files.AgeAll();

            // Everything is rooted so nothing should happen here
            FullGc(cache);

            XAssert.IsFalse(new CacheEntries(cache).AreDifferences(session1Files), "We changed the cache when we should not have!");

            // Now, if we delete the session, we should collect things.
            cache.DeleteSession("Session1");
            FullGc(cache);

            // All of the fingerprints should be changed to pending but nothing should be deleted
            CacheEntries session1gcFpPending = new CacheEntries(cache);

            XAssert.AreEqual(session1Files.Count, session1gcFpPending.Count, "Nothing should have been added or deleted!");
            XAssert.IsFalse(session1gcFpPending.FingerprintFiles.Keys.Any(IsNotPendingDelete), "All fingerprints should be pending delete");
            XAssert.IsFalse(session1gcFpPending.CasFiles.Keys.Any(IsPendingDelete), "All cas should not be pending delete");

            // Nothing to happen here as the pending files are too new
            FullGc(cache);

            // Nothing changed...
            XAssert.IsFalse(new CacheEntries(cache).AreDifferences(session1gcFpPending), "We changed the cache when we should not have!");

            // Now age the pending delete such that they are collected
            session1gcFpPending.AgeAll();

            FullGc(cache);

            CacheEntries session1gcCas1 = new CacheEntries(cache);

            XAssert.AreEqual(0, session1gcCas1.FingerprintFiles.Count, "Should have collected all fingerprints");

            // And, we should have moved to pending all CAS items (since there is no pending)
            XAssert.IsFalse(session1gcCas1.CasFiles.Keys.Any(IsNotPendingDelete), "All cas should be pending delete");

            FullGc(cache); // Should do nothing as they are not old enough pending
            XAssert.IsFalse(new CacheEntries(cache).AreDifferences(session1gcCas1), "We changed the cache when we should not have!");

            // After getting all to be old, this should finally GC it all
            session1gcCas1.AgeAll();
            FullGc(cache);

            XAssert.AreEqual(0, new CacheEntries(cache).Count, "Should have collected everything.");

            AssertSuccess(await cache.ShutdownAsync());
        }
コード例 #30
0
        public void IsValid()
        {
            HierarchicalNameId path = HierarchicalNameId.Invalid;

            XAssert.IsFalse(path.IsValid);
        }