func TestGrowToDesiredAfterReconciliation(t *gotesting.T) { testScheduler := NewEtcdScheduler(3, 0, 0, true, []*mesos.CommandInfo_URI{}, false, 4096, 1, 256) reconciliation := map[string]string{ "etcd-1": "slave-1", "etcd-2": "slave-2", } testScheduler.reconciliationInfoFunc = func([]string, string, string) (map[string]string, error) { return reconciliation, nil } testScheduler.updateReconciliationInfoFunc = func(info map[string]string, _ []string, _ string, _ string) error { reconciliation = info return nil } testScheduler.masterInfo = util.NewMasterInfo("master-1", 0, 0) mockdriver := &MockSchedulerDriver{ runningStatuses: make(chan *mesos.TaskStatus, 10), scheduler: testScheduler, } testScheduler.state = Mutable testScheduler.healthCheck = func(map[string]*config.Node) error { return nil } // Push more than enough offers to shoot self in foot if unchecked. for _, offer := range []*mesos.Offer{ NewOffer("1"), NewOffer("2"), NewOffer("3"), } { testScheduler.offerCache.Push(offer) } memberList := config.ClusterMemberList{ Members: []httptypes.Member{ { ID: "1", Name: "etcd-1", PeerURLs: nil, ClientURLs: nil, }, { ID: "2", Name: "etcd-2", PeerURLs: nil, ClientURLs: nil, }, }, } _, port1, err := emtesting.NewTestEtcdServer(t, memberList) if err != nil { t.Fatalf("Failed to create test etcd server: %s", err) } _, port2, err := emtesting.NewTestEtcdServer(t, memberList) if err != nil { t.Fatalf("Failed to create test etcd server: %s", err) } // Valid reconciled tasks should be added to the running list. mockdriver.On( "ReconcileTasks", 0, ).Return(mesos.Status_DRIVER_RUNNING, nil).Once() for _, taskStatus := range []*mesos.TaskStatus{ util.NewTaskStatus( util.NewTaskID("etcd-1 localhost 0 "+strconv.Itoa(int(port1))+" 0"), mesos.TaskState_TASK_RUNNING, ), util.NewTaskStatus( util.NewTaskID("etcd-2 localhost 0 "+strconv.Itoa(int(port2))+" 0"), mesos.TaskState_TASK_RUNNING, ), } { mockdriver.runningStatuses <- taskStatus } // Scheduler should grow cluster to desired number of nodes. offer := NewOffer("1") mockdriver.On( "LaunchTasks", []*mesos.OfferID{ offer.Id, }, []*mesos.TaskInfo{ { Resources: []*mesos.Resource{ util.NewScalarResource("cpus", 1), util.NewScalarResource("mem", 256), util.NewScalarResource("disk", 4096), util.NewRangesResource("ports", []*mesos.Value_Range{ util.NewValueRange(uint64(0), uint64(2)), }), }, }, }, &mesos.Filters{ RefuseSeconds: proto.Float64(1), }, ).Return(mesos.Status_DRIVER_RUNNING, nil).Once() // Simulate failover, registration and time passing. mockdriver.ReconcileTasks([]*mesos.TaskStatus{}) testScheduler.launchOne(mockdriver) testScheduler.launchOne(mockdriver) testScheduler.launchOne(mockdriver) testScheduler.launchOne(mockdriver) testScheduler.launchOne(mockdriver) assert.Equal(t, 3, len(testScheduler.running), "Scheduler should reconcile tasks properly.") mockdriver.AssertExpectations(t) }
func TestMemberList(t *gotesting.T) { memberList := config.ClusterMemberList{ Members: []httptypes.Member{ { ID: "1", Name: "etcd-1", PeerURLs: nil, ClientURLs: nil, }, { ID: "2", Name: "etcd-2", PeerURLs: nil, ClientURLs: nil, }, { ID: "3", Name: "etcd-3", PeerURLs: nil, ClientURLs: nil, }, }, } _, port1, err := emtesting.NewTestEtcdServer(t, memberList) if err != nil { t.Fatalf("Failed to create test etcd server: %s", err) } _, port2, err := emtesting.NewTestEtcdServer(t, memberList) if err != nil { t.Fatalf("Failed to create test etcd server: %s", err) } _, port3, err := emtesting.NewTestEtcdServer(t, memberList) if err != nil { t.Fatalf("Failed to create test etcd server: %s", err) } running := map[string]*config.Node{ "1": { Name: "etcd-1", Host: "localhost", ClientPort: uint64(port1), }, "2": { Name: "etcd-2", Host: "localhost", ClientPort: uint64(port2), }, "3": { Name: "etcd-3", Host: "localhost", ClientPort: uint64(port3), }, } nameToIdent, err := MemberList(running) assert.Equal( t, reflect.DeepEqual( nameToIdent, map[string]string{ "etcd-1": "1", "etcd-2": "2", "etcd-3": "3", }, ), true, "MemberList should return the running instances.") }