/// <summary> /// Runs the test specified by this test descriptor. /// </summary> /// <param name="testConfiguration">The test configuration to use for running the test.</param> public virtual void RunTest(ReaderTestConfiguration testConfiguration) { if (this.ShouldSkipForTestConfiguration(testConfiguration)) { return; } TestMessage message = this.CreateInputMessage(testConfiguration); IEdmModel model = this.GetMetadataProvider(testConfiguration); ReaderTestExpectedResult expectedResult = this.GetExpectedResult(testConfiguration); ExceptionUtilities.Assert(expectedResult != null, "The expected result could not be determined for the test. Did you specify it?"); Exception exception = TestExceptionUtils.RunCatching(() => { using (ODataMessageReaderTestWrapper messageReaderWrapper = TestReaderUtils.CreateMessageReader(message, model, testConfiguration)) { expectedResult.VerifyResult(messageReaderWrapper, this.PayloadKind, testConfiguration); } }); try { expectedResult.VerifyException(exception); } catch (Exception) { this.TraceFailureInformation(testConfiguration); throw; } }
/// <summary> /// Applies the specified max protocol version to copy of the settings. /// </summary> /// <param name="maxProtocolVersion">The max protocol version to apply.</param> /// <returns>A copy of this configuration with the max protocol version applied.</returns> public ReaderTestConfiguration CloneAndApplyMaxProtocolVersion(ODataVersion maxProtocolVersion) { ReaderTestConfiguration testConfiguration = new ReaderTestConfiguration(this); testConfiguration.MessageReaderSettings.MaxProtocolVersion = maxProtocolVersion; return(testConfiguration); }
/// <summary> /// Gets The model to use for the specified test configuration. /// </summary> /// <param name="testConfiguration">The test configuration to use.</param> /// <returns>The model to use for the test.</returns> protected override IEdmModel GetMetadataProvider(ReaderTestConfiguration testConfiguration) { IEdmModel model = base.GetMetadataProvider(testConfiguration); if (model == null) { // Try to set the cached model if it is null. If the PayloadEdmModel is null cached model will stay null. if (this.cachedModel == null) { this.cachedModel = this.PayloadEdmModel; } if (this.cachedModel != null) { if (this.Annotations != null) { this.cachedModel = EdmModelBuilder.BuildAnnotationModel(this.Annotations, this.cachedModel); } } model = this.cachedModel; } return(model); }
/// <summary> /// Constructor. /// </summary> /// <param name="batchTestConfiguration">The test configuration for the entire batch payload.</param> /// <param name="applyExpectedResultNormalizers">The func which applies expected result normalizers to a payload element.</param> public BatchPayloadExpectedResultNormalizer( ReaderTestConfiguration batchTestConfiguration, Func <ODataPayloadElement, ReaderTestConfiguration, ODataPayloadElement> applyExpectedResultNormalizers) { this.batchTestConfiguration = batchTestConfiguration; this.applyExpectedResultNormalizers = applyExpectedResultNormalizers; }
/// <summary> /// Called to get the expected result of the test. /// </summary> /// <param name="testConfiguration">The test configuration to use.</param> /// <returns>The expected result.</returns> protected override ReaderTestExpectedResult GetExpectedResult(ReaderTestConfiguration testConfiguration) { ReaderTestExpectedResult expectedResult = base.GetExpectedResult(testConfiguration); if (expectedResult == null) { IEdmModel model = this.GetMetadataProvider(testConfiguration); ReaderMetadata readerMetadata = new ReaderMetadata(model, this.PayloadElement); // First use the input payload as the expected result. ODataPayloadElement expectedResultPayloadElement = this.PayloadElement; // If we have an override specifically for expected result, use that instead. if (this.ExpectedResultPayloadElement != null) { expectedResultPayloadElement = this.ExpectedResultPayloadElement(testConfiguration); } if (expectedResultPayloadElement.ElementType == ODataPayloadElementType.BatchRequestPayload || expectedResultPayloadElement.ElementType == ODataPayloadElementType.BatchResponsePayload) { if (this.ExpectedResultNormalizers.Count > 0) { expectedResultPayloadElement = new BatchPayloadExpectedResultNormalizer( testConfiguration, this.ApplyExpectedResultNormalizers).Normalize(expectedResultPayloadElement); } IEdmModel payloadModel = this.GetMetadataProvider(testConfiguration); return(new BatchReaderTestExpectedResult(this.settings.BatchExpectedResultSettings) { ExpectedBatchPayload = expectedResultPayloadElement, PayloadModel = payloadModel, ExpectedException = this.ExpectedException, }); } else { expectedResultPayloadElement = this.ApplyExpectedResultNormalizers(expectedResultPayloadElement, testConfiguration); } return(new PayloadReaderTestExpectedResult(this.settings.ExpectedResultSettings) { ExpectedPayloadElement = expectedResultPayloadElement, ExpectedException = this.ExpectedException, ReaderMetadata = readerMetadata, IgnorePropertyOrder = this.IgnorePropertyOrder, }); } else { PayloadReaderTestExpectedResult payloadReaderTestExpectedResult = expectedResult as PayloadReaderTestExpectedResult; if (payloadReaderTestExpectedResult != null && payloadReaderTestExpectedResult.ReaderMetadata == null) { IEdmModel model = this.GetMetadataProvider(testConfiguration); payloadReaderTestExpectedResult.ReaderMetadata = new ReaderMetadata(model, this.PayloadElement); } return(expectedResult); } }
/// <summary> /// Writes the content of the input message into a stream. /// </summary> /// <param name="testConfiguration">The test configuration to use.</param> /// <param name="stream">The stream to write to.</param> private void WriteInputMessageContent(ReaderTestConfiguration testConfiguration, Stream stream) { if (this.InputCreator != null) { // Note that by default the StreamWriter uses UTF8 encoding which is exactly what we want. using (StreamWriter textWriter = new StreamWriter(stream)) { textWriter.Write(this.InputCreator(testConfiguration)); } } else { if (testConfiguration.Format == ODataFormat.Atom) { ExceptionUtilities.Assert( this.AtomInput != null || this.AtomInputXml != null, "The test tries to use ATOM format, thus the AtomInput or AtomInputXml must be specified."); // Note that by default the Save will use UTF8 encoding which is exactly what we want. this.AtomInput.Save(stream, SaveOptions.DisableFormatting); } else if (testConfiguration.Format == null) { ExceptionUtilities.CheckObjectNotNull(this.DefaultInput, "The test tries to use Default format, thus the DefaultInput must be specified."); // Note that by default the StreamWriter uses UTF8 encoding which is exactly what we want. using (StreamWriter textWriter = new StreamWriter(stream)) { textWriter.Write(this.DefaultInput); } } } }
/// <summary> /// Constructor. /// </summary> /// <param name="other">The <see cref="ReaderTestConfiguration"/> instance used to initialize the new instance.</param> /// <param name="behaviorKind">The behavior to use when running this test.</param> private ReaderTestConfiguration(ReaderTestConfiguration other, TestODataBehaviorKind behaviorKind) : base(other.Format, other.Version, other.IsRequest, behaviorKind) { this.MessageReaderSettings = other.MessageReaderSettings.Clone(); this.Synchronous = other.Synchronous; this.SkipStateValidationBeforeRead = other.SkipStateValidationBeforeRead; }
/// <summary> /// Called to create the input message for the reader test. /// </summary> /// <param name="testConfiguration">The test configuration.</param> /// <returns>The newly created test message to use.</returns> protected override TestMessage CreateInputMessage(ReaderTestConfiguration testConfiguration) { MemoryStream memoryStream = new MemoryStream(this.GetPayload(testConfiguration)); TestStream messageStream = new TestStream(memoryStream); if (testConfiguration.Synchronous) { messageStream.FailAsynchronousCalls = true; } else { messageStream.FailSynchronousCalls = true; } this.testMessage = TestReaderUtils.CreateInputMessageFromStream( messageStream, testConfiguration, /*payloadKind*/ null, this.ContentType, /*urlResolver*/ null); if (this.TestMessageWrapper != null) { this.testMessage = this.TestMessageWrapper(this.testMessage); } return(this.testMessage); }
/// <summary> /// Returns the payload to be used for this test case and the specified test configuration. /// </summary> /// <param name="testConfiguration">The test configuration to use.</param> /// <returns>The payload to use for testing.</returns> private byte[] GetPayload(ReaderTestConfiguration testConfiguration) { if (testConfiguration.Format != null && testConfiguration.Format != ODataFormat.Metadata) { // NOTE: metadata reading is not supported in other formats; return an empty payload for error tests return(new byte[0]); } TestStream testStream = new TestStream(new MemoryStream(), ignoreDispose: true); if (this.PayloadEdmModel != null) { using (XmlWriter xmlWriter = XmlWriter.Create(testStream)) { IEnumerable <EdmError> errors; if (!CsdlWriter.TryWriteCsdl(this.PayloadEdmModel, xmlWriter, CsdlTarget.OData, out errors)) { var errorBuilder = new StringBuilder(); foreach (var error in errors) { errorBuilder.AppendLine(error.ToString()); } throw new Exception("TryWriteEdmx Error:" + errorBuilder); } } } byte[] payload = new byte[testStream.Length]; testStream.Seek(0, SeekOrigin.Begin); testStream.Read(payload, 0, (int)testStream.Length); return(payload); }
/// <summary> /// Applies the specified behavior with default settings. /// </summary> /// <param name="behaviorKind">The behavior kind to apply.</param> /// <returns>A copy of this configuration with the new behavior applied.</returns> public ReaderTestConfiguration CloneAndApplyBehavior(TestODataBehaviorKind behaviorKind) { ReaderTestConfiguration testConfiguration = new ReaderTestConfiguration(this, behaviorKind); switch (behaviorKind) { case TestODataBehaviorKind.Default: break; case TestODataBehaviorKind.WcfDataServicesClient: testConfiguration.MessageReaderSettings.Validations &= ~ValidationKinds.ThrowOnDuplicatePropertyNames; testConfiguration.MessageReaderSettings.ClientCustomTypeResolver = null; testConfiguration.MessageReaderSettings.Validations &= ~ValidationKinds.ThrowIfTypeConflictsWithMetadata; break; case TestODataBehaviorKind.WcfDataServicesServer: testConfiguration.MessageReaderSettings.Validations &= ~ValidationKinds.ThrowOnDuplicatePropertyNames; testConfiguration.MessageReaderSettings.ClientCustomTypeResolver = null; testConfiguration.MessageReaderSettings.Validations &= ~ValidationKinds.ThrowIfTypeConflictsWithMetadata; // EnableReadingEntryContentInEntryStartState == true break; } return(testConfiguration); }
/// <summary> /// Constructor. /// </summary> /// <param name="parameterReader">The reader to wrap.</param> /// <param name="testConfiguration">The test configuration to use.</param> public ODataParameterReaderTestWrapper(ODataParameterReader parameterReader, ReaderTestConfiguration testConfiguration) { ExceptionUtilities.CheckArgumentNotNull(parameterReader, "parameterReader"); ExceptionUtilities.CheckArgumentNotNull(testConfiguration, "testConfiguration"); this.parameterReader = parameterReader; this.testConfiguration = testConfiguration; }
/// <summary> /// Constructor. /// </summary> /// <param name="collectionReader">The reader to wrap.</param> /// <param name="testConfiguration">The test configuration to use.</param> public ODataCollectionReaderTestWrapper(ODataCollectionReader collectionReader, ReaderTestConfiguration testConfiguration) { ExceptionUtilities.CheckArgumentNotNull(collectionReader, "collectionReader"); ExceptionUtilities.CheckArgumentNotNull(testConfiguration, "testConfiguration"); this.collectionReader = collectionReader; this.testConfiguration = testConfiguration; }
/// <summary> /// Constructor. /// </summary> /// <param name="batchReader">The reader to wrap.</param> /// <param name="testConfiguration">The test configuration to use.</param> public ODataBatchReaderTestWrapper(ODataBatchReader batchReader, ReaderTestConfiguration testConfiguration) { ExceptionUtilities.CheckArgumentNotNull(batchReader, "batchReader"); ExceptionUtilities.CheckArgumentNotNull(testConfiguration, "testConfiguration"); this.batchReader = batchReader; this.testConfiguration = testConfiguration; }
/// <summary> /// Constructor. /// </summary> /// <param name="reader">The reader to wrap.</param> /// <param name="testConfiguration">The test configuration to use.</param> public ODataReaderTestWrapper(ODataReader reader, ReaderTestConfiguration testConfiguration) { ExceptionUtilities.CheckArgumentNotNull(reader, "reader"); ExceptionUtilities.CheckArgumentNotNull(testConfiguration, "testConfiguration"); this.reader = reader; this.testConfiguration = testConfiguration; }
/// <summary> /// If overriden dumps the content of an input message which would be created for the specified test configuration /// into a string and returns it. This is used only for debugging purposes. /// </summary> /// <param name="testConfiguration">The test configuration to use.</param> /// <returns>The string content of the input message.</returns> protected override string DumpInputMessageContent(ReaderTestConfiguration testConfiguration) { MemoryStream stream = new MemoryStream(); TestStream testStream = new TestStream(stream, true /*ignoreDispose*/); this.WriteInputMessageContent(testConfiguration, testStream); return(Encoding.UTF8.GetString(stream.GetBuffer(), 0, (int)stream.Length)); }
/// <summary> /// Called to create the input message for the reader test and sets the specified value for the Content-Type header. /// </summary> /// <param name="testConfiguration">The test configuration.</param> /// <returns>The newly created test message to use.</returns> protected override TestMessage CreateInputMessage(ReaderTestConfiguration testConfiguration) { TestMessage testMessage = base.CreateInputMessage(testConfiguration); // overwrite the content-type header of the message testMessage.SetHeader(ODataConstants.ContentTypeHeader, this.ContentType); return testMessage; }
/// <summary> /// Constructor. /// </summary> /// <param name="messageReader">The message reader to wrap.</param> /// <param name="testConfiguration">The test configuration to use.</param> /// <remarks> /// This constructor is used if not special checks against a test message should be performed. /// Use the constructor overload that takes a <see cref="TestMessage"/> argument to enforce checks /// around disposal of the message. /// </remarks> public ODataMessageReaderTestWrapper(ODataMessageReader messageReader, ODataMessageReaderSettings messageReaderSettings, ReaderTestConfiguration testConfiguration) { ExceptionUtilities.CheckArgumentNotNull(messageReader, "messageReader"); ExceptionUtilities.CheckArgumentNotNull(testConfiguration, "testConfiguration"); this.messageReader = messageReader; this.messageReaderSettings = messageReaderSettings; this.testConfiguration = testConfiguration; }
/// <summary> /// Called to create the input message for the reader test and sets the specified value for the Content-Type header. /// </summary> /// <param name="testConfiguration">The test configuration.</param> /// <returns>The newly created test message to use.</returns> protected override TestMessage CreateInputMessage(ReaderTestConfiguration testConfiguration) { TestMessage testMessage = base.CreateInputMessage(testConfiguration); // overwrite the content-type header of the message testMessage.SetHeader(ODataConstants.ContentTypeHeader, this.ContentType); return(testMessage); }
/// <summary> /// Called to get the expected result of the test. /// </summary> /// <param name="testConfiguration">The test configuration to use.</param> /// <returns>The expected result.</returns> protected override ReaderTestExpectedResult GetExpectedResult(ReaderTestConfiguration testConfiguration) { return(new PayloadKindDetectionTestExpectedResult(this.settings.ExpectedResultSettings) { TestMessage = this.testMessage, ReadDetectedPayloads = this.ReadDetectedPayloads, ExpectedDetectionResults = this.ExpectedDetectionResults == null ? null : this.ExpectedDetectionResults(testConfiguration), ExpectedException = this.ExpectedException, }); }
/// <summary> /// Called before the test is actually executed for the specified test configuration to determine if the test should be skipped. /// </summary> /// <param name="testConfiguration">The test configuration to use.</param> /// <returns>true if the test should be skipped for the <paramref name="testConfiguration"/> or false to run the test.</returns> /// <remarks>Derived classes should always call the base class and return true if the base class returned true.</remarks> protected virtual bool ShouldSkipForTestConfiguration(ReaderTestConfiguration testConfiguration) { if (this.SkipTestConfiguration != null) { return(this.SkipTestConfiguration(testConfiguration)); } else { return(false); } }
/// <summary> /// Called to get the expected result of the test. /// </summary> /// <param name="testConfiguration">The test configuration to use.</param> /// <returns>The expected result.</returns> protected virtual ReaderTestExpectedResult GetExpectedResult(ReaderTestConfiguration testConfiguration) { if (this.ExpectedResultCallback != null) { return(this.ExpectedResultCallback(testConfiguration)); } else { return(null); } }
/// <summary> /// Verifies that the result of the test (the message reader) is what the test expected. /// </summary> /// <param name="messageReader">The message reader which is the result of the test. This method should use it to read the results /// of the parsing and verify those.</param> /// <param name="payloadKind">The payload kind specified in the test descriptor.</param> /// <param name="testConfiguration">The test configuration to use.</param> public override void VerifyResult( ODataMessageReaderTestWrapper messageReader, ODataPayloadKind payloadKind, ReaderTestConfiguration testConfiguration) { // First compare the payload kind detection results. IEnumerable <ODataPayloadKindDetectionResult> actualDetectionResults = messageReader.DetectPayloadKind(); this.VerifyPayloadKindDetectionResult(actualDetectionResults); // Then try to read the message as the detected kind if requested if (this.ReadDetectedPayloads) { bool firstResult = true; foreach (PayloadKindDetectionResult result in this.ExpectedDetectionResults) { if (firstResult) { // For the first result use the existing message reader firstResult = false; } else { // For all subsequent results we need to reset the test stream and create a new message reader // over it. this.TestMessage.Reset(); messageReader = TestReaderUtils.CreateMessageReader(this.TestMessage, result.Model, testConfiguration); // Detect the payload kinds again and make sure we can also read the subsequent payload kinds // immediately after detection. actualDetectionResults = messageReader.DetectPayloadKind(); this.VerifyPayloadKindDetectionResult(actualDetectionResults); } TestExceptionUtils.ExpectedException( this.settings.Assert, () => { using (messageReader) { this.settings.MessageToObjectModelReader.ReadMessage( messageReader, result.PayloadKind, result.Model, new PayloadReaderTestDescriptor.ReaderMetadata(result.ExpectedType), /*expectedBatchPayload*/ null, testConfiguration); } }, result.ExpectedException, this.settings.ExceptionVerifier); } } }
/// <summary> /// Verifies that the result of the test (the message reader) is what the test expected. /// </summary> /// <param name="messageReader">The message reader which is the result of the test. This method should use it to read the results /// of the parsing and verify those.</param> /// <param name="payloadKind">The payload kind specified in the test descriptor.</param> /// <param name="testConfiguration">The test configuration to use.</param> public override void VerifyResult( ODataMessageReaderTestWrapper messageReader, ODataPayloadKind payloadKind, ReaderTestConfiguration testConfiguration) { // First compare the payload kind detection results. IEnumerable<ODataPayloadKindDetectionResult> actualDetectionResults = messageReader.DetectPayloadKind(); this.VerifyPayloadKindDetectionResult(actualDetectionResults); // Then try to read the message as the detected kind if requested if (this.ReadDetectedPayloads) { bool firstResult = true; foreach (PayloadKindDetectionResult result in this.ExpectedDetectionResults) { if (firstResult) { // For the first result use the existing message reader firstResult = false; } else { // For all subsequent results we need to reset the test stream and create a new message reader // over it. this.TestMessage.Reset(); messageReader = TestReaderUtils.CreateMessageReader(this.TestMessage, result.Model, testConfiguration); // Detect the payload kinds again and make sure we can also read the subsequent payload kinds // immediately after detection. actualDetectionResults = messageReader.DetectPayloadKind(); this.VerifyPayloadKindDetectionResult(actualDetectionResults); } TestExceptionUtils.ExpectedException( this.settings.Assert, () => { using (messageReader) { this.settings.MessageToObjectModelReader.ReadMessage( messageReader, result.PayloadKind, result.Model, new PayloadReaderTestDescriptor.ReaderMetadata(result.ExpectedType), /*expectedBatchPayload*/ null, testConfiguration); } }, result.ExpectedException, this.settings.ExceptionVerifier); } } }
/// <summary> /// Constructor. /// </summary> /// <param name="messageReader">The message reader to wrap.</param> /// <param name="testConfiguration">The test configuration to use.</param> /// <param name="message">The message to read from.</param> /// <remarks> /// This constructor is used if special checks against <paramref name="message"/> should be performed. /// Use the constructor overload that does not take a <see cref="TestMessage"/> argument to prevent any checks /// around disposal of the message. /// </remarks> public ODataMessageReaderTestWrapper(ODataMessageReader messageReader, ODataMessageReaderSettings messageReaderSettings, ReaderTestConfiguration testConfiguration, TestMessage message) { ExceptionUtilities.CheckArgumentNotNull(messageReader, "messageReader"); ExceptionUtilities.CheckArgumentNotNull(testConfiguration, "testConfiguration"); ExceptionUtilities.CheckArgumentNotNull(message, "message"); this.messageReader = messageReader; this.messageReaderSettings = messageReaderSettings; this.testConfiguration = testConfiguration; this.message = message; ExceptionUtilities.Assert(this.message.TestStream == null || this.message.TestStream.DisposeCount == 0, "If the underlying message stream is a TestStream, its dispose count must be 0."); ExceptionUtilities.Assert(!this.message.StreamRetrieved, "GetMessage and GetMessageAsync must not be called previously on the given message."); }
/// <summary> /// Called before the test is actually executed for the specified test configuration to determine if the test should be skipped. /// </summary> /// <param name="testConfiguration">The test configuration to use.</param> /// <returns>true if the test should be skipped for the <paramref name="testConfiguration"/> or false to run the test.</returns> /// <remarks>Derived classes should always call the base class and return true if the base class returned true.</remarks> protected override bool ShouldSkipForTestConfiguration(ReaderTestConfiguration testConfiguration) { if (this.PayloadDescriptor.SkipTestConfiguration != null && this.PayloadDescriptor.SkipTestConfiguration(testConfiguration)) { return(true); } else if (this.SkipTestConfiguration != null) { return(this.SkipTestConfiguration(testConfiguration)); } else { return(false); } }
public void EncodingPropertyTest() { // NOTE: the XmlReader (when created via XmlReader.Create) will use the Xml declaration and/or scan // ahead to detect the encoding from the payload. Only if both fail, do we have the opportunity // to make a difference by specifying the encoding in the content type. // // Create an non-standard character in the iso-8859-9 (Turkish) encoding Encoding iso88599Encoding = Encoding.GetEncoding("iso-8859-9"); char[] chars = iso88599Encoding.GetChars(new byte[] { 250 }); string payloadValue = new string(chars); var testCases = new[] { new { ContentType = "application/xml", ResultString = payloadValue, ExpectedException = new ExpectedException(typeof(XmlException)), }, new { ContentType = "application/xml;charset=iso-8859-9", ResultString = payloadValue, ExpectedException = (ExpectedException)null, }, }; var testDescriptors = testCases.Select(testCase => new ReaderEncodingTestDescriptor(this.Settings, testCase.ContentType) { PayloadElement = PayloadBuilder.PrimitiveProperty(null, payloadValue) .SerializationEncoding("iso-8859-9", /*omitDeclaration*/ true), ExpectedResultPayloadElement = tc => PayloadBuilder.PrimitiveProperty(null, testCase.ResultString), ExpectedException = testCase.ExpectedException, } ); this.CombinatorialEngineProvider.RunCombinations( testDescriptors, this.ReaderTestConfigurationProvider.AtomFormatConfigurations, (testDescriptor, testConfiguration) => { testConfiguration = new ReaderTestConfiguration(testConfiguration); testConfiguration.MessageReaderSettings.DisableMessageStreamDisposal = true; testDescriptor.RunTest(testConfiguration); }); }
/// <summary> /// Called to get the expected result of the test. /// </summary> /// <param name="testConfiguration">The test configuration to use.</param> /// <returns>The expected result.</returns> protected override ReaderTestExpectedResult GetExpectedResult(ReaderTestConfiguration testConfiguration) { ReaderTestExpectedResult expectedResult = base.GetExpectedResult(testConfiguration); if (expectedResult == null) { return(new MetadataReaderTestExpectedResult(this.settings.ExpectedResultSettings) { ExpectedException = this.ExpectedException, }); } else { return(expectedResult); } }
/// <summary> /// Gets The model to use for the specified test configuration. /// </summary> /// <param name="testConfiguration">The test configuration to use.</param> /// <returns>The model to use for the test.</returns> protected virtual IEdmModel GetMetadataProvider(ReaderTestConfiguration testConfiguration) { if (this.cachedModel == null && this.Model != null) { if (this.Annotations != null) { this.cachedModel = EdmModelBuilder.BuildAnnotationModel(this.Annotations, this.Model); } else { this.cachedModel = this.Model; } } return(this.cachedModel); }
/// <summary> /// Called to create the input message for the reader test. /// </summary> /// <param name="testConfiguration">The test configuration.</param> /// <returns>The newly created test message to use.</returns> protected override TestMessage CreateInputMessage(ReaderTestConfiguration testConfiguration) { MemoryStream memoryStream = new MemoryStream(); this.WriteInputMessageContent(testConfiguration, new TestStream(memoryStream, ignoreDispose: true)); memoryStream.Seek(0, SeekOrigin.Begin); TestStream messageStream = new TestStream(memoryStream); TestMessage testMessage = TestReaderUtils.CreateInputMessageFromStream( messageStream, testConfiguration, this.PayloadKind, /*customContentTypeHeader*/ null, /*urlResolver*/ null); return(testMessage); }
/// <summary> /// If overriden dumps additional description of the test descriptor for the specified testConfiguration. /// This is used only for debugging purposes. /// </summary> /// <param name="testConfiguration">The test configuration to use.</param> /// <returns>String description of the test.</returns> protected override string DumpAdditionalTestDescriptions(ReaderTestConfiguration testConfiguration) { StringBuilder result = new StringBuilder(base.DumpAdditionalTestDescriptions(testConfiguration)); if (this.PayloadEdmModel != null) { result.AppendLine(); result.AppendLine("PayloadModel CSDL:"); List <StringBuilder> stringBuilders = new List <StringBuilder>(); List <XmlWriter> xmlWriters = new List <XmlWriter>(); IEnumerable <EdmError> errors; this.PayloadEdmModel.SetEdmVersion(Microsoft.OData.Edm.Library.EdmConstants.EdmVersionLatest); this.PayloadEdmModel.TryWriteCsdl( s => { stringBuilders.Add(new StringBuilder()); xmlWriters.Add(XmlWriter.Create(stringBuilders.Last())); return(xmlWriters.Last()); }, out errors); for (int i = 0; i < stringBuilders.Count; i++) { xmlWriters[i].Close(); } foreach (var sb in stringBuilders) { result.AppendLine(sb.ToString()); } if (this.Annotations != null) { result.AppendLine(); result.AppendLine("Annotations:"); string annotationSchema = "<Schema Namespace='TestModelStandardAnnotations' xmlns='http://docs.oasis-open.org/odata/ns/edm'>" + this.Annotations + "</Schema>"; result.AppendLine(XElement.Parse(annotationSchema).ToString()); } } return(result.ToString()); }
/// <summary> /// Gets The model to use for the specified test configuration. /// </summary> /// <param name="testConfiguration">The test configuration to use.</param> /// <returns>The model to use for the test.</returns> protected override IEdmModel GetMetadataProvider(ReaderTestConfiguration testConfiguration) { IEdmModel model = base.GetMetadataProvider(testConfiguration); if (model != null) { return(model); } // NOTE: get the model from the first result (if any) as the model for the message writer. // This message writer will be used to validate the first result only. PayloadKindDetectionResult firstResult = this.ExpectedDetectionResults == null ? null : this.ExpectedDetectionResults(testConfiguration).FirstOrDefault(); return(firstResult == null ? null : firstResult.Model); }
/// <summary> /// Verifies that the result of the test (the message reader) is what the test expected. /// </summary> /// <param name="messageReader">The message reader which is the result of the test. This method should use it to read the results /// of the parsing and verify those.</param> /// <param name="payloadKind">The payload kind specified in the test descriptor.</param> /// <param name="testConfiguration">The test configuration to use.</param> public override void VerifyResult( ODataMessageReaderTestWrapper messageReader, ODataPayloadKind payloadKind, ReaderTestConfiguration testConfiguration) { object odataObject = this.settings.MessageToObjectModelReader.ReadMessage( messageReader, payloadKind, /*payloadModel*/ null, this.ReaderMetadata, /*expectedBatchPayload*/ null, testConfiguration); if (this.ODataObjectModelValidator != null) { this.ODataObjectModelValidator.ValidateODataObjectModel(odataObject); } // only compare the payloads if the expected payload is not 'null'; null indicates to skip the comparison if (this.ExpectedPayloadElement != null) { ODataPayloadElement actualPayloadElement = this.settings.ObjectModelToPayloadElementConverter.Convert(odataObject, !testConfiguration.IsRequest); if (this.IgnorePropertyOrder) { if (testConfiguration.Format == ODataFormat.Json && !testConfiguration.IsRequest) { this.settings.JsonLightResponseIgnorePropertyOrderODataPayloadElementComparer.Compare(this.ExpectedPayloadElement, actualPayloadElement); } else { this.settings.IgnorePropertyOrderODataPayloadElementComparer.Compare(this.ExpectedPayloadElement, actualPayloadElement); } } else { if (testConfiguration.Format == ODataFormat.Json && !testConfiguration.IsRequest) { this.settings.ODataJsonLightResponsePayloadElementComparer.Compare(this.ExpectedPayloadElement, actualPayloadElement); } else { this.settings.ODataPayloadElementComparer.Compare(this.ExpectedPayloadElement, actualPayloadElement); } } } }
/// <summary> /// Helper method to create a test message from its content. /// </summary> /// <param name="messageContent">Stream with the content of the message.</param> /// <param name="testConfiguration">The test configuration.</param> /// <param name="payloadKind">The payload kind to use to compute and set the content type header; or null if no content type header should be set.</param> /// <param name="customContentTypeHeader">A custom content type header to be used in the message.</param> /// <param name="urlResolver">Url resolver to add to the test message created.</param> /// <returns>Newly created test message.</returns> public static TestMessage CreateInputMessageFromStream( TestStream messageContent, ReaderTestConfiguration testConfiguration, ODataPayloadKind?payloadKind, string customContentTypeHeader, IODataUrlResolver urlResolver) { TestMessage message; if (testConfiguration.IsRequest) { if (urlResolver != null) { message = new TestRequestMessageWithUrlResolver(messageContent, urlResolver, testConfiguration.Synchronous ? TestMessageFlags.NoAsynchronous : TestMessageFlags.NoSynchronous); } else { message = new TestRequestMessage(messageContent, testConfiguration.Synchronous ? TestMessageFlags.NoAsynchronous : TestMessageFlags.NoSynchronous); } } else { if (urlResolver != null) { message = new TestResponseMessageWithUrlResolver(messageContent, urlResolver, testConfiguration.Synchronous ? TestMessageFlags.NoAsynchronous : TestMessageFlags.NoSynchronous); } else { message = new TestResponseMessage(messageContent, testConfiguration.Synchronous ? TestMessageFlags.NoAsynchronous : TestMessageFlags.NoSynchronous); } } // set the OData-Version header message.SetHeader(ODataConstants.ODataVersionHeader, testConfiguration.Version.ToText()); if (customContentTypeHeader != null) { message.SetHeader(ODataConstants.ContentTypeHeader, customContentTypeHeader); } else if (payloadKind.HasValue) { message.SetContentType(testConfiguration.Format, payloadKind.Value); } return(message); }
/// <summary> /// Verifies that the result of the test (the message reader) is what the test expected. /// </summary> /// <param name="messageReader">The message reader which is the result of the test. This method should use it to read the results /// of the parsing and verify those.</param> /// <param name="payloadKind">The payload kind specified in the test descriptor.</param> /// <param name="testConfiguration">The test configuration to use.</param> public override void VerifyResult( ODataMessageReaderTestWrapper messageReader, ODataPayloadKind payloadKind, ReaderTestConfiguration testConfiguration) { this.settings.Assert.IsTrue(payloadKind == ODataPayloadKind.MetadataDocument, "Only metadata payload kind is supported."); object metadata = this.settings.MessageToObjectModelReader.ReadMessage( messageReader, payloadKind, /*payloadModel*/ null, PayloadReaderTestDescriptor.ReaderMetadata.None, /*expectedBatchPayload*/ null, testConfiguration); IEdmModel actualModel = metadata as IEdmModel; this.settings.Assert.IsTrue(metadata != null && actualModel != null, "Expected a non-null model to be read."); }
public void TopLevelDeeplyRecursiveErrorTest() { int depthLimit = 5; IEnumerable<PayloadReaderTestDescriptor> testDescriptors = PayloadReaderTestDescriptorGenerator.CreateErrorDeeplyNestedReaderTestDescriptors(this.Settings, depthLimit); this.CombinatorialEngineProvider.RunCombinations( testDescriptors, this.ReaderTestConfigurationProvider.ExplicitFormatConfigurations.Where(tc => !tc.IsRequest), (testDescriptor, testConfiguration) => { // Copy the test configuration so we can modify the depth limit. testConfiguration = new ReaderTestConfiguration(testConfiguration); testConfiguration.MessageReaderSettings.MessageQuotas.MaxNestingDepth = depthLimit; testDescriptor.RunTest(testConfiguration); }); }
// TODO: add encoding tests /// <summary> /// Ignore some test configurations based on the content type since we need to serialize the payloads /// with a supported format for that content type. /// </summary> /// <param name="contentType"></param> /// <param name="testConfiguration"></param> /// <returns></returns> private static bool IgnoreTestConfiguration(string contentType, ReaderTestConfiguration testConfiguration) { if (testConfiguration.Format != ODataFormat.Json) { string formatName = testConfiguration.Format == null ? "null" : testConfiguration.Format.GetType().Name; throw new NotSupportedException("Unsupported format " + formatName + " for method IgnoreTestConfiguration."); } return false; }
public void ContentTypeHeaderParsingTest() { IEnumerable<ContentTypeTestCase> testCases = new ContentTypeTestCase[] { #region Atom test cases new ContentTypeTestCase { // only reading an entry or feed should succeed ContentType = "application/atom+xml;type=feed", ExpectedFormat = ODataFormat.Atom, }, new ContentTypeTestCase { // only reading an entry or feed should succeed ContentType = "application/atom+xml;type=entry", ExpectedFormat = ODataFormat.Atom, }, new ContentTypeTestCase { // reading a feed, an entry, and metadata should succeed ContentType = "application/atom+xml", ExpectedFormat = ODataFormat.Atom, }, new ContentTypeTestCase { // reading a property, an entity reference link, entity reference links, a collection, a service document, and an error should succeed ContentType = "application/xml", ExpectedFormat = ODataFormat.Atom, }, new ContentTypeTestCase { // reading a property, an entity reference link, entity reference links, and a collection should succeed ContentType = "text/xml", ExpectedFormat = ODataFormat.Atom, }, new ContentTypeTestCase { // reading a service document should succeed ContentType = "application/atomsvc+xml", ExpectedFormat = ODataFormat.Atom, }, #endregion Atom test cases #region RawValue test cases new ContentTypeTestCase { // only reading a raw value will succeed ContentType = "text/plain", ExpectedFormat = ODataFormat.RawValue, ShouldSucceedForPayloadKind = pk => pk == ODataPayloadKind.Value || pk == ODataPayloadKind.BinaryValue, }, new ContentTypeTestCase { // only reading a raw value or binary value will succeed; raw values can be read as binary values when the content type is application/octet-stream ContentType = "application/octet-stream", ExpectedFormat = ODataFormat.RawValue, ShouldSucceedForPayloadKind = pk => pk == ODataPayloadKind.Value || pk == ODataPayloadKind.BinaryValue, }, new ContentTypeTestCase { // only raw value / binary value will succeed ContentType = "multipart/mixed", ExpectedFormat = ODataFormat.RawValue, ShouldSucceedForPayloadKind = pk => false, }, new ContentTypeTestCase { // Test for: MimeType allows 0x7F character, but ContentType parsing doesn't ContentType = "application/"+0x7F, ExpectedFormat = ODataFormat.RawValue, ShouldSucceedForPayloadKind = pk => false, }, #endregion RawValue test cases #region JSON Lite test cases new ContentTypeTestCase { // only batch and raw value will fail (batch payload kind tested separately in BatchContentTypeHeaderParsingTest) ContentType = ApplicationJsonODataLight, ExpectedFormat = ODataFormat.Json, ShouldSucceedForPayloadKind = pk => pk != ODataPayloadKind.Value && pk != ODataPayloadKind.BinaryValue, }, new ContentTypeTestCase { // only batch and raw value will fail (batch payload kind tested separately in BatchContentTypeHeaderParsingTest) ContentType = ApplicationJsonODataLightStreaming, ExpectedFormat = ODataFormat.Json, ShouldSucceedForPayloadKind = pk => pk != ODataPayloadKind.Value && pk != ODataPayloadKind.BinaryValue, }, new ContentTypeTestCase { // only batch and raw value will fail (batch payload kind tested separately in BatchContentTypeHeaderParsingTest) ContentType = ApplicationJsonODataLightNonStreaming, ExpectedFormat = ODataFormat.Json, ShouldSucceedForPayloadKind = pk => pk != ODataPayloadKind.Value && pk != ODataPayloadKind.BinaryValue, }, #endregion JSON Lite test cases #region Error test cases new ContentTypeTestCase { // unsupported content type; everything will fail ContentType = "application/foo", ShouldSucceedForPayloadKind = pk => false, }, new ContentTypeTestCase { // unsupported content type with parameters; everything will fail ContentType = "abc/pqr;a=b;c=d", ShouldSucceedForPayloadKind = pk => false, }, new ContentTypeTestCase { // "image/jpeg" is not supported, even for raw values. ContentType = "image/jpeg", ShouldSucceedForPayloadKind = pk => false, }, #endregion Error test cases #region Content Type is null or empty new ContentTypeTestCase { // null content type and zero content length should be default to Json if the payload kind is not binary value or value. ContentType = null, ContentLength = 0, ExpectedFormat = ODataFormat.Json, ShouldSucceedForPayloadKind = pk => true, ShouldIgnoreTest = pk => pk == ODataPayloadKind.BinaryValue || pk == ODataPayloadKind.Value }, new ContentTypeTestCase { // null content type and zero content length should be default to RawValue if the payload kind is binary value or value. ContentType = null, ContentLength = 0, ExpectedFormat = ODataFormat.RawValue, ShouldSucceedForPayloadKind = pk => true, ShouldIgnoreTest = pk => pk != ODataPayloadKind.Value }, #endregion }; string[] parameters = new string[] { "foo=bar", "foo1=bar1;foo2=bar2" }; testCases = testCases.Concat(testCases.Where(tc => tc.ContentType != null).SelectMany(tc => parameters.Select(p => new ContentTypeTestCase(tc) { ContentType = tc.ContentType + ";" + p }))); int oDataPayloadKindCount = EnumExtensionMethods.GetValues<ODataPayloadKind>().Length; this.Assert.AreEqual(oDataPayloadKindCount, TestReaderUtils.ODataPayloadKinds.Length, "The number of payload kind have changed, please update this test."); IEdmModel model = Microsoft.Test.OData.Utils.Metadata.TestModels.BuildTestModel(); // We don't support batch payloads here; we test those separately in BatchContentTypeHeaderParsingTest IEnumerable<ODataPayloadKind> payloadKinds = TestReaderUtils.ODataPayloadKinds.Where(k => k != ODataPayloadKind.Batch && k != ODataPayloadKind.Unsupported); this.CombinatorialEngineProvider.RunCombinations( testCases, payloadKinds, this.ReaderTestConfigurationProvider.AllFormatConfigurations, (testCase, payloadKind, testConfiguration) => { testConfiguration = new ReaderTestConfiguration(testConfiguration); testConfiguration.MessageReaderSettings.EnableAtom = false; if (IgnoreTestCase(payloadKind, testConfiguration)) { return; } if (testCase.ShouldIgnoreTest != null && testCase.ShouldIgnoreTest(payloadKind)) { return; } string supportedMediaTypes; if (payloadKind == ODataPayloadKind.Value || payloadKind == ODataPayloadKind.BinaryValue) { supportedMediaTypes = TestMediaTypeUtils.GetSupportedMediaTypes(ODataPayloadKind.Value) + ", " + TestMediaTypeUtils.GetSupportedMediaTypes(ODataPayloadKind.BinaryValue); } else { supportedMediaTypes = TestMediaTypeUtils.GetSupportedMediaTypes(payloadKind, /*includeAppJson*/true); } ExpectedException expectedException = testCase.ExpectedException == null ? testCase.ShouldSucceedForPayloadKind!=null && testCase.ShouldSucceedForPayloadKind(payloadKind) ? null : ODataExpectedExceptions.ODataContentTypeException("MediaTypeUtils_CannotDetermineFormatFromContentType", supportedMediaTypes, testCase.ContentType ?? "") : testCase.ExpectedException; // Make sure to run success test cases only in configurations that will work. if (expectedException == null && testConfiguration.Format != null && testCase.ExpectedFormat != testConfiguration.Format) { return; } ODataPayloadElement payloadElement = CreatePayloadElement(model, payloadKind, testConfiguration); // When we write a value with a content type different than 'text/plain', we will read it as binary. // Likewise, when we write a binary value with a 'text/plain' content type, we will read it as a string. Func<ReaderTestConfiguration, ODataPayloadElement> expectedResultElementFunc = null; if (payloadKind == ODataPayloadKind.Value && testCase.ContentType != null && !testCase.ContentType.StartsWith("text/plain")) { expectedResultElementFunc = (testConfig) => ConvertToBinaryPayloadElement(payloadElement); } else if (payloadKind == ODataPayloadKind.BinaryValue && testCase.ContentType != null && testCase.ContentType.StartsWith("text/plain")) { expectedResultElementFunc = (testConfig) => ConvertToStringPayloadElement(payloadElement); } ODataFormat expectedFormat = testCase.ExpectedFormat; ReaderContentTypeTestDescriptor testDescriptor = new ReaderContentTypeTestDescriptor(this.Settings) { PayloadElement = payloadElement, ExpectedResultPayloadElement = expectedResultElementFunc, PayloadEdmModel = model, ExpectedFormat = expectedFormat, ContentType = testCase.ContentType, ExpectedException = expectedException }; testDescriptor.RunTest(testConfiguration); testConfiguration.MessageReaderSettings.EnableAtom = true; }); }
private void RunMetadataMessageSizeLimitTests(IEdmModel model, MessageSizeLimitTestCase[] testCases) { this.CombinatorialEngineProvider.RunCombinations( testCases, this.ReaderTestConfigurationProvider.DefaultFormatConfigurations.Where(tc => !tc.IsRequest && tc.Synchronous), (testCase, testConfiguration) => { int size = -1; if (testConfiguration.Format == ODataFormat.Atom && testCase.AtomSizes != null) { size = testConfiguration.IsRequest ? testCase.AtomSizes.RequestSize : testCase.AtomSizes.ResponseSize; } else if (testConfiguration.Format == ODataFormat.Json && testCase.JsonLightSizes != null) { size = testConfiguration.IsRequest ? testCase.JsonLightSizes.RequestSize : testCase.JsonLightSizes.ResponseSize; } else if (testCase.RawSizes != null) { size = testConfiguration.IsRequest ? testCase.RawSizes.RequestSize : testCase.RawSizes.ResponseSize; } ExpectedException expectedException = size < 0 ? null : ODataExpectedExceptions.ODataException("MessageStreamWrappingStream_ByteLimitExceeded", size.ToString(), testCase.MaxMessageSize.ToString()); var testDescriptor = new MetadataReaderTestDescriptor(this.MetadataSettings) { PayloadEdmModel = model, ExpectedException = expectedException, }; if (testCase.MaxMessageSize > 0) { testConfiguration = new ReaderTestConfiguration(testConfiguration); testConfiguration.MessageReaderSettings.MessageQuotas.MaxReceivedMessageSize = testCase.MaxMessageSize; } testDescriptor.RunTest(testConfiguration); }); }
private void RunMessageSizeLimitTests( IEnumerable<ReaderTestConfiguration> testConfigurations, EdmModel model, ODataPayloadElement payload, MessageSizeLimitTestCase[] testCases, Func<ReaderTestConfiguration, bool> skipTestConfigurationFunc = null) { var transformScope = this.Settings.PayloadTransformFactory.EmptyScope(); using (transformScope.Apply()) { this.CombinatorialEngineProvider.RunCombinations( testCases, testConfigurations, (testCase, testConfiguration) => { int size = -1; if (testConfiguration.Format == ODataFormat.Atom && testCase.AtomSizes != null) { size = testConfiguration.IsRequest ? testCase.AtomSizes.RequestSize : testCase.AtomSizes.ResponseSize; } else if (testConfiguration.Format == ODataFormat.Json && testCase.JsonLightSizes != null) { size = testConfiguration.IsRequest ? testCase.JsonLightSizes.RequestSize : testCase.JsonLightSizes.ResponseSize; } else if (testCase.RawSizes != null) { size = testConfiguration.IsRequest ? testCase.RawSizes.RequestSize : testCase.RawSizes.ResponseSize; } int maxSize = testCase.MaxMessageSize >= 0 ? testCase.MaxMessageSize : 1024 * 1024; ExpectedException expectedException = size < 0 ? null : ODataExpectedExceptions.ODataException("MessageStreamWrappingStream_ByteLimitExceeded", size.ToString(), maxSize.ToString()); var testDescriptor = new PayloadReaderTestDescriptor(this.Settings) { PayloadEdmModel = model, PayloadElement = payload.DeepCopy(), ExpectedException = expectedException, SkipTestConfiguration = skipTestConfigurationFunc, ApplyPayloadTransformations = false, }; testDescriptor.ExpectedResultNormalizers.Add( tc => (Func<ODataPayloadElement, ODataPayloadElement>)null); if (testCase.MaxMessageSize > 0) { testConfiguration = new ReaderTestConfiguration(testConfiguration); testConfiguration.MessageReaderSettings.MessageQuotas.MaxReceivedMessageSize = testCase.MaxMessageSize; } testDescriptor.RunTest(testConfiguration); }); } }
private static ODataFormat ComputeExpectedFormat(ReaderTestConfiguration testConfiguration, string contentType) { switch (contentType) { case ApplicationJson: case ApplicationJsonODataLight: return ODataFormat.Json; default: return null; } }
/// <summary> /// Applies expected result normalizers to the specified payload element. /// </summary> /// <param name="expectedResultPayloadElement">The payload element to apply the normalizers to.</param> /// <param name="testConfiguration">The test configuration to use.</param> /// <returns>The expected result after normalization.</returns> private ODataPayloadElement ApplyExpectedResultNormalizers(ODataPayloadElement expectedResultPayloadElement, ReaderTestConfiguration testConfiguration) { // If we have some normalizers and some of them do apply to this test configuration // make a copy and apply the normalizer. if (this.ExpectedResultNormalizers != null) { ODataPayloadElement expectedResultPayloadElementCopy = null; foreach (var getNormalizerFunc in this.ExpectedResultNormalizers) { var normalizer = getNormalizerFunc(testConfiguration); if (normalizer != null) { if (expectedResultPayloadElementCopy == null) { expectedResultPayloadElementCopy = expectedResultPayloadElement.DeepCopy(); } expectedResultPayloadElementCopy = normalizer(expectedResultPayloadElementCopy); } } expectedResultPayloadElement = expectedResultPayloadElementCopy ?? expectedResultPayloadElement; } return expectedResultPayloadElement; }
/// <summary> /// Constructor. /// </summary> /// <param name="other">The <see cref="ReaderTestConfiguration"/> instance used to initialize the new instance.</param> /// <param name="behaviorKind">The behavior to use when running this test.</param> private ReaderTestConfiguration(ReaderTestConfiguration other, TestODataBehaviorKind behaviorKind) : base(other.Format, other.Version, other.IsRequest, behaviorKind) { this.MessageReaderSettings = new ODataMessageReaderSettings(other.MessageReaderSettings); this.Synchronous = other.Synchronous; }
/// <summary> /// Constructor. /// </summary> /// <param name="other">The <see cref="ReaderTestConfiguration"/> instance used to initialize the new instance.</param> public ReaderTestConfiguration(ReaderTestConfiguration other) :this(other, other.RunBehaviorKind) { }
/// <summary> /// Called to get the expected result of the test. /// </summary> /// <param name="testConfiguration">The test configuration to use.</param> /// <returns>The expected result.</returns> protected override ReaderTestExpectedResult GetExpectedResult(ReaderTestConfiguration testConfiguration) { ReaderTestExpectedResult expectedResult = base.GetExpectedResult(testConfiguration); if (expectedResult == null) { IEdmModel model = this.GetMetadataProvider(testConfiguration); ReaderMetadata readerMetadata = new ReaderMetadata(model, this.PayloadElement); // First use the input payload as the expected result. ODataPayloadElement expectedResultPayloadElement = this.PayloadElement; // If we have an override specifically for expected result, use that instead. if (this.ExpectedResultPayloadElement != null) { expectedResultPayloadElement = this.ExpectedResultPayloadElement(testConfiguration); } if (expectedResultPayloadElement.ElementType == ODataPayloadElementType.BatchRequestPayload || expectedResultPayloadElement.ElementType == ODataPayloadElementType.BatchResponsePayload) { if (this.ExpectedResultNormalizers.Count > 0) { expectedResultPayloadElement = new BatchPayloadExpectedResultNormalizer( testConfiguration, this.ApplyExpectedResultNormalizers).Normalize(expectedResultPayloadElement); } IEdmModel payloadModel = this.GetMetadataProvider(testConfiguration); return new BatchReaderTestExpectedResult(this.settings.BatchExpectedResultSettings) { ExpectedBatchPayload = expectedResultPayloadElement, PayloadModel = payloadModel, ExpectedException = this.ExpectedException, }; } else { expectedResultPayloadElement = this.ApplyExpectedResultNormalizers(expectedResultPayloadElement, testConfiguration); } return new PayloadReaderTestExpectedResult(this.settings.ExpectedResultSettings) { ExpectedPayloadElement = expectedResultPayloadElement, ExpectedException = this.ExpectedException, ReaderMetadata = readerMetadata, IgnorePropertyOrder = this.IgnorePropertyOrder, }; } else { PayloadReaderTestExpectedResult payloadReaderTestExpectedResult = expectedResult as PayloadReaderTestExpectedResult; if (payloadReaderTestExpectedResult != null && payloadReaderTestExpectedResult.ReaderMetadata == null) { IEdmModel model = this.GetMetadataProvider(testConfiguration); payloadReaderTestExpectedResult.ReaderMetadata = new ReaderMetadata(model, this.PayloadElement); } return expectedResult; } }
/// <summary> /// Applies the specified max protocol version to copy of the settings. /// </summary> /// <param name="maxProtocolVersion">The max protocol version to apply.</param> /// <returns>A copy of this configuration with the max protocol version applied.</returns> public ReaderTestConfiguration CloneAndApplyMaxProtocolVersion(ODataVersion maxProtocolVersion) { ReaderTestConfiguration testConfiguration = new ReaderTestConfiguration(this); testConfiguration.MessageReaderSettings.MaxProtocolVersion = maxProtocolVersion; return testConfiguration; }
/// <summary> /// Gets The model to use for the specified test configuration. /// </summary> /// <param name="testConfiguration">The test configuration to use.</param> /// <returns>The model to use for the test.</returns> protected override IEdmModel GetMetadataProvider(ReaderTestConfiguration testConfiguration) { IEdmModel model = base.GetMetadataProvider(testConfiguration); if (model == null) { // Try to set the cached model if it is null. If the PayloadEdmModel is null cached model will stay null. if (this.cachedModel == null) { this.cachedModel = this.PayloadEdmModel; } if (this.cachedModel != null) { if (this.Annotations != null) { this.cachedModel = EdmModelBuilder.BuildAnnotationModel(this.Annotations, this.cachedModel); } } model = this.cachedModel; } return model; }
/// <summary> /// If overridden dumps the content of an input message which would be created for the specified test configuration /// into a string and returns it. This is used only for debugging purposes. /// </summary> /// <param name="testConfiguration">The test configuration to use.</param> /// <returns>The string content of the input message.</returns> protected override string DumpInputMessageContent(ReaderTestConfiguration testConfiguration) { byte[] payload = TestReaderUtils.GetPayload(testConfiguration, this.PayloadNormalizers, this.settings, this.PayloadElement); return Encoding.UTF8.GetString(payload, 0, payload.Length); }
/// <summary> /// If overriden dumps additional description of the test descriptor for the specified testConfiguration. /// This is used only for debugging purposes. /// </summary> /// <param name="testConfiguration">The test configuration to use.</param> /// <returns>String description of the test.</returns> protected override string DumpAdditionalTestDescriptions(ReaderTestConfiguration testConfiguration) { StringBuilder result = new StringBuilder(base.DumpAdditionalTestDescriptions(testConfiguration)); if (this.PayloadEdmModel != null) { result.AppendLine(); result.AppendLine("PayloadModel CSDL:"); List<StringBuilder> stringBuilders = new List<StringBuilder>(); List<XmlWriter> xmlWriters = new List<XmlWriter>(); IEnumerable<EdmError> errors; this.PayloadEdmModel.SetEdmVersion(Microsoft.OData.Edm.Library.EdmConstants.EdmVersionLatest); this.PayloadEdmModel.TryWriteCsdl( s => { stringBuilders.Add(new StringBuilder()); xmlWriters.Add(XmlWriter.Create(stringBuilders.Last())); return xmlWriters.Last(); }, out errors); for (int i = 0; i < stringBuilders.Count; i++) { xmlWriters[i].Close(); } foreach (var sb in stringBuilders) { result.AppendLine(sb.ToString()); } if (this.Annotations != null) { result.AppendLine(); result.AppendLine("Annotations:"); string annotationSchema = "<Schema Namespace='TestModelStandardAnnotations' xmlns='http://docs.oasis-open.org/odata/ns/edm'>" + this.Annotations + "</Schema>"; result.AppendLine(XElement.Parse(annotationSchema).ToString()); } } return result.ToString(); }
private static bool IgnoreTestCase(ODataPayloadKind payloadKind, ReaderTestConfiguration testConfiguration) { // TODO: enable unsupported payload kinds when implemented if (payloadKind == ODataPayloadKind.MetadataDocument) { return true; } // ignore some payloads in requests since they are not allowed if (testConfiguration.IsRequest) { if (payloadKind == ODataPayloadKind.ServiceDocument || payloadKind == ODataPayloadKind.Error || payloadKind == ODataPayloadKind.EntityReferenceLinks) { // not allowed in requests return true; } } else { if (payloadKind == ODataPayloadKind.Parameter) { // not allowed in responses return true; } } ODataFormat format = testConfiguration.Format; // ignore some payloads in some formats switch (payloadKind) { case ODataPayloadKind.Feed: return format == null; case ODataPayloadKind.Entry: return format == null; case ODataPayloadKind.Property: return format == null; case ODataPayloadKind.EntityReferenceLink: return format == null; case ODataPayloadKind.EntityReferenceLinks: return format == null; case ODataPayloadKind.Value: return format != null; case ODataPayloadKind.BinaryValue: return format != null; case ODataPayloadKind.Collection: return format == null; case ODataPayloadKind.ServiceDocument: return format == null; case ODataPayloadKind.MetadataDocument: return format != null; case ODataPayloadKind.Error: return format == null; case ODataPayloadKind.Batch: return format != null; case ODataPayloadKind.Parameter: return format != ODataFormat.Json; case ODataPayloadKind.Unsupported: // fall through default: return true; } }
/// <summary> /// Applies the specified behavior with default settings. /// </summary> /// <param name="behaviorKind">The behavior kind to apply.</param> /// <returns>A copy of this configuration with the new behavior applied.</returns> public ReaderTestConfiguration CloneAndApplyBehavior(TestODataBehaviorKind behaviorKind) { ReaderTestConfiguration testConfiguration = new ReaderTestConfiguration(this, behaviorKind); switch (behaviorKind) { case TestODataBehaviorKind.Default: break; case TestODataBehaviorKind.WcfDataServicesClient: testConfiguration.MessageReaderSettings.EnableWcfDataServicesClientBehavior(null); break; case TestODataBehaviorKind.WcfDataServicesServer: testConfiguration.MessageReaderSettings.EnableODataServerBehavior(); break; } return testConfiguration; }
private static ODataPayloadElement CreatePayloadElement(IEdmModel model, ODataPayloadKind payloadKind, ReaderTestConfiguration testConfig) { IEdmEntitySet citySet = model.EntityContainer.FindEntitySet("Cities"); IEdmEntityType cityType = model.EntityTypes().Single(e => e.Name == "CityType"); IEdmProperty cityNameProperty = cityType.Properties().Single(e => e.Name == "Name"); IEdmNavigationProperty policeStationNavProp = cityType.NavigationProperties().Single(e => e.Name == "PoliceStation"); IEdmOperationImport primitiveCollectionResultOperation = model.EntityContainer.FindOperationImports("PrimitiveCollectionResultOperation").Single(); IEdmOperationImport serviceOp1 = model.EntityContainer.FindOperationImports("ServiceOperation1").Single(); bool isRequest = testConfig.IsRequest; bool isJsonLightRequest = isRequest && testConfig.Format == ODataFormat.Json; switch (payloadKind) { case ODataPayloadKind.Feed: { return PayloadBuilder.EntitySet().WithTypeAnnotation(cityType).ExpectedEntityType(cityType, citySet); } case ODataPayloadKind.Entry: { return PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).WithTypeAnnotation(cityType).ExpectedEntityType(cityType, citySet); } case ODataPayloadKind.Property: return PayloadBuilder.PrimitiveProperty(isJsonLightRequest ? string.Empty : null, "SomeCityValue").ExpectedProperty(cityType, "Name"); case ODataPayloadKind.EntityReferenceLink: return PayloadBuilder.DeferredLink("http://odata.org/entityreferencelink").ExpectedNavigationProperty(citySet, cityType, "PoliceStation"); case ODataPayloadKind.EntityReferenceLinks: return PayloadBuilder.LinkCollection().Item(PayloadBuilder.DeferredLink("http://odata.org/entityreferencelink")).ExpectedNavigationProperty((EdmEntitySet)citySet, (EdmEntityType)cityType, "CityHall"); case ODataPayloadKind.Value: return PayloadBuilder.PrimitiveValue("PrimitiveValue"); case ODataPayloadKind.BinaryValue: return PayloadBuilder.PrimitiveValue(new byte[] { 0, 0, 1, 1 }); case ODataPayloadKind.Collection: return PayloadBuilder.PrimitiveCollection().CollectionName(null).ExpectedFunctionImport((EdmOperationImport)primitiveCollectionResultOperation); case ODataPayloadKind.ServiceDocument: Debug.Assert(!isRequest, "Not supported in requests."); return new ServiceDocumentInstance().Workspace(PayloadBuilder.Workspace()); case ODataPayloadKind.MetadataDocument: Debug.Assert(!isRequest, "Not supported in requests."); throw new NotImplementedException(); case ODataPayloadKind.Error: Debug.Assert(!isRequest, "Not supported in requests."); return PayloadBuilder.Error("ErrorCode"); case ODataPayloadKind.Parameter: // build parameter payload based on model definition var parameterPayload = new ComplexInstance(null, false); ODataPayloadElement a = PayloadBuilder.PrimitiveValue(123).WithTypeAnnotation(EdmCoreModel.Instance.GetInt32(false)); ODataPayloadElement b = PayloadBuilder.PrimitiveValue("stringvalue").WithTypeAnnotation(EdmCoreModel.Instance.GetString(false)); PrimitiveProperty parametera = new PrimitiveProperty("a", "Edm.Integer", ((PrimitiveValue)a).ClrValue); PrimitiveProperty parameterb = new PrimitiveProperty("b", "Edm.String", ((PrimitiveValue)b).ClrValue); parameterPayload.Add(parametera); parameterPayload.Add(parameterb); parameterPayload.ExpectedFunctionImport((EdmOperationImport)serviceOp1); return parameterPayload; case ODataPayloadKind.Unsupported: // fall through default: throw new NotSupportedException(); } }
/// <summary> /// Called to create the input message for the reader test. /// </summary> /// <param name="testConfiguration">The test configuration.</param> /// <returns>The newly created test message to use.</returns> protected override TestMessage CreateInputMessage(ReaderTestConfiguration testConfiguration) { return TestReaderUtils.CreateInputMessage(testConfiguration, this, this.settings, this.ApplyPayloadTransformations); }
/// <summary> /// Called before the test is actually executed for the specified test configuration to determine if the test should be skipped. /// </summary> /// <param name="testConfiguration">The test configuration to use.</param> /// <returns>true if the test should be skipped for the <paramref name="testConfiguration"/> or false to run the test.</returns> /// <remarks>Derived classes should always call the base class and return true if the base class returned true.</remarks> protected override bool ShouldSkipForTestConfiguration(ReaderTestConfiguration testConfiguration) { if (this.PayloadDescriptor.SkipTestConfiguration != null && this.PayloadDescriptor.SkipTestConfiguration(testConfiguration)) { return true; } else if (this.SkipTestConfiguration != null) { return this.SkipTestConfiguration(testConfiguration); } else { return false; } }
/// <summary> /// Constructor. /// </summary> /// <param name="batchTestConfiguration">The test configuration for the entire batch payload.</param> /// <param name="applyExpectedResultNormalizers">The func which applies expected result normalizers to a payload element.</param> public BatchPayloadExpectedResultNormalizer( ReaderTestConfiguration batchTestConfiguration, Func<ODataPayloadElement, ReaderTestConfiguration, ODataPayloadElement> applyExpectedResultNormalizers) { this.batchTestConfiguration = batchTestConfiguration; this.applyExpectedResultNormalizers = applyExpectedResultNormalizers; }