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"); } } } }
private void VerifyInsertResponse(ResourceType type, PayloadObject inserted, PayloadObject returned) { // need to 'follow' deferred links to ensure that they're correct // doesn't need to match exactly AstoriaTestLog.AreEqual(inserted.Type, returned.Type, "Types do not match"); VerifyProperties(type, inserted, returned, true, (rp => !rp.Facets.ServerGenerated)); }
private void VerifyQueryResponse(ResourceType type, PayloadObject fromInsert, PayloadObject fromQuery) { bool keyShouldMatch = true; if (type.Key.Properties.Any(p => p.Facets.FixedLength)) { foreach (NodeProperty property in type.Key.Properties.Where(p => p.Facets.FixedLength)) { // this may not always be correct for all types, but it seems to work most of the time; int length; if (property.Facets.MaxSize.HasValue) { length = property.Facets.MaxSize.Value; } else if (property.Type == Clr.Types.Decimal) { length = property.Facets.Precision.Value + property.Facets.Scale.Value; } else { continue; } string value = null; if (fromInsert.PayloadProperties.Any(p => p.Name == property.Name)) { value = (fromInsert[property.Name] as PayloadSimpleProperty).Value; } else { value = fromInsert.CustomEpmMappedProperties[property.Name]; } if (value != null && value.Length < length) { keyShouldMatch = false; } } } if (keyShouldMatch) { AstoriaTestLog.AreEqual(fromInsert.AbsoluteUri, fromQuery.AbsoluteUri, "fromInsert.AbsoluteUri != fromQuery.AbsoluteUri", false); } else { AstoriaTestLog.IsFalse(fromInsert.AbsoluteUri == fromQuery.AbsoluteUri, "fromInsert.AbsoluteUri == fromQuery.AbsoluteUri, despite fixed-length string"); } // leave it to the concurrency tests to check the more involved etags if (!type.Properties.Any(p => p.Facets.ConcurrencyModeFixed && p.Facets.FixedLength)) { AstoriaTestLog.AreEqual(fromInsert.ETag, fromQuery.ETag, "fromInsert.ETag != fromQuery.ETag", false); } VerifyProperties(type, fromInsert, fromQuery, false, rp => true); }
public static void VerifyUnknownVerb(AstoriaResponse webResponse) { AstoriaTestLog.AreEqual(System.Net.HttpStatusCode.NotImplemented, webResponse.ActualStatusCode, "Unknown verbs should receive a 'Not Implemented' reply."); if (webResponse.ContentType != null) { AstoriaTestLog.IsTrue(webResponse.ContentType.StartsWith(SerializationFormatKinds.JsonMimeType, StringComparison.Ordinal), "Error messages should have no content type or an application/json content type."); } }
private void Compare(IList <object> baselineObjects, IList <PayloadObject> payloadObjects, bool ignoreOrder) { AstoriaTestLog.AreEqual(baselineObjects.Count, payloadObjects.Count, "Count of baseline not equal to returned elements.", false); for (int position = 0; position < baselineObjects.Count; position++) { PayloadObject fromPayload = payloadObjects[position]; object fromBaseline = null; if (ignoreOrder) { foreach (object entity in baselineObjects) { if (this.CompareProperties(fromPayload, entity, false)) { fromBaseline = entity; break; } } if (fromBaseline == null) { throw new TestFailedException("Could not find matching entity"); } else { baselineObjects.Remove(fromBaseline); } } else { fromBaseline = baselineObjects[position]; try { this.CompareProperties(fromPayload, fromBaseline, true); } catch (Exception e) { throw new TestFailedException("Payload properties do not match baseline for entity at position " + position + " in payload", null, null, e); } } try { this.CompareObjects(fromPayload, fromBaseline); } catch (Exception e) { throw new TestFailedException("Payload objects do not match baseline for entity at position " + position + " in payload", null, null, e); } } }
public void Add(ContainmentAttribute att, bool abbrChild) { ContainmentQuerySegment segment = new ContainmentQuerySegment(att, abbrChild); if (segments.Count == 0) { AstoriaTestLog.AreEqual(segment.attribute.ParentContainer, rootContainer, "First segment's parent container does not match this path's root container"); } else { AstoriaTestLog.AreEqual(segment.attribute.ParentContainer, segments.Last().attribute.ChildContainer, "New segment's parent does not match the current last container"); } segments.Add(segment); }
protected void CompareDynamicPropertyValues(PayloadProperty inserted, PayloadProperty returned) { if (inserted.IsNull || returned.IsNull) { if (!inserted.IsNull) { AstoriaTestLog.FailAndThrow("Null inserted value was non-null in return payload"); } if (!returned.IsNull) { AstoriaTestLog.FailAndThrow("Non-null inserted value was null in return payload"); } } else { NodeType insertType = GetDynamicPropertyType(inserted); NodeType returnType = GetDynamicPropertyType(returned); if (inserted.MappedOutOfContent == returned.MappedOutOfContent) { bool equivalentTypes = false; if (EquivalentValues(insertType, inserted, returnType, returned)) { equivalentTypes = true; } if (EquivalentValues(returnType, returned, insertType, inserted)) { equivalentTypes = true; } if (!equivalentTypes) { AstoriaTestLog.AreEqual(insertType, returnType, "Type of inserted/updated dynamic property value does not match returned type for property", false); } } else if (inserted.MappedOutOfContent) { insertType = returnType; } ComparePropertyValues(insertType, inserted, returned, true); } }
private static void CompareEntityContainer(IEdmEntityContainer edmEntityContainer, IEdmEntityContainer dataWebEntityContainer) { AstoriaTestLog.AreEqual(edmEntityContainer.FullName(), dataWebEntityContainer.FullName()); int numberOfEntitySets = 0; foreach (IEdmEntitySet entitySetBase in edmEntityContainer.EntitySets()) { // compare the entity set base IEdmEntitySet dataWebEntitySetBase = dataWebEntityContainer.FindEntitySet(entitySetBase.Name); AstoriaTestLog.IsNotNull(dataWebEntitySetBase); AstoriaTestLog.AreEqual(entitySetBase.Name, dataWebEntitySetBase.Name); AstoriaTestLog.AreEqual(entitySetBase.EntityType().FullName(), dataWebEntitySetBase.EntityType().FullName()); ++numberOfEntitySets; } AstoriaTestLog.IsTrue(numberOfEntitySets == dataWebEntityContainer.EntitySets().Count(), "Number of baseEntitySets must match"); }
public static void ComparePrimitiveValuesObjectAndString(object expected, Type expectedType, string actual, bool valueUri, SerializationFormatKind serializationKind, bool throwOnError) { object actualObject = DeserializeStringToObject(actual, expectedType, valueUri, serializationKind); string expectedStr = "null"; if (expected != null) { expectedStr = AstoriaUnitTests.Data.TypeData.XmlValueFromObject(expected); } string errorMessage = String.Format("Error Primitive Value of type:{0} not equal: \r\n\tExpected:\t{1} \r\n\tActual:\t{2}", expectedType.Name, expectedStr, actual); //Fixups if (expected != null && expectedType.Equals(typeof(string))) { if (actualObject != null) { actualObject = (actualObject as string).Trim(); } expected = (expected as string).Trim(); } if (expectedType == typeof(System.Xml.Linq.XElement)) { expectedStr = null; if (expected != null) { System.Xml.Linq.XElement xElement = expected as System.Xml.Linq.XElement; expectedStr = xElement.ToString(); } AstoriaTestLog.AreEqual(expectedStr, actual, errorMessage); } else if (expectedType == typeof(Single) || expectedType == typeof(Double)) { if (serializationKind == SerializationFormatKind.JSON) { if (expectedType == typeof(Double)) { Double d; if (expected != null) { d = Convert.ToDouble(expected); expectedStr = d.ToString("r", System.Globalization.CultureInfo.InvariantCulture); } if (actual != null) { if (double.TryParse(actual, NumberStyles.Any, CultureInfo.InvariantCulture.NumberFormat, out d)) { actual = d.ToString("r", CultureInfo.InvariantCulture.NumberFormat); } } } else if (expectedType == typeof(Single)) { Single s; if (expected != null) { s = Convert.ToSingle(expected); expectedStr = s.ToString("r", System.Globalization.CultureInfo.InvariantCulture); } if (actual != null) { if (Single.TryParse(actual, NumberStyles.Any, CultureInfo.InvariantCulture.NumberFormat, out s)) { actual = s.ToString("r", CultureInfo.InvariantCulture.NumberFormat); } } } } //Fixup if (expectedStr == "null") { expectedStr = null; } if (expectedStr != null && actual != null) { expectedStr = expectedStr.Trim(); actual = actual.Trim(); } if (throwOnError) { if (expectedStr != null) { AstoriaTestLog.Compare(expectedStr.Equals(actual), errorMessage); } else { AstoriaTestLog.Compare(actual == null, errorMessage); } } else { AstoriaTestLog.AreEqual(expectedStr, actual, errorMessage); } } #if !ClientSKUFramework //For some reason byte[] comparision is not working correctly else if ((expectedType == typeof(byte[]) || expectedType == typeof(System.Data.Linq.Binary)) && valueUri) { string expectedBytesStr = null; if (expected == null) { expectedBytesStr = null; } else if (expectedType == typeof(byte[])) { expectedBytesStr = (new System.Text.UTF8Encoding()).GetString((byte[])expected); } else if (expectedType == typeof(System.Data.Linq.Binary)) { System.Data.Linq.Binary binary = expected as System.Data.Linq.Binary; expectedBytesStr = (new System.Text.UTF8Encoding()).GetString((byte[])binary.ToArray()); } if (throwOnError) { if (expected == null) { AstoriaTestLog.Compare(null == actual, errorMessage); } else { AstoriaTestLog.Compare(expectedBytesStr.Equals(actual), errorMessage); } } else { AstoriaTestLog.AreEqual(expectedBytesStr, actual, errorMessage); } } #endif else if (expectedType == typeof(byte[]) && valueUri == false) { AreBytesEqual((byte[])expected, (byte[])actualObject, throwOnError); } else { if (throwOnError) { bool objectsEqual = true; if (expected == null) { if (actualObject != null) { objectsEqual = false; } } else { objectsEqual = expected.Equals(actualObject); } AstoriaTestLog.Compare(objectsEqual, errorMessage); } else { AstoriaTestLog.AreEqual(expected, actualObject, errorMessage); } } }
private static void AreBytesEqual(byte[] expected, byte[] actual, bool throwOnError) { if (expected == null && actual == null) { return; } else if (expected == null && actual != null) { if (throwOnError) { AstoriaTestLog.Compare(false, "Expected Actual to be null like expected"); } else { AstoriaTestLog.AreEqual(expected, actual, "Bytes not equal"); } return; } else if (expected != null && actual == null) { if (throwOnError) { AstoriaTestLog.Compare(false, "Expected Actual to be a value like expected"); } else { AstoriaTestLog.AreEqual(expected, actual, "Bytes not equal"); } return; } if (throwOnError) { AstoriaTestLog.Compare(expected.Length == actual.Length, "Bytes lengths are not equal"); } else { AstoriaTestLog.AreEqual(expected.Length, actual.Length, "Bytes lengths are not equal"); } bool errorFound = false; for (int i = 0; i < expected.Length; i++) { if (expected[i] != actual[i]) { errorFound = true; string errorMessage = String.Format("Byte arrays not equal at index {0}, expected:{1} actual:{2}", i, expected[i], actual[i]); if (throwOnError) { AstoriaTestLog.Compare(expected[i] == actual[i], errorMessage); } else { AstoriaTestLog.AreEqual(expected.Length, actual.Length, errorMessage); } } if (errorFound == true) { break; } } }
public static void CompareMetadata(IEdmModel expectedItems, IEdmModel actualItems, bool isReflectionBasedProvider, string defaultEntityContainerName, ServiceContainer serviceContainer) { // // Verify the metadata version is correct, the number of entity containers is 1, the entity // container names match, and the number of entity types are the same // AstoriaTestLog.AreEqual(1.1, actualItems.GetEdmVersion(), "The metadata version was not correct"); AstoriaTestLog.AreEqual(serviceContainer.Workspace.ContextTypeName, actualItems.EntityContainer.Name, "Entity Container names do not match"); if (!isReflectionBasedProvider) { AstoriaTestLog.AreEqual(expectedItems.SchemaElements.OfType <IEdmEntityType>().Count(), actualItems.SchemaElements.OfType <IEdmEntityType>().Count(), "Entity Type Counts do not match"); } foreach (IEdmOperationImport metadataExposedFunction in actualItems.EntityContainer.OperationImports()) { AstoriaTestLog.TraceInfo("--> " + metadataExposedFunction.Name); } // // For each entity type exposed through the metadata endpoint, verify the following // 1. Verify it has an equivalent definition in the resource container // 2. Verify the entity type name is correct // 3. Verify that no navigation property is exposed in the entity type // 4. Verify that the property count in the entity type // IEnumerable <ComplexType> rtTypeCollection = serviceContainer.AllTypes.Where(a => a.GetType().Name.Equals("ResourceType")); AstoriaTestLog.TraceInfo(rtTypeCollection.Count().ToString()); foreach (IEdmEntityType metadataExposedEntityType in actualItems.SchemaElements.OfType <IEdmEntityType>()) { ResourceType resourceContainerEntityType = serviceContainer.AllTypes.Where(b => b.GetType().Name.Equals("ResourceType") & (b.FullName.Equals(metadataExposedEntityType.FullName()))).FirstOrDefault() as ResourceType; if (resourceContainerEntityType == null) { continue; } AstoriaTestLog.IsNotNull(resourceContainerEntityType, "Did not find entity type in resource container"); AstoriaTestLog.AreEqual(resourceContainerEntityType.FullName, metadataExposedEntityType.FullName(), "Entity Type name mismatch"); // // Verify the name, type, and nullable attribute values // ResourceContainer rc = serviceContainer.ResourceContainers.Where(a => a.BaseType.Name.Equals(metadataExposedEntityType.Name)).FirstOrDefault(); if (rc == null) { continue; } int navCount = rc.BaseType.Properties.Cast <NodeProperty>().Cast <ResourceProperty>().Where(a => a.IsNavigation).Count(); AstoriaTestLog.TraceInfo(rc.Name); AstoriaTestLog.TraceInfo(navCount.ToString()); AstoriaTestLog.AreEqual(resourceContainerEntityType.Properties.Count - navCount, metadataExposedEntityType.Properties().Count(), "Edm Property count mismatch"); foreach (IEdmProperty metadataExposedProperty in metadataExposedEntityType.Properties()) { string errorStringEntityTypeProperty = metadataExposedEntityType.FullName() + " : " + metadataExposedProperty.Name; NodeProperty resourceContainerProperty = resourceContainerEntityType.Properties.Where(a => a.Name.Equals(metadataExposedProperty.Name)).FirstOrDefault(); AstoriaTestLog.IsNotNull(resourceContainerProperty, "Did not find property -->" + errorStringEntityTypeProperty + "<-- in resource container"); if (resourceContainerProperty == null) { continue; } if (metadataExposedProperty.Type.IsBinary()) { if (AstoriaTestProperties.DataLayerProviderKinds.Contains(DataLayerProviderKind.LinqToSql)) { AstoriaTestLog.AreEqual("System.Data.Linq.Binary", resourceContainerProperty.Type.ClrType.FullName, errorStringEntityTypeProperty + " type is incorrect"); } else { AstoriaTestLog.AreEqual("System.Byte[]", resourceContainerProperty.Type.ClrType.FullName, errorStringEntityTypeProperty + " type is incorrect"); } } else { AstoriaTestLog.AreEqual(metadataExposedProperty.Type.FullName(), resourceContainerProperty.Type.FullName, errorStringEntityTypeProperty + " type is incorrect"); } } } }
public static void AreEqual(object expected, object actual) { AstoriaTestLog.AreEqual(expected, actual, "", true); }
public void Verify(AstoriaResponse response) { string payload = response.Payload; XmlNodeList childNodes = null; XmlNode xmlData = FormatVerifyUtils.FindFirstChild(payload); if (xmlData.Name == "feed") { /* atom:feed elements MUST contain one or more atom:author elements, * unless all of the atom:feed element's child atom:entry elements * contain at least one atom:author element. */ childNodes = xmlData.SelectNodes("atom:author", _formatVerifier.XmlNamespaceManager); XmlNodeList entries = xmlData.SelectNodes("atom:entry", _formatVerifier.XmlNamespaceManager); if (childNodes.Count == 0) { if (entries.Count > 0) { foreach (XmlNode node in entries) { XmlNode authorNode = node.SelectSingleNode("atom:author[1]", _formatVerifier.XmlNamespaceManager); if (authorNode == null) { AstoriaTestLog.FailAndContinue(new TestFailedException("4.1.1 Feed element: No author node in entry of feed without author node.")); } } } else { AstoriaTestLog.FailAndContinue(new TestFailedException("4.1.1 Feed element: No author node in feed with no entries.")); } } // atom:feed elements MUST NOT contain more than one atom:generator element. childNodes = xmlData.SelectNodes("atom:generator", _formatVerifier.XmlNamespaceManager); if (childNodes.Count > 1) { AstoriaTestLog.FailAndContinue(new TestFailedException("4.1.1 Feed element: More than 1 generator node found for feed.")); } // atom:feed elements MUST NOT contain more than one atom:icon element. childNodes = xmlData.SelectNodes("atom:icon", _formatVerifier.XmlNamespaceManager); if (childNodes.Count > 1) { AstoriaTestLog.FailAndContinue(new TestFailedException("4.1.1 Feed element: More than 1 icon node found for feed.")); } // atom:feed elements MUST NOT contain more than one atom:logo element. childNodes = xmlData.SelectNodes("atom:logo", _formatVerifier.XmlNamespaceManager); if (childNodes.Count > 1) { AstoriaTestLog.FailAndContinue(new TestFailedException("4.1.1 Feed element: More than 1 logo node found for feed.")); } // atom:feed elements MUST contain exactly one atom:id element childNodes = xmlData.SelectNodes("atom:id", _formatVerifier.XmlNamespaceManager); if (childNodes.Count != 1) { AstoriaTestLog.FailAndContinue(new TestFailedException("4.1.1 Feed element: Not exactly 1 id node found for feed.")); } /* atom:feed elements SHOULD contain one atom:link element with a rel * attribute value of "self". This is the preferred URI for * retrieving Atom Feed Documents representing this Atom feed. * * atom:feed elements MUST NOT contain more than one atom:link * element with a rel attribute value of "alternate" that has the * same combination of type and hreflang attribute values. */ int selfLinkCount = 0, altLinkCount = 0; childNodes = xmlData.SelectNodes("atom:link", _formatVerifier.XmlNamespaceManager); foreach (XmlNode node in childNodes) { if (node.Attributes["rel"] != null && node.Attributes["rel"].Value == "self") { selfLinkCount++; } else if (node.Attributes["rel"] != null && node.Attributes["rel"].Value == "alternate") { altLinkCount++; } } AstoriaTestLog.AreEqual(1, selfLinkCount, "4.1.1 Feed element: Not exactly 1 self link node found for feed"); AstoriaTestLog.AreEqual(false, altLinkCount > 1, "4.1.1 Feed element: More than 1 alternate link node found for feed"); // atom:feed elements MUST NOT contain more than one atom:rights element. childNodes = xmlData.SelectNodes("atom:rights", _formatVerifier.XmlNamespaceManager); if (childNodes.Count > 1) { AstoriaTestLog.FailAndContinue(new TestFailedException("4.1.1 Feed element: More than 1 rights node found for feed.")); } // atom:feed elements MUST NOT contain more than one atom:subtitle element. childNodes = xmlData.SelectNodes("atom:subtitle", _formatVerifier.XmlNamespaceManager); if (childNodes.Count > 1) { AstoriaTestLog.FailAndContinue(new TestFailedException("4.1.1 Feed element: More than 1 subtitle node found for feed.")); } // atom:feed elements MUST contain exactly one atom:title element. childNodes = xmlData.SelectNodes("atom:title", _formatVerifier.XmlNamespaceManager); if (childNodes.Count != 1) { AstoriaTestLog.FailAndContinue(new TestFailedException("4.1.1 Feed element: Not exactly 1 title node found for feed.")); } // atom:feed elements MUST contain exactly one atom:updated element. childNodes = xmlData.SelectNodes("atom:updated", _formatVerifier.XmlNamespaceManager); if (childNodes.Count != 1) { AstoriaTestLog.FailAndContinue(new TestFailedException("4.1.1 Feed element: Not exactly 1 updated node found for feed.")); } } }
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); } } } }
public static bool AreEqual(object expected, object actual, string message) { return(AstoriaTestLog.AreEqual(expected, actual, message, true)); }
private void VerifyProperties(ResourceType type, PayloadObject inserted, PayloadObject returned, bool missingInsertPropertiesOk, Func <ResourceProperty, bool> strictEquality) { List <string> propertyNames = inserted.PayloadProperties.Union(returned.PayloadProperties).Select(p => p.Name).ToList(); propertyNames.AddRange(inserted.CustomEpmMappedProperties.Keys); propertyNames.AddRange(returned.CustomEpmMappedProperties.Keys); foreach (string propertyName in propertyNames.Distinct()) { PayloadProperty insertedProperty; if (inserted.Format == SerializationFormatKind.JSON) //in JSON the first one wins { insertedProperty = inserted.PayloadProperties.FirstOrDefault(p => p.Name == propertyName); } else //in xml the last one wins { insertedProperty = inserted.PayloadProperties.LastOrDefault(p => p.Name == propertyName); } bool insertHadProperty = insertedProperty != null; PayloadProperty returnedProperty = returned.PayloadProperties.LastOrDefault(p => p.Name == propertyName);; bool returnedHadProperty = returnedProperty != null; ResourceProperty property = type.Properties.OfType <ResourceProperty>().SingleOrDefault(p => p.Name == propertyName); if (property == null || !property.Facets.IsDeclaredProperty) { if (!type.Facets.IsOpenType) { string error = "included dynamic property '" + propertyName + "' despite '" + type.Name + "' not being an open type"; if (insertHadProperty && returnedHadProperty) { AstoriaTestLog.FailAndThrow("Both the inserted and returned objects " + error); } else if (insertHadProperty) { AstoriaTestLog.FailAndThrow("The inserted object " + error); } else if (returnedHadProperty) { AstoriaTestLog.FailAndThrow("The returned object " + error); } } else { if (insertHadProperty && returnedHadProperty) { CompareDynamicPropertyValues(insertedProperty, returnedProperty); } else if (insertHadProperty) { // only acceptable if inserted value was null if (insertedProperty.IsNull) { AstoriaTestLog.FailAndThrow("Returned object missing non-null dynamic property '" + propertyName + "'"); } } } } else { if (property.IsNavigation) { // the insert payload may not specify this property //PayloadObject insertedObject = inserted.PayloadObjects.SingleOrDefault(o => o.Name == property.Name); PayloadObject returnedObject = returned.PayloadObjects.Single(o => o.Name == property.Name); // returned thing should be deferred whether its a reference or not AstoriaTestLog.AreEqual(true, returnedObject.Deferred, "!returnedObject.Deferred", false); // TODO: verify only expected links are present (based on uri and payload values as well) } else { if (insertHadProperty && returnedHadProperty) { try { ComparePropertyValues(property, insertedProperty, returnedProperty, strictEquality(property)); } catch (Exception e) { throw new TestFailedException("Value of property '" + property.Name + "' does not match inserted value", null, null, e); } } else if (insertHadProperty) { AstoriaTestLog.FailAndThrow("Returned object unexpectedly missing declared property '" + propertyName + "'"); } else if (returnedHadProperty) { if (missingInsertPropertiesOk) { AstoriaTestLog.WriteLineIgnore("Ignoring missing declared property '" + propertyName + "' in insert payload"); } else { AstoriaTestLog.FailAndThrow("Inserted object unexpectedly missing declared property '" + propertyName + "'"); } } } } } }
public ContainmentQuery ToQuery(KeyExpression keyExpression, bool setOnly) { ResourceContainer finalContainer = FinalContainer; AstoriaTestLog.AreEqual(keyExpression.ResourceContainer, finalContainer, "ToQuery given a KeyExpression to an unexpected resource container"); List <KeyExpression> keys = GetContainingKeys(keyExpression); List <ResourceContainer> omittedContainers = segments.Where(s => s.omitParent).Select(s => s.attribute.ParentContainer).ToList(); ContainmentQuery query = new ContainmentQuery(); query.Query = null; query.Container = finalContainer; query.Type = query.Container.BaseType; query.Workspace = query.Container.Workspace; query.SetExpected = setOnly; ResourceContainer parentContainer = null; foreach (KeyExpression key in keys) { if (omittedContainers.Contains(key.ResourceContainer)) { continue; } bool omitKey = (setOnly && key == keyExpression); if (parentContainer == null) { if (!query.ErrorExpected && !key.ResourceContainer.BaseType.Facets.TopLevelAccess) { SetTopLevelAccessError(query, key.ResourceType); } if (!omitKey) { if (!query.ErrorExpected && key.IncludeInUri.Contains(false)) { SetMissingKeysError(query, key.ResourceType); } } query.Query = Query.From(Exp.Variable(key.ResourceContainer)); } else { ResourceProperty navProp = segments .Where(s => s.attribute.ParentContainer == parentContainer) .Select(s => s.attribute.ParentNavigationProperty) .FirstOrDefault(); query.Query = query.Query.Nav(navProp.Property()); } parentContainer = key.ResourceContainer; // if we just want the set, leave off the last where clause if (!omitKey) { query.Query = query.Query.Where(key); } } return(query); }
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; } }
internal PayloadObject ParseEntry(XElement xmlData) { PayloadObject payloadObject = new PayloadObject(this); #region edit link XElement linkEdit = xmlData.Elements(atom + "link").SingleOrDefault(l => l.Attribute("rel") != null && l.Attribute("rel").Value == "edit"); if (linkEdit != null) { payloadObject.Uri = linkEdit.Attribute("href").Value; } #endregion #region id link XElement idNode = xmlData.Element(atom + "id"); if (idNode != null) { payloadObject.Uri = idNode.Value; } // TODO: compare the edit link to the ID node's value #endregion #region name XElement titleNode = xmlData.Parent; if (titleNode != null && titleNode.Name == m + "inline") { XAttribute titleAttribute = titleNode.Parent.Attribute("title"); if (titleAttribute != null) { payloadObject.Name = titleAttribute.Value; } } else if (titleNode != null) { titleNode = titleNode.Element(atom + "title"); if (titleNode != null) { payloadObject.Name = titleNode.Value; } } else if (linkEdit != null) { XAttribute titleAttribute = linkEdit.Attribute("title"); if (titleAttribute != null) { payloadObject.Name = titleAttribute.Value; } } #endregion #region type bool isMediaLink = false; XElement category = xmlData.Element(atom + "category"); ResourceType type = null; if (category != null) { XAttribute term = category.Attribute("term"); if (term != null) { payloadObject.Type = term.Value; type = Workspace.ServiceContainer.ResourceTypes.Single(rt => rt.Namespace + "." + rt.Name == term.Value); if (type.Facets.HasStream) { isMediaLink = true; } } } #endregion #region friendly feeds ParseNullableSyndicationItemProperty(AtomSyndicationItemProperty.Title, xmlData, payloadObject); ParseNullableSyndicationItemProperty(AtomSyndicationItemProperty.Summary, xmlData, payloadObject); ParseNullableSyndicationItemProperty(AtomSyndicationItemProperty.Rights, xmlData, payloadObject); //This is the correct mapping for Friendly Feeds SyndicationItemProperty.Published XElement ffEntryPublishedNode = xmlData.Element(atom + "published"); if (ffEntryPublishedNode != null) { payloadObject.SyndicationItemProperties[AtomSyndicationItemProperty.Published] = ffEntryPublishedNode.Value; } //This is the correct mapping for Friendly Feeds SyndicationItemProperty.Updated XElement ffEntryUpdatedNode = xmlData.Element(atom + "updated"); if (ffEntryUpdatedNode != null) { payloadObject.SyndicationItemProperties[AtomSyndicationItemProperty.Updated] = ffEntryUpdatedNode.Value; } //This is the correct mapping for Friendly Feeds Author Node XElement ffEntryAuthorNode = xmlData.Element(atom + "author"); if (ffEntryAuthorNode != null) { //Friendly Feeds SyndicationItemProperty.AuthorEmail XElement ffEmailNode = ffEntryAuthorNode.Element(atom + "email"); if (ffEmailNode != null) { payloadObject.SyndicationItemProperties[AtomSyndicationItemProperty.AuthorEmail] = ffEmailNode.Value; } //Friendly Feeds SyndicationItemProperty.AuthorName XElement ffNameNode = ffEntryAuthorNode.Element(atom + "name"); if (ffNameNode != null) { payloadObject.SyndicationItemProperties[AtomSyndicationItemProperty.AuthorName] = ffNameNode.Value; } //Friendly Feeds SyndicationItemProperty.AuthorUri XElement ffUriNode = ffEntryAuthorNode.Element(atom + "uri"); if (ffUriNode != null) { payloadObject.SyndicationItemProperties[AtomSyndicationItemProperty.AuthorUri] = ffUriNode.Value; } } //This is the correct mapping for Friendly Feeds Contributor Node XElement ffEntryContributorNode = xmlData.Element(atom + "contributor"); if (ffEntryContributorNode != null) { //Friendly Feeds SyndicationItemProperty.ContributorEmail XElement ffEmailNode = ffEntryContributorNode.Element(atom + "email"); if (ffEmailNode != null) { payloadObject.SyndicationItemProperties[AtomSyndicationItemProperty.ContributorEmail] = ffEmailNode.Value; } //Friendly Feeds SyndicationItemProperty.ContributorName XElement ffNameNode = ffEntryContributorNode.Element(atom + "name"); if (ffNameNode != null) { payloadObject.SyndicationItemProperties[AtomSyndicationItemProperty.ContributorName] = ffNameNode.Value; } //Friendly Feeds SyndicationItemProperty.ContributorUri XElement ffUriNode = ffEntryContributorNode.Element(atom + "uri"); if (ffUriNode != null) { payloadObject.SyndicationItemProperties[AtomSyndicationItemProperty.ContributorUri] = ffUriNode.Value; } } #endregion #region etag if (xmlData.HasAttributes) { XAttribute etagNodeAttribute = xmlData.Attribute(m + "etag"); if (etagNodeAttribute != null) { payloadObject.ETag = etagNodeAttribute.Value; } } #endregion #region properties XElement content = xmlData.Element(atom + "content"); XElement properties = null; if (content != null) { XAttribute contentType = content.Attribute("type"); if (contentType != null) { if (!isMediaLink) { StringComparison comp; if (WasResponse) { comp = StringComparison.InvariantCulture; } else { comp = StringComparison.InvariantCultureIgnoreCase; } if (!contentType.Value.Equals("application/xml", comp)) { AstoriaTestLog.AreEqual("application/xml", contentType.Value, "Unexpected type on content element", true); } properties = content.Element(m + "properties"); } // TODO: save content type if its a media link } } if (isMediaLink) { properties = xmlData.Element(m + "properties"); } if (properties != null) { foreach (XElement element in properties.Elements()) { PayloadProperty property; if (element.HasElements) { property = ParseComplexProperty(payloadObject, element); } else { property = ParseSimpleProperty(payloadObject, element); } payloadObject.PayloadProperties.Add(property); } } #endregion #region links foreach (XElement link in xmlData.Elements(atom + "link")) { Uri linkRel = new Uri(link.Attribute("rel").Value, UriKind.RelativeOrAbsolute); if (linkRel.IsAbsoluteUri) { string linkRelValue = linkRel.GetComponents(UriComponents.AbsoluteUri, UriFormat.SafeUnescaped); if (linkRelValue.StartsWith(DataWebRelatedNamespace, StringComparison.Ordinal)) { XElement inlineTag = link.Element(m + "inline"); if (inlineTag != null) { PayloadObject nestedPayloadObject = new PayloadObject(this); nestedPayloadObject.Name = linkRelValue.Substring(DataWebRelatedNamespace.Length); string linkType = link.Attribute("type").Value; if (linkType.Contains("feed")) { if (inlineTag.HasElements) { nestedPayloadObject.PayloadObjects.AddRange(this.ParseFeed(inlineTag.Elements().Single())); } } else if (linkType.Contains("entry")) { if (inlineTag.HasElements) { nestedPayloadObject = this.ParseEntry(inlineTag.Elements().Single()); } nestedPayloadObject.Reference = true; } payloadObject.PayloadObjects.Add(nestedPayloadObject); } else { // deferred links PayloadObject deferredObject = new PayloadObject(this); deferredObject.Name = linkRelValue.Substring(DataWebRelatedNamespace.Length); if (link.Attribute("href") != null) { deferredObject.Uri = link.Attribute("href").Value; } deferredObject.Deferred = true; payloadObject.PayloadObjects.Add(deferredObject); } } else if (linkRelValue.StartsWith(DataWebMediaResourceNamespace)) { string name = linkRelValue.Substring(DataWebMediaResourceNamespace.Length); PayloadNamedStream namedStream = payloadObject.NamedStreams.SingleOrDefault(s => s.Name == name); if (namedStream == null) { namedStream = new PayloadNamedStream() { Name = name }; payloadObject.NamedStreams.Add(namedStream); } UpdateNamedStreamMetadata(link, namedStream); namedStream.SelfLink = link.Attribute("href").Value; } else if (linkRelValue.StartsWith(DataWebMediaResourceEditNamespace)) { string name = linkRelValue.Substring(DataWebMediaResourceEditNamespace.Length); PayloadNamedStream namedStream = payloadObject.NamedStreams.SingleOrDefault(s => s.Name == name); if (namedStream == null) { namedStream = new PayloadNamedStream() { Name = name }; payloadObject.NamedStreams.Add(namedStream); } UpdateNamedStreamMetadata(link, namedStream); namedStream.EditLink = link.Attribute("href").Value; } } } #endregion return(payloadObject); }