public void DeserializeIsInverseOfSerialize(string logFile, string[] rootDirs)
 {
     using (var original = new SharedOpaqueOutputLogger(logFile, rootDirs))
         using (var clone = CloneViaSerialization(original))
         {
             XAssert.AreEqual(original.SidebandLogFile, clone.SidebandLogFile);
             XAssert.ArrayEqual(original.RootDirectories?.ToArray(), clone.RootDirectories?.ToArray());
         }
 }
        public void ReadingFromCorruptedSidebandFiles(
            int numValidRecordsToWriteFirst,
            bool closeLoggerCleanly,
            bool appendBogusBytes)
        {
            var myDir = Path.Combine(TemporaryDirectory, nameof(ReadingFromCorruptedSidebandFiles));

            Directory.CreateDirectory(myDir);
            XAssert.IsTrue(Directory.Exists(myDir));

            // write some valid records first
            var validRecords = Enumerable
                               .Range(0, numValidRecordsToWriteFirst)
                               .Select(i => Path.Combine(TemporaryDirectory, $"path-{i}"))
                               .ToArray();

            var logFile = Path.Combine(myDir, $"bogus-log-close_{closeLoggerCleanly}-append_{appendBogusBytes}");
            var logger  = CreateLogger(logFile);

            logger.EnsureHeaderWritten();
            foreach (var path in validRecords)
            {
                XAssert.IsTrue(logger.RecordFileWrite(PathTable, path));
            }

            if (closeLoggerCleanly)
            {
                logger.Dispose();
            }
            else
            {
                logger.CloseWriterWithoutFixingUpHeaderForTestingOnly();
            }

            if (appendBogusBytes)
            {
                // append some bogus stuff at the end
                using (var s = new FileStream(logFile, FileMode.OpenOrCreate))
                    using (var bw = new BinaryWriter(s))
                    {
                        bw.Seek(0, SeekOrigin.End);
                        bw.Write(1231);
                        bw.Flush();
                    }
            }

            // reading should produce valid records and just finish when it encounters the bogus stuff
            var read = SharedOpaqueOutputLogger.ReadRecordedPathsFromSidebandFile(logFile).ToArray();

            XAssert.ArrayEqual(validRecords, read);
        }
        private static SharedOpaqueOutputLogger CloneViaSerialization(SharedOpaqueOutputLogger original)
        {
            using (var stream = new MemoryStream())
            {
                using (var writer = new BuildXLWriter(debug: true, stream, leaveOpen: true, logStats: true))
                {
                    original.Serialize(writer);
                }

                stream.Seek(0, SeekOrigin.Begin);
                using (var reader = new BuildXLReader(debug: true, stream, leaveOpen: true))
                {
                    return(SharedOpaqueOutputLogger.Deserialize(reader));
                }
            }
        }
예제 #4
0
        public void SerializeSandboxedProcessInfo()
        {
            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);

            var standardFiles = new SandboxedProcessStandardFiles(A("C", "pip", "pip.out"), A("C", "pip", "pip.err"));
            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 SharedOpaqueOutputLogger(sidebandLogFile, loggerRootDirs);

            SandboxedProcessInfo info = new SandboxedProcessInfo(
                pt,
                new StandardFileStorage(standardFiles),
                A("C", "tool", "tool.exe"),
                fam,
                true,
                null,
                sharedOpaqueOutputLogger: sharedOpaqueOutputLogger)
            {
                Arguments            = @"/arg1:val1 /arg2:val2",
                WorkingDirectory     = A("C", "Source"),
                EnvironmentVariables = buildParameters,
                Timeout              = TimeSpan.FromMinutes(15),
                PipSemiStableHash    = 0x12345678,
                PipDescription       = nameof(SerializeSandboxedProcessInfo),
                ProcessIdListener    = null,
                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.SharedOpaqueOutputLogger)
            {
                // Verify.
                XAssert.AreEqual(info.FileName, readInfo.FileName);
                XAssert.AreEqual(info.Arguments, readInfo.Arguments);
                XAssert.AreEqual(info.WorkingDirectory, readInfo.WorkingDirectory);
                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.ProcessIdListener, readInfo.ProcessIdListener);
                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);
                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.SharedOpaqueOutputLogger.SidebandLogFile);
                XAssert.ArrayEqual(loggerRootDirs, readInfo.SharedOpaqueOutputLogger.RootDirectories.ToArray());

                ValidationDataCreator.TestManifestRetrieval(vac.DataItems, readInfo.FileAccessManifest, false);
            }
        }