Ejemplo n.º 1
0
        public void DBEventCountVerification()
        {
            Configuration.Logging.LogExecution = true;

            var fileOne = FileArtifact.CreateOutputFile(Combine(TestDirPath, "foo.txt"));
            var fileTwo = FileArtifact.CreateOutputFile(Combine(TestDirPath, "bar.txt"));
            var dirOne  = Path.Combine(ReadonlyRoot, "baz");

            Directory.CreateDirectory(dirOne);
            File.WriteAllText(Path.Combine(dirOne, "abc.txt"), "text");
            File.WriteAllText(Path.Combine(dirOne, "xyz.txt"), "text12");

            var pipA = CreateAndSchedulePipBuilder(new[]
            {
                Operation.WriteFile(fileOne),
            }).Process;

            var pipB = CreateAndSchedulePipBuilder(new[]
            {
                Operation.WriteFile(fileTwo),
            }).Process;

            var pipC = CreateAndSchedulePipBuilder(new[]
            {
                Operation.ReadFile(fileOne),
                Operation.WriteFile(CreateOutputFileArtifact())
            }).Process;

            var pipD = CreateAndSchedulePipBuilder(new[]
            {
                Operation.EnumerateDir(new DirectoryArtifact(AbsolutePath.Create(Context.PathTable, dirOne), 0, false)),
                Operation.WriteFile(CreateOutputFileArtifact())
            }).Process;

            var buildA      = RunScheduler().AssertSuccess();
            var analyzerRes = RunAnalyzer(buildA).AssertSuccess();

            var dataStore = new XldbDataStore(storeDirectory: OutputDirPath.ToString(Context.PathTable));

            // As per Mike's offline comment, non-zero vs zero event count tests for now until we can rent out some mac machines
            // and figure out the true reason why the windows and mac event log counts differ by so much

            // For these tests, there should be a non-zero number of events logged
            XAssert.AreNotEqual(0, dataStore.GetFileArtifactContentDecidedEvents().Count());
            XAssert.AreNotEqual(0, dataStore.GetPipExecutionPerformanceEvents().Count());
            XAssert.AreNotEqual(0, dataStore.GetDirectoryMembershipHashedEvents().Count());
            XAssert.AreNotEqual(0, dataStore.GetProcessExecutionMonitoringReportedEvents().Count());
            XAssert.AreNotEqual(0, dataStore.GetProcessFingerprintComputationEvents().Count());
            XAssert.AreNotEqual(0, dataStore.GetBuildSessionConfigurationEvents().Count());
            XAssert.AreNotEqual(0, dataStore.GetPipExecutionStepPerformanceReportedEvents().Count());
            XAssert.AreNotEqual(0, dataStore.GetPipCacheMissEvents().Count());
            XAssert.AreNotEqual(0, dataStore.GetStatusReportedEvents().Count());
            XAssert.AreNotEqual(0, dataStore.GetBxlInvocationEvents().Count());

            // For these tests, there should be no events logged
            XAssert.AreEqual(0, dataStore.GetPipExecutionDirectoryOutputsEvents().Count());
            XAssert.AreEqual(0, dataStore.GetWorkerListEvents().Count());
            XAssert.AreEqual(0, dataStore.GetDependencyViolationReportedEvents().Count());
        }
Ejemplo n.º 2
0
        /// <inheritdoc/>
        public override int Analyze()
        {
            var dataStore = new XldbDataStore(storeDirectory: InputDirPath);

            File.AppendAllLines(OutputFilePath, dataStore.GetBXLInvocationEvents());

            return(0);
        }
Ejemplo n.º 3
0
        /// <inheritdoc/>
        public override int Analyze()
        {
            using (var dataStore = new XldbDataStore(storeDirectory: InputDirPath))
            {
                File.WriteAllLines(OutputFilePath, dataStore.GetBXLInvocationEvents().Select(key => key.ToString()));
            }

            return(0);
        }
Ejemplo n.º 4
0
        /// <inheritdoc/>
        public override int Analyze()
        {
            using (var dataStore = new XldbDataStore(storeDirectory: InputDirPath))
                using (var outputStream = File.OpenWrite(OutputFilePath))
                    using (var writer = new StreamWriter(outputStream))
                    {
                        var workerToEventDict = new Dictionary <uint, Dictionary <Xldb.ExecutionEventId, (int, int)> >();
                        foreach (Xldb.ExecutionEventId eventId in Enum.GetValues(typeof(Xldb.ExecutionEventId)))
                        {
                            var eventCount = dataStore.GetCountByEvent(eventId);

                            if (eventCount != null)
                            {
                                foreach (var workerCount in eventCount.WorkerToCountMap)
                                {
                                    if (workerToEventDict.TryGetValue(workerCount.Key, out var eventDict))
                                    {
                                        eventDict[eventId] = (workerCount.Value, 0);
                                    }
                                    else
                                    {
                                        var dict = new Dictionary <Xldb.ExecutionEventId, (int, int)>();
                                        dict.Add(eventId, (workerCount.Value, 0));
                                        workerToEventDict.Add(workerCount.Key, dict);
                                    }
                                }
                                foreach (var payloadSize in eventCount.WorkerToPayloadMap)
                                {
                                    workerToEventDict.TryGetValue(payloadSize.Key, out var eventDict);
                                    eventDict.TryGetValue(eventId, out var tup);
                                    eventDict[eventId] = (tup.Item1, payloadSize.Value);
                                }
                            }
                        }

                        foreach (var workerDict in workerToEventDict)
                        {
                            writer.WriteLine("Worker {0}", workerDict.Key);
                            var maxLength = Enum.GetValues(typeof(Scheduler.Tracing.ExecutionEventId)).Cast <Scheduler.Tracing.ExecutionEventId>().Select(e => e.ToString().Length).Max();
                            foreach (var eventStats in workerDict.Value)
                            {
                                writer.WriteLine(
                                    "{0}: {1} Count = {2}",
                                    eventStats.Key.ToString().PadRight(maxLength, ' '),
                                    eventStats.Value.Item2.ToString(CultureInfo.InvariantCulture).PadLeft(12, ' '),
                                    eventStats.Value.Item1.ToString(CultureInfo.InvariantCulture).PadLeft(12, ' '));
                            }
                            writer.WriteLine();
                        }
                    }

            return(0);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Dumps the information related to a pip from the Xldb instance
        /// </summary>
        public int AnalyzeDumpPip()
        {
            if (m_commandLineOptions.ContainsKey("/h"))
            {
                Console.WriteLine("\nXldb Analyzer");
                Console.WriteLine("Creates a file containing details about one or more pips, using the RocksDB database as the source");
                Console.WriteLine("/i: \t Required \t The directory to read the RocksDB database from");
                Console.WriteLine("/o: \t Required \t The file where to write the results");
                Console.WriteLine("/p: \t Optional \t The formatted semistable hash of a pip to dump (must start with 'Pip', e.g., 'PipC623BCE303738C69')");
                Console.WriteLine("    \t          \t If omitted, basic information about each process pip is output instead.");
                return(1);
            }

            if (!m_commandLineOptions.TryGetValue("/o", out var outputFilePath))
            {
                Console.WriteLine("Output file required. Exiting analyzer ...");
                return(1);
            }

            var haveSemiStableHash   = false;
            var parsedSemiStableHash = -1L;

            if (m_commandLineOptions.TryGetValue("/p", out var pipHash))
            {
                if (ParseSemistableHash(pipHash, out parsedSemiStableHash))
                {
                    haveSemiStableHash = true;
                }
                else
                {
                    Console.WriteLine($"Invalid PipId: {pipHash}. PipId must be a semistable hash that starts with Pip i.e.: PipC623BCE303738C69. Exiting analyzer ...");
                    return(1);
                }
            }
            else
            {
                Console.WriteLine("No pip hash was provided via /p; Dumping all process pips instead.");
            }

            m_commandLineOptions.TryGetValue("/i", out var inputRocksDbDir);

            using (var dataStore = new XldbDataStore(storeDirectory: inputRocksDbDir))
                using (var writer = new StreamWriter(outputFilePath, false))
                {
                    // dump the requested pip
                    if (haveSemiStableHash)
                    {
                        Console.WriteLine($"Dumping PIP for semi-stable hash {parsedSemiStableHash} ...");
                        DumpPip(dataStore, writer, parsedSemiStableHash);
                        return(0);
                    }

                    // dump all pips
                    var message = "// Processes";
                    Console.WriteLine(message);
                    writer.WriteLine(message);
                    foreach (var pip in dataStore.GetAllProcessPips())
                    {
                        writer.WriteLine(pip.ToString());
                        writer.WriteLine($"ExecutablePath: {pip.Executable.Path.Value.ToString()}");
                        writer.WriteLine($"Arguments: {pip.Arguments.ToString()}");
                        writer.WriteLine($"WorkingDirectory: {pip.WorkingDirectory.Value.ToString()}");
                    }
                }

            return(0);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Analyzes the event stats from the Xldb instance
        /// </summary>
        public int AnalyzeDbStats()
        {
            if (m_commandLineOptions.ContainsKey("/h"))
            {
                Console.WriteLine("\nDB Stats Analyzer");
                Console.WriteLine("Dumps stats on the aggregate size and count of different items stored in the Xldb instance.");
                Console.WriteLine("/i: \t Required \t The directory to read the RocksDB database from");
                Console.WriteLine("/o: \t Required \t The file where to write the results");
                return(1);
            }

            if (!m_commandLineOptions.TryGetValue("/o", out var outputFilePath))
            {
                Console.WriteLine("Output file required. Exiting analyzer ...");
                return(1);
            }

            m_commandLineOptions.TryGetValue("/i", out var inputRocksDbDir);

            using (var dataStore = new XldbDataStore(storeDirectory: inputRocksDbDir))
                using (var outputStream = File.OpenWrite(outputFilePath))
                    using (var writer = new StreamWriter(outputStream))
                    {
                        var   maxLength       = Enum.GetValues(typeof(DBStoredTypes)).Cast <DBStoredTypes>().Select(e => e.ToString().Length).Max();
                        var   storageMetadata = new List <DBStorageStatsValue>();
                        ulong totalCount      = 0;
                        ulong totalPayload    = 0;

                        writer.WriteLine("Storage stats (uncompressed) of the DB.\n\n");

                        foreach (DBStoredTypes storageType in Enum.GetValues(typeof(DBStoredTypes)))
                        {
                            var dbStorageStatValue = dataStore.GetDBStatsInfoByStorageType(storageType);

                            if (dbStorageStatValue != null)
                            {
                                totalCount   += dbStorageStatValue.Count;
                                totalPayload += dbStorageStatValue.Size;
                                storageMetadata.Add(dbStorageStatValue);
                            }
                            else
                            {
                                storageMetadata.Add(new DBStorageStatsValue());
                            }
                        }

                        // 12 digits of padding for count/payload
                        var countPadding = 12;
                        // 8 digits of percentage paddin
                        var percentagePadding = 8;

                        for (var i = 0; i < storageMetadata.Count; i++)
                        {
                            var currDbStorageStatValue = storageMetadata[i];

                            writer.WriteLine(
                                "{0}: Count = {1} K ( {2} %),   Payload = {3} KB ( {4} %)",
                                ((DBStoredTypes)i).ToString().PadRight(maxLength, ' '),
                                (currDbStorageStatValue.Count / m_thousandDivisor).ToString("#.####").PadLeft(countPadding, ' '),
                                (currDbStorageStatValue.Count / (double)totalCount * 100).ToString("#.####").PadLeft(percentagePadding, ' '),
                                (currDbStorageStatValue.Size / m_thousandDivisor).ToString("#.####").PadLeft(countPadding, ' '),
                                (currDbStorageStatValue.Size / (double)totalPayload * 100).ToString("#.####").PadLeft(percentagePadding, ' '));
                        }

                        writer.WriteLine($"\n\nTotal uncompressed storage size is: {totalPayload/m_thousandDivisor} KB");
                    }

            return(0);
        }
        /// <summary>
        /// Dumps the information related to a pip from the Xldb instance
        /// </summary>
        public int AnalyzeDumpPip()
        {
            if (m_commandLineOptions.ContainsKey("/h"))
            {
                Console.WriteLine("\nDump Pip Xldb Analyzer");
                Console.WriteLine("Creates a file containing information about the requested pip, using the RocksDB database as the source");
                Console.WriteLine("/i: \t Required \t The directory to read the RocksDB database from");
                Console.WriteLine("/o: \t Required \t The file where to write the results");
                Console.WriteLine("/p: \t Required \t The formatted semistable hash of a pip to dump (must start with 'Pip', e.g., 'PipC623BCE303738C69')");
                return(1);
            }

            if (!m_commandLineOptions.TryGetValue("/p", out var pipHash))
            {
                Console.WriteLine("Pip Semistable Hash is required. Exiting analyzer ...");
                return(1);
            }

            if (!ParseSemistableHash(pipHash, out var parsedSemiStableHash))
            {
                Console.WriteLine($"Invalid pip: {pipHash}. Id must be a semistable hash that starts with Pip i.e.: PipC623BCE303738C69. Exiting analyzer ...");
                return(1);
            }

            if (!m_commandLineOptions.TryGetValue("/o", out var outputFilePath))
            {
                Console.WriteLine("Output directory required. Exiting analyzer ...");
                return(1);
            }

            m_commandLineOptions.TryGetValue("/i", out var inputRocksDbDir);

            using (var dataStore = new XldbDataStore(storeDirectory: inputRocksDbDir))
                using (var outputStream = File.OpenWrite(outputFilePath))
                    using (var writer = new StreamWriter(outputStream))
                    {
                        var pip = dataStore.GetPipBySemiStableHash(parsedSemiStableHash, out var pipType);

                        if (pip == null)
                        {
                            Console.WriteLine($"Pip with the SemiStableHash {parsedSemiStableHash} was not found. Exiting Analyzer ...");
                            return(1);
                        }
                        Console.WriteLine($"Pip with the SemiStableHash {parsedSemiStableHash} was found. Logging to output file ...");

                        dynamic castedPip = null;

                        switch (pipType)
                        {
                        case PipType.CopyFile:
                            castedPip = (CopyFile)pip;
                            break;

                        case PipType.SealDirectory:
                            castedPip = (SealDirectory)pip;
                            break;

                        case PipType.WriteFile:
                            castedPip = (WriteFile)pip;
                            break;

                        case PipType.Process:
                            castedPip = (ProcessPip)pip;
                            break;

                        case PipType.Ipc:
                            castedPip = (IpcPip)pip;
                            break;
                        }

                        writer.WriteLine(pipType.ToString());
                        writer.WriteLine(pip.ToString());

                        dataStore.GetBXLInvocationEvents().ToList().ForEach(ev => writer.WriteLine(ev.ToString()));

                        writer.WriteLine(dataStore.GetEventByKey(ExecutionEventId.PipExecutionPerformance, castedPip.GraphInfo.PipId)?.ToString() ?? "PipExecutionPerformance empty or null");
                        writer.WriteLine(dataStore.GetEventByKey(ExecutionEventId.PipExecutionStepPerformanceReported, castedPip.GraphInfo.PipId)?.ToString() ?? "PipExecutionStepPerformanceReported empty or null");
                        writer.WriteLine(dataStore.GetEventByKey(ExecutionEventId.ProcessExecutionMonitoringReported, castedPip.GraphInfo.PipId)?.ToString() ?? "ProcessExecutionMonitoringReported empty or null");
                        writer.WriteLine(dataStore.GetEventByKey(ExecutionEventId.ProcessFingerprintComputation, castedPip.GraphInfo.PipId)?.ToString() ?? "ProcessFingerprintComputation empty or null");
                        writer.WriteLine(dataStore.GetEventByKey(ExecutionEventId.ObservedInputs, castedPip.GraphInfo.PipId)?.ToString() ?? "ObservedInputs empty or null");
                        writer.WriteLine(dataStore.GetEventByKey(ExecutionEventId.DirectoryMembershipHashed, castedPip.GraphInfo.PipId)?.ToString() ?? "DirectoryMembershipHashed empty or null");

                        var depViolatedEvents = dataStore.GetDependencyViolationReportedEvents();

                        foreach (var ev in depViolatedEvents)
                        {
                            if (ev.ViolatorPipID == castedPip.GraphInfo.PipId || ev.RelatedPipID == castedPip.GraphInfo.PipId)
                            {
                                writer.WriteLine(ev.ToString());
                            }
                        }

                        if (pipType == PipType.Process)
                        {
                            writer.WriteLine("Getting directory output information for Process Pip");
                            var pipExecutionDirEvents = dataStore.GetPipExecutionDirectoryOutputsEvents();
                            foreach (var ev in pipExecutionDirEvents)
                            {
                                foreach (var dirOutput in ev.DirectoryOutput)
                                {
                                    if (castedPip.DirectoryOutputs.Contains(dirOutput.DirectoryArtifact))
                                    {
                                        dirOutput.FileArtifactArray.ToList().ForEach(file => writer.WriteLine(file.ToString()));
                                    }
                                }
                            }

                            writer.WriteLine("Geting directory dependency information for Process Pip");

                            var pipGraph    = dataStore.GetPipGraphMetaData();
                            var directories = new Stack <(DirectoryArtifact artifact, string path)>(
                                ((ProcessPip)castedPip).DirectoryDependencies
                                .Select(d => (artifact: d, path: d.Path.Value))
                                .OrderByDescending(tupple => tupple.path));

                            while (directories.Count > 0)
                            {
                                var directory = directories.Pop();
                                writer.WriteLine(directory.ToString());

                                foreach (var kvp in pipGraph.AllSealDirectoriesAndProducers)
                                {
                                    if (kvp.Artifact == directory.artifact)
                                    {
                                        var currPipId = kvp.Value;
                                        var currPip   = dataStore.GetPipByPipId(currPipId, out var currPipType);

                                        if (currPipType == PipType.SealDirectory)
                                        {
                                            foreach (var nestedDirectory in ((SealDirectory)currPip).ComposedDirectories.Select(d => (artifact: d, path: d.Path.Value)).OrderByDescending(tupple => tupple.path))
                                            {
                                                directories.Push((nestedDirectory.artifact, nestedDirectory.path));
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }

            return(0);
        }
        /// <summary>
        /// Analyzes the event stats from the Xldb instance
        /// </summary>
        public int AnalyzeEventStats()
        {
            if (m_commandLineOptions.ContainsKey("/h"))
            {
                Console.WriteLine("\nEvent Stats Analyzer");
                Console.WriteLine("Generates stats on the aggregate size and count of execution log events, but uses the RocksDB database as the source of truth");
                Console.WriteLine("/i: \t Required \t The directory to read the RocksDB database from");
                Console.WriteLine("/o: \t Required \t The file where to write the results");
                return(1);
            }

            if (!m_commandLineOptions.TryGetValue("/o", out var outputFilePath))
            {
                Console.WriteLine("Output directory required. Exiting analyzer ...");
                return(1);
            }

            m_commandLineOptions.TryGetValue("/i", out var inputRocksDbDir);

            using (var dataStore = new XldbDataStore(storeDirectory: inputRocksDbDir))
                using (var outputStream = File.OpenWrite(outputFilePath))
                    using (var writer = new StreamWriter(outputStream))
                    {
                        var workerToEventDict = new Dictionary <uint, Dictionary <ExecutionEventId, (int, int)> >();
                        foreach (ExecutionEventId eventId in Enum.GetValues(typeof(ExecutionEventId)))
                        {
                            var eventCount = dataStore.GetCountByEvent(eventId);

                            if (eventCount != null)
                            {
                                foreach (var workerCount in eventCount.WorkerToCountMap)
                                {
                                    if (workerToEventDict.TryGetValue(workerCount.Key, out var eventDict))
                                    {
                                        eventDict[eventId] = (workerCount.Value, 0);
                                    }
                                    else
                                    {
                                        var dict = new Dictionary <ExecutionEventId, (int, int)>();
                                        dict.Add(eventId, (workerCount.Value, 0));
                                        workerToEventDict.Add(workerCount.Key, dict);
                                    }
                                }
                                foreach (var payloadSize in eventCount.WorkerToPayloadMap)
                                {
                                    workerToEventDict.TryGetValue(payloadSize.Key, out var eventDict);
                                    eventDict.TryGetValue(eventId, out var tup);
                                    eventDict[eventId] = (tup.Item1, payloadSize.Value);
                                }
                            }
                        }

                        foreach (var workerDict in workerToEventDict)
                        {
                            writer.WriteLine("Worker {0}", workerDict.Key);
                            var maxLength = Enum.GetValues(typeof(ExecutionEventId)).Cast <ExecutionEventId>().Select(e => e.ToString().Length).Max();
                            foreach (var eventStats in workerDict.Value)
                            {
                                writer.WriteLine(
                                    "{0}: {1} Count = {2}",
                                    eventStats.Key.ToString().PadRight(maxLength, ' '),
                                    eventStats.Value.Item2.ToString(CultureInfo.InvariantCulture).PadLeft(12, ' '),
                                    eventStats.Value.Item1.ToString(CultureInfo.InvariantCulture).PadLeft(12, ' '));
                            }
                            writer.WriteLine();
                        }
                    }

            return(0);
        }
Ejemplo n.º 9
0
        public override int Analyze()
        {
            using (var dataStore = new XldbDataStore(storeDirectory: m_inputDirPath))
                using (var outputStream = File.OpenWrite(m_outputFilePath))
                    using (var writer = new StreamWriter(outputStream))
                    {
                        var pip = dataStore.GetPipBySemiStableHash(m_semiStableHash, out var pipType);

                        if (pip == null)
                        {
                            Console.WriteLine($"Pip with the SemiStableHash {m_semiStableHash} was not found. Exiting Analyzer ...");
                            return(1);
                        }
                        Console.WriteLine($"Pip with the SemiStableHash {m_semiStableHash} was found. Logging to output file ...");

                        dynamic castedPip = null;

                        switch (pipType)
                        {
                        case PipType.CopyFile:
                            castedPip = (CopyFile)pip;
                            break;

                        case PipType.SealDirectory:
                            castedPip = (SealDirectory)pip;
                            break;

                        case PipType.WriteFile:
                            castedPip = (WriteFile)pip;
                            break;

                        case PipType.Process:
                            castedPip = (ProcessPip)pip;
                            break;

                        case PipType.Ipc:
                            castedPip = (IpcPip)pip;
                            break;
                        }

                        writer.WriteLine(pipType.ToString());
                        writer.WriteLine(pip.ToString());

                        dataStore.GetBXLInvocationEvents().ToList().ForEach(ev => writer.WriteLine(ev.ToString()));

                        writer.WriteLine(dataStore.GetEventByKey(ExecutionEventId.PipExecutionPerformance, castedPip.GraphInfo.PipId)?.ToString() ?? "PipExecutionPerformance empty or null");
                        writer.WriteLine(dataStore.GetEventByKey(ExecutionEventId.PipExecutionStepPerformanceReported, castedPip.GraphInfo.PipId)?.ToString() ?? "PipExecutionStepPerformanceReported empty or null");
                        writer.WriteLine(dataStore.GetEventByKey(ExecutionEventId.ProcessExecutionMonitoringReported, castedPip.GraphInfo.PipId)?.ToString() ?? "ProcessExecutionMonitoringReported empty or null");
                        writer.WriteLine(dataStore.GetEventByKey(ExecutionEventId.ProcessFingerprintComputation, castedPip.GraphInfo.PipId)?.ToString() ?? "ProcessFingerprintComputation empty or null");
                        writer.WriteLine(dataStore.GetEventByKey(ExecutionEventId.ObservedInputs, castedPip.GraphInfo.PipId)?.ToString() ?? "ObservedInputs empty or null");
                        writer.WriteLine(dataStore.GetEventByKey(ExecutionEventId.DirectoryMembershipHashed, castedPip.GraphInfo.PipId)?.ToString() ?? "DirectoryMembershipHashed empty or null");

                        var depViolatedEvents = dataStore.GetDependencyViolationReportedEvents();

                        foreach (var ev in depViolatedEvents)
                        {
                            if (ev.ViolatorPipID == castedPip.GraphInfo.PipId || ev.RelatedPipID == castedPip.GraphInfo.PipId)
                            {
                                writer.WriteLine(ev.ToString());
                            }
                        }

                        if (pipType == PipType.Process)
                        {
                            writer.WriteLine("Getting directory output information for Process Pip");
                            var pipExecutionDirEvents = dataStore.GetPipExecutionDirectoryOutputsEvents();
                            foreach (var ev in pipExecutionDirEvents)
                            {
                                foreach (var dirOutput in ev.DirectoryOutput)
                                {
                                    if (castedPip.DirectoryOutputs.Contains(dirOutput.DirectoryArtifact))
                                    {
                                        dirOutput.FileArtifactArray.ToList().ForEach(file => writer.WriteLine(file.ToString()));
                                    }
                                }
                            }

                            writer.WriteLine("Geting directory dependency information for Process Pip");

                            var pipGraph    = dataStore.GetPipGraphMetaData();
                            var directories = new Stack <(DirectoryArtifact artifact, string path)>(
                                ((ProcessPip)castedPip).DirectoryDependencies
                                .Select(d => (artifact: d, path: d.Path.Value))
                                .OrderByDescending(tupple => tupple.path));

                            while (directories.Count > 0)
                            {
                                var directory = directories.Pop();
                                writer.WriteLine(directory.ToString());

                                foreach (var kvp in pipGraph.AllSealDirectoriesAndProducers)
                                {
                                    if (kvp.Artifact == directory.artifact)
                                    {
                                        var currPipId = kvp.Value;
                                        var currPip   = dataStore.GetPipByPipId(currPipId, out var currPipType);

                                        if (currPipType == PipType.SealDirectory)
                                        {
                                            foreach (var nestedDirectory in ((SealDirectory)currPip).ComposedDirectories.Select(d => (artifact: d, path: d.Path.Value)).OrderByDescending(tupple => tupple.path))
                                            {
                                                directories.Push((nestedDirectory.artifact, nestedDirectory.path));
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }

            return(0);
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Dumps the information related to a pip from the Xldb instance
        /// </summary>
        public int AnalyzeDumpPip()
        {
            if (m_commandLineOptions.ContainsKey("/h"))
            {
                Console.WriteLine("\nDump Pip Xldb Analyzer");
                Console.WriteLine("Creates a file containing information about the requested pip, using the RocksDB database as the source");
                Console.WriteLine("/i: \t Required \t The directory to read the RocksDB database from");
                Console.WriteLine("/o: \t Required \t The file where to write the results");
                Console.WriteLine("/p: \t Required \t The formatted semistable hash of a pip to dump (must start with 'Pip', e.g., 'PipC623BCE303738C69')");
                return(1);
            }

            if (!m_commandLineOptions.TryGetValue("/p", out var pipHash))
            {
                Console.WriteLine("Pip Semistable Hash is required. Exiting analyzer ...");
                return(1);
            }

            if (!ParseSemistableHash(pipHash, out var parsedSemiStableHash))
            {
                Console.WriteLine($"Invalid pip: {pipHash}. Id must be a semistable hash that starts with Pip i.e.: PipC623BCE303738C69. Exiting analyzer ...");
                return(1);
            }

            if (!m_commandLineOptions.TryGetValue("/o", out var outputFilePath))
            {
                Console.WriteLine("Output directory required. Exiting analyzer ...");
                return(1);
            }

            m_commandLineOptions.TryGetValue("/i", out var inputRocksDbDir);

            using (var dataStore = new XldbDataStore(storeDirectory: inputRocksDbDir))
                using (var outputStream = File.OpenWrite(outputFilePath))
                    using (var writer = new StreamWriter(outputStream))
                    {
                        var pip = dataStore.GetPipBySemiStableHash(parsedSemiStableHash, out var pipType);

                        if (pip == null)
                        {
                            Console.WriteLine($"Pip with the SemiStableHash {parsedSemiStableHash} was not found. Exiting Analyzer ...");
                            return(1);
                        }
                        Console.WriteLine($"Pip with the SemiStableHash {parsedSemiStableHash} was found. Logging to output file ...");

                        dynamic castedPip = null;

                        switch (pipType)
                        {
                        case PipType.CopyFile:
                            castedPip = (CopyFile)pip;
                            break;

                        case PipType.SealDirectory:
                            castedPip = (SealDirectory)pip;
                            break;

                        case PipType.WriteFile:
                            castedPip = (WriteFile)pip;
                            break;

                        case PipType.Process:
                            castedPip = (ProcessPip)pip;
                            break;

                        case PipType.Ipc:
                            castedPip = (IpcPip)pip;
                            break;
                        }

                        writer.WriteLine($"PipType: {pipType.ToString()}");
                        writer.WriteLine("Pip Information: \n" + JsonConvert.SerializeObject(pip, Formatting.Indented));

                        uint pipId = castedPip.GraphInfo.PipId;

                        writer.WriteLine("Pip Execution Performance Information:\n");
                        foreach (var i in dataStore.GetPipExecutionPerformanceEventByKey(pipId))
                        {
                            writer.WriteLine(JToken.Parse(JsonConvert.SerializeObject(i, Formatting.Indented)));
                        }

                        writer.WriteLine("Pip Execution Step Performance Information:\n");
                        foreach (var i in dataStore.GetPipExecutionStepPerformanceEventByKey(pipId))
                        {
                            writer.WriteLine(JToken.Parse(JsonConvert.SerializeObject(i, Formatting.Indented)));
                        }

                        writer.WriteLine("Process Execution Monitoring Information:\n");
                        foreach (var i in dataStore.GetProcessExecutionMonitoringReportedEventByKey(pipId))
                        {
                            writer.WriteLine(JToken.Parse(JsonConvert.SerializeObject(i, Formatting.Indented)));
                        }

                        writer.WriteLine("Process Fingerprint Computation Information:\n");
                        foreach (var i in dataStore.GetProcessFingerprintComputationEventByKey(pipId))
                        {
                            writer.WriteLine(JToken.Parse(JsonConvert.SerializeObject(i, Formatting.Indented)));
                        }

                        writer.WriteLine("Directory Membership Hashted Information:\n");
                        foreach (var i in dataStore.GetDirectoryMembershipHashedEventByKey(pipId))
                        {
                            writer.WriteLine(JToken.Parse(JsonConvert.SerializeObject(i, Formatting.Indented)));
                        }

                        writer.WriteLine("Dependency Violation Reported Event:\n");
                        var depViolationEvents = dataStore.GetDependencyViolatedEventByKey(pipId);

                        foreach (var ev in depViolationEvents)
                        {
                            writer.WriteLine(JsonConvert.SerializeObject(ev, Formatting.Indented));
                        }

                        if (pipType == PipType.Process)
                        {
                            writer.WriteLine("Getting directory output information for Process Pip");

                            foreach (var output in dataStore.GetPipExecutionDirectoryOutputEventByKey(pipId))
                            {
                                foreach (var file in output.FileArtifactArray)
                                {
                                    writer.WriteLine(JsonConvert.SerializeObject(file, Formatting.Indented));
                                }
                            }

                            writer.WriteLine("Geting directory dependency information for Process Pip");

                            var pipGraph = dataStore.GetPipGraphMetaData();
                            var sealDirectoryAndProducersDict = new Dictionary <DirectoryArtifact, uint>();

                            foreach (var kvp in pipGraph.AllSealDirectoriesAndProducers)
                            {
                                sealDirectoryAndProducersDict.Add(kvp.Artifact, kvp.PipId);
                            }

                            var directories = new Stack <(DirectoryArtifact artifact, string path)>(
                                ((ProcessPip)castedPip).DirectoryDependencies
                                .Select(d => (artifact: d, path: d.Path.Value))
                                .OrderByDescending(tupple => tupple.path));

                            while (directories.Count > 0)
                            {
                                var directory = directories.Pop();
                                writer.WriteLine(JsonConvert.SerializeObject(directory, Formatting.Indented));

                                if (sealDirectoryAndProducersDict.TryGetValue(directory.artifact, out var currentPipId))
                                {
                                    var currPip = dataStore.GetPipByPipId(currentPipId, out var currPipType);

                                    if (currPipType == PipType.SealDirectory)
                                    {
                                        foreach (var nestedDirectory in ((SealDirectory)currPip).ComposedDirectories.Select(d => (artifact: d, path: d.Path.Value)).OrderByDescending(tuple => tuple.path))
                                        {
                                            directories.Push((nestedDirectory.artifact, nestedDirectory.path));
                                        }
                                    }
                                }
                            }
                        }
                    }

            return(0);
        }