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.
 
 
 

314 lines
7.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 header
  15. import (
  16. "net/http"
  17. "testing"
  18. "github.com/google/martian/filter"
  19. "github.com/google/martian/martiantest"
  20. "github.com/google/martian/parse"
  21. "github.com/google/martian/proxyutil"
  22. )
  23. func TestFilterFromJSON(t *testing.T) {
  24. msg := []byte(`{
  25. "header.Filter": {
  26. "scope": ["request", "response"],
  27. "name": "Martian-Passthrough",
  28. "value": "true",
  29. "modifier": {
  30. "header.Modifier" : {
  31. "scope": ["request", "response"],
  32. "name": "Martian-Testing",
  33. "value": "true"
  34. }
  35. },
  36. "else": {
  37. "header.Modifier" : {
  38. "scope": ["request", "response"],
  39. "name": "Martian-Testing",
  40. "value": "false"
  41. }
  42. }
  43. }
  44. }`)
  45. r, err := parse.FromJSON(msg)
  46. if err != nil {
  47. t.Fatalf("parse.FromJSON(): got %v, want no error", err)
  48. }
  49. reqmod := r.RequestModifier()
  50. if reqmod == nil {
  51. t.Fatal("reqmod: got nil, want not nil")
  52. }
  53. // Matching condition for request
  54. req, err := http.NewRequest("GET", "http://example.com", nil)
  55. if err != nil {
  56. t.Fatalf("http.NewRequest(): got %v, want no error", err)
  57. }
  58. req.Header.Set("Martian-Passthrough", "true")
  59. if err := reqmod.ModifyRequest(req); err != nil {
  60. t.Fatalf("ModifyRequest(): got %v, want no error", err)
  61. }
  62. if got, want := req.Header.Get("Martian-Testing"), "true"; got != want {
  63. t.Fatalf("req.Header.Get(%q): got %q, want %q", "Martian-Testing", got, want)
  64. }
  65. // Else condition for request
  66. req, err = http.NewRequest("GET", "http://example.com", nil)
  67. if err != nil {
  68. t.Fatalf("http.NewRequest(): got %v, want no error", err)
  69. }
  70. req.Header.Set("Martian-Passthrough", "false")
  71. if err := reqmod.ModifyRequest(req); err != nil {
  72. t.Fatalf("ModifyRequest(): got %v, want no error", err)
  73. }
  74. if got, want := req.Header.Get("Martian-Testing"), "false"; got != want {
  75. t.Fatalf("req.Header.Get(%q): got %q, want %q", "Martian-Testing", got, want)
  76. }
  77. // Matching condition for response
  78. resmod := r.ResponseModifier()
  79. if resmod == nil {
  80. t.Fatal("resmod: got nil, want not nil")
  81. }
  82. res := proxyutil.NewResponse(200, nil, req)
  83. res.Header.Set("Martian-Passthrough", "true")
  84. if err := resmod.ModifyResponse(res); err != nil {
  85. t.Fatalf("ModifyResponse(): got %v, want no error", err)
  86. }
  87. if got, want := res.Header.Get("Martian-Testing"), "true"; got != want {
  88. t.Fatalf("res.Header.Get(%q): got %q, want %q", "Martian-Testing", got, want)
  89. }
  90. // Else condition for response
  91. resmod = r.ResponseModifier()
  92. if resmod == nil {
  93. t.Fatal("resmod: got nil, want not nil")
  94. }
  95. res = proxyutil.NewResponse(200, nil, req)
  96. res.Header.Set("Martian-Passthrough", "false")
  97. if err := resmod.ModifyResponse(res); err != nil {
  98. t.Fatalf("ModifyResponse(): got %v, want no error", err)
  99. }
  100. if got, want := res.Header.Get("Martian-Testing"), "false"; got != want {
  101. t.Fatalf("res.Header.Get(%q): got %q, want %q", "Martian-Testing", got, want)
  102. }
  103. }
  104. func TestFilterFromJSONWithoutElse(t *testing.T) {
  105. msg := []byte(`{
  106. "header.Filter": {
  107. "scope": ["request", "response"],
  108. "name": "Martian-Passthrough",
  109. "value": "true",
  110. "modifier": {
  111. "header.Modifier" : {
  112. "scope": ["request", "response"],
  113. "name": "Martian-Testing",
  114. "value": "true"
  115. }
  116. }
  117. }
  118. }`)
  119. _, err := parse.FromJSON(msg)
  120. if err != nil {
  121. t.Fatalf("parse.FromJSON(): got %v, want no error", err)
  122. }
  123. }
  124. func TestRequestWhenTrueCondition(t *testing.T) {
  125. hm := NewMatcher("Martian-Testing", "true")
  126. tt := []struct {
  127. name string
  128. values []string
  129. want bool
  130. }{
  131. {
  132. name: "Martian-Production",
  133. values: []string{"true"},
  134. want: false,
  135. },
  136. {
  137. name: "Martian-Testing",
  138. values: []string{"see-next-value", "true"},
  139. want: true,
  140. },
  141. }
  142. for i, tc := range tt {
  143. tm := martiantest.NewModifier()
  144. f := filter.New()
  145. f.SetRequestCondition(hm)
  146. f.RequestWhenTrue(tm)
  147. req, err := http.NewRequest("GET", "/", nil)
  148. if err != nil {
  149. t.Fatalf("http.NewRequest(): got %v, want no error", err)
  150. }
  151. req.Header[tc.name] = tc.values
  152. if err := f.ModifyRequest(req); err != nil {
  153. t.Fatalf("%d. ModifyRequest(): got %v, want no error", i, err)
  154. }
  155. if tm.RequestModified() != tc.want {
  156. t.Errorf("%d. tm.RequestModified(): got %t, want %t", i, tm.RequestModified(), tc.want)
  157. }
  158. }
  159. }
  160. func TestRequestWhenFalse(t *testing.T) {
  161. hm := NewMatcher("Martian-Testing", "true")
  162. tt := []struct {
  163. name string
  164. values []string
  165. want bool
  166. }{
  167. {
  168. name: "Martian-Production",
  169. values: []string{"true"},
  170. want: true,
  171. },
  172. {
  173. name: "Martian-Testing",
  174. values: []string{"see-next-value", "true"},
  175. want: false,
  176. },
  177. }
  178. for i, tc := range tt {
  179. tm := martiantest.NewModifier()
  180. f := filter.New()
  181. f.SetRequestCondition(hm)
  182. f.RequestWhenFalse(tm)
  183. req, err := http.NewRequest("GET", "/", nil)
  184. if err != nil {
  185. t.Fatalf("http.NewRequest(): got %v, want no error", err)
  186. }
  187. req.Header[tc.name] = tc.values
  188. if err := f.ModifyRequest(req); err != nil {
  189. t.Fatalf("%d. ModifyRequest(): got %v, want no error", i, err)
  190. }
  191. if tm.RequestModified() != tc.want {
  192. t.Errorf("%d. tm.RequestModified(): got %t, want %t", i, tm.RequestModified(), tc.want)
  193. }
  194. }
  195. }
  196. func TestResponseWhenTrue(t *testing.T) {
  197. hm := NewMatcher("Martian-Testing", "true")
  198. tt := []struct {
  199. name string
  200. values []string
  201. want bool
  202. }{
  203. {
  204. name: "Martian-Production",
  205. values: []string{"true"},
  206. want: false,
  207. },
  208. {
  209. name: "Martian-Testing",
  210. values: []string{"see-next-value", "true"},
  211. want: true,
  212. },
  213. }
  214. for i, tc := range tt {
  215. tm := martiantest.NewModifier()
  216. f := filter.New()
  217. f.SetResponseCondition(hm)
  218. f.ResponseWhenTrue(tm)
  219. req, err := http.NewRequest("GET", "/", nil)
  220. if err != nil {
  221. t.Fatalf("http.NewRequest(): got %v, want no error", err)
  222. }
  223. res := proxyutil.NewResponse(200, nil, req)
  224. res.Header[tc.name] = tc.values
  225. if err := f.ModifyResponse(res); err != nil {
  226. t.Fatalf("%d. ModifyResponse(): got %v, want no error", i, err)
  227. }
  228. if tm.ResponseModified() != tc.want {
  229. t.Errorf("%d. tm.ResponseModified(): got %t, want %t", i, tm.RequestModified(), tc.want)
  230. }
  231. }
  232. }
  233. func TestResponseWhenFalse(t *testing.T) {
  234. hm := NewMatcher("Martian-Testing", "true")
  235. tt := []struct {
  236. name string
  237. values []string
  238. want bool
  239. }{
  240. {
  241. name: "Martian-Production",
  242. values: []string{"true"},
  243. want: true,
  244. },
  245. {
  246. name: "Martian-Testing",
  247. values: []string{"see-next-value", "true"},
  248. want: false,
  249. },
  250. }
  251. for i, tc := range tt {
  252. tm := martiantest.NewModifier()
  253. f := filter.New()
  254. f.SetResponseCondition(hm)
  255. f.ResponseWhenFalse(tm)
  256. req, err := http.NewRequest("GET", "/", nil)
  257. if err != nil {
  258. t.Fatalf("http.NewRequest(): got %v, want no error", err)
  259. }
  260. res := proxyutil.NewResponse(200, nil, req)
  261. res.Header[tc.name] = tc.values
  262. if err := f.ModifyResponse(res); err != nil {
  263. t.Fatalf("%d. ModifyResponse(): got %v, want no error", i, err)
  264. }
  265. if tm.ResponseModified() != tc.want {
  266. t.Errorf("%d. tm.ResponseModified(): got %t, want %t", i, tm.RequestModified(), tc.want)
  267. }
  268. }
  269. }