func (s *MySuite) TestMerge(c *C) { input := []*oproto.ValueStream{ &oproto.ValueStream{ Variable: variable.NewFromString("/test{host=a}").AsProto(), Value: []*oproto.Value{ &oproto.Value{Timestamp: 1, DoubleValue: 1.0}, &oproto.Value{Timestamp: 4, DoubleValue: 4.0}, }, }, &oproto.ValueStream{ Variable: variable.NewFromString("/test{host=b}").AsProto(), Value: []*oproto.Value{ &oproto.Value{Timestamp: 2, DoubleValue: 2.0}, &oproto.Value{Timestamp: 5, DoubleValue: 5.0}, }, }, &oproto.ValueStream{ Variable: variable.NewFromString("/test{host=c}").AsProto(), Value: []*oproto.Value{ &oproto.Value{Timestamp: 3, DoubleValue: 3.0}, &oproto.Value{Timestamp: 6, DoubleValue: 6.0}, }, }, } outCount, err := checkValueOrder(Merge(input)) if err != nil { c.Error(err) } c.Check(outCount, Equals, 6) }
func (s *MySuite) TestMeanByTwoLabels(c *C) { input := []*oproto.ValueStream{ <-s.store.Reader(context.Background(), variable.NewFromString("/test{host=a,job=foo,other=w}")), <-s.store.Reader(context.Background(), variable.NewFromString("/test{host=a,job=bar,other=x}")), <-s.store.Reader(context.Background(), variable.NewFromString("/test{host=b,job=foo,other=y}")), <-s.store.Reader(context.Background(), variable.NewFromString("/test{host=b,job=bar,other=z}")), } output := aggregations.Mean([]string{"host", "job"}, input) c.Assert(output, Not(IsNil)) c.Assert(len(output), Equals, 4) // Check that there are 4 output streams with the correct number of output labels checkHostsAndJobs(c, output, 2, 2, 2, 2) }
func ListVariables(ctx context.Context, ds *datastore.Datastore, w http.ResponseWriter, req *http.Request) { prefix := req.FormValue("p") if prefix == "" { prefix = "/*" } if prefix[len(prefix)-1] != '*' { prefix = prefix + "*" } v := variable.NewFromString(prefix) vars := make(map[string]*oproto.StreamVariable) for stream := range ds.Reader(ctx, v) { vars[stream.Variable.Name] = stream.Variable } if len(vars) == 0 { w.WriteHeader(404) return } w.WriteHeader(200) keys := make([]string, len(vars)) i := 0 for k := range vars { keys[i] = k i++ } sort.Strings(keys) out, _ := json.Marshal(keys) w.Header().Set("Content-Type", "text/json") w.Write(out) }
func (s *MySuite) TestRatio(c *C) { ctx, cancel := context.WithCancel(context.Background()) e := NewExporter(ctx, s.Client, 10*time.Second) r := NewRatio(e, variable.NewFromString("/test/ratio")) for i := 0; i < 10; i++ { r.Success() } for i := 0; i < 5; i++ { r.Failure() } // Force export streams := e.GetStreams() c.Assert(len(streams), Equals, 3) for _, stream := range streams { switch variable.ProtoToString(stream.Variable) { case "/test/ratio-success": c.Check(stream.Value[0].DoubleValue, Equals, 10.0) case "/test/ratio-failure": c.Check(stream.Value[0].DoubleValue, Equals, 5.0) case "/test/ratio-total": c.Check(stream.Value[0].DoubleValue, Equals, 15.0) default: fmt.Printf("Invalid variable %s", variable.ProtoToString(stream.Variable)) c.Fail() } } cancel() <-ctx.Done() }
func (s *MySuite) TestDefaultDropPolicy(c *C) { policyTxt := ` interval: 3600 policy { comment: "Throw everything away" policy: DROP } ` policyProto := &oproto.RetentionPolicy{} c.Assert(proto.UnmarshalText(policyTxt, policyProto), IsNil) policy := New(policyProto) input := &oproto.ValueStream{ Variable: variable.NewFromString("/test/foo/bar").AsProto(), Value: []*oproto.Value{}, } for i := 0; i < 10; i++ { input.Value = append(input.Value, &oproto.Value{Timestamp: uint64(i), DoubleValue: 1.1}) } output := policy.Apply(input) for _, value := range output.Value { log.Printf("Got output when none was expected: %s", value) c.Fail() } }
func (s *MySuite) TestTimer(c *C) { ctx, cancel := context.WithCancel(context.Background()) e := NewExporter(ctx, s.Client, 10*time.Second) t := NewTimer(e, variable.NewFromString("/test/timer")) t.Start() time.Sleep(10 * time.Millisecond) t.Stop() t.Start() time.Sleep(10 * time.Millisecond) t.Stop() // Force export streams := e.GetStreams() c.Assert(len(streams), Equals, 2) for _, stream := range streams { switch variable.ProtoToString(stream.Variable) { case "/test/timer-total-count": c.Check((stream.Value[0].DoubleValue >= 20.0 && stream.Value[0].DoubleValue <= 25.0), Equals, true) case "/test/timer-overall-sum": c.Check(stream.Value[0].DoubleValue, Equals, 2.0) default: fmt.Printf("Invalid variable %s", variable.ProtoToString(stream.Variable)) c.Fail() } } cancel() <-ctx.Done() }
func (s *MySuite) TestAverage(c *C) { ctx, cancel := context.WithCancel(context.Background()) e := NewExporter(ctx, s.Client, 10*time.Second) a := NewAverage(e, variable.NewFromString("/test/average")) a.Update(95, 1) a.Update(100, 1) a.Update(105, 1) // Force export streams := e.GetStreams() c.Assert(len(streams), Equals, 2) for _, stream := range streams { switch variable.ProtoToString(stream.Variable) { case "/test/average-total-count": c.Check(stream.Value[0].DoubleValue, Equals, 300.0) case "/test/average-overall-sum": c.Check(stream.Value[0].DoubleValue, Equals, 3.0) default: fmt.Printf("Invalid variable %s", variable.ProtoToString(stream.Variable)) c.Fail() } } cancel() <-ctx.Done() }
func main() { log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile) flag.Parse() conn, err := grpc.Dial(*connectAddress, grpc.WithInsecure()) if err != nil { log.Fatalf("Error connecting to %s: %s", *connectAddress, err) } defer conn.Close() request := &oproto.LookupBlockRequest{} if *varName != "" { request.Variable = variable.NewFromString(*varName).AsProto() } else if *ID != "" { request.BlockId = *ID } else if len(os.Args) > 1 { request.BlockId = os.Args[1] } else { log.Fatal("Specify either --variable or --id") } stub := oproto.NewStoreClient(conn) response, err := stub.LookupBlock(context.Background(), request) if err != nil { log.Fatal(err) } log.Println(openinstrument.ProtoText(response)) }
func (s *MySuite) TestMergeBy(c *C) { input := []*oproto.ValueStream{ &oproto.ValueStream{ Variable: variable.NewFromString("/test{host=a,other=x}").AsProto(), Value: []*oproto.Value{ &oproto.Value{Timestamp: 1, DoubleValue: 1.0}, &oproto.Value{Timestamp: 4, DoubleValue: 4.0}, }, }, &oproto.ValueStream{ Variable: variable.NewFromString("/test{host=b,other=y}").AsProto(), Value: []*oproto.Value{ &oproto.Value{Timestamp: 2, DoubleValue: 2.0}, &oproto.Value{Timestamp: 5, DoubleValue: 5.0}, }, }, &oproto.ValueStream{ Variable: variable.NewFromString("/test{host=a,other=z}").AsProto(), Value: []*oproto.Value{ &oproto.Value{Timestamp: 3, DoubleValue: 3.0}, &oproto.Value{Timestamp: 6, DoubleValue: 6.0}, }, }, } numSets := 0 for streams := range MergeBy(input, "host") { stv := variable.NewFromProto(streams[0].Variable) if stv.Match(variable.NewFromString("/test{host=a}")) { c.Assert(len(streams), Equals, 2) outCount, err := checkValueOrder(Merge(streams)) if err != nil { c.Error(err) } c.Check(outCount, Equals, 4) } else { c.Check(len(streams), Equals, 1) outCount, err := checkValueOrder(Merge(streams)) if err != nil { c.Error(err) } c.Check(outCount, Equals, 2) } numSets++ } c.Check(numSets, Equals, 2) }
func (s *MySuite) TestSignedRate(c *C) { for input := range s.store.Reader(context.Background(), variable.NewFromString("/test")) { output := mutations.SignedRate(input) for _, v := range output.Value { checkValue(c, v, v.Timestamp, float64(1)/float64(3)) } } }
func (s *MySuite) TestInterpolate(c *C) { for input := range s.store.Reader(context.Background(), variable.NewFromString("/test/offset")) { output := mutations.Interpolate(300, input) checkValue(c, output.Value[0], 0, float64(20)) checkValue(c, output.Value[1], 300, float64(121.81818181818181)) checkValue(c, output.Value[2], 600, float64(191.86046511627907)) checkValue(c, output.Value[3], 900, float64(258.37209302325584)) } }
func (s *MySuite) TestMeanBy(c *C) { input := []*oproto.ValueStream{ <-s.store.Reader(context.Background(), variable.NewFromString("/test{host=a,job=foo,other=w}")), <-s.store.Reader(context.Background(), variable.NewFromString("/test{host=a,job=bar,other=x}")), <-s.store.Reader(context.Background(), variable.NewFromString("/test{host=b,job=foo,other=y}")), <-s.store.Reader(context.Background(), variable.NewFromString("/test{host=b,job=bar,other=z}")), } output := aggregations.Mean([]string{"host"}, input) c.Assert(output, Not(IsNil)) c.Assert(len(output), Equals, 2) // Check that there are two output streams, as there are two distinct hosts checkHostsAndJobs(c, output, 1, 1, 0, 0) for _, stream := range output { c.Assert(len(stream.Value), Equals, 11) if stream.Variable.Label["host"] == "a" { checkValue(c, stream.Value[0], 60*0, float64((20*1+20*1)/2)) checkValue(c, stream.Value[1], 60*1, float64((20*2+20*2)/2)) checkValue(c, stream.Value[2], 60*2, float64((20*3+20*3)/2)) checkValue(c, stream.Value[3], 60*3, float64((20*4+20*4)/2)) checkValue(c, stream.Value[4], 60*4, float64((20*5+20*5)/2)) checkValue(c, stream.Value[5], 60*5, float64((20*6+20*6)/2)) checkValue(c, stream.Value[6], 60*6, float64((20*7+20*7)/2)) checkValue(c, stream.Value[7], 60*7, float64((20*8+20*8)/2)) checkValue(c, stream.Value[8], 60*8, float64((20*9+20*9)/2)) checkValue(c, stream.Value[9], 60*9, float64((20*10+20*10)/2)) checkValue(c, stream.Value[10], 60*10, float64((20*11+20*11)/2)) } else if stream.Variable.Label["host"] == "b" { checkValue(c, stream.Value[0], 60*0, float64((40*1+40*1)/2)) checkValue(c, stream.Value[1], 60*1, float64((40*2+40*2)/2)) checkValue(c, stream.Value[2], 60*2, float64((40*3+40*3)/2)) checkValue(c, stream.Value[3], 60*3, float64((40*4+40*4)/2)) checkValue(c, stream.Value[4], 60*4, float64((40*5+40*5)/2)) checkValue(c, stream.Value[5], 60*5, float64((40*6+40*6)/2)) checkValue(c, stream.Value[6], 60*6, float64((40*7+40*7)/2)) checkValue(c, stream.Value[7], 60*7, float64((40*8+40*8)/2)) checkValue(c, stream.Value[8], 60*8, float64((40*9+40*9)/2)) checkValue(c, stream.Value[9], 60*9, float64((40*10+40*10)/2)) checkValue(c, stream.Value[10], 60*10, float64((40*11+40*11)/2)) } else { c.Fail() } } }
func (s *MySuite) TestMin(c *C) { for input := range s.store.Reader(context.Background(), variable.NewFromString("/test")) { output := mutations.Min(120, input) checkValue(c, output.Value[0], 0, 20*1) checkValue(c, output.Value[1], 120, 20*3) checkValue(c, output.Value[2], 240, 20*5) checkValue(c, output.Value[3], 360, 20*7) checkValue(c, output.Value[4], 480, 20*9) } }
func (s *MySuite) TestMax(c *C) { for input := range s.store.Reader(context.Background(), variable.NewFromString("/test")) { output := mutations.Max(120, input) checkValue(c, output.Value[0], 60*2, 20*3) checkValue(c, output.Value[1], 60*4, 20*5) checkValue(c, output.Value[2], 60*6, 20*7) checkValue(c, output.Value[3], 60*8, 20*9) checkValue(c, output.Value[4], 60*10, 20*11) } }
func (s *MySuite) TestMeanByJob(c *C) { input := []*oproto.ValueStream{ <-s.store.Reader(context.Background(), variable.NewFromString("/test{host=a,job=foo,other=w}")), <-s.store.Reader(context.Background(), variable.NewFromString("/test{host=a,job=bar,other=x}")), <-s.store.Reader(context.Background(), variable.NewFromString("/test{host=b,job=foo,other=y}")), <-s.store.Reader(context.Background(), variable.NewFromString("/test{host=b,job=bar,other=z}")), } output := aggregations.Mean([]string{"job"}, input) c.Assert(output, Not(IsNil)) c.Assert(len(output), Equals, 2) // Check that there are two output streams, as there are two distinct hosts checkHostsAndJobs(c, output, 0, 0, 1, 1) // First stream is job=foo stream := output[0] c.Assert(len(stream.Value), Equals, 11) checkValue(c, stream.Value[0], 60*0, float64((20*1+40*1)/2)) checkValue(c, stream.Value[1], 60*1, float64((20*2+40*2)/2)) checkValue(c, stream.Value[2], 60*2, float64((20*3+40*3)/2)) checkValue(c, stream.Value[3], 60*3, float64((20*4+40*4)/2)) checkValue(c, stream.Value[4], 60*4, float64((20*5+40*5)/2)) checkValue(c, stream.Value[5], 60*5, float64((20*6+40*6)/2)) checkValue(c, stream.Value[6], 60*6, float64((20*7+40*7)/2)) checkValue(c, stream.Value[7], 60*7, float64((20*8+40*8)/2)) checkValue(c, stream.Value[8], 60*8, float64((20*9+40*9)/2)) checkValue(c, stream.Value[9], 60*9, float64((20*10+40*10)/2)) checkValue(c, stream.Value[10], 60*10, float64((20*11+40*11)/2)) // Second stream is job=bar stream = output[1] c.Assert(len(stream.Value), Equals, 11) checkValue(c, stream.Value[0], 60*0, float64((20*1+40*1)/2)) checkValue(c, stream.Value[1], 60*1, float64((20*2+40*2)/2)) checkValue(c, stream.Value[2], 60*2, float64((20*3+40*3)/2)) checkValue(c, stream.Value[3], 60*3, float64((20*4+40*4)/2)) checkValue(c, stream.Value[4], 60*4, float64((20*5+40*5)/2)) checkValue(c, stream.Value[5], 60*5, float64((20*6+40*6)/2)) checkValue(c, stream.Value[6], 60*6, float64((20*7+40*7)/2)) checkValue(c, stream.Value[7], 60*7, float64((20*8+40*8)/2)) checkValue(c, stream.Value[8], 60*8, float64((20*9+40*9)/2)) checkValue(c, stream.Value[9], 60*9, float64((20*10+40*10)/2)) checkValue(c, stream.Value[10], 60*10, float64((20*11+40*11)/2)) }
func (s *MySuite) TestFirst(c *C) { for input := range s.store.Reader(context.Background(), variable.NewFromString("/test")) { output := mutations.First(120, input) c.Assert(len(output.Value), Equals, 6) checkValue(c, output.Value[0], 60*0, 20*1) checkValue(c, output.Value[1], 60*2, 20*3) checkValue(c, output.Value[2], 60*4, 20*5) checkValue(c, output.Value[3], 60*6, 20*7) checkValue(c, output.Value[4], 60*8, 20*9) checkValue(c, output.Value[5], 60*10, 20*11) } }
func runAddLoadtest(ctx context.Context, conn client.Client) { log.Println("Running ADD load test") in, out, err := conn.Add(ctx) if err != nil { log.Printf("Error starting Add RPC: %s", err) return } defer close(in) sem := make(semaphore, 1000) var sent, received int go func() { tick := time.Tick(1 * time.Second) for { select { case <-out: received++ sem.V(1) case <-tick: log.Printf("Sent %d, received %d in the last second, latency %0.02fms", sent, received, 1.0/float64(received)*1000.0) received = 0 sent = 0 } } }() for { select { case <-ctx.Done(): return default: } sem.P(1) v := variable.NewFromString("/test/var1{host=rage}").AsProto() request := &oproto.AddRequest{ Stream: []*oproto.ValueStream{ { Variable: v, Value: []*oproto.Value{ { Timestamp: openinstrument.NowMs(), DoubleValue: 1.0, }, }, }, }, } in <- request sent++ } log.Println("Complete") }
func MergeBy(streams []*oproto.ValueStream, by string) <-chan []*oproto.ValueStream { c := make(chan []*oproto.ValueStream) go func() { uniqueVars := make(map[string]bool) uniqueLabels := make(map[string]bool) for _, stream := range streams { v := variable.NewFromProto(stream.Variable) uniqueVars[v.Variable] = true labelValue, ok := v.Labels[by] if !ok { uniqueLabels[""] = true } else { uniqueLabels[labelValue] = true } } for varname := range uniqueVars { v := variable.NewFromString(varname) if by == "" { var output []*oproto.ValueStream for _, stream := range streams { testvar := variable.NewFromProto(stream.Variable) if testvar.Variable != v.Variable { continue } output = append(output, stream) } if len(output) > 0 { c <- output } } else { for labelvalue := range uniqueLabels { var output []*oproto.ValueStream for _, stream := range streams { testvar := variable.NewFromProto(stream.Variable) if testvar.Variable != v.Variable { continue } value, ok := testvar.Labels[by] if ok && value == labelvalue { output = append(output, stream) } } if len(output) > 0 { c <- output } } } } close(c) }() return c }
func runSlowAddLoadtest(ctx context.Context) { log.Println("Running ADD load test") var sent, received int go func() { tick := time.Tick(1 * time.Second) for { select { case <-tick: log.Printf("Sent %d, received %d in the last second, latency %0.02fms", sent, received, 1.0/float64(received)*1000.0) received = 0 sent = 0 } } }() for { conn, err := client.NewRpcClient(ctx, *connectAddress) if err != nil { log.Fatalf("Error connecting to %s: %s", *connectAddress, err) } in, out, err := conn.Add(ctx) if err != nil { log.Printf("Error starting Add RPC: %s", err) return } v := variable.NewFromString("/test/var1{host=rage}").AsProto() request := &oproto.AddRequest{ Stream: []*oproto.ValueStream{ { Variable: v, Value: []*oproto.Value{ { Timestamp: openinstrument.NowMs(), DoubleValue: 1.0, }, }, }, }, } in <- request close(in) sent++ <-out received++ conn.Close() } log.Println("Complete") }
func (s *MySuite) TestFloat(c *C) { ctx, cancel := context.WithCancel(context.Background()) e := NewExporter(ctx, s.Client, 10*time.Second) f := NewFloat(e, variable.NewFromString("/test/float")) f.Set(100.0) // Force export streams := e.GetStreams() c.Assert(len(streams), Equals, 1) c.Check(variable.ProtoToString(streams[0].Variable), Equals, "/test/float") c.Check(streams[0].Value[0].DoubleValue, Equals, 100.0) cancel() <-ctx.Done() }
func (s *MySuite) TestMean(c *C) { input := []*oproto.ValueStream{ <-s.store.Reader(context.Background(), variable.NewFromString("/test{host=a}")), <-s.store.Reader(context.Background(), variable.NewFromString("/test{host=b}")), } output := aggregations.Mean(nil, input) c.Assert(output, Not(IsNil)) c.Assert(len(output), Equals, 1) stream := output[0] c.Assert(len(stream.Value), Equals, 11) checkValue(c, stream.Value[0], 60*0, float64((20*1+40*1)/2)) checkValue(c, stream.Value[1], 60*1, float64((20*2+40*2)/2)) checkValue(c, stream.Value[2], 60*2, float64((20*3+40*3)/2)) checkValue(c, stream.Value[3], 60*3, float64((20*4+40*4)/2)) checkValue(c, stream.Value[4], 60*4, float64((20*5+40*5)/2)) checkValue(c, stream.Value[5], 60*5, float64((20*6+40*6)/2)) checkValue(c, stream.Value[6], 60*6, float64((20*7+40*7)/2)) checkValue(c, stream.Value[7], 60*7, float64((20*8+40*8)/2)) checkValue(c, stream.Value[8], 60*8, float64((20*9+40*9)/2)) checkValue(c, stream.Value[9], 60*9, float64((20*10+40*10)/2)) checkValue(c, stream.Value[10], 60*10, float64((20*11+40*11)/2)) }
func (s *MySuite) TestStdDev(c *C) { input := []*oproto.ValueStream{ <-s.store.Reader(context.Background(), variable.NewFromString("/test{host=a}")), <-s.store.Reader(context.Background(), variable.NewFromString("/test{host=b}")), } output := aggregations.StdDev(nil, input) c.Assert(output, Not(IsNil)) c.Assert(len(output), Equals, 1) stream := output[0] c.Assert(len(stream.Value), Equals, 11) checkValue(c, stream.Value[0], 60*0, 10.0) checkValue(c, stream.Value[1], 60*1, 20.0) checkValue(c, stream.Value[2], 60*2, 30.0) checkValue(c, stream.Value[3], 60*3, 40.0) checkValue(c, stream.Value[4], 60*4, 50.0) checkValue(c, stream.Value[5], 60*5, 60.0) checkValue(c, stream.Value[6], 60*6, 70.0) checkValue(c, stream.Value[7], 60*7, 80.0) checkValue(c, stream.Value[8], 60*8, 90.0) checkValue(c, stream.Value[9], 60*9, 100.0) checkValue(c, stream.Value[10], 60*10, 110.0) }
func (s *MySuite) TestDropByValue(c *C) { policyTxt := ` interval: 3600 policy { variable: { name: "/system/filesystem/*", label { key: "device" value: "/@zfs-auto-snap/" } } policy: DROP } policy { policy: KEEP } ` policyProto := &oproto.RetentionPolicy{} c.Assert(proto.UnmarshalText(policyTxt, policyProto), IsNil) policy := New(policyProto) //log.Println(policyProto) // Device not matching regexp is kept input := &oproto.ValueStream{ Variable: variable.NewFromString("/system/filesystem/available{device=r2/home}").AsProto(), Value: []*oproto.Value{{Timestamp: uint64(1), DoubleValue: 1.0}}, } c.Check(len(policy.Apply(input).Value), Equals, 1) // Device matching regexp is dropped input = &oproto.ValueStream{ Variable: variable.NewFromString("/system/filesystem/used{device=r2/home@zfs-auto-snap_hourly}").AsProto(), Value: []*oproto.Value{{Timestamp: uint64(1), DoubleValue: 1.0}}, } c.Check(len(policy.Apply(input).Value), Equals, 0) }
func (s *MySuite) TestMovingAverage(c *C) { for input := range s.store.Reader(context.Background(), variable.NewFromString("/test")) { output := mutations.MovingAverage(120, input) // Length should be 2 less than the input, as there is no moving average across the first two elements c.Assert(len(output.Value), Equals, len(input.Value)-2) checkValue(c, output.Value[0], 60*2, 40) checkValue(c, output.Value[1], 60*3, 60) checkValue(c, output.Value[2], 60*4, 80) checkValue(c, output.Value[3], 60*5, 100) checkValue(c, output.Value[4], 60*6, 120) checkValue(c, output.Value[5], 60*7, 140) checkValue(c, output.Value[6], 60*8, 160) checkValue(c, output.Value[7], 60*9, 180) checkValue(c, output.Value[8], 60*10, 200) } }
func (s *MySuite) TestMean(c *C) { for input := range s.store.Reader(context.Background(), variable.NewFromString("/test")) { output := mutations.Mean(input) checkValue(c, output.Value[0], 60*0, float64((20*0+20*1)/2)) checkValue(c, output.Value[1], 60*1, float64((20*1+20*2)/2)) checkValue(c, output.Value[2], 60*2, float64((20*2+20*3)/2)) checkValue(c, output.Value[3], 60*3, float64((20*3+20*4)/2)) checkValue(c, output.Value[4], 60*4, float64((20*4+20*5)/2)) checkValue(c, output.Value[5], 60*5, float64((20*5+20*6)/2)) checkValue(c, output.Value[6], 60*6, float64((20*6+20*7)/2)) checkValue(c, output.Value[7], 60*7, float64((20*7+20*8)/2)) checkValue(c, output.Value[8], 60*8, float64((20*8+20*9)/2)) checkValue(c, output.Value[9], 60*9, float64((20*9+20*10)/2)) checkValue(c, output.Value[10], 60*10, float64((20*10+20*11)/2)) } }
func (s *MySuite) TestAgeKeepPolicy(c *C) { return // TODO(dparrish): Re-enable this when it works policyTxt := ` interval: 1 policy { comment: "Throw everything away" variable { name: "/test/foo*" min_timestamp: -91 max_timestamp: -75 } policy: KEEP } # Implicit DROP ` policyProto := &oproto.RetentionPolicy{} c.Assert(proto.UnmarshalText(policyTxt, policyProto), IsNil) policy := New(policyProto) input := &oproto.ValueStream{ Variable: variable.NewFromString("/test/foo/bar").AsProto(), Value: []*oproto.Value{}, } now := openinstrument.NowMs() for i := 1; i <= 10; i++ { input.Value = append(input.Value, &oproto.Value{ Timestamp: now - uint64(98-3*i), EndTimestamp: now - uint64(100-3*i), DoubleValue: 1.1, }) } output := policy.Apply(input) count := 0 for _, value := range output.Value { age := now - value.Timestamp if age < 75 || age > 91 { log.Printf("Got value outside expected age (%d)", age) c.Fail() continue } count++ } c.Check(count, Equals, 5) }
func (s *MySuite) TestDivide(c *C) { for input := range s.store.Reader(context.Background(), variable.NewFromString("/test")) { output := mutations.Multiply(1.0/2.0, input) c.Assert(len(output.Value), Equals, len(input.Value)) checkValue(c, output.Value[0], 60*0, (20*1)/2.0) checkValue(c, output.Value[1], 60*1, (20*2)/2.0) checkValue(c, output.Value[2], 60*2, (20*3)/2.0) checkValue(c, output.Value[3], 60*3, (20*4)/2.0) checkValue(c, output.Value[4], 60*4, (20*5)/2.0) checkValue(c, output.Value[5], 60*5, (20*6)/2.0) checkValue(c, output.Value[6], 60*6, (20*7)/2.0) checkValue(c, output.Value[7], 60*7, (20*8)/2.0) checkValue(c, output.Value[8], 60*8, (20*9)/2.0) checkValue(c, output.Value[9], 60*9, (20*10)/2.0) checkValue(c, output.Value[10], 60*10, (20*11)/2.0) } }
func (s *MySuite) TestAdd(c *C) { for input := range s.store.Reader(context.Background(), variable.NewFromString("/test")) { output := mutations.Add(5, input) c.Assert(len(output.Value), Equals, len(input.Value)) checkValue(c, output.Value[0], 60*0, 20*1+5) checkValue(c, output.Value[1], 60*1, 20*2+5) checkValue(c, output.Value[2], 60*2, 20*3+5) checkValue(c, output.Value[3], 60*3, 20*4+5) checkValue(c, output.Value[4], 60*4, 20*5+5) checkValue(c, output.Value[5], 60*5, 20*6+5) checkValue(c, output.Value[6], 60*6, 20*7+5) checkValue(c, output.Value[7], 60*7, 20*8+5) checkValue(c, output.Value[8], 60*8, 20*9+5) checkValue(c, output.Value[9], 60*9, 20*10+5) checkValue(c, output.Value[10], 60*10, 20*11+5) } }
func (s *MySuite) TestSubtract(c *C) { for input := range s.store.Reader(context.Background(), variable.NewFromString("/test")) { output := mutations.Add(-5, input) c.Assert(len(output.Value), Equals, len(input.Value)) checkValue(c, output.Value[0], 60*0, 20*1-5) checkValue(c, output.Value[1], 60*1, 20*2-5) checkValue(c, output.Value[2], 60*2, 20*3-5) checkValue(c, output.Value[3], 60*3, 20*4-5) checkValue(c, output.Value[4], 60*4, 20*5-5) checkValue(c, output.Value[5], 60*5, 20*6-5) checkValue(c, output.Value[6], 60*6, 20*7-5) checkValue(c, output.Value[7], 60*7, 20*8-5) checkValue(c, output.Value[8], 60*8, 20*9-5) checkValue(c, output.Value[9], 60*9, 20*10-5) checkValue(c, output.Value[10], 60*10, 20*11-5) } }
func (s *MySuite) TestPower(c *C) { for input := range s.store.Reader(context.Background(), variable.NewFromString("/test")) { output := mutations.Power(2, input) c.Assert(len(output.Value), Equals, len(input.Value)) checkValue(c, output.Value[0], 60*0, math.Pow(20*1, 2)) checkValue(c, output.Value[1], 60*1, math.Pow(20*2, 2)) checkValue(c, output.Value[2], 60*2, math.Pow(20*3, 2)) checkValue(c, output.Value[3], 60*3, math.Pow(20*4, 2)) checkValue(c, output.Value[4], 60*4, math.Pow(20*5, 2)) checkValue(c, output.Value[5], 60*5, math.Pow(20*6, 2)) checkValue(c, output.Value[6], 60*6, math.Pow(20*7, 2)) checkValue(c, output.Value[7], 60*7, math.Pow(20*8, 2)) checkValue(c, output.Value[8], 60*8, math.Pow(20*9, 2)) checkValue(c, output.Value[9], 60*9, math.Pow(20*10, 2)) checkValue(c, output.Value[10], 60*10, math.Pow(20*11, 2)) } }