예제 #1
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);
                }
            });
        }
예제 #2
0
        public void HttpContextServiceHostTunnelingTest()
        {
            CombinatorialEngine engine = CombinatorialEngine.FromDimensions(
                new Dimension("Method", new string[] { "GET", "POST", "PUT", "DELETE" }),
                new Dimension("XMethod", new string[] { "GET", "POST", "PATCH", "DELETE", "DELETE,DELETE" }));

            TestUtil.RunCombinatorialEngineFail(engine, delegate(Hashtable values)
            {
                using (TestWebRequest request = TestWebRequest.CreateForLocal())
                {
                    request.DataServiceType  = typeof(CustomDataContext);
                    request.RequestUriString = "/Orders(100)";

                    string method      = (string)values["Method"];
                    string xmethod     = (string)values["XMethod"];
                    request.HttpMethod = method;
                    if (xmethod == "PATCH")
                    {
                        request.RequestContentType = UnitTestsUtil.JsonLightMimeType;
                        request.SetRequestStreamAsText(
                            "{ @odata.type:\"#AstoriaUnitTests.Stubs.Order\"" +
                            " , DollarAmount: 10 }");
                    }

                    request.RequestHeaders["X-HTTP-Method"] = xmethod;
                    Exception exception = TestUtil.RunCatching(request.SendRequest);
                    TestUtil.AssertExceptionExpected(exception,
                                                     method != "POST",
                                                     xmethod != "PATCH");
                }
            });
        }
예제 #3
0
        public void HttpProcessUtilityJsonEncodingTest()
        {
            CombinatorialEngine engine = CombinatorialEngine.FromDimensions(
                new Dimension("Test", TestUtil.CreateDictionary <string, Encoding>(
                                  new string[] { UnitTestsUtil.JsonLightMimeType, UnitTestsUtil.JsonLightMimeType + ";charset=utf-16", UnitTestsUtil.JsonLightMimeType + ";charset=GB18030" },
                                  new Encoding[] { Encoding.UTF8, Encoding.Unicode, Encoding.GetEncoding("GB18030") })));

            using (CustomDataContext.CreateChangeScope())
                using (TestWebRequest request = TestWebRequest.CreateForInProcess())
                {
                    request.DataServiceType = typeof(CustomDataContext);
                    request.Accept          = UnitTestsUtil.JsonLightMimeType;
                    request.HttpMethod      = "POST";

                    int index = 100;
                    TestUtil.RunCombinatorialEngineFail(engine, delegate(Hashtable values)
                    {
                        KeyValuePair <string, Encoding> test = (KeyValuePair <string, Encoding>)values["Test"];
                        Encoding encoding = test.Value;

                        request.RequestContentType = test.Key;
                        request.RequestStream      = new MemoryStream();

                        byte[] bytes = encoding.GetBytes("{ @odata.type: 'AstoriaUnitTests.Stubs.Customer', ID : " + index++.ToString() + ", Name : \"P\\\\B \\/K\\\"n\\u00e4c\\f\\tke\\r\\n\\br\\u00f6d AB\" }");
                        request.RequestStream.Write(bytes, 0, bytes.Length);
                        request.RequestStream.Position = 0;

                        request.RequestUriString = "/Customers";
                        request.SendRequest();
                        string responseText = request.GetResponseStreamAsText();
                        Assert.IsTrue(responseText.Contains(@"P\\B /K\" + "\"" + @"n\u00e4c\f\tke\r\n\br\u00f6d AB"), "Response [" + responseText + "] contains the expected escape sequences.");
                    });
                }
        }
예제 #4
0
        public void HttpContextServiceHost()
        {
            using (TestWebRequest request = TestWebRequest.CreateForInProcessWcf())
            {
                request.DataServiceType = typeof(CustomDataContext);

                string[] invalidUris = new string[]
                {
                    "/Customers?$top=1&$top=2",
                    "/Customers?$top=1&$top=",
                    // "/Customers?$top=1&$top", - System.UriTemplateHelpers.ParseQueryString drops the empty argument
                    "/Customers?$top",
                    "/Customers?$foo",
                    "/Customers?$top=1&%20$top=1",
                    "/Customers?$top=1&$top%20=1",
                };

                CombinatorialEngine engine = CombinatorialEngine.FromDimensions(
                    new Dimension("uri", invalidUris));
                TestUtil.RunCombinatorialEngineFail(engine, delegate(Hashtable values)
                {
                    request.RequestUriString = (string)values["uri"];
                    Exception exception      = TestUtil.RunCatching(request.SendRequest);
                    TestUtil.AssertExceptionExpected(exception, true);
                    TestUtil.AssertExceptionStatusCode(exception, 400, "400 error expected for invalid query options " + request.RequestUriString);
                });
            }
        }
예제 #5
0
            private static void VerifyInvalidRequestForAllProviders(string uri, int errorCode, params KeyValuePair <string, string>[] headerValues)
            {
                // Very simple test at this level: simply check that we can get an entity by its ID.
                CombinatorialEngine engine = CombinatorialEngine.FromDimensions(
                    new Dimension("ContentFormat", UnitTestsUtil.ResponseFormats),
                    new Dimension("ContextType", new Type[]
                {
                    typeof(CustomDataContext),
                    typeof(ocs.CustomObjectContext),
                    typeof(CustomRowBasedContext),
                    typeof(CustomRowBasedOpenTypesContext)
                }));

                ocs.PopulateData.EntityConnection = null;
                using (System.Data.EntityClient.EntityConnection connection = ocs.PopulateData.CreateTableAndPopulateData())
                {
                    TestUtil.RunCombinatorialEngineFail(engine, delegate(Hashtable values)
                    {
                        Type contextType     = (Type)values["ContextType"];
                        string contentFormat = (string)values["ContentFormat"];

                        VerifyInvalidRequest(contextType, contentFormat, uri, errorCode, headerValues);
                    });
                }
            }
예제 #6
0
        public void OpenTypeBasicTest()
        {
            CombinatorialEngine engine = CombinatorialEngine.FromDimensions(
                new Dimension("TypeData", TypeData.Values));

            using (TestWebRequest request = TestWebRequest.CreateForInProcess())
            {
                request.DataServiceType  = typeof(OpenTypeContextWithReflection <OpenElement>);
                request.RequestUriString = "/Values";

                TestUtil.RunCombinatorialEngineFail(engine, delegate(Hashtable values)
                {
                    TypeData data = (TypeData)values["TypeData"];
                    foreach (object sampleValue in data.SampleValues)
                    {
                        using (StaticCallbackManager <PopulatingValuesEventArgs <OpenElement> > .RegisterStatic((sender, args) =>
                        {
                            var o = new OpenElement();
                            o.Properties.Add("sampleValue", sampleValue);
                            args.Values.Add(o);
                        }))
                        {
                            Exception exception = TestUtil.RunCatching(request.SendRequest);
                            // If we choose to throw when an open property is, say, IntPtr, use this:
                            // Also check for null, since when the value is null, there is no way to know the datatype of the property
                            TestUtil.AssertExceptionExpected(exception, !data.IsTypeSupported && sampleValue != null);
                        }
                    }
                });
            }
        }
예제 #7
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);
                }
            });
        }
예제 #8
0
        public void RequestUriProcessorNullNavigationTest()
        {
            string[] uris = new string[]
            {
                "/Customer(100)/BestFriend/Name",
                "/Customer(100)/Orders",
                "/Customer(100)/Orders(1)",
                "/Customer(100)/Orders(1)/DollarAmount",
                // "/Customer(100)/BestFriend/BestFriend/Name",
            };

            using (CustomDataContext.CreateChangeScope())
                using (TestWebRequest request = TestWebRequest.CreateForInProcess())
                {
                    request.DataServiceType = typeof(CustomDataContext);

                    var c = new CustomDataContext();
                    c.InternalCustomersList.Add(new Customer()
                    {
                        ID = 100, BestFriend = null, Orders = null
                    });
                    c.SaveChanges();

                    CombinatorialEngine engine = CombinatorialEngine.FromDimensions(new Dimension("URI", uris));
                    TestUtil.RunCombinatorialEngineFail(engine, delegate(Hashtable values)
                    {
                        string uri = (string)values["URI"];
                        request.RequestUriString = "/Customer(100)/BestFriend/Name";
                        Exception exception      = TestUtil.RunCatching(request.SendRequest);
                        TestUtil.AssertExceptionStatusCode(exception, 404, "404 expected for " + uri);
                    });
                }
        }
예제 #9
0
        public void VerboseExceptionTest()
        {
            CombinatorialEngine engine = CombinatorialEngine.FromDimensions(
                new Dimension(CustomDataContext.ExceptionTypeArgument, new object[] { typeof(FormatException) }),
                new Dimension(CustomDataContext.ExceptionAtEndArgument, new object[] { true }),
                new Dimension("verbose", new bool[] { true, false }));

            TestUtil.RunCombinatorialEngineFail(engine, delegate(Hashtable values)
            {
                bool verbose = (bool)values["verbose"];
                using (TestWebRequest request = TestWebRequest.CreateForInProcess())
                {
                    int customerCount = (0xA0 / "Customer 1".Length) + 1;
                    values[CustomDataContext.CustomerCountArgument] = customerCount;

                    request.TestArguments      = values;
                    request.ForceVerboseErrors = verbose;
                    request.DataServiceType    = typeof(CustomDataContext);
                    request.RequestUriString   = "/Customers";
                    Exception exception        = TestUtil.RunCatching(request.SendRequest);

                    Assert.IsNotNull(exception, "Expecting an exception, but no exception was thrown");
                    if (verbose)
                    {
                        Assert.AreEqual(typeof(FormatException), exception.InnerException.GetType(), "Expecting formatexception, when verboseErrors is turned on");
                    }
                    else
                    {
                        Assert.AreEqual(typeof(WebException), exception.GetType(), "Expecting WebException thrown by TestServiceHost.ProcessException method");
                        Assert.AreEqual("WebException from TestServiceHost.ProcessException", exception.Message);
                    }
                }
            });
        }
예제 #10
0
            public void SecurityPartialTrustTest()
            {
                // Repro: Astoria not working in partial trust with the EF
                string savedPath = LocalWebServerHelper.FileTargetPath;

                LocalWebServerHelper.Cleanup();
                try
                {
                    string[]            trustLevels = new string[] { null, "High", "Medium" };
                    CombinatorialEngine engine      = CombinatorialEngine.FromDimensions(
                        new Dimension("trustLevel", trustLevels));
                    LocalWebServerHelper.FileTargetPath = Path.Combine(Path.GetTempPath(), "SecurityPartialTrustTest");
                    IOUtil.EnsureEmptyDirectoryExists(LocalWebServerHelper.FileTargetPath);
                    LocalWebServerHelper.StartWebServer();
                    TestUtil.RunCombinatorialEngineFail(engine, delegate(Hashtable values)
                    {
                        string trustLevel = (string)values["trustLevel"];

                        if (trustLevel == "Medium")
                        {
                            Trace.WriteLine(
                                "'Medium' trust level cannot be tested reliably in unit tests, " +
                                "because it may run into problems depending on the local file system " +
                                "permissions and/or the local web server (as far as can be told). " +
                                "You can still use the generated files to prop them to IIS, set up an application " +
                                "and test there.");
                            return;
                        }

                        // Setup partial trust service.
                        SetupPartialTrustService(trustLevel);
                        string address, text = null;
                        Exception exception;
                        address = "http://localhost:" + LocalWebServerHelper.LocalPortNumber + "/service.svc/ASet?$expand=NavB";
                        Trace.WriteLine("Requesting " + address);
                        exception = TestUtil.RunCatching(delegate() { text = new WebClient().DownloadString(address); });
                        WriteExceptionOrText(exception, text);

                        // Note: the second argument should be 'false' even for medium trust.
                        TestUtil.AssertExceptionExpected(exception, false);

                        // Invoke something that would normally fail.
                        address = "http://localhost:" + LocalWebServerHelper.LocalPortNumber + "/service.svc/Q";
                        text    = null;
                        Trace.WriteLine("Requesting " + address);
                        exception = TestUtil.RunCatching(delegate() { text = new WebClient().DownloadString(address); });
                        WriteExceptionOrText(exception, text);
                        TestUtil.AssertExceptionExpected(exception,
                                                         trustLevel == "Medium" && !text.Contains("error") // The error may come in the body
                                                         );
                    });
                }
                finally
                {
                    LocalWebServerHelper.DisposeProcess();
                    LocalWebServerHelper.Cleanup();
                    LocalWebServerHelper.FileTargetPath = savedPath;
                }
            }
예제 #11
0
        public void RequestUriProcessorKeySpecialRealTest()
        {
            double[] doubleValues = new double[] { double.PositiveInfinity, double.NegativeInfinity, double.NaN };
            string[] findText     = new string[] { "INF", "-INF", "NaN" };
            int      textIndex    = 0; // Index corresponds to the findText array

            CombinatorialEngine engine = CombinatorialEngine.FromDimensions(
                new Dimension("doubleValue", doubleValues));

            using (TestWebRequest request = TestWebRequest.CreateForInProcess())
            {
                request.DataServiceType = typeof(TypedCustomDataContext <TypedEntity <double, string> >);
                TypedCustomDataContext <TypedEntity <double, string> > .ClearHandlers();

                TypedCustomDataContext <TypedEntity <double, string> > .ClearValues();

                TestUtil.RunCombinatorialEngineFail(engine, delegate(Hashtable values)
                {
                    double doubleValue = (double)values["doubleValue"];
                    TypedCustomDataContext <TypedEntity <double, string> > .ValuesRequested += (sender, args) =>
                    {
                        TypedCustomDataContext <TypedEntity <double, string> > s = (TypedCustomDataContext <TypedEntity <double, string> >)sender;
                        TypedEntity <double, string> entity = new TypedEntity <double, string>();
                        entity.ID = doubleValue;
                        s.SetValues(new object[] { entity });
                    };
                    try
                    {
                        Assert.IsTrue(textIndex < 3, "Out of bounds for test data array. Please check the doubleValues variable.");
                        string searchValue = findText[textIndex];

                        // Increment textIndex for next test case
                        ++textIndex;

                        request.RequestUriString = "/Values";
                        request.Accept           = "application/json";
                        request.SendRequest();

                        string responseText = request.GetResponseStreamAsText();
                        Assert.IsTrue(responseText.IndexOf(searchValue) > 0, String.Format("ID \"{0}\" expected in response.", searchValue));

                        Trace.WriteLine(String.Format("Found ID: {0}", searchValue));

                        // Finish the test suite after we've ran through all the strings. If we continue, the test suite continues and fails.
                        // Researching into that is a expensive at this time.
                        if (textIndex == 3)
                        {
                            return;
                        }
                    }
                    finally
                    {
                        TypedCustomDataContext <TypedEntity <double, string> > .ClearHandlers();
                        TypedCustomDataContext <TypedEntity <double, string> > .ClearValues();
                    }
                });
            }
        }
예제 #12
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();
            });
        }
예제 #13
0
        public void RequestQueryParserOperatorsPrimitives()
        {
            CombinatorialEngine engine = CombinatorialEngine.FromDimensions(
                new Dimension("Operator", OperatorData.Values),
                new Dimension("LeftType", TypeData.Values),
                new Dimension("RightType", TypeData.Values));

            TypedCustomDataContext <AllTypes> .ClearValues();

            TypedCustomDataContext <AllTypes> .ClearHandlers();

            try
            {
                TypedCustomDataContext <AllTypes> .ValuesRequested += (x, y) =>
                {
                    ((TypedCustomDataContext <AllTypes>)x).SetValues(new object[] { new AllTypes() });
                };
                using (TestWebRequest request = TestWebRequest.CreateForInProcess())
                {
                    request.DataServiceType = typeof(TypedCustomDataContext <AllTypes>);
                    TestUtil.RunCombinatorialEngineFail(engine, delegate(Hashtable values)
                    {
                        TypeData left  = (TypeData)values["LeftType"];
                        TypeData right = (TypeData)values["RightType"];

                        if (!left.IsTypeSupported || !right.IsTypeSupported)
                        {
                            return;
                        }

                        // Big matrix. Let's cut it down by assuming that left and right ordering does not matter.
                        if (Array.IndexOf(TypeData.Values, left) > Array.IndexOf(TypeData.Values, right))
                        {
                            return;
                        }

                        string leftName          = AllTypes.PropertyNameForType(left.ClrType);
                        string rightName         = AllTypes.PropertyNameForType(right.ClrType);
                        OperatorData o           = (OperatorData)values["Operator"];
                        string requestText       = "/Values?$filter=" + leftName + "%20" + o.Token + "%20" + rightName;
                        request.RequestUriString = requestText;
                        Exception exception      = TestUtil.RunCatching(request.SendRequest);
                        TestUtil.AssertExceptionExpected(exception,
                                                         o.IsEqualityComparison && !left.IsEqualityComparableTo(right),
                                                         o.IsOrderingComparison && !left.IsOrderComparableTo(right));
                    });
                }
            }
            finally
            {
                TypedCustomDataContext <AllTypes> .ClearValues();

                TypedCustomDataContext <AllTypes> .ClearHandlers();
            }
        }
예제 #14
0
        public void RequestUriProcessorKeySpecialRealTest()
        {
            double[]            doubleValues = new double[] { double.PositiveInfinity, double.NegativeInfinity, double.NaN };
            CombinatorialEngine engine       = CombinatorialEngine.FromDimensions(
                new Dimension("doubleValue", doubleValues));

            using (TestWebRequest request = TestWebRequest.CreateForInProcess())
            {
                request.DataServiceType = typeof(TypedCustomDataContext <TypedEntity <double, string> >);
                TypedCustomDataContext <TypedEntity <double, string> > .ClearHandlers();

                TypedCustomDataContext <TypedEntity <double, string> > .ClearValues();

                TestUtil.RunCombinatorialEngineFail(engine, delegate(Hashtable values)
                {
                    double doubleValue = (double)values["doubleValue"];
                    TypedCustomDataContext <TypedEntity <double, string> > .ValuesRequested += (sender, args) =>
                    {
                        TypedCustomDataContext <TypedEntity <double, string> > s = (TypedCustomDataContext <TypedEntity <double, string> >)sender;
                        TypedEntity <double, string> entity = new TypedEntity <double, string>();
                        entity.ID = doubleValue;
                        s.SetValues(new object[] { entity });
                    };
                    try
                    {
                        request.RequestUriString = "/Values";
                        request.Accept           = "application/atom+xml,application/xml";
                        request.SendRequest();
                        XmlDocument document = request.GetResponseStreamAsXmlDocument();
                        XmlElement element   = TestUtil.AssertSelectSingleElement(document, "/atom:feed/atom:entry/atom:id");

                        Trace.WriteLine("Found ID: " + element.InnerText);
                        request.FullRequestUriString = element.InnerText;
                        Exception exception          = TestUtil.RunCatching(request.SendRequest);

                        // One NaN value won't match another except throug the use of the .IsNaN
                        // method. It's probably OK to not support this.
                        TestUtil.AssertExceptionExpected(exception, double.IsNaN(doubleValue));

                        string responseText = request.GetResponseStreamAsText();
                        Trace.WriteLine(responseText);
                    }
                    finally
                    {
                        TypedCustomDataContext <TypedEntity <double, string> > .ClearHandlers();
                        TypedCustomDataContext <TypedEntity <double, string> > .ClearValues();
                    }
                });
            }
        }
예제 #15
0
            public void SecurityCallbacksFilterTest()
            {
                CombinatorialEngine engine = CombinatorialEngine.FromDimensions(
                    new Dimension("option", "$filter,$orderby".Split(',')));

                TestUtil.RunCombinatorialEngineFail(engine, delegate(Hashtable values)
                {
                    string option = (string)values["option"];
                    int callCount = 0;
                    using (AstoriaUnitTests.Tests.UnitTestModule.AuthorizationTest.InitializationCallbackManager.RegisterStatic((s, e) =>
                    {
                        e.Configuration.SetEntitySetAccessRule("*", EntitySetRights.All);
                    }))
                        using (StaticCallbackManager <AstoriaUnitTests.Tests.UnitTestModule.AuthorizationTest.ComposeQueryEventArgs> .RegisterStatic((s, e) =>
                        {
                            System.Linq.Expressions.Expression <Func <Customer, bool> > notZero =
                                c => c.ID != 0;
                            e.Filter = notZero;
                            callCount++;
                        }))
                            using (TestWebRequest request = TestWebRequest.CreateForInProcess())
                            {
                                request.ServiceType      = typeof(AstoriaUnitTests.Tests.UnitTestModule.AuthorizationTest.WebDataServiceA);
                                request.RequestUriString = "/Customers?" +
                                                           ((option == "$filter") ? "$filter=BestFriend/ID%20gt%200" : "$orderby=BestFriend/ID%20desc");
                                request.Accept = "application/atom+xml,application/xml";
                                request.SendRequest();
                                var document = request.GetResponseStreamAsXmlDocument();
                                Assert.AreEqual(2, callCount, "Callback is called twice (once for URI, once for best friend.");

                                // Customer with ID #2 has best friend with ID #1 and thus it's returned.
                                TestUtil.AssertSelectSingleElement(document, "/atom:feed/atom:entry/atom:id[text()='http://host/Customers(2)']");

                                if (option == "$filter")
                                {
                                    // Customer #0 is not returned because of the filter (on the segment), and
                                    // customer #1 is not returned because of the filter (on the navigation property).
                                    TestUtil.AssertSelectSingleElement(document, "/atom:feed[0 = count(//atom:id[text()='http://host/Customers(0)'])]");
                                    TestUtil.AssertSelectSingleElement(document, "/atom:feed[0 = count(//atom:id[text()='http://host/Customers(1)'])]");
                                }
                                else
                                {
                                    // Customer #0 is not returned because of the filter (on the segment).
                                    TestUtil.AssertSelectSingleElement(document, "/atom:feed[0 = count(//atom:id[text()='http://host/Customers(0)'])]");
                                    TestUtil.AssertSelectSingleElement(document, "/atom:feed[1 = count(//atom:id[text()='http://host/Customers(1)'])]");
                                }
                            }
                });
            }
예제 #16
0
            public void ETag_PUTPATCHResourceWithNoContent()
            {
                CombinatorialEngine engine = CombinatorialEngine.FromDimensions(
                    new Dimension("Type", new Type[] { typeof(Customer) }),
                    new Dimension("Method", new string[] { "PUT", "PATCH" }),
                    new Dimension("ProcessResponse", new bool[] { true, false }));

                using (CustomDataContext.CreateChangeScope())
                    using (TestUtil.RestoreStaticValueOnDispose(typeof(BaseTestWebRequest), "HostInterfaceType"))
                        using (TestWebRequest request = TestWebRequest.CreateForInProcess())
                        {
                            request.DataServiceType = typeof(CustomDataContext);
                            BaseTestWebRequest.HostInterfaceType = typeof(Microsoft.OData.Service.IDataServiceHost2);

                            TestUtil.RunCombinatorialEngineFail(engine, values =>
                            {
                                Type type            = (Type)values["Type"];
                                string method        = (string)values["Method"];
                                bool processResponse = (bool)values["ProcessResponse"];

                                string atomPayload = "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>" +
                                                     "<entry xml:base=\"/\" " + TestUtil.CommonPayloadNamespaces + ">" +
                                                     AtomUpdatePayloadBuilder.GetCategoryXml(type.FullName) +
                                                     "</entry>";

                                request.RequestUriString = "/Customers(0)";
                                request.HttpMethod       = method;
                                request.IfMatch          = "W/\"sdfght\""; // Wrong ETag
                                request.RequestVersion   = "4.0;";
                                if (processResponse)
                                {
                                    request.RequestHeaders["Prefer"] = "return=representation";
                                }
                                else
                                {
                                    request.RequestHeaders["Prefer"] = "return=minimal";
                                }

                                request.SetRequestStreamAsText(atomPayload);
                                request.RequestContentType = UnitTestsUtil.AtomFormat;
                                Exception e = TestUtil.RunCatching(request.SendRequest);
                                Assert.IsNotNull(e, "The request should have failed.");
                                Assert.AreEqual(412, request.ResponseStatusCode, "The request should have failed due to mismatch in ETags");
                            });
                        }
            }
예제 #17
0
        public void ErrorResponseContentTypeHasCharset()
        {
            // regression tests for these bugs :
            // [GQL Failure, ODataLib integration] Server does not write charset in content-type header on error responses
            // [GQL Failure, Astoria-ODataLib Integration] ContentType provided to DataService.HandleException does not match final header value in $batch
            CombinatorialEngine engine = CombinatorialEngine.FromDimensions(
                new Dimension(CustomDataContext.ExceptionTypeArgument, new object[] { typeof(FormatException) }),
                new Dimension(CustomDataContext.ExceptionAtEndArgument, new object[] { true }),
                new Dimension("verbose", new bool[] { true, false }),
                new Dimension("Accept", new string[] { "application/atom", UnitTestsUtil.JsonLightMimeType }),
                new Dimension("Charset", new string[] { null, Encoding.UTF8.WebName, "iso-8859-1" }));

            TestUtil.RunCombinatorialEngineFail(engine, delegate(Hashtable values)
            {
                bool verbose = (bool)values["verbose"];
                using (TestWebRequest request = TestWebRequest.CreateForInProcessWcf())
                {
                    int customerCount = (0xA0 / "Customer 1".Length) + 1;
                    string accept     = values["Accept"].ToString();
                    object charset    = values["Charset"];
                    values[CustomDataContext.CustomerCountArgument] = customerCount;

                    if (charset == null)
                    {
                        charset = Encoding.UTF8.WebName;
                    }
                    else
                    {
                        request.AcceptCharset = charset.ToString();
                    }

                    request.Accept             = accept;
                    request.TestArguments      = values;
                    request.ForceVerboseErrors = verbose;
                    request.DataServiceType    = typeof(CustomDataContext);
                    request.RequestUriString   = "/NonExistantSet";
                    Exception exception        = TestUtil.RunCatching(request.SendRequest);

                    string responseType        = string.Equals(accept, "application/atom") ? "application/xml" : UnitTestsUtil.JsonLightMimeType + ";odata.streaming=true;IEEE754Compatible=false";
                    string expectedContentType = string.Format("{0};charset={1}", responseType, charset.ToString());

                    Assert.IsNotNull(exception, "Expecting an exception, but no exception was thrown");
                    Assert.AreEqual(expectedContentType, request.ResponseContentType, true /*ignoreCase*/);
                }
            });
        }
예제 #18
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);
                }
            });
        }
예제 #19
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));
                }
            });
        }
예제 #20
0
            public void Projections_TopSkip()
            {
                CombinatorialEngine engine = CombinatorialEngine.FromDimensions(
                    new Dimension("DataServiceType", new Type[] { typeof(CustomDataContext), typeof(ocs.CustomObjectContext), typeof(CustomRowBasedContext), typeof(CustomRowBasedOpenTypesContext) }),
                    new Dimension("Format", UnitTestsUtil.ResponseFormats));

                using (TestUtil.MetadataCacheCleaner())
                    using (ocs.PopulateData.CreateTableAndPopulateData())
                        using (TestWebRequest request = TestWebRequest.CreateForInProcess())
                        {
                            TestUtil.RunCombinatorialEngineFail(engine, values =>
                            {
                                request.DataServiceType = (Type)values["DataServiceType"];
                                request.Accept          = (string)values["Format"];
                                TestUtil.RunCombinatorialEngineFail(CombinatorialEngine.FromDimensions(
                                                                        new Dimension("TopSkip", new TopSkipSetting[] {
                                    new TopSkipSetting("2", null, 0, 1),
                                    new TopSkipSetting(null, "1", 1, 2),
                                    new TopSkipSetting(null, "3"),
                                    new TopSkipSetting("1", "1", 1),
                                    new TopSkipSetting("1", null, "ID desc", 2),
                                    new TopSkipSetting(null, "1", "ID desc", 1, 0),
                                    new TopSkipSetting("1", "2", "ID desc", 0)
                                }),
                                                                        new Dimension("Select", CustomerSelects)), values2 =>
                                {
                                    TopSkipSetting topskip   = (TopSkipSetting)values2["TopSkip"];
                                    SelectDescription select = (SelectDescription)values2["Select"];

                                    VerifyEntryIDsAndXPaths(
                                        "/Customers?$select=" + select.Select +
                                        (topskip.Top != null ? "&$top=" + topskip.Top : "") +
                                        (topskip.Skip != null ? "&$skip=" + topskip.Skip : "") +
                                        (topskip.OrderBy != null ? "&$orderby=" + topskip.OrderBy : ""),
                                        request,
                                        topskip.IDs,
                                        select.VerificationXPaths);
                                });

                                VerifyEntryIDsAndXPaths("/Customers(1)/Orders?$select=ID&$top=1&$skip=1&$orderby=ID", request, new int[] { 101 });
                            });
                        }
            }
예제 #21
0
            public void Projections_Filter()
            {
                CombinatorialEngine engine = CombinatorialEngine.FromDimensions(
                    new Dimension("DataServiceType", new Type[] { typeof(CustomDataContext), typeof(ocs.CustomObjectContext), typeof(CustomRowBasedContext), typeof(CustomRowBasedOpenTypesContext) }),
                    new Dimension("Format", UnitTestsUtil.ResponseFormats));

                using (TestUtil.MetadataCacheCleaner())
                    using (ocs.PopulateData.CreateTableAndPopulateData())
                        using (TestWebRequest request = TestWebRequest.CreateForInProcess())
                        {
                            TestUtil.RunCombinatorialEngineFail(engine, values =>
                            {
                                request.DataServiceType = (Type)values["DataServiceType"];
                                request.Accept          = (string)values["Format"];
                                TestUtil.RunCombinatorialEngineFail(CombinatorialEngine.FromDimensions(
                                                                        new Dimension("Filter", new FilterSetting[] {
                                    new FilterSetting("ID eq 1", 1),
                                    new FilterSetting("ID gt 0", 1, 2),
                                    new FilterSetting("length(Name) sub ID gt 9", 0),
                                    new FilterSetting("BestFriend/ID eq 1", 2),
                                    new FilterSetting("2 sub BestFriend/BestFriend/ID gt 0", 2)
                                }),
                                                                        new Dimension("Select", CustomerSelects)), values2 =>
                                {
                                    FilterSetting filter     = (FilterSetting)values2["Filter"];
                                    SelectDescription select = (SelectDescription)values2["Select"];

                                    VerifyEntryIDsAndXPaths(
                                        "/Customers?$select=" + select.Select + "&$filter=" + filter.Filter,
                                        request,
                                        filter.FilteredIDs,
                                        select.VerificationXPaths);
                                });

                                VerifyEntryIDsAndXPaths("/Customers(1)/Orders?$select=DollarAmount&$filter=ID gt 1", request, new int[] { 101 });
                                VerifyEntryIDsAndXPaths(
                                    "/Customers?$select=BestFriend&$expand=BestFriend($select=ID)&$filter=ID gt 0&$orderby=BestFriend/ID desc",
                                    request, new int[] { 2, 1 });
                            });
                        }
            }
예제 #22
0
            public void Dev10Type_DynamicEntityService()
            {
                CombinatorialEngine engine = CombinatorialEngine.FromDimensions(
                    new Dimension("EntityType", new object[]
                {
                    // entity with a property defined by 'dynamic' keyword (eq. of System.Object)
                    Tuple.Create(typeof(Dev10TypeEntitySet <EntityWithDynamicProperties>), 0, typeof(NotSupportedException), "The CLR Type 'System.Object' has no public properties and is not a supported resource type."),

                    // entity that implements IDMOP interface
                    Tuple.Create(typeof(Dev10TypeEntitySet <EntityWithDynamicInterface>), 0, typeof(InvalidOperationException), "Internal Server Error. The type 'AstoriaUnitTests.Tests.UnitTestModule+Dev10TypeTests+EntityWithDynamicInterface' is not supported."),

                    // entity that inherits from another entity which implements IDMOP interface
                    Tuple.Create(typeof(Dev10TypeEntitySet <EntityWithDynamicAncestor>), 0, typeof(InvalidOperationException), "Internal Server Error. The type 'AstoriaUnitTests.Tests.UnitTestModule+Dev10TypeTests+EntityWithDynamicAncestor' is not supported."),

                    // entity with a complex type that implements IDMOP
                    Tuple.Create(typeof(Dev10TypeEntitySet <EntityWithDynamicComplexProperty>), 0, typeof(InvalidOperationException), "Internal Server Error. The property 'DynamicComplexProperty' is of type 'AstoriaUnitTests.Tests.UnitTestModule_Dev10TypeTests_EntityWithDynamicComplexProperty' which is an unsupported type."),

                    // entity with BigInt property
                    Tuple.Create(typeof(Dev10TypeEntitySet <EntityWithBigIntProperty>), 0, typeof(InvalidOperationException), "The property 'BigInt' on type 'AstoriaUnitTests.Tests.UnitTestModule_Dev10TypeTests_EntityWithBigIntProperty' is not a valid property. Make sure that the type of the property is a public type and a supported primitive type or a entity type with a valid key or a complex type."),

                    // entity with Tuple property
                    Tuple.Create(typeof(Dev10TypeEntitySet <EntityWithTupleProperty>), 0, typeof(InvalidOperationException), "Internal Server Error. The property 'ComplexTuple' is of type 'AstoriaUnitTests.Tests.UnitTestModule_Dev10TypeTests_EntityWithTupleProperty' which is an unsupported type.")
                }));

                TestUtil.RunCombinatorialEngineFail(engine, values =>
                {
                    using (TestWebRequest r = TestWebRequest.CreateForInProcess())
                    {
                        dynamic value = values["EntityType"];

                        r.DataServiceType  = value.Item1;
                        r.RequestUriString = "/Entities";
                        Exception ex       = TestUtil.RunCatching(r.SendRequest);
                        TestUtil.AssertExceptionExpected(ex, true);
                        Assert.IsNotNull(ex, "Should throw if using type without any public properties");
                        Exception innerEx = ex.GetBaseException();
                        Assert.AreEqual(innerEx.Message, value.Item4, "Incorrect error message on using type without public properties");
                    }
                });
            }
예제 #23
0
            public void Dev10Type_DynamicPropertyTypes()
            {
                CombinatorialEngine engine = CombinatorialEngine.FromDimensions(
                    new Dimension("TestValues", new object[] {
                    Tuple.Create(5, 0, typeof(NotSupportedException), "The CLR Type 'System.Object' has no public properties and is not a supported resource type."),               // primitive value type
                    Tuple.Create(new EntityWithDynamicProperties(), 0, typeof(NotSupportedException), "The CLR Type 'System.Object' has no public properties and is not a supported resource type."),
                    Tuple.Create("string", 0, typeof(NotSupportedException), "The CLR Type 'System.Object' has no public properties and is not a supported resource type."),        // primitive string type
                    Tuple.Create(new ComplexTypeWithDynamicInterface(), 0, typeof(NotSupportedException), "The CLR Type 'System.Object' has no public properties and is not a supported resource type."),
                    Tuple.Create(new Tuple <int>(5), 0, typeof(NotSupportedException), "The CLR Type 'System.Object' has no public properties and is not a supported resource type."),
                    Tuple.Create(new ExpandoObject(), 0, typeof(NotSupportedException), "The CLR Type 'System.Object' has no public properties and is not a supported resource type."),
                }));

                using (TestWebRequest r = TestWebRequest.CreateForInProcess())
                {
                    r.DataServiceType  = typeof(Dev10TypeEntitySet_DynamicProperty);
                    r.RequestUriString = "/Entities";

                    TestUtil.RunCombinatorialEngineFail(engine, values =>
                    {
                        dynamic value = values["TestValues"];

                        Dev10TypeEntitySet_DynamicProperty.GetEntityInstance =
                            () =>
                        {
                            return(new EntityWithDynamicProperties()
                            {
                                ID = idGenerator++,
                                DynamicProperty = value.Item1
                            });
                        };

                        Exception ex = TestUtil.RunCatching(r.SendRequest);

                        TestUtil.AssertExceptionExpected(ex, true);
                        Assert.IsNotNull(ex, "Should throw if using type without any public properties");
                        Exception innerEx = ex.GetBaseException();
                        Assert.AreEqual(innerEx.Message, value.Item4, "Incorrect error message on using type without public properties");
                    });
                }
            }
예제 #24
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);
                        }
                    }
                });
            }
예제 #25
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");
                }
            });
        }
예제 #26
0
        public void RequestUriProcessUnquotedTest()
        {
            string[] invalidUris = new string[]
            {
                "/Territories(1)",
                "/Customers(1)",
                "/Orders('1')",
            };
            ServiceModelData.Northwind.EnsureDependenciesAvailable();
            CombinatorialEngine engine = CombinatorialEngine.FromDimensions(
                new Dimension("uri", invalidUris));

            TestUtil.RunCombinatorialEngineFail(engine, delegate(Hashtable values)
            {
                using (TestWebRequest request = TestWebRequest.CreateForInProcess())
                {
                    request.DataServiceType  = typeof(NorthwindContext);
                    request.RequestUriString = (string)values["uri"];
                    Exception exception      = TestUtil.RunCatching(request.SendRequest);
                    TestUtil.AssertExceptionExpected(exception, true);
                    TestUtil.AssertExceptionStatusCode(exception, 400, "Bad Request expected for query portion errors.");
                }
            });
        }
예제 #27
0
        public void RequestQueryParserOperatorsReferences()
        {
            // AllTypesWithReferences
            var referenceTypes = new Type[]
            {
                typeof(object),                                 // an open property
                null                                            // a null literal
            };
            CombinatorialEngine engine = CombinatorialEngine.FromDimensions(
                new Dimension("Operator", OperatorData.Values),
                new Dimension("LeftType", referenceTypes),
                new Dimension("RightType", TypeData.Values));

            OpenTypeContextWithReflection <AllTypesWithReferences> .ClearHandlers();

            try
            {
                OpenTypeContextWithReflection <AllTypesWithReferences> .ValuesRequested += (x, y) =>
                {
                    ((OpenTypeContextWithReflection <AllTypesWithReferences>)x).SetValues(new object[] { new AllTypesWithReferences() });
                };

                using (TestWebRequest request = TestWebRequest.CreateForInProcess())
                {
                    request.DataServiceType = typeof(OpenTypeContextWithReflection <AllTypesWithReferences>);
                    TestUtil.RunCombinatorialEngineFail(engine, delegate(Hashtable values)
                    {
                        Type left      = (Type)values["LeftType"];
                        TypeData right = (TypeData)values["RightType"];

                        if (!right.IsTypeSupported)
                        {
                            return;
                        }

                        string leftName          = AllTypesWithReferences.PropertyNameForReferenceType(left);
                        string rightName         = AllTypesWithReferences.PropertyNameForType(right.ClrType);
                        OperatorData o           = (OperatorData)values["Operator"];
                        string requestText       = "/Values?$filter=" + leftName + "%20" + o.Token + "%20" + rightName;
                        request.RequestUriString = requestText;
                        Trace.WriteLine("Sending request " + requestText);
                        Exception exception = TestUtil.RunCatching(request.SendRequest);
                        if (left == null)
                        {
                            // Anything can be compared to null (but only for equality, no ordering supported).
                            TestUtil.AssertExceptionExpected(exception, !o.IsEqualityComparison);
                        }
                        else if (left == typeof(object))
                        {
                            // Anything can be compared to an open property for anything at parse time.
                            // At execution time, ordering will only be supported for types which can be
                            // ordered as well.
                            //
                            // NOTE: because the sample values are null, reference checks will succeed at runtime.
                            //       (we normally would just fail this at parse time, but because these are reference
                            //       types and provides the open type comparer, it passes; that's probably OK, in case
                            //       a back-end does provider order for these types)
                            TestUtil.AssertExceptionExpected(exception,
                                                             !o.IsEqualityComparison && !right.IsOrderComparableTo(right) &&
                                                             right.ClrType != typeof(byte[]) && right.ClrType != typeof(System.Data.Linq.Binary) &&
                                                             right.ClrType != typeof(System.Xml.Linq.XElement) &&
                                                             !(null != Nullable.GetUnderlyingType(right.ClrType)));
                        }
                    });
                }
            }
            finally
            {
                OpenTypeContextWithReflection <AllTypesWithReferences> .ClearHandlers();
            }
        }
예제 #28
0
        [Ignore] // test case issue, request uri and service root in this case is null.
        public void RequestQueryParserTestBasicTests()
        {
            using (OpenWebDataServiceHelper.AcceptReplaceFunctionInQuery.Restore())
            {
                OpenWebDataServiceHelper.AcceptReplaceFunctionInQuery.Value = true;
                TestUtil.ClearConfiguration();

                // Repro Protocol: Filter - replace not implemented?
                // Repro Protocol: Can't cast simple primitive value in filter expression
                CombinatorialEngine engine = CombinatorialEngine.FromDimensions(
                    new Dimension("ServiceModelData", ServiceModelData.Values));

                TestUtil.RunCombinatorialEngineFail(engine, delegate(Hashtable values)
                {
                    ServiceModelData modelData = (ServiceModelData)values["ServiceModelData"];
                    object service             = Activator.CreateInstance(typeof(OpenWebDataService <>).MakeGenericType(modelData.ServiceModelType));
                    service.GetType().GetMethod("AttachHost", BindingFlags.Public | BindingFlags.Instance).Invoke(service, new object[] { new TestServiceHost2() });
                    object context  = ServiceModelData.InitializeAndGetContext(service);
                    object provider = ServiceModelData.CreateProvider(context, service);

                    if (!modelData.ContainerNames.Contains("Customers"))
                    {
                        return;
                    }

                    string customerNameProperty = modelData.IsUnitTestProvider ? "Name" : "CompanyName";
                    string integerProperty      = modelData.IsUnitTestProvider ? "ID" : "1";

                    string[] predicates = new string[]
                    {
                        "1 eq 1",
                        "1 add 1 eq 2",
                        "2 eq 1 add 1",
                        "3.5 eq 3 add 0.5",
                        "3.5 eq 3 add 0.5",
                        "1 add 2 mul 2 eq 5",
                        "(1 add 2) mul 2 eq 6",
                        "2 sub 1 eq 1",
                        "2 sub 1 add 1 ne 1",
                        "1 add 1 lt 5",
                        "1 add 1 le 2",
                        "1 add 1 ge 2",
                        "1 add 1 gt 1",
                        "1 lt " + Int64.MaxValue + "L",
                        "1 gt " + Int64.MinValue + "L",
                        ///TODO: these 2 should succeed, (double, double, single) shouldn't get -1 from
                        ///private static int CompareConversions(Type source, Type targetA, Type targetB) , this method needs some fixing.
                        ///"1 lt " + decimal.MaxValue + "00",
                        ///"1 gt " + decimal.MinValue + "00",
                        "not (1 add 1 eq 1)",
                        "1 eq 1 or 2 eq 1",
                        "1 eq 1 and 2 eq 1 add 1",
                        "1 eq 1 and not not (2 eq 1 add 1)",
                        "1 eq 0 sub -1",
                        "1 eq 0 sub - 1",
                        "0 sub 3 eq -(3)",
                        "'a' eq 'a'",
                        "'abc' eq 'abc'",
                        "'''' eq ''''",
                        "-" + integerProperty + " eq 1 sub 2",
                        customerNameProperty + " eq 'John' or 1 eq 1",
                        "10 div 2 eq 5",
                        "3 mod 2 eq 1",
                        "1 gt " + XmlConvert.ToString(10.1E-9),
                        "1 lt " + XmlConvert.ToString(10.1E+3),
                        "binary'12AABBff' eq Binary'12aabbFF'",
                        "binary'000102030405060708090A0B0C0D0E0F' eq BINARY'000102030405060708090a0b0c0d0e0f'",
                        "binary'12AABBff' ne binary'22aabbFF'",

                        // String functions.
                        "endswith('abc', 'bc')",
                        "startswith('abc', 'ab')",
                        "not startswith('abc', 'aab')",
                        "contains('abc','b')",
                        "indexof('abc', 'b') ge 1",
                        "replace('foo','o','g') eq 'fgg'",
                        "substring('123', 1) eq '23'",
                        "substring('123', 1, 1) eq '2'",
                        "tolower('ABC') eq 'abc'",
                        "toupper('AbC') eq 'ABC'",
                        "length(toupper('aBc')) eq length(tolower('aBc'))",
                        "concat('a', 'b') eq 'ab'",
                        "'a' lt 'b'",
                        "'a' le 'a'",
                        "'a' ge 'a'",
                        "'b' ge 'a'",
                        // "'a' add 'b' eq 'ab'",
                        // Repro Protocol: can't call date function in filter expressions on LinqToSql
                        "startswith(" + customerNameProperty + ", 'C')",
                        "endswith(concat(" + customerNameProperty + ", 'b'), 'b')",
                        "contains(" + customerNameProperty + ",'C')",
                        "trim(" + customerNameProperty + ") eq substring(" + customerNameProperty + ", 0)",

                        // DateTime functions.
                        "year(2007-08-08) eq 2007",
                        "month(2007-08-10) eq 08",
                        "day(2007-08-10) eq 10",
                        "hour(2007-08-10T14:11:12Z) eq 14",
                        "minute(2007-08-10T14:11:12Z) eq 11",
                        "second(2007-08-10T14:11:12Z) eq 12",

                        // Math functions.
                        "round(1.1) eq 1",
                        "round(42) eq 42",
                        "floor(1.1M) eq 1",
                        "ceiling(1.1f) eq 2",
                    };

                    if (modelData.IsUnitTestProvider)
                    {
                        // Refer to some specific types.
                        string[] customDataContextPredicates = new string[]
                        {
                            //   "(BestFriend ne null and BestFriend/Name eq 'John') or 1 eq 1",
                            "GuidValue ne 5dc82c04-570a-41f5-b48f-c8a4e436f716",
                            "GuidValue ne 5dc82c04-570a-41f5-b48f-c8a4e436f716",
                            "GuidValue ne 5dc82c04-570a-41f5-b48f-c8a4e436f716 and GuidValue ne 5dc82c04-570a-41f5-b48f-c8a4e436f716",
                            // Type functions.
                            "ID eq cast(1, 'Edm.Int32')",
                            String.Format("not isof(1, '{0}')", UnitTestsUtil.ConvertTypeNames("AstoriaUnitTests.Stubs.Customer", context)),
                            String.Format("isof('{0}')", UnitTestsUtil.ConvertTypeNames("AstoriaUnitTests.Stubs.Customer", context)),
                            String.Format("isof('{0}') and cast('{0}')/Birthday gt 1960-01-01", UnitTestsUtil.ConvertTypeNames("AstoriaUnitTests.Stubs.CustomerWithBirthday", context))
                        };

                        if (!(context is CustomRowBasedOpenTypesContext))
                        {
                            predicates = predicates.Concat(new string[] {
                                "ID eq cast(1, 'Edm.Int64')",
                                "ID eq 1L"
                            }).ToArray();
                        }

                        predicates = predicates.Concat(customDataContextPredicates).ToArray();
                    }
                    else if (context is NorthwindModel.NorthwindContext)
                    {
                        string[] northwindPredicates = new string[]
                        {
                            // Repro 602210 - Exception when filter expression contains null
                            "((((CustomerID) eq ('ALFKI')) and ((CustomerID) eq ('ANATR')))) or ((Region) ne (null))"
                        };
                        predicates = predicates.Concat(northwindPredicates).ToArray();
                    }
                    else if (context is AstoriaUnitTests.Stubs.Sql.SqlNorthwindDataContext)
                    {
                        string[] sqlNorthwindPredicates = new string[]
                        {
                            // Repro Protocol: Can't compare properties to null in LinqToSql filter expression
                            "Categories|CategoryName eq null or 1 add 1 eq 2",
                            "Categories|null eq CategoryName or 1 add 1 eq 2",

                            // Repro Protocol: error trying to use Link property in filter expression (LinqToSql)
                            //"Categories|contains('Beer',CategoryName)",
                            //"Products|contains('Beer',Categories/CategoryName)",

                            // Repro Protocol: can't call date function in filter expressions on LinqToSql
                            //"Employees|month(HireDate) eq 5",
                        };
                        predicates = sqlNorthwindPredicates;
                        // predicates = predicates.Concat(sqlNorthwindPredicates).ToArray();
                    }

                    VerifyResultsExistForWhere(service, context, "Customers", predicates);
                });
            }
        }
예제 #29
0
        public void WebDataServiceCsdlMimeTypes()
        {
            object[] targets = new object[]
            {
                // BuiltInTypeKind.EdmFunction,
                // BuiltInTypeKind.ComplexType,
                // BuiltInTypeKind.EntityContainer,
                // BuiltInTypeKind.EntityType,
                BuiltInTypeKind.EdmProperty,
            };

            // Ensure the NorthwindModel service is ready to be used.
            Trace.WriteLine("NorthwindModel IsValid: " + ServiceModelData.Northwind.IsValid);

            CombinatorialEngine engine = CombinatorialEngine.FromDimensions(
                new Dimension("Target", targets),
                new Dimension("MimeType", new object[] { "", "text/html" }));
            int schemaCounter = 0;

            TestUtil.RunCombinatorialEngineFail(engine, delegate(Hashtable values)
            {
                BuiltInTypeKind target = (BuiltInTypeKind)values["Target"];
                string mimeType        = (string)values["MimeType"];

                // Create a copy of Northwind model files.
                schemaCounter++;
                const bool overwriteTrue = true;
                string sourceFileName    = Path.Combine(TestUtil.NorthwindMetadataDirectory, "Northwind.csdl");
                string destFileName      = sourceFileName + schemaCounter + ".csdl";
                File.Copy(sourceFileName, destFileName, overwriteTrue);
                File.SetAttributes(destFileName, FileAttributes.Normal);

                // Add an attribute at specific values.
                string csdlFileName  = destFileName;
                XmlDocument document = new XmlDocument();
                document.Load(csdlFileName);
                XmlElement element = GetElementForKind(document, target);
                element.SetAttribute("MimeType", "http://docs.oasis-open.org/odata/ns/metadata", mimeType);
                document.Save(csdlFileName);

                using (TestWebRequest request = TestWebRequest.CreateForInProcess())
                {
                    // Get the generated CSDL.
                    string connectionString = NorthwindModel.NorthwindContext.ContextConnectionString;
                    try
                    {
                        string northwindConnectionString = connectionString;
                        northwindConnectionString        = northwindConnectionString
                                                           .Replace("Northwind.csdl", "Northwind.csdl" + schemaCounter + ".csdl");
                        NorthwindModel.NorthwindContext.ContextConnectionString = northwindConnectionString;

                        request.DataServiceType  = typeof(NorthwindModel.NorthwindContext);
                        request.RequestUriString = "/$metadata";
                        Exception exception      = TestUtil.RunCatching(request.SendRequest);
                        TestUtil.AssertExceptionExpected(exception,
                                                         target != BuiltInTypeKind.EdmProperty,
                                                         mimeType == "");

                        if (exception != null)
                        {
                            return;
                        }

                        XmlDocument metadataResult = new XmlDocument(TestUtil.TestNameTable);
                        metadataResult.Load(request.GetResponseStream());
                        Trace.WriteLine(metadataResult.OuterXml);

                        // Get a value using a primitive serializer.
                        request.RequestUriString = "/Customers?$format=atom&$top=1";
                        request.SendRequest();
                        XmlDocument customerDocument = SerializationFormatData.Atom.LoadXmlDocumentFromStream(request.GetResponseStream());
                        XmlElement customerId        = TestUtil.AssertSelectSingleElement(customerDocument, "/atom:feed/atom:entry/atom:id");
                        request.FullRequestUriString = customerId.InnerText + "/CompanyName/$value";
                        request.SendRequest();
                        Assert.AreEqual(mimeType, TestUtil.GetMediaType(request.ResponseContentType));
                    }
                    finally
                    {
                        NorthwindModel.NorthwindContext.ContextConnectionString = connectionString;
                    }
                }
            });
        }
예제 #30
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));
                        }
                    }
                }
            });
        }