/// <summary> /// Compares the ClientExpectedException to the provided exception and verifies the exception is correct /// </summary> /// <param name="expectedClientException">Expected Client Exception</param> /// <param name="exception">Actual Exception</param> public void Compare(ExpectedClientErrorBaseline expectedClientException, Exception exception) { ExceptionUtilities.CheckAllRequiredDependencies(this); if (expectedClientException == null) { string exceptionMessage = null; if (exception != null) { exceptionMessage = exception.ToString(); } this.Assert.IsNull(exception, "Expected to not recieve an exception:" + exceptionMessage); return; } this.Assert.IsNotNull(exception, "Expected Exception to not be null"); this.Assert.AreEqual(expectedClientException.ExpectedExceptionType, exception.GetType(), string.Format(CultureInfo.InvariantCulture, "ExceptionType is not equal, receieved the following exception: {0}", exception.ToString())); if (expectedClientException.HasServerSpecificExpectedMessage) { if (this.ShouldVerifyServerMessageInClientException) { this.Assert.IsNotNull(exception.InnerException, "Expected Inner Exception to contain ODataError"); byte[] byteArrPayload = HttpUtilities.DefaultEncoding.GetBytes(exception.InnerException.Message); ODataErrorPayload errorPayload = this.ProtocolFormatStrategySelector.DeserializeAndCast <ODataErrorPayload>(null, MimeTypes.ApplicationXml, byteArrPayload); expectedClientException.ExpectedExceptionMessage.VerifyMatch(this.systemDataServicesVerifier, errorPayload.Message, true); } } else { expectedClientException.ExpectedExceptionMessage.VerifyMatch(this.systemDataServicesClientVerifier, exception.Message, true); } }
/// <summary> /// Wraps query Execution action sync or async and verifies exceptions /// </summary> /// <param name="continuation">Continuation token to register success or failure to</param> /// <param name="expectedValue">Expected Value of the Query</param> /// <param name="dataContext">Content the Query is executed on</param> /// <param name="clientExpectedError">Expected Error the query is executed on</param> /// <param name="executeAction">Action to execute specified query</param> private void ExecuteQueryAction( IAsyncContinuation continuation, QueryValue expectedValue, DataServiceContext dataContext, ExpectedClientErrorBaseline clientExpectedError, Action <List <object>, IAsyncContinuation> executeAction) { ExceptionUtilities.CheckAllRequiredDependencies(this); this.clientExceptionVerified = false; continuation = continuation.OnFail(() => this.expressionQueue.Clear()); continuation = continuation.OnContinue(() => this.expressionQueue.TryDequeue()); AsyncHelpers.HandleException <Exception>( continuation, exceptionHandlerContinuation => { List <object> entityPayloads = new List <object>(); if (this.DataProviderSettings.UsePayloadDrivenVerification && clientExpectedError == null) { #if !WINDOWS_PHONE this.HttpTracker.RegisterHandler(dataContext, this.BuildBaselineValueFromResponse); exceptionHandlerContinuation = AsyncHelpers.OnContinueOrFail( exceptionHandlerContinuation, () => this.HttpTracker.UnregisterHandler(dataContext, this.BuildBaselineValueFromResponse, !this.clientExceptionVerified)); #endif if (dataContext != this.currentContext) { this.currentContext = dataContext; } } exceptionHandlerContinuation = exceptionHandlerContinuation.OnContinue( () => { if (clientExpectedError != null && !this.clientExceptionVerified) { continuation.Fail(new TaupoInvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Expected a client exception with resource id '{0}' and of exception type '{1}'.", clientExpectedError.ExpectedExceptionMessage.ResourceIdentifier, clientExpectedError.ExpectedExceptionType.FullName))); } }); executeAction(entityPayloads, exceptionHandlerContinuation); }, e => { if (this.DataProviderSettings.UsePayloadDrivenVerification && this.baselineQueryValue != null && this.baselineQueryValue.EvaluationError != null) { ExceptionUtilities.Assert(e.GetType() == typeof(DataServiceQueryException), "Expected DataServiceQueryException, received " + e.GetType().ToString()); this.Logger.WriteLine(LogLevel.Verbose, this.baselineQueryValue.EvaluationError.ToString()); } else { this.CompareClientOrEvaluationException(expectedValue, clientExpectedError, e); } continuation.Continue(); }); }
internal static CodeExpression BuildClientExpectedErrorExpression(ExpectedClientErrorBaseline clientExpectedErrorExpression) { if (clientExpectedErrorExpression == null) { return(Code.Null()); } CodeExpression expectedExceptionMessageExpression = BuildExpectedErrorMessage(clientExpectedErrorExpression.ExpectedExceptionMessage); return(Code.New( Code.TypeRef(typeof(ExpectedClientErrorBaseline)), Code.TypeOf(Code.TypeRef(clientExpectedErrorExpression.ExpectedExceptionType)), Code.Primitive(clientExpectedErrorExpression.HasServerSpecificExpectedMessage), expectedExceptionMessageExpression)); }
/// <summary> /// Verify the passed query tree. /// </summary> /// <param name="expression">The query tree which will be verified</param> public virtual void Verify(QueryExpression expression) { ExceptionUtilities.CheckAllRequiredDependencies(this); ExceptionUtilities.Assert(this.IsAsync, "this verifier can only run async"); this.ThrowSkippedExceptionIfQueryExpressionNotSupported(expression); var resolvedQuery = this.LinqQueryResolver.Resolve(expression); var dataServiceContext = this.DataServiceContextCreator.CreateContext(this.DataServiceContextScope, this.workspace.ContextType, this.workspace.ServiceUri); if (this.IsExecuteURI) { // TODO: update this verifier to call ExecuteUriAndCompare if ExecuteURI test parameter is set to true } else { ClientQueryGenerator queryGenerator = new ClientQueryGenerator(new CSharpGenericTypeBuilder()); DataServiceContext clientContext = dataServiceContext.Product as DataServiceContext; CoreLinq.Expression queryLinqExpression = queryGenerator.Generate(resolvedQuery, clientContext); IQueryProvider queryProvider = clientContext.CreateQuery <int>("Set").Provider as IQueryProvider; DataServiceQuery dataServiceQuery = queryProvider.CreateQuery(queryLinqExpression) as DataServiceQuery; this.ResultComparer.EnqueueNextQuery(resolvedQuery); AsyncExecutionContext.EnqueueAsynchronousAction((queryContinuation) => { this.Log.WriteLine(LogLevel.Info, dataServiceQuery.ToString()); QueryValue baselineValue = this.GetBaselineValue(resolvedQuery); DataServiceProtocolVersion maxProtocolVersion = this.workspace.ConceptualModel.GetMaxProtocolVersion(); #if WINDOWS_PHONE DataServiceProtocolVersion maxClientProtocolVersion = DataServiceProtocolVersion.V4; #else DataServiceProtocolVersion maxClientProtocolVersion = ((DSC.DataServiceProtocolVersion)dataServiceContext.MaxProtocolVersion.Product).ToTestEnum(); #endif // Calculate version errors ExpectedClientErrorBaseline clientError = this.LinqToAstoriaErrorCalculator.CalculateExpectedClientVersionError(resolvedQuery, true, maxClientProtocolVersion, maxProtocolVersion); if (clientError != null) { this.Log.WriteLine(LogLevel.Info, "Expected client exception: " + clientError.ExpectedExceptionType.ToString()); } Type queryType = dataServiceQuery.ElementType; MethodInfo genericExecuteMethod = this.ResultComparer.GetType().GetMethod("ExecuteAndCompare").MakeGenericMethod(queryType); genericExecuteMethod.Invoke(this.ResultComparer, new object[] { queryContinuation, this.IsAsync, dataServiceQuery, baselineValue, clientContext, clientError }); }); } }
private void CompareClientOrEvaluationException(QueryValue expectedValue, ExpectedClientErrorBaseline clientExpectedException, Exception ex) { this.clientExceptionVerified = true; if (clientExpectedException != null) { this.ClientExpectedExceptionComparer.Compare(clientExpectedException, ex); } else if (ex != null) { QueryError queryError = null; if (expectedValue != null) { queryError = expectedValue.EvaluationError; } this.CompareException(queryError, ex); } }
private DataServiceProtocolVersion CalculateExpectedClientMinRequestVersion(ODataUri odataUri, out ExpectedClientErrorBaseline errorIfTooLow) { ExceptionUtilities.CheckArgumentNotNull(odataUri, "odataUri"); DataServiceProtocolVersion expectedVersion = DataServiceProtocolVersion.V4; errorIfTooLow = null; // Uri specific processing if (odataUri.HasAnyOrAllInFilter()) { expectedVersion = VersionHelper.IncreaseVersionIfRequired(expectedVersion, DataServiceProtocolVersion.V4); string anyOrAll = string.Empty; if (odataUri.Filter.Contains("/any(")) { anyOrAll = "Any"; } else { anyOrAll = "All"; } var errorInformation = new ExpectedErrorMessage("ALinq_MethodNotSupportedForMaxDataServiceVersionLessThanX", anyOrAll, expectedVersion.ConvertToHeaderFormat()); errorIfTooLow = new ExpectedClientErrorBaseline(typeof(NotSupportedException), false, errorInformation); } if (odataUri.HasSignificantTypeSegmentInPath()) { // TODO: this seems like it should be inferred from the query, not the uri expectedVersion = VersionHelper.IncreaseVersionIfRequired(expectedVersion, DataServiceProtocolVersion.V4); var errorInformation = new ExpectedErrorMessage("ALinq_MethodNotSupportedForMaxDataServiceVersionLessThanX", "OfType", expectedVersion.ConvertToHeaderFormat()); errorIfTooLow = new ExpectedClientErrorBaseline(typeof(NotSupportedException), false, errorInformation); } else if (odataUri.HasTypeSegmentInExpandOrSelect()) { // TODO: this seems like it should be inferred from the query, not the uri expectedVersion = VersionHelper.IncreaseVersionIfRequired(expectedVersion, DataServiceProtocolVersion.V4); var errorInformation = new ExpectedErrorMessage("ALinq_TypeAsNotSupportedForMaxDataServiceVersionLessThan3"); errorIfTooLow = new ExpectedClientErrorBaseline(typeof(NotSupportedException), false, errorInformation); } return(expectedVersion); }
public void ExecuteUriAndCompare <TResult>(IAsyncContinuation continuation, bool isAsync, IQueryable <TResult> query, string uriString, QueryValue expectedValue, DataServiceContext dataContext, ExpectedClientErrorBaseline clientExpectedError) { this.isAsynchronous = isAsync; this.ExecuteQueryAction( continuation, expectedValue, dataContext, clientExpectedError, delegate(List <object> entityPayloads, IAsyncContinuation continuation2) { AsyncHelpers.CatchErrors( continuation2, () => { this.Logger.WriteLine(LogLevel.Verbose, "Executing query, async:{0}, Uri:{1}:", isAsync, dataContext.BaseUri + "/" + uriString); Uri builtUri = new Uri(dataContext.BaseUri + "/" + uriString); EventHandler <SendingRequest2EventArgs> sendingRequest = delegate(object sender, SendingRequest2EventArgs args) { HttpRequestMessage request = ((HttpClientRequestMessage)args.RequestMessage).HttpRequestMessage; this.VerifyCommonExecuteHeaders(request.Headers); }; dataContext.SendingRequest2 += sendingRequest; dataContext.Execute( continuation2, isAsync, builtUri, delegate(IEnumerable <TResult> results) { this.Compare(expectedValue, () => results, dataContext); if (entityPayloads.Count > 0) { this.VerifyDescriptorAfterExecute(continuation2, dataContext, entityPayloads, expectedValue); } else { dataContext.SendingRequest2 -= sendingRequest; continuation2.Continue(); } }); }); }); }
/// <summary> /// Executes the given expression asynchronously and compares the result to a given expected value. /// </summary> /// <typeparam name="TResult">The type of the result.</typeparam> /// <param name="continuation">The continuation.</param> /// <param name="isAsync">Determines if we execute async or not</param> /// <param name="query">Query to execute</param> /// <param name="expectedValue">The expected value.</param> /// <param name="dataContext">The data context.</param> /// <param name="clientExpectedError">Client Expected Error Information</param> public void ExecuteAndCompare <TResult>(IAsyncContinuation continuation, bool isAsync, IQueryable <TResult> query, QueryValue expectedValue, DataServiceContext dataContext, ExpectedClientErrorBaseline clientExpectedError) { this.isAsynchronous = isAsync; this.ExecuteQueryAction( continuation, expectedValue, dataContext, clientExpectedError, delegate(List <object> entityPayloads, IAsyncContinuation continuation2) { AsyncHelpers.CatchErrors( continuation2, () => { var dataServiceQuery = (DataServiceQuery <TResult>)query; this.Logger.WriteLine(LogLevel.Verbose, "Executing query async:{0}, Expression:{1}:", isAsync, dataServiceQuery.Expression); dataServiceQuery.Execute( continuation2, isAsync, delegate(IEnumerable <TResult> results) { this.Compare(expectedValue, () => results, dataContext); if (entityPayloads.Count > 0) { this.VerifyDescriptorAfterExecute(continuation2, dataContext, entityPayloads, expectedValue); } else { continuation2.Continue(); } }); }); }); }
public void ExecuteUriAndCompare <TResult>(IAsyncContinuation continuation, bool isAsync, string uriString, HttpVerb verb, OperationParameter[] inputParameters, bool singleResult, DataServiceContext dataContext, ExpectedClientErrorBaseline clientExpectedError) { this.isAsynchronous = isAsync; this.ExecuteQueryAction( continuation, null, dataContext, clientExpectedError, delegate(List <object> entityPayloads, IAsyncContinuation continuation2) { AsyncHelpers.CatchErrors( continuation2, () => { this.Logger.WriteLine(LogLevel.Verbose, "Executing Invoke Action, async:{0}, Uri:{1}:", isAsync, dataContext.BaseUri + "/" + uriString); Uri builtUri = new Uri(dataContext.BaseUri + "/" + uriString); EventHandler <SendingRequest2EventArgs> sendingRequest = delegate(object sender, SendingRequest2EventArgs args) { HttpRequestMessage request = ((HttpClientRequestMessage)args.RequestMessage).HttpRequestMessage; this.VerifyActionExecuteHeaders(verb, request.Headers, inputParameters); this.VerifyCommonExecuteHeaders(request.Headers); }; dataContext.SendingRequest2 += sendingRequest; dataContext.ExecuteUri <TResult>( continuation2, isAsync, builtUri, verb, inputParameters, singleResult, delegate(QueryOperationResponse <TResult> results) { var savedRes = results.ToList(); if (singleResult) { // With singleResult=true, we expected 0/1 result item. Compare() will calculate and update the expected QueryValue to be non-NullValue. this.Compare(this.expressionQueue.Peek().ExpressionType.NullValue, () => savedRes.SingleOrDefault(), dataContext); } else { // With singleResult=false, we expected multiple result items. Compare() will calculate and update the expected QueryValue to be non-NullValue. this.Compare(this.expressionQueue.Peek().ExpressionType.NullValue, () => savedRes, dataContext); } dataContext.SendingRequest2 -= sendingRequest; continuation2.Continue(); }); }); }); }
public void ExecuteUriAndCompare(IAsyncContinuation continuation, bool isAsync, string uriString, HttpVerb verb, OperationParameter[] inputParameters, DataServiceContext dataContext, ExpectedClientErrorBaseline clientExpectedError) { this.isAsynchronous = isAsync; this.ExecuteQueryAction( continuation, null, dataContext, clientExpectedError, delegate(List <object> entityPayloads, IAsyncContinuation continuation2) { AsyncHelpers.CatchErrors( continuation2, () => { this.Logger.WriteLine(LogLevel.Verbose, "Executing Invoke Action, async:{0}, Uri:{1}:", isAsync, dataContext.BaseUri + "/" + uriString); Uri builtUri = new Uri(dataContext.BaseUri + "/" + uriString); EventHandler <SendingRequest2EventArgs> sendingRequest = delegate(object sender, SendingRequest2EventArgs args) { HttpRequestMessage request = ((HttpClientRequestMessage)args.RequestMessage).HttpRequestMessage; this.VerifyActionExecuteHeaders(verb, request.Headers, inputParameters); this.VerifyCommonExecuteHeaders(request.Headers); }; dataContext.SendingRequest2 += sendingRequest; dataContext.ExecuteUri( continuation2, isAsync, builtUri, verb, inputParameters, delegate { dataContext.SendingRequest2 -= sendingRequest; continuation2.Continue(); }); }); }); }
/// <summary> /// Returns the error expected for the Query /// </summary> /// <param name="expression">The expression.</param> /// <param name="usesClientQueryable">Whether the client uri is build from a Client Linq expression or not</param> /// <param name="clientMaxProtocolVersion">Client Max Protocol Version</param> /// <param name="maxProtocolVersion">Max Protocol version of the server</param> /// <returns> a versioning error at the Client level</returns> public ExpectedClientErrorBaseline CalculateExpectedClientVersionError(QueryExpression expression, bool usesClientQueryable, DataServiceProtocolVersion clientMaxProtocolVersion, DataServiceProtocolVersion maxProtocolVersion) { ExceptionUtilities.CheckArgumentNotNull(expression, "expression"); ExceptionUtilities.CheckAllRequiredDependencies(this); DataServiceProtocolVersion expectedDataServiceVersion = DataServiceProtocolVersion.Unspecified; DataServiceProtocolVersion minRequiredRequestVersion = DataServiceProtocolVersion.Unspecified; ExpectedErrorMessage errorInformation; // If the Client Queryable interface is not used to build the expression that is run then no error can happen at this stage // There can only be a protocol error from the server if there is no client error var serverExpression = this.ClientSideProjectionReplacer.ReplaceClientSideProjections(expression); ODataUri odataUri = this.QueryToODataUriConverter.ComputeUri(serverExpression); // Predict what the Client will generate for the data service version, if we are not using client.linq its unspecified otherwise calculate it if (usesClientQueryable) { ExpectedClientErrorBaseline expectedErrorIfTooLow; minRequiredRequestVersion = this.CalculateExpectedClientMinRequestVersion(odataUri, out expectedErrorIfTooLow); if (minRequiredRequestVersion > clientMaxProtocolVersion) { if (expectedErrorIfTooLow == null) { errorInformation = new ExpectedErrorMessage("Context_RequestVersionIsBiggerThanProtocolVersion", minRequiredRequestVersion.ConvertToHeaderFormat(), clientMaxProtocolVersion.ConvertToHeaderFormat()); expectedErrorIfTooLow = new ExpectedClientErrorBaseline(typeof(InvalidOperationException), false, errorInformation); } return(expectedErrorIfTooLow); } EntitySet expectedEntitySet = null; if (odataUri.TryGetExpectedEntitySet(out expectedEntitySet)) { DataServiceProtocolVersion entitySetVersion = expectedEntitySet.CalculateEntitySetProtocolVersion(MimeTypes.ApplicationAtomXml, VersionCalculationType.Request, maxProtocolVersion, clientMaxProtocolVersion); // Client will create a DSV based on the following pieces, metadata of the query based on sets it goes through, uri contructs (select, count, inlinecount, etc) // and headers (like DataServiceResponsePreference). In order to mimic this client behavior I will get the metadata version and a version // from the minrequestVersion and take the max. MinRequest deals with Uri and headers, metadata the metadata. expectedDataServiceVersion = VersionHelper.GetMaximumVersion(minRequiredRequestVersion, entitySetVersion); } } ODataRequest request = new ODataRequest(this.ODataUriToStringConverter) { Uri = odataUri, Verb = HttpVerb.Get, Headers = { { HttpHeaders.DataServiceVersion, expectedDataServiceVersion.ConvertToHeaderFormat() }, { HttpHeaders.MaxDataServiceVersion, clientMaxProtocolVersion.ConvertToHeaderFormat() }, { HttpHeaders.Accept, MimeTypes.ApplicationAtomXml } } }; if (this.ODataRequestVersionResourceErrorCalculator.TryCalculateError(request, maxProtocolVersion, out errorInformation)) { return(new ExpectedClientErrorBaseline(typeof(DSClient.DataServiceQueryException), true, errorInformation)); } return(null); }
public void Compare(ExpectedClientErrorBaseline expectedClientException, Exception exception) { throw new NotImplementedException(); }