Example #1
0
 private static void ForEach <T>(IList <T> list, AssertDelegate <T> method)
 {
     for (int i = 0; i < list.Count; i++)
     {
         method(i, list[i]);
     }
 }
Example #2
0
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="test"></param>
        /// <param name="actual"></param>
        /// <param name="expected"></param>
        /// <param name="itemName"></param>
        /// <param name="tokenSelector"></param>
        /// <param name="itemComparer"></param>
        /// <param name="assert"></param>
        public static void ValidateSubset <T>(this BaseTest test, IEnumerable <T> actual,
                                              IEnumerable <T> expected,
                                              string itemName,
                                              Func <T, string> tokenSelector,
                                              Func <T, T, StringBuilder, bool> itemComparer,
                                              AssertDelegate assert)
        {
            bool          ok     = true;
            StringBuilder logger = new StringBuilder();

            List <string> common = new List <string>();

            /****************/

            foreach (T info in expected)
            {
                string token      = tokenSelector(info);
                T[]    foundItems =
                    actual.Where(I => tokenSelector(I) == token).ToArray();

                if (foundItems.Length == 0)
                {
                    logger.AppendFormat(
                        "{0} with token '{1}' not found {2}",
                        itemName, token, Environment.NewLine);
                    ok = false;
                }
                else
                {
                    common.Add(token);
                }
            }

            foreach (T info in actual)
            {
                string token      = tokenSelector(info);
                T[]    foundItems =
                    expected.Where(I => tokenSelector(I) == token).ToArray();

                if (foundItems.Length == 0)
                {
                    logger.AppendFormat(
                        "{0} with token '{1}' not expected {2}",
                        itemName, token, Environment.NewLine);
                    ok = false;
                }
            }

            /****************/

            // for common only
            if (itemComparer != null)
            {
                bool local = ArrayUtils.CompareListItems(actual, expected, tokenSelector, common, itemName, logger,
                                                         itemComparer);
                ok = ok && local;
            }

            assert(ok, logger.ToStringTrimNewLine(), "Check that lists are the same", null);
        }
Example #3
0
        public static void CommonGetInfoTestBody <T>(this BaseTest test,
                                                     Func <List <T> > fullListSelector,
                                                     Func <string, T> infoSelector,
                                                     Func <T, string> tokenSelector,
                                                     Func <T, T, StringBuilder, bool> itemComparison,
                                                     string itemName,
                                                     string getInfoMethodName,
                                                     string getListMethodName,
                                                     AssertDelegate assert)
        {
            // Get valid tokens
            List <T> infos = fullListSelector();

            foreach (T info in infos)
            {
                string token    = tokenSelector(info);
                T      itemInfo = infoSelector(token);

                StringBuilder logger  = new StringBuilder("Information is different:" + Environment.NewLine);
                bool          tokenOk = true;
                if (token != tokenSelector(itemInfo))
                {
                    tokenOk = false;
                    logger.AppendLine("   Token is different");
                }

                bool ok = itemComparison(info, itemInfo, logger);
                ok = ok && tokenOk;

                string stepName = string.Format("Compare {0} got via {1} and via {2}", itemName, getInfoMethodName, getListMethodName);
                assert(ok, logger.ToStringTrimNewLine(), stepName, string.Empty);
            }
        }
Example #4
0
        public static void ValidateFullRecordingsList(GetRecordingsResponseItem[] fullList,
                                                      AssertDelegate assert)
        {
            // check that tokens are unique
            bool          tokensOk = true;
            StringBuilder logger   = new StringBuilder();

            List <string> logged = new List <string>();

            foreach (GetRecordingsResponseItem item in fullList)
            {
                string token = item.RecordingToken;
                int    count = fullList.Where(RI => RI.RecordingToken == token).Count();
                if (count != 1)
                {
                    tokensOk = false;
                    if (!logged.Contains(token))
                    {
                        logged.Add(token);
                        logger.AppendFormat("Token '{0}' is not unique{1}", token, Environment.NewLine);
                    }
                    //break; // ?
                }

                if (item.Configuration == null)
                {
                    logger.AppendFormat("Configuration element is missing for item with token '{0}'{1}", token, Environment.NewLine);
                }
            }

            assert(tokensOk, logger.ToStringTrimNewLine(),
                   "Validate recordings list got from GetRecordings", null);
        }
        public static void ValidateSubscription(DateTime?terminationTime, DateTime currentTime,
                                                int requestedTerminationTime, Event.EndpointReferenceType subscription,
                                                AssertDelegate assert)
        {
            assert(terminationTime.HasValue, "TerminationTime is not specified",
                   "Check that TerminationTime is specified", null);
            if (requestedTerminationTime >= 0)
            {
                assert(currentTime.AddSeconds(requestedTerminationTime) <= terminationTime.Value,
                       "TerminationTime < CurrentTime + InitialTerminationTime",
                       "Validate CurrentTime and TerminationTime", null);
            }
            else
            {
                assert(currentTime < terminationTime.Value,
                       "TerminationTime <= CurrentTime",
                       "Validate CurrentTime and TerminationTime", null);
            }

            assert(subscription != null, "The DUT did not return SubscriptionReference",
                   "Check if the DUT returned SubscriptionReference", null);

            assert(subscription.Address != null && subscription.Address.Value != null,
                   "SubscriptionReference does not contain address",
                   "Check if SubscriptionReference contains address", null);

            assert(subscription.Address.Value.IsValidUrl(), "URL passed in SubscriptionReference is not valid",
                   "Check that URL specified is valid", null);
        }
Example #6
0
        public void GuardedAssert_CallsGuardedFuncIfGuardIsTriggered()
        {
            var funcCalled = false;
            var ass        = AssertDelegate.GuardedAssert(() => { funcCalled = true; return(true); }, () => true);

            Assert.IsTrue(ass());
            Assert.IsTrue(funcCalled);
        }
Example #7
0
        public void GuardedAssert_DoesNotCallGuardedFuncIfGuardFailsToTrigger()
        {
            bool funcCalled = false;
            var  ass        = AssertDelegate.GuardedAssert(() => { funcCalled = true; return(true); }, () => false);

            Assert.IsTrue(ass());
            Assert.IsFalse(funcCalled);
        }
Example #8
0
        /// <summary>
        /// Checks that tokens in list are different
        /// </summary>
        /// <typeparam name="T">Item type</typeparam>
        /// <param name="test">Class containing test method in which validation should be performed.</param>
        /// <param name="list">Items list</param>
        /// <param name="tokenSelector">Function to get token from Item</param>
        /// <param name="assert"></param>
        public static void ValidateTokensInList <T>(this BaseTest test,
                                                    IEnumerable <T> list,
                                                    Func <T, string> tokenSelector,
                                                    AssertDelegate assert)
        {
            StringBuilder logger = new StringBuilder();
            bool          ok     = TestUtils.ValidateTokens(list, tokenSelector, logger);

            assert(ok, logger.ToStringTrimNewLine(), "Check that tokens are unique", string.Empty);
        }
Example #9
0
        public static void ValidateSubscription(DateTime?terminationTime, DateTime currentTime,
                                                int requestedTerminationTime, Event.EndpointReferenceType subscription,
                                                AssertDelegate assert)
        {
            assert(terminationTime.HasValue, "TerminationTime is not specified",
                   "Check that TerminationTime is specified", null);

            bool intervalIsWrong = false;

            if (currentTime < DateTime.Parse("1970-01-01T00:00:00"))
            {
                intervalIsWrong = true;
            }

            if (currentTime > DateTime.Parse("2070-01-01T00:00:00"))
            {
                intervalIsWrong = true;
            }

            if (terminationTime.Value < DateTime.Parse("1970-01-01T00:00:00"))
            {
                intervalIsWrong = true;
            }

            if (terminationTime.Value > DateTime.Parse("2070-01-01T00:00:00"))
            {
                intervalIsWrong = true;
            }

            assert(!intervalIsWrong, "TerminationTime or CurrentTime is out of reasonable interval (less than 1970-01-01T00:00:00 or greater than 2070-01-01T00:00:00).",
                   "Check that TerminationTime and CurrentTime has reasonable values", null);

            if (requestedTerminationTime >= 0)
            {
                assert(currentTime.AddSeconds(requestedTerminationTime) <= terminationTime.Value,
                       "TerminationTime < CurrentTime + InitialTerminationTime",
                       "Validate CurrentTime and TerminationTime", null);
            }
            else
            {
                assert(currentTime < terminationTime.Value,
                       "TerminationTime <= CurrentTime",
                       "Validate CurrentTime and TerminationTime", null);
            }

            assert(subscription != null, "The DUT did not return SubscriptionReference",
                   "Check if the DUT returned SubscriptionReference", null);

            assert(subscription.Address != null && subscription.Address.Value != null,
                   "SubscriptionReference does not contain address",
                   "Check if SubscriptionReference contains address", null);

            assert(subscription.Address.Value.IsValidUrl(), "URL passed in SubscriptionReference is not valid",
                   "Check that URL specified is valid", null);
        }
Example #10
0
 /// <summary>
 /// Executes user provided method but does not stop the test if the Assertion fails
 /// </summary>
 public static void Perform(AssertDelegate assertDelegate, params object[] @objects)
 {
     try
     {
         assertDelegate(objects);
     }
     catch (AssertionException ae)
     {
         HandleAssertionException(ae);
     }
 }
Example #11
0
        /// <summary>
        /// Checks that list contains only one item and this item holds expected information
        /// </summary>
        /// <typeparam name="T">Item type</typeparam>
        /// <param name="test">Class containing test method in which validation should be performed.</param>
        /// <param name="list">Items list</param>
        /// <param name="expected"></param>
        /// <param name="tokenSelector">Function to get token from Item</param>
        /// <param name="itemComparison">Method for comparing single items.</param>
        /// <param name="itemName">Name of item for eror description</param>
        /// <param name="assert"></param>
        public static void CheckRequestedInfo <T>(this BaseTest test, IEnumerable <T> list,
                                                  T expected,
                                                  Func <T, string> tokenSelector,
                                                  Func <T, T, StringBuilder, bool> itemComparison,
                                                  string itemName,
                                                  AssertDelegate assert)
        {
            string error = string.Empty;
            string token = tokenSelector(expected);

            int count = 0;

            if (list != null)
            {
                count = list.Count();
            }

            if (count == 0)
            {
                error = string.Format("No {0} information returned", itemName);
            }
            else
            {
                if (count > 1)
                {
                    error = "More than one entry returned";
                }
                else
                {
                    T item = list.First();
                    if (tokenSelector(item) != token)
                    {
                        error = "Entry for other token returned";
                    }
                    else
                    {
                        StringBuilder dump = new StringBuilder("Information is different: " + Environment.NewLine);
                        bool          ok   = itemComparison(expected, item, dump);
                        if (!ok)
                        {
                            error = dump.ToStringTrimNewLine();
                        }
                    }
                }
            }
            assert(string.IsNullOrEmpty(error), error, "Check response", string.Empty);
        }
Example #12
0
        public static void CommonGetListNoLimitTestBody <T>(this BaseTest test,
                                                            Func <int> maxLimitSelector,
                                                            GetListStepMethod <T> listSelector,
                                                            Func <T, string> tokenSelector,
                                                            string itemName,
                                                            AssertDelegate assert)
        {
            // Get maxLimit

            int maxLimit = maxLimitSelector();

            List <T> fullList = new List <T>();

            List <string> gotByThisMoment = new List <string>();
            string        offset          = null;

            while (true)
            {
                T[] nextPart = null;
                offset = listSelector(null, offset, out nextPart, string.Format("Get {0} list without limit and start reference ='{1}'", itemName, offset));

                int count = nextPart == null ? 0 : nextPart.Length;

                assert(count <= maxLimit,
                       string.Format("{0} {1}s returned when MaxLimit is {2}", count,
                                     itemName, maxLimit), "Check that limit is not exceeded",
                       string.Empty);

                if (count > 0)
                {
                    List <string> newTokens = nextPart.Select(tokenSelector).ToList();

                    test.ValidateNextPart(gotByThisMoment, newTokens, itemName, assert);

                    gotByThisMoment.AddRange(newTokens);

                    fullList.AddRange(nextPart);
                }

                if (string.IsNullOrEmpty(offset))
                {
                    break;
                }
            }
        }
        public AssertiveParser(AssertDelegate assertDelegate, Parser parser, string id, string message)
        {
            if (parser == null)
            {
                throw new ArgumentNullException("parser");
            }

            if (id == null)
            {
                throw new ArgumentNullException("id");
            }

            if (id == string.Empty)
            {
                throw new ArgumentException("id cannot be empty");
            }
            Parser  = parser;
            Message = message;
            ID      = id;
            Assert  = assertDelegate;
        }
Example #14
0
		public AssertiveParser( AssertDelegate assertDelegate, Parser parser, string id, string message)
		{
			if (parser == null)
			{
				throw new ArgumentNullException("parser");
			}

			if (id == null)
			{
				throw new ArgumentNullException("id");
			}

			if (id == string.Empty)
			{
				throw new ArgumentException("id cannot be empty");
			}
			Parser = parser;
			Message = message;
			ID = id;
			Assert = assertDelegate;

		}
Example #15
0
        public static void ValidateNextPart(this BaseTest test,
                                            IEnumerable <string> gotByThisMoment,
                                            IEnumerable <string> newItems,
                                            string itemName,
                                            AssertDelegate assert)
        {
            List <string> newNotUnique = new List <string>();   // intersection within new part
            List <string> duplicated   = new List <string>();   // intersection with received previously

            foreach (string token in newItems)
            {
                if (newItems.Count(S => S == token) > 1)
                {
                    newNotUnique.Add(token);
                }
                if (gotByThisMoment.Count(S => S == token) > 0)
                {
                    duplicated.Add(token);
                }
            }

            bool          ok    = true;
            StringBuilder error = new StringBuilder();

            if (newNotUnique.Count > 0)
            {
                ok = false;
                error.AppendLine("The following tokens are not unique: " + string.Join(", ", newNotUnique.ToArray()));
            }
            if (duplicated.Count > 0)
            {
                ok = false;
                error.AppendLine("The following tokens have been already received: " + string.Join(", ", duplicated.ToArray()));
            }

            assert(ok, error.ToStringTrimNewLine(), "Validate response received", string.Empty);
        }
Example #16
0
        public static List <T> GetFullList <T>(
            GetListMethod <T> getList,
            int?chunk,
            string itemName,
            AssertDelegate assert)
        {
            List <T> fullList = new List <T>();

            if (chunk > 0 || !chunk.HasValue)
            {
                string currentOffset = null;
                while (true)
                {
                    T[] portion = null;
                    currentOffset = getList(chunk, currentOffset, out portion);

                    if (portion != null)
                    {
                        if (chunk.HasValue)
                        {
                            assert(portion.Length <= chunk,
                                   string.Format("{0} {1}s returned", portion.Length, itemName),
                                   "Check that MaxLimit parameter is not exceeded",
                                   string.Empty);
                        }

                        fullList.AddRange(portion);
                    }
                    if (string.IsNullOrEmpty(currentOffset))
                    {
                        break;
                    }
                }
            }
            return(fullList);
        }
Example #17
0
        /// <summary>
        /// Checks that list contains exactly one item with specified token
        /// </summary>
        /// <typeparam name="T">Item type</typeparam>
        /// <param name="test">Class containing test method in which validation should be performed.</param>
        /// <param name="list">Items list</param>
        /// <param name="token">Token of desired item</param>
        /// <param name="tokenSelector">Function to get token from Item</param>
        /// <param name="itemName">Name of item for eror description</param>
        /// <param name="assert"></param>
        public static void CheckRequestedInfo <T>(this BaseTest test, IEnumerable <T> list,
                                                  string token,
                                                  Func <T, string> tokenSelector,
                                                  string itemName,
                                                  AssertDelegate assert)
        {
            string error = string.Empty;

            int count = 0;

            if (list != null)
            {
                count = list.Count();
            }

            if (count == 0)
            {
                error = string.Format("No {0} information returned", itemName);
            }
            else
            {
                if (count > 1)
                {
                    error = "More than one entry returned";
                }
                else
                {
                    T item = list.First();
                    if (tokenSelector(item) != token)
                    {
                        error = "Entry for other token returned";
                    }
                }
            }
            assert(string.IsNullOrEmpty(error), error, "Check response", string.Empty);
        }
Example #18
0
        private void CompareReceivers(Receiver receiverFromList, Receiver receiverByToken, AssertDelegate assert)
        {
            bool          ok     = true;
            StringBuilder logger = new StringBuilder();
            string        token  = receiverByToken.Token;

            if (receiverFromList.Token != receiverByToken.Token)
            {
                ok &= false;
                logger.Append(string.Format("Token of receiver in GetReceiverResponse is {0} " +
                                            "but in GetReceivesResponse is {1}{2}",
                                            receiverByToken.Token, receiverFromList.Token, Environment.NewLine));
            }

            if (receiverFromList.Configuration.Mode != receiverByToken.Configuration.Mode)
            {
                ok &= false;
                logger.Append(string.Format("Mode of receiver in GetReceiverResponse is {0} " +
                                            "but in GetReceivesResponse is {1}{2}",
                                            receiverByToken.Configuration.Mode, receiverFromList.Configuration.Mode, Environment.NewLine));
            }

            if (receiverFromList.Configuration.MediaUri != receiverByToken.Configuration.MediaUri)
            {
                ok &= false;
                logger.Append(string.Format("MediaUri of receiver in GetReceiverResponse is {0} " +
                                            "but in GetReceivesResponse is {1}{2}",
                                            receiverByToken.Configuration.MediaUri, receiverFromList.Configuration.MediaUri, Environment.NewLine));
            }

            if (receiverFromList.Configuration.StreamSetup.Stream != receiverByToken.Configuration.StreamSetup.Stream)
            {
                ok &= false;
                logger.Append(string.Format("StreamSetup.Stream of receiver in GetReceiverResponse is {0} " +
                                            "but in GetReceivesResponse is {1}{2}",
                                            receiverByToken.Configuration.StreamSetup.Stream, receiverFromList.Configuration.StreamSetup.Stream, Environment.NewLine));
            }

            string parameter = "Transport";

            CompareTransports(receiverFromList.Configuration.StreamSetup.Transport,
                              receiverByToken.Configuration.StreamSetup.Transport, logger,
                              receiverByToken.Token, ref ok, parameter);

            assert(ok, logger.ToStringTrimNewLine(),
                   string.Format("Compare receivers with token {0} in GetReceiversResponse and in GetReceiverResponse", token), null);
        }
Example #19
0
        public void GuardedAssert_ReturnsValueOfCalledFunction()
        {
            var ass = AssertDelegate.GuardedAssert(() => { return(false); }, () => true);

            Assert.IsFalse(ass());
        }
        public static void ValidateFullRecordingJobsList(GetRecordingJobsResponseItem[] jobs,
                                                         GetRecordingsResponseItem[] recordings, AssertDelegate assert)
        {
            bool          tokensOk = true;
            StringBuilder logger   = new StringBuilder();

            List <string> logged = new List <string>();

            foreach (var item in jobs)
            {
                string token = item.JobConfiguration.RecordingToken;
                if (recordings.Where(r => r.RecordingToken == token).FirstOrDefault() == null)
                {
                    tokensOk = false;
                    logged.Add(token);
                    logger.AppendFormat("Recording list doesn't contain recording {0} which token returned in GetRecordingJobsResponse",
                                        token, Environment.NewLine);
                }
            }

            assert(tokensOk, logger.ToStringTrimNewLine(),
                   "Validate recording job list got from GetRecordingJobs", null);
        }
        /// <summary>
        /// Wraps the Begin* part of a Begin / End method pair to allow for signaling when assertions have been violated.
        /// The instrumentation can be a performance hit, so this method should not be called if AppVerifier is not enabled.
        /// </summary>
        /// <param name="httpApplication">The HttpApplication instance for this request, used to get HttpContext and related items.</param>
        /// <param name="beginMethod">The Begin* part of a Begin / End method pair, likely wrapped in a lambda so only the AsyncCallback and object parameters are exposed.</param>
        /// <param name="originalDelegate">The original user-provided delegate, e.g. the thing that 'beginMethod' wraps. Provided so that we can show correct methods when asserting.</param>
        /// <param name="errorHandler">The listener that can handle verification failures.</param>
        /// <returns>The instrumented Begin* method.</returns>
        internal static Func <AsyncCallback, object, IAsyncResult> WrapBeginMethodImpl(HttpApplication httpApplication, Func <AsyncCallback, object, IAsyncResult> beginMethod, Delegate originalDelegate, Action <AppVerifierException> errorHandler, CallStackCollectionBitMasks callStackMask)
        {
            return((callback, state) => {
                // basic diagnostic info goes at the top since it's used during generation of the error message
                AsyncCallbackInvocationHelper asyncCallbackInvocationHelper = new AsyncCallbackInvocationHelper();
                CallStackCollectionBitMasks myBeginMask = callStackMask & CallStackCollectionBitMasks.AllBeginMask;
                bool captureBeginStack = (myBeginMask & (CallStackCollectionBitMasks)AppVerifierCollectCallStackMask) == myBeginMask;

                InvocationInfo beginHandlerInvocationInfo = InvocationInfo.Capture(captureBeginStack);
                Uri requestUrl = null;
                RequestNotification?currentNotification = null;
                bool isPostNotification = false;
                Type httpHandlerType = null;

                // need to collect all this up-front since it might go away during the async operation
                if (httpApplication != null)
                {
                    HttpContext context = httpApplication.Context;
                    if (context != null)
                    {
                        if (!context.HideRequestResponse && context.Request != null)
                        {
                            requestUrl = context.Request.Unvalidated.Url;
                        }

                        if (context.NotificationContext != null)
                        {
                            currentNotification = context.NotificationContext.CurrentNotification;
                            isPostNotification = context.NotificationContext.IsPostNotification;
                        }

                        if (context.Handler != null)
                        {
                            httpHandlerType = context.Handler.GetType();
                        }
                    }
                }

                // If the condition passed to this method evaluates to false, we will raise an error to whoever is listening.
                AssertDelegate assert = (condition, errorCode) => {
                    long mask = 1L << (int)errorCode;
                    // assert only if it was not masked out by a bit set
                    bool enableAssert = (AppVerifierErrorCodeEnableAssertMask & mask) == mask;

                    if (!condition && enableAssert)
                    {
                        // capture the stack only if it was not masked out by a bit set
                        bool captureStack = (AppVerifierErrorCodeCollectCallStackMask & mask) == mask;

                        InvocationInfo assertInvocationInfo = InvocationInfo.Capture(captureStack);

                        // header
                        StringBuilder errorString = new StringBuilder();
                        errorString.AppendLine(FormatErrorString(SR.AppVerifier_Title));
                        errorString.AppendLine(FormatErrorString(SR.AppVerifier_Subtitle));
                        errorString.AppendLine();

                        // basic info (about the assert)
                        errorString.AppendLine(FormatErrorString(SR.AppVerifier_BasicInfo_URL, requestUrl));
                        errorString.AppendLine(FormatErrorString(SR.AppVerifier_BasicInfo_ErrorCode, (int)errorCode));
                        errorString.AppendLine(FormatErrorString(SR.AppVerifier_BasicInfo_Description, GetLocalizedDescriptionStringForError(errorCode)));
                        errorString.AppendLine(FormatErrorString(SR.AppVerifier_BasicInfo_ThreadInfo, assertInvocationInfo.ThreadId, assertInvocationInfo.Timestamp.ToLocalTime()));
                        errorString.AppendLine(assertInvocationInfo.StackTrace.ToString());

                        // Begin* method info
                        errorString.AppendLine(FormatErrorString(SR.AppVerifier_BeginMethodInfo_EntryMethod, PrettyPrintDelegate(originalDelegate)));
                        if (currentNotification != null)
                        {
                            errorString.AppendLine(FormatErrorString(SR.AppVerifier_BeginMethodInfo_RequestNotification_Integrated, currentNotification, isPostNotification));
                        }
                        else
                        {
                            errorString.AppendLine(FormatErrorString(SR.AppVerifier_BeginMethodInfo_RequestNotification_NotIntegrated));
                        }
                        errorString.AppendLine(FormatErrorString(SR.AppVerifier_BeginMethodInfo_CurrentHandler, httpHandlerType));
                        errorString.AppendLine(FormatErrorString(SR.AppVerifier_BeginMethodInfo_ThreadInfo, beginHandlerInvocationInfo.ThreadId, beginHandlerInvocationInfo.Timestamp.ToLocalTime()));
                        errorString.AppendLine(beginHandlerInvocationInfo.StackTrace.ToString());

                        // AsyncCallback info
                        int totalAsyncInvocationCount;
                        InvocationInfo firstAsyncInvocation = asyncCallbackInvocationHelper.GetFirstInvocationInfo(out totalAsyncInvocationCount);
                        errorString.AppendLine(FormatErrorString(SR.AppVerifier_AsyncCallbackInfo_InvocationCount, totalAsyncInvocationCount));
                        if (firstAsyncInvocation != null)
                        {
                            errorString.AppendLine(FormatErrorString(SR.AppVerifier_AsyncCallbackInfo_FirstInvocation_ThreadInfo, firstAsyncInvocation.ThreadId, firstAsyncInvocation.Timestamp.ToLocalTime()));
                            errorString.AppendLine(firstAsyncInvocation.StackTrace.ToString());
                        }

                        AppVerifierException ex = new AppVerifierException(errorCode, errorString.ToString());
                        errorHandler(ex);
                        throw ex;
                    }
                };

                assert(httpApplication != null, AppVerifierErrorCode.HttpApplicationInstanceWasNull);
                assert(originalDelegate != null, AppVerifierErrorCode.BeginHandlerDelegateWasNull);

                object lockObj = new object(); // used to synchronize access to certain locals which can be touched by multiple threads
                IAsyncResult asyncResultReturnedByBeginHandler = null;
                IAsyncResult asyncResultPassedToCallback = null;
                object beginHandlerReturnValueHolder = null;                                  // used to hold the IAsyncResult returned by or Exception thrown by BeginHandler; see comments on Holder<T> for more info
                Thread threadWhichCalledBeginHandler = Thread.CurrentThread;                  // used to determine whether the callback was invoked synchronously
                bool callbackRanToCompletion = false;                                         // don't need to lock when touching this local since it's only read in the synchronous case

                HttpContext assignedContextUponCallingBeginHandler = httpApplication.Context; // used to determine whether the underlying request disappeared

                try {
                    asyncResultReturnedByBeginHandler = beginMethod(
                        asyncResult => {
                        try {
                            CallStackCollectionBitMasks myCallbackMask = callStackMask & CallStackCollectionBitMasks.AllCallbackMask;
                            bool captureEndCallStack = (myCallbackMask & AppVerifierCollectCallStackMask) == myCallbackMask;
                            // The callback must never be called more than once.
                            int newAsyncCallbackInvocationCount = asyncCallbackInvocationHelper.RecordInvocation(captureEndCallStack);
                            assert(newAsyncCallbackInvocationCount == 1, AppVerifierErrorCode.AsyncCallbackInvokedMultipleTimes);

                            // The 'asyncResult' parameter must never be null.
                            assert(asyncResult != null, AppVerifierErrorCode.AsyncCallbackInvokedWithNullParameter);

                            object tempBeginHandlerReturnValueHolder;
                            Thread tempThreadWhichCalledBeginHandler;
                            lock (lockObj) {
                                asyncResultPassedToCallback = asyncResult;
                                tempBeginHandlerReturnValueHolder = beginHandlerReturnValueHolder;
                                tempThreadWhichCalledBeginHandler = threadWhichCalledBeginHandler;
                            }

                            // At this point, 'IsCompleted = true' is mandatory.
                            assert(asyncResult.IsCompleted, AppVerifierErrorCode.AsyncCallbackGivenAsyncResultWhichWasNotCompleted);

                            if (tempBeginHandlerReturnValueHolder == null)
                            {
                                // BeginHandler hasn't yet returned, so this call may be synchronous or asynchronous.
                                // We can tell by comparing the current thread with the thread which called BeginHandler.
                                // From a correctness perspective, it is valid to invoke the AsyncCallback delegate either
                                // synchronously or asynchronously. From [....]: if 'CompletedSynchronously = true', then
                                // AsyncCallback invocation can happen either on the same thread or on a different thread,
                                // just as long as BeginHandler hasn't yet returned (which in true in this case).
                                if (!asyncResult.CompletedSynchronously)
                                {
                                    // If 'CompletedSynchronously = false', we must be on a different thread than the BeginHandler invocation.
                                    assert(tempThreadWhichCalledBeginHandler != Thread.CurrentThread, AppVerifierErrorCode.AsyncCallbackInvokedSynchronouslyButAsyncResultWasNotMarkedCompletedSynchronously);
                                }
                            }
                            else
                            {
                                // BeginHandler already returned, so this invocation is definitely asynchronous.

                                Holder <IAsyncResult> asyncResultHolder = tempBeginHandlerReturnValueHolder as Holder <IAsyncResult>;
                                if (asyncResultHolder != null)
                                {
                                    // We need to verify that the IAsyncResult we're given is the same that was returned by BeginHandler
                                    // and that the IAsyncResult is marked 'CompletedSynchronously = false'.
                                    assert(asyncResult == asyncResultHolder.Value, AppVerifierErrorCode.AsyncCallbackInvokedWithUnexpectedAsyncResultInstance);
                                    assert(!asyncResult.CompletedSynchronously, AppVerifierErrorCode.AsyncCallbackInvokedAsynchronouslyButAsyncResultWasMarkedCompletedSynchronously);
                                }
                                else
                                {
                                    // If we reached this point, BeginHandler threw an exception.
                                    // The AsyncCallback should never be invoked if BeginHandler has already failed.
                                    assert(false, AppVerifierErrorCode.BeginHandlerThrewThenAsyncCallbackInvokedAsynchronously);
                                }
                            }

                            // AsyncState must match the 'state' parameter passed to BeginHandler
                            assert(asyncResult.AsyncState == state, AppVerifierErrorCode.AsyncCallbackInvokedWithUnexpectedAsyncResultAsyncState);

                            // Make sure the underlying HttpApplication is still assigned to the captured HttpContext instance.
                            // If not, this AsyncCallback invocation could end up completing *some other request's* operation,
                            // resulting in data corruption.
                            assert(assignedContextUponCallingBeginHandler == httpApplication.Context, AppVerifierErrorCode.AsyncCallbackCalledAfterHttpApplicationReassigned);
                        }
                        catch (AppVerifierException) {
                            // We want to ---- any exceptions thrown by our verification logic, as the failure
                            // has already been recorded by the appropriate listener. Just go straight to
                            // invoking the callback.
                        }

                        // all checks complete - delegate control to the actual callback
                        if (callback != null)
                        {
                            callback(asyncResult);
                        }
                        callbackRanToCompletion = true;
                    },
                        state);

                    // The return value must never be null.
                    assert(asyncResultReturnedByBeginHandler != null, AppVerifierErrorCode.BeginHandlerReturnedNull);

                    lock (lockObj) {
                        beginHandlerReturnValueHolder = new Holder <IAsyncResult>(asyncResultReturnedByBeginHandler);
                    }

                    if (asyncResultReturnedByBeginHandler.CompletedSynchronously)
                    {
                        // If 'CompletedSynchronously = true', the IAsyncResult must be marked 'IsCompleted = true'
                        // and the AsyncCallback must have been invoked synchronously (checked in the AsyncCallback verification logic).
                        assert(asyncResultReturnedByBeginHandler.IsCompleted, AppVerifierErrorCode.BeginHandlerReturnedAsyncResultMarkedCompletedSynchronouslyButWhichWasNotCompleted);
                        assert(asyncCallbackInvocationHelper.TotalInvocations != 0, AppVerifierErrorCode.BeginHandlerReturnedAsyncResultMarkedCompletedSynchronouslyButAsyncCallbackNeverCalled);
                    }

                    IAsyncResult tempAsyncResultPassedToCallback;
                    lock (lockObj) {
                        tempAsyncResultPassedToCallback = asyncResultPassedToCallback;
                    }

                    // The AsyncCallback may have been invoked (either synchronously or asynchronously). If it has been
                    // invoked, we need to verify that it was given the same IAsyncResult returned by BeginHandler.
                    // If the AsyncCallback hasn't yet been called, we skip this check, as the AsyncCallback verification
                    // logic will eventually perform the check at the appropriate time.
                    if (tempAsyncResultPassedToCallback != null)
                    {
                        assert(tempAsyncResultPassedToCallback == asyncResultReturnedByBeginHandler, AppVerifierErrorCode.BeginHandlerReturnedUnexpectedAsyncResultInstance);
                    }

                    // AsyncState must match the 'state' parameter passed to BeginHandler
                    assert(asyncResultReturnedByBeginHandler.AsyncState == state, AppVerifierErrorCode.BeginHandlerReturnedUnexpectedAsyncResultAsyncState);

                    // all checks complete
                    return asyncResultReturnedByBeginHandler;
                }
                catch (AppVerifierException) {
                    // We want to ---- any exceptions thrown by our verification logic, as the failure
                    // has already been recorded by the appropriate listener. Just return the original
                    // IAsyncResult so that the application continues to run.
                    return asyncResultReturnedByBeginHandler;
                }
                catch (Exception ex) {
                    if (asyncResultReturnedByBeginHandler == null)
                    {
                        // If we reached this point, an exception was thrown by BeginHandler, so we need to
                        // record it and rethrow it.

                        IAsyncResult tempAsyncResultPassedToCallback;
                        lock (lockObj) {
                            beginHandlerReturnValueHolder = new Holder <Exception>(ex);
                            tempAsyncResultPassedToCallback = asyncResultPassedToCallback;
                        }

                        try {
                            // The AsyncCallback should only be invoked if BeginHandler ran to completion.
                            if (tempAsyncResultPassedToCallback != null)
                            {
                                // If AsyncCallback was invoked asynchronously, then by definition it was
                                // scheduled prematurely since BeginHandler hadn't yet run to completion
                                // (since whatever additional work it did after invoking the callback failed).
                                // Therefore it is always wrong for BeginHandler to both throw and
                                // asynchronously invoke AsyncCallback.
                                assert(tempAsyncResultPassedToCallback.CompletedSynchronously, AppVerifierErrorCode.AsyncCallbackInvokedAsynchronouslyThenBeginHandlerThrew);

                                // If AsyncCallback was invoked synchronously, then it must have been invoked
                                // before BeginHandler surfaced the exception (since otherwise BeginHandler
                                // wouldn't have reached the line of code that invoked AsyncCallback). But
                                // AsyncCallback itself could have thrown, bubbling the exception up through
                                // BeginHandler and back to us. If AsyncCallback ran to completion, then this
                                // means BeginHandler did extra work (which failed) after invoking AsyncCallback,
                                // so BeginHandler by definition hadn't yet run to completion.
                                assert(!callbackRanToCompletion, AppVerifierErrorCode.AsyncCallbackInvokedSynchronouslyThenBeginHandlerThrew);
                            }
                        }
                        catch (AppVerifierException) {
                            // We want to ---- any exceptions thrown by our verification logic, as the failure
                            // has already been recorded by the appropriate listener. Propagate the original
                            // exception upward.
                        }

                        throw;
                    }
                    else
                    {
                        // We want to ---- any exceptions thrown by our verification logic, as the failure
                        // has already been recorded by the appropriate listener. Just return the original
                        // IAsyncResult so that the application continues to run.
                        return asyncResultReturnedByBeginHandler;
                    }
                }
                finally {
                    // Since our local variables are GC-rooted in an anonymous object, we should
                    // clear references to objects we no longer need so that the GC can reclaim
                    // them if appropriate.
                    lock (lockObj) {
                        threadWhichCalledBeginHandler = null;
                    }
                }
            });
        }
Example #22
0
        public static void CommonGetListStartReferenceLimitTestBody <T>(this BaseTest test,
                                                                        Func <int> maxLimitSelector,
                                                                        GetListStepMethod <T> listSelector,
                                                                        Func <T, string> tokenSelector,
                                                                        Func <T, T, StringBuilder, bool> itemComparison,
                                                                        string itemName,
                                                                        RunStepDelegate runStepDelegate,
                                                                        AssertDelegate assert)
        {
            // Get maxLimit

            int maxLimit = maxLimitSelector();

            Func <int, List <T> > getList = (limit) =>
            {
                List <T> fullList = new List <T>();

                List <string> gotByThisMoment = new List <string>();
                string        offset          = null;
                while (true)
                {
                    T[] nextPart = null;
                    offset = listSelector(limit, offset, out nextPart, string.Format("Get {0} list with limit = {1} and start reference ='{2}'", itemName, limit, offset));

                    //assert(nextPart != null, string.Format("No {0}s returned", itemName), "Check that result is not null", string.Empty);

                    int count = nextPart == null ? 0 : nextPart.Length;

                    assert(count <= limit,
                           string.Format("{0} {1}s returned when limit is {2}", count,
                                         itemName, limit), "Check that limit is not exceeded",
                           string.Empty);

                    if (count > 0)
                    {
                        List <string> newTokens = nextPart.Select(tokenSelector).ToList();

                        test.ValidateNextPart(gotByThisMoment, newTokens, itemName, assert);

                        gotByThisMoment.AddRange(newTokens);

                        fullList.AddRange(nextPart);
                    }

                    if (string.IsNullOrEmpty(offset))
                    {
                        break;
                    }
                }

                return(fullList);
            };

            // get full list by maxLimit chunks

            List <T> gotByMaxLimit = getList(maxLimit);

            // get full list by 1 item

            List <T> gotByOne = getList(1);

            // check order
            // compare items

            //test.ValidateOrderedLists(gotByMaxLimit, gotByOne, itemName, tokenSelector,
            //                          string.Format("received with limit ={0}", maxLimit), "received with limit=1",
            //                          itemComparison, assert);


            if (maxLimit > 2)
            {
                int middle = maxLimit / 2 + 1; // 3=>2, 4=>3, 5=>3

                List <T> gotByMiddle = getList(middle);

                // check order
                // compare items

                //test.ValidateOrderedLists(gotByOne, gotByMiddle, itemName, tokenSelector,
                //                          "received with limit=1",
                //                          string.Format("received with limit ={0}", middle),
                //                          itemComparison, assert);
            }
        }
Example #23
0
        public static void CommonGetListLimitTestBody <T>(this BaseTest test,
                                                          Func <int> maxLimitSelector,
                                                          Func <List <T> > fullListSelector,
                                                          GetListStepMethod <T> listSelector,
                                                          Func <T, string> tokenSelector,
                                                          string itemName,
                                                          AssertDelegate assert)
        {
            // Get max limit
            int maxLimit = maxLimitSelector();

            // Get full list. Exit test, if no items of interest registered
            List <T> infos = fullListSelector();

            if (infos == null || infos.Count == 0)
            {
                return;
            }

            test.ValidateTokensInList(infos, tokenSelector, assert);

            int count = infos.Count;

            // Get one item
            {
                T[] shortList = null;
                listSelector(1, null, out shortList, string.Format("Get {0} list with limit = 1", itemName));

                assert(shortList != null, string.Format("No {0}s returned", itemName), "Check that result is not null", string.Empty);

                assert(shortList.Length <= 1,
                       string.Format("{0} {1}s returned when limit is {2}", shortList.Length, itemName, 1),
                       "Check that limit is not exceeded",
                       string.Empty);
            }

            // maxLimit
            if (count > 1)
            {
                T[] actual = null;

                listSelector(maxLimit, null, out actual, string.Format("Get {0} list with limit = {1}", itemName, maxLimit));

                assert(actual != null, string.Format("No {0}s returned", itemName), "Check that result is not null", string.Empty);

                assert(actual.Length <= maxLimit,
                       string.Format("{0} {1}s returned when limit is {2}", actual.Length, itemName, maxLimit),
                       "Check that limit is not exceeded",
                       string.Empty);


                test.ValidateTokensInList(actual, tokenSelector, assert);
            }


            int cnt = Math.Min(count, maxLimit);

            int limit = cnt / 2 + 1;  // 3 => 2, 4=> 3, 5=> 3,

            if (limit != maxLimit && limit != 1)
            {
                T[] infosArray = infos.ToArray();

                System.Diagnostics.Debug.WriteLine(string.Format("Get {0} with limit = {1}", itemName, limit));

                T[] expected = new T[limit];

                Array.Copy(infosArray, 0, expected, 0, limit);

                T[] actual = null;
                listSelector(limit, null, out actual, string.Format("Get {0} list with limit = {1}", itemName, limit));

                assert(actual != null, string.Format("No {0}s returned", itemName), "Check that result is not null", string.Empty);

                assert(actual.Length <= limit,
                       string.Format("{0} {1}s returned when limit is {2}", actual.Length, itemName, limit),
                       "Check that limit is not exceeded",
                       string.Empty);


                test.ValidateTokensInList(actual, tokenSelector, assert);
            }
        }
Example #24
0
        public static void CommonGetListStartReferenceTestBody <T>(this BaseTest test,
                                                                   Func <int> maxLimitSelector,
                                                                   Func <int, List <T> > fullListSelector,
                                                                   Func <int?, int?, string, T[]> listSelector,
                                                                   Func <T, string> tokenSelector,
                                                                   Action <IEnumerable <T>, IEnumerable <T>, string, string> listComparisonAction,
                                                                   Func <T, T, StringBuilder, bool> itemComparison,
                                                                   string itemName,
                                                                   RunStepDelegate runStepDelegate,
                                                                   AssertDelegate assert)
        {
            int maxLimit = maxLimitSelector();

            List <T> infos = fullListSelector(maxLimit);

            if (infos == null || infos.Count == 0)
            {
                return;
            }

            test.ValidateTokensInList(infos, tokenSelector, assert);

            int count = infos.Count;

            // one last item

            if (count > 1)
            {
                T[] shortList = listSelector(maxLimit, count - 1, string.Format("Get {0} list with offset = {1}", itemName, count - 1));

                test.CheckRequestedInfo <T>(shortList, infos[count - 1], tokenSelector, itemComparison, itemName, assert);
            }

            // first "maxLimit" items
            {
                List <T> expected = infos.Take(maxLimit).ToList();

                T[] actual = listSelector(maxLimit, 0, string.Format("Get {0} list with offset = 0", itemName));

                test.ValidateTokensInList(actual, tokenSelector, assert);

                listComparisonAction(expected, actual, string.Format("of first {0} {1}", maxLimit, itemName),
                                     "received when passing offset=0");
            }


            if (count > 2)
            {
                int offset = count / 2; // 3 => 1, 4 => 2, 5 => 2, 6 => 3

                System.Diagnostics.Debug.WriteLine(string.Format("Get {0} with offset = {1}", itemName, offset));

                // expected list

                T[] infosArray = infos.ToArray();

                int cnt = Math.Min(maxLimit, count - offset);

                T[] expected = new T[cnt];

                Array.Copy(infosArray, offset, expected, 0, cnt);


                T[] actual = listSelector(maxLimit, offset, string.Format("Get {0} list with offset = {1}", itemName, offset));

                test.ValidateTokensInList(actual, tokenSelector, assert);

                test.ValidateSubset(actual, expected, itemName, tokenSelector, itemComparison, assert);
            }
        }
Example #25
0
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="test"></param>
        /// <param name="list1"></param>
        /// <param name="list2"></param>
        /// <param name="itemName"></param>
        /// <param name="tokenSelector"></param>
        /// <param name="description1"></param>
        /// <param name="description2"></param>
        /// <param name="itemComparer"></param>
        /// <param name="assert"></param>
        public static void ValidateOrderedLists <T>(this BaseTest test, IList <T> list1,
                                                    IList <T> list2,
                                                    string itemName,
                                                    Func <T, string> tokenSelector,
                                                    string description1,
                                                    string description2,
                                                    Func <T, T, StringBuilder, bool> itemComparer,
                                                    AssertDelegate assert)
        {
            bool          ok     = true;
            StringBuilder logger = new StringBuilder();

            List <string> common = new List <string>();

            /****************/

            foreach (T info in list1)
            {
                string token      = tokenSelector(info);
                T[]    foundItems =
                    list2.Where(I => tokenSelector(I) == token).ToArray();

                if (foundItems.Length == 0)
                {
                    logger.AppendFormat(
                        "{0} with token '{1}' not found in list {2}{3}",
                        itemName, tokenSelector(info), description2, Environment.NewLine);
                    ok = false;
                }
                else
                {
                    common.Add(token);
                }
            }

            foreach (T info in list2)
            {
                string token      = tokenSelector(info);
                T[]    foundItems =
                    list1.Where(I => tokenSelector(I) == token).ToArray();

                if (foundItems.Length == 0)
                {
                    logger.AppendFormat(
                        "{0} with token '{1}' not found in {2}{3}",
                        itemName, tokenSelector(info), description1, Environment.NewLine);
                    ok = false;
                }
            }

            /****************/

            bool orderOk = true;

            // only if sets match
            if (ok)
            {
                for (int i = 0; i < list1.Count; i++)
                {
                    string token1 = tokenSelector(list1[i]);
                    string token2 = tokenSelector(list2[i]);
                    if (token1 != token2)
                    {
                        orderOk = false;
                        break;
                    }
                }
            }

            if (!orderOk)
            {
                logger.AppendLine(string.Format("Order of {0} is different{1}", itemName, Environment.NewLine));
                ok = false;
            }

            /****************/

            // for common only
            if (itemComparer != null)
            {
                bool local = ArrayUtils.CompareListItems(list1, list2, tokenSelector, common, itemName, logger,
                                                         itemComparer);
                ok = ok && local;
            }

            assert(ok, logger.ToStringTrimNewLine(), "Check that lists are the same", null);
        }
Example #26
0
        public static void CommonGetListByTokenListTestBody <T>(this BaseTest test,
                                                                Func <int> maxLimitSelector,
                                                                Func <List <T> > fullListSelector,
                                                                Func <string[], T[]> listSelector,
                                                                Func <T, string> tokenSelector,
                                                                Action <IEnumerable <T>, IEnumerable <T>, string, string> listComparisonAction,
                                                                string itemName,
                                                                string itemInfoName,
                                                                RunStepDelegate runStepDelegate,
                                                                AssertDelegate assert)
        {
            List <T> infos = fullListSelector();

            if (infos == null || infos.Count == 0)
            {
                return;
            }

            ValidateTokensInList(test, infos, tokenSelector, assert);

            //
            int maxLimit = maxLimitSelector();

            List <string> tokens = new List <string>();

            foreach (T info in infos)
            {
                tokens.Add(tokenSelector(info));
            }

            List <T>      expected            = new List <T>();
            List <string> tokensForSubsetTest = new List <string>();

            // create list of randomly selected tokens.
            // create "expected" list
            {
                List <T> fullListCopy = new List <T>(infos);

                for (int i = 0; i < maxLimit; i++)
                {
                    Random rnd = new Random();
                    int    idx = rnd.Next(0, fullListCopy.Count - 1);
                    tokensForSubsetTest.Add(tokenSelector(fullListCopy[idx]));
                    expected.Add(fullListCopy[idx]);
                    fullListCopy.RemoveAt(idx);
                    if (fullListCopy.Count == 0)
                    {
                        break;
                    }
                }
            }

            // test for random subset
            T[] actual = listSelector(tokensForSubsetTest.ToArray());

            assert(actual != null && actual.Length > 0,
                   "Empty list returned", "Check that the list is not empty", "");

            ValidateTokensInList(test, actual, tokenSelector, assert);

            test.ValidateSubset(actual, expected, itemName, tokenSelector, null, assert);

            // Get by one

            foreach (string token in tokens)
            {
                T[] shortList = listSelector(new string[] { token });

                CheckRequestedInfo(test, shortList, token, tokenSelector, itemName, assert);
            }
        }
        /// <summary>
        /// Returns an Action that determines whether SynchronizationContext.Send or Post was called after the underlying request finished.
        /// The instrumentation can be a performance hit, so this method should not be called if AppVerifier is not enabled.
        /// </summary>
        /// <param name="syncContext">The ISyncContext (HttpApplication, WebSocketPipeline, etc.) on which to perform the check.</param>
        /// <param name="errorHandler">The listener that can handle verification failures.</param>
        /// <returns>A callback which performs the verification.</returns>
        internal static Action GetSyncContextCheckDelegateImpl(ISyncContext syncContext, Action <AppVerifierException> errorHandler)
        {
            Uri    requestUrl = null;
            object originalThreadContextId = null;

            // collect all of the diagnostic information upfront
            HttpContext originalHttpContext = (syncContext != null) ? syncContext.HttpContext : null;

            if (originalHttpContext != null)
            {
                if (!originalHttpContext.HideRequestResponse && originalHttpContext.Request != null)
                {
                    requestUrl = originalHttpContext.Request.Unvalidated.Url;
                }

                // This will be used as a surrogate for the captured HttpContext so that we don't
                // have a long-lived reference to a heavy object graph. See comments on ThreadContextId
                // for more info.
                originalThreadContextId = originalHttpContext.ThreadContextId;
                originalHttpContext     = null;
            }

            // If the condition passed to this method evaluates to false, we will raise an error to whoever is listening.
            AssertDelegate assert = (condition, errorCode) => {
                long mask = 1L << (int)errorCode;
                // assert only if it was not masked out by a bit set
                bool enableAssert = (AppVerifierErrorCodeEnableAssertMask & mask) == mask;

                if (!condition && enableAssert)
                {
                    // capture the stack only if it was not masked out by a bit set
                    bool           captureStack         = (AppVerifierErrorCodeCollectCallStackMask & mask) == mask;
                    InvocationInfo assertInvocationInfo = InvocationInfo.Capture(captureStack);

                    // header
                    StringBuilder errorString = new StringBuilder();
                    errorString.AppendLine(FormatErrorString(SR.AppVerifier_Title));
                    errorString.AppendLine(FormatErrorString(SR.AppVerifier_Subtitle));
                    errorString.AppendLine();

                    // basic info (about the assert)
                    errorString.AppendLine(FormatErrorString(SR.AppVerifier_BasicInfo_URL, requestUrl));
                    errorString.AppendLine(FormatErrorString(SR.AppVerifier_BasicInfo_ErrorCode, (int)errorCode));
                    errorString.AppendLine(FormatErrorString(SR.AppVerifier_BasicInfo_Description, GetLocalizedDescriptionStringForError(errorCode)));
                    errorString.AppendLine(FormatErrorString(SR.AppVerifier_BasicInfo_ThreadInfo, assertInvocationInfo.ThreadId, assertInvocationInfo.Timestamp.ToLocalTime()));
                    errorString.AppendLine(assertInvocationInfo.StackTrace.ToString());

                    AppVerifierException ex = new AppVerifierException(errorCode, errorString.ToString());
                    errorHandler(ex);
                    throw ex;
                }
            };

            return(() => {
                try {
                    // Make sure that the ISyncContext is still associated with the same HttpContext that
                    // we captured earlier.
                    HttpContext currentHttpContext = (syncContext != null) ? syncContext.HttpContext : null;
                    object currentThreadContextId = (currentHttpContext != null) ? currentHttpContext.ThreadContextId : null;
                    assert(currentThreadContextId != null && ReferenceEquals(originalThreadContextId, currentThreadContextId), AppVerifierErrorCode.SyncContextSendOrPostCalledAfterRequestCompleted);
                }
                catch (AppVerifierException) {
                    // We want to ---- any exceptions thrown by our verification logic, as the failure
                    // has already been recorded by the appropriate listener. Propagate the original
                    // exception upward.
                }
            });
        }