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); } }); }
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); } } } }
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)")); } } }
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); } } } }
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); } }); }
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); } }
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(); }); }
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")); } }
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); } }); }
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)); }
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); } } } }
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(); } } }
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)); } }); }
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)); } } }
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); } } }); }
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"); } }); }
/// <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); }
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); } } } } }
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); } } }); }
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)); } } } }); }
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"); } }); }