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  }