You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

100 lines
2.5 KiB

  1. // Copyright 2015 Google Inc. All rights reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package status
  15. import (
  16. "encoding/json"
  17. "fmt"
  18. "net/http"
  19. "github.com/google/martian"
  20. "github.com/google/martian/parse"
  21. "github.com/google/martian/verify"
  22. )
  23. const errFormat = "response(%s) status code verify failure: got %d, want %d"
  24. // Verifier verifies the status codes of all responses.
  25. type Verifier struct {
  26. statusCode int
  27. err *martian.MultiError
  28. }
  29. type verifierJSON struct {
  30. StatusCode int `json:"statusCode"`
  31. Scope []parse.ModifierType `json:"scope"`
  32. }
  33. func init() {
  34. parse.Register("status.Verifier", verifierFromJSON)
  35. }
  36. // NewVerifier returns a new status.Verifier for statusCode.
  37. func NewVerifier(statusCode int) verify.ResponseVerifier {
  38. return &Verifier{
  39. statusCode: statusCode,
  40. err: martian.NewMultiError(),
  41. }
  42. }
  43. // ModifyResponse verifies that the status code for all requests
  44. // matches statusCode.
  45. func (v *Verifier) ModifyResponse(res *http.Response) error {
  46. ctx := martian.NewContext(res.Request)
  47. if ctx.IsAPIRequest() {
  48. return nil
  49. }
  50. if res.StatusCode != v.statusCode {
  51. v.err.Add(fmt.Errorf(errFormat, res.Request.URL, res.StatusCode, v.statusCode))
  52. }
  53. return nil
  54. }
  55. // VerifyResponses returns an error if verification for any
  56. // request failed.
  57. // If an error is returned it will be of type *martian.MultiError.
  58. func (v *Verifier) VerifyResponses() error {
  59. if v.err.Empty() {
  60. return nil
  61. }
  62. return v.err
  63. }
  64. // ResetResponseVerifications clears all failed response verifications.
  65. func (v *Verifier) ResetResponseVerifications() {
  66. v.err = martian.NewMultiError()
  67. }
  68. // verifierFromJSON builds a status.Verifier from JSON.
  69. //
  70. // Example JSON:
  71. // {
  72. // "status.Verifier": {
  73. // "scope": ["response"],
  74. // "statusCode": 401
  75. // }
  76. // }
  77. func verifierFromJSON(b []byte) (*parse.Result, error) {
  78. msg := &verifierJSON{}
  79. if err := json.Unmarshal(b, msg); err != nil {
  80. return nil, err
  81. }
  82. return parse.NewResult(NewVerifier(msg.StatusCode), msg.Scope)
  83. }