Пример #1
0
        static void PrintTest(Type lockType, ILockTest lockTest)
        {
            string lockName = lockType == null ? "No lock" : lockType.ToString();

            Console.WriteLine("Lock: '{0}' - {1}\n\t\tDescription: {2}", lockName, lockTest.GetType().ToString(), lockTest.Description);
        }
Пример #2
0
        static int Main(string[] args)
        {
            testParameters = new TestParameters();

            testParameters.MaxWaitSeconds = 5;

            Type[] lockTypes = new Type[]
            {
                typeof(NoOpLock),
                typeof(SimpleSpinLock),
                typeof(LockTest.Synchronization.SpinLock),
                typeof(Lock)
            };

            TestSpecification[] testSpecifications = new TestSpecification[]
            {
                new TestSpecification(typeof(UnbalancedCallTest), "Unbalanced calls"),
                new TestSpecification(typeof(AutoLockTest), "Automatic lock management"),
                new TestSpecification(typeof(ConcurrencyTest), ConcurrencyTest.Variant.Default, "Concurrent access - 2 threads"),
                new TestSpecification(typeof(ConcurrencyTest), ConcurrencyTest.Variant.ObjectLock, "Concurrent access - 2 threads"),
                new TestSpecification(typeof(ConcurrencyTest), ConcurrencyTest.Variant.ManyThreads, "Concurrent access - many threads"),
                new TestSpecification(typeof(ConcurrencyTest), ConcurrencyTest.Variant.BoundedWait, "Concurrent access - bounded wait sanity"),
                new TestSpecification(typeof(TimeoutTest), "Waits with maximum timeouts")
            };

            if (args.Length > 0 && args[0] == "-?")
            {
                PrintUsage(lockTypes, testSpecifications);
                return -1;
            }

            int argStart = 0;

            if (args.Length > 0)
            {
                if (args[0] == "-t")
                {
                    if (args.Length > 1)
                    {
                        testParameters.MaxWaitSeconds = int.Parse(args[1]);
                    }
                    else
                    {
                        PrintUsage(lockTypes, testSpecifications);
                        return -1;
                    }

                    argStart+=2;
                }
            }

            bool[] variationMask = null;

            int variationsIncluded = lockTypes.Length * testSpecifications.Length;

            if (argStart < args.Length)
            {
                variationsIncluded = 0;
                variationMask = new bool[lockTypes.Length * testSpecifications.Length];

                for (int argumentIndex = argStart; argumentIndex < args.Length; argumentIndex++)
                {
                    uint variationIndex = 0;
                    bool invalidIndex = false;

                    try
                    {
                        variationIndex = uint.Parse(args[argumentIndex]);
                    }
                    catch (FormatException)
                    {
                        invalidIndex = true;
                    }

                    if (!invalidIndex && variationIndex >= variationMask.Length)
                    {
                        invalidIndex = true;
                    }

                    if (invalidIndex)
                    {
                        Console.WriteLine("{0} is not a valid integer test variation", args[argumentIndex]);

                        PrintUsage(lockTypes, testSpecifications);

                        return -1;
                    }

                    variationMask[variationIndex] = true;
                    variationsIncluded++;
                }
            }

            List<Thread> testThreads = new List<Thread>();
            Dictionary<Thread, ILockTest> threadToTestMap = new Dictionary<Thread, ILockTest>();

            int currentVariationIndex = 0;

            foreach (Type lockType in lockTypes)
            {
                ISyncLock syncLock = (ISyncLock)CreateTypeInstance(lockType);

                foreach (TestSpecification testSpecification in testSpecifications)
                {
                    int thisVariationIndex = currentVariationIndex++;

                    if (variationMask != null && !variationMask[thisVariationIndex])
                    {
                        continue;
                    }

                    ILockTest test = CreateTest(testSpecification.TestType, testSpecification.Parameters);

                    Console.WriteLine("Testing: {3}: {0} - Variation: {1}: {2}", (syncLock == null) ? "No lock" : syncLock.ToString(), test, test.Description, thisVariationIndex);

                    test.Initialize();

                    currentTest = test;

                    Thread testThread = new Thread(TestThread);

                    testThreads.Add(testThread);
                    threadToTestMap.Add(testThread, test);

                    testThread.Start(syncLock);

                    int testWaitTime = testParameters.MaxWaitSeconds * 2;

                    bool completedInTime = testThread.Join(testWaitTime * 1000);

                    if (!completedInTime)
                    {
                        if (null == lastTestException)
                        {
                            lastTestException = new TimeoutException(string.Format("Variation failed to complete within {0} seconds", testWaitTime));
                        }
                    }

                    if (lastTestException != null)
                    {
                        Console.Error.WriteLine("Error: {0}: {1}", lastTestException.GetType(), lastTestException.Message);
                        failedTests++;
                        Console.WriteLine("FAILED: {0} - Variation: {1}", syncLock == null ? "No lock" : syncLock.ToString(), currentTest);
                        continue;
                    }

                    passedTests++;
                    Console.WriteLine("PASSED: {0} - Variation: {1}", syncLock, test);
                }
            }

            Console.WriteLine("\t{0} passed, {1} failed, {2} skipped, {3} total", passedTests, failedTests, lockTypes.Length * testSpecifications.Length - variationsIncluded, lockTypes.Length * testSpecifications.Length);

            if (failedTests == 0)
            {
                Console.WriteLine("Success -- all variations passed.");
            }
            else
            {
                Console.WriteLine("Failure -- one or more variations failed");
            }

            foreach (Thread testThread in testThreads)
            {
                Console.WriteLine("Thread id: {0}, State: {1}", testThread.ManagedThreadId, testThread.ThreadState.ToString());

                if (testThread.ThreadState == ThreadState.Running || testThread.ThreadState == ThreadState.WaitSleepJoin)
                {
                    ILockTest runningTest = threadToTestMap[testThread];

                    Console.WriteLine("Unfinished test will be forcibly terminated: {0}: {1}", runningTest.GetType().ToString(), runningTest.Description);

                    testThread.Abort();
                }
            }

            int exitCode = ( failedTests == 0 ) ? 0 : 1;

            Console.WriteLine("Exiting test with {0}\n", exitCode);

            return exitCode;
        }