github.com/justinjmoses/evergreen@v0.0.0-20170530173719-1d50e381ff0d/service/rest_build_test.go (about) 1 package service 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "math/rand" 7 "net/http" 8 "net/http/httptest" 9 "path/filepath" 10 "testing" 11 "time" 12 13 "github.com/evergreen-ci/evergreen" 14 "github.com/evergreen-ci/evergreen/auth" 15 "github.com/evergreen-ci/evergreen/db" 16 "github.com/evergreen-ci/evergreen/model/build" 17 modelutil "github.com/evergreen-ci/evergreen/model/testutil" 18 "github.com/evergreen-ci/evergreen/testutil" 19 "github.com/evergreen-ci/render" 20 . "github.com/smartystreets/goconvey/convey" 21 ) 22 23 var buildTestConfig = testutil.TestConfig() 24 25 func init() { 26 db.SetGlobalSessionProvider(db.SessionFactoryFromConfig(buildTestConfig)) 27 } 28 29 func TestGetBuildInfo(t *testing.T) { 30 31 userManager, err := auth.LoadUserManager(buildTestConfig.AuthConfig) 32 testutil.HandleTestingErr(err, t, "Failure in loading UserManager from config") 33 34 uis := UIServer{ 35 RootURL: buildTestConfig.Ui.Url, 36 Settings: *buildTestConfig, 37 UserManager: userManager, 38 } 39 testutil.HandleTestingErr(uis.InitPlugins(), t, "error installing plugins") 40 41 home := evergreen.FindEvergreenHome() 42 43 uis.Render = render.New(render.Options{ 44 Directory: filepath.Join(home, WebRootPath, Templates), 45 DisableCache: true, 46 }) 47 48 router, err := uis.NewRouter() 49 testutil.HandleTestingErr(err, t, "Failed to create ui server router") 50 51 Convey("When finding info on a particular build", t, func() { 52 testutil.HandleTestingErr(db.Clear(build.Collection), t, 53 "Error clearing '%v' collection", build.Collection) 54 55 buildId := "my-build" 56 versionId := "my-version" 57 projectName := "mci-test" 58 59 err := modelutil.CreateTestLocalConfig(buildTestConfig, "mci-test", "") 60 So(err, ShouldBeNil) 61 62 err = modelutil.CreateTestLocalConfig(buildTestConfig, "render", "") 63 So(err, ShouldBeNil) 64 65 err = modelutil.CreateTestLocalConfig(buildTestConfig, "project_test", "") 66 67 task := build.TaskCache{ 68 Id: "some-task-id", 69 DisplayName: "some-task-name", 70 Status: "success", 71 TimeTaken: time.Duration(100 * time.Millisecond), 72 } 73 build := &build.Build{ 74 Id: buildId, 75 CreateTime: time.Now().Add(-20 * time.Minute), 76 StartTime: time.Now().Add(-10 * time.Minute), 77 FinishTime: time.Now().Add(-5 * time.Second), 78 PushTime: time.Now().Add(-1 * time.Millisecond), 79 Version: versionId, 80 Project: projectName, 81 Revision: fmt.Sprintf("%x", rand.Int()), 82 BuildVariant: "some-build-variant", 83 BuildNumber: "42", 84 Status: "success", 85 Activated: true, 86 ActivatedTime: time.Now().Add(-15 * time.Minute), 87 RevisionOrderNumber: rand.Int(), 88 Tasks: []build.TaskCache{task}, 89 TimeTaken: time.Duration(10 * time.Minute), 90 DisplayName: "My build", 91 Requester: evergreen.RepotrackerVersionRequester, 92 } 93 So(build.Insert(), ShouldBeNil) 94 95 url, err := router.Get("build_info").URL("build_id", buildId) 96 So(err, ShouldBeNil) 97 98 request, err := http.NewRequest("GET", url.String(), nil) 99 So(err, ShouldBeNil) 100 101 response := httptest.NewRecorder() 102 // Need match variables to be set so can call mux.Vars(request) 103 // in the actual handler function 104 router.ServeHTTP(response, request) 105 106 So(response.Code, ShouldEqual, http.StatusOK) 107 108 Convey("response should match contents of database", func() { 109 var jsonBody map[string]interface{} 110 err = json.Unmarshal(response.Body.Bytes(), &jsonBody) 111 So(err, ShouldBeNil) 112 113 var rawJsonBody map[string]*json.RawMessage 114 err = json.Unmarshal(response.Body.Bytes(), &rawJsonBody) 115 So(err, ShouldBeNil) 116 117 So(jsonBody["id"], ShouldEqual, build.Id) 118 119 var createTime time.Time 120 err = json.Unmarshal(*rawJsonBody["create_time"], &createTime) 121 So(err, ShouldBeNil) 122 So(createTime, ShouldHappenWithin, TimePrecision, build.CreateTime) 123 124 var startTime time.Time 125 err = json.Unmarshal(*rawJsonBody["start_time"], &startTime) 126 So(err, ShouldBeNil) 127 So(startTime, ShouldHappenWithin, TimePrecision, build.StartTime) 128 129 var finishTime time.Time 130 err = json.Unmarshal(*rawJsonBody["finish_time"], &finishTime) 131 So(err, ShouldBeNil) 132 So(finishTime, ShouldHappenWithin, TimePrecision, build.FinishTime) 133 134 var pushTime time.Time 135 err = json.Unmarshal(*rawJsonBody["push_time"], &pushTime) 136 So(err, ShouldBeNil) 137 So(pushTime, ShouldHappenWithin, TimePrecision, build.PushTime) 138 139 So(jsonBody["version"], ShouldEqual, build.Version) 140 So(jsonBody["project"], ShouldEqual, build.Project) 141 So(jsonBody["revision"], ShouldEqual, build.Revision) 142 So(jsonBody["variant"], ShouldEqual, build.BuildVariant) 143 So(jsonBody["number"], ShouldEqual, build.BuildNumber) 144 So(jsonBody["status"], ShouldEqual, build.Status) 145 So(jsonBody["activated"], ShouldEqual, build.Activated) 146 147 var activatedTime time.Time 148 err = json.Unmarshal(*rawJsonBody["activated_time"], &activatedTime) 149 So(err, ShouldBeNil) 150 So(activatedTime, ShouldHappenWithin, TimePrecision, build.ActivatedTime) 151 152 So(jsonBody["order"], ShouldEqual, build.RevisionOrderNumber) 153 154 _jsonTasks, ok := jsonBody["tasks"] 155 So(ok, ShouldBeTrue) 156 jsonTasks, ok := _jsonTasks.(map[string]interface{}) 157 So(ok, ShouldBeTrue) 158 So(len(jsonTasks), ShouldEqual, 1) 159 160 _jsonTask, ok := jsonTasks[task.DisplayName] 161 So(ok, ShouldBeTrue) 162 jsonTask, ok := _jsonTask.(map[string]interface{}) 163 So(ok, ShouldBeTrue) 164 165 So(jsonTask["task_id"], ShouldEqual, task.Id) 166 So(jsonTask["status"], ShouldEqual, task.Status) 167 So(jsonTask["time_taken"], ShouldEqual, task.TimeTaken) 168 169 So(jsonBody["time_taken"], ShouldEqual, build.TimeTaken) 170 So(jsonBody["name"], ShouldEqual, build.DisplayName) 171 So(jsonBody["requester"], ShouldEqual, build.Requester) 172 }) 173 }) 174 175 Convey("When finding info on a nonexistent build", t, func() { 176 buildId := "not-present" 177 178 url, err := router.Get("build_info").URL("build_id", buildId) 179 So(err, ShouldBeNil) 180 181 request, err := http.NewRequest("GET", url.String(), nil) 182 So(err, ShouldBeNil) 183 184 response := httptest.NewRecorder() 185 // Need match variables to be set so can call mux.Vars(request) 186 // in the actual handler function 187 router.ServeHTTP(response, request) 188 189 So(response.Code, ShouldEqual, http.StatusNotFound) 190 191 Convey("response should contain a sensible error message", func() { 192 var jsonBody map[string]interface{} 193 err = json.Unmarshal(response.Body.Bytes(), &jsonBody) 194 So(err, ShouldBeNil) 195 So(len(jsonBody["message"].(string)), ShouldBeGreaterThan, 0) 196 }) 197 }) 198 } 199 200 func TestGetBuildStatus(t *testing.T) { 201 202 userManager, err := auth.LoadUserManager(buildTestConfig.AuthConfig) 203 testutil.HandleTestingErr(err, t, "Failure in loading UserManager from config") 204 205 uis := UIServer{ 206 RootURL: buildTestConfig.Ui.Url, 207 Settings: *buildTestConfig, 208 UserManager: userManager, 209 } 210 211 home := evergreen.FindEvergreenHome() 212 213 uis.Render = render.New(render.Options{ 214 Directory: filepath.Join(home, WebRootPath, Templates), 215 DisableCache: true, 216 }) 217 testutil.HandleTestingErr(uis.InitPlugins(), t, "problem loading plugins") 218 219 router, err := uis.NewRouter() 220 testutil.HandleTestingErr(err, t, "Failed to create ui server router") 221 222 Convey("When finding the status of a particular build", t, func() { 223 testutil.HandleTestingErr(db.Clear(build.Collection), t, 224 "Error clearing '%v' collection", build.Collection) 225 226 buildId := "my-build" 227 versionId := "my-version" 228 229 task := build.TaskCache{ 230 Id: "some-task-id", 231 DisplayName: "some-task-name", 232 Status: "success", 233 TimeTaken: time.Duration(100 * time.Millisecond), 234 } 235 build := &build.Build{ 236 Id: buildId, 237 Version: versionId, 238 BuildVariant: "some-build-variant", 239 DisplayName: "Some Build Variant", 240 Tasks: []build.TaskCache{task}, 241 } 242 So(build.Insert(), ShouldBeNil) 243 244 url, err := router.Get("build_status").URL("build_id", buildId) 245 So(err, ShouldBeNil) 246 247 request, err := http.NewRequest("GET", url.String(), nil) 248 So(err, ShouldBeNil) 249 250 response := httptest.NewRecorder() 251 // Need match variables to be set so can call mux.Vars(request) 252 // in the actual handler function 253 router.ServeHTTP(response, request) 254 255 So(response.Code, ShouldEqual, http.StatusOK) 256 257 Convey("response should match contents of database", func() { 258 var jsonBody map[string]interface{} 259 err = json.Unmarshal(response.Body.Bytes(), &jsonBody) 260 So(err, ShouldBeNil) 261 262 var rawJsonBody map[string]*json.RawMessage 263 err = json.Unmarshal(response.Body.Bytes(), &rawJsonBody) 264 So(err, ShouldBeNil) 265 266 So(jsonBody["build_id"], ShouldEqual, build.Id) 267 So(jsonBody["build_variant"], ShouldEqual, build.BuildVariant) 268 269 _jsonTasks, ok := jsonBody["tasks"] 270 So(ok, ShouldBeTrue) 271 jsonTasks, ok := _jsonTasks.(map[string]interface{}) 272 So(ok, ShouldBeTrue) 273 So(len(jsonTasks), ShouldEqual, 1) 274 275 _jsonTask, ok := jsonTasks[task.DisplayName] 276 So(ok, ShouldBeTrue) 277 jsonTask, ok := _jsonTask.(map[string]interface{}) 278 So(ok, ShouldBeTrue) 279 280 So(jsonTask["task_id"], ShouldEqual, task.Id) 281 So(jsonTask["status"], ShouldEqual, task.Status) 282 So(jsonTask["time_taken"], ShouldEqual, task.TimeTaken) 283 }) 284 }) 285 286 Convey("When finding the status of a nonexistent build", t, func() { 287 buildId := "not-present" 288 289 url, err := router.Get("build_status").URL("build_id", buildId) 290 So(err, ShouldBeNil) 291 292 request, err := http.NewRequest("GET", url.String(), nil) 293 So(err, ShouldBeNil) 294 295 response := httptest.NewRecorder() 296 // Need match variables to be set so can call mux.Vars(request) 297 // in the actual handler function 298 router.ServeHTTP(response, request) 299 300 So(response.Code, ShouldEqual, http.StatusNotFound) 301 302 Convey("response should contain a sensible error message", func() { 303 var jsonBody map[string]interface{} 304 err = json.Unmarshal(response.Body.Bytes(), &jsonBody) 305 So(err, ShouldBeNil) 306 So(len(jsonBody["message"].(string)), ShouldBeGreaterThan, 0) 307 }) 308 }) 309 }