예제 #1
0
        public void RequestUriCaseInsensitive()
        {
            // Repro: Path to the .svc file shoud not be case sensitive.
            WebServerLocation[] locations = new WebServerLocation[]
            {
                WebServerLocation.InProcessWcf,
                WebServerLocation.Local
            };
            CombinatorialEngine engine = CombinatorialEngine.FromDimensions(
                new Dimension("location", locations));

            TestUtil.RunCombinatorialEngineFail(engine, delegate(Hashtable values)
            {
                WebServerLocation location = (WebServerLocation)values["location"];
                using (TestWebRequest request = TestWebRequest.CreateForLocation(location))
                {
                    request.DataServiceType      = typeof(CustomDataContext);
                    request.RequestUriString     = "/Customers";
                    request.FullRequestUriString = request.FullRequestUriString
                                                   .Replace(".svc", ".SvC")
                                                   .Replace("Test", "test");
                    request.SendRequest();
                    string response = request.GetResponseStreamAsText();
                    Trace.WriteLine(response);
                }
            });
        }
예제 #2
0
        public void RequestUriProcessorNotFoundErrorTest()
        {
            string[] requestValues = new string[]
            {
                // Traversing a property.
                "/Customers(1)/Name/More",

                // Non-existent property
                "/Customers(1)/SomeName",

                // Traversing a $value.
                "/Customers(1)/Name/$value/More",

                "/Customers%n0",
            };

            foreach (string responseFormat in UnitTestsUtil.ResponseFormats)
            {
                using (TestWebRequest request = TestWebRequest.CreateForLocation(WebServerLocation.InProcess))
                {
                    request.Accept          = responseFormat;
                    request.DataServiceType = typeof(CustomDataContext);
                    foreach (string requestValue in requestValues)
                    {
                        request.RequestUriString = requestValue;
                        VerifyResourceNotFoundError(request);
                    }
                }
            }
        }
예제 #3
0
        public static string GetResponse(string payload, Type contextType, WebServerLocation location, string requestVersion)
        {
            string[] segments = payload.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
            string   boundary = segments[0].Substring(2);

            using (TestWebRequest request = TestWebRequest.CreateForLocation(location))
            {
                request.RequestVersion  = requestVersion;
                request.DataServiceType = contextType;

                request.RequestUriString   = "/$batch";
                request.Accept             = UnitTestsUtil.MimeMultipartMixed;
                request.HttpMethod         = "POST";
                request.RequestContentType = String.Format("{0}; boundary={1}", UnitTestsUtil.MimeMultipartMixed, boundary);
                if (request.BaseUri != null)
                {
                    payload = Regex.Replace(payload, "\\$\\(BaseUri\\)", request.BaseUri.EndsWith("/") ? request.BaseUri : request.BaseUri + "/");
                }

                request.RequestStream = IOUtil.CreateStream(payload);
                request.SendRequest();
                Stream responseStream = request.GetResponseStream();
                using (StreamReader reader = new StreamReader(responseStream))
                {
                    return(PrepareResponseForFileCompare(reader, request.BaseUri, "$(BaseUri)"));
                }
            }
        }
예제 #4
0
        public void RequestUriProcessorDollarValueMustComeAfterMleError()
        {
            string[] requestValues = new string[]
            {
                // $value after a non-MLE entity should fail.
                "/Customers(1)/$value",
            };

            foreach (string responseFormat in UnitTestsUtil.ResponseFormats)
            {
                using (TestWebRequest request = TestWebRequest.CreateForLocation(WebServerLocation.InProcess))
                {
                    request.Accept          = responseFormat;
                    request.DataServiceType = typeof(CustomDataContext);
                    foreach (string requestValue in requestValues)
                    {
                        request.RequestUriString = requestValue;
                        Exception e = TestUtil.RunCatching(request.SendRequest);
                        Assert.IsNotNull(e);
                        Assert.AreEqual(400, request.ResponseStatusCode);
                        Assert.AreEqual(typeof(DataServiceException), e.InnerException.GetType());
                        Assert.AreEqual("The URI 'http://host/Customers(1)/$value' is not valid. The segment before '$value' must be a Media Link Entry or a primitive property.", e.InnerException.Message);
                    }
                }
            }
        }
예제 #5
0
        public void HttpContextServiceHostRequestNameTest()
        {
            CombinatorialEngine engine = CombinatorialEngine.FromDimensions(
                new Dimension("WebServerLocation", new WebServerLocation[] { WebServerLocation.InProcessWcf }),
                new Dimension("LocalHostName", new string[] { "127.0.0.1" }));

            TestUtil.RunCombinatorialEngineFail(engine, delegate(Hashtable values)
            {
                WebServerLocation location = (WebServerLocation)values["WebServerLocation"];
                string hostName            = (string)values["LocalHostName"];
                using (TestWebRequest request = TestWebRequest.CreateForLocation(location))
                {
                    request.DataServiceType  = typeof(CustomDataContext);
                    request.RequestUriString = "/Customers(1)?$format=atom";
                    request.StartService();

                    UriBuilder builder = new UriBuilder(request.FullRequestUriString);
                    builder.Host       = hostName;
                    WebClient client   = new WebClient();
                    string response    = client.DownloadString(builder.Uri);

                    response             = response.Substring(response.IndexOf('<'));
                    XmlDocument document = new XmlDocument(TestUtil.TestNameTable);
                    document.LoadXml(response);
                    string baseUri = UnitTestsUtil.GetBaseUri(document.DocumentElement);
                    TestUtil.AssertContains(baseUri, hostName);
                }
            });
        }
예제 #6
0
        public void JsonLightPayloadMetadataIntegrationTest()
        {
            Stream resultStream = UnitTestsUtil.GetResponseStream(WebServerLocation.InProcess, "application/json;odata.metadata=none", "/Customers?$select=Name", typeof(CustomDataContext));
            Stream stream       = TestUtil.EnsureStreamWithSeek(resultStream);
            string actualText   = new StreamReader(stream).ReadToEnd();

            const string expectedSuccessText = @"{""value"":[{""Name"":""Customer 0""},{""Name"":""Customer 1""},{""Name"":""Customer 2""}]}";

            Assert.AreEqual(expectedSuccessText, actualText);

            // now test that it is fails for the query option
            // $controlinfo was briefly used for controlling how much metadata a client wanted
            // in JSON-Light payloads. It was removed and replaced with a parameter in the media type.
            using (TestWebRequest request = TestWebRequest.CreateForLocation(WebServerLocation.InProcessWcf))
            {
                request.DataServiceType  = typeof(CustomDataContext);
                request.RequestUriString = "/Customers?$controlinfo=all";
                request.Accept           = "application/json;odata.metadata=minimal";

                TestUtil.RunCatching(() => request.SendRequest());

                Assert.AreEqual(400, request.ResponseStatusCode);
            }

            // now test that it is fails for 'odata-light' which was also eventually replaced.
            using (TestWebRequest request = TestWebRequest.CreateForLocation(WebServerLocation.InProcessWcf))
            {
                request.DataServiceType  = typeof(CustomDataContext);
                request.RequestUriString = "/Customers";
                request.Accept           = "application/json;odata.metadata=light";

                TestUtil.RunCatching(() => request.SendRequest());

                Assert.AreEqual(415, request.ResponseStatusCode);
            }

            // now test that it is fails with 'metadata' parameter which was later combined into the 'odata' parameter.
            using (TestWebRequest request = TestWebRequest.CreateForLocation(WebServerLocation.InProcessWcf))
            {
                request.DataServiceType  = typeof(CustomDataContext);
                request.RequestUriString = "/Customers";
                request.Accept           = "application/json;odata.metadata=minimal;metadata=all";

                TestUtil.RunCatching(() => request.SendRequest());

                Assert.AreEqual(415, request.ResponseStatusCode);
            }

            // Now test that it fails for an invalid type/subtype.
            using (TestWebRequest request = TestWebRequest.CreateForLocation(WebServerLocation.InProcessWcf))
            {
                request.DataServiceType  = typeof(CustomDataContext);
                request.RequestUriString = "/Customers";
                request.Accept           = "fake/things;odata.metadata=minimal";

                TestUtil.RunCatching(() => request.SendRequest());

                Assert.AreEqual(415, request.ResponseStatusCode);
            }
        }
예제 #7
0
        public void RequestUriResourceKeyTest()
        {
            CombinatorialEngine engine = CombinatorialEngine.FromDimensions(
                new Dimension("TypeData", TypeData.Values),
                new Dimension("UseSmallCasing", new bool[] { true, false }),
                new Dimension("UseDoublePostfix", new bool[] { true, false }));

            TestUtil.RunCombinatorialEngineFail(engine, delegate(Hashtable values)
            {
                TypeData typeData = (TypeData)values["TypeData"];
                if (!typeData.IsTypeSupportedAsKey)
                {
                    return;
                }

                // TODO: when System.Uri handles '/' correctly, re-enable.
                if (typeData.ClrType == typeof(System.Xml.Linq.XElement))
                {
                    return;
                }

                Type entityType = typeof(TypedEntity <,>).MakeGenericType(typeData.ClrType, typeof(int));
                CustomDataContextSetup setup = new CustomDataContextSetup(entityType);
                object idValue = typeData.NonNullValue;
                if (idValue is byte[])
                {
                    // idValue = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
                    return;
                }

                bool useSmallCasing   = (bool)values["UseSmallCasing"];
                bool useDoublePostFix = (bool)values["UseDoublePostfix"];

                if (!(idValue is double) && useDoublePostFix)
                {
                    return;
                }

                string valueAsString = TypeData.FormatForKey(idValue, useSmallCasing, useDoublePostFix);
                using (TestWebRequest request = TestWebRequest.CreateForLocation(WebServerLocation.InProcess))
                {
                    Trace.WriteLine("Running with value: [" + valueAsString + "] for [" + typeData.ToString() + "]");
                    setup.Id                 = idValue;
                    setup.MemberValue        = 1;
                    request.DataServiceType  = setup.DataServiceType;
                    request.Accept           = "application/json";
                    request.RequestUriString = "/Values(" + valueAsString + ")";

                    Trace.WriteLine("RequestUriString: " + request.RequestUriString);
                    request.SendRequest();
                    request.GetResponseStreamAsText();
                }

                setup.Cleanup();
            });
        }
예제 #8
0
 public void InvalidMetadataForEntityHierarchy()
 {
     // Create the custom data context
     using (TestWebRequest request = TestWebRequest.CreateForLocation(WebServerLocation.InProcess))
     {
         request.DataServiceType  = typeof(BadMetadataProvider);
         request.RequestUriString = "/$metadata";
         Exception exception = TestUtil.RunCatching(delegate()
         {
             request.SendRequest();
             request.GetResponseStream();
         });
         Assert.IsInstanceOfType(exception, typeof(InvalidOperationException));
         Assert.AreEqual(true, exception.Message.Contains("IgnoreProperties"));
     }
 }
예제 #9
0
        public void WebDataServiceDocumentTest()
        {
            CombinatorialEngine engine = CombinatorialEngine.FromDimensions(
                new Dimension("Location", new object[] { WebServerLocation.InProcess, WebServerLocation.InProcessWcf }),
                new Dimension("ServiceModelData", ServiceModelData.Values),
                new Dimension("Accept", new string[]
            {
                "application/atomsvc+xml",
                "application/atomsvc+xml;q=0.8",
                "application/xml",
                "application/xml;q=0.5"
            }));

            TestUtil.RunCombinatorialEngineFail(engine, delegate(Hashtable values)
            {
                string accept = (string)values["Accept"];
                WebServerLocation location = (WebServerLocation)values["Location"];
                ServiceModelData model     = (ServiceModelData)values["ServiceModelData"];
                if (!model.IsValid)
                {
                    return;
                }

                using (TestWebRequest request = TestWebRequest.CreateForLocation(location))
                {
                    request.Accept           = accept;
                    request.DataServiceType  = model.ServiceModelType;
                    request.RequestUriString = "/";
                    request.SendRequest();

                    XmlDocument document = request.GetResponseStreamAsXmlDocument();
                    string responseType  = TestUtil.GetMediaType(request.ResponseContentType);
                    if (accept.Contains("application/atomsvc+xml"))
                    {
                        Assert.AreEqual("application/atomsvc+xml", responseType);
                    }
                    else
                    {
                        Assert.AreEqual("application/xml", responseType);
                    }

                    Trace.WriteLine(document.OuterXml);
                    CheckServiceDocument(document);
                }
            });
        }
예제 #10
0
        public void RequestUriResourceSetPropertyTest()
        {
            Func <Hashtable, XmlDocument, bool> testCallBack = (values, document) =>
            {
                string responseFormat = (string)values["ResponseFormat"];
                string xPath;

                if (responseFormat == UnitTestsUtil.JsonLightMimeType)
                {
                    xPath = String.Format("/{0}/{1}/ID", JsonValidator.ArrayString, JsonValidator.ObjectString);
                }
                else
                {
                    Assert.IsTrue(responseFormat == UnitTestsUtil.AtomFormat, "unexpected format");
                    xPath = "/atom:feed/atom:entry/atom:content/adsm:properties/ads:ID";
                }

                XmlElement order = (XmlElement)document.SelectSingleNode(xPath, TestUtil.TestNamespaceManager);

                using (TestWebRequest request = TestWebRequest.CreateForLocation(WebServerLocation.InProcess))
                {
                    request.RequestUriString = "/Customers(0)/Orders(" + order.InnerText + ")";
                    request.Accept           = responseFormat;
                    request.DataServiceType  = typeof(CustomDataContext);
                    request.SendRequest();

                    UnitTestsUtil.VerifyXPaths(request.GetResponseStream(), responseFormat,
                                               new string[] { "/cdc:Order" },
                                               new string[] { JsonValidator.GetJsonTypeXPath(typeof(Order), false /*isArray*/) },
                                               new string[0]);

                    return(true);
                }
            };

            UnitTestsUtil.VerifyPayload("/Customers(0)/Orders", typeof(CustomDataContext), testCallBack,
                                        new string[] { "/cdc:Orders",
                                                       "/cdc:Orders/cdc:Order" },
                                        new string[] { String.Format("/{0}", JsonValidator.ArrayString),
                                                       JsonValidator.GetJsonTypeXPath(typeof(Order), true /*isArray*/) },
                                        new string[0]);

            // TODO: When this is fixed, we should uncomment this test cases
            //UnitTestsUtil.VerifyInvalidUri("/Customers!1000/Orders", typeof(CustomDataContext));
            UnitTestsUtil.VerifyInvalidUri("/Customers(1)/Orders(10000)", typeof(CustomDataContext));
        }
예제 #11
0
        public void RequestUriProcessorSyntaxErrorTest()
        {
            string[] requestValues = new string[]
            {
                // Wrong number of keys.
                "/Customers(1,2)",

                //// Wrong key type.
                "/Customers(a)",
                // "/Customers(1).", // NOTE: trailing period not significant to System.Uri
                "/Customers(1.0)",

                // Wrong paren and quote format.
                "/Customers(1(",
                "/Customers(1",
                "/Customers('1",
                "/Customers('1')",

                // Traversing through non-single element.
                "/Customers/Customer",

                // Wrong place to put key information.
                "/Customers(1)/Name(1)",
                "/Customers(1)/Name/$value(1)",

                // Starting with .Net 4.5, Uri.UnescapeDataString does not throw an exception on invalid sequence. It just does not unescape something
                // that it does not understand. The url below fails with 404 segment not found instead of 400. Hence disabling this scenario.
                // Malformed Uri
                // "/Customers%FF",
            };

            foreach (string responseFormat in UnitTestsUtil.ResponseFormats)
            {
                using (TestWebRequest request = TestWebRequest.CreateForLocation(WebServerLocation.InProcess))
                {
                    request.Accept          = responseFormat;
                    request.DataServiceType = typeof(CustomDataContext);
                    foreach (string requestValue in requestValues)
                    {
                        request.RequestUriString = requestValue;
                        VerifyRequestSyntaxError(request);
                    }
                }
            }
        }
예제 #12
0
 public void ProcessGetTest()
 {
     foreach (WebServerLocation location in new WebServerLocation[] { WebServerLocation.InProcess, WebServerLocation.InProcessWcf })
     {
         using (TestWebRequest request = TestWebRequest.CreateForLocation(location))
         {
             request.DataServiceType  = typeof(CustomDataContext);
             request.RequestUriString = "/$metadata";
             request.SendRequest();
             Stream     resultStream = request.GetResponseStream();
             TextReader reader       = new StreamReader(resultStream);
             string     resultText   = reader.ReadToEnd();
             Assert.IsTrue(resultText.Length > 0);
             Assert.IsTrue(resultText.Contains("Customers"));
             request.Dispose();
         }
     }
 }
예제 #13
0
        public void RequestUriProcessorRootTest()
        {
            CombinatorialEngine engine = CombinatorialEngine.FromDimensions(
                new Dimension("UriString", new string[] { "", "/" }));

            TestUtil.RunCombinatorialEngineFail(engine, delegate(Hashtable values)
            {
                string s = (string)values["UriString"];
                using (TestWebRequest request = TestWebRequest.CreateForLocation(WebServerLocation.InProcess))
                {
                    request.DataServiceType  = typeof(CustomDataContext);
                    request.Accept           = "application/json";
                    request.RequestUriString = s;
                    request.SendRequest();
                    string expectedContentType = "application/json;odata.metadata=minimal";
                    Assert.AreEqual(expectedContentType, TestUtil.GetMediaType(request.ResponseContentType));
                }
            });
        }
예제 #14
0
 public void InvalidMetadataTestCases()
 {
     foreach (Type type in GetInvalidTypes())
     {
         // Create the custom data context
         using (TestWebRequest request = TestWebRequest.CreateForLocation(WebServerLocation.InProcess))
         {
             request.DataServiceType  = typeof(TypedCustomDataContext <>).MakeGenericType(type);
             request.RequestUriString = "/$metadata";
             Exception exception = TestUtil.RunCatching(delegate()
             {
                 request.SendRequest();
                 request.GetResponseStream();
             });
             System.Data.Test.Astoria.AstoriaTestLog.IsNotNull(exception,
                                                               String.Format("The invalid type case should not throw an exception: '{0}'", type.Name));
         }
     }
 }
예제 #15
0
            public void SecurityStackOverflowTest()
            {
                CombinatorialEngine engine = CombinatorialEngine.FromDimensions(
                    new Dimension("Feature", StackConsumingFeatureData.Values),
                    new Dimension("UseCollections", new bool [] { false, true }));

                TestUtil.RunCombinatorialEngineFail(engine, delegate(Hashtable values)
                {
                    StackConsumingFeatureData feature = (StackConsumingFeatureData)values["Feature"];
                    WebServerLocation location        = WebServerLocation.InProcess;
                    bool useCollections = (bool)values["UseCollections"];

                    using (TestWebRequest request = TestWebRequest.CreateForLocation(location))
                    {
                        if (useCollections)
                        {
                            // Collection switch only does a collection version of the test for serializers
                            if (feature.Feature != StackConsumingFeature.AtomSerializer &&
                                feature.Feature != StackConsumingFeature.JsonSerializer &&
                                feature.Feature != StackConsumingFeature.XmlSerializer)
                            {
                                return;
                            }
                            request.RequestVersion    = "4.0";
                            request.RequestMaxVersion = "4.0";
                        }

                        feature.SetupOverflowRequest(request, useCollections);
                        Exception exception = TestUtil.RunCatching(request.SendRequest);

                        TestUtil.AssertExceptionExpected(exception, true);
                        TestUtil.AssertExceptionStatusCode(exception, feature.ExpectedStatusCode, "");
                        if (location == WebServerLocation.InProcess)
                        {
                            TestUtil.AssertContains(request.GetResponseStreamAsText(), feature.ErrorMessageKey);
                        }
                    }
                });
            }
예제 #16
0
        public void WebDataServiceDocumentJsonLightTest()
        {
            // Smoke test to verify that JSON Light service document can be written through the server. Detailed format-specific tests are in ODL.
            CombinatorialEngine engine = CombinatorialEngine.FromDimensions(
                new Dimension("Location", new object[] { WebServerLocation.InProcess, WebServerLocation.InProcessWcf }),
                new Dimension("Accept", new string[]
            {
                "application/json",
                "application/json;odata.metadata=minimal"
            }));

            TestUtil.RunCombinatorialEngineFail(engine, delegate(Hashtable values)
            {
                string accept = (string)values["Accept"];
                WebServerLocation location = (WebServerLocation)values["Location"];
                ServiceModelData model     = ServiceModelData.CustomData;

                Assert.IsTrue(model.IsValid);

                using (TestWebRequest request = TestWebRequest.CreateForLocation(location))
                {
                    request.Accept           = accept;
                    request.DataServiceType  = model.ServiceModelType;
                    request.RequestUriString = "/";
                    request.SendRequest();

                    string response     = request.GetResponseStreamAsText();
                    string responseType = TestUtil.GetMediaType(request.ResponseContentType);
                    Assert.AreEqual("application/json;odata.metadata=minimal", responseType);

                    Trace.WriteLine(response);

                    // Customers is defined in ServiceModelData.
                    // Smoke test: Confirm that it's written out as the name of a resource collection somewhere in the service document.
                    Assert.IsTrue(response.Contains("{\"name\":\"Customers\""), "Expected to find \"Customers\" resource collection formatted as JSON Light");
                }
            });
        }
예제 #17
0
        /// <summary>Starts the service for the specified location and returns a new TestWebRequest pointing to that service.</summary>
        /// <param name="location">The location where to start the service.</param>
        /// <returns>The newly created TestWebRequest.</returns>
        public TestWebRequest CreateForLocation(test.WebServerLocation location)
        {
            Debug.Assert(current == null, "Can't have two instances of TestWebRequest against any service definition at any given time.");
            Debug.Assert(
                (this.ServiceType == null || this.DataServiceType == null) && (this.DataServiceType != null || this.ServiceType != null),
                "Either DataServiceType or ServiceType must not be null, but only one can be specified.");

            TestWebRequest request = TestWebRequest.CreateForLocation(location);

            if (this.DataServiceType != null)
            {
                request.DataServiceType = this.DataServiceType;
            }
            else
            {
                request.ServiceType = this.ServiceType;
            }

            current = this;
            current.InitializeService(request);
            request.RegisterForDispose(() => { current = null; });

            return(request);
        }
예제 #18
0
        public void PlainSerializersBasicTest()
        {
            CombinatorialEngine engine = CombinatorialEngine.FromDimensions(
                new Dimension("ValidMime", new object[] { true, false }),
                new Dimension("SpecificMime", new object[] { true, false }),
                new Dimension("TypeData", TypeData.Values));
            Hashtable table = new Hashtable();

            while (engine.Next(table))
            {
                bool     validMime    = (bool)table["ValidMime"];
                bool     specificMime = (bool)table["SpecificMime"];
                TypeData typeData     = (TypeData)table["TypeData"];

                // If ValidMime is false, whether it's specific or not doesn't matter.
                if (!validMime && specificMime)
                {
                    continue;
                }

                if (!typeData.IsTypeSupported)
                {
                    continue;
                }

                using (TestWebRequest request = TestWebRequest.CreateForLocation(WebServerLocation.InProcess))
                {
                    Type valueType  = typeData.ClrType;
                    Type entityType = typeof(TypedEntity <,>).MakeGenericType(typeof(int), valueType);
                    CustomDataContextSetup dataContextSetup = new CustomDataContextSetup(entityType);
                    dataContextSetup.Id          = 1;
                    dataContextSetup.MemberValue = typeData.NonNullValue;

                    Type serviceType = dataContextSetup.DataServiceType;
                    request.DataServiceType  = serviceType;
                    request.RequestUriString = "/Values(1)/Member/$value";
                    if (validMime)
                    {
                        request.Accept = TypeData.FindForType(valueType).DefaultContentType;
                    }
                    else
                    {
                        request.Accept = "application/unexpected";
                    }

                    try
                    {
                        request.SendRequest();
                        if (!validMime)
                        {
                            Assert.Fail("Request should have failed.");
                        }
                    }
                    catch (WebException)
                    {
                        if (!validMime)
                        {
                            continue;
                        }
                        throw;
                    }

                    string expectedType = request.Accept;
                    Assert.AreEqual(expectedType, TestUtil.GetMediaType(request.ResponseContentType));

                    Stream stream = request.GetResponseStream();
                    if (valueType == typeof(byte[]))
                    {
                        byte[] bytes = (byte[])dataContextSetup.MemberValue;
                        for (int i = 0; i < bytes.Length; i++)
                        {
                            Assert.AreEqual(bytes[i], (byte)stream.ReadByte());
                        }
                    }
                    else
                    {
                        using (StreamReader reader = new StreamReader(stream))
                        {
                            typeData.VerifyAreEqual(dataContextSetup.MemberValue, typeData.ValueFromXmlText(reader.ReadToEnd(), request.Accept), request.Accept);
                        }
                    }
                }
            }
        }
예제 #19
0
        public void EncodingFromAcceptCharsetTest()
        {
            // It takes over a minute to run all combinations.
            CombinatorialEngine engine = CombinatorialEngine.FromDimensions(
                new Dimension("EncodingData", EncodingData.Values),
                new Dimension("StringData", StringData.Values),
                new Dimension("SerializationFormatData", SerializationFormatData.StructuredValues),
                new Dimension("WebServerLocation", new object[] { WebServerLocation.InProcess }));

            engine.Mode = CombinatorialEngineMode.EveryElement;

            TestUtil.RunCombinatorialEngineFail(engine, delegate(Hashtable table)
            {
                EncodingData encodingData      = (EncodingData)table["EncodingData"];
                StringData stringData          = (StringData)table["StringData"];
                WebServerLocation location     = (WebServerLocation)table["WebServerLocation"];
                SerializationFormatData format = (SerializationFormatData)table["SerializationFormatData"];

                if (encodingData.Encoding == null)
                {
                    return;
                }

                if (!EncodingHandlesString(encodingData.Encoding, "<>#&;\r\n"))
                {
                    return;
                }

                // Transliteration of ISCII characters and Unicode is possible, but round-tripping from
                // Unicode will not work because all phonetic sounds share an ISCII value, but have
                // distinct Unicode points depending on the language.
                if (encodingData.Name.StartsWith("x-iscii") && stringData.TextScript != null && stringData.TextScript.SupportsIscii)
                {
                    return;
                }

                using (CustomDataContext.CreateChangeScope())
                    using (TestWebRequest request = TestWebRequest.CreateForLocation(location))
                    {
                        request.DataServiceType    = typeof(CustomDataContext);
                        request.HttpMethod         = "POST";
                        request.RequestUriString   = "/Customers";
                        request.RequestContentType = UnitTestsUtil.JsonLightMimeType;
                        request.SetRequestStreamAsText("{ " +
                                                       "@odata.type : \"AstoriaUnitTests.Stubs.Customer\" ," +
                                                       "ID: 100," +
                                                       "Name: " +
                                                       System.Data.Test.Astoria.Util.JsonPrimitiveTypesUtil.PrimitiveToString(stringData.Value, typeof(string)) +
                                                       " }");
                        request.SendRequest();

                        request.HttpMethod       = "GET";
                        request.AcceptCharset    = encodingData.Name;
                        request.Accept           = format.MimeTypes[0];
                        request.RequestUriString = "/Customers(100)";

                        bool encoderCanHandleData = EncodingHandlesString(encodingData.Encoding, stringData.Value);
                        Trace.WriteLine("Encoding handles string: " + encoderCanHandleData);

                        Exception exception = TestUtil.RunCatching(request.SendRequest);

                        XmlDocument document = null;
                        Stream byteStream    = new MemoryStream();
                        if (exception == null)
                        {
                            using (Stream stream = request.GetResponseStream())
                            {
                                IOUtil.CopyStream(stream, byteStream);
                            }

                            byteStream.Position = 0;
                            Trace.WriteLine(TestUtil.BuildHexDump(byteStream));
                            byteStream.Position = 0;

                            if (format == SerializationFormatData.Atom)
                            {
                                document = new XmlDocument(TestUtil.TestNameTable);
                                using (StreamReader reader = new StreamReader(byteStream, encodingData.Encoding))
                                {
                                    document.Load(reader);
                                }

                                TestUtil.TraceXml(document);

                                XmlElement nameElement = TestUtil.AssertSelectSingleElement(document, "//ads:Name");
                                if (stringData.Value == null)
                                {
                                    Assert.IsTrue(UnitTestsUtil.HasElementNullValue(nameElement,
                                                                                    new System.Net.Mime.ContentType(request.ResponseContentType).MediaType));
                                }
                                else
                                {
                                    Assert.AreEqual(stringData.Value, nameElement.InnerText);
                                }
                            }
                        }
                        else
                        {
                            TestUtil.AssertExceptionExpected(exception, !encoderCanHandleData);
                        }
                    }
            });
        }
예제 #20
0
        public void ProcessExceptionTest()
        {
            Type[] exceptionTypes = new Type[]
            {
                typeof(OutOfMemoryException),
                typeof(DataServiceException),
                typeof(FormatException),
                typeof(DataServiceException),
            };

            // At-End is currently always true, because the IQueryable caching
            // doesn't give us a good point to fail before content is written out.
            CombinatorialEngine engine = CombinatorialEngine.FromDimensions(
                new Dimension(CustomDataContext.ExceptionTypeArgument, exceptionTypes),
                new Dimension(CustomDataContext.ExceptionAtEndArgument, new object[] { true }),
                new Dimension("Format", SerializationFormatData.Values),
                new Dimension("WebServerLocation", new object[] { WebServerLocation.InProcess, WebServerLocation.Local }));

            TestUtil.RunCombinatorialEngineFail(engine, delegate(Hashtable values)
            {
                Type exceptionType             = (Type)values[CustomDataContext.ExceptionTypeArgument];
                bool exceptionAtEnd            = (bool)values[CustomDataContext.ExceptionAtEndArgument];
                SerializationFormatData format = (SerializationFormatData)values["Format"];
                WebServerLocation location     = (WebServerLocation)values["WebServerLocation"];

                // The local web server doesn't handle OOF gracefully - skip that case.
                if (exceptionType == typeof(OutOfMemoryException) &&
                    location == WebServerLocation.Local)
                {
                    return;
                }

                // No binary properties in the model.
                if (format.Name == "Binary")
                {
                    return;
                }

                // We need at least 1024 bytes to be written out for the default
                // StreamWriter used by the XmlTextWriter to flush out (at which point
                // we can assume that throwing at the end of the stream caused
                // a "partial send").
                //
                // However the implementation ends up using an XmlUtf8RawTextWriterIndent
                // object, with a BUFSIZE of 0x1800 as declared on XmlUtf8RawTextWriter.
                //
                // (0x1800 / "Customer 1".Length) + 1 is ideal, but we can make do with much less.
                int customerCount = (0xA0 / "Customer 1".Length) + 1;
                values[CustomDataContext.CustomerCountArgument] = customerCount;

                using (TestWebRequest request = TestWebRequest.CreateForLocation(location))
                {
                    request.DataServiceType  = typeof(CustomDataContext);
                    request.TestArguments    = values;
                    request.Accept           = format.MimeTypes[0];
                    request.RequestUriString =
                        (format.Name == "Text") ? "/Customers(" + customerCount + ")/ID/$value" : "/Customers";

                    Trace.WriteLine("Requesting " + request.RequestUriString);
                    Stream response           = new MemoryStream();
                    Exception thrownException = null;
                    try
                    {
                        request.SendRequest();
                        thrownException = new ApplicationException("No exception actually thrown.");
                    }
                    catch (Exception exception)
                    {
                        thrownException = exception;
                    }

                    // InProcess always throws WebException. Look in the inner exception for the right exception type.
                    if (location == WebServerLocation.InProcess && !format.IsPrimitive && exceptionType != typeof(OutOfMemoryException))
                    {
                        Assert.AreEqual(typeof(WebException), thrownException.GetType(), "InProcess should always throw WebException - Look in TestServiceHost.ProcessException");
                        thrownException = thrownException.InnerException;
                    }

                    // Exception may be wrapped by TargetInvocationException.
                    if (thrownException is TargetInvocationException)
                    {
                        thrownException = thrownException.InnerException;
                    }

                    TestUtil.CopyStream(request.GetResponseStream(), response);

                    response.Position = 0;
                    if (exceptionAtEnd && !format.IsPrimitive)
                    {
                        // for inprocess, there will be no exception in the payload
                        if (location == WebServerLocation.InProcess)
                        {
                            // Verify the exception type
                            Assert.AreEqual(exceptionType, thrownException.GetType(), "Exception type did not match");
                            return;
                        }

                        Assert.IsTrue(HasContent(response), "HasContent(response)");
                        Assert.IsTrue(String.Equals(request.Accept, TestUtil.GetMediaType(request.ResponseContentType), StringComparison.OrdinalIgnoreCase));
                        if (exceptionType != typeof(OutOfMemoryException))
                        {
                            string responseText = new StreamReader(response).ReadToEnd();
                            TestUtil.AssertContains(responseText, "error");
                            TestUtil.AssertContains(responseText, "message");
                        }

                        Assert.IsTrue(thrownException is ApplicationException, "No exception thrown.");
                    }
                    else
                    {
                        if (exceptionType == typeof(OutOfMemoryException))
                        {
                            if (location == WebServerLocation.InProcess)
                            {
                                Assert.IsTrue(thrownException is OutOfMemoryException, "thrownException is OutOfMemoryException");
                                Assert.IsTrue(exceptionAtEnd || !HasContent(response), "exceptionAtEnd || !HasContent(response)");
                            }
                            else
                            {
                                Assert.IsTrue(thrownException is WebException, "thrownException is WebException");
                            }
                        }
                        else
                        {
                            Assert.IsTrue(thrownException is WebException, "thrownException is WebException");
                            Assert.IsTrue(HasContent(response), "HasContent(response)");
                            string expected =
                                (location == WebServerLocation.InProcess) ? "text/plain" : "application/xml";
                            Assert.AreEqual(expected, TestUtil.GetMediaType(request.ResponseContentType));
                        }
                    }
                }
            });
        }
예제 #21
0
        public void RequestUriProcessorKeySpecialCharsTest()
        {
            ServiceModelData.Northwind.EnsureDependenciesAvailable();

            CombinatorialEngine engine = CombinatorialEngine.FromDimensions(
                new Dimension("WebServerLocation", TestWebRequest.LocalWebServerLocations));

            TestUtil.RunCombinatorialEngineFail(engine, delegate(Hashtable values)
            {
                WebServerLocation location = (WebServerLocation)values["WebServerLocation"];
                using (TestWebRequest request = TestWebRequest.CreateForLocation(location))
                {
                    Exception exception;
                    request.DataServiceType = typeof(NorthwindContext);

                    int expectedStatusCode;
                    if (location == WebServerLocation.InProcess)
                    {
                        expectedStatusCode = 404;
                    }
                    else
                    {
                        // See http://support.microsoft.com/kb/820129 for more information,
                        // including how to apply the changes.
                        // HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\HTTP\Parameters
                        int keyValue;
                        using (var key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"System\CurrentControlSet\Services\HTTP\Parameters"))
                        {
                            keyValue = (int)key.GetValue("AllowRestrictedChars", 0);
                        }

                        expectedStatusCode = (keyValue == 0) ? 400 : 404;
                    }

                    // Check that control characters are accepted.
                    request.RequestUriString = "/Customers('\x003')";
                    exception = TestUtil.RunCatching(request.SendRequest);
                    TestUtil.AssertExceptionStatusCode(exception, expectedStatusCode, "404 expected for not-found entity with control character in key");

                    // Check that other special characters are accepted.
                    if (location == WebServerLocation.InProcess || location == WebServerLocation.InProcessWcf)
                    {
                        expectedStatusCode = 404;
                    }
                    else
                    {
                        // NOTE: this would work on IIS, but Cassini doesn't use this registry key.
                        // See http://support.microsoft.com/kb/932552 for more information,
                        // including how to apply the changes.
                        // HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ASP.NET
                        //int keyValue;
                        //using (var key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\ASP.NET"))
                        //{
                        //    keyValue = (int)key.GetValue("VerificationCompatibility", 0);
                        //}

                        //expectedStatusCode = (keyValue == 0) ? 400 : 404;
                        expectedStatusCode = 400;
                    }

                    request.RequestUriString = "/Customers('.:')";
                    exception = TestUtil.RunCatching(request.SendRequest);
                    TestUtil.AssertExceptionStatusCode(exception, expectedStatusCode, "404 expected for not-found entity with special characters in key");
                }
            });
        }