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  }