예제 #1
0
파일: task.go 프로젝트: jcooklin/snap
func (s *Server) addTask(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {

	tr, err := marshalTask(r.Body)
	if err != nil {
		respond(500, rbody.FromError(err), w)
		return
	}

	sch, err := makeSchedule(tr.Schedule)
	if err != nil {
		respond(500, rbody.FromError(err), w)
		return
	}

	var opts []core.TaskOption
	if tr.Deadline != "" {
		dl, err := time.ParseDuration(tr.Deadline)
		if err != nil {
			respond(500, rbody.FromError(err), w)
			return
		}
		opts = append(opts, core.TaskDeadlineDuration(dl))
	}

	if tr.Name != "" {
		opts = append(opts, core.SetTaskName(tr.Name))
	}
	opts = append(opts, core.OptionStopOnFailure(10))

	task, errs := s.mt.CreateTask(sch, tr.Workflow, tr.Start, opts...)
	if errs != nil && len(errs.Errors()) != 0 {
		var errMsg string
		for _, e := range errs.Errors() {
			errMsg = errMsg + e.Error() + " -- "
		}
		respond(500, rbody.FromError(errors.New(errMsg[:len(errMsg)-4])), w)
		return
	}

	taskB := rbody.AddSchedulerTaskFromTask(task)
	taskB.Href = taskURI(r.Host, task)
	respond(201, taskB, w)
}
예제 #2
0
파일: task_test.go 프로젝트: Collinux/snap
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())
			})

		})

	})
}
예제 #3
0
파일: tribe_test.go 프로젝트: IRCody/snap
func (t *mockTask) Option(...core.TaskOption) core.TaskOption { return core.TaskDeadlineDuration(0) }
예제 #4
0
func TestScheduler(t *testing.T) {
	log.SetLevel(log.FatalLevel)
	Convey("NewTask", t, func() {
		c := new(mockMetricManager)
		c.setAcceptedContentType("machine", core.ProcessorPluginType, 1, []string{"snap.*", "snap.gob", "foo.bar"})
		c.setReturnedContentType("machine", core.ProcessorPluginType, 1, []string{"snap.gob"})
		c.setAcceptedContentType("rmq", core.PublisherPluginType, -1, []string{"snap.json", "snap.gob"})
		c.setAcceptedContentType("file", core.PublisherPluginType, -1, []string{"snap.json"})
		cfg := GetDefaultConfig()
		s := New(cfg)
		s.SetMetricManager(c)
		w := wmap.NewWorkflowMap()
		// Collection node
		w.CollectNode.AddMetric("/foo/bar", 1)
		w.CollectNode.AddMetric("/foo/baz", 2)
		w.CollectNode.AddConfigItem("/foo/bar", "username", "root")
		w.CollectNode.AddConfigItem("/foo/bar", "port", 8080)
		w.CollectNode.AddConfigItem("/foo/bar", "ratio", 0.32)
		w.CollectNode.AddConfigItem("/foo/bar", "yesorno", true)

		// Add a process node
		pr1 := wmap.NewProcessNode("machine", 1)
		pr1.AddConfigItem("username", "wat")
		pr1.AddConfigItem("howmuch", 9999)

		// Add a process node
		pr12 := wmap.NewProcessNode("machine", 1)
		pr12.AddConfigItem("username", "wat2")
		pr12.AddConfigItem("howmuch", 99992)

		// Publish node for our process node
		pu1 := wmap.NewPublishNode("rmq", -1)
		pu1.AddConfigItem("birthplace", "dallas")
		pu1.AddConfigItem("monies", 2)

		// Publish node direct to collection
		pu2 := wmap.NewPublishNode("file", -1)
		pu2.AddConfigItem("color", "brown")
		pu2.AddConfigItem("purpose", 42)

		pr12.Add(pu2)
		pr1.Add(pr12)
		w.CollectNode.Add(pr1)
		w.CollectNode.Add(pu1)

		e := s.Start()
		So(e, ShouldBeNil)
		t, te := s.CreateTask(schedule.NewSimpleSchedule(time.Second*1), w, false)
		So(te.Errors(), ShouldBeEmpty)

		for _, i := range t.(*task).workflow.processNodes {
			testInboundContentType(i)
		}
		for _, i := range t.(*task).workflow.publishNodes {
			testInboundContentType(i)
		}
		So(t.(*task).workflow.processNodes[0].ProcessNodes[0].PublishNodes[0].InboundContentType, ShouldEqual, "snap.json")

		Convey("returns errors when metrics do not validate", func() {
			c.failValidatingMetrics = true
			c.failValidatingMetricsAfter = 1
			_, err := s.CreateTask(schedule.NewSimpleSchedule(time.Second*1), w, false)
			So(err, ShouldNotBeNil)
			fmt.Printf("%d", len(err.Errors()))
			So(len(err.Errors()), ShouldBeGreaterThan, 0)
			So(err.Errors()[0], ShouldResemble, serror.New(errors.New("metric validation error")))

		})

		Convey("returns an error when scheduler started and MetricManager is not set", func() {
			s1 := New(GetDefaultConfig())
			err := s1.Start()
			So(err, ShouldNotBeNil)
			fmt.Printf("%v", err)
			So(err, ShouldResemble, ErrMetricManagerNotSet)

		})

		Convey("returns an error when wrong namespace is given wo workflowmap ", func() {
			w.CollectNode.AddMetric("****/&&&", 3)
			w.CollectNode.AddConfigItem("****/&&&", "username", "user")
			_, err := s.CreateTask(schedule.NewSimpleSchedule(time.Second*1), w, false)

			So(len(err.Errors()), ShouldBeGreaterThan, 0)

		})

		// TODO NICK
		Convey("returns an error when a schedule does not validate", func() {
			s1 := New(GetDefaultConfig())
			s1.Start()
			_, err := s1.CreateTask(schedule.NewSimpleSchedule(time.Second*1), w, false)
			So(err, ShouldNotBeNil)
			So(len(err.Errors()), ShouldBeGreaterThan, 0)
			So(err.Errors()[0], ShouldResemble, serror.New(ErrSchedulerNotStarted))
			s1.metricManager = c
			s1.Start()
			_, err1 := s1.CreateTask(schedule.NewSimpleSchedule(time.Second*0), w, false)
			So(err1.Errors()[0].Error(), ShouldResemble, "Interval must be greater than 0")

		})

		// 		// TODO NICK
		Convey("create a task", func() {
			tsk, err := s.CreateTask(schedule.NewSimpleSchedule(time.Second*5), w, false)
			So(len(err.Errors()), ShouldEqual, 0)
			So(tsk, ShouldNotBeNil)
			So(tsk.(*task).deadlineDuration, ShouldResemble, DefaultDeadlineDuration)
			So(len(s.GetTasks()), ShouldEqual, 2)
			Convey("error when attempting to add duplicate task", func() {
				err := s.tasks.add(tsk.(*task))
				So(err, ShouldNotBeNil)

			})
			Convey("get created task", func() {
				t, err := s.GetTask(tsk.ID())
				So(err, ShouldBeNil)
				So(t, ShouldEqual, tsk)
			})
			Convey("error when attempting to get a task that doesn't exist", func() {
				t, err := s.GetTask("1234")
				So(err, ShouldNotBeNil)
				So(t, ShouldBeNil)
			})
			Convey("stop a stopped task", func() {
				err := s.StopTask(tsk.ID())
				So(len(err), ShouldEqual, 1)
				So(err[0].Error(), ShouldEqual, "Task is already stopped.")
			})
		})

		// 		// // TODO NICK
		Convey("returns a task with a 6 second deadline duration", func() {
			tsk, err := s.CreateTask(schedule.NewSimpleSchedule(time.Second*6), w, false, core.TaskDeadlineDuration(6*time.Second))
			So(len(err.Errors()), ShouldEqual, 0)
			So(tsk.(*task).deadlineDuration, ShouldResemble, time.Duration(6*time.Second))
			prev := tsk.(*task).Option(core.TaskDeadlineDuration(1 * time.Second))
			So(tsk.(*task).deadlineDuration, ShouldResemble, time.Duration(1*time.Second))
			tsk.(*task).Option(prev)
			So(tsk.(*task).deadlineDuration, ShouldResemble, time.Duration(6*time.Second))
		})

		Convey("Enable a stopped task", func() {
			tsk, _ := s.CreateTask(schedule.NewSimpleSchedule(time.Millisecond*100), w, false)
			So(tsk, ShouldNotBeNil)

			_, err := s.EnableTask(tsk.ID())
			So(err, ShouldNotBeNil)
		})

		Convey("Enable a disabled task", func() {
			tsk, _ := s.CreateTask(schedule.NewSimpleSchedule(time.Millisecond*100), w, false)
			So(tsk, ShouldNotBeNil)

			t := s.tasks.Get(tsk.ID())
			t.state = core.TaskDisabled

			etsk, err1 := s.EnableTask(tsk.ID())
			So(err1, ShouldBeNil)
			So(etsk.State(), ShouldEqual, core.TaskStopped)
		})
		Convey("Start disabled task", func() {
			tsk, _ := s.CreateTask(schedule.NewSimpleSchedule(time.Millisecond*100), w, false)
			So(tsk, ShouldNotBeNil)

			t := s.tasks.Get(tsk.ID())
			t.state = core.TaskDisabled

			err := s.StartTask(tsk.ID())
			So(err[0].Error(), ShouldResemble, "Task is disabled. Cannot be started.")
			So(t.state, ShouldEqual, core.TaskDisabled)
		})
	})
	Convey("Stop()", t, func() {
		Convey("Should set scheduler state to SchedulerStopped", func() {
			scheduler := New(GetDefaultConfig())
			c := new(mockMetricManager)
			scheduler.metricManager = c
			scheduler.Start()
			scheduler.Stop()
			So(scheduler.state, ShouldEqual, schedulerStopped)
		})
	})
	Convey("SetMetricManager()", t, func() {
		Convey("Should set metricManager for scheduler", func() {
			scheduler := New(GetDefaultConfig())
			c := new(mockMetricManager)
			scheduler.SetMetricManager(c)
			So(scheduler.metricManager, ShouldEqual, c)
		})
	})

}