1470 lines
		
	
	
		
			27 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			1470 lines
		
	
	
		
			27 KiB
		
	
	
	
		
			Go
		
	
	
	
package influx
 | 
						|
 | 
						|
import (
 | 
						|
	"fmt"
 | 
						|
	"testing"
 | 
						|
 | 
						|
	"github.com/stretchr/testify/require"
 | 
						|
)
 | 
						|
 | 
						|
type TestingHandler struct {
 | 
						|
	results []Result
 | 
						|
}
 | 
						|
 | 
						|
func (h *TestingHandler) SetMeasurement(name []byte) {
 | 
						|
	mname := Result{
 | 
						|
		Name:  Measurement,
 | 
						|
		Value: name,
 | 
						|
	}
 | 
						|
	h.results = append(h.results, mname)
 | 
						|
}
 | 
						|
 | 
						|
func (h *TestingHandler) AddTag(key []byte, value []byte) {
 | 
						|
	tagkey := Result{
 | 
						|
		Name:  TagKey,
 | 
						|
		Value: key,
 | 
						|
	}
 | 
						|
	tagvalue := Result{
 | 
						|
		Name:  TagValue,
 | 
						|
		Value: value,
 | 
						|
	}
 | 
						|
	h.results = append(h.results, tagkey, tagvalue)
 | 
						|
}
 | 
						|
 | 
						|
func (h *TestingHandler) AddInt(key []byte, value []byte) {
 | 
						|
	fieldkey := Result{
 | 
						|
		Name:  FieldKey,
 | 
						|
		Value: key,
 | 
						|
	}
 | 
						|
	fieldvalue := Result{
 | 
						|
		Name:  FieldInt,
 | 
						|
		Value: value,
 | 
						|
	}
 | 
						|
	h.results = append(h.results, fieldkey, fieldvalue)
 | 
						|
}
 | 
						|
 | 
						|
func (h *TestingHandler) AddUint(key []byte, value []byte) {
 | 
						|
	fieldkey := Result{
 | 
						|
		Name:  FieldKey,
 | 
						|
		Value: key,
 | 
						|
	}
 | 
						|
	fieldvalue := Result{
 | 
						|
		Name:  FieldUint,
 | 
						|
		Value: value,
 | 
						|
	}
 | 
						|
	h.results = append(h.results, fieldkey, fieldvalue)
 | 
						|
}
 | 
						|
 | 
						|
func (h *TestingHandler) AddFloat(key []byte, value []byte) {
 | 
						|
	fieldkey := Result{
 | 
						|
		Name:  FieldKey,
 | 
						|
		Value: key,
 | 
						|
	}
 | 
						|
	fieldvalue := Result{
 | 
						|
		Name:  FieldFloat,
 | 
						|
		Value: value,
 | 
						|
	}
 | 
						|
	h.results = append(h.results, fieldkey, fieldvalue)
 | 
						|
}
 | 
						|
 | 
						|
func (h *TestingHandler) AddString(key []byte, value []byte) {
 | 
						|
	fieldkey := Result{
 | 
						|
		Name:  FieldKey,
 | 
						|
		Value: key,
 | 
						|
	}
 | 
						|
	fieldvalue := Result{
 | 
						|
		Name:  FieldString,
 | 
						|
		Value: value,
 | 
						|
	}
 | 
						|
	h.results = append(h.results, fieldkey, fieldvalue)
 | 
						|
}
 | 
						|
 | 
						|
func (h *TestingHandler) AddBool(key []byte, value []byte) {
 | 
						|
	fieldkey := Result{
 | 
						|
		Name:  FieldKey,
 | 
						|
		Value: key,
 | 
						|
	}
 | 
						|
	fieldvalue := Result{
 | 
						|
		Name:  FieldBool,
 | 
						|
		Value: value,
 | 
						|
	}
 | 
						|
	h.results = append(h.results, fieldkey, fieldvalue)
 | 
						|
}
 | 
						|
 | 
						|
func (h *TestingHandler) SetTimestamp(tm []byte) {
 | 
						|
	timestamp := Result{
 | 
						|
		Name:  Timestamp,
 | 
						|
		Value: tm,
 | 
						|
	}
 | 
						|
	h.results = append(h.results, timestamp)
 | 
						|
}
 | 
						|
 | 
						|
func (h *TestingHandler) Reset() {
 | 
						|
}
 | 
						|
 | 
						|
func (h *TestingHandler) Results() []Result {
 | 
						|
	return h.results
 | 
						|
}
 | 
						|
 | 
						|
func (h *TestingHandler) AddError(err error) {
 | 
						|
	e := Result{
 | 
						|
		err: err,
 | 
						|
	}
 | 
						|
	h.results = append(h.results, e)
 | 
						|
}
 | 
						|
 | 
						|
type BenchmarkingHandler struct {
 | 
						|
}
 | 
						|
 | 
						|
func (h *BenchmarkingHandler) SetMeasurement(name []byte) {
 | 
						|
}
 | 
						|
 | 
						|
func (h *BenchmarkingHandler) AddTag(key []byte, value []byte) {
 | 
						|
}
 | 
						|
 | 
						|
func (h *BenchmarkingHandler) AddInt(key []byte, value []byte) {
 | 
						|
}
 | 
						|
 | 
						|
func (h *BenchmarkingHandler) AddUint(key []byte, value []byte) {
 | 
						|
}
 | 
						|
 | 
						|
func (h *BenchmarkingHandler) AddFloat(key []byte, value []byte) {
 | 
						|
}
 | 
						|
 | 
						|
func (h *BenchmarkingHandler) AddString(key []byte, value []byte) {
 | 
						|
}
 | 
						|
 | 
						|
func (h *BenchmarkingHandler) AddBool(key []byte, value []byte) {
 | 
						|
}
 | 
						|
 | 
						|
func (h *BenchmarkingHandler) SetTimestamp(tm []byte) {
 | 
						|
}
 | 
						|
 | 
						|
func (h *BenchmarkingHandler) Reset() {
 | 
						|
}
 | 
						|
 | 
						|
type TokenType int
 | 
						|
 | 
						|
const (
 | 
						|
	NoMatch TokenType = iota
 | 
						|
	Measurement
 | 
						|
	TagKey
 | 
						|
	TagValue
 | 
						|
	FieldKey
 | 
						|
	FieldString
 | 
						|
	FieldInt
 | 
						|
	FieldUint
 | 
						|
	FieldFloat
 | 
						|
	FieldBool
 | 
						|
	Timestamp
 | 
						|
	EOL
 | 
						|
	EOF
 | 
						|
	Punc
 | 
						|
	WhiteSpace
 | 
						|
)
 | 
						|
 | 
						|
func (t TokenType) String() string {
 | 
						|
	switch t {
 | 
						|
	case NoMatch:
 | 
						|
		return "NoMatch"
 | 
						|
	case Measurement:
 | 
						|
		return "Measurement"
 | 
						|
	case TagKey:
 | 
						|
		return "TagKey"
 | 
						|
	case TagValue:
 | 
						|
		return "TagValue"
 | 
						|
	case FieldKey:
 | 
						|
		return "FieldKey"
 | 
						|
	case FieldInt:
 | 
						|
		return "FieldInt"
 | 
						|
	case FieldUint:
 | 
						|
		return "FieldUint"
 | 
						|
	case FieldFloat:
 | 
						|
		return "FieldFloat"
 | 
						|
	case FieldString:
 | 
						|
		return "FieldString"
 | 
						|
	case FieldBool:
 | 
						|
		return "FieldBool"
 | 
						|
	case Timestamp:
 | 
						|
		return "Timestamp"
 | 
						|
	case EOL:
 | 
						|
		return "EOL"
 | 
						|
	case EOF:
 | 
						|
		return "EOF"
 | 
						|
	case Punc:
 | 
						|
		return "Punc"
 | 
						|
	case WhiteSpace:
 | 
						|
		return "WhiteSpace"
 | 
						|
	default:
 | 
						|
		panic("Unknown TokenType")
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
type Token struct {
 | 
						|
	Name  TokenType
 | 
						|
	Value []byte
 | 
						|
}
 | 
						|
 | 
						|
func (t Token) String() string {
 | 
						|
	return fmt.Sprintf("(%s %q)", t.Name, t.Value)
 | 
						|
}
 | 
						|
 | 
						|
type Result struct {
 | 
						|
	Name  TokenType
 | 
						|
	Value []byte
 | 
						|
	err   error
 | 
						|
}
 | 
						|
 | 
						|
func (r Result) String() string {
 | 
						|
	return fmt.Sprintf("(%s, %q, %v)", r.Name, r.Value, r.err)
 | 
						|
}
 | 
						|
 | 
						|
var tests = []struct {
 | 
						|
	name    string
 | 
						|
	input   []byte
 | 
						|
	results []Result
 | 
						|
	err     error
 | 
						|
}{
 | 
						|
	{
 | 
						|
		name:    "empty string",
 | 
						|
		input:   []byte(""),
 | 
						|
		results: nil,
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "minimal",
 | 
						|
		input: []byte("cpu value=42"),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldKey,
 | 
						|
				Value: []byte("value"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldFloat,
 | 
						|
				Value: []byte("42"),
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "newline",
 | 
						|
		input: []byte("cpu value=42\n"),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldKey,
 | 
						|
				Value: []byte("value"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldFloat,
 | 
						|
				Value: []byte("42"),
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "minimal with timestamp",
 | 
						|
		input: []byte("cpu value=42 1516241192000000000"),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldKey,
 | 
						|
				Value: []byte("value"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldFloat,
 | 
						|
				Value: []byte("42"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  Timestamp,
 | 
						|
				Value: []byte("1516241192000000000"),
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "measurement escape non-special",
 | 
						|
		input: []byte(`c\pu value=42`),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte(`c\pu`),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldKey,
 | 
						|
				Value: []byte("value"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldFloat,
 | 
						|
				Value: []byte("42"),
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "measurement escaped trailing backslash",
 | 
						|
		input: []byte(`cpu\\ value=42`),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte(`cpu\\`),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldKey,
 | 
						|
				Value: []byte("value"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldFloat,
 | 
						|
				Value: []byte("42"),
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "single char measurement",
 | 
						|
		input: []byte("c value=42"),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("c"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldKey,
 | 
						|
				Value: []byte("value"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldFloat,
 | 
						|
				Value: []byte("42"),
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "escape backslash in measurement",
 | 
						|
		input: []byte(`cp\\u value=42`),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte(`cp\\u`),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldKey,
 | 
						|
				Value: []byte("value"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldFloat,
 | 
						|
				Value: []byte("42"),
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "measurement escape space",
 | 
						|
		input: []byte(`cpu\ abc value=42`),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte(`cpu\ abc`),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldKey,
 | 
						|
				Value: []byte("value"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldFloat,
 | 
						|
				Value: []byte("42"),
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "scientific float",
 | 
						|
		input: []byte("cpu value=42e0"),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldKey,
 | 
						|
				Value: []byte("value"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldFloat,
 | 
						|
				Value: []byte("42e0"),
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "scientific float negative mantissa",
 | 
						|
		input: []byte("cpu value=-42e0"),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldKey,
 | 
						|
				Value: []byte("value"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldFloat,
 | 
						|
				Value: []byte("-42e0"),
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "scientific float negative exponent",
 | 
						|
		input: []byte("cpu value=42e-1"),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldKey,
 | 
						|
				Value: []byte("value"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldFloat,
 | 
						|
				Value: []byte("42e-1"),
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "scientific float big e",
 | 
						|
		input: []byte("cpu value=42E0"),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldKey,
 | 
						|
				Value: []byte("value"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldFloat,
 | 
						|
				Value: []byte("42E0"),
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "scientific float missing exponent",
 | 
						|
		input: []byte("cpu value=42E"),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				err: ErrFieldParse,
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "float with decimal",
 | 
						|
		input: []byte("cpu value=42.2"),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldKey,
 | 
						|
				Value: []byte("value"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldFloat,
 | 
						|
				Value: []byte("42.2"),
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "negative float",
 | 
						|
		input: []byte("cpu value=-42"),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldKey,
 | 
						|
				Value: []byte("value"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldFloat,
 | 
						|
				Value: []byte("-42"),
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "float without integer digits",
 | 
						|
		input: []byte("cpu value=.42"),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldKey,
 | 
						|
				Value: []byte("value"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldFloat,
 | 
						|
				Value: []byte(".42"),
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "float without integer digits negative",
 | 
						|
		input: []byte("cpu value=-.42"),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldKey,
 | 
						|
				Value: []byte("value"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldFloat,
 | 
						|
				Value: []byte("-.42"),
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "float with multiple leading 0",
 | 
						|
		input: []byte("cpu value=00.42"),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldKey,
 | 
						|
				Value: []byte("value"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldFloat,
 | 
						|
				Value: []byte("00.42"),
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "invalid float with only dot",
 | 
						|
		input: []byte("cpu value=."),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				err: ErrFieldParse,
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "multiple fields",
 | 
						|
		input: []byte("cpu x=42,y=42"),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldKey,
 | 
						|
				Value: []byte("x"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldFloat,
 | 
						|
				Value: []byte("42"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldKey,
 | 
						|
				Value: []byte("y"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldFloat,
 | 
						|
				Value: []byte("42"),
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "integer field",
 | 
						|
		input: []byte("cpu value=42i"),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldKey,
 | 
						|
				Value: []byte("value"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldInt,
 | 
						|
				Value: []byte("42i"),
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "negative integer field",
 | 
						|
		input: []byte("cpu value=-42i"),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldKey,
 | 
						|
				Value: []byte("value"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldInt,
 | 
						|
				Value: []byte("-42i"),
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "zero integer field",
 | 
						|
		input: []byte("cpu value=0i"),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldKey,
 | 
						|
				Value: []byte("value"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldInt,
 | 
						|
				Value: []byte("0i"),
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "negative zero integer field",
 | 
						|
		input: []byte("cpu value=-0i"),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldKey,
 | 
						|
				Value: []byte("value"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldInt,
 | 
						|
				Value: []byte("-0i"),
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "invalid field",
 | 
						|
		input: []byte("cpu value=howdy"),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				err: ErrFieldParse,
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "string field",
 | 
						|
		input: []byte(`cpu value="42"`),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldKey,
 | 
						|
				Value: []byte("value"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldString,
 | 
						|
				Value: []byte("42"),
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "bool field",
 | 
						|
		input: []byte(`cpu value=true`),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldKey,
 | 
						|
				Value: []byte("value"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldBool,
 | 
						|
				Value: []byte("true"),
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "tag",
 | 
						|
		input: []byte(`cpu,host=localhost value=42`),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  TagKey,
 | 
						|
				Value: []byte("host"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  TagValue,
 | 
						|
				Value: []byte("localhost"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldKey,
 | 
						|
				Value: []byte("value"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldFloat,
 | 
						|
				Value: []byte("42"),
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "tag key escape space",
 | 
						|
		input: []byte(`cpu,h\ ost=localhost value=42`),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  TagKey,
 | 
						|
				Value: []byte(`h\ ost`),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  TagValue,
 | 
						|
				Value: []byte("localhost"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldKey,
 | 
						|
				Value: []byte("value"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldFloat,
 | 
						|
				Value: []byte("42"),
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "tag key escape comma",
 | 
						|
		input: []byte(`cpu,h\,ost=localhost value=42`),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  TagKey,
 | 
						|
				Value: []byte(`h\,ost`),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  TagValue,
 | 
						|
				Value: []byte("localhost"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldKey,
 | 
						|
				Value: []byte("value"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldFloat,
 | 
						|
				Value: []byte("42"),
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "tag key escape equal",
 | 
						|
		input: []byte(`cpu,h\=ost=localhost value=42`),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  TagKey,
 | 
						|
				Value: []byte(`h\=ost`),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  TagValue,
 | 
						|
				Value: []byte("localhost"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldKey,
 | 
						|
				Value: []byte("value"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldFloat,
 | 
						|
				Value: []byte("42"),
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "multiple tags",
 | 
						|
		input: []byte(`cpu,host=localhost,cpu=cpu0 value=42`),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  TagKey,
 | 
						|
				Value: []byte("host"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  TagValue,
 | 
						|
				Value: []byte("localhost"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  TagKey,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  TagValue,
 | 
						|
				Value: []byte("cpu0"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldKey,
 | 
						|
				Value: []byte("value"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldFloat,
 | 
						|
				Value: []byte("42"),
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "tag invalid missing separator",
 | 
						|
		input: []byte("cpu,xyzzy value=42"),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				err: ErrTagParse,
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "tag invalid missing value",
 | 
						|
		input: []byte("cpu,xyzzy= value=42"),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				err: ErrTagParse,
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "tag invalid unescaped space",
 | 
						|
		input: []byte("cpu,h ost=localhost value=42"),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				err: ErrTagParse,
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "tag invalid unescaped comma",
 | 
						|
		input: []byte("cpu,h,ost=localhost value=42"),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				err: ErrTagParse,
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "tag invalid unescaped equals",
 | 
						|
		input: []byte("cpu,h=ost=localhost value=42"),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				err: ErrTagParse,
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "timestamp negative",
 | 
						|
		input: []byte("cpu value=42 -1"),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldKey,
 | 
						|
				Value: []byte("value"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldFloat,
 | 
						|
				Value: []byte("42"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  Timestamp,
 | 
						|
				Value: []byte("-1"),
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "timestamp zero",
 | 
						|
		input: []byte("cpu value=42 0"),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldKey,
 | 
						|
				Value: []byte("value"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldFloat,
 | 
						|
				Value: []byte("42"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  Timestamp,
 | 
						|
				Value: []byte("0"),
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "multiline",
 | 
						|
		input: []byte("cpu value=42\n\n\ncpu value=43\n"),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldKey,
 | 
						|
				Value: []byte("value"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldFloat,
 | 
						|
				Value: []byte("42"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldKey,
 | 
						|
				Value: []byte("value"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldFloat,
 | 
						|
				Value: []byte("43"),
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "error recovery",
 | 
						|
		input: []byte("cpu value=howdy\ncpu\ncpu value=42\n"),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				err: ErrFieldParse,
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				err: ErrFieldParse,
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldKey,
 | 
						|
				Value: []byte("value"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldFloat,
 | 
						|
				Value: []byte("42"),
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "line whitespace",
 | 
						|
		input: []byte("   cpu   value=42  1516241192000000000  \n\n cpu value=42"),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldKey,
 | 
						|
				Value: []byte("value"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldFloat,
 | 
						|
				Value: []byte("42"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  Timestamp,
 | 
						|
				Value: []byte("1516241192000000000"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldKey,
 | 
						|
				Value: []byte("value"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldFloat,
 | 
						|
				Value: []byte("42"),
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "leading newline",
 | 
						|
		input: []byte("\ncpu value=42"),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldKey,
 | 
						|
				Value: []byte("value"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldFloat,
 | 
						|
				Value: []byte("42"),
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "invalid missing field value",
 | 
						|
		input: []byte("cpu value="),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				err: ErrFieldParse,
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "invalid eof field key",
 | 
						|
		input: []byte("cpu value"),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				err: ErrFieldParse,
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "invalid measurement only",
 | 
						|
		input: []byte("cpu"),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				err: ErrFieldParse,
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "invalid measurement only eol",
 | 
						|
		input: []byte("cpu\n"),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				err: ErrFieldParse,
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "invalid missing tag",
 | 
						|
		input: []byte("cpu, value=42"),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				err: ErrTagParse,
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "invalid missing field",
 | 
						|
		input: []byte("cpu,x=y "),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  TagKey,
 | 
						|
				Value: []byte("x"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  TagValue,
 | 
						|
				Value: []byte("y"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				err: ErrFieldParse,
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "invalid too many fields",
 | 
						|
		input: []byte("cpu value=42 value=43"),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldKey,
 | 
						|
				Value: []byte("value"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldFloat,
 | 
						|
				Value: []byte("42"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				err: ErrTimestampParse,
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "invalid timestamp too long",
 | 
						|
		input: []byte("cpu value=42 12345678901234567890"),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldKey,
 | 
						|
				Value: []byte("value"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldFloat,
 | 
						|
				Value: []byte("42"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				err: ErrTimestampParse,
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "invalid open string field",
 | 
						|
		input: []byte(`cpu value="42 12345678901234567890`),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				err: ErrFieldParse,
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "invalid newline in string field",
 | 
						|
		input: []byte("cpu value=\"4\n2\""),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				err: ErrFieldParse,
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				err: ErrFieldParse,
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "invalid field value",
 | 
						|
		input: []byte(`cpu value=howdy`),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				err: ErrFieldParse,
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "invalid quoted timestamp",
 | 
						|
		input: []byte(`cpu value=42 "12345678901234567890"`),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldKey,
 | 
						|
				Value: []byte("value"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldFloat,
 | 
						|
				Value: []byte("42"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				err: ErrTimestampParse,
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "commented line",
 | 
						|
		input: []byte("# blah blah\ncpu value=42"),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldKey,
 | 
						|
				Value: []byte("value"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldFloat,
 | 
						|
				Value: []byte("42"),
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "end with comment",
 | 
						|
		input: []byte("cpu value=42\n# blah blah"),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldKey,
 | 
						|
				Value: []byte("value"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldFloat,
 | 
						|
				Value: []byte("42"),
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "end with comment and whitespace",
 | 
						|
		input: []byte("cpu value=42\n# blah blah\n\n  "),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldKey,
 | 
						|
				Value: []byte("value"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldFloat,
 | 
						|
				Value: []byte("42"),
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
	{
 | 
						|
		name:  "unicode",
 | 
						|
		input: []byte("cpu ☺=42"),
 | 
						|
		results: []Result{
 | 
						|
			Result{
 | 
						|
				Name:  Measurement,
 | 
						|
				Value: []byte("cpu"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldKey,
 | 
						|
				Value: []byte("☺"),
 | 
						|
			},
 | 
						|
			Result{
 | 
						|
				Name:  FieldFloat,
 | 
						|
				Value: []byte("42"),
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
}
 | 
						|
 | 
						|
func TestMachine(t *testing.T) {
 | 
						|
	for _, tt := range tests {
 | 
						|
		t.Run(tt.name, func(t *testing.T) {
 | 
						|
			handler := &TestingHandler{}
 | 
						|
			fsm := NewMachine(handler)
 | 
						|
			fsm.SetData(tt.input)
 | 
						|
 | 
						|
			count := 0
 | 
						|
			for fsm.ParseLine() {
 | 
						|
				if fsm.Err() != nil {
 | 
						|
					handler.AddError(fsm.Err())
 | 
						|
				}
 | 
						|
				count++
 | 
						|
				if count > 20 {
 | 
						|
					break
 | 
						|
				}
 | 
						|
			}
 | 
						|
 | 
						|
			if fsm.Err() != nil {
 | 
						|
				handler.AddError(fsm.Err())
 | 
						|
			}
 | 
						|
 | 
						|
			results := handler.Results()
 | 
						|
			require.Equal(t, tt.results, results)
 | 
						|
		})
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func BenchmarkMachine(b *testing.B) {
 | 
						|
	for _, tt := range tests {
 | 
						|
		b.Run(tt.name, func(b *testing.B) {
 | 
						|
			handler := &BenchmarkingHandler{}
 | 
						|
			fsm := NewMachine(handler)
 | 
						|
 | 
						|
			for n := 0; n < b.N; n++ {
 | 
						|
				fsm.SetData(tt.input)
 | 
						|
 | 
						|
				for fsm.ParseLine() {
 | 
						|
				}
 | 
						|
			}
 | 
						|
		})
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestMachineProcstat(t *testing.T) {
 | 
						|
	input := []byte("procstat,exe=bash,process_name=bash voluntary_context_switches=42i,memory_rss=5103616i,rlimit_memory_data_hard=2147483647i,cpu_time_user=0.02,rlimit_file_locks_soft=2147483647i,pid=29417i,cpu_time_nice=0,rlimit_memory_locked_soft=65536i,read_count=259i,rlimit_memory_vms_hard=2147483647i,memory_swap=0i,rlimit_num_fds_soft=1024i,rlimit_nice_priority_hard=0i,cpu_time_soft_irq=0,cpu_time=0i,rlimit_memory_locked_hard=65536i,realtime_priority=0i,signals_pending=0i,nice_priority=20i,cpu_time_idle=0,memory_stack=139264i,memory_locked=0i,rlimit_memory_stack_soft=8388608i,cpu_time_iowait=0,cpu_time_guest=0,cpu_time_guest_nice=0,rlimit_memory_data_soft=2147483647i,read_bytes=0i,rlimit_cpu_time_soft=2147483647i,involuntary_context_switches=2i,write_bytes=106496i,cpu_time_system=0,cpu_time_irq=0,cpu_usage=0,memory_vms=21659648i,memory_data=1576960i,rlimit_memory_stack_hard=2147483647i,num_threads=1i,cpu_time_stolen=0,rlimit_memory_rss_soft=2147483647i,rlimit_realtime_priority_soft=0i,num_fds=4i,write_count=35i,rlimit_signals_pending_soft=78994i,cpu_time_steal=0,rlimit_num_fds_hard=4096i,rlimit_file_locks_hard=2147483647i,rlimit_cpu_time_hard=2147483647i,rlimit_signals_pending_hard=78994i,rlimit_nice_priority_soft=0i,rlimit_memory_rss_hard=2147483647i,rlimit_memory_vms_soft=2147483647i,rlimit_realtime_priority_hard=0i 1517620624000000000")
 | 
						|
	handler := &TestingHandler{}
 | 
						|
	fsm := NewMachine(handler)
 | 
						|
	fsm.SetData(input)
 | 
						|
	for fsm.ParseLine() {
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func BenchmarkMachineProcstat(b *testing.B) {
 | 
						|
	input := []byte("procstat,exe=bash,process_name=bash voluntary_context_switches=42i,memory_rss=5103616i,rlimit_memory_data_hard=2147483647i,cpu_time_user=0.02,rlimit_file_locks_soft=2147483647i,pid=29417i,cpu_time_nice=0,rlimit_memory_locked_soft=65536i,read_count=259i,rlimit_memory_vms_hard=2147483647i,memory_swap=0i,rlimit_num_fds_soft=1024i,rlimit_nice_priority_hard=0i,cpu_time_soft_irq=0,cpu_time=0i,rlimit_memory_locked_hard=65536i,realtime_priority=0i,signals_pending=0i,nice_priority=20i,cpu_time_idle=0,memory_stack=139264i,memory_locked=0i,rlimit_memory_stack_soft=8388608i,cpu_time_iowait=0,cpu_time_guest=0,cpu_time_guest_nice=0,rlimit_memory_data_soft=2147483647i,read_bytes=0i,rlimit_cpu_time_soft=2147483647i,involuntary_context_switches=2i,write_bytes=106496i,cpu_time_system=0,cpu_time_irq=0,cpu_usage=0,memory_vms=21659648i,memory_data=1576960i,rlimit_memory_stack_hard=2147483647i,num_threads=1i,cpu_time_stolen=0,rlimit_memory_rss_soft=2147483647i,rlimit_realtime_priority_soft=0i,num_fds=4i,write_count=35i,rlimit_signals_pending_soft=78994i,cpu_time_steal=0,rlimit_num_fds_hard=4096i,rlimit_file_locks_hard=2147483647i,rlimit_cpu_time_hard=2147483647i,rlimit_signals_pending_hard=78994i,rlimit_nice_priority_soft=0i,rlimit_memory_rss_hard=2147483647i,rlimit_memory_vms_soft=2147483647i,rlimit_realtime_priority_hard=0i 1517620624000000000")
 | 
						|
	handler := &BenchmarkingHandler{}
 | 
						|
	fsm := NewMachine(handler)
 | 
						|
	for n := 0; n < b.N; n++ {
 | 
						|
		fsm.SetData(input)
 | 
						|
		for fsm.ParseLine() {
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestSeriesMachine(t *testing.T) {
 | 
						|
	var tests = []struct {
 | 
						|
		name    string
 | 
						|
		input   []byte
 | 
						|
		results []Result
 | 
						|
		err     error
 | 
						|
	}{
 | 
						|
		{
 | 
						|
			name:    "empty string",
 | 
						|
			input:   []byte(""),
 | 
						|
			results: nil,
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:  "no tags",
 | 
						|
			input: []byte("cpu"),
 | 
						|
			results: []Result{
 | 
						|
				Result{
 | 
						|
					Name:  Measurement,
 | 
						|
					Value: []byte("cpu"),
 | 
						|
				},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:  "tags",
 | 
						|
			input: []byte("cpu,a=x,b=y"),
 | 
						|
			results: []Result{
 | 
						|
				Result{
 | 
						|
					Name:  Measurement,
 | 
						|
					Value: []byte("cpu"),
 | 
						|
				},
 | 
						|
				Result{
 | 
						|
					Name:  TagKey,
 | 
						|
					Value: []byte("a"),
 | 
						|
				},
 | 
						|
				Result{
 | 
						|
					Name:  TagValue,
 | 
						|
					Value: []byte("x"),
 | 
						|
				},
 | 
						|
				Result{
 | 
						|
					Name:  TagKey,
 | 
						|
					Value: []byte("b"),
 | 
						|
				},
 | 
						|
				Result{
 | 
						|
					Name:  TagValue,
 | 
						|
					Value: []byte("y"),
 | 
						|
				},
 | 
						|
			},
 | 
						|
		},
 | 
						|
	}
 | 
						|
 | 
						|
	for _, tt := range tests {
 | 
						|
		t.Run(tt.name, func(t *testing.T) {
 | 
						|
			handler := &TestingHandler{}
 | 
						|
			fsm := NewSeriesMachine(handler)
 | 
						|
			fsm.SetData(tt.input)
 | 
						|
 | 
						|
			count := 0
 | 
						|
			for fsm.ParseLine() {
 | 
						|
				if fsm.Err() != nil {
 | 
						|
					handler.AddError(fsm.Err())
 | 
						|
				}
 | 
						|
				count++
 | 
						|
				if count > 20 {
 | 
						|
					break
 | 
						|
				}
 | 
						|
			}
 | 
						|
 | 
						|
			if fsm.Err() != nil {
 | 
						|
				handler.AddError(fsm.Err())
 | 
						|
			}
 | 
						|
 | 
						|
			results := handler.Results()
 | 
						|
			require.Equal(t, tt.results, results)
 | 
						|
		})
 | 
						|
	}
 | 
						|
}
 |