Beispiel #1
0
        public void GetVersionUtilTest()
        {
            //positive tests
            this.Assert.AreEqual(ODataUtils.StringToODataVersion(DataServiceVersion4), ODataVersion.V4,
                                 "Failed to parse Data Service Version string");

            this.Assert.AreEqual(ODataUtils.StringToODataVersion(DataServiceVersion4 + ";"), ODataVersion.V4,
                                 "Failed to parse Data Service Version string");

            this.Assert.AreEqual(ODataUtils.StringToODataVersion(DataServiceVersion4 + ";anything"), ODataVersion.V4,
                                 "Failed to parse Data Service Version string");

            this.Assert.AreEqual(ODataUtils.ODataVersionToString(ODataVersion.V4), DataServiceVersion4,
                                 "Failed to parse Data Service Version enum");

            //negative tests
            string[] invalidVersionStrings = { "randomstring", "V1.0", "1.5", "randomstring;1.0", "5.0", "1" };
            foreach (string s in invalidVersionStrings)
            {
                TestExceptionUtils.ExpectedException(
                    this.Assert,
                    () =>
                {
                    ODataUtils.StringToODataVersion(s);
                },
                    ODataExpectedExceptions.ODataException("ODataUtils_UnsupportedVersionHeader", s),
                    this.ExceptionVerifier
                    );
            }
        }
Beispiel #2
0
        /// <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;
            }
        }
        private void RunTestCase(ConvertToUriLiteralTestCase testCase, ODataVersion version = ODataVersion.V4, IEdmModel model = null)
        {
            // Negative Test
            if (testCase.ExpectedException != null)
            {
                TestExceptionUtils.ExpectedException(
                    this.Assert,
                    () =>
                {
                    ODataUriUtils.ConvertToUriLiteral(testCase.Parameter, version, model);
                },
                    testCase.ExpectedException,
                    this.ExceptionVerifier
                    );
            }
            else // Positive Test
            {
                string actualValue   = ODataUriUtils.ConvertToUriLiteral(testCase.Parameter, version, model);
                object expectedValue = testCase.ExpectedValues;
                if (expectedValue == null)
                {
                    expectedValue = testCase.ExpectedValue;
                }

                if (!expectedValue.Equals(actualValue))
                {
                    throw new ODataTestException(string.Format(
                                                     "Different JSON.{0}Expected:{0}{1}{0}Actual:{0}{2}{0}",
                                                     Environment.NewLine,
                                                     expectedValue,
                                                     actualValue));
                }
            }
        }
        /// <summary>
        /// Called to write the payload to the specified <paramref name="messageWriter"/>.
        /// </summary>
        /// <param name="messageWriter">The <see cref="ODataMessageWriterTestWrapper"/> to use for writing the payload.</param>
        /// <param name="testConfiguration">The test configuration to generate the payload for.</param>
        protected override void WritePayload(ODataMessageWriterTestWrapper messageWriter, WriterTestConfiguration testConfiguration)
        {
            Debug.Assert(this.messageStream != null, "Streaming test stream must have been created.");
            TestMessage testMessage = this.CreateInputMessageFromStream((TestStream)this.messageStream, testConfiguration, this.PayloadKind, string.Empty, this.UrlResolver);

            testMessage.SetContentType(testConfiguration.Format, this.PayloadKind);

            Exception exception = TestExceptionUtils.RunCatching(() =>
            {
                ODataMessageReaderSettings readerSettings  = this.settings.MessageReaderSettings.Clone();
                readerSettings.EnableMessageStreamDisposal = testConfiguration.MessageWriterSettings.EnableMessageStreamDisposal;

                ReaderTestConfiguration readerConfig = new ReaderTestConfiguration(
                    testConfiguration.Format,
                    readerSettings,
                    testConfiguration.IsRequest,
                    testConfiguration.Synchronous);

                IEdmModel model = this.GetMetadataProvider();
                using (ODataMessageReaderTestWrapper messageReaderWrapper = TestReaderUtils.CreateMessageReader(testMessage, model, readerConfig))
                {
                    ODataPayloadElementToObjectModelConverter payloadElementToOMConverter = new ODataPayloadElementToObjectModelConverter(!testConfiguration.IsRequest);
                    ObjectModelToPayloadElementConverter reverseConverter = new ObjectModelToPayloadElementConverter();
                    ObjectModelWriteReadStreamer streamer = new ObjectModelWriteReadStreamer();

                    this.readObject = reverseConverter.Convert(streamer.WriteMessage(messageWriter, messageReaderWrapper, this.PayloadKind, payloadElementToOMConverter.Convert(this.PayloadElement)), !testConfiguration.IsRequest);
                }
            });
        }
Beispiel #5
0
        /// <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);
                }
        }
        /// <summary>
        /// Runs the test case.
        /// </summary>
        public override void Run()
        {
            BatchReaderStreamBufferWrapper  streamBuffer   = new BatchReaderStreamBufferWrapper();
            MemoryStreamBatchPayloadBuilder payloadBuilder = new MemoryStreamBatchPayloadBuilder(this.Encoding, this.LineFeedChars);

            // If no explicit payload func was specified, use a default payload
            MemoryStream memoryStream;

            if (this.PayloadFunc == null)
            {
                memoryStream = payloadBuilder.FillBytes(BatchReaderStreamBufferWrapper.BufferLength).ResetMemoryStream();
            }
            else
            {
                memoryStream = this.PayloadFunc(payloadBuilder);
            }

            // Create a message reader and then a batch reader for the message
            using (ODataMessageReader messageReader = this.CreateMessageReader(memoryStream))
            {
                ODataBatchReader         batchReader   = messageReader.CreateODataBatchReader();
                BatchReaderStreamWrapper streamWrapper = new BatchReaderStreamWrapper(batchReader);

                Exception exception = TestExceptionUtils.RunCatching(() =>
                {
                    this.RunTestAction(streamWrapper);
                });

                this.VerifyException(exception);
            }
        }
        public void ContentTypeHeaderParsingErrorTest()
        {
            var testCases = new ContentTypeTestCase[]
            {
                new ContentTypeTestCase
                {
                    ContentType       = null,
                    ExpectedException = ODataExpectedExceptions.ODataContentTypeException("ODataMessageReader_NoneOrEmptyContentTypeHeader")
                },
                new ContentTypeTestCase
                {
                    ContentType       = string.Empty,
                    ExpectedException = ODataExpectedExceptions.ODataContentTypeException("ODataMessageReader_NoneOrEmptyContentTypeHeader")
                },
                new ContentTypeTestCase
                {
                    ContentType       = ";foo=bar",
                    ExpectedException = ODataExpectedExceptions.ODataContentTypeException("HttpUtils_MediaTypeRequiresSlash", ";foo=bar")
                },
                new ContentTypeTestCase
                {
                    ContentType       = "application/*",
                    ExpectedException = ODataExpectedExceptions.ODataContentTypeException("ODataMessageReader_WildcardInContentType", "application/*")
                },
                new ContentTypeTestCase
                {
                    ContentType       = "*/*",
                    ExpectedException = ODataExpectedExceptions.ODataContentTypeException("ODataMessageReader_WildcardInContentType", "*/*")
                },
                new ContentTypeTestCase
                {
                    ContentType       = "application/json, application/xml",
                    ExpectedException = ODataExpectedExceptions.ODataContentTypeException("MediaTypeUtils_NoOrMoreThanOneContentTypeSpecified", "application/json, application/xml")
                },
            };

            this.CombinatorialEngineProvider.RunCombinations(
                testCases,
                this.ReaderTestConfigurationProvider.AllFormatConfigurations.Where(tc => tc.Format != ODataFormat.Json),
                (testCase, testConfiguration) =>
            {
                // create a message reader and call GetFormat; this should fail with the expected error message
                TestMessage testMessage = TestReaderUtils.CreateInputMessageFromStream(new TestStream(), testConfiguration);
                testMessage.SetHeader(Microsoft.OData.Core.ODataConstants.ContentTypeHeader, testCase.ContentType);
                testMessage.SetHeader(Microsoft.OData.Core.ODataConstants.ContentLengthHeader, testCase.ContentLength.ToString());

                TestExceptionUtils.ExpectedException(
                    this.Assert,
                    () =>
                {
                    using (ODataMessageReaderTestWrapper messageReader = TestReaderUtils.CreateMessageReader(testMessage, null, testConfiguration))
                    {
                        ODataFormat actualFormat = messageReader.DetectPayloadKind().Single().Format;
                    }
                },
                    testCase.ExpectedException,
                    this.ExceptionVerifier);
            });
        }
Beispiel #8
0
        /// <summary>
        /// Runs a single BufferingJsonReaderTestCaseDescriptor test with a single toggle index in it
        /// and verifies that the reader state after turning off buffering is correct.
        /// </summary>
        /// <param name="testCase">The test case descriptor to run.</param>
        /// <param name="assert"></param>
        public static void ReadAndVerifyStateAfterStopBuffering(BufferingJsonReaderTestCaseDescriptor testCase, AssertionHandler assert)
        {
            assert.AreEqual(2, testCase.ToggleBufferingCallCounts.Length, "Expected a single toggle position.");

            TextReader testReader = new StringReader(testCase.JsonText);
            Exception  exception  = TestExceptionUtils.RunCatching(() =>
            {
                BufferingJsonReader bufferingJsonReader = new BufferingJsonReader(testReader, ODataConstants.DefaultMaxRecursionDepth, assert, isIeee754Compatible: true);

                int callCount      = -1;
                int startBuffering = testCase.ToggleBufferingCallCounts[0];
                int stopBuffering  = testCase.ToggleBufferingCallCounts[1];
                bool isBuffering   = false;

                List <BufferingJsonReaderTestCaseDescriptor.ReaderNode> bufferedNodes = new List <BufferingJsonReaderTestCaseDescriptor.ReaderNode>();

                bool hasMore = false;
                do
                {
                    callCount++;

                    if (startBuffering == callCount)
                    {
                        BufferingJsonReaderTestCaseDescriptor.ReaderNode bufferedNode = new BufferingJsonReaderTestCaseDescriptor.ReaderNode(bufferingJsonReader.NodeType, bufferingJsonReader.Value);
                        bufferedNodes.Add(bufferedNode);

                        bufferingJsonReader.StartBuffering();
                        isBuffering = true;
                    }

                    if (stopBuffering == callCount)
                    {
                        bufferingJsonReader.StopBuffering();
                        isBuffering = false;

                        assert.AreEqual(bufferedNodes[0].NodeType, bufferingJsonReader.NodeType, "Node types must be equal.");
                        assert.AreEqual(bufferedNodes[0].Value, bufferingJsonReader.Value, "Values must be equal.");
                        bufferedNodes.RemoveAt(0);
                    }

                    hasMore = bufferingJsonReader.Read();
                    if (isBuffering)
                    {
                        bufferedNodes.Add(new BufferingJsonReaderTestCaseDescriptor.ReaderNode(bufferingJsonReader.NodeType, bufferingJsonReader.Value));
                    }
                    else if (bufferedNodes.Count > 0)
                    {
                        assert.AreEqual(bufferedNodes[0].NodeType, bufferingJsonReader.NodeType, "Node types must be equal.");
                        assert.AreEqual(bufferedNodes[0].Value, bufferingJsonReader.Value, "Values must be equal.");
                        bufferedNodes.RemoveAt(0);
                    }
                }while (hasMore);
            });

            assert.IsNull(exception, "Did not expect an exception.");
        }
Beispiel #9
0
        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;
            }
        }
Beispiel #10
0
        /// <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);
                }
            }
        }
Beispiel #11
0
        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.
                    }
            });
        }
Beispiel #12
0
 /// <summary>
 /// Verifies that the test correctly threw an exception.
 /// </summary>
 /// <param name="exception">null if the test didn't throw, the exception thrown by the test otherwise.</param>
 public virtual void VerifyException(Exception exception)
 {
     exception = TestExceptionUtils.UnwrapAggregateException(exception, this.settings.Assert);
     if (this.ExpectedException != null)
     {
         this.settings.Assert.IsNotNull(exception,
                                        "Expected exception of type '{0}' with message resource ID '{1}' but none was thrown.",
                                        this.ExpectedException.ExpectedExceptionType.ToString(),
                                        this.ExpectedException.ExpectedMessage == null ? "<null>" : this.ExpectedException.ExpectedMessage.ResourceIdentifier);
         this.settings.ExceptionVerifier.VerifyExceptionResult(this.ExpectedException, exception);
     }
     else
     {
         this.settings.Assert.IsNull(exception, "Unexpected exception was thrown: {0}", (exception == null) ? string.Empty : exception.ToString());
     }
 }
Beispiel #13
0
        private FilterClause BindFilter(IEdmModel model, string filter, string errorMessage)
        {
            FilterClause actualFilter = null;

            TestExceptionUtils.ExpectedException <ODataException>(
                this.Assert,
                () =>
            {
                string query    = "/TypesWithPrimitiveProperties?$filter=" + filter;
                ODataUri actual = QueryNodeUtils.BindQuery(query, model);

                // the filter node should be the top-level node in the query tree
                actualFilter = (FilterClause)actual.Filter;
            },
                errorMessage,
                null);
            return(actualFilter);
        }
Beispiel #14
0
        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);
                    }
                }
            });
        }
Beispiel #15
0
        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();
                    }
            });
        }
Beispiel #16
0
        /// <summary>
        /// Verifies that the test correctly threw an exception.
        /// </summary>
        /// <param name="exception">null if the test didn't throw, the exception thrown by the test otherwise.</param>
        public virtual void VerifyException(Exception exception)
        {
            exception = TestExceptionUtils.UnwrapAggregateException(exception, this.settings.Assert);

            if (this.ExpectedException2 != null)
            {
                this.settings.ExceptionVerifier.VerifyExceptionResult(this.ExpectedException2, exception);
            }
            else if (this.ExpectedException != null)
            {
                this.settings.Assert.IsExpectedException <Exception>(exception, this.ExpectedException.Message);
            }
            else if (this.ExpectedODataErrorException != null)
            {
                this.settings.Assert.IsExpectedException <ODataErrorException>(exception, this.ExpectedODataErrorException.Message);
                this.settings.Assert.IsTrue(ODataObjectModelValidationUtils.AreEqual(this.ExpectedODataErrorException.Error, ((ODataErrorException)exception).Error), "Expected ODataError instances to be equal.");
            }
            else
            {
                this.settings.Assert.IsExpectedException <ODataException>(exception, this.ExpectedODataExceptionMessage);
            }
        }
        /// <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;
            }
        }
Beispiel #18
0
        public void SyncAsyncMismatchTest()
        {
            var model = new EdmModel();
            var payloadDescriptors = Test.OData.Utils.ODataLibTest.TestFeeds.GetFeeds(model, true /*withTypeNames*/);
            var testDescriptors    = this.PayloadDescriptorsToReaderDescriptors(payloadDescriptors);

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                this.ReaderTestConfigurationProvider.ExplicitFormatConfigurations,
                (testDescriptor, testConfiguration) =>
            {
                var message = TestReaderUtils.CreateInputMessage(testConfiguration, testDescriptor, this.Settings, false);
                message.IgnoreSynchronousError            = true;
                message.TestStream.IgnoreSynchronousError = true;

                Exception exception = TestExceptionUtils.RunCatching(() =>
                {
                    using (ODataMessageReaderTestWrapper messageReaderWrapper = TestReaderUtils.CreateMessageReader(message, model, testConfiguration))
                    {
                        var feedReader = messageReaderWrapper.MessageReader.CreateODataResourceSetReader(model.EntityContainer.FindEntitySet("MyBaseType"), model.EntityTypes().FirstOrDefault());
                        if (testConfiguration.Synchronous)
                        {
                            feedReader.Read();
                            feedReader.ReadAsync();
                        }
                        else
                        {
                            feedReader.ReadAsync();
                            feedReader.Read();
                        }
                    }
                });

                var expected = ODataExpectedExceptions.ODataException("ODataReaderCore_AsyncCallOnSyncReader");
                ExceptionVerifier.VerifyExceptionResult(expected, exception);
            });
        }
        /// <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;
            }
        }
Beispiel #20
0
        /// <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 case.
        /// </summary>
        public override void Run()
        {
            BatchReaderStreamBufferWrapper  streamBuffer   = new BatchReaderStreamBufferWrapper();
            MemoryStreamBatchPayloadBuilder payloadBuilder = new MemoryStreamBatchPayloadBuilder(this.Encoding, this.LineFeedChars);

            // If no explicit payload func was specified, use a default payload
            MemoryStream memoryStream;

            if (this.PayloadFunc == null)
            {
                memoryStream = payloadBuilder.FillBytes(BatchReaderStreamBufferWrapper.BufferLength).ResetMemoryStream();
            }
            else
            {
                memoryStream = this.PayloadFunc(payloadBuilder);
            }

            Exception exception = TestExceptionUtils.RunCatching(() =>
            {
                this.RunTestAction(streamBuffer, memoryStream);
            });

            this.VerifyException(exception);
        }
Beispiel #22
0
        private static void RunHeaderTest(
            Func <IEnumerable <KeyValuePair <string, string> > > getHeadersFunc,
            bool writing,
            Func <string, string> getHeaderFunc,
            Action <string, string> setHeaderAction,
            AssertionHandler assert,
            IExceptionVerifier exceptionVerifier)
        {
            assert.IsNotNull(getHeadersFunc(), "Non-null headers expected.");
            assert.AreEqual(0, getHeadersFunc().Count(), "Empty header collection expected.");
            assert.IsNull(getHeaderFunc("a"), "Unexpectedly found header.");

            ExpectedException expectedException = writing ? null : ODataExpectedExceptions.ODataException("ODataMessage_MustNotModifyMessage");

            TestExceptionUtils.ExpectedException(
                assert,
                () =>
            {
                setHeaderAction("a", "b");

                assert.AreEqual(1, getHeadersFunc().Count(), "One header expected.");
                assert.AreEqual("b", getHeaderFunc("a"), "Header not found or invalid header value.");
                List <KeyValuePair <string, string> > expectedHeaders = new List <KeyValuePair <string, string> >
                {
                    new KeyValuePair <string, string>("a", "b")
                };
                VerificationUtils.VerifyEnumerationsAreEqual(
                    expectedHeaders,
                    getHeadersFunc(),
                    (first, second, assert2) => assert2.AreEqual(first, second, "Items differ."),
                    (item) => item.Key + " = " + item.Value,
                    assert);

                setHeaderAction("a", "c");

                assert.AreEqual(1, getHeadersFunc().Count(), "One header expected.");
                assert.AreEqual("c", getHeaderFunc("a"), "Header not found or invalid header value.");
                expectedHeaders[0] = new KeyValuePair <string, string>("a", "c");
                VerificationUtils.VerifyEnumerationsAreEqual(
                    expectedHeaders,
                    getHeadersFunc(),
                    (first, second, assert2) => assert2.AreEqual(first, second, "Items differ."),
                    (item) => item.Key + " = " + item.Value,
                    assert);

                setHeaderAction("d", "e");

                assert.AreEqual(2, getHeadersFunc().Count(), "Two headers expected.");
                assert.AreEqual("c", getHeaderFunc("a"), "Header not found or invalid header value.");
                assert.AreEqual("e", getHeaderFunc("d"), "Header not found or invalid header value.");
                expectedHeaders.Add(new KeyValuePair <string, string>("d", "e"));
                VerificationUtils.VerifyEnumerationsAreEqual(
                    expectedHeaders,
                    getHeadersFunc(),
                    (first, second, assert2) => assert2.AreEqual(first, second, "Items differ."),
                    (item) => item.Key + " = " + item.Value,
                    assert);

                setHeaderAction("d", null);
                setHeaderAction("a", null);

                assert.AreEqual(0, getHeadersFunc().Count(), "Empty header collection expected.");
                assert.IsNull(getHeaderFunc("a"), "Unexpectedly found header.");
            },
                expectedException,
                exceptionVerifier);
        }
Beispiel #23
0
        public void ParameterReaderCreateReaderStateMachineTests()
        {
            IEdmModel           model = TestModels.BuildModelWithFunctionImport();
            IEdmOperationImport functionImport_Primitive           = model.FindEntityContainer("TestContainer").FindOperationImports("FunctionImport_Primitive").First();
            IEdmOperationImport functionImport_PrimitiveCollection = model.FindEntityContainer("TestContainer").FindOperationImports("FunctionImport_PrimitiveCollection").First();
            IEdmOperationImport functionImport_Complex             = model.FindEntityContainer("TestContainer").FindOperationImports("FunctionImport_Complex").First();
            IEdmOperationImport functionImport_ComplexCollection   = model.FindEntityContainer("TestContainer").FindOperationImports("FunctionImport_ComplexCollection").First();
            IEdmOperationImport functionImport_Entry = model.FindEntityContainer("TestContainer").FindOperationImports("FunctionImport_Entry").First();
            IEdmOperationImport functionImport_Feed  = model.FindEntityContainer("TestContainer").FindOperationImports("FunctionImport_Feed").First();

            CreateReaderMethods[] createReaderMethods = new CreateReaderMethods[]
            {
                CreateReaderMethods.CreateCollectionReader,
            };

            var testConfigurations = this.ReaderTestConfigurationProvider.JsonLightFormatConfigurations.Where(c => c.IsRequest);

            this.CombinatorialEngineProvider.RunCombinations(
                testConfigurations,
                createReaderMethods,
                (testConfiguration, createReaderMethod) =>
            {
                // Calling Create*Reader in Start state should fail.
                ODataParameterReader reader = this.CreateParameterReaderForRequestOrResponse(model, functionImport_Complex, testConfiguration, "{ complex : { PrimitiveProperty : \"456\" } }");
                this.Assert.ExpectedException(
                    () => CreateSubReader(reader, createReaderMethod),
                    ODataExpectedExceptions.ODataException("ODataParameterReaderCore_InvalidCreateReaderMethodCalledForState", createReaderMethod.ToString(), ODataParameterReaderState.Start.ToString()), this.ExceptionVerifier);
                this.Assert.AreEqual(ODataParameterReaderState.Start, reader.State, "Unexpected parameter reader state.");

                // Calling Create*Reader in Value state should fail.
                reader.Read();
                this.Assert.AreEqual(ODataParameterReaderState.Resource, reader.State, "Unexpected parameter reader state.");
                this.Assert.ExpectedException(
                    () => CreateSubReader(reader, createReaderMethod),
                    ODataExpectedExceptions.ODataException("ODataParameterReaderCore_InvalidCreateReaderMethodCalledForState", createReaderMethod.ToString(), ODataParameterReaderState.Resource.ToString()), this.ExceptionVerifier);
                this.Assert.AreEqual(ODataParameterReaderState.Resource, reader.State, "Unexpected parameter reader state.");

                if (createReaderMethod != CreateReaderMethods.CreateResourceReader)
                {
                    // Calling Create*Reader in Entry state should fail.
                    reader = this.CreateParameterReaderForRequestOrResponse(model, functionImport_Entry, testConfiguration, "{ entry : {} }");
                    reader.Read();
                    this.Assert.AreEqual(ODataParameterReaderState.Resource, reader.State, "Unexpected parameter reader state.");
                    this.Assert.ExpectedException(
                        () => CreateSubReader(reader, createReaderMethod),
                        ODataExpectedExceptions.ODataException("ODataParameterReaderCore_InvalidCreateReaderMethodCalledForState", createReaderMethod.ToString(), ODataParameterReaderState.Resource.ToString()), this.ExceptionVerifier);
                    this.Assert.AreEqual(ODataParameterReaderState.Resource, reader.State, "Unexpected parameter reader state.");
                }

                if (createReaderMethod != CreateReaderMethods.CreateResourceSetReader)
                {
                    // Calling Create*Reader in Feed state should fail.
                    reader = this.CreateParameterReaderForRequestOrResponse(model, functionImport_Feed, testConfiguration, "{ feed : [] }");
                    reader.Read();
                    this.Assert.AreEqual(ODataParameterReaderState.ResourceSet, reader.State, "Unexpected parameter reader state.");
                    this.Assert.ExpectedException(
                        () => CreateSubReader(reader, createReaderMethod),
                        ODataExpectedExceptions.ODataException("ODataParameterReaderCore_InvalidCreateReaderMethodCalledForState", createReaderMethod.ToString(), ODataParameterReaderState.ResourceSet.ToString()), this.ExceptionVerifier);
                    this.Assert.AreEqual(ODataParameterReaderState.ResourceSet, reader.State, "Unexpected parameter reader state.");
                }

                if (createReaderMethod != CreateReaderMethods.CreateCollectionReader)
                {
                    // Calling Create*Reader in Collection state should fail.
                    reader = this.CreateParameterReaderForRequestOrResponse(model, functionImport_ComplexCollection, testConfiguration, "{ complexCollection : [] }");
                    reader.Read();
                    this.Assert.AreEqual(ODataParameterReaderState.Collection, reader.State, "Unexpected parameter reader state.");
                    this.Assert.ExpectedException(
                        () => CreateSubReader(reader, createReaderMethod),
                        ODataExpectedExceptions.ODataException("ODataParameterReaderCore_InvalidCreateReaderMethodCalledForState", createReaderMethod.ToString(), ODataParameterReaderState.Collection.ToString()), this.ExceptionVerifier);
                    this.Assert.AreEqual(ODataParameterReaderState.Collection, reader.State, "Unexpected parameter reader state.");
                }

                // Calling Read() in Entry/Feed/Collection state without calling Create***Reader should fail.
                IEdmOperationImport functionImport = createReaderMethod == CreateReaderMethods.CreateResourceReader ? functionImport_Entry : (createReaderMethod == CreateReaderMethods.CreateResourceSetReader ? functionImport_Feed : functionImport_ComplexCollection);
                string payload = createReaderMethod == CreateReaderMethods.CreateResourceReader ? "{ entry : {} }" : (createReaderMethod == CreateReaderMethods.CreateResourceSetReader ? "{ feed : [] }" : "{ complexCollection : [] }");
                ODataParameterReaderState expectedParameterState = createReaderMethod == CreateReaderMethods.CreateResourceReader ? ODataParameterReaderState.Resource : ODataParameterReaderState.ResourceSet;
                var expectedReaderMethod = createReaderMethod == CreateReaderMethods.CreateCollectionReader ? CreateReaderMethods.CreateResourceSetReader.ToString() : createReaderMethod.ToString();
                reader = this.CreateParameterReaderForRequestOrResponse(model, functionImport, testConfiguration, payload);
                reader.Read();
                this.Assert.AreEqual(expectedParameterState, reader.State, "Unexpected parameter reader state.");
                this.Assert.ExpectedException(
                    () => reader.Read(),
                    ODataExpectedExceptions.ODataException("ODataParameterReaderCore_SubReaderMustBeCreatedAndReadToCompletionBeforeTheNextReadOrReadAsyncCall", expectedParameterState.ToString(), expectedReaderMethod), this.ExceptionVerifier);
                this.Assert.AreEqual(expectedParameterState, reader.State, "Unexpected parameter reader state.");

                // Calling Read() in Entry/Feed/Collection state after Create***Reader() is called but before the created reader finishes should fail.
                var subReaderMethod = createReaderMethod == CreateReaderMethods.CreateCollectionReader
                        ? CreateReaderMethods.CreateResourceSetReader : createReaderMethod;
                object subReader = CreateSubReader(reader,
                                                   subReaderMethod);
                this.Assert.ExpectedException(
                    () => reader.Read(),
                    ODataExpectedExceptions.ODataException("ODataParameterReaderCore_SubReaderMustBeInCompletedStateBeforeTheNextReadOrReadAsyncCall", expectedParameterState.ToString(), expectedReaderMethod), this.ExceptionVerifier);
                this.Assert.AreEqual(expectedParameterState, reader.State, "Unexpected parameter reader state.");

                // Calling Create*Reader() before the sub-reader is completed should fail.
                string parameterName = createReaderMethod == CreateReaderMethods.CreateResourceReader ? "entry" : (createReaderMethod == CreateReaderMethods.CreateResourceSetReader ? "feed" : "complexCollection");
                subReader.GetType().GetMethod("Read").Invoke(subReader, null);
                this.Assert.ExpectedException(
                    () => CreateSubReader(reader, subReaderMethod),
                    ODataExpectedExceptions.ODataException("ODataParameterReaderCore_CreateReaderAlreadyCalled", expectedReaderMethod, parameterName), this.ExceptionVerifier);
                this.Assert.AreEqual(expectedParameterState, reader.State, "Unexpected parameter reader state.");

                // Calling Create*Reader() after sub-reader is completed should fail.
                while ((bool)subReader.GetType().GetMethod("Read").Invoke(subReader, null))
                {
                    ;
                }
                this.Assert.AreEqual("Completed", subReader.GetType().GetProperty("State").GetValue(subReader, null).ToString(), "Unexpected sub-reader state.");
                this.Assert.ExpectedException(
                    () => CreateSubReader(reader, subReaderMethod),
                    ODataExpectedExceptions.ODataException("ODataParameterReaderCore_CreateReaderAlreadyCalled", expectedReaderMethod, parameterName), this.ExceptionVerifier);
                this.Assert.AreEqual(expectedParameterState, reader.State, "Unexpected parameter reader state.");

                // Finish reading...
                reader.Read();
                this.Assert.AreEqual(ODataParameterReaderState.Completed, reader.State, "Unexpected parameter reader state.");

                // Calling Create*Reader in Completed state should fail.
                this.Assert.ExpectedException(
                    () => CreateSubReader(reader, subReaderMethod),
                    ODataExpectedExceptions.ODataException("ODataParameterReaderCore_InvalidCreateReaderMethodCalledForState", expectedReaderMethod, ODataParameterReaderState.Completed.ToString()), this.ExceptionVerifier);
                this.Assert.AreEqual(ODataParameterReaderState.Completed, reader.State, "Unexpected parameter reader state.");

                // Exception in subReader should put parent reader in Exception state.
                payload = createReaderMethod == CreateReaderMethods.CreateResourceReader ? "{ entry : \"foo\" }" : (createReaderMethod == CreateReaderMethods.CreateResourceSetReader ? "{ feed : { \"foo\" : \"bar\" } }" : "{ complexCollection : { \"foo\" : \"bar\" } }");
                reader  = this.CreateParameterReaderForRequestOrResponse(model, functionImport, testConfiguration, payload);
                reader.Read();
                this.Assert.AreEqual(expectedParameterState, reader.State, "Unexpected parameter reader state.");
                subReader = CreateSubReader(reader, subReaderMethod);
                this.Assert.IsNotNull(TestExceptionUtils.RunCatching(() => { while ((bool)subReader.GetType().GetMethod("Read").Invoke(subReader, null))
                                                                             {
                                                                             }
                                                                     }), "Expecting sub-reader.Read() to fail.");
                this.Assert.AreEqual("Exception", subReader.GetType().GetProperty("State").GetValue(subReader, null).ToString(), "Unexpected sub-reader state.");
                this.Assert.AreEqual(ODataParameterReaderState.Exception, reader.State, "Unexpected parameter reader state.");

                // Calling Create*Reader in Exception state should fail.
                this.Assert.ExpectedException(
                    () => CreateSubReader(reader, subReaderMethod),
                    ODataExpectedExceptions.ODataException("ODataParameterReaderCore_InvalidCreateReaderMethodCalledForState", expectedReaderMethod, ODataParameterReaderState.Exception.ToString()), this.ExceptionVerifier);
                this.Assert.AreEqual(ODataParameterReaderState.Exception, reader.State, "Unexpected parameter reader state.");
            });
        }
        public void OrderByBinderTest()
        {
            IEdmModel model = QueryTestMetadata.BuildTestMetadata(this.PrimitiveTypeResolver, this.UntypedDataServiceProviderFactory);

            // TODO: add an error test where the input collection to the order-by is a singleton

            ResourceRangeVariable entityRangeVariable = new ResourceRangeVariable("dummy", model.ResolveTypeReference("TestNS.Customer", false).AsEntity(), model.FindEntityContainer("BinderTestMetadata").FindEntitySet("Customers"));

            OrderByTestCase[] testCases = new OrderByTestCase[]
            {
                new OrderByTestCase()
                {
                    OrderBy = new string[] { "true" },
                    ExpectedOrderByExpressions = new SingleValueNode[]
                    {
                        new ConstantNode(true)
                    }
                },

                new OrderByTestCase()
                {
                    OrderBy = new string[] { "Name" },
                    ExpectedOrderByExpressions = new SingleValueNode[]
                    {
                        new SingleValuePropertyAccessNode(
                            new ResourceRangeVariableReferenceNode(entityRangeVariable.Name, entityRangeVariable),
                            model.ResolveProperty("TestNS.Customer.Name")
                            )
                    }
                },

                new OrderByTestCase()
                {
                    OrderBy = new string[] { "3" },
                    ExpectedOrderByExpressions = new SingleValueNode[]
                    {
                        new ConstantNode(3)
                    }
                },

                new OrderByTestCase()
                {
                    OrderBy = new string[] { "null" },
                    ExpectedOrderByExpressions = new SingleValueNode[]
                    {
                        new ConstantNode(null)
                    }
                },


                new OrderByTestCase()
                {
                    OrderBy = new string[] { "Address" },
                    ExpectedExceptionMessage = "The $orderby expression must evaluate to a single value of primitive type."
                },

                new OrderByTestCase()
                {
                    OrderBy = new string[] { "Emails" },
                    ExpectedExceptionMessage = "The $orderby expression must evaluate to a single value of primitive type."
                },

                new OrderByTestCase()
                {
                    OrderBy = new string[] { "NonExistant" },
                    ExpectedExceptionMessage = "Could not find a property named 'NonExistant' on type 'TestNS.Customer'."
                },

                new OrderByTestCase()
                {
                    OrderBy = new string[] { "Name", "ID" },
                    ExpectedOrderByExpressions = new SingleValueNode[]
                    {
                        new SingleValuePropertyAccessNode(
                            new ResourceRangeVariableReferenceNode(entityRangeVariable.Name, entityRangeVariable),
                            model.ResolveProperty("TestNS.Customer.Name")
                            ),
                        new SingleValuePropertyAccessNode(
                            new ResourceRangeVariableReferenceNode(entityRangeVariable.Name, entityRangeVariable),
                            model.ResolveProperty("TestNS.Customer.ID")
                            ),
                    }
                },

                new OrderByTestCase()
                {
                    OrderBy = new string[] { "Name", "Address" },
                    ExpectedExceptionMessage = "The $orderby expression must evaluate to a single value of primitive type."
                },

                new OrderByTestCase()
                {
                    OrderBy = new string[] { "Name", "Emails" },
                    ExpectedExceptionMessage = "The $orderby expression must evaluate to a single value of primitive type."
                },

                new OrderByTestCase()
                {
                    OrderBy = new string[] { "Name", "NonExistant" },
                    ExpectedExceptionMessage = "Could not find a property named 'NonExistant' on type 'TestNS.Customer'."
                },
            };

            this.CombinatorialEngineProvider.RunCombinations(
                testCases,
                new OrderByDirection?[] { null, OrderByDirection.Ascending, OrderByDirection.Descending },
                (testCase, direction) =>
            {
                string orderByDirection = direction == null
                        ? string.Empty
                        : direction == OrderByDirection.Ascending
                            ? " asc"
                            : " desc";

                this.Assert.IsTrue(testCase.OrderBy.Length > 0, "Need at least one order-by expression");

                StringBuilder queryBuilder = new StringBuilder("/Customers?$orderby=");
                for (int i = 0; i < testCase.OrderBy.Length; ++i)
                {
                    if (i > 0)
                    {
                        queryBuilder.Append(", ");
                    }
                    queryBuilder.Append(testCase.OrderBy[i]);
                    queryBuilder.Append(orderByDirection);
                }

                TestExceptionUtils.ExpectedException <ODataException>(
                    this.Assert,
                    () =>
                {
                    ODataUri actual = QueryNodeUtils.BindQuery(queryBuilder.ToString(), model);

                    // construct the expected order-by node
                    OrderByClause orderByNode = null;
                    for (int i = testCase.ExpectedOrderByExpressions.Length - 1; i >= 0; --i)
                    {
                        orderByNode = new OrderByClause(
                            orderByNode,
                            testCase.ExpectedOrderByExpressions[i],
                            direction ?? OrderByDirection.Ascending,
                            new ResourceRangeVariable(ExpressionConstants.It, model.ResolveTypeReference("TestNS.Customer", false).AsEntity(), model.FindEntityContainer("BinderTestMetadata").FindEntitySet("Customers"))
                            );
                    }

                    QueryNodeUtils.VerifyOrderByClauseAreEqual(
                        orderByNode,
                        actual.OrderBy,
                        this.Assert);
                },
                    testCase.ExpectedExceptionMessage,
                    null);
            });
        }
Beispiel #25
0
        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);
                }
            });
        }
        public void CustomQueryOptionBinderTest()
        {
            var metadata = QueryTestMetadata.BuildTestMetadata(this.PrimitiveTypeResolver, this.UntypedDataServiceProviderFactory);

            var testCases = new[]
            {
                new QueryOptionTestCase
                {
                    Query = "/Customers?$foo=12",
                    ExpectedExceptionMessage = "The system query option '$foo' is not supported."
                },
                new QueryOptionTestCase
                {
                    Query = "/Customers?a=b",
                    ExpectedQueryOptions = new CustomQueryOptionNode[]
                    {
                        new CustomQueryOptionNode("a", "b")
                    }
                },
                new QueryOptionTestCase
                {
                    Query = "/Customers?a=b&c=d",
                    ExpectedQueryOptions = new CustomQueryOptionNode[]
                    {
                        new CustomQueryOptionNode("a", "b"),
                        new CustomQueryOptionNode("c", "d")
                    }
                },
                new QueryOptionTestCase
                {
                    Query = "/Customers?a=b&a=c",
                    ExpectedQueryOptions = new CustomQueryOptionNode[]
                    {
                        new CustomQueryOptionNode("a", "b"),
                        new CustomQueryOptionNode("a", "c")
                    }
                },
                new QueryOptionTestCase
                {
                    Query = "/Customers?foo",
                    ExpectedQueryOptions = new CustomQueryOptionNode[]
                    {
                        new CustomQueryOptionNode(null, "foo")
                    }
                },
                new QueryOptionTestCase
                {
                    Query = "/Customers?foo=",
                    ExpectedQueryOptions = new CustomQueryOptionNode[]
                    {
                        new CustomQueryOptionNode("foo", string.Empty)
                    }
                },
                new QueryOptionTestCase
                {
                    Query = "/Customers?&",
                    ExpectedQueryOptions = new CustomQueryOptionNode[]
                    {
                        new CustomQueryOptionNode(null, string.Empty),
                        new CustomQueryOptionNode(null, string.Empty)
                    }
                },
                new QueryOptionTestCase
                {
                    Query = "/Customers?a=b&",
                    ExpectedQueryOptions = new CustomQueryOptionNode[]
                    {
                        new CustomQueryOptionNode("a", "b"),
                        new CustomQueryOptionNode(null, string.Empty)
                    }
                },
                new QueryOptionTestCase
                {
                    Query = "/Customers?&&",
                    ExpectedQueryOptions = new CustomQueryOptionNode[]
                    {
                        new CustomQueryOptionNode(null, string.Empty),
                        new CustomQueryOptionNode(null, string.Empty),
                        new CustomQueryOptionNode(null, string.Empty)
                    }
                },
                new QueryOptionTestCase
                {
                    Query = "/Customers?a=b&&",
                    ExpectedQueryOptions = new CustomQueryOptionNode[]
                    {
                        new CustomQueryOptionNode("a", "b"),
                        new CustomQueryOptionNode(null, string.Empty),
                        new CustomQueryOptionNode(null, string.Empty)
                    }
                },
            };

            this.CombinatorialEngineProvider.RunCombinations(
                testCases,
                (testCase) =>
            {
                TestExceptionUtils.ExpectedException <ODataException>(
                    this.Assert,
                    () =>
                {
                    SemanticTree actual = QueryNodeUtils.BindQuery(testCase.Query, metadata);
                    QueryNodeUtils.VerifyQueryNodesAreEqual(
                        testCase.ExpectedQueryOptions,
                        actual.CustomQueryOptions,
                        this.Assert);
                },
                    testCase.ExpectedExceptionMessage,
                    null);
            });
        }
Beispiel #27
0
        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);
                }
            });
        }
Beispiel #28
0
 /// <summary>
 /// Verifies that the specified action fails with argument being null exception.
 /// </summary>
 /// <param name="action">The action to execute.</param>
 private void VerifyArgumentNullException(Action action)
 {
     // TODO: Support raw error message verification for non-product exceptions
     TestExceptionUtils.ExpectedException(this.Assert, action, new ExpectedException(typeof(ArgumentNullException)), this.ExceptionVerifier);
 }
Beispiel #29
0
        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 + ".");
                            }
                        }
                    }
            });
        }
Beispiel #30
0
 /// <summary>
 /// Verifies that the action fails due to the fact that the writer was already disposed.
 /// </summary>
 /// <param name="action">The action to execute.</param>
 private void VerifyWriterAlreadyDisposed(Action action)
 {
     TestExceptionUtils.ExpectedException(this.Assert, action, new ExpectedException(typeof(ObjectDisposedException)), this.ExceptionVerifier);
 }