public void VerifyServer(ExpNode q) { AstoriaTestLog.WriteLineIgnore("Verify server query"); try { UriQueryBuilder ub = new UriQueryBuilder(_workspace, ""); string ruri = ub.Build(q); AstoriaTestLog.WriteLineIgnore(ruri); AstoriaRequest request = _workspace.CreateRequest(q); request.Format = _kind; if (request.URI.Length > 260) { return; } AstoriaResponse response = request.GetResponse(); response.Verify(); } catch (Exception e) { AstoriaTestLog.WriteLineIgnore(e.ToString()); } }
//--------------------------------------------------------------------- public AstoriaResponse SendAndVerify(object expectedPayload, params string[] headers) { // Set auxiliary header values, if any (like ETag). for (int i = 0; i < headers.Length; i += 2) { base.Headers[headers[i]] = headers[i + 1]; } // Determine lowest possible protocol versions. string requestVersion = "1.0"; string responseVersion = "1.0"; if (base.ExpectedStatusCode == HttpStatusCode.OK) { if (base.URI.Contains("$select=")) { requestVersion = "2.0"; responseVersion = "1.0"; } if (base.URI.Contains("$inlinecount=")) { requestVersion = "2.0"; responseVersion = "2.0"; } if (base.URI.Contains("/$count")) { requestVersion = "2.0"; responseVersion = "2.0"; } } // Set request version headers semi-randomly. switch (base.URI.GetHashCode() & 3) { case 0: base.DataServiceVersion = requestVersion; break; case 1: base.DataServiceVersion = null; break; } switch ((base.URI.GetHashCode() >> 2) & 3) { case 0: base.MaxDataServiceVersion = requestVersion; break; case 1: base.MaxDataServiceVersion = Versioning.Server.DataServiceVersion; break; } // Send request to server. AstoriaResponse response = GetResponse(); // Update last seen MLE or MR ETags. if (response.ETagHeaderFound) { if (base.URI.Contains("$value")) { ETagMRR = response.ETagHeader; } else { ETagMLE = response.ETagHeader; } } if ((AstoriaTestProperties.DataLayerProviderKinds.Contains(DataLayerProviderKind.NonClr)) && (AstoriaTestProperties.UseOpenTypes)) { // // This section of code is handling the DSV values returned from server changes // bool not_3_0 = response.DataServiceVersion.StartsWith("1.0"); not_3_0 = response.DataServiceVersion.StartsWith("2.0") | not_3_0; AstoriaTestLog.Compare(not_3_0, "DataServiceVersion response header was returned with " + response.DataServiceVersion); AstoriaTestLog.TraceInfo("Returned DSV was " + response.DataServiceVersion); } else { // Verify response version header. AstoriaTestLog.Compare(response.DataServiceVersion.StartsWith(responseVersion), "DataServiceVersion response header must be " + responseVersion + " but was " + response.DataServiceVersion); } // Verify content type: xml for Atom, json for JSON. if (!base.Batched && !string.IsNullOrEmpty(response.Payload)) { if (base.Format == SerializationFormatKind.Atom && !response.ContentType.Contains("xml") || (base.Format == SerializationFormatKind.JSON && !response.ContentType.Contains("json"))) { AstoriaTestLog.WriteLine(string.Format("Wrong Content-Type {0} in response to {1} request: ", response.ContentType, base.Format)); AstoriaTestLog.WriteLine("Payload:"); AstoriaTestLog.FailAndThrow(response.Payload ?? "{null}"); } } // Verify MLE (BlobsPayload) or MR response payload. if (expectedPayload is BlobsPayload) { // Compare MLE payloads. BlobsPayload actualPayload = (expectedPayload as BlobsPayload); if (actualPayload.ToString() != expectedPayload.ToString()) { AstoriaTestLog.FailAndThrow( "MLE received:" + TestLog.NewLine + actualPayload + TestLog.NewLine + "MLE expected:" + TestLog.NewLine + expectedPayload); } // Temporarily morph MLE into normal entity and call Verify(). string originalPayload = response.Payload; response.Payload = actualPayload.AdjustedForVerify(); response.Verify(); response.Payload = originalPayload; } else { // Compare MR payloads. string actualPayload = response.Payload; if (expectedPayload != null && actualPayload != expectedPayload as string) { AstoriaTestLog.FailAndThrow( "MR received:" + TestLog.NewLine + actualPayload + TestLog.NewLine + "MR expected:" + TestLog.NewLine + expectedPayload); } response.Verify(); } // Remove auxiliary headers, if any. for (int i = 0; i < headers.Length; i += 2) { base.Headers.Remove(headers[i]); } return(response); }
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); }
private static CommonPayload SnapshotEntityState(AstoriaRequest request) { if (!request.SnapshotForUpdate) { return(null); } request.SnapshotForUpdate = true; // try to figure out entity-level request Workspace workspace = request.Workspace; List <string> neededSegments = new List <string>() { workspace.ServiceUri }; string[] segments = request.URI.Replace(workspace.ServiceUri, null).Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries); string firstSegment = segments[0]; neededSegments.Add(firstSegment); if (firstSegment.Contains('(')) { firstSegment = firstSegment.Substring(0, firstSegment.IndexOf('(')); } ResourceContainer container = workspace.ServiceContainer.ResourceContainers[firstSegment]; if (container == null) { return(null); } ResourceType baseType = container.BaseType; bool etagExpected = baseType.Properties.Any(p => p.Facets.ConcurrencyModeFixed); for (int i = 1; i < segments.Length; i++) { string propertyName = segments[i]; if (propertyName.Contains('(')) { propertyName = propertyName.Substring(0, propertyName.IndexOf('(')); } ResourceProperty property = baseType.Properties[propertyName] as ResourceProperty; if (property == null || !property.IsNavigation) { break; } etagExpected = property.OtherAssociationEnd.ResourceType.Properties.Any(p => p.Facets.ConcurrencyModeFixed); neededSegments.Add(segments[i]); } AstoriaRequest get = workspace.CreateRequest(); get.Format = request.Format; get.ETagHeaderExpected = etagExpected; get.URI = string.Join("/", neededSegments.ToArray()); AstoriaResponse getResponse = get.GetResponse(); getResponse.Verify(); return(getResponse.CommonPayload); }