github.com/billybanfield/evergreen@v0.0.0-20170525200750-eeee692790f7/service/api_middleware_test.go (about) 1 package service 2 3 import ( 4 "io/ioutil" 5 "net/http" 6 "net/http/httptest" 7 "testing" 8 "time" 9 10 "github.com/evergreen-ci/evergreen" 11 "github.com/evergreen-ci/evergreen/db" 12 "github.com/evergreen-ci/evergreen/model/host" 13 "github.com/evergreen-ci/evergreen/model/task" 14 "github.com/evergreen-ci/evergreen/testutil" 15 "github.com/gorilla/context" 16 "github.com/gorilla/mux" 17 . "github.com/smartystreets/goconvey/convey" 18 "github.com/smartystreets/goconvey/convey/reporting" 19 ) 20 21 func init() { 22 reporting.QuietMode() 23 } 24 25 func TestCheckHostWrapper(t *testing.T) { 26 h1 := host.Host{ 27 Id: "h1", 28 Secret: "swordfish", 29 RunningTask: "t1", 30 } 31 t1 := task.Task{ 32 Id: "t1", 33 Secret: "password", 34 HostId: "h1", 35 } 36 37 Convey("With a simple checkTask and checkHost-wrapped route", t, func() { 38 if err := db.ClearCollections(host.Collection, task.Collection); err != nil { 39 t.Fatalf("clearing db: %v", err) 40 } 41 var ctx map[interface{}]interface{} 42 as, err := NewAPIServer(testutil.TestConfig(), nil) 43 if err != nil { 44 t.Fatalf("creating test API server: %v", err) 45 } 46 root := mux.NewRouter() 47 root.HandleFunc("/{taskId}/", as.checkTask(true, as.checkHost( 48 http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 49 ctx = context.GetAll(r) 50 as.WriteJSON(w, http.StatusOK, nil) 51 }), 52 ))) 53 54 Convey("and documents representing a proper host-task relationship", func() { 55 So(t1.Insert(), ShouldBeNil) 56 So(h1.Insert(), ShouldBeNil) 57 58 w := httptest.NewRecorder() 59 r, err := http.NewRequest("GET", "/t1/", nil) 60 if err != nil { 61 t.Fatalf("building request: %v", err) 62 } 63 64 Convey("a request without proper task fields should fail", func() { 65 root.ServeHTTP(w, r) 66 So(w.Code, ShouldEqual, http.StatusConflict) 67 68 Convey("and attach nothing to the context", func() { 69 So(ctx[apiTaskKey], ShouldBeNil) 70 So(ctx[apiHostKey], ShouldBeNil) 71 }) 72 }) 73 Convey("a request with proper task fields but no host fields should not pass", func() { 74 r.Header.Add(evergreen.TaskSecretHeader, t1.Secret) 75 root.ServeHTTP(w, r) 76 So(w.Code, ShouldEqual, http.StatusBadRequest) 77 78 Convey("and attach nothing to the context", func() { 79 So(ctx[apiTaskKey], ShouldBeNil) 80 So(ctx[apiHostKey], ShouldBeNil) 81 }) 82 }) 83 Convey("a request with proper task fields and host fields should pass", func() { 84 r.Header.Add(evergreen.TaskSecretHeader, t1.Secret) 85 r.Header.Add(evergreen.HostHeader, h1.Id) 86 r.Header.Add(evergreen.HostSecretHeader, h1.Secret) 87 root.ServeHTTP(w, r) 88 So(w.Code, ShouldEqual, http.StatusOK) 89 90 Convey("and attach the and host to the context", func() { 91 So(ctx[apiTaskKey], ShouldNotBeNil) 92 So(ctx[apiHostKey], ShouldNotBeNil) 93 asHost, ok := ctx[apiHostKey].(*host.Host) 94 So(ok, ShouldBeTrue) 95 So(asHost.Id, ShouldEqual, h1.Id) 96 Convey("with an updated LastCommunicationTime", func() { 97 So(asHost.LastCommunicationTime, ShouldHappenWithin, time.Second, time.Now()) 98 }) 99 }) 100 }) 101 Convey("a request with the wrong host secret should fail", func() { 102 r.Header.Add(evergreen.TaskSecretHeader, t1.Secret) 103 r.Header.Add(evergreen.HostHeader, h1.Id) 104 r.Header.Add(evergreen.HostSecretHeader, "bad thing!!!") 105 root.ServeHTTP(w, r) 106 So(w.Code, ShouldEqual, http.StatusConflict) 107 msg, _ := ioutil.ReadAll(w.Body) 108 So(string(msg), ShouldContainSubstring, "secret") 109 110 Convey("and attach nothing to the context", func() { 111 So(ctx[apiTaskKey], ShouldBeNil) 112 So(ctx[apiHostKey], ShouldBeNil) 113 }) 114 }) 115 }) 116 Convey("and documents representing a mismatched host-task relationship", func() { 117 h2 := host.Host{ 118 Id: "h2", 119 Secret: "swordfish", 120 RunningTask: "t29", 121 } 122 t2 := task.Task{ 123 Id: "t2", 124 Secret: "password", 125 HostId: "h50", 126 } 127 So(t2.Insert(), ShouldBeNil) 128 So(h2.Insert(), ShouldBeNil) 129 130 w := httptest.NewRecorder() 131 r, err := http.NewRequest("GET", "/t2/", nil) 132 if err != nil { 133 t.Fatalf("building request: %v", err) 134 } 135 136 Convey("a request with proper task fields and host fields should fail", func() { 137 r.Header.Add(evergreen.TaskSecretHeader, t2.Secret) 138 r.Header.Add(evergreen.HostHeader, h2.Id) 139 r.Header.Add(evergreen.HostSecretHeader, h2.Secret) 140 root.ServeHTTP(w, r) 141 So(w.Code, ShouldEqual, http.StatusConflict) 142 msg, _ := ioutil.ReadAll(w.Body) 143 So(string(msg), ShouldContainSubstring, "should be running") 144 145 Convey("and attach the and host to the context", func() { 146 So(ctx[apiTaskKey], ShouldBeNil) 147 So(ctx[apiHostKey], ShouldBeNil) 148 }) 149 }) 150 }) 151 }) 152 Convey("With a checkTask and checkHost-wrapped route using URL params", t, func() { 153 if err := db.ClearCollections(host.Collection, task.Collection); err != nil { 154 t.Fatalf("clearing db: %v", err) 155 } 156 var ctx map[interface{}]interface{} 157 as, err := NewAPIServer(testutil.TestConfig(), nil) 158 if err != nil { 159 t.Fatalf("creating test API server: %v", err) 160 } 161 root := mux.NewRouter() 162 root.HandleFunc("/{taskId}/{hostId}", as.checkTask(true, as.checkHost( 163 http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 164 ctx = context.GetAll(r) 165 as.WriteJSON(w, http.StatusOK, nil) 166 }), 167 ))) 168 169 Convey("and documents representing a proper host-task relationship", func() { 170 171 So(t1.Insert(), ShouldBeNil) 172 So(h1.Insert(), ShouldBeNil) 173 174 w := httptest.NewRecorder() 175 r, err := http.NewRequest("GET", "/t1/h1", nil) 176 if err != nil { 177 t.Fatalf("building request: %v", err) 178 } 179 180 Convey("a request with proper host params and fields should pass", func() { 181 r.Header.Add(evergreen.TaskSecretHeader, t1.Secret) 182 r.Header.Add(evergreen.HostSecretHeader, h1.Secret) 183 root.ServeHTTP(w, r) 184 So(w.Code, ShouldEqual, http.StatusOK) 185 186 Convey("and attach the and host to the context", func() { 187 So(ctx[apiTaskKey], ShouldNotBeNil) 188 So(ctx[apiHostKey], ShouldNotBeNil) 189 asHost, ok := ctx[apiHostKey].(*host.Host) 190 So(ok, ShouldBeTrue) 191 So(asHost.Id, ShouldEqual, h1.Id) 192 Convey("with an updated LastCommunicationTime", func() { 193 So(asHost.LastCommunicationTime, ShouldHappenWithin, time.Second, time.Now()) 194 }) 195 }) 196 }) 197 Convey("a request with the wrong host secret should fail", func() { 198 r.Header.Add(evergreen.TaskSecretHeader, t1.Secret) 199 r.Header.Add(evergreen.HostSecretHeader, "bad thing!!!") 200 root.ServeHTTP(w, r) 201 So(w.Code, ShouldEqual, http.StatusConflict) 202 msg, _ := ioutil.ReadAll(w.Body) 203 So(string(msg), ShouldContainSubstring, "secret") 204 205 Convey("and attach nothing to the context", func() { 206 So(ctx[apiTaskKey], ShouldBeNil) 207 So(ctx[apiHostKey], ShouldBeNil) 208 }) 209 }) 210 }) 211 }) 212 }