[Ignore] // Remove Atom // [TestMethod, Variation(Description = "Verifies that sync and async calls cannot be mixed on a single writer.")] public void SyncAsyncMismatchTest() { // ToDo: Fix places where we've lost JsonVerbose coverage to add JsonLight this.CombinatorialEngineProvider.RunCombinations( TestCalls, this.WriterTestConfigurationProvider.ExplicitFormatConfigurations.Where(tc => false), new bool[] { false, true }, new bool[] { false, true }, (testCall, testConfiguration, writingFeed, testSynchronousCall) => { testConfiguration = testConfiguration.Clone(); testConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri); using (TestStream memoryStream = new TestStream()) { // We purposely don't use the using pattern around the messageWriter here. Disposing the message writer will // fail here because the writer is not left in a valid state. var messageWriter = TestWriterUtils.CreateMessageWriter(memoryStream, testConfiguration, this.Assert); // Note that the CreateODataWriter call will call either sync or async variant based on the testConfiguration // which is independent axis to the testSynchronousCall and thus we will end up with async creation but sync write // and vice versa. ODataWriter odataWriter = messageWriter.CreateODataWriter(writingFeed); ODataWriterTestWrapper writer = (ODataWriterTestWrapper)odataWriter; if (testCall.AssumesFeedWriter) { if (!writingFeed) { // Skip this case since we need feed writer for this case. return; } } else { if (writingFeed) { writer.WriteStart(ObjectModelUtils.CreateDefaultFeed()); } } this.Assert.ExpectedException <ODataException>( () => { if (testSynchronousCall) { testCall.Sync(writer); } else { testCall.Async(writer); } }, testConfiguration.Synchronous == testSynchronousCall ? null : testSynchronousCall ? "A synchronous operation was called on an asynchronous writer. Calls on a writer instance must be either all synchronous or all asynchronous." : "An asynchronous operation was called on a synchronous writer. Calls on a writer instance must be either all synchronous or all asynchronous."); } }); }
/// <summary> /// Creates an <see cref="ODataCollectionWriter"/> for the specified format and the specified version and /// invokes the specified methods on it. It then parses /// the written Xml/JSON and compares it to the expected result as specified in the descriptor. /// </summary> /// <param name="descriptor">The test descriptor to process.</param> /// <param name="testConfiguration">The configuration of the test.</param> /// <param name="assert">The assertion handler to report errors to.</param> /// <param name="baselineLogger">Logger to log baseline.</param> internal static void WriteAndVerifyCollectionPayload(CollectionWriterTestDescriptor descriptor, WriterTestConfiguration testConfiguration, AssertionHandler assert, BaselineLogger baselineLogger) { baselineLogger.LogConfiguration(testConfiguration); baselineLogger.LogModelPresence(descriptor.Model); // serialize to a memory stream using (var memoryStream = new MemoryStream()) using (var testMemoryStream = new TestStream(memoryStream, ignoreDispose: true)) { TestMessage testMessage = null; Exception exception = TestExceptionUtils.RunCatching(() => { using (var messageWriter = TestWriterUtils.CreateMessageWriter(testMemoryStream, testConfiguration, assert, out testMessage, null, descriptor.Model)) { IEdmTypeReference itemTypeReference = descriptor.ItemTypeParameter; ODataCollectionWriter writer = itemTypeReference == null ? messageWriter.CreateODataCollectionWriter() : messageWriter.CreateODataCollectionWriter(itemTypeReference); WriteCollectionPayload(messageWriter, writer, true, descriptor); } }); exception = TestExceptionUtils.UnwrapAggregateException(exception, assert); WriterTestExpectedResults expectedResults = descriptor.ExpectedResultCallback(testConfiguration); TestWriterUtils.ValidateExceptionOrLogResult(testMessage, testConfiguration, expectedResults, exception, assert, descriptor.TestDescriptorSettings.ExpectedResultSettings.ExceptionVerifier, baselineLogger); TestWriterUtils.ValidateContentType(testMessage, expectedResults, true, assert); } }
public void SyncAsyncMismatchTest() { this.CombinatorialEngineProvider.RunCombinations( TestCalls, this.WriterTestConfigurationProvider.DefaultFormatConfigurations, new bool[] { false, true }, (testCall, testConfiguration, testSynchronousCall) => { using (var memoryStream = new TestStream()) { // We purposely don't use the using pattern around the messageWriter here. Disposing the message writer will // fail here because the writer is not left in a valid state. var messageWriter = TestWriterUtils.CreateMessageWriter(memoryStream, testConfiguration, this.Assert); ODataBatchWriterTestWrapper writer = messageWriter.CreateODataBatchWriter(); this.Assert.ExpectedException <ODataException>( () => { if (testSynchronousCall) { testCall.Sync(writer, testConfiguration); } else { testCall.Async(writer, testConfiguration); } }, testConfiguration.Synchronous == testSynchronousCall || testCall.ShouldNotFail ? null : testSynchronousCall ? "A synchronous operation was called on an asynchronous batch writer. Calls on a batch writer instance must be either all synchronous or all asynchronous." : "An asynchronous operation was called on a synchronous batch writer. Calls on a batch writer instance must be either all synchronous or all asynchronous."); } }); }
public void SyncAsyncMismatchTest() { this.CombinatorialEngineProvider.RunCombinations( TestCalls, this.WriterTestConfigurationProvider.JsonLightFormatConfigurations.Where(tc => tc.IsRequest), new bool[] { false, true }, (testCall, testConfiguration, testSynchronousCall) => { using (var memoryStream = new TestStream()) using (var messageWriter = TestWriterUtils.CreateMessageWriter(memoryStream, testConfiguration, this.Assert)) { ODataParameterWriter parameterWriter = messageWriter.CreateODataParameterWriter(null /*functionImport*/); ODataParameterWriterTestWrapper writer = (ODataParameterWriterTestWrapper)parameterWriter; this.Assert.ExpectedException( () => { if (testSynchronousCall) { testCall.Sync(writer); } else { testCall.Async(writer); } }, testConfiguration.Synchronous == testSynchronousCall ? null : testSynchronousCall ? ODataExpectedExceptions.ODataException("ODataParameterWriterCore_SyncCallOnAsyncWriter") : ODataExpectedExceptions.ODataException("ODataParameterWriterCore_AsyncCallOnSyncWriter"), this.ExceptionVerifier); } }); }
public override void RunTest(ReaderTestConfiguration testConfiguration) { //TODO: Use Logger to verify result, right now this change is only to unblock writer testcase checkin BaselineLogger logger = null; if (this.ShouldSkipForTestConfiguration(testConfiguration)) { return; } var originalPayload = this.PayloadElement; this.PayloadElement = this.PayloadElement.DeepCopy(); // Create messages (payload gets serialized in createInputMessage) TestMessage readerMessage = this.CreateInputMessage(testConfiguration); var settings = new ODataMessageWriterSettings() { Version = testConfiguration.Version, BaseUri = testConfiguration.MessageReaderSettings.BaseUri, EnableMessageStreamDisposal = testConfiguration.MessageReaderSettings.EnableMessageStreamDisposal, }; settings.SetContentType(testConfiguration.Format); WriterTestConfiguration writerConfig = new WriterTestConfiguration(testConfiguration.Format, settings, testConfiguration.IsRequest, testConfiguration.Synchronous); TestMessage writerMessage = TestWriterUtils.CreateOutputMessageFromStream(new TestStream(new MemoryStream()), writerConfig, this.PayloadKind, String.Empty, this.UrlResolver); IEdmModel model = this.GetMetadataProvider(testConfiguration); WriterTestExpectedResults expectedResult = this.GetExpectedResult(writerConfig); 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(readerMessage, model, testConfiguration)) using (ODataMessageWriterTestWrapper messageWriterWrapper = TestWriterUtils.CreateMessageWriter(writerMessage, model, writerConfig, this.settings.Assert)) { var streamer = new ObjectModelReadWriteStreamer(); streamer.StreamMessage(messageReaderWrapper, messageWriterWrapper, this.PayloadKind, writerConfig); expectedResult.VerifyResult(writerMessage, this.PayloadKind, writerConfig, logger); } }); this.PayloadElement = originalPayload; try { expectedResult.VerifyException(exception); } catch (Exception) { this.TraceFailureInformation(testConfiguration); throw; } }
public void FatalExceptionTest() { ODataResource entry = ObjectModelUtils.CreateDefaultEntry(); this.CombinatorialEngineProvider.RunCombinations( new ODataItem[] { entry }, new bool[] { true, false }, // flush // TODO: also enable this test for the sync scenarios this.WriterTestConfigurationProvider.ExplicitFormatConfigurations.Where(tc => !tc.Synchronous), (payload, flush, testConfiguration) => { testConfiguration = testConfiguration.Clone(); testConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri); using (var memoryStream = new TestStream()) using (var messageWriter = TestWriterUtils.CreateMessageWriter(memoryStream, testConfiguration, this.Assert)) { ODataWriter writer = messageWriter.CreateODataWriter(isFeed: false); ODataWriterCoreInspector inspector = new ODataWriterCoreInspector(writer); // close the memory stream so that any attempt to flush will cause a fatal error memoryStream.CloseInner(); // write the payload and call FlushAsync() to trigger a fatal exception Exception ex = TestExceptionUtils.RunCatching(() => TestWriterUtils.WritePayload(messageWriter, writer, true, entry)); this.Assert.IsNotNull(ex, "Expected exception but none was thrown."); NotSupportedException notSupported = null; #if SILVERLIGHT || WINDOWS_PHONE var baseEx = ex.GetBaseException(); this.Assert.IsNotNull(baseEx, "BaseException of exception:" + ex.ToString() + " should not be null"); notSupported = baseEx as NotSupportedException; this.Assert.IsNotNull(notSupported, "Expected NotSupportedException but " + baseEx.GetType().FullName + " was reported."); #else notSupported = TestExceptionUtils.UnwrapAggregateException(ex, this.Assert) as NotSupportedException; this.Assert.IsNotNull(notSupported, "Expected NotSupportedException but " + ex.ToString() + " was reported."); #endif this.Assert.AreEqual("Stream does not support writing.", notSupported.Message, "Did not find expected error message."); this.Assert.IsTrue(inspector.IsInErrorState, "Writer is not in expected 'Error' state."); if (flush) { // Flush should work in error state. writer.Flush(); } // in all cases we have to be able to dispose the writer without problems. } }); }
/// <summary> /// Creates an ODataWriter for the specified format and the specified version and /// writes the property in the descriptor to an in-memory stream. It then parses /// the written Xml and compares it to the expected result as specified in the descriptor. /// </summary> /// <param name="originalPayload">The payload to first clone and then write.</param> /// <param name="testConfiguration">Configuration for the test</param> /// <param name="model">The model to use.</param> protected void WriteAndVerifyODataProperty(ODataPayloadElement originalPayload, WriterTestConfiguration testConfiguration, IEdmModel model) { this.Logger.LogConfiguration(testConfiguration); this.Logger.LogModelPresence(model); using (var memoryStream = new TestStream()) { TestMessage testMessage; using (ODataMessageWriterTestWrapper writer = TestWriterUtils.CreateMessageWriter(memoryStream, testConfiguration, this.Assert, out testMessage, null, model)) { Action <ODataPayloadElement> writeElementToStream = payload => this.PropertyPayloadElementWriter.WriteProperty(writer.MessageWriter, payload); this.WriteAndLogODataPayload(originalPayload, writer.Message, testConfiguration.Version, testConfiguration.Format, writeElementToStream); } } }
/// <summary> /// Creates an ODataWriter for the specified format and the specified version and /// writes the payload in the descriptor to an in-memory stream. It then parses /// the written Xml and compares it to the expected result as specified in the descriptor. /// </summary> /// <param name="originalPayload">expectedPayload to write and</param> /// <param name="testConfiguration">Configuration for the test</param> protected void WriteAndVerifyODataPayloadElement(ODataPayloadElement originalPayload, WriterTestConfiguration testConfiguration) { this.Logger.LogConfiguration(testConfiguration); bool feedWriter = originalPayload.ElementType == ODataPayloadElementType.EntitySetInstance; using (var memoryStream = new TestStream()) { using (var messageWriter = TestWriterUtils.CreateMessageWriter(memoryStream, testConfiguration, this.Assert)) { ODataWriter writer = messageWriter.CreateODataWriter(feedWriter); Action <ODataPayloadElement> writeToStream = payload => this.PayloadElementWriter.WritePayload(writer, payload); this.WriteAndLogODataPayload(originalPayload, messageWriter.Message, testConfiguration.Version, testConfiguration.Format, writeToStream); } } }
public void DisposeAfterWritingNothingTest() { this.CombinatorialEngineProvider.RunCombinations( this.WriterTestConfigurationProvider.ExplicitFormatConfigurations, new bool[] { true, false }, (testConfiguration, forFeed) => { testConfiguration = testConfiguration.Clone(); testConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri); using (var stream = new TestStream()) using (var messageWriter = TestWriterUtils.CreateMessageWriter(stream, testConfiguration, this.Assert)) { ODataWriter writer = messageWriter.CreateODataWriter(forFeed); } }); }
/// <summary> /// Runs the specified action for all interesting writers. /// </summary> /// <param name="feedWriter">True if writing a feed; false if writing an entry.</param> /// <param name="action">The action to run.</param> private void ForWriters(bool feedWriter, Action <ODataWriter> action) { this.CombinatorialEngineProvider.RunCombinations( this.WriterTestConfigurationProvider.ExplicitFormatConfigurations, (testConfiguration) => { testConfiguration = testConfiguration.Clone(); testConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri); using (TestStream stream = new TestStream()) using (var messageWriter = TestWriterUtils.CreateMessageWriter(stream, testConfiguration, this.Assert)) { ODataWriter writer = messageWriter.CreateODataWriter(feedWriter); action(writer); } }); }
public void FeedInvalidContentTests() { ODataFeed defaultFeed = ObjectModelUtils.CreateDefaultFeed(); ODataItem[] invalidPayload1 = new ODataItem[] { defaultFeed, defaultFeed }; var testCases = new[] { new { Items = invalidPayload1, ExpectedError = "Cannot transition from state 'Feed' to state 'Feed'. The only valid action in state 'Feed' is to write an entry." } }; this.CombinatorialEngineProvider.RunCombinations( testCases, ODataFormatUtils.ODataFormats.Where(f => f != null), // Async test configuration is not supported for Phone and Silverlight #if !SILVERLIGHT && !WINDOWS_PHONE new bool[] { false, true }, #else new bool[] { true }, #endif (testCase, format, synchronous) => { using (var memoryStream = new TestStream()) { ODataMessageWriterSettings settings = new ODataMessageWriterSettings(); settings.Version = ODataVersion.V4; settings.SetServiceDocumentUri(ServiceDocumentUri); using (var messageWriter = TestWriterUtils.CreateMessageWriter(memoryStream, new WriterTestConfiguration(format, settings, false, synchronous), this.Assert)) { ODataWriter writer = messageWriter.CreateODataWriter(isFeed: true); TestExceptionUtils.ExpectedException <ODataException>( this.Assert, () => TestWriterUtils.WritePayload(messageWriter, writer, true, testCase.Items), testCase.ExpectedError); } } }); }
public void WriteAfterExceptionTest() { // create a default entry and then set both read and edit links to null to provoke an exception during writing ODataResource faultyEntry = ObjectModelUtils.CreateDefaultEntry(); this.Assert.IsNull(faultyEntry.EditLink, "entry.EditLink == null"); ODataResource defaultEntry = ObjectModelUtils.CreateDefaultEntry(); ODataResourceSet defaultFeed = ObjectModelUtils.CreateDefaultFeed(); this.CombinatorialEngineProvider.RunCombinations( new ODataItem[] { faultyEntry }, new ODataItem[] { defaultFeed, defaultEntry }, this.WriterTestConfigurationProvider.ExplicitFormatConfigurations, (faultyPayload, contentPayload, testConfiguration) => { testConfiguration = testConfiguration.Clone(); testConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri); using (var memoryStream = new TestStream()) using (var messageWriter = TestWriterUtils.CreateMessageWriter(memoryStream, testConfiguration, this.Assert)) { ODataWriter writer = messageWriter.CreateODataWriter(isFeed: false); ODataWriterCoreInspector inspector = new ODataWriterCoreInspector(writer); // write the invalid entry and expect an exception this.Assert.ExpectedException( () => TestWriterUtils.WritePayload(messageWriter, writer, false, faultyEntry), ODataExpectedExceptions.ODataException("WriterValidationUtils_EntriesMustHaveNonEmptyId"), this.ExceptionVerifier); this.Assert.IsTrue(inspector.IsInErrorState, "Writer is not in expected 'error' state."); // now write some non-error content which is invalid to do Exception ex = TestExceptionUtils.RunCatching(() => TestWriterUtils.WritePayload(messageWriter, writer, false, contentPayload)); ex = TestExceptionUtils.UnwrapAggregateException(ex, this.Assert); this.Assert.IsNotNull(ex, "Expected exception but none was thrown"); this.Assert.IsTrue(ex is ODataException, "Expected an ODataException instance but got a " + ex.GetType().FullName + "."); this.Assert.IsTrue(ex.Message.Contains("Cannot transition from state 'Error' to state "), "Did not find expected start of error message."); this.Assert.IsTrue(ex.Message.Contains("Nothing can be written once the writer entered the error state."), "Did not find expected end of error message in '" + ex.Message + "'."); this.Assert.IsTrue(inspector.IsInErrorState, "Writer is not in expected 'error' state."); writer.Flush(); } }); }
/// <summary> /// Runs the test specified by this test descriptor. /// </summary> /// <param name="testConfiguration">The test configuration to use for running the test.</param> public override void RunTest(WriterTestConfiguration testConfiguration, BaselineLogger logger) { if (this.ShouldSkipForTestConfiguration(testConfiguration)) { return; } // Wrap the memory stream in a non-disposing stream so we can dump the message content // even in the case of a failure where the message stream normally would get disposed. logger.LogConfiguration(testConfiguration); logger.LogModelPresence(this.Model); this.messageStream = new NonDisposingStream(new MemoryStream()); TestMessage message = this.CreateOutputMessage(this.messageStream, testConfiguration, this.PayloadElement); IEdmModel model = this.GetMetadataProvider(); WriterTestExpectedResults 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(() => { // We create a new test configuration for batch because the payload indicates whether we are dealing with a request or a response and the configuration won't know that in advance var newTestConfig = new WriterTestConfiguration(testConfiguration.Format, testConfiguration.MessageWriterSettings, this.PayloadElement is BatchRequestPayload, testConfiguration.Synchronous); using (ODataMessageWriterTestWrapper messageWriterWrapper = TestWriterUtils.CreateMessageWriter(message, model, newTestConfig, this.settings.Assert, null)) { this.WritePayload(messageWriterWrapper, testConfiguration); expectedResult.VerifyResult(message, this.PayloadKind, testConfiguration, logger); } }); try { expectedResult.VerifyException(exception); } catch (Exception failureException) { this.TraceFailureInformation(message, this.messageStream, testConfiguration); throw failureException; } }
/// <summary> /// Runs the test specified by this test descriptor. /// </summary> /// <param name="testConfiguration">The test configuration to use for running the test.</param> public override void RunTest(WriterTestConfiguration testConfiguration, BaselineLogger logger = null) { //TODO: Use Logger to verify result, right now this change is only to unblock writer testcase checkin if (this.ShouldSkipForTestConfiguration(testConfiguration)) { return; } // Generate a StreamingTestStream with a NonDisposingStream. this.messageStream = new StreamingTestStream(new NonDisposingStream(new MemoryStream())); TestMessage message = this.CreateOutputMessage(this.messageStream, testConfiguration); IEdmModel model = this.GetMetadataProvider(); StreamingWriterTestExpectedResults expectedResult = (StreamingWriterTestExpectedResults)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 (ODataMessageWriterTestWrapper messageWriterWrapper = TestWriterUtils.CreateMessageWriter(message, model, testConfiguration, this.settings.Assert)) { this.WritePayload(messageWriterWrapper, testConfiguration); expectedResult.ObservedElement = this.readObject; expectedResult.VerifyResult(message, this.PayloadKind, testConfiguration); } }); try { expectedResult.VerifyException(exception); } catch (Exception failureException) { this.TraceFailureInformation(message, this.messageStream, testConfiguration); throw failureException; } }
/// <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(WriterTestConfiguration testConfiguration, BaselineLogger logger) { if (this.ShouldSkipForTestConfiguration(testConfiguration)) { return; } // Wrap the memory stream in a non-disposing stream so we can dump the message content // even in the case of a failure where the message stream normally would get disposed. logger.LogConfiguration(testConfiguration); logger.LogModelPresence(this.Model); this.messageStream = new NonDisposingStream(new MemoryStream()); TestMessage message = this.CreateOutputMessage(this.messageStream, testConfiguration); IEdmModel model = this.GetMetadataProvider(); WriterTestExpectedResults 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 (ODataMessageWriterTestWrapper messageWriterWrapper = TestWriterUtils.CreateMessageWriter(message, model, testConfiguration, this.settings.Assert)) { this.WritePayload(messageWriterWrapper, testConfiguration); expectedResult.VerifyResult(message, this.PayloadKind, testConfiguration, logger); } }); try { expectedResult.VerifyException(exception); } catch (Exception failureException) { this.TraceFailureInformation(message, this.messageStream, testConfiguration); throw failureException; } }
public void WriteAfterDisposeTest() { this.CombinatorialEngineProvider.RunCombinations( this.WriterTestConfigurationProvider.ExplicitFormatConfigurations, (testConfiguration) => { testConfiguration = testConfiguration.Clone(); testConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri); using (var stream = new TestStream()) { ODataWriter writer; using (var messageWriter = TestWriterUtils.CreateMessageWriter(stream, testConfiguration, this.Assert)) { writer = messageWriter.CreateODataWriter(isFeed: true); // Message writer is disposed outside of this scope. } this.VerifyWriterAlreadyDisposed(() => writer.WriteStart(ObjectModelUtils.CreateDefaultFeed())); this.VerifyWriterAlreadyDisposed(() => writer.WriteStart(ObjectModelUtils.CreateDefaultEntry())); this.VerifyWriterAlreadyDisposed(() => writer.WriteStart(ObjectModelUtils.CreateDefaultCollectionLink())); } }); }
public void SyncAsyncMismatchTest() { // ToDo: Fix places where we've lost JsonVerbose coverage to add JsonLight this.CombinatorialEngineProvider.RunCombinations( TestCalls, this.WriterTestConfigurationProvider.ExplicitFormatConfigurations.Where(tc => !tc.IsRequest && tc.Format == ODataFormat.Atom), new bool[] { false, true }, (testCall, testConfiguration, testSynchronousCall) => { using (var memoryStream = new TestStream()) using (var messageWriter = TestWriterUtils.CreateMessageWriter(memoryStream, testConfiguration, this.Assert)) { ODataCollectionWriter collectionWriter = messageWriter.CreateODataCollectionWriter(); ODataCollectionWriterTestWrapper writer = (ODataCollectionWriterTestWrapper)collectionWriter; this.Assert.ExpectedException( () => { if (testSynchronousCall) { testCall.Sync(writer); } else { testCall.Async(writer); } }, testConfiguration.Synchronous == testSynchronousCall ? null : testSynchronousCall ? ODataExpectedExceptions.ODataException("ODataCollectionWriterCore_SyncCallOnAsyncWriter") : ODataExpectedExceptions.ODataException("ODataCollectionWriterCore_AsyncCallOnSyncWriter"), this.ExceptionVerifier); } }); }
public void CollectionWriterStatesTest() { var testCases = new CollectionWriterStatesTestDescriptor[] { new CollectionWriterStatesTestDescriptor { DebugDescription = "Start", Setup = null, ExpectedResults = new Dictionary <CollectionWriterAction, string> { { CollectionWriterAction.Start, null }, { CollectionWriterAction.Item, "Cannot transition from state 'Start' to state 'Item'. The only valid actions in state 'Start' are to write the collection or to write nothing at all." }, { CollectionWriterAction.End, "ODataCollectionWriter.WriteEnd was called in an invalid state ('Start'); WriteEnd is only supported in states 'Start', 'Collection', and 'Item'." }, { CollectionWriterAction.Error, null }, } }, new CollectionWriterStatesTestDescriptor { DebugDescription = "Collection", Setup = (mw, w, s) => { w.WriteStart(new ODataCollectionStart { Name = "foo" }); }, ExpectedResults = new Dictionary <CollectionWriterAction, string> { { CollectionWriterAction.Start, "Cannot transition from state 'Collection' to state 'Collection'. The only valid actions in state 'Collection' are to write an item or to write the end of the collection." }, { CollectionWriterAction.Item, null }, { CollectionWriterAction.End, null }, { CollectionWriterAction.Error, null }, } }, new CollectionWriterStatesTestDescriptor { DebugDescription = "Item", Setup = (mw, w, s) => { w.WriteStart(new ODataCollectionStart { Name = "foo" }); w.WriteItem(42); }, ExpectedResults = new Dictionary <CollectionWriterAction, string> { { CollectionWriterAction.Start, "Cannot transition from state 'Item' to state 'Collection'. The only valid actions in state 'Item' are to write an item or the end of the collection." }, { CollectionWriterAction.Item, null }, { CollectionWriterAction.End, null }, { CollectionWriterAction.Error, null }, } }, new CollectionWriterStatesTestDescriptor { DebugDescription = "Completed", Setup = (mw, w, s) => { w.WriteStart(new ODataCollectionStart { Name = "foo" }); w.WriteEnd(); }, ExpectedResults = new Dictionary <CollectionWriterAction, string> { { CollectionWriterAction.Start, "Cannot transition from state 'Completed' to state 'Collection'. Nothing further can be written once the writer has completed." }, { CollectionWriterAction.Item, "Cannot transition from state 'Completed' to state 'Item'. Nothing further can be written once the writer has completed." }, { CollectionWriterAction.End, "ODataCollectionWriter.WriteEnd was called in an invalid state ('Completed'); WriteEnd is only supported in states 'Start', 'Collection', and 'Item'." }, { CollectionWriterAction.Error, "Cannot transition from state 'Completed' to state 'Error'. Nothing further can be written once the writer has completed." }, } }, new CollectionWriterStatesTestDescriptor { DebugDescription = "ODataExceptionThrown", Setup = (mw, w, s) => { TestExceptionUtils.RunCatching(() => w.WriteItem(42)); }, ExpectedResults = new Dictionary <CollectionWriterAction, string> { { CollectionWriterAction.Start, "Cannot transition from state 'Error' to state 'Collection'. Nothing can be written once the writer entered the error state." }, { CollectionWriterAction.Item, "Cannot transition from state 'Error' to state 'Item'. Nothing can be written once the writer entered the error state." }, { CollectionWriterAction.End, "ODataCollectionWriter.WriteEnd was called in an invalid state ('Error'); WriteEnd is only supported in states 'Start', 'Collection', and 'Item'." }, { CollectionWriterAction.Error, null }, } }, new CollectionWriterStatesTestDescriptor { DebugDescription = "FatalExceptionThrown", Setup = (mw, w, s) => { // In JSON we can make the stream fail s.FailNextCall = true; w.WriteStart(new ODataCollectionStart { Name = "foo" }); TestExceptionUtils.RunCatching(() => w.Flush()); }, ExpectedResults = new Dictionary <CollectionWriterAction, string> { { CollectionWriterAction.Start, "Cannot transition from state 'Error' to state 'Collection'. Nothing can be written once the writer entered the error state." }, { CollectionWriterAction.Item, "Cannot transition from state 'Error' to state 'Item'. Nothing can be written once the writer entered the error state." }, { CollectionWriterAction.End, "ODataCollectionWriter.WriteEnd was called in an invalid state ('Error'); WriteEnd is only supported in states 'Start', 'Collection', and 'Item'." }, { CollectionWriterAction.Error, null }, }, // There's no simple way to make the writer go into a fatal exception state with XmlWriter underneath. // XmlWriter will move to an Error state if anything goes wrong with it, and thus we can't write into it anymore. // As a result for example the in-stream error case for this one can't work as it should. SkipForConfiguration = (tc) => tc.Format != ODataFormat.Json }, new CollectionWriterStatesTestDescriptor { DebugDescription = "Error", Setup = (mw, w, s) => { mw.WriteError(new ODataError(), false); }, ExpectedResults = new Dictionary <CollectionWriterAction, string> { { CollectionWriterAction.Start, "Cannot transition from state 'Error' to state 'Collection'. Nothing can be written once the writer entered the error state." }, { CollectionWriterAction.Item, "Cannot transition from state 'Error' to state 'Item'. Nothing can be written once the writer entered the error state." }, { CollectionWriterAction.End, "ODataCollectionWriter.WriteEnd was called in an invalid state ('Error'); WriteEnd is only supported in states 'Start', 'Collection', and 'Item'." }, { CollectionWriterAction.Error, "The WriteError method or the WriteErrorAsync method on the ODataMessageWriter has already been called to write an error payload. Only a single error payload can be written with each ODataMessageWriter instance." }, } }, }; //ToDo: Fix places where we've lost JsonVerbose coverage to add JsonLight this.CombinatorialEngineProvider.RunCombinations( testCases, EnumExtensionMethods.GetValues <CollectionWriterAction>().Cast <CollectionWriterAction>(), this.WriterTestConfigurationProvider.ExplicitFormatConfigurations.Where(tc => false), (testCase, writerAction, testConfiguration) => { using (TestStream stream = new TestStream()) { if (testCase.SkipForConfiguration != null && testCase.SkipForConfiguration(testConfiguration)) { return; } // We purposely don't use the using pattern around the messageWriter here. Disposing the message writer will // fail here because the writer is not left in a valid state. var messageWriter = TestWriterUtils.CreateMessageWriter(stream, testConfiguration, this.Assert); ODataCollectionWriter writer = messageWriter.CreateODataCollectionWriter(); if (testCase.Setup != null) { testCase.Setup(messageWriter, writer, stream); } string expectedException = testCase.ExpectedResults[writerAction]; this.Assert.ExpectedException <ODataException>( () => InvokeCollectionWriterAction(messageWriter, writer, writerAction), expectedException); } }); }
private void WriterStatesTestImplementation(bool feedWriter) { var testCases = new WriterStatesTestDescriptor[] { // Start new WriterStatesTestDescriptor { Setup = null, ExpectedResults = new Dictionary <WriterAction, ExpectedException> { { WriterAction.StartResource, feedWriter ? ODataExpectedExceptions.ODataException("ODataWriterCore_CannotWriteTopLevelResourceWithResourceSetWriter") : (ExpectedException)null }, { WriterAction.StartFeed, feedWriter ? (ExpectedException)null : ODataExpectedExceptions.ODataException("ODataWriterCore_CannotWriteTopLevelResourceSetWithResourceWriter") }, { WriterAction.StartLink, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidTransitionFromStart", "Start", "NavigationLink") }, { WriterAction.End, ODataExpectedExceptions.ODataException("ODataWriterCore_WriteEndCalledInInvalidState", "Start") }, { WriterAction.Error, null }, } }, // Entry new WriterStatesTestDescriptor { Setup = (mw, w, s) => { if (feedWriter) { w.WriteStart(ObjectModelUtils.CreateDefaultFeed()); } w.WriteStart(ObjectModelUtils.CreateDefaultEntry()); }, ExpectedResults = new Dictionary <WriterAction, ExpectedException> { { WriterAction.StartResource, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidTransitionFromResource", "Entry", "Entry") }, { WriterAction.StartFeed, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidTransitionFromResource", "Entry", "Feed") }, { WriterAction.StartLink, null }, { WriterAction.End, null }, { WriterAction.Error, null }, } }, // Feed new WriterStatesTestDescriptor { Setup = (mw, w, s) => { if (feedWriter) { w.WriteStart(ObjectModelUtils.CreateDefaultFeed()); } else { w.WriteStart(ObjectModelUtils.CreateDefaultEntry()); w.WriteStart(ObjectModelUtils.CreateDefaultCollectionLink()); w.WriteStart(ObjectModelUtils.CreateDefaultFeed()); } }, ExpectedResults = new Dictionary <WriterAction, ExpectedException> { { WriterAction.StartResource, null }, { WriterAction.StartFeed, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidTransitionFromResourceSet", "Feed", "Feed") }, { WriterAction.StartLink, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidTransitionFromResourceSet", "Feed", "NavigationLink") }, { WriterAction.End, null }, { WriterAction.Error, null }, } }, // Link - single new WriterStatesTestDescriptor { Setup = (mw, w, s) => { if (feedWriter) { w.WriteStart(ObjectModelUtils.CreateDefaultFeed()); } w.WriteStart(ObjectModelUtils.CreateDefaultEntry()); w.WriteStart(new ODataNestedResourceInfo { Name = ObjectModelUtils.DefaultLinkName, Url = ObjectModelUtils.DefaultLinkUrl, IsCollection = false }); }, ExpectedResults = new Dictionary <WriterAction, ExpectedException> { { WriterAction.StartResource, null }, { WriterAction.StartFeed, ODataExpectedExceptions.ODataException("WriterValidationUtils_ExpandedLinkIsCollectionFalseWithResourceSetContent", "http://odata.org/link") }, { WriterAction.StartLink, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidStateTransition", "NavigationLink", "NavigationLink") }, { WriterAction.End, null }, { WriterAction.Error, null }, }, SkipForTestConfiguration = tc => tc.IsRequest }, // Link - collection new WriterStatesTestDescriptor { Setup = (mw, w, s) => { if (feedWriter) { w.WriteStart(ObjectModelUtils.CreateDefaultFeed()); } w.WriteStart(ObjectModelUtils.CreateDefaultEntry()); w.WriteStart(ObjectModelUtils.CreateDefaultCollectionLink()); }, ExpectedResults = new Dictionary <WriterAction, ExpectedException> { { WriterAction.StartResource, ODataExpectedExceptions.ODataException("WriterValidationUtils_ExpandedLinkIsCollectionTrueWithResourceContent", "http://odata.org/link") }, { WriterAction.StartFeed, null }, { WriterAction.StartLink, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidStateTransition", "NavigationLink", "NavigationLink") }, { WriterAction.End, null }, { WriterAction.Error, null }, }, SkipForTestConfiguration = tc => tc.IsRequest }, // Expanded link - there's no way to get to the expanded link state alone since the writer will always // immediately transition to either entry or feed state instead. // Completed new WriterStatesTestDescriptor { Setup = (mw, w, s) => { if (feedWriter) { w.WriteStart(ObjectModelUtils.CreateDefaultFeed()); w.WriteEnd(); } else { w.WriteStart(ObjectModelUtils.CreateDefaultEntry()); w.WriteEnd(); } }, ExpectedResults = new Dictionary <WriterAction, ExpectedException> { { WriterAction.StartResource, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidTransitionFromCompleted", "Completed", "Entry") }, { WriterAction.StartFeed, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidTransitionFromCompleted", "Completed", "Feed") }, { WriterAction.StartLink, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidTransitionFromCompleted", "Completed", "NavigationLink") }, { WriterAction.End, ODataExpectedExceptions.ODataException("ODataWriterCore_WriteEndCalledInInvalidState", "Completed") }, { WriterAction.Error, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidTransitionFromCompleted", "Completed", "Error") }, } }, // ODataExceptionThrown new WriterStatesTestDescriptor { Setup = (mw, w, s) => { TestExceptionUtils.RunCatching(() => w.WriteStart(ObjectModelUtils.CreateDefaultCollectionLink())); }, ExpectedResults = new Dictionary <WriterAction, ExpectedException> { { WriterAction.StartResource, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidTransitionFromError", "Error", "Entry") }, { WriterAction.StartFeed, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidTransitionFromError", "Error", "Feed") }, { WriterAction.StartLink, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidTransitionFromError", "Error", "NavigationLink") }, { WriterAction.End, ODataExpectedExceptions.ODataException("ODataWriterCore_WriteEndCalledInInvalidState", "Error") }, { WriterAction.Error, null }, }, SkipForTestConfiguration = tc => tc.IsRequest, }, // Error new WriterStatesTestDescriptor { Setup = (mw, w, s) => { mw.WriteError(new ODataError(), false); }, ExpectedResults = new Dictionary <WriterAction, ExpectedException> { { WriterAction.StartResource, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidTransitionFromError", "Error", "Entry") }, { WriterAction.StartFeed, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidTransitionFromError", "Error", "Feed") }, { WriterAction.StartLink, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidTransitionFromError", "Error", "NavigationLink") }, { WriterAction.End, ODataExpectedExceptions.ODataException("ODataWriterCore_WriteEndCalledInInvalidState", "Error") }, { WriterAction.Error, ODataExpectedExceptions.ODataException("ODataMessageWriter_WriteErrorAlreadyCalled") }, }, SkipForTestConfiguration = tc => tc.IsRequest, }, }; ExpectedException errorNotAllowedException = ODataExpectedExceptions.ODataException("ODataMessageWriter_ErrorPayloadInRequest"); this.CombinatorialEngineProvider.RunCombinations( testCases, EnumExtensionMethods.GetValues <WriterAction>().Cast <WriterAction>(), this.WriterTestConfigurationProvider.AtomFormatConfigurations, (testCase, writerAction, testConfiguration) => { testConfiguration = testConfiguration.Clone(); testConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri); if (testCase.SkipForTestConfiguration != null && testCase.SkipForTestConfiguration(testConfiguration)) { return; } ExpectedException expectedExceptionOnError; if (testCase.ExpectedResults.TryGetValue(WriterAction.Error, out expectedExceptionOnError)) { if (testConfiguration.IsRequest) { testCase = new WriterStatesTestDescriptor(testCase); testCase.ExpectedResults[WriterAction.Error] = errorNotAllowedException; } } using (TestStream stream = new TestStream()) { // We purposely don't use the using pattern around the messageWriter here. Disposing the message writer will // fail here because the writer is not left in a valid state. var messageWriter = TestWriterUtils.CreateMessageWriter(stream, testConfiguration, this.Assert); ODataWriter writer = messageWriter.CreateODataWriter(feedWriter); TestExceptionUtils.ExpectedException( this.Assert, () => { if (testCase.Setup != null) { testCase.Setup(messageWriter, writer, stream); } this.InvokeWriterAction(messageWriter, writer, writerAction); }, testCase.ExpectedResults[writerAction], this.ExceptionVerifier); } }); }
public void BatchWriterStatesTest() { var testCases = new BatchWriterStatesTestDescriptor[] { // Start new BatchWriterStatesTestDescriptor { Setup = null, ExpectedResults = new Dictionary <BatchWriterAction, ExpectedException> { { BatchWriterAction.StartBatch, null }, { BatchWriterAction.EndBatch, ODataExpectedExceptions.ODataException("ODataBatchWriter_InvalidTransitionFromStart") }, { BatchWriterAction.StartChangeset, ODataExpectedExceptions.ODataException("ODataBatchWriter_InvalidTransitionFromStart") }, { BatchWriterAction.EndChangeset, ODataExpectedExceptions.ODataException("ODataBatchWriter_CannotCompleteChangeSetWithoutActiveChangeSet") }, { BatchWriterAction.Operation, ODataExpectedExceptions.ODataException("ODataBatchWriter_InvalidTransitionFromStart") }, { BatchWriterAction.GetOperationStream, null }, { BatchWriterAction.DisposeOperationStream, null }, }, ReadOperationReady = true }, // BatchStarted new BatchWriterStatesTestDescriptor { Setup = (w, s, tc) => { w.WriteStartBatch(); return(null); }, ExpectedResults = new Dictionary <BatchWriterAction, ExpectedException> { { BatchWriterAction.StartBatch, ODataExpectedExceptions.ODataException("ODataBatchWriter_InvalidTransitionFromBatchStarted") }, { BatchWriterAction.EndBatch, null }, { BatchWriterAction.StartChangeset, null }, { BatchWriterAction.EndChangeset, ODataExpectedExceptions.ODataException("ODataBatchWriter_CannotCompleteChangeSetWithoutActiveChangeSet") }, { BatchWriterAction.Operation, null }, { BatchWriterAction.GetOperationStream, null }, { BatchWriterAction.DisposeOperationStream, null }, }, ReadOperationReady = true }, // ChangeSetStarted new BatchWriterStatesTestDescriptor { Setup = (w, s, tc) => { w.WriteStartBatch(); w.WriteStartChangeset(); return(null); }, ExpectedResults = new Dictionary <BatchWriterAction, ExpectedException> { { BatchWriterAction.StartBatch, ODataExpectedExceptions.ODataException("ODataBatchWriter_InvalidTransitionFromChangeSetStarted") }, { BatchWriterAction.EndBatch, ODataExpectedExceptions.ODataException("ODataBatchWriter_CannotCompleteBatchWithActiveChangeSet") }, { BatchWriterAction.StartChangeset, ODataExpectedExceptions.ODataException("ODataBatchWriter_CannotStartChangeSetWithActiveChangeSet") }, { BatchWriterAction.EndChangeset, null }, { BatchWriterAction.Operation, null }, { BatchWriterAction.GetOperationStream, null }, { BatchWriterAction.DisposeOperationStream, null }, }, ReadOperationReady = false }, // OperationCreated - Read new BatchWriterStatesTestDescriptor { Setup = (w, s, tc) => { w.WriteStartBatch(); if (tc.IsRequest) { return(new BatchWriterStatesTestSetupResult { Message = w.CreateOperationRequestMessage("GET", new Uri("http://odata.org")) }); } else { return(new BatchWriterStatesTestSetupResult { Message = w.CreateOperationResponseMessage() }); } }, ExpectedResults = new Dictionary <BatchWriterAction, ExpectedException> { { BatchWriterAction.StartBatch, ODataExpectedExceptions.ODataException("ODataBatchWriter_InvalidTransitionFromOperationCreated") }, { BatchWriterAction.EndBatch, null }, { BatchWriterAction.StartChangeset, null }, { BatchWriterAction.EndChangeset, ODataExpectedExceptions.ODataException("ODataBatchWriter_CannotCompleteChangeSetWithoutActiveChangeSet") }, { BatchWriterAction.Operation, null }, { BatchWriterAction.GetOperationStream, null }, { BatchWriterAction.DisposeOperationStream, null }, }, ReadOperationReady = true }, // OperationStreamRequested - Read new BatchWriterStatesTestDescriptor { Setup = (w, s, tc) => { w.WriteStartBatch(); if (tc.IsRequest) { return(GetOperationStream(w.CreateOperationRequestMessage("GET", new Uri("http://odata.org")), tc)); } else { return(GetOperationStream(w.CreateOperationResponseMessage(), tc)); } }, ExpectedResults = new Dictionary <BatchWriterAction, ExpectedException> { { BatchWriterAction.StartBatch, ODataExpectedExceptions.ODataException("ODataBatchWriter_InvalidTransitionFromOperationContentStreamRequested") }, { BatchWriterAction.EndBatch, ODataExpectedExceptions.ODataException("ODataBatchWriter_InvalidTransitionFromOperationContentStreamRequested") }, { BatchWriterAction.StartChangeset, ODataExpectedExceptions.ODataException("ODataBatchWriter_InvalidTransitionFromOperationContentStreamRequested") }, { BatchWriterAction.EndChangeset, ODataExpectedExceptions.ODataException("ODataBatchWriter_InvalidTransitionFromOperationContentStreamRequested") }, { BatchWriterAction.Operation, ODataExpectedExceptions.ODataException("ODataBatchWriter_InvalidTransitionFromOperationContentStreamRequested") }, { BatchWriterAction.GetOperationStream, ODataExpectedExceptions.ODataException("ODataBatchOperationMessage_VerifyNotCompleted") }, { BatchWriterAction.DisposeOperationStream, null }, }, ReadOperationReady = true }, // OperationStreamDisposed - Read new BatchWriterStatesTestDescriptor { Setup = (w, s, tc) => { w.WriteStartBatch(); BatchWriterStatesTestSetupResult result; if (tc.IsRequest) { result = GetOperationStream(w.CreateOperationRequestMessage("GET", new Uri("http://odata.org")), tc); } else { result = GetOperationStream(w.CreateOperationResponseMessage(), tc); } result.MessageStream.Dispose(); return(result); }, ExpectedResults = new Dictionary <BatchWriterAction, ExpectedException> { { BatchWriterAction.StartBatch, ODataExpectedExceptions.ODataException("ODataBatchWriter_InvalidTransitionFromOperationContentStreamDisposed") }, { BatchWriterAction.EndBatch, null }, { BatchWriterAction.StartChangeset, null }, { BatchWriterAction.EndChangeset, ODataExpectedExceptions.ODataException("ODataBatchWriter_CannotCompleteChangeSetWithoutActiveChangeSet") }, { BatchWriterAction.Operation, null }, { BatchWriterAction.GetOperationStream, ODataExpectedExceptions.ODataException("ODataBatchOperationMessage_VerifyNotCompleted") }, // Calling IDisposable.Dispose should not throw. { BatchWriterAction.DisposeOperationStream, null }, }, ReadOperationReady = true }, // OperationCreated - Update new BatchWriterStatesTestDescriptor { Setup = (w, s, tc) => { w.WriteStartBatch(); w.WriteStartChangeset(); if (tc.IsRequest) { return(new BatchWriterStatesTestSetupResult { Message = w.CreateOperationRequestMessage("POST", new Uri("http://odata.org"), "1") }); } else { return(new BatchWriterStatesTestSetupResult { Message = w.CreateOperationResponseMessage() }); } }, ExpectedResults = new Dictionary <BatchWriterAction, ExpectedException> { { BatchWriterAction.StartBatch, ODataExpectedExceptions.ODataException("ODataBatchWriter_InvalidTransitionFromOperationCreated") }, { BatchWriterAction.EndBatch, ODataExpectedExceptions.ODataException("ODataBatchWriter_CannotCompleteBatchWithActiveChangeSet") }, { BatchWriterAction.StartChangeset, ODataExpectedExceptions.ODataException("ODataBatchWriter_CannotStartChangeSetWithActiveChangeSet") }, { BatchWriterAction.EndChangeset, null }, { BatchWriterAction.Operation, null }, { BatchWriterAction.GetOperationStream, null }, { BatchWriterAction.DisposeOperationStream, null }, }, ReadOperationReady = false }, // OperationStreamRequested - Update new BatchWriterStatesTestDescriptor { Setup = (w, s, tc) => { w.WriteStartBatch(); w.WriteStartChangeset(); if (tc.IsRequest) { return(GetOperationStream(w.CreateOperationRequestMessage("POST", new Uri("http://odata.org"), "2"), tc)); } else { return(GetOperationStream(w.CreateOperationResponseMessage(), tc)); } }, ExpectedResults = new Dictionary <BatchWriterAction, ExpectedException> { { BatchWriterAction.StartBatch, ODataExpectedExceptions.ODataException("ODataBatchWriter_InvalidTransitionFromOperationContentStreamRequested") }, { BatchWriterAction.EndBatch, ODataExpectedExceptions.ODataException("ODataBatchWriter_InvalidTransitionFromOperationContentStreamRequested") }, { BatchWriterAction.StartChangeset, ODataExpectedExceptions.ODataException("ODataBatchWriter_InvalidTransitionFromOperationContentStreamRequested") }, { BatchWriterAction.EndChangeset, ODataExpectedExceptions.ODataException("ODataBatchWriter_InvalidTransitionFromOperationContentStreamRequested") }, { BatchWriterAction.Operation, ODataExpectedExceptions.ODataException("ODataBatchWriter_InvalidTransitionFromOperationContentStreamRequested") }, { BatchWriterAction.GetOperationStream, ODataExpectedExceptions.ODataException("ODataBatchOperationMessage_VerifyNotCompleted") }, { BatchWriterAction.DisposeOperationStream, null }, }, ReadOperationReady = false }, // OperationStreamDisposed - Update new BatchWriterStatesTestDescriptor { Setup = (w, s, tc) => { w.WriteStartBatch(); w.WriteStartChangeset(); BatchWriterStatesTestSetupResult result; if (tc.IsRequest) { result = GetOperationStream(w.CreateOperationRequestMessage("POST", new Uri("http://odata.org"), "3"), tc); } else { result = GetOperationStream(w.CreateOperationResponseMessage(), tc); } result.MessageStream.Dispose(); return(result); }, ExpectedResults = new Dictionary <BatchWriterAction, ExpectedException> { { BatchWriterAction.StartBatch, ODataExpectedExceptions.ODataException("ODataBatchWriter_InvalidTransitionFromOperationContentStreamDisposed") }, { BatchWriterAction.EndBatch, ODataExpectedExceptions.ODataException("ODataBatchWriter_CannotCompleteBatchWithActiveChangeSet") }, { BatchWriterAction.StartChangeset, ODataExpectedExceptions.ODataException("ODataBatchWriter_CannotStartChangeSetWithActiveChangeSet") }, { BatchWriterAction.EndChangeset, null }, { BatchWriterAction.Operation, null }, { BatchWriterAction.GetOperationStream, ODataExpectedExceptions.ODataException("ODataBatchOperationMessage_VerifyNotCompleted") }, // Calling IDisposable.Dispose should not throw. { BatchWriterAction.DisposeOperationStream, null }, }, ReadOperationReady = false }, // ChangeSetCompleted new BatchWriterStatesTestDescriptor { Setup = (w, s, tc) => { w.WriteStartBatch(); w.WriteStartChangeset(); w.WriteEndChangeset(); return(null); }, ExpectedResults = new Dictionary <BatchWriterAction, ExpectedException> { { BatchWriterAction.StartBatch, ODataExpectedExceptions.ODataException("ODataBatchWriter_InvalidTransitionFromChangeSetCompleted") }, { BatchWriterAction.EndBatch, null }, { BatchWriterAction.StartChangeset, null }, { BatchWriterAction.EndChangeset, ODataExpectedExceptions.ODataException("ODataBatchWriter_CannotCompleteChangeSetWithoutActiveChangeSet") }, { BatchWriterAction.Operation, null }, { BatchWriterAction.GetOperationStream, null }, { BatchWriterAction.DisposeOperationStream, null }, }, ReadOperationReady = true }, // BatchCompleted new BatchWriterStatesTestDescriptor { Setup = (w, s, tc) => { w.WriteStartBatch(); w.WriteEndBatch(); return(null); }, ExpectedResults = new Dictionary <BatchWriterAction, ExpectedException> { { BatchWriterAction.StartBatch, ODataExpectedExceptions.ODataException("ODataBatchWriter_InvalidTransitionFromBatchCompleted") }, { BatchWriterAction.EndBatch, ODataExpectedExceptions.ODataException("ODataBatchWriter_InvalidTransitionFromBatchCompleted") }, { BatchWriterAction.StartChangeset, ODataExpectedExceptions.ODataException("ODataBatchWriter_InvalidTransitionFromBatchCompleted") }, { BatchWriterAction.EndChangeset, ODataExpectedExceptions.ODataException("ODataBatchWriter_CannotCompleteChangeSetWithoutActiveChangeSet") }, { BatchWriterAction.Operation, ODataExpectedExceptions.ODataException("ODataBatchWriter_InvalidTransitionFromBatchCompleted") }, { BatchWriterAction.GetOperationStream, null }, { BatchWriterAction.DisposeOperationStream, null }, }, ReadOperationReady = true }, // FatalExceptionThrown new BatchWriterStatesTestDescriptor { Setup = (w, s, tc) => { s.FailNextCall = true; w.WriteStartBatch(); if (tc.IsRequest) { w.CreateOperationRequestMessage("GET", new Uri("http://odata.org")); } else { w.CreateOperationResponseMessage(); } TestExceptionUtils.RunCatching(() => w.Flush()); return(null); }, ExpectedResults = new Dictionary <BatchWriterAction, ExpectedException> { { BatchWriterAction.StartBatch, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidTransitionFromError", "Error", "BatchStarted") }, { BatchWriterAction.EndBatch, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidTransitionFromError", "Error", "BatchCompleted") }, { BatchWriterAction.StartChangeset, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidTransitionFromError", "Error", "ChangeSetStarted") }, { BatchWriterAction.EndChangeset, ODataExpectedExceptions.ODataException("ODataBatchWriter_CannotCompleteChangeSetWithoutActiveChangeSet") }, { BatchWriterAction.Operation, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidTransitionFromError", "Error", "OperationCreated") }, { BatchWriterAction.GetOperationStream, null }, { BatchWriterAction.DisposeOperationStream, null }, }, ReadOperationReady = true }, }; this.CombinatorialEngineProvider.RunCombinations( testCases, EnumExtensionMethods.GetValues <BatchWriterAction>().Cast <BatchWriterAction>(), this.WriterTestConfigurationProvider.DefaultFormatConfigurations, (testCase, writerAction, testConfiguration) => { using (TestStream stream = new TestStream()) { // We purposely don't use the using pattern around the messageWriter here. Disposing the message writer will // fail here because the writer is not left in a valid state. var messageWriter = TestWriterUtils.CreateMessageWriter(stream, testConfiguration, this.Assert); ODataBatchWriterTestWrapper writer = messageWriter.CreateODataBatchWriter(); BatchWriterStatesTestSetupResult setupResult = null; if (testCase.Setup != null) { setupResult = testCase.Setup(writer, stream, testConfiguration); } ExpectedException expectedException = testCase.ExpectedResults[writerAction]; TestExceptionUtils.ExpectedException( this.Assert, () => InvokeBatchWriterAction(writer, writerAction, testConfiguration, testCase.ReadOperationReady, setupResult), expectedException, this.ExceptionVerifier); } }); }
public void ExpandedLinkWithMultiplicityTests() { ODataNavigationLink expandedEntryLink = ObjectModelUtils.CreateDefaultCollectionLink(); expandedEntryLink.IsCollection = false; ODataNavigationLink expandedFeedLink = ObjectModelUtils.CreateDefaultCollectionLink(); expandedFeedLink.IsCollection = true; ODataEntry defaultEntry = ObjectModelUtils.CreateDefaultEntry(); ODataFeed defaultFeed = ObjectModelUtils.CreateDefaultFeed(); ODataEntityReferenceLink defaultEntityReferenceLink = ObjectModelUtils.CreateDefaultEntityReferenceLink(); ODataEntry officeEntry = ObjectModelUtils.CreateDefaultEntry("TestModel.OfficeType"); ODataEntry officeWithNumberEntry = ObjectModelUtils.CreateDefaultEntry("TestModel.OfficeWithNumberType"); ODataEntry cityEntry = ObjectModelUtils.CreateDefaultEntry("TestModel.CityType"); // CityHall is a nav prop with multiplicity '*' of type 'TestModel.OfficeType' ODataNavigationLink cityHallLinkIsCollectionNull = ObjectModelUtils.CreateDefaultCollectionLink("CityHall", /*isCollection*/ null); ODataNavigationLink cityHallLinkIsCollectionTrue = ObjectModelUtils.CreateDefaultCollectionLink("CityHall", /*isCollection*/ true); ODataNavigationLink cityHallLinkIsCollectionFalse = ObjectModelUtils.CreateDefaultCollectionLink("CityHall", /*isCollection*/ false); // PoliceStation is a nav prop with multiplicity '1' of type 'TestModel.OfficeType' ODataNavigationLink policeStationLinkIsCollectionNull = ObjectModelUtils.CreateDefaultCollectionLink("PoliceStation", /*isCollection*/ null); ODataNavigationLink policeStationLinkIsCollectionTrue = ObjectModelUtils.CreateDefaultCollectionLink("PoliceStation", /*isCollection*/ true); ODataNavigationLink policeStationLinkIsCollectionFalse = ObjectModelUtils.CreateDefaultCollectionLink("PoliceStation", /*isCollection*/ false); ExpectedException expandedEntryLinkWithFeedContentError = ODataExpectedExceptions.ODataException("WriterValidationUtils_ExpandedLinkIsCollectionFalseWithFeedContent", "http://odata.org/link"); ExpectedException expandedFeedLinkWithEntryContentError = ODataExpectedExceptions.ODataException("WriterValidationUtils_ExpandedLinkIsCollectionTrueWithEntryContent", "http://odata.org/link"); ExpectedException expandedFeedLinkWithEntryMetadataError = ODataExpectedExceptions.ODataException("WriterValidationUtils_ExpandedLinkIsCollectionTrueWithEntryMetadata", "http://odata.org/link"); ExpectedException expandedEntryLinkWithFeedMetadataErrorResponse = ODataExpectedExceptions.ODataException("WriterValidationUtils_ExpandedLinkIsCollectionFalseWithFeedMetadata", "http://odata.org/link"); ExpectedException expandedFeedLinkPayloadWithEntryMetadataErrorRequest = ODataExpectedExceptions.ODataException("WriterValidationUtils_ExpandedLinkWithFeedPayloadAndEntryMetadata", "http://odata.org/link"); ExpectedException expandedFeedLinkPayloadWithEntryMetadataErrorResponse = ODataExpectedExceptions.ODataException("WriterValidationUtils_ExpandedLinkIsCollectionTrueWithEntryMetadata", "http://odata.org/link"); ExpectedException expandedEntryLinkPayloadWithFeedMetadataErrorResponse = ODataExpectedExceptions.ODataException("WriterValidationUtils_ExpandedLinkIsCollectionFalseWithFeedMetadata", "http://odata.org/link"); ExpectedException expandedEntryLinkPayloadWithFeedMetadataError = ODataExpectedExceptions.ODataException("WriterValidationUtils_ExpandedLinkWithEntryPayloadAndFeedMetadata", "http://odata.org/link"); ExpectedException multipleItemsInExpandedLinkError = ODataExpectedExceptions.ODataException("ODataWriterCore_MultipleItemsInNavigationLinkContent", "http://odata.org/link"); ExpectedException entityReferenceLinkInResponseError = ODataExpectedExceptions.ODataException("ODataWriterCore_EntityReferenceLinkInResponse"); IEdmModel model = Microsoft.Test.OData.Utils.Metadata.TestModels.BuildTestModel(); var testCases = new ExpandedLinkMultiplicityTestCase[] { #region IsCollection flag does not match payload new ExpandedLinkMultiplicityTestCase { // Expanded link with IsCollection is 'false' and feed payload Items = new ODataItem[] { defaultEntry, expandedEntryLink, defaultFeed }, ExpectedError = tc => expandedEntryLinkWithFeedContentError, }, new ExpandedLinkMultiplicityTestCase { // Expanded link with IsCollection is 'true' and entry payload Items = new ODataItem[] { defaultEntry, expandedFeedLink, defaultEntry }, ExpectedError = tc => expandedFeedLinkWithEntryContentError, }, #endregion IsCollection flag does not match payload #region IsCollection == null; check compatibility of entity types of navigation property and entity in expanded link new ExpandedLinkMultiplicityTestCase { // Expanded link of singleton type without IsCollection value and an entry of a non-matching entity type; Items = new ODataItem[] { cityEntry, policeStationLinkIsCollectionNull, cityEntry }, ExpectedError = tc => tc.Format == ODataFormat.Atom || !tc.IsRequest ? ODataExpectedExceptions.ODataException("WriterValidationUtils_EntryTypeInExpandedLinkNotCompatibleWithNavigationPropertyType", "TestModel.CityType", "TestModel.OfficeType") : ODataExpectedExceptions.ODataException("WriterValidationUtils_NavigationLinkMustSpecifyIsCollection", "PoliceStation"), Model = model, }, new ExpandedLinkMultiplicityTestCase { // Expanded link of singleton type without IsCollection value and an entry of a matching entity type; no error expected. Items = new ODataItem[] { cityEntry, policeStationLinkIsCollectionNull, officeEntry }, ExpectedError = tc => tc.Format == ODataFormat.Json && !tc.IsRequest ? null : ODataExpectedExceptions.ODataException("WriterValidationUtils_NavigationLinkMustSpecifyIsCollection", "PoliceStation"), Model = model, }, new ExpandedLinkMultiplicityTestCase { // Expanded link of singleton type without IsCollection and an entry of a derived entity type; no error expected. Items = new ODataItem[] { cityEntry, policeStationLinkIsCollectionNull, officeWithNumberEntry }, ExpectedError = tc => tc.Format == ODataFormat.Json && !tc.IsRequest ? null : ODataExpectedExceptions.ODataException("WriterValidationUtils_NavigationLinkMustSpecifyIsCollection", "PoliceStation"), Model = model, }, new ExpandedLinkMultiplicityTestCase { // Expanded link of collection type without IsCollection value and an entry of a non-matching entity type; Items = new ODataItem[] { cityEntry, cityHallLinkIsCollectionNull, defaultFeed, cityEntry }, ExpectedError = tc => tc.Format == ODataFormat.Json && !tc.IsRequest ? ODataExpectedExceptions.ODataException("WriterValidationUtils_EntryTypeInExpandedLinkNotCompatibleWithNavigationPropertyType", "TestModel.CityType", "TestModel.OfficeType") : ODataExpectedExceptions.ODataException("WriterValidationUtils_NavigationLinkMustSpecifyIsCollection", "CityHall"), Model = model, }, new ExpandedLinkMultiplicityTestCase { // Expanded link of collection type without IsCollection value and an entry of a matching entity type; no error expected. Items = new ODataItem[] { cityEntry, cityHallLinkIsCollectionNull, defaultFeed, officeEntry }, ExpectedError = tc => tc.Format == ODataFormat.Json && !tc.IsRequest ? null : ODataExpectedExceptions.ODataException("WriterValidationUtils_NavigationLinkMustSpecifyIsCollection", "CityHall"), Model = model, }, new ExpandedLinkMultiplicityTestCase { // Expanded link of collection type without IsCollection and an entry of a derived entity type; no error expected. Items = new ODataItem[] { cityEntry, cityHallLinkIsCollectionNull, defaultFeed, officeWithNumberEntry }, ExpectedError = tc => tc.Format == ODataFormat.Json && !tc.IsRequest ? null : ODataExpectedExceptions.ODataException("WriterValidationUtils_NavigationLinkMustSpecifyIsCollection", "CityHall"), Model = model, }, #endregion IsCollection == null; check compatibility of entity types of navigation property and entity in expanded link #region Expanded link with entry content new ExpandedLinkMultiplicityTestCase { // Entry content, IsCollection == false, singleton nav prop; should not fail. Items = new ODataItem[] { cityEntry, policeStationLinkIsCollectionFalse, officeEntry }, }, new ExpandedLinkMultiplicityTestCase { // Entry content, IsCollection == true, singleton nav prop; should fail. Items = new ODataItem[] { cityEntry, policeStationLinkIsCollectionTrue, officeEntry }, ExpectedError = tc => expandedFeedLinkWithEntryContentError, }, new ExpandedLinkMultiplicityTestCase { // Entry content, IsCollection == false, collection nav prop; should fail. Items = new ODataItem[] { cityEntry, cityHallLinkIsCollectionFalse, officeEntry }, ExpectedError = tc => tc.IsRequest ? expandedEntryLinkPayloadWithFeedMetadataError : expandedEntryLinkPayloadWithFeedMetadataErrorResponse, Model = model }, new ExpandedLinkMultiplicityTestCase { // Entry content, IsCollection == true, collection nav prop; should fail. Items = new ODataItem[] { cityEntry, cityHallLinkIsCollectionTrue, officeEntry }, ExpectedError = tc => expandedFeedLinkWithEntryContentError, Model = model }, new ExpandedLinkMultiplicityTestCase { // Entry content, IsCollection == null, singleton nav prop; should not fail. Items = new ODataItem[] { cityEntry, policeStationLinkIsCollectionNull, officeEntry }, ExpectedError = tc => tc.IsRequest || tc.Format == ODataFormat.Atom ? ODataExpectedExceptions.ODataException("WriterValidationUtils_NavigationLinkMustSpecifyIsCollection", "PoliceStation") : null, Model = model, }, new ExpandedLinkMultiplicityTestCase { // Entry content, IsCollection == null, collection nav prop; should fail. Items = new ODataItem[] { cityEntry, cityHallLinkIsCollectionNull, officeEntry }, ExpectedError = tc => expandedEntryLinkPayloadWithFeedMetadataError, Model = model, }, #endregion Expanded collection link with entry content #region Expanded link with feed content new ExpandedLinkMultiplicityTestCase { // Feed content, IsCollection == false, singleton nav prop; should fail. Items = new ODataItem[] { cityEntry, policeStationLinkIsCollectionFalse, defaultFeed, officeEntry }, ExpectedError = tc => expandedEntryLinkWithFeedContentError, }, new ExpandedLinkMultiplicityTestCase { // Feed content, IsCollection == true, singleton nav prop; should fail. Items = new ODataItem[] { cityEntry, policeStationLinkIsCollectionTrue, defaultFeed, officeEntry }, ExpectedError = tc => tc.IsRequest ? expandedFeedLinkPayloadWithEntryMetadataErrorRequest : expandedFeedLinkPayloadWithEntryMetadataErrorResponse, Model = model }, new ExpandedLinkMultiplicityTestCase { // Feed content, IsCollection == false, collection nav prop; should fail. Items = new ODataItem[] { cityEntry, cityHallLinkIsCollectionFalse, defaultFeed, officeEntry }, ExpectedError = tc => tc.IsRequest ? expandedEntryLinkWithFeedContentError : expandedEntryLinkWithFeedMetadataErrorResponse, Model = model }, new ExpandedLinkMultiplicityTestCase { // Feed content, IsCollection == true, collection nav prop; should not fail. Items = new ODataItem[] { cityEntry, cityHallLinkIsCollectionTrue, defaultFeed, officeEntry }, Model = model }, new ExpandedLinkMultiplicityTestCase { // Feed content, IsCollection == null, singleton nav prop; should fail. Items = new ODataItem[] { cityEntry, policeStationLinkIsCollectionNull, defaultFeed, officeEntry }, ExpectedError = tc => expandedFeedLinkPayloadWithEntryMetadataErrorRequest, Model = model, }, new ExpandedLinkMultiplicityTestCase { // Feed content, IsCollection == null, collection nav prop; should not fail. Items = new ODataItem[] { cityEntry, cityHallLinkIsCollectionNull, defaultFeed, officeEntry }, ExpectedError = tc => tc.IsRequest || tc.Format == ODataFormat.Atom ? ODataExpectedExceptions.ODataException("WriterValidationUtils_NavigationLinkMustSpecifyIsCollection", "CityHall") : null, Model = model, }, #endregion Expanded collection link with entry content #region Expanded link with entity reference link content new ExpandedLinkMultiplicityTestCase { // Single ERL (entity reference link) content, IsCollection == false, singleton nav prop; should not fail. Items = new ODataItem[] { cityEntry, policeStationLinkIsCollectionFalse, defaultEntityReferenceLink }, ExpectedError = tc => tc.IsRequest ? null : entityReferenceLinkInResponseError }, new ExpandedLinkMultiplicityTestCase { // Multiple ERL (entity reference link) content, IsCollection == false, singleton nav prop; should not fail. Items = new ODataItem[] { cityEntry, policeStationLinkIsCollectionFalse, defaultEntityReferenceLink, defaultEntityReferenceLink }, ExpectedError = tc => tc.IsRequest ? multipleItemsInExpandedLinkError : entityReferenceLinkInResponseError, }, new ExpandedLinkMultiplicityTestCase { // Single ERL content, IsCollection == true, singleton nav prop; should fail. Items = new ODataItem[] { cityEntry, policeStationLinkIsCollectionTrue, defaultEntityReferenceLink }, ExpectedError = tc => expandedFeedLinkWithEntryMetadataError, Model = model, }, new ExpandedLinkMultiplicityTestCase { // Multiple ERL content, IsCollection == true, singleton nav prop; should fail. Items = new ODataItem[] { cityEntry, policeStationLinkIsCollectionTrue, defaultEntityReferenceLink, defaultEntityReferenceLink }, ExpectedError = tc => expandedFeedLinkWithEntryMetadataError, Model = model, }, new ExpandedLinkMultiplicityTestCase { // Single ERL content, IsCollection == false, collection nav prop; should not fail (metadata mismatch explicitly allowed). Items = new ODataItem[] { cityEntry, cityHallLinkIsCollectionFalse, defaultEntityReferenceLink }, ExpectedError = tc => tc.IsRequest ? null : expandedEntryLinkWithFeedMetadataErrorResponse, Model = model, }, new ExpandedLinkMultiplicityTestCase { // Multiple ERL content, IsCollection == false, collection nav prop; should fail. Items = new ODataItem[] { cityEntry, cityHallLinkIsCollectionFalse, defaultEntityReferenceLink, defaultEntityReferenceLink }, ExpectedError = tc => tc.IsRequest ? multipleItemsInExpandedLinkError : expandedEntryLinkWithFeedMetadataErrorResponse, Model = model, }, new ExpandedLinkMultiplicityTestCase { // Single ERL content, IsCollection == true, collection nav prop; should not fail. Items = new ODataItem[] { cityEntry, cityHallLinkIsCollectionTrue, defaultEntityReferenceLink }, ExpectedError = tc => tc.IsRequest ? null : entityReferenceLinkInResponseError, Model = model, }, new ExpandedLinkMultiplicityTestCase { // Multiple ERL content, IsCollection == true, collection nav prop; should not fail. Items = new ODataItem[] { cityEntry, cityHallLinkIsCollectionTrue, defaultEntityReferenceLink, defaultEntityReferenceLink }, ExpectedError = tc => tc.IsRequest ? null : entityReferenceLinkInResponseError, Model = model, }, //// NOTE: Not testing the cases where IsCollection == null here since ERL payloads are only allowed in //// requests where IsCollection is required (in ATOM and JSON) #endregion Expanded link with entity reference link content }; // TODO: Fix places where we've lost JsonVerbose coverage to add JsonLight this.CombinatorialEngineProvider.RunCombinations( testCases, this.WriterTestConfigurationProvider.ExplicitFormatConfigurations.Where(tc => tc.Format == ODataFormat.Atom), (testCase, testConfiguration) => { testConfiguration = testConfiguration.Clone(); testConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri); using (var memoryStream = new TestStream()) using (var messageWriter = TestWriterUtils.CreateMessageWriter(memoryStream, testConfiguration, this.Assert, null, testCase.Model)) { ODataWriter writer = messageWriter.CreateODataWriter(isFeed: false); TestExceptionUtils.ExpectedException( this.Assert, () => TestWriterUtils.WritePayload(messageWriter, writer, true, testCase.Items), testCase.ExpectedError == null ? null : testCase.ExpectedError(testConfiguration), this.ExceptionVerifier); } }); }
public void DisposeAfterExceptionTest() { // create a default entry and then set both read and edit links to null to provoke an exception during writing ODataResource entry = ObjectModelUtils.CreateDefaultEntry(); this.Assert.IsNull(entry.EditLink, "entry.EditLink == null"); this.CombinatorialEngineProvider.RunCombinations( new ODataItem[] { entry }, new bool[] { true, false }, // writeError new bool[] { true, false }, // flush this.WriterTestConfigurationProvider.ExplicitFormatConfigurations.Where(c => c.IsRequest == false), (payload, writeError, flush, testConfiguration) => { testConfiguration = testConfiguration.Clone(); testConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri); // try writing to a memory stream using (var memoryStream = new TestStream()) using (var messageWriter = TestWriterUtils.CreateMessageWriter(memoryStream, testConfiguration, this.Assert)) { ODataWriter writer = messageWriter.CreateODataWriter(isFeed: false); ODataWriterCoreInspector inspector = new ODataWriterCoreInspector(writer); try { // write the invalid entry and expect an exception TestExceptionUtils.ExpectedException( this.Assert, () => TestWriterUtils.WritePayload(messageWriter, writer, false, entry), ODataExpectedExceptions.ODataException("WriterValidationUtils_EntriesMustHaveNonEmptyId"), this.ExceptionVerifier); this.Assert.IsTrue(inspector.IsInErrorState, "Writer is not in expected 'error' state."); if (writeError) { // now write an error which is the only valid thing to do ODataAnnotatedError error = new ODataAnnotatedError { Error = new ODataError() { Message = "DisposeAfterExceptionTest error message." } }; Exception ex = TestExceptionUtils.RunCatching(() => TestWriterUtils.WritePayload(messageWriter, writer, false, error)); this.Assert.IsNull(ex, "Unexpected error '" + (ex == null ? "<none>" : ex.Message) + "' while writing an error."); this.Assert.IsTrue(inspector.IsInErrorState, "Writer is not in expected 'error' state."); } if (flush) { writer.Flush(); } } catch (ODataException oe) { if (writeError && !flush) { this.Assert.AreEqual("A writer or stream has been disposed with data still in the buffer. You must call Flush or FlushAsync before calling Dispose when some data has already been written.", oe.Message, "Did not find expected error message"); this.Assert.IsTrue(inspector.IsInErrorState, "Writer is not in expected 'error' state."); } else { this.Assert.Fail("Caught an unexpected ODataException: " + oe.Message + "."); } } } }); }
public void FeedAndEntryUpdatedTimeTests() { ODataFeed defaultFeedWithEmptyMetadata = ObjectModelUtils.CreateDefaultFeed(); defaultFeedWithEmptyMetadata.SetAnnotation <AtomFeedMetadata>(new AtomFeedMetadata()); ODataEntry defaultEntryWithEmptyMetadata = ObjectModelUtils.CreateDefaultEntry(); defaultEntryWithEmptyMetadata.SetAnnotation <AtomEntryMetadata>(new AtomEntryMetadata()); IEnumerable <PayloadWriterTestDescriptor <ODataItem> > testPayloads = new[] { new PayloadWriterTestDescriptor <ODataItem>(this.Settings, ObjectModelUtils.CreateDefaultFeed()), new PayloadWriterTestDescriptor <ODataItem>(this.Settings, defaultFeedWithEmptyMetadata), new PayloadWriterTestDescriptor <ODataItem>(this.Settings, ObjectModelUtils.CreateDefaultFeedWithAtomMetadata()), }.PayloadCases(WriterPayloads.FeedPayloads) .Concat((new[] { new PayloadWriterTestDescriptor <ODataItem>(this.Settings, ObjectModelUtils.CreateDefaultEntry()), new PayloadWriterTestDescriptor <ODataItem>(this.Settings, defaultEntryWithEmptyMetadata), new PayloadWriterTestDescriptor <ODataItem>(this.Settings, ObjectModelUtils.CreateDefaultEntryWithAtomMetadata()), }.PayloadCases(WriterPayloads.EntryPayloads))); this.CombinatorialEngineProvider.RunCombinations( testPayloads, this.WriterTestConfigurationProvider.AtomFormatConfigurationsWithIndent.Where(tc => !tc.IsRequest), (testPayload, testConfiguration) => { testConfiguration = testConfiguration.Clone(); testConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri); string lastUpdatedTimeStr = null; using (var memoryStream = new MemoryStream()) { using (var testMemoryStream = TestWriterUtils.CreateTestStream(testConfiguration, memoryStream, ignoreDispose: true)) { bool feedWriter = testPayload.PayloadItems[0] is ODataFeed; TestMessage testMessage = null; Exception exception = TestExceptionUtils.RunCatching(() => { using (var messageWriter = TestWriterUtils.CreateMessageWriter(testMemoryStream, testConfiguration, this.Assert, out testMessage, null, testPayload.Model)) { ODataWriter writer = messageWriter.CreateODataWriter(feedWriter); TestWriterUtils.WritePayload(messageWriter, writer, true, testPayload.PayloadItems, testPayload.ThrowUserExceptionAt); } }); this.Assert.IsNull(exception, "Received exception but expected none."); } memoryStream.Position = 0; XElement result = XElement.Load(memoryStream); foreach (XElement updated in result.Descendants(((XNamespace)TestAtomConstants.AtomNamespace) + "updated")) { if (updated.Value != ObjectModelUtils.DefaultFeedUpdated && updated.Value != ObjectModelUtils.DefaultEntryUpdated) { if (lastUpdatedTimeStr == null) { lastUpdatedTimeStr = updated.Value; } else { this.Assert.AreEqual(lastUpdatedTimeStr, updated.Value, "<atom:updated> should contain the same value."); } } } } }); }