mirror of
https://github.com/featurebasedb/featurebase.git
synced 2026-08-28 10:54:59 +00:00
adjust the tests to match the new unexported Field and FrameOptions
This commit is contained in:
parent
d799967fc6
commit
dbb4cdf390
10 changed files with 423 additions and 640 deletions
|
|
@ -244,16 +244,17 @@ func TestClient_ImportValue(t *testing.T) {
|
|||
hldr := test.MustOpenHolder()
|
||||
defer hldr.Close()
|
||||
|
||||
fld := pilosa.Field{
|
||||
Name: "fld",
|
||||
Type: pilosa.FieldTypeInt,
|
||||
fldName := "f"
|
||||
|
||||
fo := pilosa.FrameOptions{
|
||||
Type: pilosa.FrameTypeInt,
|
||||
Min: -100,
|
||||
Max: 100,
|
||||
}
|
||||
|
||||
// Load bitmap into cache to ensure cache gets updated.
|
||||
index := hldr.MustCreateIndexIfNotExists("i", pilosa.IndexOptions{})
|
||||
frame, err := index.CreateFrameIfNotExists("f", pilosa.FrameOptions{Fields: []*pilosa.Field{&fld}})
|
||||
frame, err := index.CreateFrameIfNotExists(fldName, fo)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -266,7 +267,7 @@ func TestClient_ImportValue(t *testing.T) {
|
|||
|
||||
// Send import request.
|
||||
c := test.MustNewClient(s.Host(), defaultClient)
|
||||
if err := c.ImportValue(context.Background(), "i", "f", fld.Name, 0, []pilosa.FieldValue{
|
||||
if err := c.ImportValue(context.Background(), "i", "f", fldName, 0, []pilosa.FieldValue{
|
||||
{ColumnID: 1, Value: -10},
|
||||
{ColumnID: 2, Value: 20},
|
||||
{ColumnID: 3, Value: 40},
|
||||
|
|
@ -275,7 +276,7 @@ func TestClient_ImportValue(t *testing.T) {
|
|||
}
|
||||
|
||||
// Verify Sum.
|
||||
sum, cnt, err := frame.FieldSum(nil, fld.Name)
|
||||
sum, cnt, err := frame.FieldSum(nil, fldName)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -284,7 +285,7 @@ func TestClient_ImportValue(t *testing.T) {
|
|||
}
|
||||
|
||||
// Verify Min.
|
||||
min, cnt, err := frame.FieldMin(nil, fld.Name)
|
||||
min, cnt, err := frame.FieldMin(nil, fldName)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -293,11 +294,11 @@ func TestClient_ImportValue(t *testing.T) {
|
|||
}
|
||||
|
||||
// Verify Min with Filter.
|
||||
filter, err := frame.FieldRange(fld.Name, pql.GT, 40)
|
||||
filter, err := frame.FieldRange(fldName, pql.GT, 40)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
min, cnt, err = frame.FieldMin(filter, fld.Name)
|
||||
min, cnt, err = frame.FieldMin(filter, fldName)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -306,7 +307,7 @@ func TestClient_ImportValue(t *testing.T) {
|
|||
}
|
||||
|
||||
// Verify Max.
|
||||
max, cnt, err := frame.FieldMax(nil, fld.Name)
|
||||
max, cnt, err := frame.FieldMax(nil, fldName)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -422,24 +422,6 @@ func TestCluster_ResizeStates(t *testing.T) {
|
|||
tc.SetBit("i", "f", "standard", 1, 101, nil)
|
||||
tc.SetBit("i", "f", "standard", 1, 1300000, nil)
|
||||
|
||||
// Add Field Data to node0.
|
||||
if err := tc.CreateFrame("i", "fields", FrameOptions{
|
||||
Fields: []*oField{
|
||||
{
|
||||
Name: "fld0",
|
||||
Type: FieldTypeInt,
|
||||
Min: -100,
|
||||
Max: 100,
|
||||
},
|
||||
},
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
tc.SetFieldValue("i", "fields", 1, "fld0", -10)
|
||||
tc.SetFieldValue("i", "fields", 1, "fld0", 10)
|
||||
tc.SetFieldValue("i", "fields", 1300000, "fld0", -99)
|
||||
tc.SetFieldValue("i", "fields", 1300000, "fld0", 99)
|
||||
|
||||
// Before starting the resize, get the CheckSum to use for
|
||||
// comparison later.
|
||||
node0Frame := node0.Holder.Frame("i", "f")
|
||||
|
|
@ -447,11 +429,6 @@ func TestCluster_ResizeStates(t *testing.T) {
|
|||
node0Fragment := node0View.Fragment(1)
|
||||
node0Checksum := node0Fragment.Checksum()
|
||||
|
||||
node0Frame = node0.Holder.Frame("i", "fields")
|
||||
node0View = node0Frame.View("field_fld0")
|
||||
node0Fragment = node0View.Fragment(1)
|
||||
node0ChecksumFld := node0Fragment.Checksum()
|
||||
|
||||
// AddNode needs to block until the resize process has completed.
|
||||
tc.AddNode(false)
|
||||
node1 := tc.Clusters[1]
|
||||
|
|
@ -485,17 +462,6 @@ func TestCluster_ResizeStates(t *testing.T) {
|
|||
t.Fatalf("expected standard view checksum to match: %x - %x", chksum, node0Checksum)
|
||||
}
|
||||
|
||||
// Values
|
||||
// Verify that node-1 contains the fragment (i/fields/field_fld0/1) transferred from node-0.
|
||||
node1Frame = node1.Holder.Frame("i", "fields")
|
||||
node1View = node1Frame.View("field_fld0")
|
||||
node1Fragment = node1View.Fragment(1)
|
||||
|
||||
// Ensure checksums are the same.
|
||||
if chksum := node1Fragment.Checksum(); !bytes.Equal(chksum, node0ChecksumFld) {
|
||||
t.Fatalf("expected checksum to match: %x - %x", chksum, node0ChecksumFld)
|
||||
}
|
||||
|
||||
// Close TestCluster.
|
||||
if err := tc.Close(); err != nil {
|
||||
t.Fatal(err)
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ func TestImportCommand_Run(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: revisit this test once Frame is renamed Field
|
||||
// Ensure that the ImportValue path runs (note: we have specified a value
|
||||
// for cm.Field.)
|
||||
func TestImportCommand_RunValue(t *testing.T) {
|
||||
|
|
@ -107,11 +108,11 @@ func TestImportCommand_RunValue(t *testing.T) {
|
|||
cm.Host = s.Host()
|
||||
|
||||
http.DefaultClient.Do(MustNewHTTPRequest("POST", s.URL+"/index/i", strings.NewReader("")))
|
||||
http.DefaultClient.Do(MustNewHTTPRequest("POST", s.URL+"/index/i/frame/f", strings.NewReader(`{"options":{"fields": [{"name": "foo", "type": "int", "min": 0, "max": 100}]}}`)))
|
||||
http.DefaultClient.Do(MustNewHTTPRequest("POST", s.URL+"/index/i/frame/f", strings.NewReader(`{"options":{"type": "int", "min": 0, "max": 100}}`)))
|
||||
|
||||
cm.Index = "i"
|
||||
cm.Frame = "f"
|
||||
cm.Field = "foo"
|
||||
cm.Field = "f"
|
||||
cm.Paths = []string{file.Name()}
|
||||
err = cm.Run(ctx)
|
||||
if err != nil {
|
||||
|
|
|
|||
223
executor_test.go
223
executor_test.go
|
|
@ -272,10 +272,9 @@ func TestExecutor_Execute_SetFieldValue(t *testing.T) {
|
|||
// Create frames.
|
||||
index := hldr.MustCreateIndexIfNotExists("i", pilosa.IndexOptions{})
|
||||
if _, err := index.CreateFrameIfNotExists("f", pilosa.FrameOptions{
|
||||
Fields: []*pilosa.Field{
|
||||
{Name: "field0", Type: pilosa.FieldTypeInt, Min: 0, Max: 50},
|
||||
{Name: "field1", Type: pilosa.FieldTypeInt, Min: 1, Max: 2},
|
||||
},
|
||||
Type: pilosa.FrameTypeInt,
|
||||
Min: 0,
|
||||
Max: 50,
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if _, err := index.CreateFrameIfNotExists("xxx", pilosa.FrameOptions{}); err != nil {
|
||||
|
|
@ -284,14 +283,14 @@ func TestExecutor_Execute_SetFieldValue(t *testing.T) {
|
|||
|
||||
// Set field values.
|
||||
e := test.NewExecutor(hldr.Holder, test.NewCluster(1))
|
||||
if _, err := e.Execute(context.Background(), "i", test.MustParse(`SetFieldValue(col=10, frame=f, field0=25, field1=2)`), nil, nil); err != nil {
|
||||
if _, err := e.Execute(context.Background(), "i", test.MustParse(`SetFieldValue(col=10, frame=f, f=25)`), nil, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if _, err := e.Execute(context.Background(), "i", test.MustParse(`SetFieldValue(col=100, frame=f, field0=10)`), nil, nil); err != nil {
|
||||
} else if _, err := e.Execute(context.Background(), "i", test.MustParse(`SetFieldValue(col=100, frame=f, f=10)`), nil, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
f := hldr.Frame("i", "f")
|
||||
if value, exists, err := f.FieldValue(10, "field0"); err != nil {
|
||||
if value, exists, err := f.FieldValue(10, "f"); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if !exists {
|
||||
t.Fatal("expected value to exist")
|
||||
|
|
@ -299,15 +298,7 @@ func TestExecutor_Execute_SetFieldValue(t *testing.T) {
|
|||
t.Fatalf("unexpected value: %v", value)
|
||||
}
|
||||
|
||||
if value, exists, err := f.FieldValue(10, "field1"); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if !exists {
|
||||
t.Fatal("expected value to exist")
|
||||
} else if value != 2 {
|
||||
t.Fatalf("unexpected value: %v", value)
|
||||
}
|
||||
|
||||
if value, exists, err := f.FieldValue(100, "field0"); err != nil {
|
||||
if value, exists, err := f.FieldValue(100, "f"); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if !exists {
|
||||
t.Fatal("expected value to exist")
|
||||
|
|
@ -321,37 +312,37 @@ func TestExecutor_Execute_SetFieldValue(t *testing.T) {
|
|||
defer hldr.Close()
|
||||
index := hldr.MustCreateIndexIfNotExists("i", pilosa.IndexOptions{})
|
||||
if _, err := index.CreateFrameIfNotExists("f", pilosa.FrameOptions{
|
||||
Fields: []*pilosa.Field{
|
||||
{Name: "field0", Type: pilosa.FieldTypeInt, Min: 0, Max: 100},
|
||||
},
|
||||
Type: pilosa.FrameTypeInt,
|
||||
Min: 0,
|
||||
Max: 100,
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
t.Run("ErrFrameRequired", func(t *testing.T) {
|
||||
e := test.NewExecutor(hldr.Holder, test.NewCluster(1))
|
||||
if _, err := e.Execute(context.Background(), "i", test.MustParse(`SetFieldValue(col=10, field0=100)`), nil, nil); err == nil || err.Error() != `SetFieldValue() frame required` {
|
||||
if _, err := e.Execute(context.Background(), "i", test.MustParse(`SetFieldValue(col=10, f=100)`), nil, nil); err == nil || err.Error() != `SetFieldValue() frame required` {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("ErrColumnFieldRequired", func(t *testing.T) {
|
||||
e := test.NewExecutor(hldr.Holder, test.NewCluster(1))
|
||||
if _, err := e.Execute(context.Background(), "i", test.MustParse(`SetFieldValue(invalid_column_name=10, frame=f, field0=100)`), nil, nil); err == nil || err.Error() != `SetFieldValue() column field 'col' required` {
|
||||
if _, err := e.Execute(context.Background(), "i", test.MustParse(`SetFieldValue(invalid_column_name=10, frame=f, f=100)`), nil, nil); err == nil || err.Error() != `SetFieldValue() column field 'col' required` {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("ErrColumnFieldValue", func(t *testing.T) {
|
||||
e := test.NewExecutor(hldr.Holder, test.NewCluster(1))
|
||||
if _, err := e.Execute(context.Background(), "i", test.MustParse(`SetFieldValue(invalid_column_name="bad_column", frame=f, field0=100)`), nil, nil); err == nil || err.Error() != `SetFieldValue() column field 'col' required` {
|
||||
if _, err := e.Execute(context.Background(), "i", test.MustParse(`SetFieldValue(invalid_column_name="bad_column", frame=f, f=100)`), nil, nil); err == nil || err.Error() != `SetFieldValue() column field 'col' required` {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("ErrInvalidFieldValueType", func(t *testing.T) {
|
||||
e := test.NewExecutor(hldr.Holder, test.NewCluster(1))
|
||||
if _, err := e.Execute(context.Background(), "i", test.MustParse(`SetFieldValue(col=10, frame=f, field0="hello")`), nil, nil); err == nil || err.Error() != `invalid field value type` {
|
||||
if _, err := e.Execute(context.Background(), "i", test.MustParse(`SetFieldValue(col=10, frame=f, f="hello")`), nil, nil); err == nil || err.Error() != `invalid field value type` {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
})
|
||||
|
|
@ -588,29 +579,33 @@ func TestExecutor_Execute_MinMax(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if _, err := idx.CreateFrame("x", pilosa.FrameOptions{}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if _, err := idx.CreateFrame("f", pilosa.FrameOptions{
|
||||
Fields: []*pilosa.Field{
|
||||
{Name: "foo", Type: pilosa.FieldTypeInt, Min: -10, Max: 100},
|
||||
},
|
||||
Type: pilosa.FrameTypeInt,
|
||||
Min: -10,
|
||||
Max: 100,
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if _, err := e.Execute(context.Background(), "i", test.MustParse(`
|
||||
SetBit(frame=f, row=0, col=0)
|
||||
SetBit(frame=f, row=0, col=3)
|
||||
SetBit(frame=f, row=0, col=`+strconv.Itoa(SliceWidth+1)+`)
|
||||
SetBit(frame=f, row=1, col=1)
|
||||
SetBit(frame=f, row=2, col=`+strconv.Itoa(SliceWidth+2)+`)
|
||||
SetBit(frame=x, row=0, col=0)
|
||||
SetBit(frame=x, row=0, col=3)
|
||||
SetBit(frame=x, row=0, col=`+strconv.Itoa(SliceWidth+1)+`)
|
||||
SetBit(frame=x, row=1, col=1)
|
||||
SetBit(frame=x, row=2, col=`+strconv.Itoa(SliceWidth+2)+`)
|
||||
|
||||
SetFieldValue(frame=f, foo=20, col=0)
|
||||
SetFieldValue(frame=f, foo=-5, col=1)
|
||||
SetFieldValue(frame=f, foo=-5, col=2)
|
||||
SetFieldValue(frame=f, foo=10, col=3)
|
||||
SetFieldValue(frame=f, foo=30, col=`+strconv.Itoa(SliceWidth)+`)
|
||||
SetFieldValue(frame=f, foo=40, col=`+strconv.Itoa(SliceWidth+2)+`)
|
||||
SetFieldValue(frame=f, foo=50, col=`+strconv.Itoa((5*SliceWidth)+100)+`)
|
||||
SetFieldValue(frame=f, foo=60, col=`+strconv.Itoa(SliceWidth+1)+`)
|
||||
SetFieldValue(frame=f, f=20, col=0)
|
||||
SetFieldValue(frame=f, f=-5, col=1)
|
||||
SetFieldValue(frame=f, f=-5, col=2)
|
||||
SetFieldValue(frame=f, f=10, col=3)
|
||||
SetFieldValue(frame=f, f=30, col=`+strconv.Itoa(SliceWidth)+`)
|
||||
SetFieldValue(frame=f, f=40, col=`+strconv.Itoa(SliceWidth+2)+`)
|
||||
SetFieldValue(frame=f, f=50, col=`+strconv.Itoa((5*SliceWidth)+100)+`)
|
||||
SetFieldValue(frame=f, f=60, col=`+strconv.Itoa(SliceWidth+1)+`)
|
||||
`), nil, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -622,16 +617,16 @@ func TestExecutor_Execute_MinMax(t *testing.T) {
|
|||
cnt int64
|
||||
}{
|
||||
{filter: ``, exp: -5, cnt: 2},
|
||||
{filter: `Bitmap(frame=f, row=0)`, exp: 10, cnt: 1},
|
||||
{filter: `Bitmap(frame=f, row=1)`, exp: -5, cnt: 1},
|
||||
{filter: `Bitmap(frame=f, row=2)`, exp: 40, cnt: 1},
|
||||
{filter: `Bitmap(frame=x, row=0)`, exp: 10, cnt: 1},
|
||||
{filter: `Bitmap(frame=x, row=1)`, exp: -5, cnt: 1},
|
||||
{filter: `Bitmap(frame=x, row=2)`, exp: 40, cnt: 1},
|
||||
}
|
||||
for i, tt := range tests {
|
||||
var pql string
|
||||
if tt.filter == "" {
|
||||
pql = `Min(frame=f, field=foo)`
|
||||
pql = `Min(frame=f, field=f)`
|
||||
} else {
|
||||
pql = fmt.Sprintf(`Min(%s, frame=f, field=foo)`, tt.filter)
|
||||
pql = fmt.Sprintf(`Min(%s, frame=f, field=f)`, tt.filter)
|
||||
}
|
||||
if result, err := e.Execute(context.Background(), "i", test.MustParse(pql), nil, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
|
|
@ -648,16 +643,16 @@ func TestExecutor_Execute_MinMax(t *testing.T) {
|
|||
cnt int64
|
||||
}{
|
||||
{filter: ``, exp: 60, cnt: 1},
|
||||
{filter: `Bitmap(frame=f, row=0)`, exp: 60, cnt: 1},
|
||||
{filter: `Bitmap(frame=f, row=1)`, exp: -5, cnt: 1},
|
||||
{filter: `Bitmap(frame=f, row=2)`, exp: 40, cnt: 1},
|
||||
{filter: `Bitmap(frame=x, row=0)`, exp: 60, cnt: 1},
|
||||
{filter: `Bitmap(frame=x, row=1)`, exp: -5, cnt: 1},
|
||||
{filter: `Bitmap(frame=x, row=2)`, exp: 40, cnt: 1},
|
||||
}
|
||||
for i, tt := range tests {
|
||||
var pql string
|
||||
if tt.filter == "" {
|
||||
pql = `Max(frame=f, field=foo)`
|
||||
pql = `Max(frame=f, field=f)`
|
||||
} else {
|
||||
pql = fmt.Sprintf(`Max(%s, frame=f, field=foo)`, tt.filter)
|
||||
pql = fmt.Sprintf(`Max(%s, frame=f, field=f)`, tt.filter)
|
||||
}
|
||||
if result, err := e.Execute(context.Background(), "i", test.MustParse(pql), nil, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
|
|
@ -679,39 +674,51 @@ func TestExecutor_Execute_Sum(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if _, err := idx.CreateFrame("f", pilosa.FrameOptions{
|
||||
Fields: []*pilosa.Field{
|
||||
{Name: "foo", Type: pilosa.FieldTypeInt, Min: 10, Max: 100},
|
||||
{Name: "bar", Type: pilosa.FieldTypeInt, Min: 0, Max: 100000},
|
||||
},
|
||||
if _, err := idx.CreateFrame("x", pilosa.FrameOptions{}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if _, err := idx.CreateFrame("foo", pilosa.FrameOptions{
|
||||
Type: pilosa.FrameTypeInt,
|
||||
Min: 10,
|
||||
Max: 100,
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if _, err := idx.CreateFrame("bar", pilosa.FrameOptions{
|
||||
Type: pilosa.FrameTypeInt,
|
||||
Min: 0,
|
||||
Max: 100000,
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if _, err := idx.CreateFrame("other", pilosa.FrameOptions{
|
||||
Fields: []*pilosa.Field{
|
||||
{Name: "foo", Type: pilosa.FieldTypeInt, Min: 0, Max: 1000},
|
||||
},
|
||||
Type: pilosa.FrameTypeInt,
|
||||
Min: 0,
|
||||
Max: 1000,
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if _, err := e.Execute(context.Background(), "i", test.MustParse(`
|
||||
SetBit(frame=f, row=0, col=0)
|
||||
SetBit(frame=f, row=0, col=`+strconv.Itoa(SliceWidth+1)+`)
|
||||
SetBit(frame=x, row=0, col=0)
|
||||
SetBit(frame=x, row=0, col=`+strconv.Itoa(SliceWidth+1)+`)
|
||||
|
||||
SetFieldValue(frame=f, foo=20, bar=2000, col=0)
|
||||
SetFieldValue(frame=f, foo=30, col=`+strconv.Itoa(SliceWidth)+`)
|
||||
SetFieldValue(frame=f, foo=40, col=`+strconv.Itoa(SliceWidth+2)+`)
|
||||
SetFieldValue(frame=f, foo=50, col=`+strconv.Itoa((5*SliceWidth)+100)+`)
|
||||
SetFieldValue(frame=f, foo=60, col=`+strconv.Itoa(SliceWidth+1)+`)
|
||||
SetFieldValue(frame=other, foo=1000, col=0)
|
||||
SetFieldValue(frame=foo, foo=20, col=0)
|
||||
SetFieldValue(frame=bar, bar=2000, col=0)
|
||||
SetFieldValue(frame=foo, foo=30, col=`+strconv.Itoa(SliceWidth)+`)
|
||||
SetFieldValue(frame=foo, foo=40, col=`+strconv.Itoa(SliceWidth+2)+`)
|
||||
SetFieldValue(frame=foo, foo=50, col=`+strconv.Itoa((5*SliceWidth)+100)+`)
|
||||
SetFieldValue(frame=foo, foo=60, col=`+strconv.Itoa(SliceWidth+1)+`)
|
||||
SetFieldValue(frame=other, other=1000, col=0)
|
||||
`), nil, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
t.Run("NoFilter", func(t *testing.T) {
|
||||
if result, err := e.Execute(context.Background(), "i", test.MustParse(`Sum(frame=f, field=foo)`), nil, nil); err != nil {
|
||||
if result, err := e.Execute(context.Background(), "i", test.MustParse(`Sum(frame=foo, field=foo)`), nil, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if !reflect.DeepEqual(result[0], pilosa.ValCount{Val: 200, Count: 5}) {
|
||||
t.Fatalf("unexpected result: %s", spew.Sdump(result))
|
||||
|
|
@ -719,7 +726,7 @@ func TestExecutor_Execute_Sum(t *testing.T) {
|
|||
})
|
||||
|
||||
t.Run("WithFilter", func(t *testing.T) {
|
||||
if result, err := e.Execute(context.Background(), "i", test.MustParse(`Sum(Bitmap(frame=f, row=0), frame=f, field=foo)`), nil, nil); err != nil {
|
||||
if result, err := e.Execute(context.Background(), "i", test.MustParse(`Sum(Bitmap(frame=x, row=0), frame=foo, field=foo)`), nil, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if !reflect.DeepEqual(result[0], pilosa.ValCount{Val: 80, Count: 2}) {
|
||||
t.Fatalf("unexpected result: %s", spew.Sdump(result))
|
||||
|
|
@ -738,6 +745,7 @@ func TestExecutor_Execute_Range(t *testing.T) {
|
|||
|
||||
// Create frame.
|
||||
if _, err := index.CreateFrameIfNotExists("f", pilosa.FrameOptions{
|
||||
Type: pilosa.FrameTypeTime,
|
||||
TimeQuantum: pilosa.TimeQuantum("YMDH"),
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
|
|
@ -766,7 +774,6 @@ func TestExecutor_Execute_Range(t *testing.T) {
|
|||
t.Fatalf("unexpected columns: %+v", columns)
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
// Ensure a Range(field) query can be executed.
|
||||
|
|
@ -780,27 +787,38 @@ func TestExecutor_Execute_FieldRange(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if _, err := idx.CreateFrame("f", pilosa.FrameOptions{
|
||||
Fields: []*pilosa.Field{
|
||||
{Name: "foo", Type: pilosa.FieldTypeInt, Min: 10, Max: 100},
|
||||
{Name: "bar", Type: pilosa.FieldTypeInt, Min: 0, Max: 100000},
|
||||
},
|
||||
if _, err := idx.CreateFrame("f", pilosa.FrameOptions{}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if _, err := idx.CreateFrame("foo", pilosa.FrameOptions{
|
||||
Type: pilosa.FrameTypeInt,
|
||||
Min: 10,
|
||||
Max: 100,
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if _, err := idx.CreateFrame("bar", pilosa.FrameOptions{
|
||||
Type: pilosa.FrameTypeInt,
|
||||
Min: 0,
|
||||
Max: 100000,
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if _, err := idx.CreateFrame("other", pilosa.FrameOptions{
|
||||
Fields: []*pilosa.Field{
|
||||
{Name: "foo", Type: pilosa.FieldTypeInt, Min: 0, Max: 1000},
|
||||
},
|
||||
Type: pilosa.FrameTypeInt,
|
||||
Min: 0,
|
||||
Max: 1000,
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if _, err := idx.CreateFrame("edge", pilosa.FrameOptions{
|
||||
Fields: []*pilosa.Field{
|
||||
{Name: "foo", Type: pilosa.FieldTypeInt, Min: -100, Max: 100},
|
||||
},
|
||||
Type: pilosa.FrameTypeInt,
|
||||
Min: -100,
|
||||
Max: 100,
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -809,20 +827,21 @@ func TestExecutor_Execute_FieldRange(t *testing.T) {
|
|||
SetBit(frame=f, row=0, col=0)
|
||||
SetBit(frame=f, row=0, col=`+strconv.Itoa(SliceWidth+1)+`)
|
||||
|
||||
SetFieldValue(frame=f, foo=20, bar=2000, col=50)
|
||||
SetFieldValue(frame=f, foo=30, col=`+strconv.Itoa(SliceWidth)+`)
|
||||
SetFieldValue(frame=f, foo=10, col=`+strconv.Itoa(SliceWidth+2)+`)
|
||||
SetFieldValue(frame=f, foo=20, col=`+strconv.Itoa((5*SliceWidth)+100)+`)
|
||||
SetFieldValue(frame=f, foo=60, col=`+strconv.Itoa(SliceWidth+1)+`)
|
||||
SetFieldValue(frame=other, foo=1000, col=0)
|
||||
SetFieldValue(frame=edge, foo=100, col=0)
|
||||
SetFieldValue(frame=edge, foo=-100, col=1)
|
||||
SetFieldValue(frame=foo, foo=20, col=50)
|
||||
SetFieldValue(frame=bar, bar=2000, col=50)
|
||||
SetFieldValue(frame=foo, foo=30, col=`+strconv.Itoa(SliceWidth)+`)
|
||||
SetFieldValue(frame=foo, foo=10, col=`+strconv.Itoa(SliceWidth+2)+`)
|
||||
SetFieldValue(frame=foo, foo=20, col=`+strconv.Itoa((5*SliceWidth)+100)+`)
|
||||
SetFieldValue(frame=foo, foo=60, col=`+strconv.Itoa(SliceWidth+1)+`)
|
||||
SetFieldValue(frame=other, other=1000, col=0)
|
||||
SetFieldValue(frame=edge, edge=100, col=0)
|
||||
SetFieldValue(frame=edge, edge=-100, col=1)
|
||||
`), nil, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
t.Run("EQ", func(t *testing.T) {
|
||||
if result, err := e.Execute(context.Background(), "i", test.MustParse(`Range(frame=f, foo == 20)`), nil, nil); err != nil {
|
||||
if result, err := e.Execute(context.Background(), "i", test.MustParse(`Range(frame=foo, foo == 20)`), nil, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if !reflect.DeepEqual([]uint64{50, (5 * SliceWidth) + 100}, result[0].(*pilosa.Row).Columns()) {
|
||||
t.Fatalf("unexpected result: %s", spew.Sdump(result))
|
||||
|
|
@ -831,19 +850,19 @@ func TestExecutor_Execute_FieldRange(t *testing.T) {
|
|||
|
||||
t.Run("NEQ", func(t *testing.T) {
|
||||
// NEQ null
|
||||
if result, err := e.Execute(context.Background(), "i", test.MustParse(`Range(frame=other, foo != null)`), nil, nil); err != nil {
|
||||
if result, err := e.Execute(context.Background(), "i", test.MustParse(`Range(frame=other, other != null)`), nil, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if !reflect.DeepEqual([]uint64{0}, result[0].(*pilosa.Row).Columns()) {
|
||||
t.Fatalf("unexpected result: %s", spew.Sdump(result))
|
||||
}
|
||||
// NEQ <int>
|
||||
if result, err := e.Execute(context.Background(), "i", test.MustParse(`Range(frame=f, foo != 20)`), nil, nil); err != nil {
|
||||
if result, err := e.Execute(context.Background(), "i", test.MustParse(`Range(frame=foo, foo != 20)`), nil, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if !reflect.DeepEqual([]uint64{SliceWidth, SliceWidth + 1, SliceWidth + 2}, result[0].(*pilosa.Row).Columns()) {
|
||||
t.Fatalf("unexpected result: %s", spew.Sdump(result))
|
||||
}
|
||||
// NEQ -<int>
|
||||
if result, err := e.Execute(context.Background(), "i", test.MustParse(`Range(frame=other, foo != -20)`), nil, nil); err != nil {
|
||||
if result, err := e.Execute(context.Background(), "i", test.MustParse(`Range(frame=other, other != -20)`), nil, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if !reflect.DeepEqual([]uint64{0}, result[0].(*pilosa.Row).Columns()) {
|
||||
//t.Fatalf("unexpected result: %s", spew.Sdump(result))
|
||||
|
|
@ -852,7 +871,7 @@ func TestExecutor_Execute_FieldRange(t *testing.T) {
|
|||
})
|
||||
|
||||
t.Run("LT", func(t *testing.T) {
|
||||
if result, err := e.Execute(context.Background(), "i", test.MustParse(`Range(frame=f, foo < 20)`), nil, nil); err != nil {
|
||||
if result, err := e.Execute(context.Background(), "i", test.MustParse(`Range(frame=foo, foo < 20)`), nil, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if !reflect.DeepEqual([]uint64{SliceWidth + 2}, result[0].(*pilosa.Row).Columns()) {
|
||||
t.Fatalf("unexpected result: %s", spew.Sdump(result))
|
||||
|
|
@ -860,7 +879,7 @@ func TestExecutor_Execute_FieldRange(t *testing.T) {
|
|||
})
|
||||
|
||||
t.Run("LTE", func(t *testing.T) {
|
||||
if result, err := e.Execute(context.Background(), "i", test.MustParse(`Range(frame=f, foo <= 20)`), nil, nil); err != nil {
|
||||
if result, err := e.Execute(context.Background(), "i", test.MustParse(`Range(frame=foo, foo <= 20)`), nil, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if !reflect.DeepEqual([]uint64{50, SliceWidth + 2, (5 * SliceWidth) + 100}, result[0].(*pilosa.Row).Columns()) {
|
||||
t.Fatalf("unexpected result: %s", spew.Sdump(result))
|
||||
|
|
@ -868,7 +887,7 @@ func TestExecutor_Execute_FieldRange(t *testing.T) {
|
|||
})
|
||||
|
||||
t.Run("GT", func(t *testing.T) {
|
||||
if result, err := e.Execute(context.Background(), "i", test.MustParse(`Range(frame=f, foo > 20)`), nil, nil); err != nil {
|
||||
if result, err := e.Execute(context.Background(), "i", test.MustParse(`Range(frame=foo, foo > 20)`), nil, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if !reflect.DeepEqual([]uint64{SliceWidth, SliceWidth + 1}, result[0].(*pilosa.Row).Columns()) {
|
||||
t.Fatalf("unexpected result: %s", spew.Sdump(result))
|
||||
|
|
@ -876,7 +895,7 @@ func TestExecutor_Execute_FieldRange(t *testing.T) {
|
|||
})
|
||||
|
||||
t.Run("GTE", func(t *testing.T) {
|
||||
if result, err := e.Execute(context.Background(), "i", test.MustParse(`Range(frame=f, foo >= 20)`), nil, nil); err != nil {
|
||||
if result, err := e.Execute(context.Background(), "i", test.MustParse(`Range(frame=foo, foo >= 20)`), nil, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if !reflect.DeepEqual([]uint64{50, SliceWidth, SliceWidth + 1, (5 * SliceWidth) + 100}, result[0].(*pilosa.Row).Columns()) {
|
||||
t.Fatalf("unexpected result: %s", spew.Sdump(result))
|
||||
|
|
@ -884,7 +903,7 @@ func TestExecutor_Execute_FieldRange(t *testing.T) {
|
|||
})
|
||||
|
||||
t.Run("BETWEEN", func(t *testing.T) {
|
||||
if result, err := e.Execute(context.Background(), "i", test.MustParse(`Range(frame=other, foo >< [1, 1000])`), nil, nil); err != nil {
|
||||
if result, err := e.Execute(context.Background(), "i", test.MustParse(`Range(frame=other, other >< [1, 1000])`), nil, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if !reflect.DeepEqual([]uint64{0}, result[0].(*pilosa.Row).Columns()) {
|
||||
t.Fatalf("unexpected result: %s", spew.Sdump(result))
|
||||
|
|
@ -893,7 +912,7 @@ func TestExecutor_Execute_FieldRange(t *testing.T) {
|
|||
|
||||
// Ensure that the FieldNotNull code path gets run.
|
||||
t.Run("FieldNotNull", func(t *testing.T) {
|
||||
if result, err := e.Execute(context.Background(), "i", test.MustParse(`Range(frame=other, foo >< [0, 1000])`), nil, nil); err != nil {
|
||||
if result, err := e.Execute(context.Background(), "i", test.MustParse(`Range(frame=other, other >< [0, 1000])`), nil, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if !reflect.DeepEqual([]uint64{0}, result[0].(*pilosa.Row).Columns()) {
|
||||
t.Fatalf("unexpected result: %s", spew.Sdump(result))
|
||||
|
|
@ -901,7 +920,7 @@ func TestExecutor_Execute_FieldRange(t *testing.T) {
|
|||
})
|
||||
|
||||
t.Run("BelowMin", func(t *testing.T) {
|
||||
if result, err := e.Execute(context.Background(), "i", test.MustParse(`Range(frame=f, foo == 0)`), nil, nil); err != nil {
|
||||
if result, err := e.Execute(context.Background(), "i", test.MustParse(`Range(frame=foo, foo == 0)`), nil, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if !reflect.DeepEqual([]uint64{}, result[0].(*pilosa.Row).Columns()) {
|
||||
t.Fatalf("unexpected result: %s", spew.Sdump(result))
|
||||
|
|
@ -909,7 +928,7 @@ func TestExecutor_Execute_FieldRange(t *testing.T) {
|
|||
})
|
||||
|
||||
t.Run("AboveMax", func(t *testing.T) {
|
||||
if result, err := e.Execute(context.Background(), "i", test.MustParse(`Range(frame=f, foo == 200)`), nil, nil); err != nil {
|
||||
if result, err := e.Execute(context.Background(), "i", test.MustParse(`Range(frame=foo, foo == 200)`), nil, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if !reflect.DeepEqual([]uint64{}, result[0].(*pilosa.Row).Columns()) {
|
||||
t.Fatalf("unexpected result: %s", spew.Sdump(result))
|
||||
|
|
@ -917,7 +936,7 @@ func TestExecutor_Execute_FieldRange(t *testing.T) {
|
|||
})
|
||||
|
||||
t.Run("LTAboveMax", func(t *testing.T) {
|
||||
if result, err := e.Execute(context.Background(), "i", test.MustParse(`Range(frame=edge, foo < 200)`), nil, nil); err != nil {
|
||||
if result, err := e.Execute(context.Background(), "i", test.MustParse(`Range(frame=edge, edge < 200)`), nil, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if !reflect.DeepEqual([]uint64{0, 1}, result[0].(*pilosa.Row).Columns()) {
|
||||
t.Fatalf("unexpected result: %s", spew.Sdump(result[0].(*pilosa.Row).Columns()))
|
||||
|
|
@ -925,7 +944,7 @@ func TestExecutor_Execute_FieldRange(t *testing.T) {
|
|||
})
|
||||
|
||||
t.Run("GTBelowMin", func(t *testing.T) {
|
||||
if result, err := e.Execute(context.Background(), "i", test.MustParse(`Range(frame=edge, foo > -200)`), nil, nil); err != nil {
|
||||
if result, err := e.Execute(context.Background(), "i", test.MustParse(`Range(frame=edge, edge > -200)`), nil, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if !reflect.DeepEqual([]uint64{0, 1}, result[0].(*pilosa.Row).Columns()) {
|
||||
t.Fatalf("unexpected result: %s", spew.Sdump(result[0].(*pilosa.Row).Columns()))
|
||||
|
|
@ -939,7 +958,7 @@ func TestExecutor_Execute_FieldRange(t *testing.T) {
|
|||
})
|
||||
|
||||
t.Run("ErrFieldNotFound", func(t *testing.T) {
|
||||
if _, err := e.Execute(context.Background(), "i", test.MustParse(`Range(frame=f, bad_field >= 20)`), nil, nil); err != pilosa.ErrFieldNotFound {
|
||||
if _, err := e.Execute(context.Background(), "i", test.MustParse(`Range(frame=foo, bad_field >= 20)`), nil, nil); err != pilosa.ErrFieldNotFound {
|
||||
t.Fatal(err)
|
||||
}
|
||||
})
|
||||
|
|
|
|||
37
frame.go
37
frame.go
|
|
@ -69,14 +69,25 @@ type Frame struct {
|
|||
Logger Logger
|
||||
}
|
||||
|
||||
// FrameOption is a functional option type for pilosa.Frame.
|
||||
type FrameOption func(f *Frame) error
|
||||
|
||||
// TODO: break these out into separate Options (not a FrameOptions object)
|
||||
func OptFrameFrameOptions(o FrameOptions) FrameOption {
|
||||
return func(f *Frame) error {
|
||||
f.options = o
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// NewFrame returns a new instance of frame.
|
||||
func NewFrame(path, index, name string) (*Frame, error) {
|
||||
func NewFrame(path, index, name string, opts ...FrameOption) (*Frame, error) {
|
||||
err := ValidateName(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Frame{
|
||||
f := &Frame{
|
||||
path: path,
|
||||
index: index,
|
||||
name: name,
|
||||
|
|
@ -95,7 +106,16 @@ func NewFrame(path, index, name string) (*Frame, error) {
|
|||
},
|
||||
|
||||
Logger: NopLogger,
|
||||
}, nil
|
||||
}
|
||||
|
||||
for _, opt := range opts {
|
||||
err := opt(f)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "applying option")
|
||||
}
|
||||
}
|
||||
|
||||
return f, nil
|
||||
}
|
||||
|
||||
// Name returns the name the frame was initialized with.
|
||||
|
|
@ -299,7 +319,7 @@ func (f *Frame) applyOptions(opt FrameOptions) error {
|
|||
f.options.TimeQuantum = ""
|
||||
case FrameTypeInt:
|
||||
f.options.Type = opt.Type
|
||||
f.options.CacheType = ""
|
||||
f.options.CacheType = CacheTypeNone
|
||||
f.options.CacheSize = 0
|
||||
f.options.Min = opt.Min
|
||||
f.options.Max = opt.Max
|
||||
|
|
@ -321,7 +341,7 @@ func (f *Frame) applyOptions(opt FrameOptions) error {
|
|||
}
|
||||
case FrameTypeTime:
|
||||
f.options.Type = opt.Type
|
||||
f.options.CacheType = ""
|
||||
f.options.CacheType = CacheTypeNone
|
||||
f.options.CacheSize = 0
|
||||
f.options.Min = 0
|
||||
f.options.Max = 0
|
||||
|
|
@ -657,7 +677,7 @@ func (f *Frame) ClearBit(name string, rowID, colID uint64, t *time.Time) (change
|
|||
|
||||
// Clear non-time bit.
|
||||
if v, err := view.ClearBit(rowID, colID); err != nil {
|
||||
return changed, errors.Wrap(err, "setting on view")
|
||||
return changed, errors.Wrap(err, "clearing on view")
|
||||
} else if v {
|
||||
changed = v
|
||||
}
|
||||
|
|
@ -675,7 +695,7 @@ func (f *Frame) ClearBit(name string, rowID, colID uint64, t *time.Time) (change
|
|||
}
|
||||
|
||||
if c, err := view.ClearBit(rowID, colID); err != nil {
|
||||
return changed, errors.Wrapf(err, "setting on view %s", subname)
|
||||
return changed, errors.Wrapf(err, "clearing on view %s", subname)
|
||||
} else if c {
|
||||
changed = true
|
||||
}
|
||||
|
|
@ -995,7 +1015,7 @@ type FrameOptions struct {
|
|||
CacheSize uint32 `json:"cacheSize,omitempty"`
|
||||
Min int64 `json:"min,omitempty"`
|
||||
Max int64 `json:"max,omitempty"`
|
||||
TimeQuantum TimeQuantum `json:"timeQuantum,omitempty"` // TODO travis: rename this Quantum?
|
||||
TimeQuantum TimeQuantum `json:"timeQuantum,omitempty"` // TODO: rename this Quantum?
|
||||
}
|
||||
|
||||
// Validate ensures that FrameOption values are valid.
|
||||
|
|
@ -1064,6 +1084,7 @@ func IsValidFieldType(v string) bool {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: finish unexporting this. also, rename it.
|
||||
// oField represents a range field on a frame.
|
||||
type oField struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
|
|
|
|||
149
frame_internal_test.go
Normal file
149
frame_internal_test.go
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
// Copyright 2017 Pilosa Corp.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package pilosa
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/pilosa/pilosa/pql"
|
||||
)
|
||||
|
||||
// Ensure a field can adjust to its baseValue.
|
||||
func TestField_BaseValue(t *testing.T) {
|
||||
f0 := &oField{
|
||||
Name: "f0",
|
||||
Type: FieldTypeInt,
|
||||
Min: -100,
|
||||
Max: 900,
|
||||
}
|
||||
f1 := &oField{
|
||||
Name: "f1",
|
||||
Type: FieldTypeInt,
|
||||
Min: 0,
|
||||
Max: 1000,
|
||||
}
|
||||
|
||||
f2 := &oField{
|
||||
Name: "f2",
|
||||
Type: FieldTypeInt,
|
||||
Min: 100,
|
||||
Max: 1100,
|
||||
}
|
||||
|
||||
t.Run("Normal Condition", func(t *testing.T) {
|
||||
|
||||
for _, tt := range []struct {
|
||||
f *oField
|
||||
op pql.Token
|
||||
val int64
|
||||
expBaseValue uint64
|
||||
expOutOfRange bool
|
||||
}{
|
||||
// LT
|
||||
{f0, pql.LT, 5, 105, false},
|
||||
{f0, pql.LT, -8, 92, false},
|
||||
{f0, pql.LT, -108, 0, true},
|
||||
{f0, pql.LT, 1005, 1000, false},
|
||||
{f0, pql.LT, 0, 100, false},
|
||||
|
||||
{f1, pql.LT, 5, 5, false},
|
||||
{f1, pql.LT, -8, 0, true},
|
||||
{f1, pql.LT, 1005, 1000, false},
|
||||
{f1, pql.LT, 0, 0, false},
|
||||
|
||||
{f2, pql.LT, 5, 0, true},
|
||||
{f2, pql.LT, -8, 0, true},
|
||||
{f2, pql.LT, 105, 5, false},
|
||||
{f2, pql.LT, 1105, 1000, false},
|
||||
|
||||
// GT
|
||||
{f0, pql.GT, -105, 0, false},
|
||||
{f0, pql.GT, 5, 105, false},
|
||||
{f0, pql.GT, 905, 0, true},
|
||||
{f0, pql.GT, 0, 100, false},
|
||||
|
||||
{f1, pql.GT, 5, 5, false},
|
||||
{f1, pql.GT, -8, 0, false},
|
||||
{f1, pql.GT, 1005, 0, true},
|
||||
{f1, pql.GT, 0, 0, false},
|
||||
|
||||
{f2, pql.GT, 5, 0, false},
|
||||
{f2, pql.GT, -8, 0, false},
|
||||
{f2, pql.GT, 105, 5, false},
|
||||
{f2, pql.GT, 1105, 0, true},
|
||||
|
||||
// EQ
|
||||
{f0, pql.EQ, -105, 0, true},
|
||||
{f0, pql.EQ, 5, 105, false},
|
||||
{f0, pql.EQ, 905, 0, true},
|
||||
{f0, pql.EQ, 0, 100, false},
|
||||
|
||||
{f1, pql.EQ, 5, 5, false},
|
||||
{f1, pql.EQ, -8, 0, true},
|
||||
{f1, pql.EQ, 1005, 0, true},
|
||||
{f1, pql.EQ, 0, 0, false},
|
||||
|
||||
{f2, pql.EQ, 5, 0, true},
|
||||
{f2, pql.EQ, -8, 0, true},
|
||||
{f2, pql.EQ, 105, 5, false},
|
||||
{f2, pql.EQ, 1105, 0, true},
|
||||
} {
|
||||
bv, oor := tt.f.BaseValue(tt.op, tt.val)
|
||||
if oor != tt.expOutOfRange {
|
||||
t.Fatalf("baseValue calculation on %s op %s, expected outOfRange %v, got %v", tt.f.Name, tt.op, tt.expOutOfRange, oor)
|
||||
} else if !reflect.DeepEqual(bv, tt.expBaseValue) {
|
||||
t.Fatalf("baseValue calculation on %s, expected value %v, got %v", tt.f.Name, tt.expBaseValue, bv)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Betwween Condition", func(t *testing.T) {
|
||||
for _, tt := range []struct {
|
||||
f *oField
|
||||
predMin int64
|
||||
predMax int64
|
||||
expBaseValueMin uint64
|
||||
expBaseValueMax uint64
|
||||
expOutOfRange bool
|
||||
}{
|
||||
|
||||
{f0, -205, -105, 0, 0, true},
|
||||
{f0, -105, 80, 0, 180, false},
|
||||
{f0, 5, 20, 105, 120, false},
|
||||
{f0, 20, 1005, 120, 1000, false},
|
||||
{f0, 1005, 2000, 0, 0, true},
|
||||
|
||||
{f1, -105, -5, 0, 0, true},
|
||||
{f1, -5, 20, 0, 20, false},
|
||||
{f1, 5, 20, 5, 20, false},
|
||||
{f1, 20, 1005, 20, 1000, false},
|
||||
{f1, 1005, 2000, 0, 0, true},
|
||||
|
||||
{f2, 5, 95, 0, 0, true},
|
||||
{f2, 95, 120, 0, 20, false},
|
||||
{f2, 105, 120, 5, 20, false},
|
||||
{f2, 120, 1105, 20, 1000, false},
|
||||
{f2, 1105, 2000, 0, 0, true},
|
||||
} {
|
||||
min, max, oor := tt.f.BaseValueBetween(tt.predMin, tt.predMax)
|
||||
if oor != tt.expOutOfRange {
|
||||
t.Fatalf("baseValueBetween calculation on %s, expected outOfRange %v, got %v", tt.f.Name, tt.expOutOfRange, oor)
|
||||
} else if !reflect.DeepEqual(min, tt.expBaseValueMin) || !reflect.DeepEqual(max, tt.expBaseValueMax) {
|
||||
t.Fatalf("baseValueBetween calculation on %s, expected min/max %v/%v, got %v/%v", tt.f.Name, tt.expBaseValueMin, tt.expBaseValueMax, min, max)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
190
frame_test.go
190
frame_test.go
|
|
@ -16,11 +16,9 @@ package pilosa_test
|
|||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/pilosa/pilosa"
|
||||
"github.com/pilosa/pilosa/pql"
|
||||
"github.com/pilosa/pilosa/test"
|
||||
)
|
||||
|
||||
|
|
@ -52,7 +50,10 @@ func TestFrame_CreateViewIfNotExists(t *testing.T) {
|
|||
|
||||
// Ensure frame can set its time quantum.
|
||||
func TestFrame_SetTimeQuantum(t *testing.T) {
|
||||
f := test.MustOpenFrame()
|
||||
fo := pilosa.FrameOptions{
|
||||
Type: "time",
|
||||
}
|
||||
f := test.MustOpenFrame(pilosa.OptFrameFrameOptions(fo))
|
||||
defer f.Close()
|
||||
|
||||
// Set & retrieve time quantum.
|
||||
|
|
@ -77,31 +78,23 @@ func TestFrame_SetFieldValue(t *testing.T) {
|
|||
defer idx.Close()
|
||||
|
||||
f, err := idx.CreateFrame("f", pilosa.FrameOptions{
|
||||
Fields: []*pilosa.Field{
|
||||
{Name: "field0", Type: pilosa.FieldTypeInt, Min: 0, Max: 30},
|
||||
{Name: "field1", Type: pilosa.FieldTypeInt, Min: 20, Max: 25},
|
||||
},
|
||||
Type: pilosa.FrameTypeInt,
|
||||
Min: 0,
|
||||
Max: 30,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Set value on first field.
|
||||
if changed, err := f.SetFieldValue(100, "field0", 21); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if !changed {
|
||||
t.Fatal("expected change")
|
||||
}
|
||||
|
||||
// Set value on same column but different field.
|
||||
if changed, err := f.SetFieldValue(100, "field1", 25); err != nil {
|
||||
// Set value on field.
|
||||
if changed, err := f.SetFieldValue(100, "f", 21); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if !changed {
|
||||
t.Fatal("expected change")
|
||||
}
|
||||
|
||||
// Read value.
|
||||
if value, exists, err := f.FieldValue(100, "field0"); err != nil {
|
||||
if value, exists, err := f.FieldValue(100, "f"); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if value != 21 {
|
||||
t.Fatalf("unexpected value: %d", value)
|
||||
|
|
@ -110,7 +103,7 @@ func TestFrame_SetFieldValue(t *testing.T) {
|
|||
}
|
||||
|
||||
// Setting value should return no change.
|
||||
if changed, err := f.SetFieldValue(100, "field0", 21); err != nil {
|
||||
if changed, err := f.SetFieldValue(100, "f", 21); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if changed {
|
||||
t.Fatal("expected no change")
|
||||
|
|
@ -122,30 +115,30 @@ func TestFrame_SetFieldValue(t *testing.T) {
|
|||
defer idx.Close()
|
||||
|
||||
f, err := idx.CreateFrame("f", pilosa.FrameOptions{
|
||||
Fields: []*pilosa.Field{
|
||||
{Name: "field0", Type: pilosa.FieldTypeInt, Min: 0, Max: 30},
|
||||
},
|
||||
Type: pilosa.FrameTypeInt,
|
||||
Min: 0,
|
||||
Max: 30,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Set value.
|
||||
if changed, err := f.SetFieldValue(100, "field0", 21); err != nil {
|
||||
if changed, err := f.SetFieldValue(100, "f", 21); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if !changed {
|
||||
t.Fatal("expected change")
|
||||
}
|
||||
|
||||
// Set different value.
|
||||
if changed, err := f.SetFieldValue(100, "field0", 23); err != nil {
|
||||
if changed, err := f.SetFieldValue(100, "f", 23); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if !changed {
|
||||
t.Fatal("expected change")
|
||||
}
|
||||
|
||||
// Read value.
|
||||
if value, exists, err := f.FieldValue(100, "field0"); err != nil {
|
||||
if value, exists, err := f.FieldValue(100, "f"); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if value != 23 {
|
||||
t.Fatalf("unexpected value: %d", value)
|
||||
|
|
@ -159,9 +152,9 @@ func TestFrame_SetFieldValue(t *testing.T) {
|
|||
defer idx.Close()
|
||||
|
||||
f, err := idx.CreateFrame("f", pilosa.FrameOptions{
|
||||
Fields: []*pilosa.Field{
|
||||
{Name: "field0", Type: pilosa.FieldTypeInt, Min: 0, Max: 30},
|
||||
},
|
||||
Type: pilosa.FrameTypeInt,
|
||||
Min: 0,
|
||||
Max: 30,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
|
@ -178,16 +171,16 @@ func TestFrame_SetFieldValue(t *testing.T) {
|
|||
defer idx.Close()
|
||||
|
||||
f, err := idx.CreateFrame("f", pilosa.FrameOptions{
|
||||
Fields: []*pilosa.Field{
|
||||
{Name: "field0", Type: pilosa.FieldTypeInt, Min: 20, Max: 30},
|
||||
},
|
||||
Type: pilosa.FrameTypeInt,
|
||||
Min: 20,
|
||||
Max: 30,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Set value.
|
||||
if _, err := f.SetFieldValue(100, "field0", 15); err != pilosa.ErrFieldValueTooLow {
|
||||
if _, err := f.SetFieldValue(100, "f", 15); err != pilosa.ErrFieldValueTooLow {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
})
|
||||
|
|
@ -197,16 +190,16 @@ func TestFrame_SetFieldValue(t *testing.T) {
|
|||
defer idx.Close()
|
||||
|
||||
f, err := idx.CreateFrame("f", pilosa.FrameOptions{
|
||||
Fields: []*pilosa.Field{
|
||||
{Name: "field0", Type: pilosa.FieldTypeInt, Min: 20, Max: 30},
|
||||
},
|
||||
Type: pilosa.FrameTypeInt,
|
||||
Min: 20,
|
||||
Max: 30,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Set value.
|
||||
if _, err := f.SetFieldValue(100, "field0", 31); err != pilosa.ErrFieldValueTooHigh {
|
||||
if _, err := f.SetFieldValue(100, "f", 31); err != pilosa.ErrFieldValueTooHigh {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
})
|
||||
|
|
@ -294,130 +287,3 @@ func TestFrame_DeleteView(t *testing.T) {
|
|||
t.Fatal("failed to create new view")
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure a field can adjust to its baseValue.
|
||||
func TestField_BaseValue(t *testing.T) {
|
||||
f0 := &pilosa.Field{
|
||||
Name: "f0",
|
||||
Type: pilosa.FieldTypeInt,
|
||||
Min: -100,
|
||||
Max: 900,
|
||||
}
|
||||
f1 := &pilosa.Field{
|
||||
Name: "f1",
|
||||
Type: pilosa.FieldTypeInt,
|
||||
Min: 0,
|
||||
Max: 1000,
|
||||
}
|
||||
|
||||
f2 := &pilosa.Field{
|
||||
Name: "f2",
|
||||
Type: pilosa.FieldTypeInt,
|
||||
Min: 100,
|
||||
Max: 1100,
|
||||
}
|
||||
|
||||
t.Run("Normal Condition", func(t *testing.T) {
|
||||
|
||||
for _, tt := range []struct {
|
||||
f *pilosa.Field
|
||||
op pql.Token
|
||||
val int64
|
||||
expBaseValue uint64
|
||||
expOutOfRange bool
|
||||
}{
|
||||
// LT
|
||||
{f0, pql.LT, 5, 105, false},
|
||||
{f0, pql.LT, -8, 92, false},
|
||||
{f0, pql.LT, -108, 0, true},
|
||||
{f0, pql.LT, 1005, 1000, false},
|
||||
{f0, pql.LT, 0, 100, false},
|
||||
|
||||
{f1, pql.LT, 5, 5, false},
|
||||
{f1, pql.LT, -8, 0, true},
|
||||
{f1, pql.LT, 1005, 1000, false},
|
||||
{f1, pql.LT, 0, 0, false},
|
||||
|
||||
{f2, pql.LT, 5, 0, true},
|
||||
{f2, pql.LT, -8, 0, true},
|
||||
{f2, pql.LT, 105, 5, false},
|
||||
{f2, pql.LT, 1105, 1000, false},
|
||||
|
||||
// GT
|
||||
{f0, pql.GT, -105, 0, false},
|
||||
{f0, pql.GT, 5, 105, false},
|
||||
{f0, pql.GT, 905, 0, true},
|
||||
{f0, pql.GT, 0, 100, false},
|
||||
|
||||
{f1, pql.GT, 5, 5, false},
|
||||
{f1, pql.GT, -8, 0, false},
|
||||
{f1, pql.GT, 1005, 0, true},
|
||||
{f1, pql.GT, 0, 0, false},
|
||||
|
||||
{f2, pql.GT, 5, 0, false},
|
||||
{f2, pql.GT, -8, 0, false},
|
||||
{f2, pql.GT, 105, 5, false},
|
||||
{f2, pql.GT, 1105, 0, true},
|
||||
|
||||
// EQ
|
||||
{f0, pql.EQ, -105, 0, true},
|
||||
{f0, pql.EQ, 5, 105, false},
|
||||
{f0, pql.EQ, 905, 0, true},
|
||||
{f0, pql.EQ, 0, 100, false},
|
||||
|
||||
{f1, pql.EQ, 5, 5, false},
|
||||
{f1, pql.EQ, -8, 0, true},
|
||||
{f1, pql.EQ, 1005, 0, true},
|
||||
{f1, pql.EQ, 0, 0, false},
|
||||
|
||||
{f2, pql.EQ, 5, 0, true},
|
||||
{f2, pql.EQ, -8, 0, true},
|
||||
{f2, pql.EQ, 105, 5, false},
|
||||
{f2, pql.EQ, 1105, 0, true},
|
||||
} {
|
||||
bv, oor := tt.f.BaseValue(tt.op, tt.val)
|
||||
if oor != tt.expOutOfRange {
|
||||
t.Fatalf("baseValue calculation on %s op %s, expected outOfRange %v, got %v", tt.f.Name, tt.op, tt.expOutOfRange, oor)
|
||||
} else if !reflect.DeepEqual(bv, tt.expBaseValue) {
|
||||
t.Fatalf("baseValue calculation on %s, expected value %v, got %v", tt.f.Name, tt.expBaseValue, bv)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Betwween Condition", func(t *testing.T) {
|
||||
for _, tt := range []struct {
|
||||
f *pilosa.Field
|
||||
predMin int64
|
||||
predMax int64
|
||||
expBaseValueMin uint64
|
||||
expBaseValueMax uint64
|
||||
expOutOfRange bool
|
||||
}{
|
||||
|
||||
{f0, -205, -105, 0, 0, true},
|
||||
{f0, -105, 80, 0, 180, false},
|
||||
{f0, 5, 20, 105, 120, false},
|
||||
{f0, 20, 1005, 120, 1000, false},
|
||||
{f0, 1005, 2000, 0, 0, true},
|
||||
|
||||
{f1, -105, -5, 0, 0, true},
|
||||
{f1, -5, 20, 0, 20, false},
|
||||
{f1, 5, 20, 5, 20, false},
|
||||
{f1, 20, 1005, 20, 1000, false},
|
||||
{f1, 1005, 2000, 0, 0, true},
|
||||
|
||||
{f2, 5, 95, 0, 0, true},
|
||||
{f2, 95, 120, 0, 20, false},
|
||||
{f2, 105, 120, 5, 20, false},
|
||||
{f2, 120, 1105, 20, 1000, false},
|
||||
{f2, 1105, 2000, 0, 0, true},
|
||||
} {
|
||||
min, max, oor := tt.f.BaseValueBetween(tt.predMin, tt.predMax)
|
||||
if oor != tt.expOutOfRange {
|
||||
t.Fatalf("baseValueBetween calculation on %s, expected outOfRange %v, got %v", tt.f.Name, tt.expOutOfRange, oor)
|
||||
} else if !reflect.DeepEqual(min, tt.expBaseValueMin) || !reflect.DeepEqual(max, tt.expBaseValueMax) {
|
||||
t.Fatalf("baseValueBetween calculation on %s, expected min/max %v/%v, got %v/%v", tt.f.Name, tt.expBaseValueMin, tt.expBaseValueMax, min, max)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
240
handler_test.go
240
handler_test.go
|
|
@ -17,7 +17,6 @@ package pilosa_test
|
|||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
|
|
@ -817,245 +816,6 @@ func TestHandler_Frame_AttrStore_Diff(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// Ensure the handler can create a new field on an existing frame.
|
||||
func TestHandler_Frame_AddField(t *testing.T) {
|
||||
hldr := test.MustOpenHolder()
|
||||
defer hldr.Close()
|
||||
|
||||
s := test.NewServer()
|
||||
s.Handler.API.Holder = hldr.Holder
|
||||
defer s.Close()
|
||||
|
||||
t.Run("OK", func(t *testing.T) {
|
||||
idx := hldr.MustCreateIndexIfNotExists("i", pilosa.IndexOptions{})
|
||||
f, err := idx.CreateFrameIfNotExists("f", pilosa.FrameOptions{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
resp, err := http.Post(
|
||||
s.URL+"/index/i/frame/f/field/x",
|
||||
"application/json",
|
||||
strings.NewReader(`{"type":"int","min":100,"max":200}`),
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
} else if err := resp.Body.Close(); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if resp.StatusCode != http.StatusOK {
|
||||
t.Fatalf("unexpected status code: %d", resp.StatusCode)
|
||||
}
|
||||
|
||||
if field := f.Field("x"); !reflect.DeepEqual(field, &pilosa.Field{Name: "x", Type: "int", Min: 100, Max: 200}) {
|
||||
t.Fatalf("unexpected field: %#v", field)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("ErrInvalidFieldType", func(t *testing.T) {
|
||||
idx := hldr.MustCreateIndexIfNotExists("i", pilosa.IndexOptions{})
|
||||
if _, err := idx.CreateFrameIfNotExists("f", pilosa.FrameOptions{}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
resp, err := http.Post(
|
||||
s.URL+"/index/i/frame/f/field/x",
|
||||
"application/json",
|
||||
strings.NewReader(`{"type":"bad_type","min":100,"max":200}`),
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
} else if body := MustReadAll(resp.Body); string(body) != `creating field: validating field: invalid field type`+"\n" {
|
||||
t.Fatalf("unexpected body: %q", body)
|
||||
} else if err := resp.Body.Close(); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if resp.StatusCode != http.StatusInternalServerError {
|
||||
t.Fatalf("unexpected status code: %d", resp.StatusCode)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("ErrInvalidFieldRange", func(t *testing.T) {
|
||||
idx := hldr.MustCreateIndexIfNotExists("i", pilosa.IndexOptions{})
|
||||
if _, err := idx.CreateFrameIfNotExists("f", pilosa.FrameOptions{}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
resp, err := http.Post(
|
||||
s.URL+"/index/i/frame/f/field/x",
|
||||
"application/json",
|
||||
strings.NewReader(`{"type":"int","min":200,"max":100}`),
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
} else if body := MustReadAll(resp.Body); string(body) != `creating field: validating field: invalid field range`+"\n" {
|
||||
t.Fatalf("unexpected body: %q", body)
|
||||
} else if err := resp.Body.Close(); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if resp.StatusCode != http.StatusInternalServerError {
|
||||
t.Fatalf("unexpected status code: %d", resp.StatusCode)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("ErrFieldAlreadyExists", func(t *testing.T) {
|
||||
idx := hldr.MustCreateIndexIfNotExists("i", pilosa.IndexOptions{})
|
||||
if _, err := idx.CreateFrameIfNotExists("f", pilosa.FrameOptions{
|
||||
Fields: []*pilosa.Field{{Name: "x", Type: pilosa.FieldTypeInt, Min: 0, Max: 100}},
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
resp, err := http.Post(
|
||||
s.URL+"/index/i/frame/f/field/x",
|
||||
"application/json",
|
||||
strings.NewReader(`{"type":"int","min":0,"max":100}`),
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
} else if body := MustReadAll(resp.Body); string(body) != `creating field: field already exists`+"\n" {
|
||||
t.Fatalf("unexpected body: %q", body)
|
||||
} else if err := resp.Body.Close(); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if resp.StatusCode != http.StatusInternalServerError {
|
||||
t.Fatalf("unexpected status code: %d", resp.StatusCode)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Ensure the handler can delete existing fields.
|
||||
func TestHandler_Frame_DeleteField(t *testing.T) {
|
||||
hldr := test.MustOpenHolder()
|
||||
defer hldr.Close()
|
||||
|
||||
s := test.NewServer()
|
||||
s.Handler.API.Holder = hldr.Holder
|
||||
defer s.Close()
|
||||
|
||||
t.Run("OK", func(t *testing.T) {
|
||||
idx := hldr.MustCreateIndexIfNotExists("i", pilosa.IndexOptions{})
|
||||
f, err := idx.CreateFrameIfNotExists("f", pilosa.FrameOptions{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
} else if err := f.CreateField(&pilosa.Field{Name: "x", Type: pilosa.FieldTypeInt, Min: 0, Max: 100}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("DELETE", s.URL+"/index/i/frame/f/field/x", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
} else if err := resp.Body.Close(); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if resp.StatusCode != http.StatusOK {
|
||||
t.Fatalf("unexpected status code: %d", resp.StatusCode)
|
||||
}
|
||||
|
||||
if field := f.Field("x"); field != nil {
|
||||
t.Fatalf("expected nil field, got: %#v", field)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("ErrFieldNotFound", func(t *testing.T) {
|
||||
idx := hldr.MustCreateIndexIfNotExists("i", pilosa.IndexOptions{})
|
||||
f, err := idx.CreateFrameIfNotExists("f", pilosa.FrameOptions{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
} else if err := f.CreateField(&pilosa.Field{Name: "x", Type: pilosa.FieldTypeInt, Min: 0, Max: 100}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("DELETE", s.URL+"/index/i/frame/f/field/y", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
} else if body, err := ioutil.ReadAll(resp.Body); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if strings.TrimSpace(string(body)) != `deleting field: field not found` {
|
||||
t.Fatalf("unexpected body: %q", body)
|
||||
} else if err := resp.Body.Close(); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if resp.StatusCode != http.StatusInternalServerError {
|
||||
t.Fatalf("unexpected status code: %d", resp.StatusCode)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestHandler_Frame_GetFields(t *testing.T) {
|
||||
hldr := test.MustOpenHolder()
|
||||
defer hldr.Close()
|
||||
|
||||
s := test.NewServer()
|
||||
s.Handler.API.Holder = hldr.Holder
|
||||
defer s.Close()
|
||||
|
||||
t.Run("OK", func(t *testing.T) {
|
||||
idx := hldr.MustCreateIndexIfNotExists("i", pilosa.IndexOptions{})
|
||||
f, err := idx.CreateFrameIfNotExists("f", pilosa.FrameOptions{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
} else if err := f.CreateField(&pilosa.Field{Name: "x", Type: pilosa.FieldTypeInt, Min: 1, Max: 100}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
resp, err := http.Get(s.URL + "/index/i/frame/f/fields")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
} else if resp.StatusCode != http.StatusOK {
|
||||
t.Fatalf("unexpected status code: %d", resp.StatusCode)
|
||||
}
|
||||
|
||||
var fields FrameFields
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err = json.Unmarshal([]byte(body), &fields); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
field := fields.Fields[0]
|
||||
if field.Name != "x" {
|
||||
t.Fatalf("expected field's name: x, actuall name: %v", field.Name)
|
||||
} else if field.Min != 1 {
|
||||
t.Fatalf("expected field's min: x, actuall min: %v", field.Min)
|
||||
} else if field.Max != 100 {
|
||||
t.Fatalf("expected field's max: x, actuall max: %v", field.Max)
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
t.Run("ErrFrameFieldNotAllowed", func(t *testing.T) {
|
||||
idx := hldr.MustCreateIndexIfNotExists("i", pilosa.IndexOptions{})
|
||||
_, err := idx.CreateFrameIfNotExists("f1", pilosa.FrameOptions{})
|
||||
if err != nil {
|
||||
t.Fatalf("creating frame: %v", err)
|
||||
}
|
||||
|
||||
resp, err := http.Get(s.URL + "/index/i/frame/f1/fields")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
} else if resp.StatusCode != http.StatusOK {
|
||||
t.Fatalf("unexpected status code: %d", resp.StatusCode)
|
||||
} else if body, err := ioutil.ReadAll(resp.Body); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if strings.TrimSpace(string(body)) == `frame fields not allowed` {
|
||||
t.Fatalf("shouldn't get frame fields not allowed error: %q", body)
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
type FrameFields struct {
|
||||
Fields []pilosa.Field
|
||||
}
|
||||
|
||||
// Ensure the handler can retrieve the version.
|
||||
func TestHandler_Version(t *testing.T) {
|
||||
hldr := test.MustOpenHolder()
|
||||
|
|
|
|||
156
index_test.go
156
index_test.go
|
|
@ -57,7 +57,10 @@ func TestIndex_CreateFrame(t *testing.T) {
|
|||
defer index.Close()
|
||||
|
||||
// Create frame with explicit quantum.
|
||||
f, err := index.CreateFrame("f", pilosa.FrameOptions{TimeQuantum: pilosa.TimeQuantum("YMDH")})
|
||||
f, err := index.CreateFrame("f", pilosa.FrameOptions{
|
||||
Type: pilosa.FrameTypeTime,
|
||||
TimeQuantum: pilosa.TimeQuantum("YMDH"),
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
} else if q := f.TimeQuantum(); q != pilosa.TimeQuantum("YMDH") {
|
||||
|
|
@ -74,103 +77,100 @@ func TestIndex_CreateFrame(t *testing.T) {
|
|||
|
||||
// Create frame with schema and verify it exists.
|
||||
if f, err := index.CreateFrame("f", pilosa.FrameOptions{
|
||||
Fields: []*pilosa.Field{
|
||||
{Name: "field0", Type: pilosa.FieldTypeInt, Min: 10, Max: 20},
|
||||
{Name: "field1", Type: pilosa.FieldTypeInt, Min: 11, Max: 21},
|
||||
},
|
||||
Type: pilosa.FrameTypeInt,
|
||||
Min: 10,
|
||||
Max: 20,
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if !reflect.DeepEqual(f.Fields(), []*pilosa.Field{
|
||||
{Name: "field0", Type: pilosa.FieldTypeInt, Min: 10, Max: 20},
|
||||
{Name: "field1", Type: pilosa.FieldTypeInt, Min: 11, Max: 21},
|
||||
}) {
|
||||
t.Fatalf("unexpected fields: %#v", f.Fields())
|
||||
} else if !reflect.DeepEqual(f.Type(), pilosa.FrameTypeInt) {
|
||||
t.Fatalf("unexpected type: %#v", f.Type())
|
||||
}
|
||||
|
||||
// Reopen the index & verify the fields are loaded.
|
||||
if err := index.Reopen(); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if f := index.Frame("f"); !reflect.DeepEqual(f.Fields(), []*pilosa.Field{
|
||||
{Name: "field0", Type: pilosa.FieldTypeInt, Min: 10, Max: 20},
|
||||
{Name: "field1", Type: pilosa.FieldTypeInt, Min: 11, Max: 21},
|
||||
}) {
|
||||
t.Fatalf("unexpected fields after reopen: %#v", f.Fields())
|
||||
} else if f := index.Frame("f"); !reflect.DeepEqual(f.Type(), pilosa.FrameTypeInt) {
|
||||
t.Fatalf("unexpected type after reopen: %#v", f.Type())
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("ErrRangeCacheAllowed", func(t *testing.T) {
|
||||
index := test.MustOpenIndex()
|
||||
defer index.Close()
|
||||
// TODO: These errors don't apply here. Instead, we need these tests
|
||||
// on frame creation FrameOptions validation.
|
||||
/*
|
||||
t.Run("ErrRangeCacheAllowed", func(t *testing.T) {
|
||||
index := test.MustOpenIndex()
|
||||
defer index.Close()
|
||||
|
||||
if _, err := index.CreateFrame("f", pilosa.FrameOptions{
|
||||
CacheType: pilosa.CacheTypeRanked,
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
})
|
||||
if _, err := index.CreateFrame("f", pilosa.FrameOptions{
|
||||
CacheType: pilosa.CacheTypeRanked,
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("BSIFieldsWithCacheTypeNone", func(t *testing.T) {
|
||||
index := test.MustOpenIndex()
|
||||
defer index.Close()
|
||||
if _, err := index.CreateFrame("f", pilosa.FrameOptions{
|
||||
CacheType: pilosa.CacheTypeNone,
|
||||
CacheSize: uint32(5),
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
})
|
||||
t.Run("BSIFieldsWithCacheTypeNone", func(t *testing.T) {
|
||||
index := test.MustOpenIndex()
|
||||
defer index.Close()
|
||||
if _, err := index.CreateFrame("f", pilosa.FrameOptions{
|
||||
CacheType: pilosa.CacheTypeNone,
|
||||
CacheSize: uint32(5),
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("ErrFrameFieldsAllowed", func(t *testing.T) {
|
||||
index := test.MustOpenIndex()
|
||||
defer index.Close()
|
||||
t.Run("ErrFrameFieldsAllowed", func(t *testing.T) {
|
||||
index := test.MustOpenIndex()
|
||||
defer index.Close()
|
||||
|
||||
if _, err := index.CreateFrame("f", pilosa.FrameOptions{
|
||||
Fields: []*pilosa.Field{
|
||||
{Name: "field0", Type: pilosa.FieldTypeInt},
|
||||
},
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
})
|
||||
if _, err := index.CreateFrame("f", pilosa.FrameOptions{
|
||||
Fields: []*pilosa.Field{
|
||||
{Name: "field0", Type: pilosa.FieldTypeInt},
|
||||
},
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("ErrFieldNameRequired", func(t *testing.T) {
|
||||
index := test.MustOpenIndex()
|
||||
defer index.Close()
|
||||
t.Run("ErrFieldNameRequired", func(t *testing.T) {
|
||||
index := test.MustOpenIndex()
|
||||
defer index.Close()
|
||||
|
||||
if _, err := index.CreateFrame("f", pilosa.FrameOptions{
|
||||
Fields: []*pilosa.Field{
|
||||
{Name: "", Type: pilosa.FieldTypeInt},
|
||||
},
|
||||
}); err != pilosa.ErrFieldNameRequired {
|
||||
t.Fatal(err)
|
||||
}
|
||||
})
|
||||
if _, err := index.CreateFrame("f", pilosa.FrameOptions{
|
||||
Fields: []*pilosa.Field{
|
||||
{Name: "", Type: pilosa.FieldTypeInt},
|
||||
},
|
||||
}); err != pilosa.ErrFieldNameRequired {
|
||||
t.Fatal(err)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("ErrInvalidFieldType", func(t *testing.T) {
|
||||
index := test.MustOpenIndex()
|
||||
defer index.Close()
|
||||
t.Run("ErrInvalidFieldType", func(t *testing.T) {
|
||||
index := test.MustOpenIndex()
|
||||
defer index.Close()
|
||||
|
||||
if _, err := index.CreateFrame("f", pilosa.FrameOptions{
|
||||
Fields: []*pilosa.Field{
|
||||
{Name: "field0", Type: "bad_type"},
|
||||
},
|
||||
}); err != pilosa.ErrInvalidFieldType {
|
||||
t.Fatal(err)
|
||||
}
|
||||
})
|
||||
if _, err := index.CreateFrame("f", pilosa.FrameOptions{
|
||||
Fields: []*pilosa.Field{
|
||||
{Name: "field0", Type: "bad_type"},
|
||||
},
|
||||
}); err != pilosa.ErrInvalidFieldType {
|
||||
t.Fatal(err)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("ErrInvalidFieldRange", func(t *testing.T) {
|
||||
index := test.MustOpenIndex()
|
||||
defer index.Close()
|
||||
t.Run("ErrInvalidFieldRange", func(t *testing.T) {
|
||||
index := test.MustOpenIndex()
|
||||
defer index.Close()
|
||||
|
||||
if _, err := index.CreateFrame("f", pilosa.FrameOptions{
|
||||
Fields: []*pilosa.Field{
|
||||
{Name: "field0", Type: pilosa.FieldTypeInt, Min: 100, Max: 50},
|
||||
},
|
||||
}); err != pilosa.ErrInvalidFieldRange {
|
||||
t.Fatal(err)
|
||||
}
|
||||
})
|
||||
if _, err := index.CreateFrame("f", pilosa.FrameOptions{
|
||||
Fields: []*pilosa.Field{
|
||||
{Name: "field0", Type: pilosa.FieldTypeInt, Min: 100, Max: 50},
|
||||
},
|
||||
}); err != pilosa.ErrInvalidFieldRange {
|
||||
t.Fatal(err)
|
||||
}
|
||||
})
|
||||
*/
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,12 +29,12 @@ type Frame struct {
|
|||
}
|
||||
|
||||
// NewFrame returns a new instance of Frame d/0.
|
||||
func NewFrame() *Frame {
|
||||
func NewFrame(opt ...pilosa.FrameOption) *Frame {
|
||||
path, err := ioutil.TempDir("", "pilosa-frame-")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
frame, err := pilosa.NewFrame(path, "i", "f")
|
||||
frame, err := pilosa.NewFrame(path, "i", "f", opt...)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
|
@ -42,8 +42,8 @@ func NewFrame() *Frame {
|
|||
}
|
||||
|
||||
// MustOpenFrame returns a new, opened frame at a temporary path. Panic on error.
|
||||
func MustOpenFrame() *Frame {
|
||||
f := NewFrame()
|
||||
func MustOpenFrame(opt ...pilosa.FrameOption) *Frame {
|
||||
f := NewFrame(opt...)
|
||||
if err := f.Open(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue