Beispiel #1
0
        /// <summary>
        /// Visits the children of the given payload element and replaces it with a copy if any child changes
        /// </summary>
        /// <param name="payloadElement">The payload element to potentially replace</param>
        /// <returns>The original element or a copy to replace it with</returns>
        public virtual ODataPayloadElement Visit(ODataErrorPayload payloadElement)
        {
            ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement");

            var innerError = payloadElement.InnerError;

            if (innerError != null)
            {
                // Note: we specifically allow it to be replaced with null
                innerError = this.Recurse(innerError) as ODataInternalExceptionPayload;
            }

            if (this.ShouldReplace(payloadElement.InnerError, innerError))
            {
                return(payloadElement.ReplaceWith(
                           new ODataErrorPayload()
                {
                    Message = payloadElement.Message,
                    Code = payloadElement.Code,
                    InnerError = innerError,
                }));
            }

            return(payloadElement);
        }
Beispiel #2
0
        /// <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>
        /// Visits the payload element
        /// </summary>
        /// <param name="payloadElement">The payload element to visit</param>
        public override void Visit(ODataErrorPayload payloadElement)
        {
            ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement");
            ExceptionUtilities.CheckObjectNotNull(this.currentXElement, "Current XElement is not defined");

            XElement errorElement = CreateMetadataElement(this.currentXElement, ODataConstants.ErrorElementName);

            string code = payloadElement.Code;

            if (code != null)
            {
                XElement codeElement = CreateMetadataElement(errorElement, ODataConstants.CodeElementName);
                codeElement.Add(code);
            }

            string message = payloadElement.Message;

            if (message != null)
            {
                XElement messageElement = CreateMetadataElement(errorElement, ODataConstants.MessageElementName);
                messageElement.Add(message);
            }

            ODataInternalExceptionPayload innerError = payloadElement.InnerError;

            if (innerError != null)
            {
                XElement innerErrorElement = CreateMetadataElement(errorElement, ODataConstants.InnerErrorElementName);
                this.VisitPayloadElement(innerError, innerErrorElement);
            }

            PostProcessXElement(payloadElement, errorElement);
        }
Beispiel #4
0
 /// <summary>
 /// Visits a payload element whose root is an ODataErrorPayload.
 /// </summary>
 /// <param name="payloadElement">The root node of payload element being visited.</param>
 public virtual void Visit(ODataErrorPayload payloadElement)
 {
     ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement");
     if (payloadElement.InnerError != null)
     {
         this.Recurse(payloadElement.InnerError);
     }
 }
Beispiel #5
0
        public override void Visit(ODataErrorPayload payloadElement)
        {
            ExceptionUtilities.Assert(this.items.Count == 0, "Error should only be top level");
            var error = new ODataError()
            {
                ErrorCode = payloadElement.Code,
                Message   = payloadElement.Message
            };

            this.items.Push(error);
            base.Visit(payloadElement);
        }
Beispiel #6
0
        /// <summary>
        /// Converts an <see cref="ODataErrorpayload"/> into the corresponding <see cref="ODataError"/>.
        /// </summary>
        /// <param name="errorPayload">The error payload to convert.</param>
        /// <param name="forAtom">true if the conversion follows ATOM format rules; false for JSON format rules.</param>
        /// <returns>A new <see cref="ODataError"/> representing the <paramref name="errorPayload"/>.</returns>
        private static ODataError ConvertErrorPayload(ODataErrorPayload errorPayload, bool forAtom)
        {
            ODataError error = new ODataError();

            error.ErrorCode = errorPayload.Code;
            error.Message   = errorPayload.Message;;

            ODataInternalExceptionPayload innerErrorPayload = errorPayload.InnerError;

            if (innerErrorPayload != null)
            {
                error.InnerError = ConvertInnerErrorPayload(innerErrorPayload);
            }

            return(error);
        }
        /// <summary>
        /// Helper method for getting the error payload from the response. Handles a special case for media-resource operations which may contain errors despite not normally
        /// being deserialized as such.
        /// </summary>
        /// <param name="response">The current response</param>
        /// <param name="formatSelector">The format selector to use if the response needs to be deserialized</param>
        /// <param name="errorPayload">The error payload if one was found</param>
        /// <returns>Whether or not an error payload was found</returns>
        internal static bool TryGetErrorPayloadFromResponse(ODataResponse response, IProtocolFormatStrategySelector formatSelector, out ODataErrorPayload errorPayload)
        {
            ExceptionUtilities.CheckArgumentNotNull(response, "response");

            errorPayload = null;
            var payload = response.RootElement;
            if (payload == null)
            {
                return false;
            }

            if (payload.ElementType == ODataPayloadElementType.ODataErrorPayload)
            {
                errorPayload = (ODataErrorPayload)payload;
                return true;
            }

            // From here out, try to handle special case for streams which come back with error payloads and are not interpreted
            if (payload.ElementType != ODataPayloadElementType.PrimitiveValue)
            {
                return false;
            }

            var body = ((PrimitiveValue)payload).ClrValue as byte[];
            if (body == null)
            {
                return false;
            }

            var contentType = response.GetHeaderValueIfExists(HttpHeaders.ContentType);
            if (contentType == null)
            {
                return false;
            }

            // deserialize it
            ExceptionUtilities.CheckArgumentNotNull(formatSelector, "formatSelector");
            var formatForContentType = formatSelector.GetStrategy(contentType, null);
            var deserializer = formatForContentType.GetDeserializer();
            payload = deserializer.DeserializeFromBinary(body, new ODataPayloadContext { EncodingName = HttpUtilities.GetContentTypeCharsetOrNull(contentType) });

            errorPayload = payload as ODataErrorPayload;
            return errorPayload != null;
        }
        /// <summary>
        /// Verifies the ExceptionMessage recursively
        /// </summary>
        /// <param name="expectedErrorMessage">Error Message to Verify</param>
        /// <param name="resourceVerifier">Resource Verifier to use</param>
        /// <param name="errorPayload">Error payload to verify</param>
        /// <param name="assert">assert call to make</param>
        public static void VerifyExceptionMessage(this ExpectedErrorMessage expectedErrorMessage, IStringResourceVerifier resourceVerifier, ODataErrorPayload errorPayload, Action<bool, string> assert)
        {
            ExceptionUtilities.CheckArgumentNotNull(expectedErrorMessage, "expectedErrorMessage");
            ExceptionUtilities.CheckArgumentNotNull(resourceVerifier, "resourceVerifier");
            ExceptionUtilities.CheckArgumentNotNull(errorPayload, "errorPayload");
            ExceptionUtilities.CheckArgumentNotNull(assert, "assert");

            // Verify messages are the same
            // TODO: Need to also verify the language and code
            expectedErrorMessage.VerifyMatch(resourceVerifier, errorPayload.Message, true);

            ExpectedErrorMessage expectedInnerError = expectedErrorMessage.InnerError;
            ODataInternalExceptionPayload innerError = errorPayload.InnerError;

            // Set it to null so comparison won't occur
            if (expectedErrorMessage.SkipInnerErrorVerification)
            {
                innerError = null;
                expectedInnerError = null;
            }

            while (innerError != null)
            {
                // TODO: better error message
                assert(expectedInnerError != null, "Did not expect inner error");

                // Verify messages are the same
                expectedInnerError.VerifyMatch(resourceVerifier, innerError.Message, true);

                if (expectedInnerError.SkipInnerErrorVerification)
                {
                    innerError = null;
                    expectedInnerError = null;
                }
                else
                {
                    // TODO: verify stack trace, type name, etc
                    innerError = innerError.InternalException;
                    expectedInnerError = expectedInnerError.InnerError;
                }
            }
        }
            /// <summary>
            /// Visits a payload element whose root is an ODataErrorPayload.
            /// </summary>
            /// <param name="expected">The root node of payload element being visited.</param>
            public void Visit(ODataErrorPayload expected)
            {
                ExceptionUtilities.CheckArgumentNotNull(expected, "expected");
                var observed = this.GetNextObservedElement <ODataErrorPayload>();

                using (this.Assert.WithMessage("Error did not match expectation"))
                {
                    this.Assert.AreEqual(expected.Message, observed.Message, "Message did not match expectation");
                    this.Assert.AreEqual(expected.Code, observed.Code, "Code did not match expectation");
                    this.CompareAnnotations(expected.Annotations, observed.Annotations);

                    if (expected.InnerError != null)
                    {
                        this.Assert.IsNotNull(observed.InnerError, "Inner error unexpectedly null");
                        this.WrapAccept(expected.InnerError, observed.InnerError);
                    }
                    else
                    {
                        this.Assert.IsNull(observed.InnerError, "Inner error unexpectedly non-null");
                    }
                }
            }
 /// <summary>
 /// Visits a payload element whose root is an ODataErrorPayload.
 /// </summary>
 /// <param name="payloadElement">The root node of payload element being visited.</param>
 public void Visit(ODataErrorPayload payloadElement)
 {
     throw new TaupoNotSupportedException("Not supported yet");
 }
        /// <summary>
        /// Parse the error tag from an Odata response.  It is assumed that the error portion is well formed xml.
        /// </summary>
        /// <param name="reader">Reader where the start error tag has already been parsed.</param>
        /// <returns>The resulting error payload.</returns>
        public ODataErrorPayload ParseErrorFragment(XmlReader reader)
        {
            // example xml error fragment
            // <m:error>
            //   <m:code>…</>
            //   <m:message xml:lang=”…”>…</>
            //   <m:innererror>
            //     <m:message>…</>
            //     <m:type>…</>
            //     <m:stacktrace>…</>
            //     <m:internalexception>
            //       … another inner error structure …
            //     </>
            //   </m:innererror>
            // </m:error>
            ODataErrorPayload topLevelError = new ODataErrorPayload();
            ODataInternalExceptionPayload innerError = null;

            int errorStartDepth = reader.Depth;
            while (reader.Read())
            {
                if (reader.IsStartElement() && reader.NamespaceURI == ODataConstants.DataServicesMetadataNamespaceName)
                {
                    if (reader.LocalName == ODataConstants.InnerErrorElementName)
                    {
                        this.Assert.IsNull(innerError, "Should not find inner error element on internal exceptions");
                        topLevelError.InnerError = innerError = new ODataInternalExceptionPayload();
                    }
                    else if (reader.LocalName == ODataConstants.InternalExceptionElementName)
                    {
                        this.Assert.IsNotNull(innerError, "Should not find internal exception element on top-level errors");
                        ExceptionUtilities.Assert(innerError.InternalException == null, "Expected internal error to be null");
                        innerError.InternalException = new ODataInternalExceptionPayload();
                        innerError = innerError.InternalException;
                    }
                    else if (reader.LocalName == ODataConstants.MessageElementName)
                    {
                        if (reader.HasAttributes)
                        {
                            this.Assert.IsNull(innerError, "Should not find attributes on inner errors");
                        }

                        if (!reader.IsEmptyElement)
                        {
                            reader.Read();
                            if (innerError == null)
                            {
                                topLevelError.Message = reader.Value;
                            }
                            else
                            {
                                innerError.Message = reader.Value;
                            }
                        }
                    }
                    else if (reader.LocalName == ODataConstants.CodeElementName)
                    {
                        this.Assert.IsNull(innerError, "Should not find code element on inner errors");
                        if (!reader.IsEmptyElement)
                        {
                            reader.Read();
                            topLevelError.Code = reader.Value;
                        }
                    }
                    else if (reader.LocalName == ODataConstants.TypeNameElementName)
                    {
                        this.Assert.IsNotNull(innerError, "Should not find type name element on top-level errors");
                        if (!reader.IsEmptyElement)
                        {
                            reader.Read();
                            innerError.TypeName = reader.Value;
                        }
                    }
                    else if (reader.LocalName == ODataConstants.StackTraceElementName)
                    {
                        this.Assert.IsNotNull(innerError, "Should not find stack trace element on top-level errors");
                        if (!reader.IsEmptyElement)
                        {
                            reader.Read();
                            innerError.StackTrace = reader.Value;
                        }
                    }
                }

                // don't read past the end of <error> since there may be un-closed tags
                if (reader.Depth == errorStartDepth)
                {
                    break;
                }
            }

            return topLevelError;
        }
Beispiel #12
0
 /// <summary>
 /// Visits a payload element whose root is an ODataErrorPayload.
 /// </summary>
 /// <param name="payloadElement">The root node of payload element being visited.</param>
 public void Visit(ODataErrorPayload payloadElement)
 {
     throw new TaupoNotSupportedException("Not supported yet");
 }
Beispiel #13
0
        /// <summary>
        /// Creates several PayloadTestDescriptors containing Batch Responses
        /// </summary>
        /// <param name="requestManager">Used for building the requests/responses.</param>
        /// <param name="model">The model to use for adding additional types.</param>
        /// <param name="withTypeNames">Whether or not to use full type names.</param>
        /// <returns>PayloadTestDescriptors</returns>
        public static IEnumerable <PayloadTestDescriptor> CreateBatchResponseTestDescriptors(
            IODataRequestManager requestManager,
            EdmModel model,
            bool withTypeNames = false)
        {
            EdmEntityType  personType = null;
            EdmComplexType carType    = null;

            if (model != null)
            {
                //TODO: CLONE for EdmModel
                //model = model.Clone();

                personType = model.FindDeclaredType("TestModel.TFPerson") as EdmEntityType;
                carType    = model.FindDeclaredType("TestModel.TFCar") as EdmComplexType;

                // Create the metadata types for the entity instance used in the entity set
                if (carType == null)
                {
                    carType = new EdmComplexType("TestModel", "TFCar");
                    model.AddElement(carType);
                    carType.AddStructuralProperty("Make", EdmPrimitiveTypeKind.String, true);
                    carType.AddStructuralProperty("Color", EdmPrimitiveTypeKind.String, true);
                }

                if (personType == null)
                {
                    personType = new EdmEntityType("TestModel", "TFPerson");
                    model.AddElement(personType);
                    personType.AddKeys(personType.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32));
                    personType.AddStructuralProperty("Name", EdmPrimitiveTypeKind.String, true);
                    personType.AddStructuralProperty("Car", carType.ToTypeReference());

                    EdmEntityContainer container = (EdmEntityContainer)model.EntityContainer;
                    if (container == null)
                    {
                        container = new EdmEntityContainer("TestModel", "DefaultContainer");
                        model.AddElement(container);
                        container.AddEntitySet("Customers", personType);
                        container.AddEntitySet("TFPerson", personType);
                    }
                }
            }

            ComplexInstance carInstance = PayloadBuilder.ComplexValue(withTypeNames ? "TestModel.TFCar" : null)
                                          .Property("Make", PayloadBuilder.PrimitiveValue("Ford"))
                                          .Property("Color", PayloadBuilder.PrimitiveValue("Blue"));
            ComplexProperty carProperty = (ComplexProperty)PayloadBuilder.Property("Car", carInstance)
                                          .WithTypeAnnotation(carType);

            EntityInstance personInstance = PayloadBuilder.Entity(withTypeNames ? "TestModel.TFPerson" : null)
                                            .Property("Id", PayloadBuilder.PrimitiveValue(1))
                                            .Property("Name", PayloadBuilder.PrimitiveValue("John Doe"))
                                            .Property("Car", carInstance)
                                            .WithTypeAnnotation(personType);

            ODataErrorPayload errorInstance = PayloadBuilder.Error("ErrorCode")
                                              .Message("ErrorValue")
                                              .InnerError(
                PayloadBuilder.InnerError().Message("InnerErrorMessage").StackTrace("InnerErrorStackTrace").TypeName("InnerErrorTypeName"));

            var carPropertyPayload = new PayloadTestDescriptor()
            {
                PayloadElement  = carProperty,
                PayloadEdmModel = model
            };

            var emptyPayload = new PayloadTestDescriptor()
            {
                PayloadEdmModel = CreateEmptyEdmModel()
            };

            var personPayload = new PayloadTestDescriptor()
            {
                // This payload will be serialised to JSON so we need the annotation to mark it as a response.
                PayloadElement = personInstance.AddAnnotation(new PayloadFormatVersionAnnotation()
                {
                    Response = true, ResponseWrapper = true
                }),
                PayloadEdmModel = model
            };

            var errorPayload = new PayloadTestDescriptor()
            {
                PayloadElement  = errorInstance,
                PayloadEdmModel = model,
            };

            // response operation with a status code of 5 containing a complex instance
            var carPropertyPayloadOperation = carPropertyPayload.InResponseOperation(5, requestManager);
            // response operation with no payload and a status code of 200
            var emptyPayloadOperation = emptyPayload.InResponseOperation(200, requestManager);
            // response operation with a status code of 418 containing an entity instance
            var personPayloadOperation = personPayload.InResponseOperation(418, requestManager, MimeTypes.ApplicationJsonLight);
            // response operation with a status code of 404 containing an error instance
            var errorPayloadOperation = errorPayload.InResponseOperation(404, requestManager);

            // changeset with multiple operations
            var twoOperationsChangeset = BatchUtils.GetResponseChangeset(new IMimePart[] { carPropertyPayloadOperation, emptyPayloadOperation }, requestManager);
            // changesets with a single operation
            var oneOperationChangeset = BatchUtils.GetResponseChangeset(new IMimePart[] { personPayloadOperation }, requestManager);
            var oneErrorChangeset     = BatchUtils.GetResponseChangeset(new IMimePart[] { errorPayloadOperation }, requestManager);
            // empty changeset
            var emptyChangeset = BatchUtils.GetResponseChangeset(new IMimePart[] { }, requestManager);

            // Empty Batch
            yield return(new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchResponsePayload(new IMimePart[] {  })
                                 .AddAnnotation(new BatchBoundaryAnnotation("bb_emptybatch")),
                PayloadEdmModel = emptyPayload.PayloadEdmModel,
                SkipTestConfiguration = (tc) => tc.IsRequest,
            });

            // Single Operation
            yield return(new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchResponsePayload(new IMimePart[] { carPropertyPayloadOperation })
                                 .AddAnnotation(new BatchBoundaryAnnotation("bb_singleoperation")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => tc.IsRequest,
            });

            // Multiple Operations
            yield return(new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchResponsePayload(new IMimePart[] { carPropertyPayloadOperation, emptyPayloadOperation, errorPayloadOperation, personPayloadOperation })
                                 .AddAnnotation(new BatchBoundaryAnnotation("bb_multipleoperations")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => tc.IsRequest,
            });

            // Single Changeset
            yield return(new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchResponsePayload(new IMimePart[] { twoOperationsChangeset })
                                 .AddAnnotation(new BatchBoundaryAnnotation("bb_singlechangeset")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => tc.IsRequest,
            });

            // Multiple Changesets
            yield return(new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchResponsePayload(new IMimePart[] { twoOperationsChangeset, oneOperationChangeset })
                                 .AddAnnotation(new BatchBoundaryAnnotation("bb_multiplechangesets")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => tc.IsRequest,
            });

            // Operations and changesets
            yield return(new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchResponsePayload(new IMimePart[] { twoOperationsChangeset, carPropertyPayloadOperation, oneOperationChangeset })
                                 .AddAnnotation(new BatchBoundaryAnnotation("bb_operationsandchangesets_1")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => tc.IsRequest,
            });

            yield return(new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchResponsePayload(new IMimePart[] { carPropertyPayloadOperation, oneOperationChangeset, emptyPayloadOperation })
                                 .AddAnnotation(new BatchBoundaryAnnotation("bb_operationsandchangesets_2")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => tc.IsRequest,
            });

            yield return(new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchResponsePayload(new IMimePart[] { errorPayloadOperation, carPropertyPayloadOperation, emptyPayloadOperation, twoOperationsChangeset, oneOperationChangeset })
                                 .AddAnnotation(new BatchBoundaryAnnotation("bb_operationsandchangesets_3")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => tc.IsRequest,
            });

            yield return(new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchResponsePayload(
                    new IMimePart[] { oneErrorChangeset, carPropertyPayloadOperation, emptyChangeset, emptyPayloadOperation, twoOperationsChangeset, personPayloadOperation, oneOperationChangeset, errorPayloadOperation })
                                 .AddAnnotation(new BatchBoundaryAnnotation("bb_operationsandchangesets_4")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => tc.IsRequest,
            });
        }
Beispiel #14
0
        /// <summary>
        /// Parse the error tag from an Odata response.  It is assumed that the error portion is well formed xml.
        /// </summary>
        /// <param name="reader">Reader where the start error tag has already been parsed.</param>
        /// <returns>The resulting error payload.</returns>
        public ODataErrorPayload ParseErrorFragment(XmlReader reader)
        {
            // example xml error fragment
            // <m:error>
            //   <m:code>…</>
            //   <m:message xml:lang=”…”>…</>
            //   <m:innererror>
            //     <m:message>…</>
            //     <m:type>…</>
            //     <m:stacktrace>…</>
            //     <m:internalexception>
            //       … another inner error structure …
            //     </>
            //   </m:innererror>
            // </m:error>
            ODataErrorPayload             topLevelError = new ODataErrorPayload();
            ODataInternalExceptionPayload innerError    = null;

            int errorStartDepth = reader.Depth;

            while (reader.Read())
            {
                if (reader.IsStartElement() && reader.NamespaceURI == ODataConstants.DataServicesMetadataNamespaceName)
                {
                    if (reader.LocalName == ODataConstants.InnerErrorElementName)
                    {
                        this.Assert.IsNull(innerError, "Should not find inner error element on internal exceptions");
                        topLevelError.InnerError = innerError = new ODataInternalExceptionPayload();
                    }
                    else if (reader.LocalName == ODataConstants.InternalExceptionElementName)
                    {
                        this.Assert.IsNotNull(innerError, "Should not find internal exception element on top-level errors");
                        ExceptionUtilities.Assert(innerError.InternalException == null, "Expected internal error to be null");
                        innerError.InternalException = new ODataInternalExceptionPayload();
                        innerError = innerError.InternalException;
                    }
                    else if (reader.LocalName == ODataConstants.MessageElementName)
                    {
                        if (reader.HasAttributes)
                        {
                            this.Assert.IsNull(innerError, "Should not find attributes on inner errors");
                        }

                        if (!reader.IsEmptyElement)
                        {
                            reader.Read();
                            if (innerError == null)
                            {
                                topLevelError.Message = reader.Value;
                            }
                            else
                            {
                                innerError.Message = reader.Value;
                            }
                        }
                    }
                    else if (reader.LocalName == ODataConstants.CodeElementName)
                    {
                        this.Assert.IsNull(innerError, "Should not find code element on inner errors");
                        if (!reader.IsEmptyElement)
                        {
                            reader.Read();
                            topLevelError.Code = reader.Value;
                        }
                    }
                    else if (reader.LocalName == ODataConstants.TypeNameElementName)
                    {
                        this.Assert.IsNotNull(innerError, "Should not find type name element on top-level errors");
                        if (!reader.IsEmptyElement)
                        {
                            reader.Read();
                            innerError.TypeName = reader.Value;
                        }
                    }
                    else if (reader.LocalName == ODataConstants.StackTraceElementName)
                    {
                        this.Assert.IsNotNull(innerError, "Should not find stack trace element on top-level errors");
                        if (!reader.IsEmptyElement)
                        {
                            reader.Read();
                            innerError.StackTrace = reader.Value;
                        }
                    }
                }

                // don't read past the end of <error> since there may be un-closed tags
                if (reader.Depth == errorStartDepth)
                {
                    break;
                }
            }

            return(topLevelError);
        }
        public override void Visit(ODataErrorPayload payloadElement)
        {
            ExceptionUtilities.Assert(this.items.Count == 0, "Error should only be top level");
            var error = new ODataError()
            {
                ErrorCode = payloadElement.Code,
                Message = payloadElement.Message
            };

            this.items.Push(error);
            base.Visit(payloadElement);
        }
        /// <summary>
        /// Helper method for getting the error payload from the response. Handles a special case for media-resource operations which may contain errors despite not normally
        /// being deserialized as such.
        /// </summary>
        /// <param name="response">The current response</param>
        /// <param name="formatSelector">The format selector to use if the response needs to be deserialized</param>
        /// <param name="errorPayload">The error payload if one was found</param>
        /// <returns>Whether or not an error payload was found</returns>
        internal static bool TryGetErrorPayloadFromResponse(ODataResponse response, IProtocolFormatStrategySelector formatSelector, out ODataErrorPayload errorPayload)
        {
            ExceptionUtilities.CheckArgumentNotNull(response, "response");

            errorPayload = null;
            var payload = response.RootElement;

            if (payload == null)
            {
                return(false);
            }

            if (payload.ElementType == ODataPayloadElementType.ODataErrorPayload)
            {
                errorPayload = (ODataErrorPayload)payload;
                return(true);
            }

            // From here out, try to handle special case for streams which come back with error payloads and are not interpreted
            if (payload.ElementType != ODataPayloadElementType.PrimitiveValue)
            {
                return(false);
            }

            var body = ((PrimitiveValue)payload).ClrValue as byte[];

            if (body == null)
            {
                return(false);
            }

            var contentType = response.GetHeaderValueIfExists(HttpHeaders.ContentType);

            if (contentType == null)
            {
                return(false);
            }

            // deserialize it
            ExceptionUtilities.CheckArgumentNotNull(formatSelector, "formatSelector");
            var formatForContentType = formatSelector.GetStrategy(contentType, null);
            var deserializer         = formatForContentType.GetDeserializer();

            payload = deserializer.DeserializeFromBinary(body, new ODataPayloadContext {
                EncodingName = HttpUtilities.GetContentTypeCharsetOrNull(contentType)
            });

            errorPayload = payload as ODataErrorPayload;
            return(errorPayload != null);
        }
 /// <summary>
 /// Visits a payload element whose root is an ODataErrorPayload.
 /// </summary>
 /// <param name="payloadElement">The root node of payload element being visited.</param>
 public void Visit(ODataErrorPayload payloadElement)
 {
     throw new AssertionFailedException("Payload should not have contained an error");
 }
        /// <summary>
        /// Deserializes given HTTP payload as a json error payload or returns false
        /// </summary>
        /// <param name="serialized">The payload that was sent over HTTP</param>
        /// <param name="encodingName">Optional name of an encoding to use if it is relevant to the current format. May be null if no character-set information was known.</param>
        /// <param name="errorPayload">Error payload that is found</param>
        /// <returns>True if it finds and error, false if not</returns>
        public bool TryDeserializeErrorPayload(byte[] serialized, string encodingName, out ODataPayloadElement errorPayload)
        {
            ExceptionUtilities.CheckArgumentNotNull(serialized, "serialized");
            errorPayload = null;

            Encoding encoding = HttpUtilities.GetEncodingOrDefault(encodingName);
            string payload = encoding.GetString(serialized, 0, serialized.Length);
            
            // sample json error
            // {
            //   “error”: {
            //     “code”: <string>
            //     “message”: {
            //       “lang”: <string>,
            //       “value“: <string>
            //     },
            //     “innererror”: {
            //       “message”: <string>,
            //       “type”: <string>,
            //       “stacktrace”: <string>,
            //       “internalexception”: {
            //         … another inner error structure …
            //       }
            //     }
            //   }
            // }
            string errorName = "\"" + ODataConstants.ErrorElementName + "\":";
            int errorElementPos = payload.IndexOf(errorName, StringComparison.Ordinal);

            // Look in the payload and see if an error exists
            if (errorElementPos > -1)
            {
                ODataErrorPayload topLevelError = new ODataErrorPayload();
                errorPayload = topLevelError;
                ODataInternalExceptionPayload innerError = null;
                bool inTopLevelMessage = false;
                bool inError = false;

                using (StringReader reader = new StringReader(payload.Substring(errorElementPos)))
                {
                    JsonTokenizer tokenizer = new JsonTokenizer(reader);
                    
                    while (tokenizer.HasMoreTokens())
                    {
                        if (tokenizer.TokenType == JsonTokenType.String)
                        {
                            string tokenValue = null;
                            if (tokenizer != null)
                            {
                                tokenValue = tokenizer.Value.ToString();
                            }

                            // don't start processing other properties until we're definitely inside the error itself
                            if (!inError)
                            {
                                inError = tokenValue == ODataConstants.ErrorElementName;
                            }
                            else
                            {
                                if (tokenValue == ODataConstants.InnerErrorElementName)
                                {
                                    this.Assert.IsNull(innerError, "Should not find 'innererror' property on inner errors");
                                    topLevelError.InnerError = innerError = new ODataInternalExceptionPayload();
                                }
                                else if (tokenValue == ODataConstants.InternalExceptionElementName)
                                {
                                    this.Assert.IsNotNull(innerError, "Should not find 'internalexception' property on top-level errors");
                                    ExceptionUtilities.Assert(innerError.InternalException == null, "Inner error should have been null");
                                    innerError.InternalException = new ODataInternalExceptionPayload();
                                    innerError = innerError.InternalException;
                                }
                                else if (tokenValue == ODataConstants.MessageElementName)
                                {
                                    if (innerError == null)
                                    {
                                        inTopLevelMessage = true;
                                    }
                                    else
                                    {
                                        innerError.Message = this.GetIdentifierValue(tokenizer);
                                    }
                                }
                                else if (tokenValue == ODataConstants.ValueElementName)
                                {
                                    this.Assert.IsTrue(inTopLevelMessage, "Should not find 'value' property outside top-level message");
                                    this.Assert.IsNull(innerError, "Should not find 'value' property on inner errors");
                                    topLevelError.Message = this.GetIdentifierValue(tokenizer);
                                }
                                else if (tokenValue == ODataConstants.CodeElementName)
                                {
                                    this.Assert.IsNull(innerError, "Should not find 'code' property on inner errors");
                                    topLevelError.Code = this.GetIdentifierValue(tokenizer);
                                }
                                else if (tokenValue == ODataConstants.TypeNameElementName)
                                {
                                    this.Assert.IsNotNull(innerError, "Should not find 'type' on top-level errors");
                                    innerError.TypeName = this.GetIdentifierValue(tokenizer);
                                }
                                else if (tokenValue == ODataConstants.StackTraceElementName)
                                {
                                    this.Assert.IsNotNull(innerError, "Should not find 'stacktrace' on top-level errors");
                                    innerError.StackTrace = this.GetIdentifierValue(tokenizer);
                                }
                            }
                        }
                        else if (tokenizer.TokenType == JsonTokenType.RightCurly)
                        {
                            inTopLevelMessage = false;
                        }

                        tokenizer.GetNextToken();
                    }
                }

                return true;
            }

            return false;
        }
Beispiel #19
0
        /// <summary>
        /// Verifies the ExceptionMessage recursively
        /// </summary>
        /// <param name="expectedErrorMessage">Error Message to Verify</param>
        /// <param name="resourceVerifier">Resource Verifier to use</param>
        /// <param name="errorPayload">Error payload to verify</param>
        /// <param name="assert">assert call to make</param>
        public static void VerifyExceptionMessage(this ExpectedErrorMessage expectedErrorMessage, IStringResourceVerifier resourceVerifier, ODataErrorPayload errorPayload, Action <bool, string> assert)
        {
            ExceptionUtilities.CheckArgumentNotNull(expectedErrorMessage, "expectedErrorMessage");
            ExceptionUtilities.CheckArgumentNotNull(resourceVerifier, "resourceVerifier");
            ExceptionUtilities.CheckArgumentNotNull(errorPayload, "errorPayload");
            ExceptionUtilities.CheckArgumentNotNull(assert, "assert");

            // Verify messages are the same
            // TODO: Need to also verify the language and code
            expectedErrorMessage.VerifyMatch(resourceVerifier, errorPayload.Message, true);

            ExpectedErrorMessage          expectedInnerError = expectedErrorMessage.InnerError;
            ODataInternalExceptionPayload innerError         = errorPayload.InnerError;

            // Set it to null so comparison won't occur
            if (expectedErrorMessage.SkipInnerErrorVerification)
            {
                innerError         = null;
                expectedInnerError = null;
            }

            while (innerError != null)
            {
                // TODO: better error message
                assert(expectedInnerError != null, "Did not expect inner error");

                // Verify messages are the same
                expectedInnerError.VerifyMatch(resourceVerifier, innerError.Message, true);

                if (expectedInnerError.SkipInnerErrorVerification)
                {
                    innerError         = null;
                    expectedInnerError = null;
                }
                else
                {
                    // TODO: verify stack trace, type name, etc
                    innerError         = innerError.InternalException;
                    expectedInnerError = expectedInnerError.InnerError;
                }
            }
        }
        /// <summary>
        /// Deserializes given HTTP payload as a json error payload or returns false
        /// </summary>
        /// <param name="serialized">The payload that was sent over HTTP</param>
        /// <param name="encodingName">Optional name of an encoding to use if it is relevant to the current format. May be null if no character-set information was known.</param>
        /// <param name="errorPayload">Error payload that is found</param>
        /// <returns>True if it finds and error, false if not</returns>
        public bool TryDeserializeErrorPayload(byte[] serialized, string encodingName, out ODataPayloadElement errorPayload)
        {
            ExceptionUtilities.CheckArgumentNotNull(serialized, "serialized");
            errorPayload = null;

            Encoding encoding = HttpUtilities.GetEncodingOrDefault(encodingName);
            string   payload  = encoding.GetString(serialized, 0, serialized.Length);

            // sample json error
            // {
            //   “error”: {
            //     “code”: <string>
            //     “message”: {
            //       “lang”: <string>,
            //       “value“: <string>
            //     },
            //     “innererror”: {
            //       “message”: <string>,
            //       “type”: <string>,
            //       “stacktrace”: <string>,
            //       “internalexception”: {
            //         … another inner error structure …
            //       }
            //     }
            //   }
            // }
            string errorName       = "\"" + ODataConstants.ErrorElementName + "\":";
            int    errorElementPos = payload.IndexOf(errorName, StringComparison.Ordinal);

            // Look in the payload and see if an error exists
            if (errorElementPos > -1)
            {
                ODataErrorPayload topLevelError = new ODataErrorPayload();
                errorPayload = topLevelError;
                ODataInternalExceptionPayload innerError = null;
                bool inTopLevelMessage = false;
                bool inError           = false;

                using (StringReader reader = new StringReader(payload.Substring(errorElementPos)))
                {
                    JsonTokenizer tokenizer = new JsonTokenizer(reader);

                    while (tokenizer.HasMoreTokens())
                    {
                        if (tokenizer.TokenType == JsonTokenType.String)
                        {
                            string tokenValue = null;
                            if (tokenizer != null)
                            {
                                tokenValue = tokenizer.Value.ToString();
                            }

                            // don't start processing other properties until we're definitely inside the error itself
                            if (!inError)
                            {
                                inError = tokenValue == ODataConstants.ErrorElementName;
                            }
                            else
                            {
                                if (tokenValue == ODataConstants.InnerErrorElementName)
                                {
                                    this.Assert.IsNull(innerError, "Should not find 'innererror' property on inner errors");
                                    topLevelError.InnerError = innerError = new ODataInternalExceptionPayload();
                                }
                                else if (tokenValue == ODataConstants.InternalExceptionElementName)
                                {
                                    this.Assert.IsNotNull(innerError, "Should not find 'internalexception' property on top-level errors");
                                    ExceptionUtilities.Assert(innerError.InternalException == null, "Inner error should have been null");
                                    innerError.InternalException = new ODataInternalExceptionPayload();
                                    innerError = innerError.InternalException;
                                }
                                else if (tokenValue == ODataConstants.MessageElementName)
                                {
                                    if (innerError == null)
                                    {
                                        inTopLevelMessage = true;
                                    }
                                    else
                                    {
                                        innerError.Message = this.GetIdentifierValue(tokenizer);
                                    }
                                }
                                else if (tokenValue == ODataConstants.ValueElementName)
                                {
                                    this.Assert.IsTrue(inTopLevelMessage, "Should not find 'value' property outside top-level message");
                                    this.Assert.IsNull(innerError, "Should not find 'value' property on inner errors");
                                    topLevelError.Message = this.GetIdentifierValue(tokenizer);
                                }
                                else if (tokenValue == ODataConstants.CodeElementName)
                                {
                                    this.Assert.IsNull(innerError, "Should not find 'code' property on inner errors");
                                    topLevelError.Code = this.GetIdentifierValue(tokenizer);
                                }
                                else if (tokenValue == ODataConstants.TypeNameElementName)
                                {
                                    this.Assert.IsNotNull(innerError, "Should not find 'type' on top-level errors");
                                    innerError.TypeName = this.GetIdentifierValue(tokenizer);
                                }
                                else if (tokenValue == ODataConstants.StackTraceElementName)
                                {
                                    this.Assert.IsNotNull(innerError, "Should not find 'stacktrace' on top-level errors");
                                    innerError.StackTrace = this.GetIdentifierValue(tokenizer);
                                }
                            }
                        }
                        else if (tokenizer.TokenType == JsonTokenType.RightCurly)
                        {
                            inTopLevelMessage = false;
                        }

                        tokenizer.GetNextToken();
                    }
                }

                return(true);
            }

            return(false);
        }
        /// <summary>
        /// Converts an <see cref="ODataErrorpayload"/> into the corresponding <see cref="ODataError"/>.
        /// </summary>
        /// <param name="errorPayload">The error payload to convert.</param>
        /// <param name="forAtom">true if the conversion follows ATOM format rules; false for JSON format rules.</param>
        /// <returns>A new <see cref="ODataError"/> representing the <paramref name="errorPayload"/>.</returns>
        private static ODataError ConvertErrorPayload(ODataErrorPayload errorPayload, bool forAtom)
        {
            ODataError error = new ODataError();

            error.ErrorCode = errorPayload.Code;
            error.Message = errorPayload.Message; ;

            ODataInternalExceptionPayload innerErrorPayload = errorPayload.InnerError;
            if (innerErrorPayload != null)
            {
                error.InnerError = ConvertInnerErrorPayload(innerErrorPayload);
            }

            return error;
        }
        public void TopLevelAtomErrorTest()
        {
            #region Extra attributes on the error elements (and sub-elements)
            var extraAttributePayloads = new[]
            {
                new { PayloadElement = PayloadBuilder.Error(), Template = "<m:error {0} />", },
                new { PayloadElement = PayloadBuilder.Error().Code("ErrorCode"), Template = "<m:error><m:code {0}>ErrorCode</m:code></m:error>" },
                new { PayloadElement = PayloadBuilder.Error().Code("ErrorCode").Message("Message"), Template = "<m:error><m:code>ErrorCode</m:code><m:message {0}>Message</m:message></m:error>" },
                new { PayloadElement = PayloadBuilder.Error().InnerError(PayloadBuilder.InnerError()), Template = "<m:error><m:innererror {0}></m:innererror></m:error>" },
                new { PayloadElement = PayloadBuilder.Error().InnerError(PayloadBuilder.InnerError().Message("InnerMessage")), Template = "<m:error><m:innererror><m:message {0}>InnerMessage</m:message></m:innererror></m:error>" },
                new { PayloadElement = PayloadBuilder.Error().InnerError(PayloadBuilder.InnerError().TypeName("TypeName")), Template = "<m:error><m:innererror><m:type {0}>TypeName</m:type></m:innererror></m:error>" },
                new { PayloadElement = PayloadBuilder.Error().InnerError(PayloadBuilder.InnerError().StackTrace("StackTrace")), Template = "<m:error><m:innererror><m:stacktrace {0}>StackTrace</m:stacktrace></m:innererror></m:error>" },
                new { PayloadElement = PayloadBuilder.Error().InnerError(PayloadBuilder.InnerError().InnerError(new ODataInternalExceptionPayload())), Template = "<m:error><m:innererror><m:internalexception {0}></m:internalexception></m:innererror></m:error>" },
            };

            string[] attributes = new string[]
            {
                "foo='bar'",
                "m:foo='bar'",
                "foo=''",
                "lang='invalid'",
            };

            IEnumerable <PayloadReaderTestDescriptor> testDescriptors = extraAttributePayloads.SelectMany(extraAttributePayload =>
                                                                                                          attributes.Select(attribute =>
            {
                var payloadElement = extraAttributePayload.PayloadElement.DeepCopy();
                string xmlRep      = string.Format(CultureInfo.InvariantCulture, extraAttributePayload.Template, attribute);
                payloadElement     = payloadElement.XmlRepresentation(xmlRep);

                return(new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = payloadElement
                });
            }));
            #endregion Extra attributes on the error elements (and sub-elements)

            #region Extra padding in the error elements' content
            var extraPaddingPayloads = new[]
            {
                new { PayloadElement = PayloadBuilder.Error().Code("ErrorCode"), Template = "<m:error>{0}<m:code>ErrorCode</m:code></m:error>" },
                new { PayloadElement = PayloadBuilder.Error().Code("ErrorCode"), Template = "<m:error><m:code>ErrorCode</m:code>{0}</m:error>" },
                new { PayloadElement = PayloadBuilder.Error().Code("ErrorCode").Message("Message"), Template = "<m:error><m:code>ErrorCode</m:code>{0}<m:message>Message</m:message></m:error>" },
                new { PayloadElement = PayloadBuilder.Error().Code("ErrorCode").Message("Message").InnerError(PayloadBuilder.InnerError()), Template = "<m:error><m:code>ErrorCode</m:code><m:message>Message</m:message>{0}<m:innererror></m:innererror></m:error>" },
                new { PayloadElement = PayloadBuilder.Error().Code("ErrorCode").Message("Message").InnerError(PayloadBuilder.InnerError()), Template = "<m:error><m:code>ErrorCode</m:code><m:message>Message</m:message><m:innererror>{0}</m:innererror></m:error>" },
                new { PayloadElement = PayloadBuilder.Error().InnerError(PayloadBuilder.InnerError().Message("InnerMessage")), Template = "<m:error><m:innererror>{0}<m:message>InnerMessage</m:message></m:innererror></m:error>" },
                new { PayloadElement = PayloadBuilder.Error().InnerError(PayloadBuilder.InnerError().Message("InnerMessage")), Template = "<m:error><m:innererror><m:message>InnerMessage</m:message>{0}</m:innererror></m:error>" },
                new { PayloadElement = PayloadBuilder.Error().InnerError(PayloadBuilder.InnerError().TypeName("TypeName")), Template = "<m:error><m:innererror>{0}<m:type>TypeName</m:type></m:innererror></m:error>" },
                new { PayloadElement = PayloadBuilder.Error().InnerError(PayloadBuilder.InnerError().TypeName("TypeName")), Template = "<m:error><m:innererror><m:type>TypeName</m:type>{0}</m:innererror></m:error>" },
                new { PayloadElement = PayloadBuilder.Error().InnerError(PayloadBuilder.InnerError().TypeName("TypeName").StackTrace("StackTrace")), Template = "<m:error><m:innererror><m:type>TypeName</m:type>{0}<m:stacktrace>StackTrace</m:stacktrace></m:innererror></m:error>" },
                new { PayloadElement = PayloadBuilder.Error().InnerError(PayloadBuilder.InnerError().TypeName("TypeName").StackTrace("StackTrace")), Template = "<m:error><m:innererror><m:type>TypeName</m:type><m:stacktrace>StackTrace</m:stacktrace>{0}</m:innererror></m:error>" },
                new { PayloadElement = PayloadBuilder.Error().InnerError(PayloadBuilder.InnerError().InnerError(new ODataInternalExceptionPayload())), Template = "<m:error><m:innererror>{0}<m:internalexception></m:internalexception></m:innererror></m:error>" },
                new { PayloadElement = PayloadBuilder.Error().InnerError(PayloadBuilder.InnerError().InnerError(new ODataInternalExceptionPayload())), Template = "<m:error><m:innererror><m:internalexception>{0}</m:internalexception></m:innererror></m:error>" },
                new { PayloadElement = PayloadBuilder.Error().InnerError(PayloadBuilder.InnerError().InnerError(new ODataInternalExceptionPayload())), Template = "<m:error><m:innererror><m:internalexception></m:internalexception>{0}</m:innererror></m:error>" },
            };

            string[] xmlPaddingToIgnore = new string[]
            {
                string.Empty,                                           // Nothing
                "  \r\n\t",                                             // Whitespace only
                "<!--s--> <?value?>",                                   // Insignificant nodes
                "some text <![CDATA[cdata]]>",                          // Significant nodes to be ignored
                "<foo xmlns=''/>",                                      // Element in no namespace
                "<c:foo xmlns:c='uri' attr='1'><c:child/>text</c:foo>", // Element in custom namespace
                "<m:properties/>",                                      // Element in metadata namespace (should be ignored as well)
                "<entry/>",                                             // Element in atom namespace (should also be ignored)
            };

            IEnumerable <PayloadReaderTestDescriptor> extraPaddingTestDescriptors = extraPaddingPayloads.SelectMany(extraPaddingPayload =>
                                                                                                                    xmlPaddingToIgnore.Select(xmlPadding =>
            {
                var payloadElement = extraPaddingPayload.PayloadElement.DeepCopy();
                string xmlRep      = string.Format(CultureInfo.InvariantCulture, extraPaddingPayload.Template, xmlPadding);
                payloadElement     = payloadElement.XmlRepresentation(xmlRep);

                return(new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = payloadElement
                });
            }));

            testDescriptors = testDescriptors.Concat(extraPaddingTestDescriptors);
            #endregion Extra padding in the error elements' content

            #region Extra elements in various interesting places of an error payload
            ODataErrorPayload errorPayload = PayloadBuilder.Error()
                                             .Code("ErrorCode")
                                             .Message("Message")
                                             .InnerError(
                PayloadBuilder.InnerError()
                .Message("InnerMessage")
                .TypeName("TypeName")
                .StackTrace("StackTrace")
                .InnerError(
                    PayloadBuilder.InnerError()
                    .Message("InnerInnerMessage")));

            XElement xmlRepresentation = new XElement(TestAtomConstants.ODataMetadataXNamespace + TestAtomConstants.ODataErrorElementName,
                                                      new XElement(TestAtomConstants.ODataMetadataXNamespace + TestAtomConstants.ODataErrorCodeElementName, "ErrorCode"),
                                                      new XElement(TestAtomConstants.ODataMetadataXNamespace + TestAtomConstants.ODataErrorMessageElementName, "Message"),
                                                      new XElement(TestAtomConstants.ODataMetadataXNamespace + TestAtomConstants.ODataInnerErrorElementName,
                                                                   new XElement(TestAtomConstants.ODataMetadataXNamespace + TestAtomConstants.ODataInnerErrorMessageElementName, "InnerMessage"),
                                                                   new XElement(TestAtomConstants.ODataMetadataXNamespace + TestAtomConstants.ODataInnerErrorTypeElementName, "TypeName"),
                                                                   new XElement(TestAtomConstants.ODataMetadataXNamespace + TestAtomConstants.ODataInnerErrorStackTraceElementName, "StackTrace"),
                                                                   new XElement(TestAtomConstants.ODataMetadataXNamespace + TestAtomConstants.ODataInnerErrorInnerErrorElementName,
                                                                                new XElement(TestAtomConstants.ODataMetadataXNamespace + TestAtomConstants.ODataInnerErrorMessageElementName, "InnerInnerMessage"))));

            XElement[] extraElements = new XElement[]
            {
                new XElement(XName.Get("foo"), "bar"),
                new XElement(XName.Get("foo"), new XElement(XName.Get("bar"))),
                new XElement(XName.Get("foo"), new XAttribute(XName.Get("bar"), "attribute-value")),
                new XElement(TestAtomConstants.ODataMetadataXNamespace + "foo", "bar"),
                new XElement(TestAtomConstants.ODataMetadataXNamespace + "foo", new XElement(TestAtomConstants.ODataMetadataXNamespace + "bar")),
                new XElement(XName.Get("foo"), new XAttribute(TestAtomConstants.ODataMetadataXNamespace + "bar", "attribute-value")),
            };

            IEnumerable <PayloadReaderTestDescriptor> extraElementTestDescriptors = extraElements.SelectMany(extraElement =>
            {
                return(InjectElement(extraElement, xmlRepresentation).Select(errorWithInjectedElement =>
                                                                             new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = errorPayload.DeepCopy().XmlRepresentation(errorWithInjectedElement)
                }
                                                                             ));
            });
            testDescriptors = testDescriptors.Concat(extraElementTestDescriptors);
            #endregion Extra elements in various interesting places of an error payload

            #region Various payload orders for an error element
            errorPayload = PayloadBuilder.Error()
                           .Code("ErrorCode")
                           .Message("Message")
                           .InnerError(
                PayloadBuilder.InnerError()
                .Message("InnerMessage")
                .TypeName("TypeName")
                .StackTrace("StackTrace")
                .InnerError(
                    PayloadBuilder.InnerError()
                    .Message("InnerInnerMessage")));

            xmlRepresentation = new XElement(TestAtomConstants.ODataMetadataXNamespace + TestAtomConstants.ODataErrorElementName,
                                             new XElement(TestAtomConstants.ODataMetadataXNamespace + TestAtomConstants.ODataErrorCodeElementName, "ErrorCode"),
                                             new XElement(TestAtomConstants.ODataMetadataXNamespace + TestAtomConstants.ODataErrorMessageElementName, "Message"),
                                             new XElement(TestAtomConstants.ODataMetadataXNamespace + TestAtomConstants.ODataInnerErrorElementName,
                                                          new XElement(TestAtomConstants.ODataMetadataXNamespace + TestAtomConstants.ODataInnerErrorMessageElementName, "InnerMessage"),
                                                          new XElement(TestAtomConstants.ODataMetadataXNamespace + TestAtomConstants.ODataInnerErrorTypeElementName, "TypeName"),
                                                          new XElement(TestAtomConstants.ODataMetadataXNamespace + TestAtomConstants.ODataInnerErrorStackTraceElementName, "StackTrace"),
                                                          new XElement(TestAtomConstants.ODataMetadataXNamespace + TestAtomConstants.ODataInnerErrorInnerErrorElementName,
                                                                       new XElement(TestAtomConstants.ODataMetadataXNamespace + TestAtomConstants.ODataInnerErrorMessageElementName, "InnerInnerMessage"))));

            IEnumerable <PayloadReaderTestDescriptor> payloadOrderTestDescriptors = GeneratePayloadOrders(xmlRepresentation).Select(xmlRep =>
                                                                                                                                    new PayloadReaderTestDescriptor(this.Settings)
            {
                PayloadElement = errorPayload.DeepCopy().XmlRepresentation(xmlRep)
            }
                                                                                                                                    );
            testDescriptors = testDescriptors.Concat(payloadOrderTestDescriptors);
            #endregion Various payload orders for an error element

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                this.ReaderTestConfigurationProvider.AtomFormatConfigurations.Where(tc => !tc.IsRequest),
                (testDescriptor, testConfiguration) =>
            {
                testDescriptor.RunTest(testConfiguration);
            });
        }
 /// <summary>
 /// Visits a payload element whose root is an ODataErrorPayload.
 /// </summary>
 /// <param name="payloadElement">The root node of payload element being visited.</param>
 public override void Visit(ODataErrorPayload payloadElement)
 {
     base.Visit(payloadElement);
 }
Beispiel #24
0
        /// <summary>
        /// Creates a set of interesting error values.
        /// </summary>
        /// <param name="settings">The test descriptor settings to use.</param>
        /// <returns>List of test descriptors with interesting error values as payload.</returns>
        public static IEnumerable<PayloadTestDescriptor> CreateErrorTestDescriptors()
        {
            // error payloads
            IEnumerable<ODataErrorPayload> errors = new ODataErrorPayload[]
            {
                PayloadBuilder.Error().Code("ErrorCode"),
                PayloadBuilder.Error().Code("ErrorCode").Message("Error message"),
                PayloadBuilder.Error().Code("ErrorCode").Message(string.Empty),
                PayloadBuilder.Error().Message("Error message"),
                PayloadBuilder.Error().Message(string.Empty),
                PayloadBuilder.Error().Message("Error message"),
            };

            foreach (ODataErrorPayload errorPayload in errors)
            {
                yield return new PayloadTestDescriptor(){ PayloadElement = errorPayload.DeepCopy() };
            }

            // inner error payloads
            IEnumerable<ODataInternalExceptionPayload> innerErrors = new ODataInternalExceptionPayload[]
            {
                PayloadBuilder.InnerError(),
                PayloadBuilder.InnerError().Message("Inner error message"),
                PayloadBuilder.InnerError().StackTrace("Stack trace"),
                PayloadBuilder.InnerError().TypeName("Type name"),
                PayloadBuilder.InnerError().Message("Inner error message").StackTrace("Stack trace").TypeName("Type name"),
            };

            // create nested inner error payloads
            innerErrors = innerErrors.Concat(innerErrors.Select(inner =>
                PayloadBuilder.InnerError().Message("Outer inner error message").StackTrace("Stack trace").TypeName("Type name").InnerError(inner.DeepCopy())));

            // create a deeply nested inner error payload
            var deeplyNestedInnerError = PayloadBuilder.InnerError();
            foreach (var innerError in innerErrors)
            {
                var copyOfInnerError = innerError.DeepCopy();
                if (copyOfInnerError.InternalException == null)
                {
                    copyOfInnerError.InnerError(deeplyNestedInnerError);
                }
                else
                {
                    ExceptionUtilities.Assert(copyOfInnerError.InternalException.InternalException == null, "Did not expect inner error nesting beyond 2");
                    copyOfInnerError.InternalException.InnerError(deeplyNestedInnerError);
                }

                deeplyNestedInnerError = copyOfInnerError;
            }

            innerErrors = innerErrors.ConcatSingle(deeplyNestedInnerError);

            // put the inner errors into an empty error and all the other error payloads.
            foreach (ODataInternalExceptionPayload innerError in innerErrors)
            {
                yield return new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.Error().InnerError(innerError.DeepCopy()) };

                foreach (ODataErrorPayload outerError in errors)
                {
                    yield return new PayloadTestDescriptor() { PayloadElement = outerError.DeepCopy().InnerError(innerError.DeepCopy()) };
                }
            }
        }
Beispiel #25
0
 /// <summary>
 /// Visits a payload element whose root is an ODataErrorPayload.
 /// </summary>
 /// <param name="payloadElement">The root node of payload element being visited.</param>
 public override void Visit(ODataErrorPayload payloadElement)
 {
     base.Visit(payloadElement);
 }
Beispiel #26
0
        /// <summary>
        /// Creates a set of interesting error values.
        /// </summary>
        /// <param name="settings">The test descriptor settings to use.</param>
        /// <returns>List of test descriptors with interesting error values as payload.</returns>
        public static IEnumerable <PayloadTestDescriptor> CreateErrorTestDescriptors()
        {
            // error payloads
            IEnumerable <ODataErrorPayload> errors = new ODataErrorPayload[]
            {
                PayloadBuilder.Error().Code("ErrorCode"),
                PayloadBuilder.Error().Code("ErrorCode").Message("Error message"),
                PayloadBuilder.Error().Code("ErrorCode").Message(string.Empty),
                PayloadBuilder.Error().Message("Error message"),
                PayloadBuilder.Error().Message(string.Empty),
                PayloadBuilder.Error().Message("Error message"),
            };

            foreach (ODataErrorPayload errorPayload in errors)
            {
                yield return(new PayloadTestDescriptor()
                {
                    PayloadElement = errorPayload.DeepCopy()
                });
            }

            // inner error payloads
            IEnumerable <ODataInternalExceptionPayload> innerErrors = new ODataInternalExceptionPayload[]
            {
                PayloadBuilder.InnerError(),
                                                        PayloadBuilder.InnerError().Message("Inner error message"),
                PayloadBuilder.InnerError().StackTrace("Stack trace"),
                PayloadBuilder.InnerError().TypeName("Type name"),
                PayloadBuilder.InnerError().Message("Inner error message").StackTrace("Stack trace").TypeName("Type name"),
            };

            // create nested inner error payloads
            innerErrors = innerErrors.Concat(innerErrors.Select(inner =>
                                                                PayloadBuilder.InnerError().Message("Outer inner error message").StackTrace("Stack trace").TypeName("Type name").InnerError(inner.DeepCopy())));

            // create a deeply nested inner error payload
            var deeplyNestedInnerError = PayloadBuilder.InnerError();

            foreach (var innerError in innerErrors)
            {
                var copyOfInnerError = innerError.DeepCopy();
                if (copyOfInnerError.InternalException == null)
                {
                    copyOfInnerError.InnerError(deeplyNestedInnerError);
                }
                else
                {
                    ExceptionUtilities.Assert(copyOfInnerError.InternalException.InternalException == null, "Did not expect inner error nesting beyond 2");
                    copyOfInnerError.InternalException.InnerError(deeplyNestedInnerError);
                }

                deeplyNestedInnerError = copyOfInnerError;
            }

            innerErrors = innerErrors.ConcatSingle(deeplyNestedInnerError);

            // put the inner errors into an empty error and all the other error payloads.
            foreach (ODataInternalExceptionPayload innerError in innerErrors)
            {
                yield return(new PayloadTestDescriptor()
                {
                    PayloadElement = PayloadBuilder.Error().InnerError(innerError.DeepCopy())
                });

                foreach (ODataErrorPayload outerError in errors)
                {
                    yield return(new PayloadTestDescriptor()
                    {
                        PayloadElement = outerError.DeepCopy().InnerError(innerError.DeepCopy())
                    });
                }
            }
        }