influxdb/pkg/csv2lp/csv_annotations_test.go

216 lines
6.0 KiB
Go

package csv2lp
import (
"fmt"
"strconv"
"strings"
"testing"
"time"
"github.com/stretchr/testify/require"
)
func annotation(name string) annotationComment {
for _, a := range supportedAnnotations {
if a.prefix == name {
return a
}
}
panic("no annotation named " + name + " found!")
}
// Test_GroupAnnotation tests #group annotation
func Test_GroupAnnotation(t *testing.T) {
subject := annotation("#group")
require.True(t, subject.matches("#Group"))
require.False(t, subject.isTableAnnotation())
var tests = []struct {
value string
expect int
}{
{"#group true", linePartTag},
{"#group false", 0},
{"false", 0},
{"unknown", 0},
}
for _, test := range tests {
t.Run(test.value, func(t *testing.T) {
col := &CsvTableColumn{}
subject.setupColumn(col, test.value)
require.Equal(t, test.expect, col.LinePart)
})
}
}
// Test_DefaultAnnotation tests #default annotation
func Test_DefaultAnnotation(t *testing.T) {
subject := annotation("#default")
require.True(t, subject.matches("#Default"))
require.False(t, subject.isTableAnnotation())
var tests = []struct {
value string
expect string
}{
{"#default 1", "1"},
{"#default ", ""},
{"whatever", "whatever"},
}
for _, test := range tests {
t.Run(test.value, func(t *testing.T) {
col := &CsvTableColumn{}
subject.setupColumn(col, test.value)
require.Equal(t, test.expect, col.DefaultValue)
})
}
}
// Test_DatatypeAnnotation tests #datatype annotation
func Test_DatatypeAnnotation(t *testing.T) {
subject := annotation("#datatype")
require.True(t, subject.matches("#dataType"))
require.False(t, subject.isTableAnnotation())
var tests = []struct {
value string
expectType string
expectFormat string
expectLinePart int
}{
{"#datatype long", "long", "", 0},
{"#datatype ", "", "", 0},
{"#datatype measurement", "_", "", linePartMeasurement},
{"#datatype tag", "_", "", linePartTag},
{"#datatype field", "", "", linePartField},
{"dateTime", "dateTime", "", linePartTime},
{"dateTime:RFC3339", "dateTime", "RFC3339", linePartTime},
{"#datatype dateTime:RFC3339", "dateTime", "RFC3339", linePartTime},
{"whatever:format", "whatever", "format", 0},
}
for _, test := range tests {
t.Run(test.value, func(t *testing.T) {
col := &CsvTableColumn{}
subject.setupColumn(col, test.value)
if test.expectType != "_" {
require.Equal(t, test.expectType, col.DataType)
}
require.Equal(t, test.expectFormat, col.DataFormat)
})
}
}
// Test_ConstantAnnotation tests #constant annotation
func Test_ConstantAnnotation(t *testing.T) {
subject := annotation("#constant")
require.True(t, subject.matches("#Constant"))
require.True(t, subject.isTableAnnotation())
var tests = []struct {
value []string
expectLabel string
expectDefault string
expectLinePart int
}{
{[]string{"#constant "}, "", "", 0}, // means literally nothing
{[]string{"#constant measurement", "a"}, "_", "a", linePartMeasurement},
{[]string{"#constant measurement", "a", "b"}, "_", "b", linePartMeasurement},
{[]string{"#constant measurement", "a", ""}, "_", "a", linePartMeasurement},
{[]string{"#constant tag", "tgName", "tgValue"}, "tgName", "tgValue", linePartTag},
{[]string{"#constant", "tag", "tgName", "tgValue"}, "tgName", "tgValue", linePartTag},
{[]string{"#constant field", "fName", "fVal"}, "fName", "fVal", linePartField},
{[]string{"#constant", "field", "fName", "fVal"}, "fName", "fVal", linePartField},
{[]string{"dateTime", "1"}, "_", "1", linePartTime},
{[]string{"dateTime", "1", "2"}, "_", "2", linePartTime},
{[]string{"dateTime", "", "2"}, "_", "2", linePartTime},
{[]string{"dateTime", "3", ""}, "_", "3", linePartTime},
{[]string{"long", "fN", "fV"}, "fN", "fV", 0},
}
for i, test := range tests {
t.Run(strconv.Itoa(i), func(t *testing.T) {
table := &CsvTable{}
subject.setupTable(table, test.value)
require.Equal(t, 1, len(table.extraColumns))
col := table.extraColumns[0]
require.Equal(t, test.expectLinePart, col.LinePart)
require.Greater(t, 0, col.Index)
if test.expectLabel != "_" {
require.Equal(t, test.expectLabel, col.Label)
} else {
require.NotEqual(t, "", col.Label)
}
require.Equal(t, test.expectDefault, col.DefaultValue)
})
}
}
// Test_TimeZoneAnnotation tests #timezone annotation
func Test_TimeZoneAnnotation(t *testing.T) {
subject := annotation("#timezone")
require.True(t, subject.matches("#timeZone"))
require.True(t, subject.isTableAnnotation())
var tests = []struct {
value string
err string
}{
{"#timezone ", ""},
{"#timezone EST", ""},
{"#timezone,EST", ""},
{"#timezone,+0100", ""},
{"#timezone,whatever", "#timezone annotation"},
}
for i, test := range tests {
t.Run(strconv.Itoa(i), func(t *testing.T) {
table := &CsvTable{}
err := subject.setupTable(table, strings.Split(test.value, ","))
if test.err == "" {
require.Nil(t, err)
require.NotNil(t, table.timeZone != nil)
} else {
require.NotNil(t, err)
require.True(t, strings.Contains(fmt.Sprintf("%v", err), test.err))
}
})
}
}
// Test_ParseTimeZone tests parseTimeZone fn
func Test_ParseTimeZone(t *testing.T) {
now := time.Now()
_, localOffset := now.Zone()
var tests = []struct {
value string
offset int
}{
{"local", localOffset},
{"Local", localOffset},
{"-0000", 0},
{"+0000", 0},
{"-0100", -3600},
{"+0100", 3600},
{"+0130", 3600 + 3600/2},
{"", 0},
{"-01", -1},
{"0000", -1},
{"UTC", 0},
{"EST", -5 * 3600},
}
for i, test := range tests {
t.Run(fmt.Sprint(i), func(t *testing.T) {
tz, err := parseTimeZone(test.value)
require.NotEqual(t, tz, err) // both cannot be nil
if err != nil {
require.Nil(t, tz)
// fmt.Println(err)
if test.offset >= 0 {
require.Fail(t, "offset expected")
}
return
}
require.NotNil(t, tz)
testDate := fmt.Sprintf("%d-%02d-%02d", now.Year(), now.Month(), now.Day())
result, err := time.ParseInLocation("2006-01-02", testDate, tz)
require.Nil(t, err)
_, offset := result.Zone()
require.Equal(t, test.offset, offset)
})
}
}