コード例 #1
0
        private static void VerifyLinksPayload(Workspace w, CommonPayload payload, LinqQueryBuilder linqBuilder)
        {
            ArrayList expectedEntities = CommonPayload.CreateList(linqBuilder.QueryResult);

            if (payload == null)
            {
                AstoriaTestLog.AreEqual(expectedEntities.Count, 0, "Unexpected null $ref payload");
            }
            else
            {
                KeyExpressions expectedKeys = new KeyExpressions();
                foreach (object o in expectedEntities)
                {
                    KeyExpression keyExp = w.CreateKeyExpressionFromProviderObject(o);
                    expectedKeys.Add(keyExp);
                }

                List <string> linksFound = new List <string>();

                if (payload.Resources == null)
                {
                    linksFound.Add(payload.Value);
                }
                else
                {
                    foreach (PayloadObject o in (payload.Resources as List <PayloadObject>))
                    {
                        if (o.PayloadProperties.Any(p => p.Name == "uri"))
                        {
                            linksFound.Add((o["uri"] as PayloadSimpleProperty).Value);
                        }
                    }
                }

                AstoriaTestLog.AreEqual(expectedKeys.Count, linksFound.Count, "Number of expected entities does not match number of links found");

                foreach (string link in linksFound)
                {
                    KeyExpression match = null;
                    foreach (KeyExpression expectedKey in expectedKeys)
                    {
                        if (compareKeyURI(link, expectedKey))
                        {
                            match = expectedKey;
                            break;
                        }
                    }

                    if (match != null)
                    {
                        expectedKeys.Remove(match);
                    }
                    else
                    {
                        AstoriaTestLog.WriteLineIgnore("Unexpected URI: '" + link + "'");
                        AstoriaTestLog.FailAndThrow("Unexpected URI found in $ref payload");
                    }
                }
            }
        }
コード例 #2
0
        private static ResourceInstanceComplexProperty ConvertComplexPayloadObjectToComplexProperty(ResourceProperty rp, PayloadComplexProperty payloadComplexProperty)
        {
            List <ResourceInstanceProperty> properties = new List <ResourceInstanceProperty>();

            foreach (ResourceProperty childProperty in (rp.Type as ComplexType).Properties.OfType <ResourceProperty>())
            {
                if (childProperty.IsComplexType)
                {
                    PayloadComplexProperty fromPayload = payloadComplexProperty.PayloadProperties[childProperty.Name] as PayloadComplexProperty;
                    properties.Add(ConvertComplexPayloadObjectToComplexProperty(childProperty, fromPayload));
                }
                else
                {
                    PayloadSimpleProperty fromPayload = payloadComplexProperty.PayloadProperties[childProperty.Name] as PayloadSimpleProperty;
                    if (fromPayload != null)
                    {
                        ResourceInstanceProperty newProperty = null;
                        object val = CommonPayload.DeserializeStringToObject(fromPayload.Value, childProperty.Type.ClrType, false, fromPayload.ParentObject.Format);
                        newProperty = new ResourceInstanceSimpleProperty(childProperty.Name, new NodeValue(val, childProperty.Type));
                        properties.Add(newProperty);
                    }
                }
            }
            ComplexResourceInstance complexResourceInstance = new ComplexResourceInstance(rp.Type.Name, properties.ToArray());

            return(new ResourceInstanceComplexProperty(rp.Type.Name, rp.Name, complexResourceInstance));
        }
コード例 #3
0
 public PayloadObject(CommonPayload parent)
 {
     Payload                   = parent;
     PayloadObjects            = new List <PayloadObject>();
     PayloadProperties         = new List <PayloadProperty>();
     NamedStreams              = new List <PayloadNamedStream>();
     CustomEpmMappedProperties = new Dictionary <string, string>();
 }
コード例 #4
0
ファイル: PayloadVerifier.cs プロジェクト: zhonli/odata.net
        protected static bool TryGetSingleObjectFromPayload(CommonPayload payload, out PayloadObject payloadObject)
        {
            List <PayloadObject> list = payload.Resources as List <PayloadObject>;

            if (list == null || list.Count != 1)
            {
                payloadObject = null;
                return(false);
            }
            payloadObject = list[0];
            return(true);
        }
コード例 #5
0
        internal static KeyedResourceInstance CreateKeyedResourceInstanceFromPayloadObject(ResourceContainer container, ResourceType resourceType, PayloadObject payloadObject)
        {
            List <ResourceInstanceProperty> properties    = new List <ResourceInstanceProperty>();
            List <ResourceInstanceProperty> keyProperties = new List <ResourceInstanceProperty>();

            foreach (ResourceProperty property in resourceType.Properties.OfType <ResourceProperty>())
            {
                if (property.IsNavigation)
                {
                    continue;
                }

                if (property.IsComplexType)
                {
                    PayloadComplexProperty fromPayload = payloadObject[property.Name] as PayloadComplexProperty;
                    properties.Add(ConvertComplexPayloadObjectToComplexProperty(property, fromPayload));
                }
                else
                {
                    string stringValue;
                    if (payloadObject.PayloadProperties.Any(p => p.Name == property.Name))
                    {
                        PayloadSimpleProperty fromPayload = payloadObject[property.Name] as PayloadSimpleProperty;
                        stringValue = fromPayload.Value;
                    }
                    else
                    {
                        if (!payloadObject.CustomEpmMappedProperties.TryGetValue(property.Name, out stringValue))
                        {
                            stringValue = null;
                        }
                    }

                    ResourceInstanceProperty newProperty = null;
                    object val = CommonPayload.DeserializeStringToObject(stringValue, property.Type.ClrType, false, payloadObject.Format);
                    newProperty = new ResourceInstanceSimpleProperty(property.Name, new NodeValue(val, property.Type));

                    if (property.PrimaryKey != null)
                    {
                        keyProperties.Add(newProperty);
                    }
                    else
                    {
                        properties.Add(newProperty);
                    }
                }
            }

            ResourceInstanceKey key = new ResourceInstanceKey(container, resourceType, keyProperties.ToArray());

            return(new KeyedResourceInstance(key, properties.ToArray()));
        }
コード例 #6
0
ファイル: ConcurrencyUtil.cs プロジェクト: zhonli/odata.net
        public static KeyExpression ConstructKey(ResourceContainer container, PayloadObject entity)
        {
            Dictionary <string, object> properties = new Dictionary <string, object>();

            ResourceType type = container.BaseType;

            if (entity.Type != type.Namespace + "." + type.Name)
            {
                type = container.ResourceTypes.SingleOrDefault(rt => rt.Namespace + "." + rt.Name == entity.Type);
                if (type == null)
                {
                    AstoriaTestLog.FailAndThrow("Could not find resource type for payload type value: " + entity.Type);
                }
            }

            foreach (ResourceProperty property in type.Properties.OfType <ResourceProperty>())
            {
                if (property.IsNavigation || property.IsComplexType)
                {
                    continue;
                }

                string propertyName = property.Name;
                string valueString;
                if (entity.PayloadProperties.Any(p => p.Name == propertyName))
                {
                    PayloadSimpleProperty simpleProperty = entity[propertyName] as PayloadSimpleProperty;
                    if (simpleProperty == null)
                    {
                        continue;
                    }

                    valueString = simpleProperty.Value;
                }
                else
                {
                    continue;
                }

                object value = CommonPayload.DeserializeStringToObject(valueString, property.Type.ClrType, false, entity.Format);
                if (value is DateTime && entity.Format == SerializationFormatKind.JSON)
                {
                    // TODO: this is because the server will make any JSON datetime into UTC, and currently we always send 'unspecified' values
                    value = new DateTime(((DateTime)value).Ticks, DateTimeKind.Unspecified);
                }

                properties[propertyName] = value;
            }

            return(new KeyExpression(container, type, properties));
        }
コード例 #7
0
        public static void VerifyLinq(Workspace workspace, ExpNode q, IQueryable results)
        {
            //verify if the results are ok before building the URI
            System.Collections.ArrayList list = new System.Collections.ArrayList();
            foreach (object element in results)
            {
                list.Add(element);
            }


            //UriQueryBuilder ub = new UriQueryBuilder(workspace, "");
            // string ruri = ub.Build(q);

            //System.Uri uri = new Uri(workspace.ServiceUri);
            // string uriRel = ruri.Substring(ruri.IndexOf("/") + 1);
            // AstoriaTestLog.WriteLineIgnore(uri.ToString() + uriRel);

            AstoriaRequest request = workspace.CreateRequest(q);

            request.Format = SerializationFormatKind.Atom;

            try
            {
                AstoriaResponse response = request.GetResponse();
                //response.VerifyHttpStatusCodeOk(response.StatusCode);

                CommonPayload payload = response.CommonPayload;
                if (payload.Value != null)
                {
                    payload.CompareValue(results, false, false);
                }
                else
                {
                    payload.Compare(results);
                }

                //AstoriaTestLog.AreEqual(response.ContentType, SerializationFormatKinds.ContentTypeFromKind(response.OriginalRequest.SerializationKind),
                //"Content-Type does not match Accept header request");
            }
            catch (Exception e)
            {
                AstoriaTestLog.FailAndContinue(e);
            }
        }
コード例 #8
0
ファイル: CommonPayload.cs プロジェクト: zdzislaw/odata.net
        public virtual void Compare(IQueryable baseline)
        {
            System.Collections.ArrayList baseLineEntities = CommonPayload.CreateList(baseline);

            if (this.Resources is PayloadComplexProperty)
            {
                PayloadComplexProperty complexProperty = (PayloadComplexProperty)this.Resources;
                this.CompareComplexType(complexProperty, baseLineEntities[0], false);
            }
            else if (this.Resources is PayloadSimpleProperty)
            {
                PayloadSimpleProperty simpleProperty = (PayloadSimpleProperty)this.Resources;
                this.CompareSimpleType(simpleProperty, baseLineEntities[0], false);
            }
            else if (this.Resources is List <PayloadObject> )
            {
                List <PayloadObject> payloadObjects = (List <PayloadObject>) this.Resources;
                Compare(baseLineEntities.OfType <object>().ToList(), payloadObjects, false);
            }
        }
コード例 #9
0
ファイル: RequestUtil.cs プロジェクト: zhonli/odata.net
        public static void GetAndVerifyStatusCode(Workspace w, string uri, HttpStatusCode expectedStatusCode, out CommonPayload responsePayload)
        {
            AstoriaResponse response;

            GetAndVerifyStatusCode(w, uri, expectedStatusCode, out response);
            responsePayload = response.CommonPayload;
        }
コード例 #10
0
        public static void Verify(Workspace w, ExpNode q, IEnumerable results, ResourceType resType, ComplexType cType, bool bCount)
        {
            long count = 0;

            if (bCount)
            {
                object[] args    = new object[] { results };
                Type     qorType = typeof(QueryOperationResponseWrapper <>).MakeGenericType(resType.ClientClrType);
                object   qor     = Activator.CreateInstance(qorType, args);

                PropertyInfo pi = qor.GetType().GetProperty("GetTotalCount");
                object       i  = pi.GetValue(qor, new object[] { });

                count = (long)i;

                LinqQueryBuilder lb = new LinqQueryBuilder(w);
                lb.CountingMode = true;
                lb.Build(q);

                object baselineElementsCount = CommonPayload.CreateList(lb.QueryResult).Count;
                AstoriaTestLog.IsTrue(count == Convert.ToInt64(baselineElementsCount), "Count is different.Count is " + count.ToString() + ". Baseline count is " + baselineElementsCount.ToString());
            }

            LinqQueryBuilder linqBuilder = new LinqQueryBuilder(w);

            linqBuilder.Build(q);

            IQueryable baselines = linqBuilder.QueryResult;

            IEnumerator b = null;

            IEnumerator r = null;

            try
            {
                b = TrustedMethods.IQueryableGetEnumerator(baselines);
                r = results.GetEnumerator();
            }
            catch (InvalidOperationException invalidOperation)
            {
                if (!AstoriaTestProperties.IsRemoteClient)
                {
                    throw invalidOperation;
                }
            }

            PropertyInfo propertyInfo    = null;
            Object       expectedResult1 = null;
            Object       expectedResult2 = null;

            try
            {
                while (b.MoveNext() && r.MoveNext())
                {
                    if (b.Current == null)
                    {
                        return;
                    }

                    if (r.Current == null)
                    {
                        throw new TestFailedException("Less results than expected");
                    }
                    //skip verification for Binary data type for Linq to Sql
                    if (AstoriaTestProperties.DataLayerProviderKinds[0] == DataLayerProviderKind.LinqToSql && b.Current is System.Byte[])
                    {
                        return;
                    }

                    if (b.Current is System.Byte[])
                    {
                        byte[] newBase = (byte[])b.Current;
                        byte[] newAct  = (byte[])r.Current;

                        if (newBase.Length != newAct.Length)
                        {
                            throw new TestFailedException("Failed to compare the results!");
                        }
                    }
#if !ClientSKUFramework
                    else if (b.Current is System.Data.Linq.Binary)
                    {
                        System.Data.Linq.Binary newBase = (System.Data.Linq.Binary)b.Current;
                        System.Data.Linq.Binary newAct  = new System.Data.Linq.Binary((byte[])r.Current);

                        if (newBase.Length != newAct.Length)
                        {
                            throw new TestFailedException("Failed to compare the results!");
                        }
                    }
#endif

                    else if (b.Current is System.Xml.Linq.XElement)
                    {
                        if (b.Current.ToString() != r.Current.ToString())
                        {
                            throw new TestFailedException("Failed to compare the results!");
                        }
                    }
                    else
                    {
                        if (!b.Current.Equals(r.Current))
                        {
                            if (cType != null)
                            {
                                foreach (ResourceProperty property in cType.Properties)
                                {
                                    if (!property.IsNavigation && !property.IsComplexType && !(property.Type is CollectionType))
                                    {
                                        propertyInfo    = b.Current.GetType().GetProperty(property.Name);
                                        expectedResult1 = propertyInfo.GetValue(b.Current, null);

                                        PropertyInfo propertyInfo2 = r.Current.GetType().GetProperty(property.Name);
                                        expectedResult2 = propertyInfo2.GetValue(r.Current, null);

                                        if (expectedResult1 != expectedResult2)
                                        {
                                            if (expectedResult1 is System.Xml.Linq.XElement)
                                            {
                                                expectedResult1 = ((System.Xml.Linq.XElement)expectedResult1).ToString(System.Xml.Linq.SaveOptions.None);
                                            }
                                            if (expectedResult2 is System.Xml.Linq.XElement)
                                            {
                                                expectedResult2 = ((System.Xml.Linq.XElement)expectedResult2).ToString(System.Xml.Linq.SaveOptions.None);
                                            }
                                            #if !ClientSKUFramework
                                            if (expectedResult1 is byte[])
                                            {
                                                expectedResult1 = new System.Data.Linq.Binary((byte[])expectedResult1);
                                            }

                                            if (expectedResult2 is byte[])
                                            {
                                                expectedResult2 = new System.Data.Linq.Binary((byte[])expectedResult2);
                                            }
                                            #endif


                                            AstoriaTestLog.AreEqual(expectedResult1, expectedResult2, String.Format("Resource value for {0} does not match", property.Name), false);
                                        }
                                    }
                                }
                            }
                            else
                            {
                                foreach (ResourceProperty property in resType.Properties)
                                {
                                    if (!property.IsNavigation && !property.IsComplexType && !(property.Type is CollectionType))
                                    {
                                        //skip verification for Binary data type for Linq to Sql
                                        if (AstoriaTestProperties.DataLayerProviderKinds[0] == DataLayerProviderKind.LinqToSql && property.Type.Name == "LinqToSqlBinary")
                                        {
                                            return;
                                        }

                                        propertyInfo    = b.Current.GetType().GetProperty(property.Name);
                                        expectedResult1 = propertyInfo.GetValue(b.Current, null);

                                        PropertyInfo propertyinfo2 = r.Current.GetType().GetProperty(property.Name);
                                        expectedResult2 = propertyinfo2.GetValue(r.Current, null);

                                        if (expectedResult1 != expectedResult2)
                                        {
                                            if (expectedResult1 is System.Xml.Linq.XElement)
                                            {
                                                expectedResult1 = ((System.Xml.Linq.XElement)expectedResult1).ToString(System.Xml.Linq.SaveOptions.None);
                                            }

                                            if (expectedResult2 is System.Xml.Linq.XElement)
                                            {
                                                expectedResult2 = ((System.Xml.Linq.XElement)expectedResult2).ToString(System.Xml.Linq.SaveOptions.None);
                                            }
                                            #if !ClientSKUFramework
                                            if (expectedResult1 is byte[])
                                            {
                                                expectedResult1 = new System.Data.Linq.Binary((byte[])expectedResult1);
                                            }

                                            if (expectedResult2 is byte[])
                                            {
                                                expectedResult2 = new System.Data.Linq.Binary((byte[])expectedResult2);
                                            }
                                            #endif
                                            AstoriaTestLog.AreEqual(expectedResult1, expectedResult2, String.Format("Resource value for {0} does not match", property.Name), false);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                AstoriaTestLog.WriteLine(e.ToString());
                throw;
            }
        }
コード例 #11
0
        protected override void Verify()
        {
            if (!Applies(Response))
            {
                return;
            }

            // build a common payload for the insert
            //
            CommonPayload insertPayload = Response.Request.CommonPayload;

            // get the entity that was inserted
            PayloadObject inserted;

            if (!TryGetSingleObjectFromPayload(insertPayload, out inserted))
            {
                ResponseVerification.LogFailure(Response, new Exception("Insert request payload did not contain a single entity"));
            }

            // determine the type based on what was inserted
            ResourceType type = Response.Workspace.ServiceContainer.ResourceTypes.Single(rt => inserted.Type.Equals(rt.Namespace + "." + rt.Name));

            // get the entity that was returned
            PayloadObject returned;

            if (!TryGetSingleObjectFromPayload(Response.CommonPayload, out returned))
            {
                if (Versioning.Server.SupportsLiveFeatures)
                {
                    string preferHeader;
                    if (Response.Request.Headers.TryGetValue("prefer", out preferHeader) && preferHeader == "return=minimal")
                    {
                        return;
                    }
                }

                ResponseVerification.LogFailure(Response, new Exception("Insert response payload did not contain a single entity"));
            }

            // verify that the inserted and returned entities are equivalent
            VerifyInsertResponse(type, inserted, returned);

            // re-query the entity
            Workspace      workspace    = Response.Workspace;
            AstoriaRequest queryRequest = workspace.CreateRequest();

            if (type.Properties.Any(p => p.Facets.ConcurrencyModeFixed))
            {
                queryRequest.ETagHeaderExpected = true;
            }

            if (type.Key.Properties.Any(p => p.Type == Clr.Types.DateTime))
            {
                // this will blow up for MEST, but we don't currently have any datetime key + MEST types
                ResourceContainer container = Response.Workspace.ServiceContainer.ResourceContainers.Single(rc => !(rc is ServiceOperation) && rc.ResourceTypes.Contains(type));
                queryRequest.Query = ContainmentUtil.BuildCanonicalQuery(ConcurrencyUtil.ConstructKey(container, returned));
            }
            else
            {
                queryRequest.URI = Uri.UnescapeDataString(returned.AbsoluteUri);
                if (queryRequest.URI.Contains("E+"))
                {
                    queryRequest.URI = queryRequest.URI.Replace("E+", "E");
                }
                if (queryRequest.URI.Contains("e+"))
                {
                    queryRequest.URI = queryRequest.URI.Replace("e+", "e");
                }
            }

            AstoriaResponse queryResponse = queryRequest.GetResponse();

            if (queryResponse.ActualStatusCode == HttpStatusCode.BadRequest)
            {
                // try it as a filter instead (possibly caused by the URI being too long)
                // this will blow up for MEST
                ResourceContainer container = Response.Workspace.ServiceContainer.ResourceContainers
                                              .Single(rc => !(rc is ServiceOperation) && rc.ResourceTypes.Contains(type));
                KeyExpression key = ConcurrencyUtil.ConstructKey(container, returned);
                queryRequest  = workspace.CreateRequest(Query.From(Exp.Variable(container)).Where(key.Predicate));
                queryResponse = queryRequest.GetResponse();
            }
            queryResponse.Verify();

            // get the entity from the query
            PayloadObject queried;

            if (!TryGetSingleObjectFromPayload(queryResponse.CommonPayload, out queried))
            {
                ResponseVerification.LogFailure(queryResponse, new Exception("Query response payload did not contain a single entity"));
            }

            // ensure that the entity did not change between the insert and the re-query
            VerifyQueryResponse(type, returned, queried);
        }
コード例 #12
0
        public static void ValidateCountException(AstoriaResponse response, AstoriaRequest request, TestFailedException tfe)
        {
            // Errors are expected for older versions.
            if (!Versioning.Server.SupportsV2Features)
            {
                if (request.URI.Contains("$inlinecount=allpages"))
                {
                    // Query parameter not recognized.
                    if (response.ActualStatusCode == System.Net.HttpStatusCode.BadRequest)
                    {
                        return;
                    }
                }
                //anything other than http 404 or 400 is an invalid status code for a count query
                else if (
                    response.ActualStatusCode != System.Net.HttpStatusCode.BadRequest ||
                    response.ActualStatusCode != System.Net.HttpStatusCode.NotFound)
                {
                    throw tfe;
                }
                else
                {
                    // Resource segment $count not found.
                    if (response.ActualStatusCode == System.Net.HttpStatusCode.NotFound || response.ActualStatusCode == System.Net.HttpStatusCode.BadRequest)
                    {
                        return;
                    }
                }
            }

            LinqQueryBuilder linqBuilder = new LinqQueryBuilder(request.Workspace);

            linqBuilder.CountingMode = request.URI.Contains("$inlinecount=allpages");
            try
            {
                linqBuilder.Build(request.Query);
            }
            catch (KeyNotFoundException kfe)
            {
                if (!AstoriaTestProperties.DataLayerProviderKinds.Contains(DataLayerProviderKind.NonClr))
                {
                    throw kfe;
                }
            }
            bool isInvalidError = true;

            if (response.ActualStatusCode == System.Net.HttpStatusCode.NotFound)
            {
                if (request.Query.Input is CountExpression)
                {
                    ExpNode internalQuery = ((CountExpression)request.Query.Input).ScanNode;
                    if (internalQuery is KeyExpression || internalQuery is PredicateExpression)
                    {
                        isInvalidError = false;
                    }
                }
                if (isInvalidError)
                {
                    if (CommonPayload.CreateList(linqBuilder.QueryResult).Count == 0)
                    {
                        isInvalidError = false;
                    }
                }
            }
            if (response.ActualStatusCode == System.Net.HttpStatusCode.BadRequest)
            {
                if (request.Query.Input is CountExpression)
                {
                    ExpNode internalQuery = ((CountExpression)request.Query.Input).ScanNode;
                    if (internalQuery is KeyExpression || internalQuery is PredicateExpression)
                    {
                        isInvalidError = false;
                    }
                }
                else if (request.Query.Input is KeyExpression)
                {
                    isInvalidError = false;
                }
            }

            if (isInvalidError)
            {
                throw tfe;
            }
        }
コード例 #13
0
        public static void VerifyGet(AstoriaResponse response)
        {
            AstoriaRequest request = response.Request;

            if (request.Query != null)
            {
                LinqQueryBuilder linqBuilder = new LinqQueryBuilder(request.Workspace);
                linqBuilder.Build(request.Query);
                if (request.URI.Contains("$value"))
                {
                    CommonPayload payload;

                    // $value queries will sometimes return unexpected 404s due to null values
                    // if we get a 404 unexpectedly, the underlying result must be null
                    if (response.ActualStatusCode == System.Net.HttpStatusCode.NotFound)
                    {
                        payload = request.CommonPayload;
                    }

                    IEnumerable enumerable     = linqBuilder.QueryResult;
                    object      expectedResult = CommonPayload.GetSingleValueFromIQueryable(linqBuilder.QueryResult, false);

                    ResourceProperty rp = request.GetPropertyFromQuery();
                    CommonPayload.ComparePrimitiveValuesObjectAndString(expectedResult, rp.Type.ClrType, response.Payload, true, request.Format, false);
                }
                else if (request.URI.Contains("$count") || request.URI.Contains("$inlinecount"))
                {
                    if (request.URI.Contains("$count"))
                    {
                        // Versioning: make sure the server always returns 2.0.
                        VerifySpecificResponseVersion(response, 2, 0);

                        // PlainText payload.
                        try
                        {
                            VerifyStatusCode(response);
                            if (response.Request.ExpectedStatusCode == System.Net.HttpStatusCode.OK)
                            {
                                int countPayload  = Int32.Parse(response.Payload);
                                int countBaseline = CommonPayload.CreateList(linqBuilder.QueryResult).Count;
                                AstoriaTestLog.AreEqual(countPayload, countBaseline, "Counts in payload (" + countPayload + ") and baseline (" + countBaseline + ") differ.");
                            }
                        }
                        catch (TestFailedException tfe)
                        {
                            //When the underlying resource has zero elements, the server now throws a 404 error , causing false negatives
                            ValidateCountException(response, request, tfe);
                        }
                    }
                    else
                    {
                        VerifySpecificResponseVersion(response, 2, 0);

                        try
                        {
                            // JSON, Atom or PlainXml ($ref) payload.
                            VerifyStatusCode(response);
                            if (response.Request.ExpectedStatusCode == System.Net.HttpStatusCode.OK)
                            {
                                CommonPayload    payload             = response.CommonPayload;
                                LinqQueryBuilder baselineLinqBuilder = new LinqQueryBuilder(request.Workspace);
                                baselineLinqBuilder.CountingMode = true;
                                baselineLinqBuilder.Build(request.Query);

                                object baselineElementsCount = CommonPayload.CreateList(baselineLinqBuilder.QueryResult).Count;
                                payload.CompareCountInline(linqBuilder.QueryResult, baselineElementsCount);
                                AstoriaTestLog.WriteLine(linqBuilder.QueryExpression);
                                if (request.URI.Contains("$ref"))
                                {
                                    VerifyLinksPayload(request.Workspace, payload, linqBuilder);
                                }
                            }
                        }
                        catch (TestFailedException tfe)
                        {
                            //When the underlying resource has zero elements, the server now throws a 404 error , causing false negatives
                            ValidateCountException(response, request, tfe);
                        }
                    }
                }
                else
                {
                    if (response.ActualStatusCode == System.Net.HttpStatusCode.NoContent && response.Payload == "")
                    {
                        response.Payload = null; // allow result from Linq query and payload to be compared (NoContent is a get to a null Nav prop)
                    }
                    if (response.ActualStatusCode == System.Net.HttpStatusCode.NotFound)
                    {
                        return;
                    }

                    CommonPayload payload = response.CommonPayload;
                    if (request.URI.Contains("$ref"))
                    {
                        VerifyLinksPayload(request.Workspace, payload, linqBuilder);
                    }
                    else if (payload.Resources == null)
                    {
                        if (request.Format == SerializationFormatKind.JSON)
                        {
                            payload.CompareValue(linqBuilder.QueryResult, true, false);
                        }
                        else
                        {
                            payload.CompareValue(linqBuilder.QueryResult, false, false);
                        }
                    }
                    else
                    {
                        payload.Compare(linqBuilder.QueryResult);
                    }
                }
            }
        }
コード例 #14
0
ファイル: PayloadVerifier.cs プロジェクト: zhonli/odata.net
        protected void ComparePropertyValues(NodeType type, PayloadProperty first, PayloadProperty second, bool checkValue)
        {
            if (type is ComplexType)
            {
                if (first.IsNull)
                {
                    if (!second.IsNull)
                    {
                        AstoriaTestLog.FailAndThrow("Second property is unexpectedly non-null");
                    }
                    return;
                }
                else if (second.IsNull)
                {
                    AstoriaTestLog.FailAndThrow("Second property is unexpectedly null");
                }

                PayloadComplexProperty firstComplex  = first as PayloadComplexProperty;
                PayloadComplexProperty secondComplex = second as PayloadComplexProperty;

                if (firstComplex == null)
                {
                    AstoriaTestLog.FailAndThrow("First property was not a complex property");
                }
                if (secondComplex == null)
                {
                    AstoriaTestLog.FailAndThrow("Second property was not a complex property");
                }

                foreach (string propertyName in firstComplex.PayloadProperties.Keys.Union(secondComplex.PayloadProperties.Keys))
                {
                    // TODO: verify typing
                    if (propertyName == "__metadata")
                    {
                        continue;
                    }

                    PayloadProperty firstProperty;
                    bool            firstHadProperty = firstComplex.PayloadProperties.TryGetValue(propertyName, out firstProperty);

                    PayloadProperty secondProperty;
                    bool            secondHadProperty = secondComplex.PayloadProperties.TryGetValue(propertyName, out secondProperty);

                    // so that we can ignore this case later on, check it now
                    if (!firstHadProperty && !secondHadProperty)
                    {
                        AstoriaTestLog.FailAndThrow("Property list contained property '" + propertyName + "' despite neither complex property containing it");
                    }

                    // since a complex type is never open, there shouldnt be any unexpected properties
                    NodeProperty property = (type as ComplexType).Properties.SingleOrDefault(p => p.Name == propertyName);
                    if (property == null)
                    {
                        if (firstHadProperty && secondHadProperty)
                        {
                            AstoriaTestLog.FailAndThrow("Both complex properties contained sub-property '" + propertyName + "' which is not defined on type '" + type.Name + "'");
                        }
                        else if (firstHadProperty)
                        {
                            AstoriaTestLog.FailAndThrow("First complex property contained sub-property '" + propertyName + "' which is not defined on type '" + type.Name + "'");
                        }
                        else if (secondHadProperty)
                        {
                            AstoriaTestLog.FailAndThrow("Second complex property contained sub-property '" + propertyName + "' which is not defined on type '" + type.Name + "'");
                        }
                    }

                    if (!firstHadProperty)
                    {
                        AstoriaTestLog.FailAndThrow("First complex property property missing sub-property '" + propertyName + "'");
                    }
                    else if (!secondHadProperty)
                    {
                        AstoriaTestLog.FailAndThrow("Second complex property property missing sub-property '" + propertyName + "'");
                    }

                    ComparePropertyValues(property, firstProperty, secondProperty, checkValue && !property.Facets.ServerGenerated);
                }
            }
            else
            {
                PayloadSimpleProperty firstSimple  = first as PayloadSimpleProperty;
                PayloadSimpleProperty secondSimple = second as PayloadSimpleProperty;

                if (firstSimple == null)
                {
                    AstoriaTestLog.FailAndThrow("First property was not a simple property");
                }
                if (secondSimple == null)
                {
                    AstoriaTestLog.FailAndThrow("Second property was not a simple property");
                }

                object expectedObject = CommonPayload.DeserializeStringToObject(firstSimple.Value, type.ClrType, false, first.ParentObject.Format);
                if (checkValue)
                {
                    CommonPayload.ComparePrimitiveValuesObjectAndString(expectedObject, type.ClrType, secondSimple.Value, false, second.ParentObject.Format, true);
                }
                else
                {
                    CommonPayload.DeserializeStringToObject(secondSimple.Value, type.ClrType, false, second.ParentObject.Format);
                }
            }
        }
コード例 #15
0
        private void Verify(AstoriaRequest request)
        {
            RequestVerb verb  = request.EffectiveVerb;
            bool        merge = verb == RequestVerb.Patch;

            PayloadObject entityBefore;

            if (!TryGetSingleObjectFromPayload(request.BeforeUpdatePayload, out entityBefore))
            {
                AstoriaTestLog.FailAndThrow("Pre-update payload did not contain a single entity");
            }

            // determine the type based on what was there (doing .Single() doesn't work for MEST, because the type shows up twice)
            ResourceType type = request.Workspace.ServiceContainer.ResourceTypes.First(rt => entityBefore.Type.Equals(rt.Namespace + "." + rt.Name));

            PayloadObject entityAfter;

            if (!TryGetSingleObjectFromPayload(request.AfterUpdatePayload, out entityAfter))
            {
                AstoriaTestLog.FailAndThrow("Post-update payload did not contain a single entity");
            }

            CommonPayload updatePayload = request.CommonPayload;
            PayloadObject entityUpdate  = null;

            if (request.URI.EndsWith("$value"))
            {
                Match match = Regex.Match(request.URI, @".*/(.+)/\$value");
                if (!match.Success)
                {
                    AstoriaTestLog.FailAndThrow("Could not determine property name for $value request");
                }

                string propertyValue = null;
                if (request.ContentType.Equals(SerializationFormatKinds.MimeApplicationOctetStream, StringComparison.InvariantCultureIgnoreCase))
                {
                    object value = (request.UpdateTree as ResourceInstanceSimpleProperty).PropertyValue;
                    if (updatePayload.Format == SerializationFormatKind.JSON)
                    {
                        propertyValue = JSONPayload.ConvertJsonValue(value);
                    }
                    else
                    {
                        AstoriaTestLog.FailAndThrow("Unsure how to fake property value");
                    }
                }
                else
                {
                    propertyValue = request.Payload;
                }

                entityUpdate = new PayloadObject(updatePayload);
                PayloadSimpleProperty propertyUpdate = new PayloadSimpleProperty(entityUpdate);
                propertyUpdate.Name  = match.Groups[1].Value;
                propertyUpdate.Value = propertyValue;
                entityUpdate.PayloadProperties.Add(propertyUpdate);
                merge = true; //PUT to a single property doesn't reset the resource
            }
            else if (!TryGetSingleObjectFromPayload(updatePayload, out entityUpdate))
            {
                // must be a single property update
                PayloadProperty propertyUpdate = updatePayload.Resources as PayloadProperty;
                if (propertyUpdate == null)
                {
                    AstoriaTestLog.FailAndThrow("Expected either a property or an entity in the update payload");
                }
                entityUpdate = new PayloadObject(updatePayload);
                entityUpdate.PayloadProperties.Add(propertyUpdate);
                propertyUpdate.ParentObject = entityUpdate;
                merge = true; //PUT to a single property doesn't reset the resource
            }

            List <string> allPropertyNames = entityBefore.PayloadProperties
                                             .Union(entityAfter.PayloadProperties)
                                             .Union(entityUpdate.PayloadProperties)
                                             .Select(p => p.Name)
                                             .ToList();

            allPropertyNames.AddRange(entityBefore.CustomEpmMappedProperties.Keys);
            allPropertyNames.AddRange(entityUpdate.CustomEpmMappedProperties.Keys);
            allPropertyNames.AddRange(entityAfter.CustomEpmMappedProperties.Keys);

            foreach (string propertyName in allPropertyNames.Distinct())
            {
                PayloadProperty original            = null;
                bool            originalHadProperty = entityBefore.PayloadProperties.Any(p => (original = p).Name == propertyName);

                PayloadProperty update            = null;
                bool            updateHadProperty = entityUpdate.PayloadProperties.Any(p => (update = p).Name == propertyName);

                PayloadProperty final            = null;
                bool            finalHadProperty = entityAfter.PayloadProperties.Any(p => (final = p).Name == propertyName);

                if (type.Properties.Any(p => p.Name == propertyName && p.Facets.IsDeclaredProperty))
                {
                    // declared property

                    if (!finalHadProperty)
                    {
                        AstoriaTestLog.FailAndThrow("Final version of entity is missing declared property '" + propertyName + "'");
                    }

                    ResourceProperty property = type.Properties[propertyName] as ResourceProperty;

                    if (property.IsNavigation)
                    {
                        continue;
                    }

                    if (!originalHadProperty)
                    {
                        AstoriaTestLog.FailAndThrow("Original version of entity is missing declared property '" + propertyName + "'");
                    }

                    bool checkValue = property.PrimaryKey == null && !property.Facets.ServerGenerated;

                    // if we changed it, we don't care what it was
                    if (updateHadProperty)
                    {
                        ComparePropertyValues(property, update, final, checkValue);
                    }
                    else if (merge)
                    {
                        ComparePropertyValues(property, original, final, checkValue);
                    }
                    else if (checkValue)
                    {
                        CompareResetProperty(property, final);
                    }
                }
                else
                {
                    // dynamic property
                    if (updateHadProperty)
                    {
                        if (!finalHadProperty)
                        {
                            AstoriaTestLog.FailAndThrow("Final version of entity is missing dynamic property '" + propertyName + "'");
                        }
                        CompareDynamicPropertyValues(update, final);
                    }
                    else if (merge)
                    {
                        if (!finalHadProperty)
                        {
                            AstoriaTestLog.FailAndThrow("Final version of entity is missing dynamic property '" + propertyName + "'");
                        }
                        CompareDynamicPropertyValues(original, final);
                    }
                    else if (finalHadProperty)
                    {
                        AstoriaTestLog.FailAndThrow("Dynamic property '" + propertyName + "' was not cleared after reset");
                    }
                }
            }
        }
コード例 #16
0
        private void CompareResetProperty(NodeProperty property, PayloadProperty value)
        {
            bool complexType = property.Type is ComplexType;

            Workspace w          = value.ParentObject.Payload.Workspace;
            bool      expectNull = false;

            if (w.DataLayerProviderKind == DataLayerProviderKind.NonClr && (!property.Facets.IsClrProperty || complexType))
            {
                expectNull = true;
            }
            if (w.DataLayerProviderKind == DataLayerProviderKind.InMemoryLinq && complexType)
            {
                expectNull = true;
            }
            if (!property.Facets.IsDeclaredProperty)
            {
                expectNull = true;
            }
            if (property.Facets.Nullable)
            {
                expectNull = true;
            }

            if (property.Type is ComplexType)
            {
                if (value.IsNull)
                {
                    if (!expectNull)
                    {
                        AstoriaTestLog.FailAndThrow("Complex property '" + property.Name + " is unexpectedly null after reset");
                    }
                }
                else
                {
                    if (!(value is PayloadComplexProperty))
                    {
                        AstoriaTestLog.FailAndThrow("Property '" + property.Name + "' is complex, but a simple property was found instead");
                    }

                    ComplexType            ct = property.Type as ComplexType;
                    PayloadComplexProperty complexProperty = value as PayloadComplexProperty;
                    foreach (NodeProperty subProperty in ct.Properties)
                    {
                        PayloadProperty subValue;
                        if (!complexProperty.PayloadProperties.TryGetValue(subProperty.Name, out subValue))
                        {
                            AstoriaTestLog.FailAndThrow("Property of complex type '" + ct.Name + "' missing sub-property '" + subProperty.Name + "'");
                        }

                        CompareResetProperty(subProperty, subValue);
                    }
                }
            }
            else
            {
                PayloadSimpleProperty simpleProperty = value as PayloadSimpleProperty;
                if (simpleProperty == null)
                {
                    AstoriaTestLog.FailAndThrow("Property was unexpectedly not a simple property");
                }

                Type   propertyType = property.Type.ClrType;
                object expected     = null;
                if (!expectNull)
                {
                    expected = DefaultValue(propertyType);
                }
                CommonPayload.ComparePrimitiveValuesObjectAndString(expected, propertyType, simpleProperty.Value, false, value.ParentObject.Format, true);
            }
        }