/// <summary>
        /// Sets the TestScheduler property on the target <paramref name="contextSpecification"/>.
        /// </summary>
        /// <param name="contextSpecification">
        /// The target context specification instance.
        /// </param>
        /// <param name="testScheduler">
        /// The test scheduler to apply to <paramref name="contextSpecification"/>.
        /// </param>
        /// <exception cref="InvalidOperationException">
        /// Thrown when this aspect is applied to a test fixture not defining a TestScheduler property.
        /// </exception>
        private static void SetTestScheduler(IContextSpecification contextSpecification,
                                             [CanBeNull] TestScheduler testScheduler)
        {
            var testSchedulerPropertyInfo = contextSpecification.GetType().GetProperty("TestScheduler", BindingFlags.Instance | BindingFlags.NonPublic);

            if (testSchedulerPropertyInfo == null)
            {
                throw new InvalidOperationException("RxTestSchedulerAspect was applied but the target test fixture does not contain a TestScheduler property.");
            }

            Helper.SetPrivateProperty(contextSpecification, "TestScheduler", testScheduler);
        }
Пример #2
0
        /// <summary>
        /// Sets the TestScheduler property on the target <paramref name="contextSpecification"/>.
        /// </summary>
        /// <param name="contextSpecification">
        /// The target context specification instance.
        /// </param>
        /// <param name="testScheduler">
        /// The test scheduler to apply to <paramref name="contextSpecification"/>.
        /// </param>
        /// <exception cref="InvalidOperationException">
        /// Thrown when this aspect is applied to a test fixture not defining a TestScheduler property.
        /// </exception>
        private static void SetTestScheduler(IContextSpecification contextSpecification,
                                             [CanBeNull] TestScheduler testScheduler)
        {
            var testSchedulerPropertyInfo = contextSpecification.GetType().GetProperty("TestScheduler", BindingFlags.Instance | BindingFlags.NonPublic);

            if (testSchedulerPropertyInfo == null)
            {
                throw new InvalidOperationException("RxTestSchedulerAspect was applied but the target test fixture does not contain a TestScheduler property.");
            }

            Helper.SetPrivateProperty(contextSpecification, "TestScheduler", testScheduler);
        }
Пример #3
0
        /// <summary>
        /// Clear the TestScheduler property and all schedulers in <see cref="SchedulerSwitch"/>.
        /// </summary>
        private void TeardownTestScheduler(IContextSpecification contextSpecification)
        {
            SetTestScheduler(contextSpecification, null);

            SchedulerSwitch.GetCurrentThreadScheduler = null;
            SchedulerSwitch.GetDispatcherScheduler    = null;
            SchedulerSwitch.GetImmediateScheduler     = null;
            SchedulerSwitch.GetNewThreadScheduler     = null;
            SchedulerSwitch.GetTaskPoolScheduler      = null;
            SchedulerSwitch.GetThreadPoolScheduler    = null;

            var testPlatformEnlightenmentProvider = (TestPlatformEnlightenmentProvider)PlatformEnlightenmentProvider.Current;

            testPlatformEnlightenmentProvider.GetTestScheduler = null;
        }
Пример #4
0
        /// <summary>
        /// Determines whether TPL tasks will be run on a given <see cref="IContextSpecification"/>. The <paramref name="contextSpecification"/> instance needs to have the <see cref="TplContextAspect"/> aspect applied to it.
        /// </summary>
        /// <param name="contextSpecification">
        /// The context specification to inspect.
        /// </param>
        /// <returns>
        /// The value defined in <see cref="TplContextAspect.ExecuteTplTasks"/>.
        /// </returns>
        /// <exception cref="InvalidOperationException">The <paramref name="contextSpecification"/> instance does not have <see cref="TplContextAspect"/> applied to it.</exception>
        public static bool WillExecuteTplTasksOn(IContextSpecification contextSpecification)
        {
            var tplContextAspect =
                contextSpecification.GetType()
                                    .GetCustomAttributes(typeof(TplContextAspect), true)
                                    .Cast<TplContextAspect>()
                                    .SingleOrDefault();

            if (tplContextAspect == null)
            {
                throw new InvalidOperationException(string.Format("The {0} test fixture is missing a {1} attribute!", contextSpecification.GetType().FullName, typeof(TplContextAspect).Name));
            }

            return tplContextAspect.ExecuteTplTasks;
        }
Пример #5
0
        /// <summary>
        ///     Helper method that runs a <seealso cref="TestScheduler" /> and waits on a task and tries to replicate the handling
        ///     of exceptions that is achieved with the "await" keyword (not wrapping it in an AggregateException).
        /// </summary>
        /// <param name="testScheduler">The <seealso cref="TestScheduler" /> used in the <paramref name="contextSpecification" />.</param>
        /// <param name="contextSpecification">The current test fixture.</param>
        /// <param name="result">The task to wait on.</param>
        public static void StartWaiting(
            [NotNull] this TestScheduler testScheduler,
            IContextSpecification contextSpecification,
            Task result)
        {
            if (!TplTestHelper.WillExecuteTplTasksOn(contextSpecification))
            {
                return;
            }

            testScheduler.StartWaiting();

            // Emulate the "await" exception handling behavior
            result.Wait(contextSpecification);
        }
Пример #6
0
 /// <summary>
 /// Constructs an object which has a private constructor.
 /// </summary>
 /// <param name="specification">
 /// The specification object.
 /// </param>
 /// <param name="args">
 /// The arguments to pass to the constructor.
 /// </param>
 /// <typeparam name="T">
 /// The concrete object type.
 /// </typeparam>
 /// <returns>
 /// The constructed object.
 /// </returns>
 /// <exception cref="Exception">
 /// Returns any exception thrown by <see cref="Activator.CreateInstance(System.Type,System.Reflection.BindingFlags,System.Reflection.Binder,object[],System.Globalization.CultureInfo)"/>. Unwraps <see cref="TargetInvocationException"/>.
 /// </exception>
 public static T InstancePrivateObject <T>(this IContextSpecification specification,
                                           params object[] args)
 {
     try
     {
         return((T)Activator.CreateInstance(typeof(T),
                                            BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.CreateInstance,
                                            null,
                                            args,
                                            null));
     }
     catch (TargetInvocationException exception)
     {
         throw ExceptionEnlightenment.PrepareForRethrow(exception.InnerException);
     }
 }
Пример #7
0
        /// <summary>
        ///     Helper method waits on tasks and tries to replicate the handling of exceptions that is achieved with the "await"
        ///     keyword (not wrapping it in an AggregateException).
        /// </summary>
        /// <param name="result">The task to wait on.</param>
        /// <param name="contextSpecification">The current test fixture.</param>
        public static void Wait(
            this Task result,
            IContextSpecification contextSpecification)
        {
            if (!TplTestHelper.WillExecuteTplTasksOn(contextSpecification))
            {
                return;
            }

            // Emulate the "await" exception handling behavior
            try
            {
                result.Wait(CancellationToken.None);
            }
            catch (AggregateException e)
            {
                throw e.InnerException;
            }
        }
        /// <summary>
        /// Replaces the <see cref="ContextSpecificationBase.PreTestFixtureSetUp"/> method to instantiate the <see cref="TestScheduler"/>
        /// and configure the <see cref="RxSchedulers.Switch.SchedulerSwitch"/>.
        /// </summary>
        private void SetupTestScheduler(IContextSpecification contextSpecification)
        {
            Func<IScheduler> unassignedGuardScheduler = () => { throw new InvalidOperationException("Please assign a scheduler to the respective SchedulerSwitch property. No scheduler is currently assigned."); };

            SchedulerSwitch.GetCurrentThreadScheduler = unassignedGuardScheduler;
            SchedulerSwitch.GetDispatcherScheduler = unassignedGuardScheduler;
            SchedulerSwitch.GetImmediateScheduler = unassignedGuardScheduler;
            SchedulerSwitch.GetNewThreadScheduler = unassignedGuardScheduler;
            SchedulerSwitch.GetTaskPoolScheduler = unassignedGuardScheduler;
            SchedulerSwitch.GetThreadPoolScheduler = unassignedGuardScheduler;

            // Replace the default IConcurrencyAbstractionLayer through a specialized PlatformEnlightenmentProvider,
            // in order to be able to leverage our TestScheduler to introduce virtual time everywhere.
            var testPlatformEnlightenmentProvider = (TestPlatformEnlightenmentProvider)PlatformEnlightenmentProvider.Current;
            var testScheduler = new ThreadLocal<TestScheduler>(() => new TestScheduler());
            testPlatformEnlightenmentProvider.GetTestScheduler = () => testScheduler.Value;

            SetTestScheduler(contextSpecification, testScheduler.Value);
        }
Пример #9
0
        /// <summary>
        ///     Helper method waits on tasks and tries to replicate the handling of exceptions that is achieved with the "await"
        ///     keyword (not wrapping it in an AggregateException).
        /// </summary>
        /// <param name="result">The task to wait on.</param>
        /// <param name="contextSpecification">The current test fixture.</param>
        public static void Wait(
            this Task result,
            IContextSpecification contextSpecification)
        {
            if (!TplTestHelper.WillExecuteTplTasksOn(contextSpecification))
            {
                return;
            }

            // Emulate the "await" exception handling behavior
            try
            {
                result.Wait(CancellationToken.None);
            }
            catch (AggregateException e)
            {
                throw e.InnerException;
            }
        }
Пример #10
0
        /// <summary>
        /// Replaces the <see cref="ContextSpecificationBase.PreTestFixtureSetUp"/> method to instantiate the <see cref="TestScheduler"/>
        /// and configure the <see cref="RxSchedulers.Switch.SchedulerSwitch"/>.
        /// </summary>
        private void SetupTestScheduler(IContextSpecification contextSpecification)
        {
            Func <IScheduler> unassignedGuardScheduler = () => { throw new InvalidOperationException("Please assign a scheduler to the respective SchedulerSwitch property. No scheduler is currently assigned."); };

            SchedulerSwitch.GetCurrentThreadScheduler = unassignedGuardScheduler;
            SchedulerSwitch.GetDispatcherScheduler    = unassignedGuardScheduler;
            SchedulerSwitch.GetImmediateScheduler     = unassignedGuardScheduler;
            SchedulerSwitch.GetNewThreadScheduler     = unassignedGuardScheduler;
            SchedulerSwitch.GetTaskPoolScheduler      = unassignedGuardScheduler;
            SchedulerSwitch.GetThreadPoolScheduler    = unassignedGuardScheduler;

            // Replace the default IConcurrencyAbstractionLayer through a specialized PlatformEnlightenmentProvider,
            // in order to be able to leverage our TestScheduler to introduce virtual time everywhere.
            var testPlatformEnlightenmentProvider = (TestPlatformEnlightenmentProvider)PlatformEnlightenmentProvider.Current;
            var testScheduler = new ThreadLocal <TestScheduler>(() => new TestScheduler());

            testPlatformEnlightenmentProvider.GetTestScheduler = () => testScheduler.Value;

            SetTestScheduler(contextSpecification, testScheduler.Value);
        }
Пример #11
0
 /// <summary>
 /// Called by the framework to register the attribute with the context for setup/teardown notifications.
 /// </summary>
 /// <param name="contextSpecification">
 /// The target context specification instance.
 /// </param>
 public abstract void Register(IContextSpecification contextSpecification);
Пример #12
0
        /// <summary>
        /// Replaces the <see cref="ContextSpecificationBase.PreTestFixtureSetUp"/> method to set the <see cref="TplTestPlatformHelper.TestTaskScheduler"/> as the default scheduler.
        /// </summary>
        /// <param name="contextSpecification">
        /// The target context specification instance.
        /// </param>
        private void SetupTestTaskScheduler(IContextSpecification contextSpecification)
        {
            var testTaskScheduler = new TplTestPlatformHelper.TestTaskScheduler(this.ExecuteTplTasks);

            TplTestPlatformHelper.SetDefaultScheduler(testTaskScheduler);
        }
Пример #13
0
 /// <summary>
 /// Called by the framework to register the attribute with the context for setup/teardown notifications.
 /// </summary>
 /// <param name="contextSpecification">
 /// The target context specification instance.
 /// </param>
 public override void Register(IContextSpecification contextSpecification)
 {
     contextSpecification.SetupTasks.Add(this.SetupTestTaskScheduler);
 }
        /// <summary>
        ///   Method executed when entering a test method.
        /// </summary>
        /// <param name="instance"> The instance of the context specification. </param>
        /// <param name="methodInfo"> The test method. </param>
        /// <param name="becauseAction"> The because method. </param>
        private void OnTestMethodEntry(
            IContextSpecification instance, 
            MethodBase methodInfo, 
            Action becauseAction)
        {
            var isRunningInTheContextOfAnotherTest = instance.ArePrerequisiteTestsRunning;

            if (isRunningInTheContextOfAnotherTest)
            {
                return;
            }

            var isRunningPrerequisite = methodInfo.IsDefined(typeof(PrerequisiteAttribute), true);

            becauseAction();

            if (!isRunningPrerequisite)
            {
                this.RunPrerequisiteTestsMethod();
            }
        }
Пример #15
0
        /// <summary>
        /// Determines whether TPL tasks will be run on a given <see cref="IContextSpecification"/>. The <paramref name="contextSpecification"/> instance needs to have the <see cref="TplContextAspect"/> aspect applied to it.
        /// </summary>
        /// <param name="contextSpecification">
        /// The context specification to inspect.
        /// </param>
        /// <returns>
        /// The value defined in <see cref="TplContextAspect.ExecuteTplTasks"/>.
        /// </returns>
        /// <exception cref="InvalidOperationException">The <paramref name="contextSpecification"/> instance does not have <see cref="TplContextAspect"/> applied to it.</exception>
        public static bool WillExecuteTplTasksOn(IContextSpecification contextSpecification)
        {
            var tplContextAspect =
                contextSpecification.GetType()
                                    .GetCustomAttributes(typeof(TplContextAspect), true)
                                    .Cast<TplContextAspect>()
                                    .SingleOrDefault();

            if (tplContextAspect == null)
            {
                throw new InvalidOperationException(string.Format("The {0} test fixture is missing a {1} attribute!", contextSpecification.GetType().FullName, typeof(TplContextAspect).Name));
            }

            return tplContextAspect.ExecuteTplTasks;
        }
Пример #16
0
        /// <summary>
        /// Replaces the <see cref="ContextSpecificationBase.PreTestFixtureSetUp"/> method to set the <see cref="TplTestPlatformHelper.TestTaskScheduler"/> as the default scheduler.
        /// </summary>
        /// <param name="contextSpecification">
        /// The target context specification instance.
        /// </param>
        private void SetupTestTaskScheduler(IContextSpecification contextSpecification)
        {
            var testTaskScheduler = new TplTestPlatformHelper.TestTaskScheduler(this.ExecuteTplTasks);

            TplTestPlatformHelper.SetDefaultScheduler(testTaskScheduler);
        }
Пример #17
0
 /// <summary>
 /// Called by the framework to register the attribute with the context for setup/teardown notifications.
 /// </summary>
 /// <param name="contextSpecification">
 /// The target context specification instance.
 /// </param>
 public override void Register(IContextSpecification contextSpecification)
 {
     contextSpecification.SetupTasks.Add(this.SetupTestScheduler);
     contextSpecification.TeardownTasks.Add(this.TeardownTestScheduler);
 }
Пример #18
0
        /// <summary>
        /// Determines whether TPL tasks will be run on a given <see cref="IContextSpecification"/>. The <paramref name="contextSpecification"/> instance needs to have the <see cref="TplContextAspectAttribute"/> aspect applied to it.
        /// </summary>
        /// <param name="contextSpecification">
        /// The context specification to inspect.
        /// </param>
        /// <returns>
        /// The value defined in <see cref="TplContextAspectAttribute.ExecuteTplTasks"/>.
        /// </returns>
        /// <exception cref="InvalidOperationException">The <paramref name="contextSpecification"/> instance does not have <see cref="TplContextAspectAttribute"/> applied to it.</exception>
        public static bool WillExecuteTplTasksOn(IContextSpecification contextSpecification)
        {
            var tplContextAspectAttribute =
                contextSpecification.GetType()
                                    .GetCustomAttributes(typeof(TplContextAspectAttribute), true)
                                    .Cast<TplContextAspectAttribute>()
                                    .Single();

            return tplContextAspectAttribute.ExecuteTplTasks;
        }
 /// <summary>
 /// Called by the framework to register the attribute with the context for setup/teardown notifications.
 /// </summary>
 /// <param name="contextSpecification">
 /// The target context specification instance.
 /// </param>
 public abstract void Register(IContextSpecification contextSpecification);
Пример #20
0
        /// <summary>
        /// Clear the TestScheduler property and all schedulers in <see cref="SchedulerSwitch"/>.
        /// </summary>
        private void TeardownTestScheduler(IContextSpecification contextSpecification)
        {
            SetTestScheduler(contextSpecification, null);

            SchedulerSwitch.GetCurrentThreadScheduler = null;
            SchedulerSwitch.GetDispatcherScheduler = null;
            SchedulerSwitch.GetImmediateScheduler = null;
            SchedulerSwitch.GetNewThreadScheduler = null;
            SchedulerSwitch.GetTaskPoolScheduler = null;
            SchedulerSwitch.GetThreadPoolScheduler = null;

            var testPlatformEnlightenmentProvider = (TestPlatformEnlightenmentProvider)PlatformEnlightenmentProvider.Current;
            testPlatformEnlightenmentProvider.GetTestScheduler = null;
        }