public void SyncAsyncMismatchTest()
        {
            this.CombinatorialEngineProvider.RunCombinations(
                TestCalls,
                this.WriterTestConfigurationProvider.JsonLightFormatConfigurations.Where(tc => tc.IsRequest),
                new bool[] { false, true },
                (testCall, testConfiguration, testSynchronousCall) =>
                {
                    using (var memoryStream = new TestStream())
                    using (var messageWriter = TestWriterUtils.CreateMessageWriter(memoryStream, testConfiguration, this.Assert))
                    {
                        ODataParameterWriter parameterWriter = messageWriter.CreateODataParameterWriter(null /*functionImport*/);
                        ODataParameterWriterTestWrapper writer = (ODataParameterWriterTestWrapper)parameterWriter;

                        this.Assert.ExpectedException(
                            () =>
                            {
                                if (testSynchronousCall)
                                {
                                    testCall.Sync(writer);
                                }
                                else
                                {
                                    testCall.Async(writer);
                                }
                            },
                            testConfiguration.Synchronous == testSynchronousCall ?
                                null :
                                testSynchronousCall 
                                    ? ODataExpectedExceptions.ODataException("ODataParameterWriterCore_SyncCallOnAsyncWriter")
                                    : ODataExpectedExceptions.ODataException("ODataParameterWriterCore_AsyncCallOnSyncWriter"),
                            this.ExceptionVerifier);
                    }
                });
        }
Пример #2
0
        /// <summary>
        /// Resets the test message so that it can be used again.
        /// </summary>
        public virtual void Reset()
        {
            this.StreamRetrieved = false;
            TestStream testStream = this.TestStream;

            if (testStream != null)
            {
                testStream.Reset();
            }
            else
            {
                ExceptionUtilities.Assert(this.stream.CanSeek, "Need seekable stream in order to reset.");
                this.stream.Seek(0, SeekOrigin.Begin);
            }
        }
        /// <summary>
        /// Runs the specified action for all interesting writers.
        /// </summary>
        /// <param name="feedWriter">True if writing a feed; false if writing an entry.</param>
        /// <param name="action">The action to run.</param>
        private void ForWriters(bool feedWriter, Action<ODataWriter> action)
        {
            this.CombinatorialEngineProvider.RunCombinations(
                this.WriterTestConfigurationProvider.ExplicitFormatConfigurations,
                (testConfiguration) =>
                {
                    testConfiguration = testConfiguration.Clone();
                    testConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri);

                    using (TestStream stream = new TestStream())
                    using (var messageWriter = TestWriterUtils.CreateMessageWriter(stream, testConfiguration, this.Assert))
                    {
                        ODataWriter writer = messageWriter.CreateODataWriter(feedWriter);
                        action(writer);
                    }
                });
        }
Пример #4
0
            protected override TestMessage CreateInputMessage(ReaderTestConfiguration testConfiguration)
            {
                MemoryStream memoryStream  = new MemoryStream(this.RawMessage);
                TestStream   messageStream = new TestStream(memoryStream);

                if (testConfiguration.Synchronous)
                {
                    messageStream.FailAsynchronousCalls = true;
                }
                else
                {
                    messageStream.FailSynchronousCalls = true;
                }

                TestMessage testMessage = TestReaderUtils.CreateInputMessageFromStream(
                    messageStream,
                    testConfiguration,
                    this.PayloadElement.GetPayloadKindFromPayloadElement(),
                    this.BatchContentTypeHeader,
                    this.UrlResolver);

                return(testMessage);
            }
        public void SyncAsyncMismatchTest()
        {
            // ToDo: Fix places where we've lost JsonVerbose coverage to add JsonLight
            this.CombinatorialEngineProvider.RunCombinations(
                TestCalls,
                this.WriterTestConfigurationProvider.ExplicitFormatConfigurations.Where(tc => !tc.IsRequest && tc.Format == ODataFormat.Atom),
                new bool[] { false, true },
                (testCall, testConfiguration, testSynchronousCall) =>
                {
                    using (var memoryStream = new TestStream())
                    using (var messageWriter = TestWriterUtils.CreateMessageWriter(memoryStream, testConfiguration, this.Assert))
                    {
                        ODataCollectionWriter collectionWriter = messageWriter.CreateODataCollectionWriter();
                        ODataCollectionWriterTestWrapper writer = (ODataCollectionWriterTestWrapper)collectionWriter;

                        this.Assert.ExpectedException(
                            () =>
                            {
                                if (testSynchronousCall)
                                {
                                    testCall.Sync(writer);
                                }
                                else
                                {
                                    testCall.Async(writer);
                                }
                            },
                            testConfiguration.Synchronous == testSynchronousCall ?
                                null :
                                testSynchronousCall
                                    ? ODataExpectedExceptions.ODataException("ODataCollectionWriterCore_SyncCallOnAsyncWriter")
                                    : ODataExpectedExceptions.ODataException("ODataCollectionWriterCore_AsyncCallOnSyncWriter"),
                            this.ExceptionVerifier);
                    }
                });
        }
        /// <summary>
        /// Returns the payload to be used for this test case and the specified test configuration.
        /// </summary>
        /// <param name="testConfiguration">The test configuration to use.</param>
        /// <returns>The payload to use for testing.</returns>
        private byte[] GetPayload(ReaderTestConfiguration testConfiguration)
        {
            if (testConfiguration.Format != null && testConfiguration.Format != ODataFormat.Metadata)
            {
                // NOTE: metadata reading is not supported in other formats; return an empty payload for error tests
                return new byte[0];
            }

            TestStream testStream = new TestStream(new MemoryStream(), ignoreDispose: true);

            if (this.PayloadEdmModel != null)
            {
                using (XmlWriter xmlWriter = XmlWriter.Create(testStream))
                {
                    IEnumerable<EdmError> errors;

                    if (!EdmxWriter.TryWriteEdmx(this.PayloadEdmModel, xmlWriter, EdmxTarget.OData, out errors))
                    {
                        var errorBuilder = new StringBuilder();

                        foreach (var error in errors)
                        {
                            errorBuilder.AppendLine(error.ToString());
                        }

                        throw new Exception("TryWriteEdmx Error:" + errorBuilder);
                    }
                }
            }

            byte[] payload = new byte[testStream.Length];
            testStream.Seek(0, SeekOrigin.Begin);
            testStream.Read(payload, 0, (int)testStream.Length);
            return payload;
        }
Пример #7
0
        public void SetVersionInMessageHeaderAndSettingsTest()
        {
            IEdmModel model = Microsoft.Test.OData.Utils.Metadata.TestModels.BuildTestModel();

            IEnumerable<string> validVersionHeaders = ODataVersionUtils.AllSupportedVersions.Select(version => ODataUtils.ODataVersionToString(version));

            string[] suffixes = new string[]
            {
                string.Empty,       // no user-agent string
                ";",                // empty user-agent string
                ";UserAgentString"
            };

            // Build combinations of all valid versions with a set of interesting user agent strings
            IEnumerable<VersionMessageHeaderTestCase> testCases = validVersionHeaders.SelectMany(
                validHeader => suffixes.Select(
                    suffix => new VersionMessageHeaderTestCase { VersionHeaderValue = validHeader + suffix }));

            // Add some invalid header strings; won't matter because we won't look at them
            string[] invalidVersionHeaders = { null, "randomstring", "V1.0", "1.5", "randomstring;1.0", "4.0", "1", ";UserAgentString" };
            IEnumerable<VersionMessageHeaderTestCase> errorTestCases = invalidVersionHeaders.Select(invalidHeader =>
                new VersionMessageHeaderTestCase { VersionHeaderValue = invalidHeader });


            this.CombinatorialEngineProvider.RunCombinations(
                testCases.Concat(errorTestCases),
                writerActionsForPayloadKinds,
                this.WriterTestConfigurationProvider.AtomFormatConfigurations,
                (testCase, writerInvocation, testConfiguration) =>
                {
                    testConfiguration = testConfiguration.Clone();
                    testConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri);

                    ODataPayloadKind payloadKind = writerInvocation.PayloadKind;
                    if (!payloadKind.IsSupported(testConfiguration))
                    {
                        return;
                    }

                    // NOTE: we don't clone the message writer settings of the test configuation; just ensure that they have a version
                    this.Assert.IsNotNull(testConfiguration.MessageWriterSettings.Version, "Version must exist on the message writer settings.");

                    using (var memoryStream = new TestStream())
                    {
                        TestMessage testMessage;
                        using (ODataMessageWriterTestWrapper messageWriter = TestWriterUtils.CreateMessageWriter(memoryStream, testConfiguration, this.Assert, out testMessage, null, model))
                        {
                            // Set the version header in the test message; this should have no effect independently of the value of the header.
                            // A version is specified on the settings and that should win.
                            testMessage.SetHeader(ODataConstants.ODataVersionHeader, testCase.VersionHeaderValue);
                            this.Assert.IsNull(testCase.ExpectedException, "No exception should be expected.");

                            writerInvocation.WriterAction(messageWriter);

                            // Check that the version was properly set (in the writer settings and in the message header)
                            ODataVersion? expectedVersion = testConfiguration.MessageWriterSettings.Version.Value;
                            this.Assert.IsNotNull(expectedVersion, "Version on actual writer settings must not be null!");

                            string versionFromHeader = testMessage.GetHeader(ODataConstants.ODataVersionHeader);
                            this.Assert.AreEqual(
                                ODataUtils.ODataVersionToString(expectedVersion.Value), versionFromHeader,
                                "The version message header should have been updated.");

                            ODataMessageWriterSettings actualSettings = messageWriter.PrivateSettings;
                            this.Assert.AreEqual(expectedVersion, actualSettings.Version, "Versions do not match!");
                        }
                    }
                });
        }
Пример #8
0
        /// <summary>
        /// Creates the input message for the test descriptor
        /// </summary>
        /// <param name="testConfiguration">the test configuration to use</param>
        /// <param name="readerTestDescriptor">The test descriptor</param>
        /// <param name="settings">The test descriptor settings</param>
        /// <param name="applyPayloadTransformations">Whether or not to apply payload transformations</param>
        /// <returns>The message for the test</returns>
        public static TestMessage CreateInputMessage(ReaderTestConfiguration testConfiguration, 
            PayloadReaderTestDescriptor readerTestDescriptor,
            PayloadReaderTestDescriptor.Settings settings, 
            bool? applyPayloadTransformations)
        {
            TestMessage testMessage;
            bool originalApplyTransformValue = false;           
            var odataTransformFactory = settings.PayloadTransformFactory as ODataLibPayloadTransformFactory;

            try
            {
                if (applyPayloadTransformations.HasValue && odataTransformFactory != null)
                {
                    originalApplyTransformValue = odataTransformFactory.ApplyTransform;
                    odataTransformFactory.ApplyTransform = applyPayloadTransformations.Value;
                }

                if (readerTestDescriptor.TestDescriptorNormalizers != null)
                {
                    foreach (var testDescriptorNormalizer in readerTestDescriptor.TestDescriptorNormalizers)
                    {
                        var normalizerAction = testDescriptorNormalizer(testConfiguration);
                        if (normalizerAction != null)
                        {
                            normalizerAction(readerTestDescriptor);
                        }
                    }
                }

                MemoryStream memoryStream = new MemoryStream(GetPayload(testConfiguration, readerTestDescriptor.PayloadNormalizers, settings, readerTestDescriptor.PayloadElement));
                TestStream messageStream = new TestStream(memoryStream);
                if (testConfiguration.Synchronous)
                {
                    messageStream.FailAsynchronousCalls = true;
                }
                else
                {
                    messageStream.FailSynchronousCalls = true;
                }

                testMessage = TestReaderUtils.CreateInputMessageFromStream(
                    messageStream, 
                    testConfiguration, 
                    readerTestDescriptor.PayloadElement.GetPayloadKindFromPayloadElement(),
                    readerTestDescriptor.PayloadElement.GetCustomContentTypeHeader(), readerTestDescriptor.UrlResolver);

                if (readerTestDescriptor.TestMessageWrapper != null)
                {
                    testMessage = readerTestDescriptor.TestMessageWrapper(testMessage);
                }

                return testMessage;
            }
            finally
            {
                if (applyPayloadTransformations.HasValue && odataTransformFactory != null)
                {
                    odataTransformFactory.ApplyTransform = originalApplyTransformValue;
                }
            }
        }
Пример #9
0
        /// <summary>
        /// Creates an ODataWriter for the specified format and the specified version and
        /// writes the property in the descriptor to an in-memory stream. It then parses
        /// the written Xml and compares it to the expected result as specified in the descriptor.
        /// </summary>
        /// <param name="originalPayload">The payload to first clone and then write.</param>
        /// <param name="testConfiguration">Configuration for the test</param>
        /// <param name="model">The model to use.</param>
        protected void WriteAndVerifyODataProperty(ODataPayloadElement originalPayload, WriterTestConfiguration testConfiguration, IEdmModel model)
        {
            this.Logger.LogConfiguration(testConfiguration);
            this.Logger.LogModelPresence(model);

            using (var memoryStream = new TestStream())
            {
                TestMessage testMessage;
                using (ODataMessageWriterTestWrapper writer = TestWriterUtils.CreateMessageWriter(memoryStream, testConfiguration, this.Assert, out testMessage, null, model))
                {
                    Action<ODataPayloadElement> writeElementToStream = payload => this.PropertyPayloadElementWriter.WriteProperty(writer.MessageWriter, payload);
#if !SILVERLIGHT
                    this.WriteAndLogODataPayload(originalPayload, writer.Message, testConfiguration.Version, testConfiguration.Format, writeElementToStream);
#else
                    //TODO: Add roundtrip for silverlight
#endif
                }
            }
        }
        /// <summary>
        /// Called to create the input message for the reader test.
        /// </summary>
        /// <param name="innerStream">The <see cref="Stream"/> instance to be used as inner stream of the <see cref="TestStream"/>.</param>
        /// <param name="testConfiguration">The test configuration.</param>
        /// <returns>The newly created test message to use.</returns>
        protected override TestMessage CreateOutputMessage(Stream innerStream, WriterTestConfiguration testConfiguration)
        {
            TestStream messageStream = new TestStream(innerStream);
            if (testConfiguration.Synchronous)
            {
                messageStream.FailAsynchronousCalls = true;
            }
            else
            {
                messageStream.FailSynchronousCalls = true;
            }

            TestMessage testMessage = TestWriterUtils.CreateOutputMessageFromStream(
                messageStream, 
                testConfiguration, 
                this.PayloadKind, 
                this.PayloadElement.GetCustomContentTypeHeader(), 
                this.UrlResolver);

            return testMessage;
        }
 public void SyncAsyncMismatchTest()
 {
     this.CombinatorialEngineProvider.RunCombinations(
         TestCalls,
         this.WriterTestConfigurationProvider.DefaultFormatConfigurations,
         new bool[] { false, true },
         (testCall, testConfiguration, testSynchronousCall) =>
         {
             using(var memoryStream = new TestStream())
             {
                 // We purposely don't use the using pattern around the messageWriter here. Disposing the message writer will
                 // fail here because the writer is not left in a valid state.
                 var messageWriter = TestWriterUtils.CreateMessageWriter(memoryStream, testConfiguration, this.Assert);
                 ODataBatchWriterTestWrapper writer = messageWriter.CreateODataBatchWriter();
                 this.Assert.ExpectedException<ODataException>(
                     () =>
                     {
                         if (testSynchronousCall)
                         {
                             testCall.Sync(writer, testConfiguration);
                         }
                         else
                         {
                             testCall.Async(writer, testConfiguration);
                         }
                     },
                     testConfiguration.Synchronous == testSynchronousCall || testCall.ShouldNotFail ?
                         null :
                         testSynchronousCall ?
                         "A synchronous operation was called on an asynchronous batch writer. Calls on a batch writer instance must be either all synchronous or all asynchronous." :
                         "An asynchronous operation was called on a synchronous batch writer. Calls on a batch writer instance must be either all synchronous or all asynchronous.");
             }
         });
 }
Пример #12
0
        public void DisposeAfterExceptionTest()
        {
            // create a default entry and then set both read and edit links to null to provoke an exception during writing
            ODataEntry 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 + ".");
                            }
                        }
                    }
                });
        }
Пример #13
0
        public void UseWriterOnceTests()
        {
            Uri baseUri = new Uri("http://www.odata.org/");

            ODataError error = new ODataError();
            ODataEntityReferenceLink link = new ODataEntityReferenceLink { Url = new Uri("http://www.odata.org") };
            ODataEntityReferenceLinks links = new ODataEntityReferenceLinks
            {
                Links = new ODataEntityReferenceLink[] { link, link, link },
            };

            ODataServiceDocument serviceDocument = ObjectModelUtils.CreateDefaultWorkspace();
            ODataProperty property = new ODataProperty() { Name = "FirstName", Value = "Bill" };
            object rawValue = 42;

            // TODO: add WriteMetadataDocumentAsync() here once implemented.
            UseWriterOnceTestCase[] messageWriterOperations = new UseWriterOnceTestCase[]
            {
                new UseWriterOnceTestCase { WriterMethod = (messageWriter) => messageWriter.CreateODataCollectionWriter() },
                new UseWriterOnceTestCase { WriterMethod = (messageWriter) => messageWriter.CreateODataEntryWriter() },
                new UseWriterOnceTestCase { WriterMethod = (messageWriter) => messageWriter.CreateODataEntryWriter() },
                new UseWriterOnceTestCase { WriterMethod = (messageWriter) => messageWriter.WriteError(error, false), IsWriteError = true },
                new UseWriterOnceTestCase { WriterMethod = (messageWriter) => messageWriter.WriteEntityReferenceLink(link) },
                new UseWriterOnceTestCase { WriterMethod = (messageWriter) => messageWriter.WriteEntityReferenceLinks(links) },
                new UseWriterOnceTestCase { WriterMethod = (messageWriter) => messageWriter.WriteProperty(property) },
                new UseWriterOnceTestCase { WriterMethod = (messageWriter) => messageWriter.WriteServiceDocument(serviceDocument) },
                new UseWriterOnceTestCase { WriterMethod = (messageWriter) => messageWriter.WriteValue(rawValue), IsWriteValue = true },
            };

            var testCases = messageWriterOperations.Combinations(2);

            this.CombinatorialEngineProvider.RunCombinations(
                testCases,
                this.WriterTestConfigurationProvider.AtomFormatConfigurations.Where(tc => !tc.IsRequest),
                (testCase, testConfiguration) =>
                {
                    ODataMessageWriterSettings settingsWithBaseUri = testConfiguration.MessageWriterSettings.Clone();
                    settingsWithBaseUri.PayloadBaseUri = baseUri;
                    settingsWithBaseUri.SetServiceDocumentUri(ServiceDocumentUri);

                    using (var memoryStream = new TestStream())
                    {
                        TestMessage testMessage;
                        using (ODataMessageWriterTestWrapper messageWriter = TestWriterUtils.CreateMessageWriter(memoryStream, testConfiguration, this.Assert, out testMessage, settingsWithBaseUri))
                        {
                            testCase[0].WriterMethod(messageWriter);

                            string expectedException = "The ODataMessageWriter has already been used to write a message payload. An ODataMessageWriter can only be used once to write a payload for a given message.";
                            if (testCase[0].IsWriteValue && testCase[1].IsWriteError)
                            {
                                expectedException = "The WriteError method or the WriteErrorAsync method on ODataMessageWriter cannot be called after the WriteValue method or the WriteValueAsync method is called. In OData, writing an in-stream error for raw values is not supported.";
                            }
                            else if (!testCase[0].IsWriteError && testCase[1].IsWriteError)
                            {
                                expectedException = null;
                            }

                            TestExceptionUtils.ExpectedException<ODataException>(this.Assert, () => testCase[1].WriterMethod(messageWriter), expectedException);
                        }
                    }
                });
        }
Пример #14
0
        public void DisposeAfterWritingNothingTest()
        {
            this.CombinatorialEngineProvider.RunCombinations(
                this.WriterTestConfigurationProvider.ExplicitFormatConfigurations,
                new bool[] { true, false },
                (testConfiguration, forFeed) =>
                {
                    testConfiguration = testConfiguration.Clone();
                    testConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri);

                    using (var stream = new TestStream())
                    using (var messageWriter = TestWriterUtils.CreateMessageWriter(stream, testConfiguration, this.Assert))
                    {
                        ODataWriter writer = messageWriter.CreateODataWriter(forFeed);
                    }
                });
        }
Пример #15
0
        public void WriteAfterDisposeTest()
        {
            this.CombinatorialEngineProvider.RunCombinations(
                this.WriterTestConfigurationProvider.ExplicitFormatConfigurations,
                (testConfiguration) =>
                {
                    testConfiguration = testConfiguration.Clone();
                    testConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri);

                    using (var stream = new TestStream())
                    {
                        ODataWriter writer;
                        using (var messageWriter = TestWriterUtils.CreateMessageWriter(stream, testConfiguration, this.Assert))
                        {
                            writer = messageWriter.CreateODataWriter(isFeed: true);
                            // Message writer is disposed outside of this scope.
                        }

                        this.VerifyWriterAlreadyDisposed(() => writer.WriteStart(ObjectModelUtils.CreateDefaultFeed()));
                        this.VerifyWriterAlreadyDisposed(() => writer.WriteStart(ObjectModelUtils.CreateDefaultEntry()));
                        this.VerifyWriterAlreadyDisposed(() => writer.WriteStart(ObjectModelUtils.CreateDefaultCollectionLink()));
                    }
                });
        }
Пример #16
0
        public void WriteAfterExceptionTest()
        {
            // create a default entry and then set both read and edit links to null to provoke an exception during writing
            ODataEntry faultyEntry = ObjectModelUtils.CreateDefaultEntry();
            this.Assert.IsNull(faultyEntry.EditLink, "entry.EditLink == null");

            ODataEntry defaultEntry = ObjectModelUtils.CreateDefaultEntry();
            ODataFeed 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();
                    }
                });
        }
Пример #17
0
        public void FatalExceptionTest()
        {
            ODataEntry 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.
                    }
                });
        }
Пример #18
0
        /// <summary>
        /// Creates an ODataParameterReader with the given input.
        /// </summary>
        /// <param name="model">Model containing the function import.</param>
        /// <param name="functionImport">function import whose parameters are being read.</param>
        /// <param name="testConfiguration">test configuration.</param>
        /// <param name="payload">optional parameter payload.</param>
        /// <returns>Returns the created ODataParameterReader</returns>
        internal static ODataParameterReaderTestWrapper CreateODataParameterReader(IEdmModel model, IEdmOperationImport functionImport, ReaderTestConfiguration testConfiguration, string payload = null)
        {
            // TODO: ODataLib test item: Add new ODataPayloadElement for parameters payload
            // Once the bug is fixed, we should generate the parameters payload from the new ODataPayloadElement to make
            // tests in this file format agnostic.
            TestStream messageStream;
            if (payload != null)
            {
                messageStream = new TestStream(new MemoryStream(Encoding.UTF8.GetBytes(payload)));
            }
            else
            {
                messageStream = new TestStream();
            }

            TestMessage message = TestReaderUtils.CreateInputMessageFromStream(messageStream, testConfiguration, ODataPayloadKind.Parameter, /*customContentTypeHeader*/null, /*urlResolver*/null);
            ODataMessageReaderTestWrapper messageReader = TestReaderUtils.CreateMessageReader(message, model, testConfiguration);
            return messageReader.CreateODataParameterReader(functionImport);
        }
Пример #19
0
        public void SetContentTypeInMessageHeaderTest()
        {
            IEdmModel model = Microsoft.Test.OData.Utils.Metadata.TestModels.BuildTestModel();

            var testDescriptors = writerActionsForPayloadKinds.SelectMany(
                writerAction => CreateContentTypeHeaderTestCases(writerAction.PayloadKind).Select(
                    testCase =>
                        new
                        {
                            WriterInvocation = writerAction,
                            TestCase = testCase
                        }));
            // ToDo: Fix places where we've lost JsonVerbose coverage to add JsonLight
            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors.Where(td => td.TestCase.ExpectedFormat == ODataFormat.Atom),
                this.WriterTestConfigurationProvider.AllFormatsConfigurations.Where(tc => tc.Format == ODataFormat.Atom),
                (testDescriptor, testConfiguration) =>
                {
                    ODataPayloadKind payloadKind = testDescriptor.WriterInvocation.PayloadKind;
                    if (!payloadKind.IsSupported(testConfiguration))
                    {
                        return;
                    }

                    // Clone the test configuration and make sure no content type is set on the message writer settings
                    ODataMessageWriterSettings settings = testConfiguration.MessageWriterSettings;
                    ODataMessageWriterSettings clonedSettings = new ODataMessageWriterSettings()
                    {
                        // NOTE intentionally not copying acceptable media types, acceptable char sets, format and useFormat
                        PayloadBaseUri = settings.PayloadBaseUri,
                        CheckCharacters = settings.CheckCharacters,
                        DisableMessageStreamDisposal = settings.DisableMessageStreamDisposal,
                        Indent = settings.Indent,
                        MessageQuotas = new ODataMessageQuotas(settings.MessageQuotas),
                        Version = settings.Version,
                        EnableAtom = true
                    };
                    clonedSettings.SetServiceDocumentUri(ServiceDocumentUri);
                    WriterTestConfiguration clonedTestConfiguration = new WriterTestConfiguration(
                        testConfiguration.Format, 
                        clonedSettings, 
                        testConfiguration.IsRequest, 
                        testConfiguration.Synchronous);

                    using (var memoryStream = new TestStream())
                    {
                        TestMessage testMessage;
                        using (ODataMessageWriterTestWrapper messageWriter = TestWriterUtils.CreateMessageWriter(memoryStream, clonedTestConfiguration, this.Assert, out testMessage, null, model))
                        {
                            // Set the content type header in the test message
                            testMessage.SetHeader(ODataConstants.ContentTypeHeader, testDescriptor.TestCase.ContentTypeHeaderValue);

                            Func<WriterTestConfiguration, ExpectedException> expectedExceptionFunc = testDescriptor.TestCase.ExpectedException;
                            ExpectedException expectedException = expectedExceptionFunc == null ? null : expectedExceptionFunc(testConfiguration);

                            TestExceptionUtils.ExpectedException(
                                this.Assert,
                                () => testDescriptor.WriterInvocation.WriterAction(messageWriter),
                                expectedException,
                                this.ExceptionVerifier);

                            if (expectedException != null)
                            {
                                // nothing more to do if we expected an exception
                                return;
                            }

                            // Check that the format and encoding was properly set
                            ODataFormat actualFormat = messageWriter.PrivateFormat;
                            Encoding actualEncoding = messageWriter.PrivateEncoding;

                            string actualEncodingName = actualEncoding != null ? actualEncoding.WebName : null;
                            string expectedEncodingName = testDescriptor.TestCase.ExpectedEncoding != null ? testDescriptor.TestCase.ExpectedEncoding.WebName : null;

                            this.Assert.AreEqual(expectedEncodingName, actualEncodingName, "Encodings do not match!");
                            this.Assert.AreEqual(testDescriptor.TestCase.ExpectedFormat, actualFormat, "Formats do not match!");

                            // For batch payloads we need to validate the boundary string as well.
                            if (payloadKind == ODataPayloadKind.Batch)
                            {
                                string batchBoundary = messageWriter.PrivateBatchBoundary;
                                this.Assert.IsNotNull(batchBoundary, "Boundary string must not be null.");
                                this.Assert.IsTrue(testDescriptor.TestCase.ContentTypeHeaderValue.Contains("boundary=" + batchBoundary), "Boundary strings don't match.");
                            }
                        }
                    }
                });
        }
Пример #20
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);
            }
        }
Пример #21
0
        public void SetContentTypeInMessageHeaderAndSettingsTest()
        {
            IEdmModel model = Microsoft.Test.OData.Utils.Metadata.TestModels.BuildTestModel();

            var testDescriptors = writerActionsForPayloadKinds.SelectMany(
                writerAction => CreateContentTypeHeaderTestCases(writerAction.PayloadKind).Select(
                    testCase =>
                        new
                        {
                            WriterInvocation = writerAction,
                            TestCase = testCase
                        }));

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                this.WriterTestConfigurationProvider.AtomFormatConfigurations,
                (testDescriptor, testConfiguration) =>
                {
                    ODataPayloadKind payloadKind = testDescriptor.WriterInvocation.PayloadKind;
                    if (!payloadKind.IsSupported(testConfiguration))
                    {
                        return;
                    }

                    // NOTE: ensure that the writter settings have a format set - independently of the content type header
                    //       the format of the settings should win.
                    WriterTestConfiguration clonedTestConfiguration = testConfiguration.Clone();
                    clonedTestConfiguration.MessageWriterSettings.SetContentType(testConfiguration.Format);
                    clonedTestConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri);

                    using (var memoryStream = new TestStream())
                    {
                        TestMessage testMessage;
                        using (ODataMessageWriterTestWrapper messageWriter = TestWriterUtils.CreateMessageWriter(memoryStream, clonedTestConfiguration, this.Assert, out testMessage, null, model))
                        {
                            // Set the content type header in the test message; should not have any effect.
                            testMessage.SetHeader(ODataConstants.ContentTypeHeader, testDescriptor.TestCase.ContentTypeHeaderValue);

                            TestExceptionUtils.ExpectedException(
                                this.Assert,
                                () => testDescriptor.WriterInvocation.WriterAction(messageWriter),
                                /*expectedException*/ null,
                                this.ExceptionVerifier);

                            ODataFormat expectedFormat = TestMediaTypeUtils.GetDefaultFormat(payloadKind, clonedTestConfiguration.Format);

                            // Check that the content type header has been set correctly.
                            string contentTypeHeader = testMessage.GetHeader(ODataConstants.ContentTypeHeader);
                            string defaultContentType = TestMediaTypeUtils.GetDefaultContentType(payloadKind, expectedFormat);
                            if (payloadKind == ODataPayloadKind.Batch)
                            {
                                this.Assert.IsTrue(contentTypeHeader.StartsWith(defaultContentType), "Batch content type header does not start with expected prefix.");
                            }
                            else
                            {
                                this.Assert.AreEqual(defaultContentType, contentTypeHeader, "Content type header was not properly set.");
                            }

                            // Check that the format and encoding was properly set
                            ODataFormat actualFormat = messageWriter.PrivateFormat;
                            Encoding actualEncoding = messageWriter.PrivateEncoding;
                            this.Assert.AreEqual(expectedFormat, actualFormat, "Formats do not match!");
                            this.Assert.AreEqual(TestMediaTypeUtils.GetDefaultEncoding(payloadKind, actualFormat), actualEncoding, "Encodings do not match!");
                        }
                    }
                });
        }
Пример #22
0
        public void NoByteOrderMarkByDefaultTest()
        {
            IEdmModel model = Microsoft.Test.OData.Utils.Metadata.TestModels.BuildTestModel();

            this.CombinatorialEngineProvider.RunCombinations(
                writerActionsForPayloadKinds.Where(writerAction =>
                    writerAction.PayloadKind != ODataPayloadKind.Unsupported &&
                    writerAction.PayloadKind != ODataPayloadKind.Batch &&
                    writerAction.PayloadKind != ODataPayloadKind.Error &&
                    writerAction.PayloadKind != ODataPayloadKind.ServiceDocument &&
                    writerAction.PayloadKind != ODataPayloadKind.Value),
                this.WriterTestConfigurationProvider.AtomFormatConfigurations,
                (testCase, testConfiguration) =>
                {
                    testConfiguration = testConfiguration.Clone();
                    testConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri);

                    if (!testCase.PayloadKind.IsSupported(testConfiguration))
                    {
                        return;
                    }

                    using (var memoryStream = new TestStream())
                    {
                        TestMessage testMessage;
                        byte[] payload;
                        using (ODataMessageWriterTestWrapper messageWriter = TestWriterUtils.CreateMessageWriter(memoryStream, testConfiguration, this.Assert, out testMessage, null, model))
                        {
                            testCase.WriterAction(messageWriter);
                            payload = new byte[testMessage.TestStream.Length];
                            testMessage.TestStream.Seek(0, SeekOrigin.Begin);
                            this.Assert.IsTrue(testMessage.TestStream.Length >= 2, "payload is not big enough");

                            testMessage.TestStream.Read(payload, 0, 2 /* 2 bytes only are needed for validation */);
                        }

                        this.Assert.AreEqual(60, payload[0], "BOM might be present which is not expected");
                        this.Assert.AreEqual(63, payload[1], "BOM might be present which is not expected");
                    }
                });   
        }
            protected override TestMessage CreateInputMessage(ReaderTestConfiguration testConfiguration)
            {
                MemoryStream memoryStream = new MemoryStream(this.RawMessage);
                TestStream messageStream = new TestStream(memoryStream);
                if (testConfiguration.Synchronous)
                {
                    messageStream.FailAsynchronousCalls = true;
                }
                else
                {
                    messageStream.FailSynchronousCalls = true;
                }

                TestMessage testMessage = TestReaderUtils.CreateInputMessageFromStream(
                    messageStream,
                    testConfiguration,
                    this.PayloadElement.GetPayloadKindFromPayloadElement(),
                    this.BatchContentTypeHeader,
                    this.UrlResolver);

                return testMessage;
            }
Пример #24
0
        public void ODataFeedAndEntryWriterIncorrectPayload()
        {
            var testCases = new[]
                {
                    new
                    {
                        ODataWriterFunc = (Func<ODataMessageWriterTestWrapper, ODataWriter>)(messageWriter => messageWriter.CreateODataEntryWriter()),
                        WriteAction = (Action<ODataWriter>)(writer => writer.WriteStart(ObjectModelUtils.CreateDefaultFeed())),
                        ExpectedErrorMessage = "Cannot write a top-level feed with a writer that was created to write a top-level entry."
                    },
                    new
                    {
                        ODataWriterFunc = (Func<ODataMessageWriterTestWrapper, ODataWriter>)(messageWriter => messageWriter.CreateODataFeedWriter()),
                        WriteAction = (Action<ODataWriter>)(writer => writer.WriteStart(ObjectModelUtils.CreateDefaultEntry())),
                        ExpectedErrorMessage = "Cannot write a top-level entry with a writer that was created to write a top-level feed."
                    },
                };

            this.CombinatorialEngineProvider.RunCombinations(
                testCases,
                this.WriterTestConfigurationProvider.ExplicitFormatConfigurationsWithIndent,
                (testCase, testConfiguration) =>
                {
                    testConfiguration = testConfiguration.Clone();
                    testConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri);

                    using (var memoryStream = new TestStream())
                    {
                        TestMessage testMessage;
                        using (ODataMessageWriterTestWrapper messageWriter = TestWriterUtils.CreateMessageWriter(memoryStream, testConfiguration, this.Assert, out testMessage))
                        {
                            ODataWriter writer = testCase.ODataWriterFunc(messageWriter);
                            TestExceptionUtils.ExpectedException<ODataException>(
                                this.Assert,
                                () => testCase.WriteAction(writer),
                                testCase.ExpectedErrorMessage);
                        }
                    }
                });
        }
Пример #25
0
        private void WriterStatesTestImplementation(bool feedWriter)
        {
            var testCases = new WriterStatesTestDescriptor[]
            {
                // Start
                new WriterStatesTestDescriptor {
                    Setup = null,
                    ExpectedResults = new Dictionary<WriterAction, ExpectedException> { 
                        { WriterAction.StartEntry, feedWriter ? ODataExpectedExceptions.ODataException("ODataWriterCore_CannotWriteTopLevelEntryWithFeedWriter") : (ExpectedException)null },
                        { WriterAction.StartFeed, feedWriter ? (ExpectedException)null : ODataExpectedExceptions.ODataException("ODataWriterCore_CannotWriteTopLevelFeedWithEntryWriter") },
                        { WriterAction.StartLink, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidTransitionFromStart", "Start", "NavigationLink") },
                        { WriterAction.End, ODataExpectedExceptions.ODataException("ODataWriterCore_WriteEndCalledInInvalidState", "Start") },
                        { WriterAction.Error, null },
                    }
                },

                // Entry
                new WriterStatesTestDescriptor {
                    Setup = (mw, w, s) => { 
                        if (feedWriter) { w.WriteStart(ObjectModelUtils.CreateDefaultFeed()); }
                        w.WriteStart(ObjectModelUtils.CreateDefaultEntry()); 
                    },
                    ExpectedResults = new Dictionary<WriterAction, ExpectedException> { 
                        { WriterAction.StartEntry, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidTransitionFromEntry", "Entry", "Entry") },
                        { WriterAction.StartFeed, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidTransitionFromEntry", "Entry", "Feed") },
                        { WriterAction.StartLink, null },
                        { WriterAction.End, null },
                        { WriterAction.Error, null },
                    }
                },

                // Feed
                new WriterStatesTestDescriptor {
                    Setup = (mw, w, s) => { 
                        if (feedWriter) { w.WriteStart(ObjectModelUtils.CreateDefaultFeed()); }
                        else { w.WriteStart(ObjectModelUtils.CreateDefaultEntry()); w.WriteStart(ObjectModelUtils.CreateDefaultCollectionLink()); w.WriteStart(ObjectModelUtils.CreateDefaultFeed()); }
                    },
                    ExpectedResults = new Dictionary<WriterAction, ExpectedException> { 
                        { WriterAction.StartEntry, null },
                        { WriterAction.StartFeed, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidTransitionFromFeed", "Feed", "Feed") },
                        { WriterAction.StartLink, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidTransitionFromFeed", "Feed", "NavigationLink") },
                        { WriterAction.End, null },
                        { WriterAction.Error, null },
                    }
                },

                // Link - single
                new WriterStatesTestDescriptor {
                    Setup = (mw, w, s) => { 
                        if (feedWriter) { w.WriteStart(ObjectModelUtils.CreateDefaultFeed()); }
                        w.WriteStart(ObjectModelUtils.CreateDefaultEntry()); 
                        w.WriteStart(new ODataNavigationLink { Name = ObjectModelUtils.DefaultLinkName, Url = ObjectModelUtils.DefaultLinkUrl, IsCollection = false });
                    },
                    ExpectedResults = new Dictionary<WriterAction, ExpectedException> { 
                        { WriterAction.StartEntry, null },
                        { WriterAction.StartFeed, ODataExpectedExceptions.ODataException("WriterValidationUtils_ExpandedLinkIsCollectionFalseWithFeedContent", "http://odata.org/link") },
                        { WriterAction.StartLink, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidStateTransition", "NavigationLink", "NavigationLink") },
                        { WriterAction.End, null },
                        { WriterAction.Error, null },
                    },
                    SkipForTestConfiguration = tc => tc.IsRequest
                },

                // Link - collection
                new WriterStatesTestDescriptor {
                    Setup = (mw, w, s) => { 
                        if (feedWriter) { w.WriteStart(ObjectModelUtils.CreateDefaultFeed()); }
                        w.WriteStart(ObjectModelUtils.CreateDefaultEntry()); 
                        w.WriteStart(ObjectModelUtils.CreateDefaultCollectionLink());
                    },
                    ExpectedResults = new Dictionary<WriterAction, ExpectedException> { 
                        { WriterAction.StartEntry, ODataExpectedExceptions.ODataException("WriterValidationUtils_ExpandedLinkIsCollectionTrueWithEntryContent", "http://odata.org/link") },
                        { WriterAction.StartFeed, null },
                        { WriterAction.StartLink, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidStateTransition", "NavigationLink", "NavigationLink") },
                        { WriterAction.End, null },
                        { WriterAction.Error, null },
                    },
                    SkipForTestConfiguration = tc => tc.IsRequest
                },

                // Expanded link - there's no way to get to the expanded link state alone since the writer will always
                //   immediately transition to either entry or feed state instead.

                // Completed
                new WriterStatesTestDescriptor {
                    Setup = (mw, w, s) => {
                        if (feedWriter) { w.WriteStart(ObjectModelUtils.CreateDefaultFeed()); w.WriteEnd(); }
                        else { w.WriteStart(ObjectModelUtils.CreateDefaultEntry()); w.WriteEnd(); }
                    },
                    ExpectedResults = new Dictionary<WriterAction, ExpectedException> { 
                        { WriterAction.StartEntry, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidTransitionFromCompleted", "Completed", "Entry") },
                        { WriterAction.StartFeed, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidTransitionFromCompleted", "Completed", "Feed") },
                        { WriterAction.StartLink, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidTransitionFromCompleted", "Completed", "NavigationLink") },
                        { WriterAction.End, ODataExpectedExceptions.ODataException("ODataWriterCore_WriteEndCalledInInvalidState", "Completed") },
                        { WriterAction.Error, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidTransitionFromCompleted", "Completed", "Error") },
                    }
                },

                // ODataExceptionThrown
                new WriterStatesTestDescriptor {
                    Setup = (mw, w, s) => {
                        TestExceptionUtils.RunCatching(() => w.WriteStart(ObjectModelUtils.CreateDefaultCollectionLink()));
                    },
                    ExpectedResults = new Dictionary<WriterAction, ExpectedException> { 
                        { WriterAction.StartEntry, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidTransitionFromError", "Error", "Entry") },
                        { WriterAction.StartFeed, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidTransitionFromError", "Error", "Feed") },
                        { WriterAction.StartLink, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidTransitionFromError", "Error", "NavigationLink") },
                        { WriterAction.End, ODataExpectedExceptions.ODataException("ODataWriterCore_WriteEndCalledInInvalidState", "Error") },
                        { WriterAction.Error, null },
                    },
                    SkipForTestConfiguration = tc => tc.IsRequest,
                },

                // Error
                new WriterStatesTestDescriptor {
                    Setup = (mw, w, s) => {
                        mw.WriteError(new ODataError(), false);
                    },
                    ExpectedResults = new Dictionary<WriterAction, ExpectedException> { 
                        { WriterAction.StartEntry, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidTransitionFromError", "Error", "Entry") },
                        { WriterAction.StartFeed, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidTransitionFromError", "Error", "Feed") },
                        { WriterAction.StartLink, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidTransitionFromError", "Error", "NavigationLink") },
                        { WriterAction.End, ODataExpectedExceptions.ODataException("ODataWriterCore_WriteEndCalledInInvalidState", "Error") },
                        { WriterAction.Error, ODataExpectedExceptions.ODataException("ODataMessageWriter_WriteErrorAlreadyCalled") },
                    },
                    SkipForTestConfiguration = tc => tc.IsRequest,
                },
            };

            ExpectedException errorNotAllowedException = ODataExpectedExceptions.ODataException("ODataMessageWriter_ErrorPayloadInRequest");

            this.CombinatorialEngineProvider.RunCombinations(
                testCases,
                EnumExtensionMethods.GetValues<WriterAction>().Cast<WriterAction>(),
                this.WriterTestConfigurationProvider.AtomFormatConfigurations,
                (testCase, writerAction, testConfiguration) =>
                {
                    testConfiguration = testConfiguration.Clone();
                    testConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri);

                    if (testCase.SkipForTestConfiguration != null && testCase.SkipForTestConfiguration(testConfiguration))
                    {
                        return;
                    }

                    ExpectedException expectedExceptionOnError;
                    if (testCase.ExpectedResults.TryGetValue(WriterAction.Error, out expectedExceptionOnError))
                    {
                        if (testConfiguration.IsRequest)
                        {
                            testCase = new WriterStatesTestDescriptor(testCase);
                            testCase.ExpectedResults[WriterAction.Error] = errorNotAllowedException;
                        }
                    }

                    using (TestStream stream = new TestStream())
                    {
                        // We purposely don't use the using pattern around the messageWriter here. Disposing the message writer will
                        // fail here because the writer is not left in a valid state.
                        var messageWriter = TestWriterUtils.CreateMessageWriter(stream, testConfiguration, this.Assert);
                        ODataWriter writer = messageWriter.CreateODataWriter(feedWriter);

                        TestExceptionUtils.ExpectedException(
                            this.Assert,
                            () => 
                            {
                                if (testCase.Setup != null) testCase.Setup(messageWriter, writer, stream);
                                this.InvokeWriterAction(messageWriter, writer, writerAction); 
                            },
                            testCase.ExpectedResults[writerAction],
                            this.ExceptionVerifier);
                    }
                });
        }
        public void 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 => !tc.IsRequest && tc.Format == ODataFormat.Atom),
                (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);
                    }
                });
        }
Пример #27
0
        /// <summary>
        /// Helper method to create a test message from its content.
        /// </summary>
        /// <param name="messageContent">Stream with the content of the message.</param>
        /// <param name="testConfiguration">The test configuration.</param>
        /// <param name="payloadKind">The payload kind to use to compute and set the content type header; or null if no content type header should be set.</param>
        /// <param name="customContentTypeHeader">A custom content type header to be used in the message.</param>
        /// <param name="urlResolver">Url resolver to add to the test message created.</param>
        /// <returns>Newly created test message.</returns>
        public static TestMessage CreateInputMessageFromStream(
            TestStream messageContent, 
            ReaderTestConfiguration testConfiguration,
            ODataPayloadKind? payloadKind,
            string customContentTypeHeader,
            IODataUrlResolver urlResolver)
        {
            TestMessage message;
            if (testConfiguration.IsRequest)
            {
                if (urlResolver != null)
                {
                    message = new TestRequestMessageWithUrlResolver(messageContent, urlResolver, testConfiguration.Synchronous ? TestMessageFlags.NoAsynchronous : TestMessageFlags.NoSynchronous);
                }
                else
                {
                    message = new TestRequestMessage(messageContent, testConfiguration.Synchronous ? TestMessageFlags.NoAsynchronous : TestMessageFlags.NoSynchronous);
                }
            }
            else
            {
                if (urlResolver != null)
                {
                    message = new TestResponseMessageWithUrlResolver(messageContent, urlResolver, testConfiguration.Synchronous ? TestMessageFlags.NoAsynchronous : TestMessageFlags.NoSynchronous);
                }
                else
                {
                    message = new TestResponseMessage(messageContent, testConfiguration.Synchronous ? TestMessageFlags.NoAsynchronous : TestMessageFlags.NoSynchronous);
                }
            }

            // set the OData-Version header
            message.SetHeader(ODataConstants.ODataVersionHeader, testConfiguration.Version.ToText());

            if (customContentTypeHeader != null)
            {
                message.SetHeader(ODataConstants.ContentTypeHeader, customContentTypeHeader);
            }
            else if (payloadKind.HasValue)
            {
                message.SetContentType(testConfiguration.Format, payloadKind.Value);
            }

            return message;
        }
Пример #28
0
        public void SetHeadersForPayloadTest()
        {
            string multipleTypesWithQualityValues = "application/json;q=0.7, application/xml;q=0.2";

            IEnumerable<SetHeadersForPayloadTestCase> testCases = new SetHeadersForPayloadTestCase[]
                {
                    #region Invalid payload kind
                    new SetHeadersForPayloadTestCase
                    {
                        PayloadKind = ODataPayloadKind.Unsupported,
                        ExpectedException = ODataExpectedExceptions.ArgumentException("ODataMessageWriter_CannotSetHeadersWithInvalidPayloadKind", "Unsupported"),
                    },
                    #endregion Invalid payload kind

                    #region No accept headers
                    new SetHeadersForPayloadTestCase
                    {
                        PayloadKind = ODataPayloadKind.Batch,
                        ExpectedFormatFunc = tc => ODataFormat.Batch,
                    },
                    new SetHeadersForPayloadTestCase
                    {
                        PayloadKind = ODataPayloadKind.BinaryValue,
                        ExpectedFormatFunc = tc => ODataFormat.RawValue,
                    },
                    new SetHeadersForPayloadTestCase
                    {
                        PayloadKind = ODataPayloadKind.Collection,
                        ExpectedFormatFunc = tc => ODataFormat.Json,
                    },
                    new SetHeadersForPayloadTestCase
                    {
                        PayloadKind = ODataPayloadKind.EntityReferenceLink,
                        ExpectedFormatFunc = tc => ODataFormat.Json,
                    },
                    new SetHeadersForPayloadTestCase
                    {
                        PayloadKind = ODataPayloadKind.EntityReferenceLinks,
                        ExpectedFormatFunc = tc => ODataFormat.Json,
                    },
                    new SetHeadersForPayloadTestCase
                    {
                        PayloadKind = ODataPayloadKind.Entry,
                        ExpectedFormatFunc = tc => ODataFormat.Json,
                    },
                    new SetHeadersForPayloadTestCase
                    {
                        PayloadKind = ODataPayloadKind.Error,
                        ExpectedFormatFunc = tc => ODataFormat.Json,
                    },
                    new SetHeadersForPayloadTestCase
                    {
                        PayloadKind = ODataPayloadKind.Feed,
                        ExpectedFormatFunc = tc => ODataFormat.Json,
                    },
                    new SetHeadersForPayloadTestCase
                    {
                        PayloadKind = ODataPayloadKind.MetadataDocument,
                        ExpectedFormatFunc = tc => ODataFormat.Metadata,
                    },
                    new SetHeadersForPayloadTestCase
                    {
                        PayloadKind = ODataPayloadKind.Parameter,
                        ExpectedFormatFunc = tc => ODataFormat.Json,
                    },
                    new SetHeadersForPayloadTestCase
                    {
                        PayloadKind = ODataPayloadKind.Property,
                        ExpectedFormatFunc = tc => ODataFormat.Json,
                    },
                    new SetHeadersForPayloadTestCase
                    {
                        PayloadKind = ODataPayloadKind.ServiceDocument,
                        ExpectedFormatFunc = tc => ODataFormat.Json,
                    },
                    #endregion No accept headers

                    #region With accept headers
                    new SetHeadersForPayloadTestCase
                    {
                        PayloadKind = ODataPayloadKind.Batch,
                        AcceptHeader = "multipart/mixed, a/b, c/d",
                        ExpectedFormatFunc = tc => ODataFormat.Batch,
                    },
                    new SetHeadersForPayloadTestCase
                    {
                        PayloadKind = ODataPayloadKind.BinaryValue,
                        AcceptHeader = "application/octet-stream, a/b, c/d",
                        ExpectedFormatFunc = tc => ODataFormat.RawValue,
                    },
                    new SetHeadersForPayloadTestCase
                    {
                        PayloadKind = ODataPayloadKind.Collection,
                        AcceptHeader = multipleTypesWithQualityValues,
                        ExpectedFormatFunc = tc => ODataFormat.Json,
                    },
                    new SetHeadersForPayloadTestCase
                    {
                        PayloadKind = ODataPayloadKind.EntityReferenceLink,
                        AcceptHeader = multipleTypesWithQualityValues,
                        ExpectedFormatFunc = tc => ODataFormat.Json,
                    },
                    new SetHeadersForPayloadTestCase
                    {
                        PayloadKind = ODataPayloadKind.EntityReferenceLinks,
                        AcceptHeader = multipleTypesWithQualityValues,
                        ExpectedFormatFunc = tc => ODataFormat.Json,
                    },
                    new SetHeadersForPayloadTestCase
                    {
                        PayloadKind = ODataPayloadKind.Entry,
                        AcceptHeader = multipleTypesWithQualityValues,
                        ExpectedFormatFunc = tc => ODataFormat.Json,
                    },
                    new SetHeadersForPayloadTestCase
                    {
                        PayloadKind = ODataPayloadKind.Error,
                        AcceptHeader = multipleTypesWithQualityValues,
                        ExpectedFormatFunc = tc => ODataFormat.Json,
                    },
                    new SetHeadersForPayloadTestCase
                    {
                        PayloadKind = ODataPayloadKind.Feed,
                        AcceptHeader = multipleTypesWithQualityValues,
                        ExpectedFormatFunc = tc => ODataFormat.Json,
                    },
                    new SetHeadersForPayloadTestCase
                    {
                        PayloadKind = ODataPayloadKind.MetadataDocument,
                        AcceptHeader = multipleTypesWithQualityValues,
                        ExpectedFormatFunc = tc => ODataFormat.Metadata,
                    },
                    new SetHeadersForPayloadTestCase
                    {
                        PayloadKind = ODataPayloadKind.Parameter,
                        AcceptHeader = multipleTypesWithQualityValues,
                        ExpectedFormatFunc = tc => ODataFormat.Json,
                    },
                    new SetHeadersForPayloadTestCase
                    {
                        PayloadKind = ODataPayloadKind.Property,
                        AcceptHeader = multipleTypesWithQualityValues,
                        ExpectedFormatFunc = tc => ODataFormat.Json,
                    },
                    new SetHeadersForPayloadTestCase
                    {
                        PayloadKind = ODataPayloadKind.ServiceDocument,
                        AcceptHeader = multipleTypesWithQualityValues,
                        ExpectedFormatFunc = tc => ODataFormat.Json,
                    },
                    #endregion With accept headers

                    #region With accept charsets
                    new SetHeadersForPayloadTestCase
                    {
                        PayloadKind = ODataPayloadKind.Value,
                        AcceptHeader = "text/*",
                        AcceptCharSets = null,
                        ExpectedContentType = "text/plain;charset=utf-8",
                        ExpectedFormatFunc = tc => ODataFormat.RawValue,
                    },
                    new SetHeadersForPayloadTestCase
                    {
                        PayloadKind = ODataPayloadKind.Value,
                        AcceptHeader = "text/*",
                        AcceptCharSets = "utf-8",
                        ExpectedContentType = "text/plain;charset=utf-8",
                        ExpectedFormatFunc = tc => ODataFormat.RawValue,
                    },
                    new SetHeadersForPayloadTestCase
                    {
                        PayloadKind = ODataPayloadKind.Value,
                        AcceptHeader = "text/*",
                        AcceptCharSets = "utf-8",
                        ExpectedContentType = "text/plain;charset=utf-8",
                        ExpectedFormatFunc = tc => ODataFormat.RawValue,
                    },
                    new SetHeadersForPayloadTestCase
                    {
                        PayloadKind = ODataPayloadKind.Value,
                        AcceptHeader = "text/*",
                        AcceptCharSets = "utf-8,iso-8859-1",
                        ExpectedContentType = "text/plain;charset=utf-8",
                        ExpectedFormatFunc = tc => ODataFormat.RawValue,
                    },
                    new SetHeadersForPayloadTestCase
                    {
                        PayloadKind = ODataPayloadKind.Value,
                        AcceptHeader = "text/*",
                        AcceptCharSets = "iso-8859-1,utf-8",
                        ExpectedContentType = "text/plain;charset=iso-8859-1",
                        ExpectedFormatFunc = tc => ODataFormat.RawValue,
                    },
                    new SetHeadersForPayloadTestCase
                    {
                        PayloadKind = ODataPayloadKind.Value,
                        AcceptHeader = "text/*",
                        AcceptCharSets = "iso-8859-1,utf-8",
                        ExpectedContentType = "text/plain;charset=iso-8859-1",
                        ExpectedFormatFunc = tc => ODataFormat.RawValue,
                    },
                    new SetHeadersForPayloadTestCase
                    {
                        PayloadKind = ODataPayloadKind.Value,
                        AcceptHeader = "text/*",
                        // unsupported encoding name; return the default encoding
                        AcceptCharSets = "abc-pqr",
                        ExpectedContentType = "text/plain;charset=utf-8",
                        ExpectedFormatFunc = tc => ODataFormat.RawValue,
                    },
                    #endregion With accept charsets
                };

            this.CombinatorialEngineProvider.RunCombinations(
                testCases,
                this.WriterTestConfigurationProvider.DefaultFormatConfigurations,
                (testCase, testConfiguration) =>
                {
                    ODataPayloadKind payloadKind = testCase.PayloadKind;

                    TestExceptionUtils.ExpectedException(
                        this.Assert,
                        () =>
                        {
                            ODataMessageWriterSettings writerSettings = testConfiguration.MessageWriterSettings;
                            if (testCase.AcceptHeader != null)
                            {
                                writerSettings = writerSettings.Clone();
                                writerSettings.SetContentType(testCase.AcceptHeader, testCase.AcceptCharSets);
                            }

                            using (var memoryStream = new TestStream())
                            {
                                TestMessage testMessage;
                                using (ODataMessageWriterTestWrapper messageWriter = TestWriterUtils.CreateMessageWriter(memoryStream, testConfiguration, this.Assert, out testMessage, writerSettings))
                                {
                                    ODataFormat format = messageWriter.SetHeadersForPayload(testCase.PayloadKind);
                                    this.Assert.AreEqual(testCase.ExpectedFormatFunc(testConfiguration), format, "Formats don't match.");
                                }

                                // validate that the test message has the proper content type header set
                                if (testCase.ExpectedContentType != null)
                                {
                                    this.Assert.AreEqual(testCase.ExpectedContentType, testMessage.GetHeader(ODataConstants.ContentTypeHeader), "Content types don't match.");
                                }
                            }
                        },
                        testCase.ExpectedException,
                        this.ExceptionVerifier);
                });
        }
Пример #29
0
 /// <summary>
 /// Helper method to create a test message from its content.
 /// </summary>
 /// <param name="messageContent">Stream with the content of the message.</param>
 /// <param name="testConfiguration">The test configuration.</param>
 /// <returns>Newly created test message.</returns>
 public static TestMessage CreateInputMessageFromStream(TestStream messageContent, ReaderTestConfiguration testConfiguration)
 {
     return CreateInputMessageFromStream(messageContent, testConfiguration, null, null, null);
 }
Пример #30
0
        public void SetVersionInMessageHeaderTest()
        {
            IEdmModel model = Microsoft.Test.OData.Utils.Metadata.TestModels.BuildTestModel();

            IEnumerable<KeyValuePair<string, ODataVersion>> validMappings = ODataVersionUtils.AllSupportedVersions.Select(
                version => new KeyValuePair<string, ODataVersion>(ODataUtils.ODataVersionToString(version), version));

            string[] suffixes = new string[]
            {
                string.Empty,       // no user-agent string
                ";",                // empty user-agent string
                ";UserAgentString", // random user-agent string
                ";NetFx"            // user-agend string used by Astoria
            };

            // Build combinations of all valid versions with a set of interesting user agent strings
            IEnumerable<VersionMessageHeaderTestCase> testCases = validMappings.SelectMany(
                mapping => suffixes.Select(
                    suffix => new VersionMessageHeaderTestCase { VersionHeaderValue = mapping.Key + suffix, ExpectedVersion = mapping.Value }));

            // Add the 'null' header case (same as no header) => default version since no version on the settings
            testCases = testCases.ConcatSingle(new VersionMessageHeaderTestCase { VersionHeaderValue = null, ExpectedVersion = ODataVersionUtils.DefaultVersion });

            // Add some error combinations
            string[] invalidVersionHeaders = { "randomstring", "V1.0", "1.5", "randomstring;1.0", "1", ";UserAgentString" };
            IEnumerable<VersionMessageHeaderTestCase> errorTestCases = invalidVersionHeaders.Select(invalidHeader => 
                new VersionMessageHeaderTestCase
                {
                    VersionHeaderValue = invalidHeader,
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataUtils_UnsupportedVersionHeader", invalidHeader)
                });

            this.CombinatorialEngineProvider.RunCombinations(
                testCases.Concat(errorTestCases),
                writerActionsForPayloadKinds,
                this.WriterTestConfigurationProvider.AtomFormatConfigurations,
                (testCase, writerInvocation, testConfiguration) =>
                {
                    ODataPayloadKind payloadKind = writerInvocation.PayloadKind;
                    if (!payloadKind.IsSupported(testConfiguration))
                    {
                        return;
                    }

                    // Clone the test configuration and make sure no version is set
                    WriterTestConfiguration clonedTestConfiguration = testConfiguration.Clone();
                    clonedTestConfiguration.MessageWriterSettings.Version = null;
                    clonedTestConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri);

                    using (var memoryStream = new TestStream())
                    {
                        TestMessage testMessage;
                        using (ODataMessageWriterTestWrapper messageWriter = TestWriterUtils.CreateMessageWriter(memoryStream, clonedTestConfiguration, this.Assert, out testMessage, null, model))
                        {
                            // Set the version header in the test message
                            testMessage.SetHeader(ODataConstants.ODataVersionHeader, testCase.VersionHeaderValue);

                            TestExceptionUtils.ExpectedException(
                                this.Assert,
                                () => writerInvocation.WriterAction(messageWriter),
                                testCase.ExpectedException,
                                this.ExceptionVerifier);

                            if (testCase.ExpectedException != null)
                            {
                                // nothing more to do if we expected an exception
                                return;
                            }

                            // Check that the version was properly set
                            ODataMessageWriterSettings actualSettings = messageWriter.PrivateSettings;
                            this.Assert.IsNotNull(actualSettings.Version, "Version on actual writer settings must not be null!");
                            this.Assert.AreEqual(testCase.ExpectedVersion, actualSettings.Version, "Versions do not match!");

                            if (testCase.VersionHeaderValue == null)
                            {
                                this.Assert.AreEqual(ODataUtils.ODataVersionToString(ODataVersionUtils.DefaultVersion), testMessage.GetHeader(ODataConstants.ODataVersionHeader), "Default version should be append to hearders!");
                            }
                        }
                    }
                });
        }
Пример #31
0
        public void SetHeadersForPayloadAndInvalidCallsErrorTest()
        {
            string errorMessageTemplate = "The payload kind '{0}' used in the last call to ODataUtils.SetHeadersForPayload is incompatible with the payload being written which is of kind '{1}'.";

            this.CombinatorialEngineProvider.RunCombinations(
                writerActionsForPayloadKinds,
                this.WriterTestConfigurationProvider.AllFormatsConfigurationsWithIndent,
                (testCase, testConfiguration) =>
                {
                    ODataMessageWriterSettings settingsWithBaseUri = testConfiguration.MessageWriterSettings.Clone();
                    settingsWithBaseUri.PayloadBaseUri = baseUri;

                    ODataPayloadKind payloadKind = testCase.PayloadKind;

                    if (!payloadKind.IsSupported(testConfiguration))
                    {
                        return;
                    }

                    foreach (var writerAction in writerActionsForPayloadKinds)
                    {
                        if (writerAction.PayloadKind == ODataPayloadKind.Unsupported || !payloadKind.IsSupported(testConfiguration))
                        {
                            return;
                        }

                        // Continue to ensure we run all test cases for a given payload kind.
                        if (payloadKind == writerAction.PayloadKind)
                        {
                            continue;
                        }

                        using (var memoryStream = new TestStream())
                        {
                            TestMessage testMessage;
                            using (ODataMessageWriterTestWrapper messageWriter = TestWriterUtils.CreateMessageWriter(memoryStream, testConfiguration, this.Assert, out testMessage, settingsWithBaseUri))
                            {
                                // expecting an argument exception for unsupported kinds; no exception otherwise.
                                TestExceptionUtils.ExpectedException<ArgumentException>(
                                    this.Assert,
                                    // this will call ODataMessage.SetHeader for valid payload kinds.
                                    () => messageWriter.SetHeadersForPayload(payloadKind),
                                    payloadKind == ODataPayloadKind.Unsupported
                                        ? "Cannot set message headers for the invalid payload kind 'Unsupported'.\r\nParameter name: payloadKind" : null,
                                    null);

                                // nothing more to do for unsupported payload kinds
                                if (payloadKind == ODataPayloadKind.Unsupported)
                                {
                                    return;
                                }

                                string errorMessage = string.Format(errorMessageTemplate, payloadKind, writerAction.PayloadKind);

                                // we expect an exception if we try to write any other payload kinds
                                TestExceptionUtils.ExpectedException<ODataException>(
                                    this.Assert,
                                    () => writerAction.WriterAction(messageWriter),
                                    errorMessage,
                                    null);
                            }
                        }
                    }
                });
        }
        /// <summary>
        /// Called to create the input message for the reader test.
        /// </summary>
        /// <param name="testConfiguration">The test configuration.</param>
        /// <returns>The newly created test message to use.</returns>
        protected override TestMessage CreateInputMessage(ReaderTestConfiguration testConfiguration)
        {
            MemoryStream memoryStream = new MemoryStream(this.GetPayload(testConfiguration));
            TestStream messageStream = new TestStream(memoryStream);
            if (testConfiguration.Synchronous)
            {
                messageStream.FailAsynchronousCalls = true;
            }
            else
            {
                messageStream.FailSynchronousCalls = true;
            }

            TestMessage testMessage = TestReaderUtils.CreateInputMessageFromStream(
                messageStream, 
                testConfiguration, 
                ODataPayloadKind.MetadataDocument,
                this.ContentType,
                /*urlResolver*/ null);
            return testMessage;
        }