func TestTask(t *testing.T) { log.SetLevel(log.FatalLevel) Convey("Task", t, func() { sampleWFMap := wmap.Sample() wf, errs := wmapToWorkflow(sampleWFMap) So(errs, ShouldBeEmpty) c := &mockMetricManager{} c.setAcceptedContentType("rabbitmq", core.PublisherPluginType, 5, []string{plugin.SnapGOBContentType}) mgrs := newManagers(c) err := wf.BindPluginContentTypes(&mgrs) So(err, ShouldBeNil) Convey("task + simple schedule", func() { sch := schedule.NewSimpleSchedule(time.Millisecond * 100) task, err := newTask(sch, wf, newWorkManager(), c, emitter) So(err, ShouldBeNil) task.Spin() time.Sleep(time.Millisecond * 10) // it is a race so we slow down the test So(task.state, ShouldEqual, core.TaskSpinning) task.Stop() }) Convey("Task specified-name test", func() { sch := schedule.NewSimpleSchedule(time.Millisecond * 100) task, err := newTask(sch, wf, newWorkManager(), c, emitter, core.SetTaskName("My name is unique")) So(err, ShouldBeNil) task.Spin() So(task.GetName(), ShouldResemble, "My name is unique") }) Convey("Task default-name test", func() { sch := schedule.NewSimpleSchedule(time.Millisecond * 100) task, err := newTask(sch, wf, newWorkManager(), c, emitter) So(err, ShouldBeNil) task.Spin() So(task.GetName(), ShouldResemble, "Task-"+task.ID()) }) Convey("Task deadline duration test", func() { sch := schedule.NewSimpleSchedule(time.Millisecond * 100) task, err := newTask(sch, wf, newWorkManager(), c, emitter, core.TaskDeadlineDuration(20*time.Second)) So(err, ShouldBeNil) task.Spin() So(task.deadlineDuration, ShouldEqual, 20*time.Second) task.Option(core.TaskDeadlineDuration(20 * time.Second)) So(core.TaskDeadlineDuration(2*time.Second), ShouldNotBeEmpty) }) Convey("Tasks are created and creation of task table is checked", func() { sch := schedule.NewSimpleSchedule(time.Millisecond * 100) task, err := newTask(sch, wf, newWorkManager(), c, emitter) So(err, ShouldBeNil) task1, err := newTask(sch, wf, newWorkManager(), c, emitter) So(err, ShouldBeNil) task1.Spin() task.Spin() tC := newTaskCollection() tC.add(task) tC.add(task1) taskTable := tC.Table() So(len(taskTable), ShouldEqual, 2) }) Convey("Task is created and starts to spin", func() { sch := schedule.NewSimpleSchedule(time.Second * 5) task, err := newTask(sch, wf, newWorkManager(), c, emitter) So(err, ShouldBeNil) task.Spin() So(task.state, ShouldEqual, core.TaskSpinning) Convey("Task is Stopped", func() { task.Stop() time.Sleep(time.Millisecond * 10) // it is a race so we slow down the test So(task.state, ShouldEqual, core.TaskStopped) }) }) Convey("task fires", func() { sch := schedule.NewSimpleSchedule(time.Nanosecond * 100) task, err := newTask(sch, wf, newWorkManager(), c, emitter) So(err, ShouldBeNil) task.Spin() time.Sleep(time.Millisecond * 50) So(task.hitCount, ShouldBeGreaterThan, 2) So(task.missedIntervals, ShouldBeGreaterThan, 2) task.Stop() }) Convey("Enable a running task", func() { sch := schedule.NewSimpleSchedule(time.Millisecond * 10) task, err := newTask(sch, wf, newWorkManager(), c, emitter) So(err, ShouldBeNil) task.Spin() err = task.Enable() So(err, ShouldNotBeNil) So(task.State(), ShouldEqual, core.TaskSpinning) }) Convey("Enable a disabled task", func() { sch := schedule.NewSimpleSchedule(time.Millisecond * 10) task, err := newTask(sch, wf, newWorkManager(), c, emitter) So(err, ShouldBeNil) task.state = core.TaskDisabled err = task.Enable() So(err, ShouldBeNil) So(task.State(), ShouldEqual, core.TaskStopped) }) }) Convey("Create task collection", t, func() { sampleWFMap := wmap.Sample() wf, errs := wmapToWorkflow(sampleWFMap) So(errs, ShouldBeEmpty) sch := schedule.NewSimpleSchedule(time.Millisecond * 10) task, err := newTask(sch, wf, newWorkManager(), &mockMetricManager{}, emitter) So(err, ShouldBeNil) So(task.id, ShouldNotBeEmpty) So(task.id, ShouldNotBeNil) taskCollection := newTaskCollection() Convey("Add task to collection", func() { err := taskCollection.add(task) So(err, ShouldBeNil) So(len(taskCollection.table), ShouldEqual, 1) Convey("Attempt to add the same task again", func() { err := taskCollection.add(task) So(err, ShouldNotBeNil) }) Convey("Get task from collection", func() { t := taskCollection.Get(task.id) So(t, ShouldNotBeNil) So(t.ID(), ShouldEqual, task.id) So(t.CreationTime().Nanosecond(), ShouldBeLessThan, time.Now().Nanosecond()) So(t.HitCount(), ShouldEqual, 0) So(t.MissedCount(), ShouldEqual, 0) So(t.State(), ShouldEqual, core.TaskStopped) So(t.Status(), ShouldEqual, core.WorkflowStopped) So(t.LastRunTime().IsZero(), ShouldBeTrue) }) Convey("Attempt to get task with an invalid Id", func() { t := taskCollection.Get("1234") So(t, ShouldBeNil) }) Convey("Create another task and compare the id", func() { task2, err := newTask(sch, wf, newWorkManager(), &mockMetricManager{}, emitter) So(err, ShouldBeNil) So(task2.id, ShouldNotEqual, task.ID()) }) }) }) }
func CheckTablet(t *testing.T, ts topo.Server) { cell := getLocalCell(t, ts) tablet := &topo.Tablet{ Alias: topo.TabletAlias{Cell: cell, Uid: 1}, Hostname: "localhost", IPAddr: "10.11.12.13", Portmap: map[string]int{ "vt": 3333, "mysql": 3334, }, Tags: map[string]string{"tag": "value"}, Keyspace: "test_keyspace", Type: topo.TYPE_MASTER, State: topo.STATE_READ_WRITE, KeyRange: newKeyRange("-10"), } if err := ts.CreateTablet(tablet); err != nil { t.Errorf("CreateTablet: %v", err) } if err := ts.CreateTablet(tablet); err != topo.ErrNodeExists { t.Errorf("CreateTablet(again): %v", err) } if _, err := ts.GetTablet(topo.TabletAlias{Cell: cell, Uid: 666}); err != topo.ErrNoNode { t.Errorf("GetTablet(666): %v", err) } ti, err := ts.GetTablet(tablet.Alias) if err != nil { t.Errorf("GetTablet %v: %v", tablet.Alias, err) } if eq, err := tabletEqual(ti.Tablet, tablet); err != nil { t.Errorf("cannot compare tablets: %v", err) } else if !eq { t.Errorf("put and got tablets are not identical:\n%#v\n%#v", tablet, ti.Tablet) } if _, err := ts.GetTabletsByCell("666"); err != topo.ErrNoNode { t.Errorf("GetTabletsByCell(666): %v", err) } inCell, err := ts.GetTabletsByCell(cell) if err != nil { t.Errorf("GetTabletsByCell: %v", err) } if len(inCell) != 1 || inCell[0] != tablet.Alias { t.Errorf("GetTabletsByCell: want [%v], got %v", tablet.Alias, inCell) } ti.State = topo.STATE_READ_ONLY if err := topo.UpdateTablet(ts, ti); err != nil { t.Errorf("UpdateTablet: %v", err) } ti, err = ts.GetTablet(tablet.Alias) if err != nil { t.Errorf("GetTablet %v: %v", tablet.Alias, err) } if want := topo.STATE_READ_ONLY; ti.State != want { t.Errorf("ti.State: want %v, got %v", want, ti.State) } if err := ts.UpdateTabletFields(tablet.Alias, func(t *topo.Tablet) error { t.State = topo.STATE_READ_WRITE return nil }); err != nil { t.Errorf("UpdateTabletFields: %v", err) } ti, err = ts.GetTablet(tablet.Alias) if err != nil { t.Errorf("GetTablet %v: %v", tablet.Alias, err) } if want := topo.STATE_READ_WRITE; ti.State != want { t.Errorf("ti.State: want %v, got %v", want, ti.State) } if err := ts.DeleteTablet(tablet.Alias); err != nil { t.Errorf("DeleteTablet: %v", err) } if err := ts.DeleteTablet(tablet.Alias); err != topo.ErrNoNode { t.Errorf("DeleteTablet(again): %v", err) } if _, err := ts.GetTablet(tablet.Alias); err != topo.ErrNoNode { t.Errorf("GetTablet: expected error, tablet was deleted: %v", err) } }