func TestSummarize(t *testing.T) { start := time.Date(2016, time.Month(1), 21, 0, 0, 0, 0, time.UTC) end := start.Add(36 * time.Hour) step := time.Hour NaN := math.NaN() ts1, err := ts.NewTimeSeriesOfTimeRange("ts1", start, end, step, 1) checkErr(t, err) if ts1 == nil { t.Errorf("FAIL(ts1): can't be nil, if we want to continue with other tests") return } ts1NaN, err := ts.NewTimeSeriesOfData("ts1NaN", start, step, []float64{ 1, NaN, 1, NaN, 1, NaN, 1, NaN, 1, NaN, 1, NaN, 1, NaN, 1, NaN, 1, NaN, 1, NaN, 1, NaN, 1, NaN, 1, NaN, 1, NaN, 1, NaN, 1, NaN, 1, NaN, 1, NaN, }) checkErr(t, err) if ts1NaN == nil { t.Errorf("FAIL(ts1NaN): can't be nil, if we want to continue with other tests") return } tss := []struct { Got *ts.TimeSeries Exp *TestSeries }{ { Got: Summarize(ts1, 24*time.Hour), Exp: &TestSeries{ Key: "Summarize(24h0m0s)(ts1)", Start: start, End: start.Add(2 * 24 * time.Hour), Step: 24 * time.Hour, Data: []float64{24, 12}, }, }, { Got: Summarize(ts1NaN, 24*time.Hour), Exp: &TestSeries{ Key: "Summarize(24h0m0s)(ts1NaN)", Start: start, End: start.Add(2 * 24 * time.Hour), Step: 24 * time.Hour, Data: []float64{12, 6}, }, }, } for _, pair := range tss { fmt.Printf("%s\n%s\n\n", pair.Got, pair.Exp) checkTimeSeries(t, pair.Got, pair.Exp) } //t.Errorf("here") }
func TestProperties(t *testing.T) { start := time.Date(2016, time.Month(1), 21, 0, 0, 0, 0, time.UTC) step := time.Hour NaN := math.NaN() ts1, err := ts.NewTimeSeriesOfData("ts1", start, step, []float64{1, 2, 3, 4, 5}) checkErr(t, err) tsNaN, err := ts.NewTimeSeriesOfData("tsNaN", start, step, []float64{1, 2, NaN, 4, 5}) checkErr(t, err) tests := []struct { f func(*ts.TimeSeries, func(float64) bool) bool ts *ts.TimeSeries pred func(float64) bool exp bool }{ { f: Any, ts: ts1, pred: EQ(5), exp: true, }, { f: Any, ts: ts1, pred: GT(5), exp: false, }, { f: None, ts: ts1, pred: GT(5), exp: true, }, { f: None, ts: ts1, pred: EQ(5), exp: false, }, { f: Any, ts: tsNaN, pred: EQNAN, exp: true, }, { f: None, ts: tsNaN, pred: EQNAN, exp: false, }, { f: Any, ts: tsNaN, pred: EQ(5), exp: true, }, { f: Any, ts: tsNaN, pred: GT(5), exp: false, }, { f: None, ts: tsNaN, pred: GT(5), exp: true, }, { f: None, ts: tsNaN, pred: EQ(5), exp: false, }, { f: None, ts: nil, pred: EQ(5), exp: false, }, } for i, test := range tests { got := test.f(test.ts, test.pred) if got != test.exp { fmt.Printf("FAIL(%d): got '%v' != '%v' exp\n", i, got, test.exp) t.Fail() } } }
func TestTransforms(t *testing.T) { start := time.Date(2016, time.Month(1), 14, 10, 0, 0, 0, time.UTC) end := start.Add(6 * time.Minute) step := time.Minute NaN := math.NaN() ts1, err := ts.NewTimeSeriesOfTimeRange("ts1", start, end, step, 1) checkErr(t, err) if ts1 == nil { t.Errorf("FAIL(ts1): can't be nil, if we want to continue with other tests") return } ts1NaN, err := ts.NewTimeSeriesOfData("ts1NaN", start, step, []float64{1, NaN, NaN, 1, 1, NaN}) checkErr(t, err) if ts1NaN == nil { t.Errorf("FAIL(ts1NaN): can't be nil, if we want to continue with other tests") return } tsRaise, err := ts.NewTimeSeriesOfData("tsRaise", start, step, []float64{NaN, 1, 1, 0, 1, NaN, 2, 2}) checkErr(t, err) if tsRaise == nil { t.Errorf("FAIL(tsRaise): can't be nil, if we want to continue with other tests") return } tss := []struct { Got *ts.TimeSeries Exp *TestSeries }{ { Got: ts1.Transform(&CumulativeSum{}), Exp: &TestSeries{ Key: "CumulativeSum(ts1)", Start: start, End: end, Step: step, Data: []float64{1, 2, 3, 4, 5, 6}, }, }, { Got: ts1NaN.Transform(&CumulativeSum{}), Exp: &TestSeries{ Key: "CumulativeSum(ts1NaN)", Start: start, End: end, Step: step, Data: []float64{1, 1, 1, 2, 3, 3}, }, }, { Got: ts1.Transform(&DivideBy{2}), Exp: &TestSeries{ Key: (&DivideBy{2}).Name() + "(ts1)", Start: start, End: end, Step: step, Data: []float64{0.5, 0.5, 0.5, 0.5, 0.5, 0.5}, }, }, { Got: ts1NaN.Transform(&DivideBy{2}), Exp: &TestSeries{ Key: (&DivideBy{2}).Name() + "(ts1NaN)", Start: start, End: end, Step: step, Data: []float64{0.5, NaN, NaN, 0.5, 0.5, NaN}, }, }, { Got: ts1.Transform(&MultiplyBy{2}), Exp: &TestSeries{ Key: (&MultiplyBy{2}).Name() + "(ts1)", Start: start, End: end, Step: step, Data: []float64{2, 2, 2, 2, 2, 2}, }, }, { Got: ts1NaN.Transform(&MultiplyBy{2}), Exp: &TestSeries{ Key: (&MultiplyBy{2}).Name() + "(ts1NaN)", Start: start, End: end, Step: step, Data: []float64{2, NaN, NaN, 2, 2, NaN}, }, }, { Got: tsRaise.Transform(&MarkRaise{}), Exp: &TestSeries{ Key: (&MarkRaise{}).Name() + "(tsRaise)", Start: start, End: start.Add(8 * step), Step: step, Data: []float64{NaN, 0, 0, 0, 1, NaN, 1, 0}, }, }, } for _, pair := range tss { fmt.Printf("%s\n%s\n\n", pair.Got, pair.Exp) checkTimeSeries(t, pair.Got, pair.Exp) } //t.Errorf("here") }
func (resp *Response) readLine(line []byte) (*ts.TimeSeries, error) { var key string var start, end time.Time var step time.Duration var data []float64 buf := bytes.NewBuffer(line) if header, err := buf.ReadBytes('|'); err != nil { return nil, err } else { header = header[:len(header)-1] headers := bytes.Split(header, []byte(",")) if len(headers) < 4 { resp.Error = errors.New("graphite data header size <= 4") return nil, resp.Error } key = string(bytes.Join(headers[:len(headers)-3], []byte(","))) startInt, err := strconv.ParseInt(string(headers[len(headers)-3]), 10, 64) if err != nil { return nil, errors.New("conv to int fail") } endInt, err := strconv.ParseInt(string(headers[len(headers)-2]), 10, 64) if err != nil { return nil, errors.New("conv to int fail") } step, err = time.ParseDuration(string(headers[len(headers)-1]) + "s") if err != nil { return nil, errors.New("step couldn't be determined") } start = time.Unix(startInt, 0).UTC() end = time.Unix(endInt, 0).UTC() points := end.Sub(start) / step data = make([]float64, points) } var err, errP error var point []byte for i := 0; err == nil; i++ { point, err = buf.ReadBytes(',') point = point[:len(point)-1] if bytes.Equal(point, []byte("None")) { data[i] = math.NaN() continue } data[i], errP = strconv.ParseFloat(string(point), 64) if errP != nil { resp.Error = errP return nil, errP } } if err != io.EOF { resp.Error = err return nil, resp.Error } return ts.NewTimeSeriesOfData(key, start, step, data) }