public static bool Applies(AstoriaResponse response) { if (response.Request.EffectiveVerb != RequestVerb.Post) return false; if (response.Request.IsBlobRequest) return false; if (string.IsNullOrEmpty(response.Request.Payload)) { // must be a service op or something return false; } if (response.Request.URI.Contains("$ref") || response.Request.URI.Contains("$batch")) { // not an insert return false; } // we don't know how to handle batched updates yet if (response.Request.Batched) return false; return true; }
internal void OnReceive(object caller, AstoriaResponse response) { if (OnReceiveEvent != null) { OnReceiveEvent(caller, new ResponseEventArgs(response)); } }
public static void DefaultVerify(AstoriaResponse response) { // special case for ETags if (response.ActualStatusCode == System.Net.HttpStatusCode.NotModified) { return; } AstoriaRequest request = response.Request; RequestVerb verb = request.EffectiveVerb; switch (verb) { case RequestVerb.Get: VerifyGet(response); break; case RequestVerb.Post: case RequestVerb.Patch: case RequestVerb.Put: case RequestVerb.Delete: // other verbs now handled by default elsewhere break; default: VerifyUnknownVerb(response); break; } }
public static void VerifyConcurrency(AstoriaResponse response) { if (response.Request.ETagHeaderExpected) { if (!response.ETagHeaderFound && !RequestUtil.ExpectEmptyHeaders(response)) { AstoriaTestLog.FailAndThrow("Missing ETag header in response"); } } else if (response.ETagHeaderFound) { if (string.IsNullOrEmpty(response.ETagHeader)) { if (Versioning.Server.BugFixed_NullETagWhenTypeHasNoConcurrency) { AstoriaTestLog.FailAndThrow("Unexpected null ETag header in response"); } else { AstoriaTestLog.WriteLine("Ignoring unexpected null ETag header in response due to known bug"); } } else { AstoriaTestLog.FailAndThrow("Unexpected ETag header in response: '" + response.ETagHeader + "'"); } } }
public void Verify(AstoriaResponse response) { foreach (IVerifier verifier in _verifierList) { verifier.Verify(response); } }
public static void Verify(APICallLogBuilder callLogBuilder, AstoriaResponse response, params ComplexType[] types) { if (!response.Request.LogAPICalls) AstoriaTestLog.FailAndThrow("Cannot verify call order when the request did not log the calls"); Verify(callLogBuilder, response, Equal, types); }
public static void GetAndVerifyStatusCode(Workspace w, string uri, HttpStatusCode expectedStatusCode, out AstoriaResponse response, WebHeaderCollection requestHeaders) { AstoriaRequest request = w.CreateRequest(); request.URI = uri; request.ExpectedStatusCode = expectedStatusCode; request.Accept = "*/*"; if (requestHeaders != null) { foreach (string header in requestHeaders.AllKeys) { request.Headers[header] = requestHeaders[header]; } } response = request.GetResponse(); try { ResponseVerification.VerifyStatusCode(response); } catch (Exception e) { ResponseVerification.LogFailure(response, e); } }
public override AstoriaResponse GetResponse() { LogRequest(); foreach (AstoriaRequest subRequest in Changesets.SelectMany(c => c).Union(this.Requests)) { subRequest.OnSend(this); } #if !ClientSKUFramework // NOTHING should come in between this and actually sending the request SetupAPICallLog(); #endif AstoriaResponse response = RequestSender.SendRequest(this); #if !ClientSKUFramework // NOTHING should come in between this and actually recieving the response RetrieveAPICallLog(); #endif BatchResponse batchResponse = new BatchResponse(this, response); foreach (AstoriaResponse subResponse in batchResponse.Responses) { subResponse.Request.OnReceive(this, subResponse); } return(batchResponse); }
public BatchResponse(BatchRequest request, AstoriaResponse response) : base(request) { if (request.ExpectedStatusCode == HttpStatusCode.Accepted) { try { ResponseVerification.VerifyStatusCode(response); } catch (Exception e) { ResponseVerification.LogFailure(response, e); } } Responses = new List<AstoriaResponse>(); this.Headers = response.Headers; this.Payload = response.Payload; this.ETagHeaderFound = response.ETagHeaderFound; this.ActualStatusCode = response.ActualStatusCode; this.Exception = response.Exception; if (request.ExpectedStatusCode == HttpStatusCode.Accepted) BatchReader.ParseBatchResponse(this); }
public BatchResponse(BatchRequest request, AstoriaResponse response) : base(request) { if (request.ExpectedStatusCode == HttpStatusCode.Accepted) { try { ResponseVerification.VerifyStatusCode(response); } catch (Exception e) { ResponseVerification.LogFailure(response, e); } } Responses = new List <AstoriaResponse>(); this.Headers = response.Headers; this.Payload = response.Payload; this.ETagHeaderFound = response.ETagHeaderFound; this.ActualStatusCode = response.ActualStatusCode; this.Exception = response.Exception; if (request.ExpectedStatusCode == HttpStatusCode.Accepted) { BatchReader.ParseBatchResponse(this); } }
/// <summary>Verifies the result when an unknown verb is sent to the server.</summary> public static void VerifyMetadata(AstoriaResponse response) { #if !ClientSKUFramework response.Workspace.VerifyMetadata(response.Payload); #endif }
public static bool Applies(AstoriaResponse response) { if (response.Request.EffectiveVerb != RequestVerb.Post) { return(false); } if (response.Request.IsBlobRequest) { return(false); } if (string.IsNullOrEmpty(response.Request.Payload)) { // must be a service op or something return(false); } if (response.Request.URI.Contains("$ref") || response.Request.URI.Contains("$batch")) { // not an insert return(false); } // we don't know how to handle batched updates yet if (response.Request.Batched) { return(false); } return(true); }
public static void VerifyResponseFormat(AstoriaResponse response) { if ((response.Request.Format == SerializationFormatKind.JSON && response.ContentType.StartsWith(SerializationFormatKinds.JsonMimeType, StringComparison.Ordinal)) || (response.Request.Format == SerializationFormatKind.Atom && response.ContentType != "application/xml")) { throw new TestFailedException(String.Format("Error content-type does not match request content-type - expected: {0}, actual: {1}", response.Request.Format.ToString(), response.ContentType)); } }
public static bool Applies(AstoriaResponse response) { if (response.Request.EffectiveVerb != RequestVerb.Delete) return false; if (response.Request is BlobsRequest) return false; return true; }
//--------------------------------------------------------------------- // Sends and verifies request for all possible access rights. //--------------------------------------------------------------------- public void TestAccess(string container) { // Save current state. HttpStatusCode normalStatusCode = ExpectedStatusCode; #if !ClientSKUFramework for (uint i = 0; i <= (uint)Microsoft.OData.Service.EntitySetRights.All; i++) { // Set entity set access right. Workspace.DataService.ConfigSettings.SetEntitySetAccessRule(container, (Microsoft.OData.Service.EntitySetRights)i); // Calculate minimum access needed for request to succeed. Microsoft.OData.Service.EntitySetRights minAccess = Microsoft.OData.Service.EntitySetRights.All; switch (Verb) { case RequestVerb.Post: minAccess = Microsoft.OData.Service.EntitySetRights.WriteAppend; break; case RequestVerb.Get: minAccess = Microsoft.OData.Service.EntitySetRights.ReadSingle; break; case RequestVerb.Put: minAccess = Microsoft.OData.Service.EntitySetRights.WriteReplace | Microsoft.OData.Service.EntitySetRights.ReadSingle; break; case RequestVerb.Patch: minAccess = Microsoft.OData.Service.EntitySetRights.WriteMerge | Microsoft.OData.Service.EntitySetRights.ReadSingle; break; case RequestVerb.Delete: minAccess = Microsoft.OData.Service.EntitySetRights.WriteDelete | Microsoft.OData.Service.EntitySetRights.ReadSingle; break; default: AstoriaTestLog.FailAndThrow("Test issue - unknown request verb (2)"); break; } // Calculate expected status code. ExpectedStatusCode = i == 0 ? HttpStatusCode.NotFound : (i & (uint)minAccess) == (uint)minAccess ? normalStatusCode : HttpStatusCode.Forbidden; // Send and verify request. AstoriaResponse response = SendAndVerify(null); // Delete the entity if it was created to avoid "key already exists" collisions. if (response.Headers.ContainsKey("Location")) { string newEntity = response.Headers["Location"]; Workspace.DataService.ConfigSettings.SetEntitySetAccessRule(container, Microsoft.OData.Service.EntitySetRights.WriteDelete | Microsoft.OData.Service.EntitySetRights.ReadSingle); BlobsRequest.MLE(Workspace, Format, RequestVerb.Delete, null, HttpStatusCode.NoContent, newEntity).SendAndVerify(null); } } #endif // Restore previous state. ExpectedStatusCode = normalStatusCode; #if !ClientSKUFramework Workspace.DataService.ConfigSettings.SetEntitySetAccessRule(container, Microsoft.OData.Service.EntitySetRights.All); #endif }
public static void Verify(APICallLogBuilder callLogBuilder, AstoriaResponse response, params ComplexType[] types) { if (!response.Request.LogAPICalls) { AstoriaTestLog.FailAndThrow("Cannot verify call order when the request did not log the calls"); } Verify(callLogBuilder, response, Equal, types); }
public static void GetAndVerifyStatusCode(Workspace w, QueryNode query, HttpStatusCode expectedStatusCode) { AstoriaRequest request = w.CreateRequest(query); request.ExpectedStatusCode = expectedStatusCode; AstoriaResponse response = request.GetResponse(); ResponseVerification.VerifyStatusCode(response); }
public static void VerifySpecificResponseVersion(AstoriaResponse response, int major, int minor) { if (response.DataServiceVersion == null) { AstoriaTestLog.FailAndThrow("Data service version should always be specified in response"); } AstoriaTestLog.IsTrue(response.DataServiceVersion.StartsWith(major + "." + minor), String.Format("Unexpected value in response's DataServiceVersion header: {0}, expected: {1}.{2}", response.DataServiceVersion, major, minor)); }
public static void VerifyError(AstoriaResponse response, ResourceIdentifier resourceIdentifier, params object[] args) { if (response.ContentType.Contains(SerializationFormatKinds.JsonMimeType)) { VerifyError(ParseResponseErrorJSON, response, resourceIdentifier, false, args); } else { VerifyError(ParseResponseErrorXML, response, resourceIdentifier, false, args); } }
public static bool ExpectEmptyHeaders(AstoriaResponse response) { // it seems that for all the 'real' verbs, XmlHttpRequest does not give headers back on 204's if (response.Request.Verb != RequestVerb.Patch && AstoriaTestProperties.Client == ClientEnum.XMLHTTP && response.ActualStatusCode == HttpStatusCode.NoContent) { return(true); } return(false); }
public static void VerifyError(AstoriaResponse response, string pattern, params object[] args) { if (response.ContentType.Contains(SerializationFormatKinds.JsonMimeType)) { VerifyError(ParseResponseErrorJSON, response, ResourceUtil.FormatResourceString(pattern, args), ComparisonFlag.Full); } else { VerifyError(ParseResponseErrorXML, response, ResourceUtil.FormatResourceString(pattern, args), ComparisonFlag.Full); } }
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."); } }
public static void VerifyStatusCode(AstoriaResponse response, System.Net.HttpStatusCode expected) { bool areEqual = expected == response.ActualStatusCode; if (!areEqual) { string errorMessage = string.Format("Expecting status code {0}, but received status code {1}", expected, response.ActualStatusCode); throw new TestFailedException(errorMessage); } }
//--------------------------------------------------------------------- public static BlobsPayload Parse(SerializationFormatKind format, AstoriaResponse response) { switch (format) { case SerializationFormatKind.Atom: return new BlobsPayload.Atom(response.Payload); case SerializationFormatKind.JSON: return new BlobsPayload.JSON(response.Payload); default: AstoriaTestLog.FailAndThrow("Unknown serialization format kind: " + format.ToString()); return null; } }
public static bool Applies(AstoriaResponse response) { if (response.Request.EffectiveVerb != RequestVerb.Delete) { return(false); } if (response.Request is BlobsRequest) { return(false); } return(true); }
//--------------------------------------------------------------------- public static BlobsPayload Parse(SerializationFormatKind format, AstoriaResponse response) { switch (format) { case SerializationFormatKind.Atom: return(new BlobsPayload.Atom(response.Payload)); case SerializationFormatKind.JSON: return(new BlobsPayload.JSON(response.Payload)); default: AstoriaTestLog.FailAndThrow("Unknown serialization format kind: " + format.ToString()); return(null); } }
public override void Verify(AstoriaResponse response) { base.Verify(response); string payload = response.Payload; XmlNode xmlData = FormatVerifyUtils.FindFirstChild(payload); if (xmlData.Name == "feed") { this.VerifyEntry(xmlData); } }
public static CommonPayload CreateCommonPayload(AstoriaRequest request, string responsePayload) { if (request == null) { throw new ArgumentNullException("request"); } AstoriaResponse response = new AstoriaResponse(request); response.Payload = responsePayload; return(CreateCommonPayload(response)); }
public void Verify(AstoriaResponse response) { //AstoriaTestLog.TraceInfo(payload); try { JSONPayload jsonPayload = new JSONPayload(response); } catch (Exception e) { AstoriaTestLog.FailAndContinue(new TestFailedException("Failed to parse JSON payload : " + e.ToString())); } //AstoriaTestLog.TraceInfo(jsonPayload.ToString()); return; }
public void SendRequest(AstoriaRequest request, out AstoriaResponse response) { // doing it this way so the compiler knows that response got initialized if (!SendRequest_Internal(request, out response)) { bool valid = false; for (int retry = 0; retry < 4; retry++) { valid = SendRequest_Internal(request, out response); if (valid) break; } if (!valid) throw new Microsoft.Test.ModuleCore.TestFailedException("Could not get a valid response despite retrying"); } }
private static AstoriaResponse FragmentToResponse(AstoriaRequest request, ResponseFragment fragment) { AstoriaResponse response = new AstoriaResponse(request); response.Payload = fragment.Payload; response.ContentType = fragment.ContentType; response.ActualStatusCode = fragment.StatusCode; response.ETagHeaderFound = false; foreach (var header in fragment.Headers) { if (header.Key == "ETag") { response.ETagHeaderFound = true; } response.Headers[header.Key] = header.Value; } return(response); }
private static string ParseResponseErrorJSON(AstoriaResponse response, bool inStream) { // error should be something like //{ // "error": { // "code": "", "message": "Error message" // } //} ServiceError serviceError = new ServiceError(); string payloadString = response.Payload; CommonPayload payload; if (inStream) { Match match = JsonInStreamErrorRegex.Match(payloadString); if (!match.Success) { AstoriaTestLog.TraceLine(payloadString); AstoriaTestLog.FailAndThrow("Payload did not contain expected in-stream error"); } response.Payload = match.Groups[1].Value; } payload = response.CommonPayload; PayloadProperty prop; PayloadComplexProperty complex = payload.Resources as PayloadComplexProperty; if (complex != null) { if (complex.PayloadProperties.TryGetValue("message", out prop)) { if (prop is PayloadComplexProperty) { if ((prop as PayloadComplexProperty).PayloadProperties.TryGetValue("value", out prop)) { serviceError.message = (prop as PayloadSimpleProperty).Value; } } } } return(serviceError.message); }
public static void Verify(APICallLogBuilder callLogBuilder, AstoriaResponse response, Func<APICallLogEntry, APICallLogEntry, bool> compare, params ComplexType[] types) { if (!AstoriaTestProperties.IsLabRun) { StringBuilder builder = new StringBuilder(); builder.AppendLine("------------------------------------"); builder.AppendLine(""); builder.AppendLine("Verifying call order"); builder.AppendLine(""); if(types.Length > 0) { builder.AppendLine("Metadata:"); WriteTypesToLog(builder, types); builder.AppendLine(""); } builder.AppendLine("Request:"); response.Request.LogRequest(builder, true, true); builder.AppendLine(""); builder.AppendLine("Response:"); response.LogResponse(builder, true, true); builder.AppendLine(""); AstoriaTestLog.WriteLineIgnore(builder.ToString()); } try { Verify(callLogBuilder.Entries, response.Request.APICallLogEntries, compare); } catch (Exception ex) { if (types.Length > 0) { StringBuilder builder = new StringBuilder(); builder.AppendLine("Metadata:"); WriteTypesToLog(builder, types); builder.AppendLine(""); AstoriaTestLog.WriteLineIgnore(builder.ToString()); } ResponseVerification.LogFailure(response, ex); } }
public static void Verify(APICallLogBuilder callLogBuilder, AstoriaResponse response, Func <APICallLogEntry, APICallLogEntry, bool> compare, params ComplexType[] types) { if (!AstoriaTestProperties.IsLabRun) { StringBuilder builder = new StringBuilder(); builder.AppendLine("------------------------------------"); builder.AppendLine(""); builder.AppendLine("Verifying call order"); builder.AppendLine(""); if (types.Length > 0) { builder.AppendLine("Metadata:"); WriteTypesToLog(builder, types); builder.AppendLine(""); } builder.AppendLine("Request:"); response.Request.LogRequest(builder, true, true); builder.AppendLine(""); builder.AppendLine("Response:"); response.LogResponse(builder, true, true); builder.AppendLine(""); AstoriaTestLog.WriteLineIgnore(builder.ToString()); } try { Verify(callLogBuilder.Entries, response.Request.APICallLogEntries, compare); } catch (Exception ex) { if (types.Length > 0) { StringBuilder builder = new StringBuilder(); builder.AppendLine("Metadata:"); WriteTypesToLog(builder, types); builder.AppendLine(""); AstoriaTestLog.WriteLineIgnore(builder.ToString()); } ResponseVerification.LogFailure(response, ex); } }
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); } }
public virtual void Verify(AstoriaResponse response) { string payload = response.Payload; XmlNode xmlData = FormatVerifyUtils.FindFirstChild(payload); if (xmlData.Name == "feed") { XmlNodeList entries = xmlData.SelectNodes("atom:entry", _formatVerifier.XmlNamespaceManager); foreach (XmlNode node in entries) { VerifyEntry(node); } } else if (xmlData.Name == "entry") { VerifyEntry(xmlData); } }
public static bool Applies(AstoriaResponse response) { if (response.Request.EffectiveVerb != RequestVerb.Patch && response.Request.EffectiveVerb != RequestVerb.Put) { return(false); } if (response.ActualStatusCode != HttpStatusCode.NoContent) { return(false); } if (response.Request.IsBlobRequest) { return(false); } if (response.Request.URI.Contains("$ref")) { return(false); } return(true); }
public void SendRequest(AstoriaRequest request, out AstoriaResponse response) { // doing it this way so the compiler knows that response got initialized if (!SendRequest_Internal(request, out response)) { bool valid = false; for (int retry = 0; retry < 4; retry++) { valid = SendRequest_Internal(request, out response); if (valid) { break; } } if (!valid) { throw new Microsoft.Test.ModuleCore.TestFailedException("Could not get a valid response despite retrying"); } } }
// order: most to least specific public static void VerifyError(AstoriaResponse response) { // general error verification, called directly by response.Verify() if (!InStreamErrorExpected(response)) { // Error responses should ALWAYS be 1.0 for top-level errors VerifySpecificResponseVersion(response, 1, 0); } if (response.Request.ExpectedErrorIdentifier != null) { VerifyError(response, response.Request.ExpectedErrorIdentifier, response.Request.ExpectedErrorArguments); } // leaving this off until we're ready to fix it everywhere //else // AstoriaTestLog.Warning(false, "Error condition with ExpectedErrorIdentifier unset"); if (response.Exception != null) { AstoriaTestLog.HandleException(response.Exception); } }
public static void VerifyError(Func<AstoriaResponse, string> responseParser, AstoriaResponse response, ResourceIdentifier resourceIdentifier, bool localResource, params object[] args) { VerifyError((payload, inStream) => responseParser(payload), response, resourceIdentifier, localResource, args); }
private static string ParseResponseErrorXML(AstoriaResponse response, bool inStream) { string payloadString = response.Payload; ServiceError serviceError = new ServiceError(); XmlNode error = null; if (inStream) { Match match = XmlInStreamErrorRegex.Match(payloadString); if (!match.Success) { AstoriaTestLog.TraceLine(payloadString); AstoriaTestLog.FailAndThrow("Payload did not contain expected in-stream error"); } payloadString = match.Groups[1].Value; // if there was a namespace prefix, we need to inject a wrapping element with the namespace defined // if (!string.IsNullOrEmpty(match.Groups[2].Value)) { payloadString = "<wrapper xmlns:" + match.Groups[2].Value + "=\"" + AtomUpdatePayloadBuilder.DataWebMetadataXmlNamespace + "\">" + payloadString + "</wrapper>"; } else { // just for consistency later when we pull out the <error> tag // payloadString = "<wrapper>" + payloadString + "</wrapper>"; } XmlDocument xmlDoc = new XmlDocument(); try { xmlDoc.LoadXml(payloadString); } catch (XmlException ex) { AstoriaTestLog.FailAndContinue(ex); return null; } // pull out the <error> tag, assuming that there is a <wrapper> tag around it // error = xmlDoc.FirstChild.FirstChild; } else { XmlDocument xmlDoc = new XmlDocument(); try { xmlDoc.LoadXml(payloadString); } catch (XmlException ex) { AstoriaTestLog.FailAndContinue(ex); return null; } error = xmlDoc.FirstChild.NextSibling; } if (error != null) { XmlNode code = error.FirstChild; XmlNode message = code.NextSibling; XmlNode innerError = message.NextSibling; serviceError.code = code.InnerXml; serviceError.message = message.InnerXml; if (message.Attributes["xml:lang"] != null) serviceError.language = message.Attributes["xml:lang"].Value; else serviceError.language = null; if (innerError != null) { XmlNode innerMessage = null; XmlNode innerType = null; XmlNode innerStackTrace = null; innerMessage = innerError.FirstChild; if (innerMessage != null) { serviceError.InnerServiceError.message = innerMessage.InnerXml; innerType = innerMessage.NextSibling; if (innerType != null) { serviceError.InnerServiceError.type = innerType.InnerXml; innerStackTrace = innerType.NextSibling; if (innerStackTrace != null) { serviceError.InnerServiceError.stacktrace = innerStackTrace.InnerXml; } } } } } return serviceError.message; }
private static string ParseResponseErrorJSON(AstoriaResponse response, bool inStream) { // error should be something like //{ // "error": { // "code": "", "message": "Error message" // } //} ServiceError serviceError = new ServiceError(); string payloadString = response.Payload; CommonPayload payload; if (inStream) { Match match = JsonInStreamErrorRegex.Match(payloadString); if (!match.Success) { AstoriaTestLog.TraceLine(payloadString); AstoriaTestLog.FailAndThrow("Payload did not contain expected in-stream error"); } response.Payload = match.Groups[1].Value; } payload = response.CommonPayload; PayloadProperty prop; PayloadComplexProperty complex = payload.Resources as PayloadComplexProperty; if (complex != null) { if (complex.PayloadProperties.TryGetValue("message", out prop)) { if (prop is PayloadComplexProperty) { if ((prop as PayloadComplexProperty).PayloadProperties.TryGetValue("value", out prop)) { serviceError.message = (prop as PayloadSimpleProperty).Value; } } } } return serviceError.message; }
public virtual void Verify(AstoriaResponse response) { string payload = response.Payload; XmlNode xmlData = FormatVerifyUtils.FindFirstChild(payload); if (xmlData.Name == "feed") { XmlNodeList entries = xmlData.SelectNodes("atom:entry", _formatVerifier.XmlNamespaceManager); foreach (XmlNode node in entries) VerifyEntry(node); } else if (xmlData.Name == "entry") VerifyEntry(xmlData); }
private static void VerifyError(Func<AstoriaResponse, bool, string> responseParser, AstoriaResponse response, string expectedErrorString, ComparisonFlag comparison) { bool inStream = InStreamErrorExpected(response); // actual error returned string actualErrorString = responseParser(response, inStream); // expected error string (from service op in service) AstoriaTestLog.TraceInfo("Actual Error String --> " + actualErrorString); AstoriaTestLog.TraceInfo("Expected Error String --> " + expectedErrorString); ResourceUtil.VerifyMessage(actualErrorString, expectedErrorString, comparison); }
protected override sealed bool SendRequest_Internal(AstoriaRequest request, out AstoriaResponse response) { HttpWebRequest underlyingRequest = (HttpWebRequest)HttpWebRequest.Create(request.URI); WebResponse underlyingResponse; #region set up request // workaround: Protocol Violation in HttpWebRequest when receiving an immediate error response from server before sending request body // ideally, we would only flip this to false if we knew the request would have an error, // but we can't reliably tell at this point if (AstoriaTestProperties.Host == Host.IDSH || AstoriaTestProperties.Host == Host.IDSH2) { if (Environment.OSVersion.Version.Major < 6 || Environment.OSVersion.Version.Minor < 1) underlyingRequest.ServicePoint.Expect100Continue = false; } underlyingRequest.UseDefaultCredentials = AstoriaTestProperties.HostAuthenicationMethod.Equals("Windows", StringComparison.InvariantCultureIgnoreCase); underlyingRequest.Method = request.Verb.ToHttpMethod(); underlyingRequest.Accept = request.Accept; underlyingRequest.ContentType = request.ContentType; foreach (KeyValuePair<string, string> header in request.Headers) { switch (header.Key) { case "Accept": case "Content-Type": break; default: underlyingRequest.Headers.Add(header.Key, header.Value); break; } } underlyingRequest.ContentLength = 0; byte[] bytes = request.PayloadBytes; if (bytes != null) { underlyingRequest.ContentLength = bytes.Length; try { using (Stream os = underlyingRequest.GetRequestStream()) { os.Write(bytes, 0, bytes.Length); } } catch (WebException ex) { HandleWebException(ex, out underlyingResponse); response = null; return false; } } else if (request.HttpStreamWriter != null) { // Call external stream writer. try { // Set ContentLength header. underlyingRequest.ContentLength = request.HttpStreamWriter(null); // Stream payload. using (Stream requestStream = underlyingRequest.GetRequestStream()) { request.HttpStreamWriter(requestStream); } } catch (WebException ex) { HandleWebException(ex, out underlyingResponse); response = null; return false; } } #endregion try { underlyingResponse = underlyingRequest.GetResponse(); } catch (WebException webException) { if (HandleWebException(webException, out underlyingResponse)) { if (underlyingResponse == null) { response = null; return false; } } else throw webException; } // This should not be possible if (underlyingResponse == null) AstoriaTestLog.FailAndThrow("Somehow got a null underlying response"); HttpWebResponse httpResponse = underlyingResponse as HttpWebResponse; response = new AstoriaResponse(request); #region populate response response.ContentType = underlyingResponse.ContentType; // hook everything up if (httpResponse != null) response.ActualStatusCode = httpResponse.StatusCode; else response.ActualStatusCode = HttpStatusCode.Ambiguous; // have to be careful and only mark ETag as found if it was actually sent // regardless of whether the value was null response.ETagHeaderFound = false; foreach (string header in underlyingResponse.Headers.AllKeys) { if (header == "ETag") response.ETagHeaderFound = true; if (underlyingResponse is HttpWebResponse) response.Headers[header] = (underlyingResponse as HttpWebResponse).GetResponseHeader(header); else response.Headers[header] = string.Join(", ", underlyingResponse.Headers.GetValues(header)); } // For Streamed/StreamedResponse, Transfer-Encoding is chunked and ContentLength could be -1 if ((underlyingResponse.Headers[HttpResponseHeader.TransferEncoding] == "chunked" || underlyingResponse.ContentLength > 0)) { Encoding encoding = Encoding.UTF8; using (Stream responseStream = underlyingResponse.GetResponseStream()) { if (request.HttpStreamReader != null) { // Call external stream reader. response.Payload = request.HttpStreamReader(responseStream); } else { if (underlyingResponse.ContentLength > 0 && response.ContentType == SerializationFormatKinds.MimeApplicationOctetStream) { using (System.IO.BinaryReader reader = new System.IO.BinaryReader(responseStream)) response.Bytes = reader.ReadBytes((int)underlyingResponse.ContentLength); } else { using (System.IO.TextReader reader = new System.IO.StreamReader(responseStream, encoding)) response.Payload = reader.ReadToEnd(); } } } } else { // only make an assignment to response.Payload if we're sure there was no content // if we set this prematurely, it can mess up the internal state of the response response.Payload = string.Empty; } #endregion return true; }
// order: most to least specific public static void VerifyError(AstoriaResponse response) { // general error verification, called directly by response.Verify() if (!InStreamErrorExpected(response)) { // Error responses should ALWAYS be 1.0 for top-level errors VerifySpecificResponseVersion(response, 1, 0); } if (response.Request.ExpectedErrorIdentifier != null) VerifyError(response, response.Request.ExpectedErrorIdentifier, response.Request.ExpectedErrorArguments); // leaving this off until we're ready to fix it everywhere //else // AstoriaTestLog.Warning(false, "Error condition with ExpectedErrorIdentifier unset"); if (response.Exception != null) AstoriaTestLog.HandleException(response.Exception); }
public static void GetAndVerifyStatusCode(Workspace w, string uri, HttpStatusCode expectedStatusCode, out AstoriaResponse response) { GetAndVerifyStatusCode(w, uri, expectedStatusCode, out response, null); }
public void Verify(AstoriaResponse response) { foreach (IVerifier verifier in _verifierList) { verifier.Verify(response); } }
public static void LogFailure(AstoriaResponse response, Exception ex) { LogFailure(response, ex, true); }
public static void VerifyError(AstoriaResponse response, ResourceIdentifier resourceIdentifier, params object[] args) { if (response.ContentType.Contains(SerializationFormatKinds.JsonMimeType)) VerifyError(ParseResponseErrorJSON, response, resourceIdentifier, false, args); else VerifyError(ParseResponseErrorXML, response, resourceIdentifier, false, args); }
public static void VerifyResponseFormat(AstoriaResponse response) { if ((response.Request.Format == SerializationFormatKind.JSON && response.ContentType.StartsWith(SerializationFormatKinds.JsonMimeType, StringComparison.Ordinal)) || (response.Request.Format == SerializationFormatKind.Atom && response.ContentType != "application/xml")) throw new TestFailedException(String.Format("Error content-type does not match request content-type - expected: {0}, actual: {1}", response.Request.Format.ToString(), response.ContentType)); }
public static bool ExpectEmptyHeaders(AstoriaResponse response) { // it seems that for all the 'real' verbs, XmlHttpRequest does not give headers back on 204's if (response.Request.Verb != RequestVerb.Patch && AstoriaTestProperties.Client == ClientEnum.XMLHTTP && response.ActualStatusCode == HttpStatusCode.NoContent) return true; return false; }
public static void VerifyConcurrency(AstoriaResponse response) { if (response.Request.ETagHeaderExpected) { if (!response.ETagHeaderFound && !RequestUtil.ExpectEmptyHeaders(response)) AstoriaTestLog.FailAndThrow("Missing ETag header in response"); } else if (response.ETagHeaderFound) { if (string.IsNullOrEmpty(response.ETagHeader)) { if (Versioning.Server.BugFixed_NullETagWhenTypeHasNoConcurrency) AstoriaTestLog.FailAndThrow("Unexpected null ETag header in response"); else AstoriaTestLog.WriteLine("Ignoring unexpected null ETag header in response due to known bug"); } else AstoriaTestLog.FailAndThrow("Unexpected ETag header in response: '" + response.ETagHeader + "'"); } }
public static bool InStreamErrorExpected(AstoriaResponse response) { // for now, in stream errors are expected for status codes < 400 and not PreconditionFailed // return (int)response.ActualStatusCode < 400 && response.ActualStatusCode != System.Net.HttpStatusCode.PreconditionFailed; }
private static void VerifyError(Func<AstoriaResponse, bool, string> responseParser, AstoriaResponse response, ResourceIdentifier resourceIdentifier, bool localResource, params object[] args) { string resourceText = GetLocalizedResourceString(response.Workspace, resourceIdentifier, localResource, args); VerifyError(responseParser, response, resourceText, resourceIdentifier.ComparisonFlag); }
public static void VerifyError(AstoriaResponse response, string pattern, params object[] args) { if (response.ContentType.Contains(SerializationFormatKinds.JsonMimeType)) VerifyError(ParseResponseErrorJSON, response, ResourceUtil.FormatResourceString(pattern, args), ComparisonFlag.Full); else VerifyError(ParseResponseErrorXML, response, ResourceUtil.FormatResourceString(pattern, args), ComparisonFlag.Full); }
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 void Verify(AstoriaResponse response) { //AstoriaTestLog.TraceInfo(payload); try { JSONPayload jsonPayload = new JSONPayload(response); } catch (Exception e) { AstoriaTestLog.FailAndContinue(new TestFailedException("Failed to parse JSON payload : " + e.ToString())); } //AstoriaTestLog.TraceInfo(jsonPayload.ToString()); return; }
public override void Verify(AstoriaResponse response) { base.Verify(response); string payload = response.Payload; XmlNode xmlData = FormatVerifyUtils.FindFirstChild(payload); if (xmlData.Name == "feed") this.VerifyEntry(xmlData); }
public static void LogFailure(AstoriaResponse response, Exception ex, bool shouldThrow) { StringBuilder builder = new StringBuilder(); builder.AppendLine("Response verification failed"); builder.AppendLine("----------------------------------------"); response.Request.LogRequest(builder, true, true); builder.AppendLine("----------------------------------------"); response.LogResponse(builder, true, true); builder.AppendLine("----------------------------------------"); string log = builder.ToString(); ex = new TestFailedException(log, null, null, ex); if (shouldThrow) throw ex; else AstoriaTestLog.FailAndContinue(ex); }