func createTestConfig(filename string, t *testing.T) (*model.TaskConfig, error) { clearDataMsg := "Failed to clear test data collection" testutil.HandleTestingErr( db.ClearCollections( task.Collection, model.ProjectVarsCollection), t, clearDataMsg) data, err := ioutil.ReadFile(filename) if err != nil { return nil, err } testProject := &model.Project{} err = yaml.Unmarshal(data, testProject) if err != nil { return nil, err } testProjectRef := &model.ProjectRef{ Identifier: "mongodb-mongo-master", Owner: "mongodb", Repo: "mongo", RepoKind: "github", Branch: "master", Enabled: true, BatchTime: 180, } workDir, err := ioutil.TempDir("", "plugintest_") if err != nil { return nil, err } testTask := &task.Task{ Id: "mocktaskid", BuildId: "testBuildId", BuildVariant: "linux-64", Project: "mongodb-mongo-master", DisplayName: "test", HostId: "testHost", Version: "versionId", Secret: "mocktasksecret", Status: evergreen.TaskDispatched, Revision: "cb91350bf017337a734dcd0321bf4e6c34990b6a", Requester: evergreen.RepotrackerVersionRequester, } testutil.HandleTestingErr(testTask.Insert(), t, "failed to insert task") projectVars := &model.ProjectVars{ Id: "mongodb-mongo-master", Vars: map[string]string{ "abc": "xyz", "123": "456", }, } _, err = projectVars.Upsert() testutil.HandleTestingErr(err, t, "failed to upsert project vars") testDistro := &distro.Distro{Id: "linux-64", WorkDir: workDir} testVersion := &version.Version{} return model.NewTaskConfig(testDistro, testVersion, testProject, testTask, testProjectRef) }
func TestCreateHostBuckets(t *testing.T) { testutil.HandleTestingErr(db.ClearCollections(host.Collection), t, "couldnt reset host") Convey("With a starting time and a minute bucket size and inserting dynamic hosts with different time frames", t, func() { now := time.Now() bucketSize := time.Duration(10) * time.Second // -20 -> 20 beforeStartHost := host.Host{Id: "beforeStartHost", CreationTime: now.Add(time.Duration(-20) * time.Second), TerminationTime: now.Add(time.Duration(20) * time.Second), Provider: "ec2"} So(beforeStartHost.Insert(), ShouldBeNil) // 80 -> 120 afterEndHost := host.Host{Id: "afterEndHost", CreationTime: now.Add(time.Duration(80) * time.Second), TerminationTime: now.Add(time.Duration(120) * time.Second), Provider: "ec2"} So(afterEndHost.Insert(), ShouldBeNil) // 20 -> 40 h1 := host.Host{Id: "h1", CreationTime: now.Add(time.Duration(20) * time.Second), TerminationTime: now.Add(time.Duration(40) * time.Second), Provider: "ec2"} So(h1.Insert(), ShouldBeNil) // 10 -> 80 h2 := host.Host{Id: "h2", CreationTime: now.Add(time.Duration(10) * time.Second), TerminationTime: now.Add(time.Duration(80) * time.Second), Provider: "ec2"} So(h2.Insert(), ShouldBeNil) // 20 -> h3 := host.Host{Id: "h3", CreationTime: now.Add(time.Duration(20) * time.Second), TerminationTime: util.ZeroTime, Provider: "ec2", Status: evergreen.HostRunning} So(h3.Insert(), ShouldBeNil) // 5 -> 7 sameBucket := host.Host{Id: "sameBucket", CreationTime: now.Add(time.Duration(5) * time.Second), TerminationTime: now.Add(time.Duration(7) * time.Second), Provider: "ec2"} So(sameBucket.Insert(), ShouldBeNil) // 5 -> 30 h4 := host.Host{Id: "h4", CreationTime: now.Add(time.Duration(5) * time.Second), TerminationTime: now.Add(time.Duration(30) * time.Second), Provider: "ec2"} So(h4.Insert(), ShouldBeNil) Convey("for three buckets of 10 seconds, should only retrieve pertinent host docs", func() { endTime := now.Add(time.Duration(30) * time.Second) hosts, err := host.Find(host.ByDynamicWithinTime(now, endTime)) So(err, ShouldBeNil) So(len(hosts), ShouldEqual, 6) frameBounds := FrameBounds{ StartTime: now, EndTime: endTime, BucketSize: bucketSize, NumberBuckets: 3, } Convey("should create the correct buckets and bucket time accordingly", func() { buckets, errors := CreateHostBuckets(hosts, frameBounds) So(errors, ShouldBeEmpty) So(len(buckets), ShouldEqual, 3) So(int(buckets[0].TotalTime.Seconds()), ShouldEqual, 17) So(int(buckets[1].TotalTime.Seconds()), ShouldEqual, 30) So(int(math.Ceil(buckets[2].TotalTime.Seconds())), ShouldEqual, 40) }) }) }) }
func TestUpdateBuildStatusForTask(t *testing.T) { Convey("With two tasks and a build", t, func() { testutil.HandleTestingErr(db.ClearCollections(task.Collection, build.Collection, version.Collection), t, "Error clearing task and build collections") displayName := "testName" b := &build.Build{ Id: "buildtest", Status: evergreen.BuildStarted, Version: "abc", } v := &version.Version{ Id: b.Version, Status: evergreen.VersionStarted, } testTask := task.Task{ Id: "testone", DisplayName: displayName, Activated: false, BuildId: b.Id, Project: "sample", Status: evergreen.TaskFailed, } anotherTask := task.Task{ Id: "two", DisplayName: displayName, Activated: true, BuildId: b.Id, Project: "sample", Status: evergreen.TaskFailed, } b.Tasks = []build.TaskCache{ { Id: testTask.Id, Status: evergreen.TaskSucceeded, }, { Id: anotherTask.Id, Status: evergreen.TaskFailed, }, } So(b.Insert(), ShouldBeNil) So(testTask.Insert(), ShouldBeNil) So(anotherTask.Insert(), ShouldBeNil) So(v.Insert(), ShouldBeNil) Convey("updating the build for a task should update the build's status and the version's status", func() { So(UpdateBuildAndVersionStatusForTask(testTask.Id), ShouldBeNil) b, err := build.FindOne(build.ById(b.Id)) So(err, ShouldBeNil) So(b.Status, ShouldEqual, evergreen.BuildFailed) v, err := version.FindOne(version.ById(v.Id)) So(v.Status, ShouldEqual, evergreen.VersionFailed) }) }) }
func cleanupdb() { err := db.ClearCollections( model.TasksCollection, model.NotifyTimesCollection, model.NotifyHistoryCollection, build.Collection, version.Collection) So(err, ShouldBeNil) }
func TestCreateTaskBuckets(t *testing.T) { testutil.HandleTestingErr(db.ClearCollections(task.Collection), t, "couldnt reset host") Convey("With a starting time and a minute bucket size and inserting tasks with different start and finish", t, func() { now := time.Now() bucketSize := time.Duration(10) * time.Second // -20 -> 20 beforeStartHost := task.Task{Id: "beforeStartTask", StartTime: now.Add(time.Duration(-20) * time.Second), FinishTime: now.Add(time.Duration(20) * time.Second), Status: evergreen.TaskSucceeded} So(beforeStartHost.Insert(), ShouldBeNil) // 80 -> 120 afterEndHost := task.Task{Id: "afterStartTask", StartTime: now.Add(time.Duration(80) * time.Second), FinishTime: now.Add(time.Duration(120) * time.Second), Status: evergreen.TaskFailed} So(afterEndHost.Insert(), ShouldBeNil) // 20 -> 40: shouldnt be added h1 := task.Task{Id: "h1", StartTime: now.Add(time.Duration(20) * time.Second), FinishTime: now.Add(time.Duration(40) * time.Second), Status: evergreen.TaskUndispatched} So(h1.Insert(), ShouldBeNil) // 10 -> 80 h2 := task.Task{Id: "h2", StartTime: now.Add(time.Duration(10) * time.Second), FinishTime: now.Add(time.Duration(80) * time.Second), Status: evergreen.TaskSucceeded} So(h2.Insert(), ShouldBeNil) // 20 -> shouldnt be added neverEnding := task.Task{Id: "neverEnding", StartTime: now.Add(time.Duration(20) * time.Second), Status: evergreen.TaskSucceeded} So(neverEnding.Insert(), ShouldBeNil) // 5 -> 7 sameBucket := task.Task{Id: "sameBucket", StartTime: now.Add(time.Duration(5) * time.Second), FinishTime: now.Add(time.Duration(7) * time.Second), Status: evergreen.TaskFailed} So(sameBucket.Insert(), ShouldBeNil) // 5 -> 30 h4 := task.Task{Id: "h4", StartTime: now.Add(time.Duration(5) * time.Second), FinishTime: now.Add(time.Duration(30) * time.Second), Status: evergreen.TaskFailed} So(h4.Insert(), ShouldBeNil) endTime := now.Add(time.Duration(40) * time.Second) frameBounds := FrameBounds{ StartTime: now, EndTime: endTime, NumberBuckets: 4, BucketSize: bucketSize, } Convey("for four buckets of 10 seconds", func() { tasks, err := task.Find(task.ByTimeRun(now, endTime)) So(err, ShouldBeNil) So(len(tasks), ShouldEqual, 4) buckets, errors := CreateTaskBuckets(tasks, []task.Task{}, frameBounds) So(errors, ShouldBeEmpty) So(len(buckets), ShouldEqual, 4) So(int(buckets[0].TotalTime.Seconds()), ShouldEqual, 17) So(int(math.Ceil(buckets[1].TotalTime.Seconds())), ShouldEqual, 30) So(int(math.Ceil(buckets[2].TotalTime.Seconds())), ShouldEqual, 20) }) }) }
func TestHostFindNextTask(t *testing.T) { Convey("With a host", t, func() { Convey("when finding the next task to be run on the host", func() { testutil.HandleTestingErr(db.ClearCollections(host.Collection, task.Collection, TaskQueuesCollection), t, "Error clearing test collections") h := &host.Host{Id: "hostId", Distro: distro.Distro{}} So(h.Insert(), ShouldBeNil) Convey("if there is no task queue for the host's distro, no task"+ " should be returned", func() { nextTask, err := NextTaskForHost(h) So(err, ShouldBeNil) So(nextTask, ShouldBeNil) }) Convey("if the task queue is empty, no task should be"+ " returned", func() { tQueue := &TaskQueue{Distro: h.Distro.Id} So(tQueue.Save(), ShouldBeNil) nextTask, err := NextTaskForHost(h) So(err, ShouldBeNil) So(nextTask, ShouldBeNil) }) Convey("if the task queue is not empty, the corresponding task"+ " object from the database should be returned", func() { tQueue := &TaskQueue{ Distro: h.Distro.Id, Queue: []TaskQueueItem{{Id: "taskOne"}}, } So(tQueue.Save(), ShouldBeNil) task := &task.Task{Id: "taskOne"} So(task.Insert(), ShouldBeNil) nextTask, err := NextTaskForHost(h) So(err, ShouldBeNil) So(nextTask.Id, ShouldEqual, task.Id) }) }) }) }
func TestDeletingBuild(t *testing.T) { Convey("With a build", t, func() { testutil.HandleTestingErr(db.Clear(build.Collection), t, "Error clearing"+ " '%v' collection", build.Collection) b := &build.Build{ Id: "build", } So(b.Insert(), ShouldBeNil) Convey("deleting it should remove it and all its associated"+ " tasks from the database", func() { testutil.HandleTestingErr(db.ClearCollections(task.Collection), t, "Error"+ " clearing '%v' collection", task.Collection) // insert two tasks that are part of the build, and one that isn't matchingTaskOne := &task.Task{ Id: "matchingOne", BuildId: b.Id, } So(matchingTaskOne.Insert(), ShouldBeNil) matchingTaskTwo := &task.Task{ Id: "matchingTwo", BuildId: b.Id, } So(matchingTaskTwo.Insert(), ShouldBeNil) nonMatchingTask := &task.Task{ Id: "nonMatching", BuildId: "blech", } So(nonMatchingTask.Insert(), ShouldBeNil) // delete the build, make sure only it and its tasks are deleted So(DeleteBuild(b.Id), ShouldBeNil) b, err := build.FindOne(build.ById(b.Id)) So(err, ShouldBeNil) So(b, ShouldBeNil) matchingTasks, err := task.Find(task.ByBuildId("build")) So(err, ShouldBeNil) So(len(matchingTasks), ShouldEqual, 0) nonMatchingTask, err = task.FindOne(task.ById(nonMatchingTask.Id)) So(err, ShouldBeNil) So(nonMatchingTask, ShouldNotBeNil) }) }) }
func TestS3CopyPluginExecution(t *testing.T) { testConfig := evergreen.TestConfig() db.SetGlobalSessionProvider(db.SessionFactoryFromConfig(testConfig)) testutil.ConfigureIntegrationTest(t, testConfig, "TestS3CopyPluginExecution") Convey("With a SimpleRegistry and test project file", t, func() { registry := plugin.NewSimpleRegistry() s3CopyPlugin := &S3CopyPlugin{} testutil.HandleTestingErr(registry.Register(s3CopyPlugin), t, "failed to register s3Copy plugin") testutil.HandleTestingErr(registry.Register(&s3Plugin.S3Plugin{}), t, "failed to register S3 plugin") testutil.HandleTestingErr( db.ClearCollections(model.PushlogCollection, version.Collection), t, "error clearing test collections") version := &version.Version{ Id: "", } So(version.Insert(), ShouldBeNil) server, err := apiserver.CreateTestServer(testConfig, nil, plugin.APIPlugins, false) testutil.HandleTestingErr(err, t, "Couldn't set up testing server") httpCom := plugintest.TestAgentCommunicator("mocktaskid", "mocktasksecret", server.URL) //server.InstallPlugin(s3CopyPlugin) taskConfig, err := plugintest.CreateTestConfig("testdata/plugin_s3_copy.yml", t) testutil.HandleTestingErr(err, t, "failed to create test config: %v", err) taskConfig.WorkDir = "." sliceAppender := &evergreen.SliceAppender{[]*slogger.Log{}} logger := agent.NewTestLogger(sliceAppender) taskConfig.Expansions.Update(map[string]string{ "aws_key": testConfig.Providers.AWS.Id, "aws_secret": testConfig.Providers.AWS.Secret, }) Convey("the s3 copy command should execute successfully", func() { for _, task := range taskConfig.Project.Tasks { So(len(task.Commands), ShouldNotEqual, 0) for _, command := range task.Commands { pluginCmds, err := registry.GetCommands(command, taskConfig.Project.Functions) testutil.HandleTestingErr(err, t, "Couldn't get plugin command: %v") So(pluginCmds, ShouldNotBeNil) So(err, ShouldBeNil) pluginCom := &agent.TaskJSONCommunicator{s3CopyPlugin.Name(), httpCom} err = pluginCmds[0].Execute(logger, pluginCom, taskConfig, make(chan bool)) So(err, ShouldBeNil) } } }) }) }
func clearAll(t *testing.T) { testutil.HandleTestingErr( db.ClearCollections( model.ProjectRefCollection, patch.Collection, version.Collection, build.Collection, task.Collection, distro.Collection, ), t, "Error clearing test collection: %v") }
// prependConfigToVersion modifies the project config with the given id func prependConfigToVersion(t *testing.T, versionId, configData string) { v, err := version.FindOne(version.ById(versionId)) testutil.HandleTestingErr(err, t, "failed to load version") if v == nil { err = fmt.Errorf("could not find version to update") testutil.HandleTestingErr(err, t, "failed to find version") } v.Config = configData + v.Config testutil.HandleTestingErr(dbutil.ClearCollections(version.Collection), t, "couldnt reset version") testutil.HandleTestingErr(v.Insert(), t, "failed to insert version") }
func TestDeactivatePreviousTask(t *testing.T) { Convey("With two tasks and a build", t, func() { testutil.HandleTestingErr(db.ClearCollections(task.Collection, build.Collection), t, "Error clearing task and build collections") // create two tasks displayName := "testTask" userName := "******" b := &build.Build{ Id: "testBuild", } previousTask := &task.Task{ Id: "one", DisplayName: displayName, RevisionOrderNumber: 1, Priority: 1, Activated: true, ActivatedBy: "user", BuildId: b.Id, Status: evergreen.TaskUndispatched, Project: "sample", } currentTask := &task.Task{ Id: "two", DisplayName: displayName, RevisionOrderNumber: 2, Status: evergreen.TaskFailed, Priority: 1, Activated: true, BuildId: b.Id, Project: "sample", } tc := []build.TaskCache{ { DisplayName: displayName, Id: previousTask.Id, }, { DisplayName: displayName, Id: currentTask.Id, }, } b.Tasks = tc So(b.Insert(), ShouldBeNil) So(previousTask.Insert(), ShouldBeNil) So(currentTask.Insert(), ShouldBeNil) Convey("activating a previous task should set the previous task's active field to true", func() { So(DeactivatePreviousTasks(currentTask.Id, userName), ShouldBeNil) previousTask, err := task.FindOne(task.ById(previousTask.Id)) So(err, ShouldBeNil) So(previousTask.Activated, ShouldBeFalse) }) }) }
func TestMarkStart(t *testing.T) { Convey("With a task, build and version", t, func() { testutil.HandleTestingErr(db.ClearCollections(task.Collection, build.Collection, version.Collection), t, "Error clearing task and build collections") displayName := "testName" b := &build.Build{ Id: "buildtest", Status: evergreen.BuildCreated, Version: "abc", } v := &version.Version{ Id: b.Version, Status: evergreen.VersionCreated, } testTask := task.Task{ Id: "testTask", DisplayName: displayName, Activated: true, BuildId: b.Id, Project: "sample", Status: evergreen.TaskUndispatched, Version: b.Version, } b.Tasks = []build.TaskCache{ { Id: testTask.Id, Status: evergreen.TaskUndispatched, }, } So(b.Insert(), ShouldBeNil) So(testTask.Insert(), ShouldBeNil) So(v.Insert(), ShouldBeNil) Convey("when calling MarkStart, the task, version and build should be updated", func() { So(MarkStart(testTask.Id), ShouldBeNil) testTask, err := task.FindOne(task.ById(testTask.Id)) So(err, ShouldBeNil) So(testTask.Status, ShouldEqual, evergreen.TaskStarted) b, err := build.FindOne(build.ById(b.Id)) So(err, ShouldBeNil) So(b.Status, ShouldEqual, evergreen.BuildStarted) So(b.Tasks, ShouldNotBeNil) So(len(b.Tasks), ShouldEqual, 1) So(b.Tasks[0].Status, ShouldEqual, evergreen.TaskStarted) v, err := version.FindOne(version.ById(v.Id)) So(err, ShouldBeNil) So(v.Status, ShouldEqual, evergreen.VersionStarted) }) }) }
func TestAverageStatistics(t *testing.T) { testutil.HandleTestingErr(db.ClearCollections(task.Collection), t, "couldnt reset host") Convey("With a distro sampleDistro inserted", t, func() { d := distro.Distro{ Id: "sampleDistro", } err := d.Insert() So(err, ShouldBeNil) distroId := d.Id Convey("With a set of tasks that have different scheduled -> start times over a given time period", func() { now := time.Now() bucketSize := 10 * time.Second numberBuckets := 3 task1 := task.Task{Id: "task1", ScheduledTime: now, StartTime: now.Add(time.Duration(5) * time.Second), Status: evergreen.TaskStarted, DistroId: distroId} So(task1.Insert(), ShouldBeNil) task2 := task.Task{Id: "task2", ScheduledTime: now, StartTime: now.Add(time.Duration(20) * time.Second), Status: evergreen.TaskStarted, DistroId: distroId} So(task2.Insert(), ShouldBeNil) task3 := task.Task{Id: "task3", ScheduledTime: now.Add(time.Duration(10) * time.Second), StartTime: now.Add(time.Duration(20) * time.Second), Status: evergreen.TaskStarted, DistroId: distroId} So(task3.Insert(), ShouldBeNil) frameBounds := FrameBounds{ StartTime: now, EndTime: now.Add(time.Duration(numberBuckets) * bucketSize), NumberBuckets: numberBuckets, BucketSize: bucketSize, } avgBuckets, err := AverageStatistics(distroId, frameBounds) So(err, ShouldBeNil) So(avgBuckets[0].AverageTime, ShouldEqual, 5*time.Second) So(avgBuckets[1].AverageTime, ShouldEqual, 0) So(avgBuckets[2].AverageTime, ShouldEqual, 15*time.Second) Convey("if the distro id given does not exist, it shoud return an empty list", func() { _, err := AverageStatistics("noId", frameBounds) So(err, ShouldNotBeNil) }) }) }) }
func setupCLITestHarness() cliTestHarness { // create a test API server testServer, err := service.CreateTestServer(testConfig, nil, plugin.APIPlugins, true) So(err, ShouldBeNil) So( db.ClearCollections( task.Collection, build.Collection, user.Collection, patch.Collection, model.ProjectRefCollection, artifact.Collection, ), ShouldBeNil) So(db.Clear(patch.Collection), ShouldBeNil) So(db.Clear(model.ProjectRefCollection), ShouldBeNil) So((&user.DBUser{Id: "testuser", APIKey: "testapikey", EmailAddress: "*****@*****.**"}).Insert(), ShouldBeNil) localConfBytes, err := ioutil.ReadFile(filepath.Join(testutil.GetDirectoryOfFile(), "testdata", "sample.yml")) So(err, ShouldBeNil) projectRef := &model.ProjectRef{ Identifier: "sample", Owner: "evergreen-ci", Repo: "sample", RepoKind: "github", Branch: "master", RemotePath: "evergreen.yml", LocalConfig: string(localConfBytes), Enabled: true, BatchTime: 180, } So(projectRef.Insert(), ShouldBeNil) // create a settings file for the command line client settings := model.CLISettings{ APIServerHost: testServer.URL + "/api", UIServerHost: "http://dev-evg.mongodb.com", APIKey: "testapikey", User: "******", } settingsFile, err := ioutil.TempFile("", "settings") So(err, ShouldBeNil) settingsBytes, err := yaml.Marshal(settings) So(err, ShouldBeNil) _, err = settingsFile.Write(settingsBytes) So(err, ShouldBeNil) settingsFile.Close() return cliTestHarness{testServer, settingsFile.Name()} }
func TestAbortTask(t *testing.T) { Convey("With a task and a build", t, func() { testutil.HandleTestingErr(db.ClearCollections(task.Collection, build.Collection, version.Collection), t, "Error clearing task, build, and version collections") displayName := "testName" userName := "******" b := &build.Build{ Id: "buildtest", } testTask := task.Task{ Id: "testone", DisplayName: displayName, Activated: false, BuildId: b.Id, Status: evergreen.TaskStarted, } finishedTask := task.Task{ Id: "another", DisplayName: displayName, Activated: false, BuildId: b.Id, Status: evergreen.TaskFailed, } b.Tasks = []build.TaskCache{ { Id: testTask.Id, }, { Id: finishedTask.Id, }, } So(b.Insert(), ShouldBeNil) So(testTask.Insert(), ShouldBeNil) So(finishedTask.Insert(), ShouldBeNil) Convey("with a task that has started, aborting a task should work", func() { So(AbortTask(testTask.Id, userName), ShouldBeNil) testTask, err := task.FindOne(task.ById(testTask.Id)) So(err, ShouldBeNil) So(testTask.Activated, ShouldEqual, false) So(testTask.Aborted, ShouldEqual, true) }) Convey("a task that is finished should error when aborting", func() { So(AbortTask(finishedTask.Id, userName), ShouldNotBeNil) }) }) }
func TestBuildSetPriority(t *testing.T) { Convey("With a build", t, func() { testutil.HandleTestingErr(db.ClearCollections(build.Collection, TasksCollection), t, "Error clearing test collection") b := &build.Build{ Id: "build", } So(b.Insert(), ShouldBeNil) taskOne := &Task{Id: "taskOne", BuildId: b.Id} So(taskOne.Insert(), ShouldBeNil) taskTwo := &Task{Id: "taskTwo", BuildId: b.Id} So(taskTwo.Insert(), ShouldBeNil) taskThree := &Task{Id: "taskThree", BuildId: b.Id} So(taskThree.Insert(), ShouldBeNil) Convey("setting its priority should update the priority"+ " of all its tasks in the database", func() { So(SetBuildPriority(b.Id, 42), ShouldBeNil) tasks, err := FindAllTasks( bson.M{ TaskBuildIdKey: b.Id, }, db.NoProjection, db.NoSort, db.NoSkip, db.NoLimit, ) So(err, ShouldBeNil) So(len(tasks), ShouldEqual, 3) So(tasks[0].Priority, ShouldEqual, 42) So(tasks[1].Priority, ShouldEqual, 42) So(tasks[2].Priority, ShouldEqual, 42) }) }) }
func TestMarkEnd(t *testing.T) { Convey("With a task and a build", t, func() { testutil.HandleTestingErr(db.ClearCollections(task.Collection, build.Collection, version.Collection), t, "Error clearing task and build collections") displayName := "testName" userName := "******" b := &build.Build{ Id: "buildtest", Status: evergreen.BuildStarted, Version: "abc", } p := &Project{ Identifier: "sample", } v := &version.Version{ Id: b.Version, Status: evergreen.VersionStarted, } testTask := task.Task{ Id: "testone", DisplayName: displayName, Activated: true, BuildId: b.Id, Project: "sample", Status: evergreen.TaskStarted, } b.Tasks = []build.TaskCache{ { Id: testTask.Id, Status: evergreen.TaskStarted, }, } So(b.Insert(), ShouldBeNil) So(testTask.Insert(), ShouldBeNil) So(v.Insert(), ShouldBeNil) Convey("task, build and version status will be updated properly", func() { details := apimodels.TaskEndDetail{ Status: evergreen.TaskFailed, } So(MarkEnd(testTask.Id, userName, time.Now(), &details, p, false), ShouldBeNil) }) }) }
func TestFlaggingProvisioningFailedHosts(t *testing.T) { testConfig := evergreen.TestConfig() db.SetGlobalSessionProvider(db.SessionFactoryFromConfig(testConfig)) Convey("When flagging hosts whose provisioning failed", t, func() { // reset the db testutil.HandleTestingErr(db.ClearCollections(host.Collection), t, "error clearing hosts collection") Convey("only hosts whose provisioning failed should be"+ " picked up", func() { host1 := &host.Host{ Id: "h1", Status: evergreen.HostRunning, } testutil.HandleTestingErr(host1.Insert(), t, "error inserting host") host2 := &host.Host{ Id: "h2", Status: evergreen.HostUninitialized, } testutil.HandleTestingErr(host2.Insert(), t, "error inserting host") host3 := &host.Host{ Id: "h3", Status: evergreen.HostProvisionFailed, } testutil.HandleTestingErr(host3.Insert(), t, "error inserting host") unprovisioned, err := flagProvisioningFailedHosts(nil, nil) So(err, ShouldBeNil) So(len(unprovisioned), ShouldEqual, 1) So(unprovisioned[0].Id, ShouldEqual, "h3") }) }) }
func TestBuildSetPriority(t *testing.T) { Convey("With a build", t, func() { testutil.HandleTestingErr(db.ClearCollections(build.Collection, task.Collection), t, "Error clearing test collection") b := &build.Build{ Id: "build", } So(b.Insert(), ShouldBeNil) taskOne := &task.Task{Id: "taskOne", BuildId: b.Id} So(taskOne.Insert(), ShouldBeNil) taskTwo := &task.Task{Id: "taskTwo", BuildId: b.Id} So(taskTwo.Insert(), ShouldBeNil) taskThree := &task.Task{Id: "taskThree", BuildId: b.Id} So(taskThree.Insert(), ShouldBeNil) Convey("setting its priority should update the priority"+ " of all its tasks in the database", func() { So(SetBuildPriority(b.Id, 42), ShouldBeNil) tasks, err := task.Find(task.ByBuildId(b.Id)) So(err, ShouldBeNil) So(len(tasks), ShouldEqual, 3) So(tasks[0].Priority, ShouldEqual, 42) So(tasks[1].Priority, ShouldEqual, 42) So(tasks[2].Priority, ShouldEqual, 42) }) }) }
func setupAPITestData(testConfig *evergreen.Settings, taskDisplayName string, variant string, patchMode patchTestMode, t *testing.T) (*model.Task, *build.Build, error) { //ignore errs here because the ns might just not exist. clearDataMsg := "Failed to clear test data collection" testCollections := []string{ model.TasksCollection, build.Collection, host.Collection, distro.Collection, version.Collection, patch.Collection, model.PushlogCollection, model.ProjectVarsCollection, model.TaskQueuesCollection, manifest.Collection, model.ProjectRefCollection} testutil.HandleTestingErr(dbutil.ClearCollections(testCollections...), t, clearDataMsg) projectVars := &model.ProjectVars{ Id: "evergreen-ci-render", Vars: map[string]string{ "aws_key": testConfig.Providers.AWS.Id, "aws_secret": testConfig.Providers.AWS.Secret, "fetch_key": "fetch_expansion_value", }, } _, err := projectVars.Upsert() testutil.HandleTestingErr(err, t, clearDataMsg) taskOne := &model.Task{ Id: "testTaskId", BuildId: "testBuildId", DistroId: "test-distro-one", BuildVariant: variant, Project: "evergreen-ci-render", DisplayName: taskDisplayName, HostId: "testHost", Secret: "testTaskSecret", Version: "testVersionId", Status: evergreen.TaskDispatched, Requester: evergreen.RepotrackerVersionRequester, } taskTwo := &model.Task{ Id: "testTaskIdTwo", BuildId: "testBuildId", DistroId: "test-distro-one", BuildVariant: variant, Project: "evergreen-ci-render", DisplayName: taskDisplayName, HostId: "", Secret: "testTaskSecret", Activated: true, Version: "testVersionId", Status: evergreen.TaskUndispatched, Requester: evergreen.RepotrackerVersionRequester, } if patchMode != NoPatch { taskOne.Requester = evergreen.PatchVersionRequester } testutil.HandleTestingErr(taskOne.Insert(), t, "failed to insert taskOne") testutil.HandleTestingErr(taskTwo.Insert(), t, "failed to insert taskTwo") // set up task queue for task end tests taskQueue := &model.TaskQueue{ Distro: "test-distro-one", Queue: []model.TaskQueueItem{ model.TaskQueueItem{ Id: "testTaskIdTwo", DisplayName: taskDisplayName, }, }, } testutil.HandleTestingErr(taskQueue.Save(), t, "failed to insert taskqueue") workDir, err := ioutil.TempDir("", "agent_test_") testutil.HandleTestingErr(err, t, "failed to create working directory") host := &host.Host{ Id: "testHost", Host: "testHost", Distro: distro.Distro{ Id: "test-distro-one", WorkDir: workDir, Expansions: []distro.Expansion{{"distro_exp", "DISTRO_EXP"}}, }, RunningTask: "testTaskId", StartedBy: evergreen.User, AgentRevision: agentRevision, } testutil.HandleTestingErr(host.Insert(), t, "failed to insert host") // read in the project configuration projectFile := "testdata/config_test_plugin/project/evergreen-ci-render.yml" projectConfig, err := ioutil.ReadFile(projectFile) testutil.HandleTestingErr(err, t, "failed to read project config") projectRef := &model.ProjectRef{ Identifier: "evergreen-ci-render", Owner: "evergreen-ci", Repo: "render", RepoKind: "github", Branch: "master", Enabled: true, BatchTime: 180, } testutil.HandleTestingErr(projectRef.Insert(), t, "failed to insert projectRef") err = testutil.CreateTestLocalConfig(testConfig, "evergreen-ci-render", "testdata/config_test_plugin/project/evergreen-ci-render.yml") testutil.HandleTestingErr(err, t, "failed to marshall project config") // unmarshall the project configuration into a struct project := &model.Project{} testutil.HandleTestingErr(yaml.Unmarshal(projectConfig, project), t, "failed to unmarshal project config") // now then marshall the project YAML for storage projectYamlBytes, err := yaml.Marshal(project) testutil.HandleTestingErr(err, t, "failed to marshall project config") // insert the version document v := &version.Version{ Id: "testVersionId", BuildIds: []string{taskOne.BuildId}, Config: string(projectYamlBytes), } testutil.HandleTestingErr(v.Insert(), t, "failed to insert version") if patchMode != NoPatch { mainPatchContent, err := ioutil.ReadFile("testdata/test.patch") testutil.HandleTestingErr(err, t, "failed to read test patch file") modulePatchContent, err := ioutil.ReadFile("testdata/testmodule.patch") testutil.HandleTestingErr(err, t, "failed to read test module patch file") ptch := &patch.Patch{ Status: evergreen.PatchCreated, Version: v.Id, } if patchMode == InlinePatch { ptch.Patches = []patch.ModulePatch{ { ModuleName: "", Githash: "1e5232709595db427893826ce19289461cba3f75", PatchSet: patch.PatchSet{Patch: string(mainPatchContent)}, }, { ModuleName: "recursive", Githash: "1e5232709595db427893826ce19289461cba3f75", PatchSet: patch.PatchSet{Patch: string(modulePatchContent)}, }, } } else { p1Id, p2Id := bson.NewObjectId().Hex(), bson.NewObjectId().Hex() So(dbutil.WriteGridFile(patch.GridFSPrefix, p1Id, strings.NewReader(string(mainPatchContent))), ShouldBeNil) So(dbutil.WriteGridFile(patch.GridFSPrefix, p2Id, strings.NewReader(string(modulePatchContent))), ShouldBeNil) ptch.Patches = []patch.ModulePatch{ { ModuleName: "", Githash: "1e5232709595db427893826ce19289461cba3f75", PatchSet: patch.PatchSet{PatchFileId: p1Id}, }, { ModuleName: "recursive", Githash: "1e5232709595db427893826ce19289461cba3f75", PatchSet: patch.PatchSet{PatchFileId: p2Id}, }, } } testutil.HandleTestingErr(ptch.Insert(), t, "failed to insert patch") } session, _, err := dbutil.GetGlobalSessionFactory().GetSession() testutil.HandleTestingErr(err, t, "couldn't get db session!") // Remove any logs for our test task from previous runs. _, err = session.DB(model.TaskLogDB).C(model.TaskLogCollection). RemoveAll(bson.M{"t_id": bson.M{"$in": []string{taskOne.Id, taskTwo.Id}}}) testutil.HandleTestingErr(err, t, "failed to remove logs") build := &build.Build{ Id: "testBuildId", Tasks: []build.TaskCache{ build.NewTaskCache(taskOne.Id, taskOne.DisplayName, true), build.NewTaskCache(taskTwo.Id, taskTwo.DisplayName, true), }, Version: "testVersionId", } testutil.HandleTestingErr(build.Insert(), t, "failed to insert build") return taskOne, build, nil }
func TestPushTask(t *testing.T) { testConfig := evergreen.TestConfig() setupTlsConfigs(t) db.SetGlobalSessionProvider(db.SessionFactoryFromConfig(testConfig)) testutil.ConfigureIntegrationTest(t, testConfig, "TestPushTask") for tlsString, tlsConfig := range tlsConfigs { for _, testSetup := range testSetups { Convey(testSetup.testSpec, t, func() { Convey("With agent running a push task "+tlsString, func() { testTask, _, err := setupAPITestData(testConfig, evergreen.PushStage, "linux-64", false, t) testutil.HandleTestingErr(err, t, "Error setting up test data: %v", err) testutil.HandleTestingErr(db.ClearCollections(artifact.Collection), t, "can't clear files collection") testServer, err := apiserver.CreateTestServer(testConfig, tlsConfig, plugin.Published, Verbose) testutil.HandleTestingErr(err, t, "Couldn't create apiserver: %v", err) testAgent, err := New(testServer.URL, testTask.Id, testTask.Secret, "", testConfig.Expansions["api_httpscert"]) testutil.HandleTestingErr(err, t, "Error making test agent: %v", err) // actually run the task. // this function won't return until the whole thing is done. testAgent.RunTask() time.Sleep(100 * time.Millisecond) testAgent.APILogger.FlushAndWait() printLogsForTask(testTask.Id) newDate := testAgent.taskConfig.Expansions.Get("new_date") Convey("all scripts in task should have been run successfully", func() { So(scanLogsForTask(testTask.Id, "executing the pre-run script!"), ShouldBeTrue) So(scanLogsForTask(testTask.Id, "executing the post-run script!"), ShouldBeTrue) So(scanLogsForTask(testTask.Id, "push task pre-run!"), ShouldBeTrue) So(scanLogsForTask(testTask.Id, "push task post-run!"), ShouldBeTrue) Convey("s3.put attaches task file properly", func() { entry, err := artifact.FindOne(artifact.ByTaskId(testTask.Id)) So(err, ShouldBeNil) So(len(entry.Files), ShouldEqual, 2) for _, element := range entry.Files { So(element.Name, ShouldNotEqual, "") } So(entry.Files[0].Name, ShouldEqual, "push_file") link := "https://s3.amazonaws.com/build-push-testing/pushtest-stage/unittest-testTaskId-DISTRO_EXP-BUILDVAR_EXP-FILE_EXP.txt" So(entry.Files[0].Link, ShouldEqual, link) }) Convey("s3.copy attached task file properly", func() { entry, err := artifact.FindOne(artifact.ByTaskId(testTask.Id)) So(err, ShouldBeNil) So(len(entry.Files), ShouldNotEqual, 0) So(entry.Files[0].Name, ShouldEqual, "push_file") So(entry.Files[1].Name, ShouldEqual, "copy_file") So(entry.Files[0].Link, ShouldEqual, "https://s3.amazonaws.com/build-push-testing/pushtest-stage/unittest-testTaskId-DISTRO_EXP-BUILDVAR_EXP-FILE_EXP.txt") So(entry.Files[1].Link, ShouldEqual, "https://s3.amazonaws.com/build-push-testing/pushtest/unittest-DISTRO_EXP-BUILDVAR_EXP-FILE_EXP-latest.txt") }) testTask, err = model.FindTask(testTask.Id) testutil.HandleTestingErr(err, t, "Error finding test task: %v", err) So(testTask.Status, ShouldEqual, evergreen.TaskSucceeded) // Check the file written to s3 is what we expected auth := &aws.Auth{ AccessKey: testConfig.Providers.AWS.Id, SecretKey: testConfig.Providers.AWS.Secret, } // check the staging location first filebytes, err := getS3FileBytes(auth, "build-push-testing", "/pushtest-stage/unittest-testTaskId-DISTRO_EXP-BUILDVAR_EXP-FILE_EXP.txt") testutil.HandleTestingErr(err, t, "Failed to get file from s3: %v", err) So(string(filebytes), ShouldEqual, newDate+"\n") // now check remote location (after copy) filebytes, err = getS3FileBytes(auth, "build-push-testing", "/pushtest/unittest-DISTRO_EXP-BUILDVAR_EXP-FILE_EXP-latest.txt") testutil.HandleTestingErr(err, t, "Failed to get remote file from s3: %v", err) So(string(filebytes), ShouldEqual, newDate+"\n") }) }) }) } } }
func TestSetupFuncs(t *testing.T) { var taskPrioritizer *CmpBasedTaskPrioritizer var taskIds []string var tasks []model.Task Convey("When running the setup funcs for task prioritizing", t, func() { taskPrioritizer = &CmpBasedTaskPrioritizer{} taskIds = []string{"t1", "t2", "t3"} tasks = []model.Task{ model.Task{Id: taskIds[0]}, model.Task{Id: taskIds[1]}, model.Task{Id: taskIds[2]}, } testutil.HandleTestingErr( db.ClearCollections(build.Collection, model.TasksCollection), t, "Failed to clear test collections") Convey("the previous task caching setup func should fetch and save the"+ " relevant previous runs of tasks", func() { displayNames := []string{"disp1", "disp2", "disp3"} buildVariant := "bv" prevTaskIds := []string{"pt1", "pt2", "pt3"} project := "project" tasks[0].RevisionOrderNumber = 100 tasks[0].Requester = evergreen.RepotrackerVersionRequester tasks[0].DisplayName = displayNames[0] tasks[0].BuildVariant = buildVariant tasks[0].Project = project tasks[1].RevisionOrderNumber = 200 tasks[1].Requester = evergreen.RepotrackerVersionRequester tasks[1].DisplayName = displayNames[1] tasks[1].BuildVariant = buildVariant tasks[1].Project = project tasks[2].RevisionOrderNumber = 300 tasks[2].Requester = evergreen.RepotrackerVersionRequester tasks[2].DisplayName = displayNames[2] tasks[2].BuildVariant = buildVariant tasks[2].Project = project // the previous tasks prevTaskOne := &model.Task{ Id: prevTaskIds[0], RevisionOrderNumber: 99, Requester: evergreen.RepotrackerVersionRequester, DisplayName: displayNames[0], BuildVariant: buildVariant, Project: project, Status: evergreen.TaskFailed, } prevTaskTwo := &model.Task{ Id: prevTaskIds[1], RevisionOrderNumber: 199, Requester: evergreen.RepotrackerVersionRequester, DisplayName: displayNames[1], BuildVariant: buildVariant, Project: project, Status: evergreen.TaskSucceeded, } prevTaskThree := &model.Task{ Id: prevTaskIds[2], RevisionOrderNumber: 299, Requester: evergreen.RepotrackerVersionRequester, DisplayName: displayNames[2], BuildVariant: buildVariant, Project: project, Status: evergreen.TaskSucceeded, } So(prevTaskOne.Insert(), ShouldBeNil) So(prevTaskTwo.Insert(), ShouldBeNil) So(prevTaskThree.Insert(), ShouldBeNil) taskPrioritizer.tasks = tasks So(cachePreviousTasks(taskPrioritizer), ShouldBeNil) So(len(taskPrioritizer.previousTasksCache), ShouldEqual, 3) So(taskPrioritizer.previousTasksCache[taskIds[0]].Id, ShouldEqual, prevTaskIds[0]) So(taskPrioritizer.previousTasksCache[taskIds[1]].Id, ShouldEqual, prevTaskIds[1]) So(taskPrioritizer.previousTasksCache[taskIds[2]].Id, ShouldEqual, prevTaskIds[2]) }) }) }
func SetupAPITestData(taskDisplayName string, isPatch bool, t *testing.T) (*model.Task, *build.Build, error) { //ignore errs here because the ns might just not exist. testutil.HandleTestingErr( db.ClearCollections(model.TasksCollection, build.Collection, host.Collection, version.Collection, patch.Collection), t, "Failed to clear test collections") testHost := &host.Host{ Id: "testHost", Host: "testHost", RunningTask: "testTaskId", StartedBy: evergreen.User, } testutil.HandleTestingErr(testHost.Insert(), t, "failed to insert host") task := &model.Task{ Id: "testTaskId", BuildId: "testBuildId", DistroId: "rhel55", BuildVariant: "linux-64", Project: "mongodb-mongo-master", DisplayName: taskDisplayName, HostId: "testHost", Version: "testVersionId", Secret: "testTaskSecret", Status: evergreen.TaskDispatched, Requester: evergreen.RepotrackerVersionRequester, } if isPatch { task.Requester = evergreen.PatchVersionRequester } testutil.HandleTestingErr(task.Insert(), t, "failed to insert task") version := &version.Version{Id: "testVersionId", BuildIds: []string{task.BuildId}} testutil.HandleTestingErr(version.Insert(), t, "failed to insert version %v") if isPatch { modulePatchContent, err := ioutil.ReadFile("testdata/testmodule.patch") testutil.HandleTestingErr(err, t, "failed to read test module patch file %v") patch := &patch.Patch{ Status: evergreen.PatchCreated, Version: version.Id, Patches: []patch.ModulePatch{ { ModuleName: "enterprise", Githash: "c2d7ce942a96d7dacd27c55b257e3f2774e04abf", PatchSet: patch.PatchSet{Patch: string(modulePatchContent)}, }, }, } testutil.HandleTestingErr(patch.Insert(), t, "failed to insert patch %v") } session, _, err := db.GetGlobalSessionFactory().GetSession() testutil.HandleTestingErr(err, t, "couldn't get db session!") //Remove any logs for our test task from previous runs. _, err = session.DB(model.TaskLogDB).C(model.TaskLogCollection).RemoveAll(bson.M{"t_id": task.Id}) testutil.HandleTestingErr(err, t, "failed to remove logs") build := &build.Build{Id: "testBuildId", Tasks: []build.TaskCache{build.NewTaskCache(task.Id, task.DisplayName, true)}} testutil.HandleTestingErr(build.Insert(), t, "failed to insert build %v") return task, build, nil }
func TestWarnSlowProvisioningHosts(t *testing.T) { testConfig := evergreen.TestConfig() db.SetGlobalSessionProvider(db.SessionFactoryFromConfig(testConfig)) Convey("When building warnings for hosts that are taking a long time to"+ " provision", t, func() { // reset the db testutil.HandleTestingErr(db.ClearCollections(host.Collection), t, "error clearing hosts collection") Convey("hosts that have not hit the threshold should not trigger a"+ " warning", func() { host1 := &host.Host{ Id: "h1", StartedBy: evergreen.User, CreationTime: time.Now().Add(-10 * time.Minute), } testutil.HandleTestingErr(host1.Insert(), t, "error inserting host") warnings, err := slowProvisioningWarnings(testConfig) So(err, ShouldBeNil) So(len(warnings), ShouldEqual, 0) }) Convey("hosts that have already triggered a notification should not"+ " trigger another", func() { host1 := &host.Host{ Id: "h1", StartedBy: evergreen.User, CreationTime: time.Now().Add(-1 * time.Hour), Notifications: map[string]bool{ slowProvisioningWarning: true, }, } testutil.HandleTestingErr(host1.Insert(), t, "error inserting host") warnings, err := slowProvisioningWarnings(testConfig) So(err, ShouldBeNil) So(len(warnings), ShouldEqual, 0) }) Convey("terminated hosts should not trigger a warning", func() { host1 := &host.Host{ Id: "h1", StartedBy: evergreen.User, Status: evergreen.HostTerminated, CreationTime: time.Now().Add(-1 * time.Hour), } testutil.HandleTestingErr(host1.Insert(), t, "error inserting host") warnings, err := slowProvisioningWarnings(testConfig) So(err, ShouldBeNil) So(len(warnings), ShouldEqual, 0) }) Convey("hosts that are at the threshold and have not previously"+ " triggered a warning should trigger one", func() { host1 := &host.Host{ Id: "h1", StartedBy: evergreen.User, CreationTime: time.Now().Add(-1 * time.Hour), } testutil.HandleTestingErr(host1.Insert(), t, "error inserting host") warnings, err := slowProvisioningWarnings(testConfig) So(err, ShouldBeNil) So(len(warnings), ShouldEqual, 1) // make sure running the callback sets the notification key So(warnings[0].callback(warnings[0].host, warnings[0].threshold), ShouldBeNil) host1, err = host.FindOne(host.ById("h1")) So(err, ShouldBeNil) So(host1.Notifications[slowProvisioningWarning], ShouldBeTrue) }) }) }
func TestWarnExpiringSpawnedHosts(t *testing.T) { testConfig := evergreen.TestConfig() db.SetGlobalSessionProvider(db.SessionFactoryFromConfig(testConfig)) Convey("When building warnings for spawned hosts that will be expiring"+ " soon", t, func() { // reset the db testutil.HandleTestingErr(db.ClearCollections(host.Collection), t, "error clearing hosts collection") Convey("any hosts not expiring within a threshold should not trigger"+ " warnings", func() { // this host does not expire within the first notification // threshold host1 := &host.Host{ Id: "h1", ExpirationTime: time.Now().Add(time.Hour * 15), } testutil.HandleTestingErr(host1.Insert(), t, "error inserting host") warnings, err := spawnHostExpirationWarnings(testConfig) So(err, ShouldBeNil) So(len(warnings), ShouldEqual, 0) }) Convey("any thresholds for which warnings have already been sent"+ " should be ignored", func() { // this host meets the first notification warning threshold host1 := &host.Host{ Id: "h1", ExpirationTime: time.Now().Add(time.Hour * 10), Notifications: map[string]bool{ "720": true, // the first threshold in minutes }, } testutil.HandleTestingErr(host1.Insert(), t, "error inserting host") warnings, err := spawnHostExpirationWarnings(testConfig) So(err, ShouldBeNil) So(len(warnings), ShouldEqual, 0) }) Convey("the most recent threshold crossed should be used to create"+ " the warning", func() { // this host meets both notification warning thresholds host1 := &host.Host{ Id: "h1", ExpirationTime: time.Now().Add(time.Minute * 10), } testutil.HandleTestingErr(host1.Insert(), t, "error inserting host") warnings, err := spawnHostExpirationWarnings(testConfig) So(err, ShouldBeNil) So(len(warnings), ShouldEqual, 1) // execute the callback, make sure the correct threshold is set So(warnings[0].callback(warnings[0].host, warnings[0].threshold), ShouldBeNil) host1, err = host.FindOne(host.ById("h1")) So(err, ShouldBeNil) So(host1.Notifications["120"], ShouldBeTrue) }) Convey("hosts that are quarantined or have already expired should not"+ " merit warnings", func() { // quarantined host host1 := &host.Host{ Id: "h1", Status: evergreen.HostQuarantined, ExpirationTime: time.Now().Add(time.Minute * 10), } testutil.HandleTestingErr(host1.Insert(), t, "error inserting host") // terminated host host2 := &host.Host{ Id: "h2", Status: evergreen.HostTerminated, ExpirationTime: time.Now().Add(time.Minute * 10), } testutil.HandleTestingErr(host2.Insert(), t, "error inserting host") // past the expiration. no warning needs to be sent since this host // is theoretically about to be terminated, at which time a // notification will be sent host3 := &host.Host{ Id: "h3", ExpirationTime: time.Now().Add(-time.Minute * 10), } testutil.HandleTestingErr(host3.Insert(), t, "error inserting host") warnings, err := spawnHostExpirationWarnings(testConfig) So(err, ShouldBeNil) So(len(warnings), ShouldEqual, 0) }) }) }
func reset(t *testing.T) { db.SetGlobalSessionProvider(db.SessionFactoryFromConfig(evergreen.TestConfig())) testutil.HandleTestingErr( db.ClearCollections(model.TasksCollection, model.TestLogCollection), t, "error clearing test collections") }
func TestSetTaskActivated(t *testing.T) { Convey("With a task and build", t, func() { testutil.HandleTestingErr( db.ClearCollections(TasksCollection, build.Collection, host.Collection), t, "Error clearing test collections") taskId := "t1" buildId := "b1" testTime := time.Now() task := &Task{ Id: taskId, ScheduledTime: testTime, BuildId: buildId, DependsOn: []Dependency{ {"t2", evergreen.TaskSucceeded}, {"t3", evergreen.TaskSucceeded}, }, } b := &build.Build{ Id: buildId, Tasks: []build.TaskCache{ {Id: taskId}, {Id: "t2"}, {Id: "t3"}, }, } dep1 := &Task{ Id: "t2", ScheduledTime: testTime, BuildId: buildId, } dep2 := &Task{ Id: "t3", ScheduledTime: testTime, BuildId: buildId, } So(dep1.Insert(), ShouldBeNil) So(dep2.Insert(), ShouldBeNil) So(task.Insert(), ShouldBeNil) So(b.Insert(), ShouldBeNil) Convey("setting the test to active will update relevant db fields", func() { So(SetTaskActivated(taskId, "", true), ShouldBeNil) dbTask, err := FindTask(taskId) So(err, ShouldBeNil) So(dbTask.Activated, ShouldBeTrue) So(dbTask.ScheduledTime, ShouldHappenWithin, oneMs, testTime) // make sure the dependencies were activated dbDepOne, err := FindTask(dep1.Id) So(err, ShouldBeNil) So(dbDepOne.Activated, ShouldBeTrue) dbDepTwo, err := FindTask(dep2.Id) So(err, ShouldBeNil) So(dbDepTwo.Activated, ShouldBeTrue) Convey("and setting active to false will reset the relevant fields", func() { So(SetTaskActivated(taskId, "", false), ShouldBeNil) dbTask, err := FindTask(taskId) So(err, ShouldBeNil) So(dbTask.Activated, ShouldBeFalse) So(dbTask.ScheduledTime, ShouldHappenWithin, oneMs, ZeroTime) }) }) }) }
func TestFlaggingIdleHosts(t *testing.T) { testConfig := evergreen.TestConfig() db.SetGlobalSessionProvider(db.SessionFactoryFromConfig(testConfig)) Convey("When flagging idle hosts to be terminated", t, func() { // reset the db testutil.HandleTestingErr(db.ClearCollections(host.Collection), t, "error clearing hosts collection") Convey("hosts currently running a task should never be"+ " flagged", func() { // insert a host that is currently running a task - but whose // creation time would otherwise indicate it has been idle a while host1 := host.Host{ Id: "h1", Provider: mock.ProviderName, CreationTime: time.Now().Add(-30 * time.Minute), RunningTask: "t1", Status: evergreen.HostRunning, StartedBy: evergreen.User, } testutil.HandleTestingErr(host1.Insert(), t, "error inserting host") // finding idle hosts should not return the host idle, err := flagIdleHosts(nil, nil) So(err, ShouldBeNil) So(len(idle), ShouldEqual, 0) }) Convey("hosts not currently running a task should be flagged if they"+ " have been idle at least 15 minutes and will incur a payment in"+ " less than 10 minutes", func() { // insert two hosts - one whose last task was more than 15 minutes // ago, one whose last task was less than 15 minutes ago host1 := host.Host{ Id: "h1", Provider: mock.ProviderName, LastTaskCompleted: "t1", LastTaskCompletedTime: time.Now().Add(-time.Minute * 20), Status: evergreen.HostRunning, StartedBy: evergreen.User, } testutil.HandleTestingErr(host1.Insert(), t, "error inserting host") host2 := host.Host{ Id: "h2", Provider: mock.ProviderName, LastTaskCompleted: "t2", LastTaskCompletedTime: time.Now().Add(-time.Minute * 5), Status: evergreen.HostRunning, StartedBy: evergreen.User, } testutil.HandleTestingErr(host2.Insert(), t, "error inserting host") // finding idle hosts should only return the first host idle, err := flagIdleHosts(nil, nil) So(err, ShouldBeNil) So(len(idle), ShouldEqual, 1) So(idle[0].Id, ShouldEqual, "h1") }) }) }
func TestMarkAsDispatched(t *testing.T) { var ( taskId string hostId string buildId string task *Task myHost *host.Host b *build.Build ) Convey("With a task", t, func() { taskId = "t1" hostId = "h1" buildId = "b1" task = &Task{ Id: taskId, BuildId: buildId, } myHost = &host.Host{ Id: hostId, } b = &build.Build{ Id: buildId, Tasks: []build.TaskCache{ {Id: taskId}, }, } testutil.HandleTestingErr( db.ClearCollections(TasksCollection, build.Collection, host.Collection), t, "Error clearing test collections") So(task.Insert(), ShouldBeNil) So(myHost.Insert(), ShouldBeNil) So(b.Insert(), ShouldBeNil) Convey("when marking the task as dispatched, the fields for"+ " the task, the host it is on, and the build it is a part of"+ " should be set to reflect this", func() { // mark the task as dispatched So(task.MarkAsDispatched(myHost, time.Now()), ShouldBeNil) // make sure the task's fields were updated, both in memory and // in the db So(task.DispatchTime, ShouldNotResemble, time.Unix(0, 0)) So(task.Status, ShouldEqual, evergreen.TaskDispatched) So(task.HostId, ShouldEqual, myHost.Id) So(task.LastHeartbeat, ShouldResemble, task.DispatchTime) task, err := FindTask(taskId) So(err, ShouldBeNil) So(task.DispatchTime, ShouldNotResemble, time.Unix(0, 0)) So(task.Status, ShouldEqual, evergreen.TaskDispatched) So(task.HostId, ShouldEqual, myHost.Id) So(task.LastHeartbeat, ShouldResemble, task.DispatchTime) // make sure the build's fields were updated in the db b, err = build.FindOne(build.ById(buildId)) So(err, ShouldBeNil) So(b.Tasks[0].Status, ShouldEqual, evergreen.TaskDispatched) }) }) }
func TestFlaggingExpiredHosts(t *testing.T) { testConfig := evergreen.TestConfig() db.SetGlobalSessionProvider(db.SessionFactoryFromConfig(testConfig)) Convey("When flagging expired hosts to be terminated", t, func() { // reset the db testutil.HandleTestingErr(db.ClearCollections(host.Collection), t, "error clearing hosts collection") Convey("hosts started by the default user should be filtered"+ " out", func() { host1 := &host.Host{ Id: "h1", Status: evergreen.HostRunning, StartedBy: evergreen.User, } testutil.HandleTestingErr(host1.Insert(), t, "error inserting host") expired, err := flagExpiredHosts(nil, nil) So(err, ShouldBeNil) So(len(expired), ShouldEqual, 0) }) Convey("hosts that are terminated or quarantined should be filtered"+ " out", func() { host1 := &host.Host{ Id: "h1", Status: evergreen.HostQuarantined, } testutil.HandleTestingErr(host1.Insert(), t, "error inserting host") host2 := &host.Host{ Id: "h2", Status: evergreen.HostTerminated, } testutil.HandleTestingErr(host2.Insert(), t, "error inserting host") expired, err := flagExpiredHosts(nil, nil) So(err, ShouldBeNil) So(len(expired), ShouldEqual, 0) }) Convey("hosts should be returned if their expiration threshold has"+ " been reached", func() { // not expired host1 := &host.Host{ Id: "h1", Status: evergreen.HostRunning, ExpirationTime: time.Now().Add(time.Minute * 10), } testutil.HandleTestingErr(host1.Insert(), t, "error inserting host") // expired host2 := &host.Host{ Id: "h2", Status: evergreen.HostRunning, ExpirationTime: time.Now().Add(-time.Minute * 10), } testutil.HandleTestingErr(host2.Insert(), t, "error inserting host") expired, err := flagExpiredHosts(nil, nil) So(err, ShouldBeNil) So(len(expired), ShouldEqual, 1) So(expired[0].Id, ShouldEqual, "h2") }) }) }