Beispiel #1
0
            public Covered Merge(Covered other)
            {
                if (other.MethodName != MethodName)
                {
                    throw new Exception("Can't merge with different names");
                }
                if (other.SequencePoints.Length != SequencePoints.Length)
                {
                    throw new Exception("uhhhh");
                }

                var inner = new SequencePoint[SequencePoints.Length];

                for (var i = 0; i < SequencePoints.Length; i++)
                {
                    var selfPoint  = SequencePoints[i];
                    var otherPoint = other.SequencePoints[i];
                    if (selfPoint.Visited)
                    {
                        inner[i] = selfPoint;
                    }
                    else
                    {
                        inner[i] = otherPoint;
                    }
                }

                return(new Covered(MethodName, inner));
            }
Beispiel #2
0
        public void Click([Frozen] Cell cell, Covered sut)
        {
            // Act
            sut.Click();

            // Assert
            cell.CoverState.Should().BeOfType <Uncovered>();
        }
Beispiel #3
0
        public void RightClick([Frozen] Cell cell, Covered sut)
        {
            // Act
            sut.RightClick();

            // Assert
            cell.CoverState.Should().BeOfType <Flaged>();
        }
Beispiel #4
0
        public void SquareRoot_ThrowsOnNegative()
        {
            var covered = new Covered();

            new Action(() => covered.SquareRoot(-25)).Should().Throw <NotImplementedException>();
        }
Beispiel #5
0
        public void SquareRoot_ThrowsOnNonIntegerRoot()
        {
            var covered = new Covered();

            new Action(() => covered.SquareRoot(37)).Should().Throw <NotImplementedException>();
        }
Beispiel #6
0
        static Dictionary <string, TestResult> ShardAndCollect(List <string> testNames, out List <Covered> covered)
        {
            var finished = 0;

            // all this just so we can make sure the subprocesses die when their parent does
            var _    = new Extern.SECURITY_ATTRIBUTES {
            };
            var job  = Extern.CreateJobObject(ref _, "LinqAF.TestRunner");
            var info = new Extern.JOBOBJECT_BASIC_LIMIT_INFORMATION();

            info.LimitFlags = 0x2000;   // JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE

            var extendedInfo = new Extern.JOBOBJECT_EXTENDED_LIMIT_INFORMATION();

            extendedInfo.BasicLimitInformation = info;

            int length          = Marshal.SizeOf(typeof(Extern.JOBOBJECT_EXTENDED_LIMIT_INFORMATION));
            var extendedInfoPtr = Marshal.AllocHGlobal(length);

            Marshal.StructureToPtr(extendedInfo, extendedInfoPtr, false);

            if (!Extern.SetInformationJobObject(job, Extern.JobObjectInfoType.ExtendedLimitInformation, extendedInfoPtr, (uint)length))
            {
                throw new Exception("Wat");
            }

            var results = new Dictionary <string, TestResult>();

            var runningProcesses     = new List <Tuple <Process, Thread, Thread> >();
            var pendingProcessStarts = new Queue <ProcessStartInfo>();

            string currentProcFile;

            using (var proc = Process.GetCurrentProcess())
            {
                currentProcFile = proc.MainModule.FileName;
            }

            var coveredRefLock = new object();
            IEnumerable <Covered> coveredRef = null;

            foreach (var name in testNames)
            {
                var procStart =
                    new ProcessStartInfo
                {
                    FileName               = currentProcFile,
                    Arguments              = name,
                    CreateNoWindow         = true,
                    RedirectStandardError  = true,
                    RedirectStandardOutput = true,
                    UseShellExecute        = false
                };

                pendingProcessStarts.Enqueue(procStart);
            }

            Func <int> getPendingProcessStartsCount =
                () =>
            {
                lock (pendingProcessStarts)
                {
                    return(pendingProcessStarts.Count);
                }
            };

            while (getPendingProcessStartsCount() > 0 || runningProcesses.Count > 0)
            {
                Thread.Sleep(TimeSpan.FromSeconds(1));

                for (var i = runningProcesses.Count - 1; i >= 0; i--)
                {
                    var t         = runningProcesses[i];
                    var proc      = t.Item1;
                    var outThread = t.Item2;
                    var errThread = t.Item3;

                    if (!outThread.IsAlive && !errThread.IsAlive && proc.HasExited)
                    {
                        runningProcesses.RemoveAt(i);
                        proc.Dispose();
                    }
                }

                if (runningProcesses.Count >= UseProceses())
                {
                    continue;
                }

                if (getPendingProcessStartsCount() > 0)
                {
                    ProcessStartInfo next;

                    lock (pendingProcessStarts)
                    {
                        next = pendingProcessStarts.Dequeue();
                    }
                    var newProc = Process.Start(next);

                    Extern.AssignProcessToJobObject(job, newProc.Handle);

                    if (Debugger.IsAttached)
                    {
                        AttachDebugger(newProc);
                    }

                    var outThread =
                        new Thread(
                            () =>
                    {
                        while (!newProc.HasExited)
                        {
                            // need to read it off, but needn't actually print it
                            var toWrite = newProc.StandardOutput.ReadLine();
                            //Console.WriteLine($"[Proc: {newProc.Id}]: {toWrite}");
                        }
                    }
                            );

                    var errThread =
                        new Thread(
                            () =>
                    {
                        var needsHandling = new StringBuilder();

                        while (!newProc.HasExited)
                        {
                            int c;
                            while ((c = newProc.StandardError.Read()) != -1)
                            {
                                needsHandling.Append((char)c);
                            }
                        }

                        var json = needsHandling.ToString();
                        dynamic data;

                        try
                        {
                            data = JSON.DeserializeDynamic(json);
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine($"[Proc: {newProc.Id}] ({next.Arguments}) ~~CRASHED~~");
                            Console.WriteLine(e.Message);
                            Console.WriteLine(e.StackTrace);

                            Console.WriteLine("Rescheduling");
                            lock (pendingProcessStarts)
                            {
                                pendingProcessStarts.Enqueue(next);
                            }

                            return;
                        }

                        foreach (var entry in data)
                        {
                            string name                = entry.TestName;
                            string errorMessage        = entry.ErrorMessage;
                            string testCoverageEncoded = entry.TestCoverageEncoded;
                            lock (results)
                            {
                                results[name] =
                                    new TestResult
                                {
                                    ErrorMessage = errorMessage,
                                    Coverage     = null
                                };
                            }

                            double coverageRate;

                            var parsedCoverage = Covered.DecodeList(testCoverageEncoded);
                            if (parsedCoverage != null)
                            {
                                lock (coveredRefLock)
                                {
                                    if (coveredRef == null)
                                    {
                                        coveredRef   = parsedCoverage;
                                        coverageRate = double.NaN;
                                    }
                                    else
                                    {
                                        coveredRef = Covered.Merge(coveredRef.Concat(parsedCoverage).AsEnumerable());
                                    }

                                    var total100 = coveredRef.Count(c => c.CoveragePercent >= 100);
                                    var total    = coveredRef.Count();

                                    coverageRate = Math.Round(((double)total100) / (double)total * 100.0, 1);
                                }
                            }
                            else
                            {
                                coverageRate = double.NaN;
                            }

                            var num = Interlocked.Increment(ref finished);

                            if (errorMessage == null)
                            {
                                if (!double.IsNaN(coverageRate))
                                {
                                    Console.WriteLine($"[Proc: {newProc.Id}] ({num}/{testNames.Count}): {name} PASSED (covered methods: {coverageRate}%)");
                                }
                                else
                                {
                                    Console.WriteLine($"[Proc: {newProc.Id}] ({num}/{testNames.Count}): {name} PASSED");
                                }
                            }
                            else
                            {
                                Console.WriteLine($"[Proc: {newProc.Id}] ({num}/{testNames.Count}): {name} !!FAILED!!");
                            }
                        }
                    }
                            );

                    outThread.IsBackground = true;
                    errThread.IsBackground = true;

                    outThread.Start();
                    errThread.Start();

                    runningProcesses.Add(Tuple.Create(newProc, outThread, errThread));
                }
            }

            covered = coveredRef?.ToList();
            return(results);
        }
Beispiel #7
0
        static void Main(string[] args)
        {
            const bool defaultSuppressCoverage = true;  // set false to collect coverage, true to not

            var run = new List <Test>();
            var asm = Assembly.Load("LinqAF.Tests");

            List <Covered> covered;
            Dictionary <string, TestResult> results;

            var masterProcess = false;

            IDisposable redirecting;

            if (args.Length == 0)
            {
                redirecting = RedirectOut();

                var tests = new List <string>();

                foreach (var @class in asm.GetTypes())
                {
                    if (@class.GetCustomAttribute <TestClassAttribute>() != null)
                    {
                        tests.AddRange(QueueTests(@class, suppressCoverage: defaultSuppressCoverage).Select(t => t.Name).AsEnumerable());
                    }
                }

                tests = tests.OrderBy(x => x).ToList();

                Console.WriteLine($"Queuing {tests.Count} tests on {UseProceses()} different processes");

                results       = ShardAndCollect(tests, out covered);
                masterProcess = true;
            }
            else
            {
                redirecting = null;

                covered = null;
                var suppressCoverage = args.Length > 1 ? args[1] == "no-coverage" : defaultSuppressCoverage;

                var testNames = new HashSet <string>(args[0].Split(';'));

                var classes = testNames.Select(t => t.Substring(0, t.IndexOf('.'))).ToList();

                foreach (var @class in asm.GetTypes())
                {
                    if (@class.GetCustomAttribute <TestClassAttribute>() != null)
                    {
                        if (classes.Contains(@class.Name))
                        {
                            var testsOnClass = QueueTests(@class, suppressCoverage);
                            var toRun        = testsOnClass.Where(c => testNames.Contains(c.Name)).AsEnumerable();

                            run.AddRange(toRun);
                        }
                    }
                }

                results = new Dictionary <string, TestResult>();

                foreach (var test in run.OrderBy(r => r.Name))
                {
                    List <Covered> coverage;
                    string         errorMessage;
                    if (!test.Run(out coverage, out errorMessage))
                    {
                        results[test.Name] =
                            new TestResult
                        {
                            ErrorMessage = errorMessage,
                            Coverage     = null
                        };
                    }
                    else
                    {
                        results[test.Name] =
                            new TestResult
                        {
                            ErrorMessage = null,
                            Coverage     = coverage
                        };
                    }
                }

                var data = results.Select(kv => new { TestName = kv.Key, ErrorMessage = kv.Value.ErrorMessage, TestCoverageEncoded = Covered.EncodeList(kv.Value.Coverage) }).ToList();
                var json = JSON.Serialize(data, Options.PrettyPrint);
                Console.Error.Write(json);
            }

            var passedCount = results.Count(kv => kv.Value.ErrorMessage == null);
            var runCount    = results.Count;

            Console.WriteLine($"{passedCount}/{runCount} tests passed");
            foreach (var kv in results)
            {
                if (kv.Value.ErrorMessage != null)
                {
                    Console.WriteLine($"Failed: {kv.Key}");
                    Console.WriteLine(kv.Value.ErrorMessage);
                }
            }

            if (masterProcess)
            {
                Console.WriteLine();

                if (covered != null)
                {
                    covered.Sort((x, y) => - (x.CoveragePercent.CompareTo(y.CoveragePercent)));

                    var totalMethods = covered.Count;
                    var at100        = covered.Count(c => c.CoveragePercent >= 100);
                    var covPer       = ((double)at100) / (double)totalMethods * 100.0;
                    Console.WriteLine($"{at100}/{totalMethods} methods ({Math.Round(covPer, 1)}%) at 100% code coverage");

                    Console.WriteLine("Press any key to dump 0% coverage methods");
                    Console.ReadKey();

                    foreach (var method in covered.Where(p => p.CoveragePercent <= 0))
                    {
                        Console.WriteLine($"\t{method.NiceMethodName} at {Math.Round(method.CoveragePercent, 1)}% coverage");
                    }
                }

#if DEBUG
                Console.WriteLine();
                Console.WriteLine("Press any key to exit");
                Console.ReadKey();
#endif
            }

            redirecting?.Dispose();
        }
Beispiel #8
0
 public void ReturnToString(Covered sut)
 {
     // Assert
     sut.ToString().Should().Be(".");
 }