func (tm *TaskMaster) CreateTICKScope() *tick.Scope { scope := tick.NewScope() scope.Set("influxql", newInfluxQL()) scope.Set("time", func(d time.Duration) time.Duration { return d }) // Add dynamic methods to the scope for UDFs if tm.UDFService != nil { for _, f := range tm.UDFService.FunctionList() { f := f info, _ := tm.UDFService.FunctionInfo(f) scope.SetDynamicMethod( f, tick.DynamicMethod(func(self interface{}, args ...interface{}) (interface{}, error) { parent, ok := self.(pipeline.Node) if !ok { return nil, fmt.Errorf("cannot call %s on %T", f, self) } udf := pipeline.NewUDF( parent, f, info.Commander, info.Timeout, info.Wants, info.Provides, info.Options, ) return udf, nil }), ) } } return scope }
func NewTask(name, script string, tt TaskType, dbrps []DBRP) (*Task, error) { t := &Task{ Name: name, Type: tt, DBRPs: dbrps, } var srcEdge pipeline.EdgeType switch tt { case StreamTask: srcEdge = pipeline.StreamEdge case BatchTask: srcEdge = pipeline.BatchEdge } scope := tick.NewScope() scope.Set("influxql", newInfluxQL()) scope.Set("time", func(d time.Duration) time.Duration { return d }) p, err := pipeline.CreatePipeline(script, srcEdge, scope) if err != nil { return nil, err } t.Pipeline = p return t, nil }
func ExampleEvaluate() { //Run a test that evaluates the DSL against the Process struct. script := ` //Name the parent parent.name('parent') // Spawn a first child var child1 = parent.spawn() // Name the first child child1.name('child1') //Spawn a grandchild and name it child1.spawn().name('grandchild') //Spawn a second child and name it parent.spawn().name('child2') ` scope := tick.NewScope() parent := &Process{} scope.Set("parent", parent) err := tick.Evaluate(script, scope) if err != nil { fmt.Println(err) } fmt.Println(parent) // Output: {"parent" [{"child1" [{"grandchild" []}]} {"child2" []}]} }
func TestEvaluate(t *testing.T) { assert := assert.New(t) //Run a test that evaluates the DSL against the above structures. script := ` var s2 = a.structB() .field1('f1') .field2(42) s2.field3(15m) s2.structC() .options('c', 21.5, 7h) .aggFunc(influxql.agg.sum) ` scope := tick.NewScope() a := &structA{} scope.Set("a", a) i := &influxql{ Agg: &agg{ Sum: aggSum, }, } scope.Set("influxql", i) err := tick.Evaluate(script, scope) if err != nil { t.Fatal(err) } s2I, err := scope.Get("s2") if err != nil { t.Fatal(err) } s2 := s2I.(*structB) assert.NotNil(s2) assert.Equal("f1", s2.Field1) assert.Equal(int64(42), s2.Field2) assert.Equal(time.Minute*15, s2.Field3) s3 := s2.c if assert.NotNil(s3) { assert.Equal("c", s3.field1) assert.Equal(21.5, s3.field2) assert.Equal(time.Hour*7, s3.field3) if assert.NotNil(s3.AggFunc) { assert.Equal([]float64{10.0}, s3.AggFunc([]float64{5, 5})) } } }
func mergeFieldsAndTags(fields models.Fields, tags map[string]string) (*tick.Scope, error) { scope := tick.NewScope() for k, v := range fields { if _, ok := tags[k]; ok { return nil, fmt.Errorf("cannot have field and tags with same name %q", k) } scope.Set(k, v) } for k, v := range tags { scope.Set(k, v) } return scope, nil }
func TestEvaluate_DynamicMethod(t *testing.T) { script := `var x = a.dynamicMethod(1,'str', 10s).sad(FALSE)` scope := tick.NewScope() a := &structA{} scope.Set("a", a) dm := func(self interface{}, args ...interface{}) (interface{}, error) { a, ok := self.(*structA) if !ok { return nil, fmt.Errorf("cannot call dynamicMethod on %T", self) } o := &orphan{ parent: a, Sad: true, args: args, } return o, nil } scope.SetDynamicMethod("dynamicMethod", dm) err := tick.Evaluate(script, scope) if err != nil { t.Fatal(err) } xI, err := scope.Get("x") if err != nil { t.Fatal(err) } x, ok := xI.(*orphan) if !ok { t.Fatalf("expected x to be an *orphan, got %T", xI) } if x.Sad { t.Errorf("expected x to not be sad") } if got, exp := len(x.args), 3; exp != got { t.Fatalf("unexpected number of args: got %d exp %d", got, exp) } if got, exp := x.args[0], int64(1); exp != got { t.Errorf("unexpected x.args[0]: got %v exp %d", got, exp) } if got, exp := x.args[1], "str"; exp != got { t.Errorf("unexpected x.args[1]: got %v exp %s", got, exp) } if got, exp := x.args[2], time.Second*10; exp != got { t.Errorf("unexpected x.args[1]: got %v exp %v", got, exp) } }
func mergeFieldsAndTags(now time.Time, fields models.Fields, tags models.Tags) (*tick.Scope, error) { scope := tick.NewScope() scope.Set("time", now.Local()) for k, v := range fields { if _, ok := tags[k]; ok { return nil, fmt.Errorf("cannot have field and tags with same name %q", k) } scope.Set(k, v) } for k, v := range tags { scope.Set(k, v) } return scope, nil }
func TestTICK_To_Pipeline_MultiLine(t *testing.T) { assert := assert.New(t) var tickScript = ` var w = stream.window() w.period(10s) w.every(1s) ` scope := tick.NewScope() p, err := CreatePipeline(tickScript, StreamEdge, scope) assert.Nil(err) assert.NotNil(p) assert.Equal(1, len(p.Source.Children())) w, ok := p.Source.Children()[0].(*WindowNode) if assert.True(ok) { assert.Equal(time.Duration(10)*time.Second, w.Period) assert.Equal(time.Duration(1)*time.Second, w.Every) } }
func TestTICK_To_Pipeline_MultiLine(t *testing.T) { var tickScript = ` var w = stream.from().window() w.period(10s) w.every(1s) ` d := deadman{} scope := tick.NewScope() p, err := CreatePipeline(tickScript, StreamEdge, scope, d) if err != nil { t.Fatal(err) } if p == nil { t.Fatal("unexpected pipeline, got nil") } if exp, got := 1, len(p.sources); exp != got { t.Errorf("unexpected number of pipeline sources: exp %d got %d", exp, got) } if exp, got := 1, len(p.sources[0].Children()); exp != got { t.Errorf("unexpected number of source0 children: exp %d got %d", exp, got) } sn, ok := p.sources[0].Children()[0].(*StreamNode) if !ok { t.Fatalf("unexpected node type: exp StreamNode got %T", p.sources[0].Children()[0]) } w, ok := sn.Children()[0].(*WindowNode) if !ok { t.Fatalf("unexpected node type: exp WindowNode got %T", sn.Children()[0]) } if exp, got := time.Duration(10)*time.Second, w.Period; exp != got { t.Errorf("unexpected window period exp %v got %v", exp, got) } if exp, got := time.Duration(1)*time.Second, w.Every; exp != got { t.Errorf("unexpected window every exp %v got %v", exp, got) } }
func TestEvaluate_Vars(t *testing.T) { script := ` var x = 3m var y = -x var n = TRUE var m = !n ` scope := tick.NewScope() err := tick.Evaluate(script, scope) if err != nil { t.Fatal(err) } x, err := scope.Get("x") if err != nil { t.Fatal(err) } if value, ok := x.(time.Duration); ok { if exp, got := time.Minute*3, value; exp != got { t.Errorf("unexpected x value: exp %v got %v", exp, got) } } else { t.Errorf("unexpected x value type: exp time.Duration got %T", x) } y, err := scope.Get("y") if err != nil { t.Fatal(err) } if value, ok := y.(time.Duration); ok { if exp, got := time.Minute*-3, value; exp != got { t.Errorf("unexpected y value: exp %v got %v", exp, got) } } else { t.Errorf("unexpected y value type: exp time.Duration got %T", x) } n, err := scope.Get("n") if err != nil { t.Fatal(err) } if value, ok := n.(bool); ok { if exp, got := true, value; exp != got { t.Errorf("unexpected n value: exp %v got %v", exp, got) } } else { t.Errorf("unexpected m value type: exp bool got %T", x) } m, err := scope.Get("m") if err != nil { t.Fatal(err) } if value, ok := m.(bool); ok { if exp, got := false, value; exp != got { t.Errorf("unexpected m value: exp %v got %v", exp, got) } } else { t.Errorf("unexpected m value type: exp bool got %T", x) } }