github.com/billybanfield/evergreen@v0.0.0-20170525200750-eeee692790f7/scheduler/scheduler_test.go (about) 1 package scheduler 2 3 import ( 4 "testing" 5 6 "github.com/evergreen-ci/evergreen" 7 "github.com/evergreen-ci/evergreen/cloud/providers/mock" 8 "github.com/evergreen-ci/evergreen/db" 9 "github.com/evergreen-ci/evergreen/model" 10 "github.com/evergreen-ci/evergreen/model/distro" 11 "github.com/evergreen-ci/evergreen/model/host" 12 "github.com/evergreen-ci/evergreen/model/task" 13 "github.com/evergreen-ci/evergreen/model/version" 14 "github.com/evergreen-ci/evergreen/testutil" 15 "github.com/mongodb/grip" 16 "github.com/pkg/errors" 17 . "github.com/smartystreets/goconvey/convey" 18 ) 19 20 var schedulerTestConf = testutil.TestConfig() 21 22 func init() { 23 db.SetGlobalSessionProvider(db.SessionFactoryFromConfig(schedulerTestConf)) 24 grip.CatchError(grip.SetSender(testutil.SetupTestSender(schedulerTestConf.Scheduler.LogFile))) 25 } 26 27 const versionProjectString = ` 28 buildvariants: 29 - name: ubuntu 30 display_name: ubuntu1404 31 run_on: 32 - ubuntu1404-test 33 expansions: 34 mongo_url: http://fastdl.mongodb.org/linux/mongodb-linux-x86_64-2.6.1.tgz 35 tasks: 36 - name: agent 37 - name: plugin 38 - name: model 39 tasks: 40 - name: agent 41 - name: plugin 42 - name: model 43 ` 44 45 // mock implementations, for testing purposes 46 47 type MockTaskFinder struct{} 48 49 func (self *MockTaskFinder) FindRunnableTasks() ([]task.Task, error) { 50 return nil, errors.New("FindRunnableTasks not implemented") 51 } 52 53 type MockTaskPrioritizer struct{} 54 55 func (self *MockTaskPrioritizer) PrioritizeTasks(settings *evergreen.Settings, 56 tasks []task.Task) ([]task.Task, error) { 57 return nil, errors.New("PrioritizeTasks not implemented") 58 } 59 60 type MockTaskQueuePersister struct{} 61 62 func (self *MockTaskQueuePersister) PersistTaskQueue(distro string, 63 tasks []task.Task, 64 projectTaskDuration model.ProjectTaskDurations) ([]model.TaskQueueItem, error) { 65 return nil, errors.New("PersistTaskQueue not implemented") 66 } 67 68 type MockTaskDurationEstimator struct{} 69 70 func (self *MockTaskDurationEstimator) GetExpectedDurations( 71 runnableTasks []task.Task) (model.ProjectTaskDurations, error) { 72 return model.ProjectTaskDurations{}, errors.New("GetExpectedDurations not " + 73 "implemented") 74 } 75 76 type MockHostAllocator struct{} 77 78 func (self *MockHostAllocator) NewHostsNeeded(d HostAllocatorData, s *evergreen.Settings) ( 79 map[string]int, error) { 80 return nil, errors.New("NewHostsNeeded not implemented") 81 } 82 83 func TestUpdateVersionBuildVarMap(t *testing.T) { 84 Convey("When updating a version build variant mapping... ", t, func() { 85 versionBuildVarMap := make(map[versionBuildVariant]model.BuildVariant) 86 schedulerInstance := &Scheduler{ 87 schedulerTestConf, 88 &MockTaskFinder{}, 89 &MockTaskPrioritizer{}, 90 &MockTaskDurationEstimator{}, 91 &MockTaskQueuePersister{}, 92 &MockHostAllocator{}, 93 } 94 95 Convey("if there are no versions with the given id, an error should "+ 96 "be returned", func() { 97 err := schedulerInstance.updateVersionBuildVarMap("versionStr", versionBuildVarMap) 98 So(err, ShouldNotBeNil) 99 }) 100 101 Convey("if there is a version with the given id, no error should "+ 102 "be returned and the map should be updated", func() { 103 v := &version.Version{ 104 Id: "versionStr", 105 Config: versionProjectString, 106 } 107 108 // insert the test version 109 So(v.Insert(), ShouldBeNil) 110 key := versionBuildVariant{"versionStr", "ubuntu"} 111 err := schedulerInstance.updateVersionBuildVarMap("versionStr", versionBuildVarMap) 112 So(err, ShouldBeNil) 113 114 // check versionBuildVariant map 115 buildVariant, ok := versionBuildVarMap[key] 116 So(ok, ShouldBeTrue) 117 So(buildVariant, ShouldNotBeNil) 118 119 // check buildvariant tasks 120 So(len(buildVariant.Tasks), ShouldEqual, 3) 121 }) 122 123 Reset(func() { 124 So(db.Clear(version.Collection), ShouldBeNil) 125 }) 126 127 }) 128 129 } 130 131 func TestSpawnHosts(t *testing.T) { 132 133 Convey("When spawning hosts", t, func() { 134 135 distroIds := []string{"d1", "d2", "d3"} 136 137 schedulerInstance := &Scheduler{ 138 schedulerTestConf, 139 &MockTaskFinder{}, 140 &MockTaskPrioritizer{}, 141 &MockTaskDurationEstimator{}, 142 &MockTaskQueuePersister{}, 143 &MockHostAllocator{}, 144 } 145 146 Convey("if there are no hosts to be spawned, the Scheduler should not"+ 147 " make any calls to the CloudManager", func() { 148 newHostsNeeded := map[string]int{ 149 distroIds[0]: 0, 150 distroIds[1]: 0, 151 distroIds[2]: 0, 152 } 153 154 newHostsSpawned, err := schedulerInstance.spawnHosts(newHostsNeeded) 155 So(err, ShouldBeNil) 156 So(len(newHostsSpawned[distroIds[0]]), ShouldEqual, 0) 157 So(len(newHostsSpawned[distroIds[1]]), ShouldEqual, 0) 158 So(len(newHostsSpawned[distroIds[2]]), ShouldEqual, 0) 159 }) 160 161 Convey("if there are hosts to be spawned, the Scheduler should make"+ 162 " one call to the CloudManager for each host, and return the"+ 163 " results bucketed by distro", func() { 164 165 newHostsNeeded := map[string]int{ 166 distroIds[0]: 3, 167 distroIds[1]: 0, 168 distroIds[2]: 1, 169 } 170 171 for _, id := range distroIds { 172 d := distro.Distro{Id: id, PoolSize: 3, Provider: mock.ProviderName} 173 So(d.Insert(), ShouldBeNil) 174 } 175 176 newHostsSpawned, err := schedulerInstance.spawnHosts(newHostsNeeded) 177 So(err, ShouldBeNil) 178 distroZeroHosts := newHostsSpawned[distroIds[0]] 179 distroOneHosts := newHostsSpawned[distroIds[1]] 180 distroTwoHosts := newHostsSpawned[distroIds[2]] 181 So(len(distroZeroHosts), ShouldEqual, 3) 182 So(distroZeroHosts[0].Distro.Id, ShouldEqual, distroIds[0]) 183 So(distroZeroHosts[1].Distro.Id, ShouldEqual, distroIds[0]) 184 So(distroZeroHosts[2].Distro.Id, ShouldEqual, distroIds[0]) 185 So(len(distroOneHosts), ShouldEqual, 0) 186 So(len(distroTwoHosts), ShouldEqual, 1) 187 So(distroTwoHosts[0].Distro.Id, ShouldEqual, distroIds[2]) 188 }) 189 190 Reset(func() { 191 So(db.Clear(distro.Collection), ShouldBeNil) 192 So(db.Clear(host.Collection), ShouldBeNil) 193 }) 194 }) 195 }