Example #1
0
        /// <summary>
        /// Dumps the given item from the given cache and container.
        /// </summary>
        /// <param name="cache">Cache to look in.</param>
        /// <param name="container">Container to look in.</param>
        /// <param name="item">Item to dump.</param>
        private static void DumpItem(IItemCache cache, ItemCacheContainer container, string item)
        {
#if true
            byte[] content = cache.FetchItem(container, item);
            if (content != null)
            {
                BinaryWriter writer = new BinaryWriter(Console.OpenStandardOutput());
                writer.Write(content);
                writer.Close();
            }
#endif
#if false
            ResultSummaryRecord record = FetchRecord(cache, container, item);
            if (record != null)
            {
                Console.WriteLine();
                Console.WriteLine("IsVerificationTimeout = {0}", record.IsVerificationTimeout);
                Console.WriteLine("IsFailure = {0}", record.IsFailure);
            }
            else
            {
                Console.WriteLine();
                Console.WriteLine("FetchRecord failed for {0}", item);
            }
#endif
        }
Example #2
0
        /// <summary>
        /// Retrieves the requested result from the given cache.
        /// </summary>
        /// <param name="cache">Cache to query.</param>
        /// <param name="container">Container to query.</param>
        /// <param name="itemHash">Result to get.</param>
        /// <returns>The requested ResultSummaryRecord, or null if not found.</returns>
        private static ResultSummaryRecord FetchRecord(IItemCache cache, ItemCacheContainer container, string itemHash)
        {
            byte[] result = cache.FetchItem(container, itemHash);

            if (result != null)
            {
                MemoryStream resultStream = new MemoryStream(result);
                try
                {
                    using (StreamReader inReader = new StreamReader(resultStream))
                    {
                        string xmlSummary          = inReader.ReadToEnd();
                        ResultSummaryRecord record = ResultSummaryRecord.FromXml(xmlSummary);
                        if (record == null)
                        {
                            Console.WriteLine("FromXml failed for {0}", itemHash);
                        }

                        return(record);
                    }
                }
                catch (System.Xml.XmlException ex)
                {
                    Console.WriteLine("Malformed xml in {0}: {1}", itemHash, ex.ToString());
                    return(null);
                }
                finally
                {
                    resultStream.Dispose();
                }
            }
            else
            {
                Console.WriteLine("FetchItem failed for {0}", itemHash);
                return(null);
            }
        }
Example #3
0
        /// <summary>
        /// Checks the given cache(s) Results and FailedResults for goodness.
        /// </summary>
        /// <param name="queriedCaches">Caches to check.</param>
        /// <param name="cleanup">Whether to cleanup after bad cache entries.</param>
        private static void CheckResults(
            IItemCache[] queriedCaches,
            bool cleanup)
        {
            // We can do this for Local, Cloud, or both.
            foreach (IItemCache cache in queriedCaches)
            {
                // We have one Objects container for objects referenced by
                // results in both the Results and FailedResults containers.
                HashSet <string> objects = cache.GetItemsInContainer(ItemCacheContainer.Objects);

                // Likewise, we have only one Sources container.
                // REVIEW: Should a "source" ever show up as a verb result?
                HashSet <string> sources = cache.GetItemsInContainer(ItemCacheContainer.Sources);

                // We initialize the orphanedObjects set to all objects and
                // then remove objects from the set when we find them listed
                // in a result (stored in either Results or FailedResults).
                HashSet <string> orphanedObjects = cache.GetItemsInContainer(ItemCacheContainer.Objects);

                // We check both successful and failed results.
                foreach (ItemCacheContainer resultsContainer in new ItemCacheContainer[] { ItemCacheContainer.Results, ItemCacheContainer.FailedResults })
                {
                    HashSet <string> parseErrors = new HashSet <string>();

                    // Misfiled results (i.e. failures in Results container or
                    // non-failures in FailedResults container).
                    HashSet <string> misfiledResults = new HashSet <string>();

                    // Results that are missing one or more ouput objects.
                    HashSet <string> resultsMissingOutputs = new HashSet <string>();

                    HashSet <string> missingOutputHashes = new HashSet <string>();
                    HashSet <string> missingOutputPaths  = new HashSet <string>();
                    int timeouts = 0;
                    int failures = 0;
                    int missing  = 0;

                    HashSet <string> results = cache.GetItemsInContainer(resultsContainer);
                    foreach (string result in results)
                    {
                        ResultSummaryRecord record = FetchRecord(cache, resultsContainer, result);
                        if (record == null)
                        {
                            Console.WriteLine("Parse error in {0}.", result);
                            parseErrors.Add(result);
                        }
                        else
                        {
                            if (record.IsFailure)
                            {
                                if (resultsContainer == ItemCacheContainer.Results)
                                {
                                    // We shouldn't have any failures in Results!
                                    misfiledResults.Add(result);
                                }

                                if (record.IsVerificationTimeout)
                                {
                                    ////Console.WriteLine("Timeout in {0}.", result);
                                    timeouts++;
                                }
                                else
                                {
                                    ////Console.WriteLine("Failure in {0}.", result);
                                    failures++;
                                }
                            }
                            else if (resultsContainer == ItemCacheContainer.FailedResults)
                            {
                                // We should only have failures in FailedResults!
                                misfiledResults.Add(result);
                            }

                            // Verify each output is in the cache.
                            bool hasMissingOuputs = false;
                            foreach (BuildObjectValuePointer output in record.Outputs)
                            {
                                if (objects.Contains(output.ObjectHash))
                                {
                                    // Output present in object cache.
                                    // Remove it from orphaned objects list.
                                    orphanedObjects.Remove(output.ObjectHash);
                                }
                                else if (sources.Contains(output.ObjectHash))
                                {
                                    // Output present in sources cache.
                                    Console.WriteLine("Has 'source' file listed as an output: {0}!", result);
                                }
                                else
                                {
                                    // Output missing from both object and sources caches.
                                    hasMissingOuputs = true;
                                    missingOutputHashes.Add(output.ObjectHash);
                                    missingOutputPaths.Add(output.RelativePath);
                                    missing++;
                                    Console.WriteLine("Missing Output Listed in {0}, Object {1} ({2}).", result, output.ObjectHash, output.RelativePath);
                                }
                            }

                            if (hasMissingOuputs)
                            {
                                resultsMissingOutputs.Add(result);
                            }
                        }
                    }

                    Console.WriteLine();
                    Console.WriteLine("Checked {0} results in {1} cache {2} container:", results.Count, cache.Name, resultsContainer.ToString());
                    Console.WriteLine("Corrupted (parsing errors or otherwise unreadable): {0}", parseErrors.Count);
                    Console.WriteLine("Filed in wrong container: {0}", misfiledResults.Count);
                    Console.WriteLine("Timeouts: {0}, Other failures: {1}, Total failures: {2}", timeouts, failures, timeouts + failures);
                    Console.WriteLine("Missing at least one output object: {0}", resultsMissingOutputs.Count);
                    Console.WriteLine("Total missing output objects: {0}, Unique contents: {1}, Unique paths: {2}", missing, missingOutputHashes.Count, missingOutputPaths.Count);
                    Console.WriteLine();

                    if (cleanup)
                    {
                        if (misfiledResults.Count != 0)
                        {
                            Console.Write("Deleting misfiled results...");
                            foreach (string misfiledResult in misfiledResults)
                            {
                                cache.DeleteItem(resultsContainer, misfiledResult);
                            }

                            Console.WriteLine("Done.");
                        }

                        if (resultsMissingOutputs.Count != 0)
                        {
                            Console.Write("Deleting results with missing outputs...");
                            foreach (string resultMissingOutputs in resultsMissingOutputs)
                            {
                                cache.DeleteItem(resultsContainer, resultMissingOutputs);
                            }

                            Console.WriteLine("Done.");
                        }

                        Console.WriteLine();
                    }
                }

                // REVIEW: in at least one instance, we cache an intermediate
                // object that isn't referenced by a result.  That instance is
                // DafnyIncludes.ExpandDafny(), which is called from
                // DafnyCompileOneVerb.  This is to allow cloud execution of the
                // process invoke part of the verb's execution (with the dafny
                // expansion happening in the verb's getWorker() method).  Since
                // ExpandDafny() is a work-around for a Dafny issue, it's not
                // clear whether we should further accommodate this in the build
                // system (i.e. by making ExpandDafny its own verb) or not.
                // At any rate, having orphaned objects is not necessarily bad.
                Console.WriteLine("Orphaned objects not listed in any result: {0}", orphanedObjects.Count);

                if (cleanup)
                {
                    Console.WriteLine();

                    if (orphanedObjects.Count != 0)
                    {
                        Console.Write("Deleting orphaned objects...");
                        foreach (string orphanedObject in orphanedObjects)
                        {
                            cache.DeleteItem(ItemCacheContainer.Objects, orphanedObject);
                        }

                        Console.WriteLine("Done.");
                    }
                }
            }
        }