From f6d17b1b583e24f125ba20d301e3003457f26094 Mon Sep 17 00:00:00 2001 From: Seebs Date: Mon, 8 Aug 2022 15:50:44 -0500 Subject: [PATCH] refactor testing to share clusters more often When doing tests, we create a ton of one-off clusters. This turns out to be expensive and slow. Fixing it is surprisingly hard. Fundamentally: If we're sharing clusters, we need to use different indexes for each test, to avoid clashes. This changes index names. As a side-effect, this reorders many partition-based things, like the order keys are returned in. Thus, to fix this, we change a lot of tests to no longer depend on the *order* in which strings are returned. Having done that, we can also discard the ModHasher behavior, since that only existed to allow us to reliably predict partitioning. The basic design is as follows: Instead of a cluster being a []*Command, a "shareable" cluster is now a []*Command plus some flags, and a "cluster" is a pointer to a possibly-shared cluster, plus a link to the specific test using this specific cluster, and correspondingly, its test name suitably coerced to be a valid index name prefix. The "test.Cluster" object now has methods to allow retrieving an index name, and also implemnts fmt.Formatter to let you use, e.g., `%i` with it in Sprintf to get "the index name, plus an i". (This works for everything but %p and %T.) This allows us to consistently rework all the many things that use index names in a persistent way. We also have `MustUnshared` and `MustRunUnsharedCluster` methods which allow us to specify that a given test needs its own cluster for some reason. For instance, the tests that want to run backups need their own isolated cluster, and the tests that want to close or reopen nodes need their own cluster because a reopened cluster won't have working GRPC for some reason. On "closing" a shared cluster (actually the test-specific wrapper that reflects a given sharing), we delete any indexes starting with that test's index name prefix. Otherwise, the huge pile of open indexes prevents `go test -race` from working on MacOS, where we run out of address space too quickly. This is fairly enormous but most of the individual changes are fairly trivial things like replacing the string "i" with "c.Idx()". We also tweaked a test that failed for me a couple of times to not depend on sort order. --- api_test.go | 215 ++-- client/client_it_test.go | 2 +- cluster_internal_test.go | 50 +- ctl/import_test.go | 33 +- dbshard_test.go | 30 +- delete_test.go | 27 +- executor.go | 18 +- executor_internal_test.go | 25 + executor_test.go | 1531 +++++++++++++------------ holder_test.go | 154 +-- http_handler_test.go | 127 +- index_test.go | 2 +- internal_client_test.go | 458 ++++---- server/handler_test.go | 32 +- server/server_test.go | 34 +- server_test.go | 4 +- sql/handler_test.go | 9 +- sql3/planner/executionplanner_test.go | 134 +-- stats/stats_test.go | 7 +- test/cluster.go | 321 +++++- test/disco.go | 3 +- test/glue.go | 129 +++ test/pilosa.go | 22 +- testdata/schema.json | 6 +- translator_test.go | 152 +-- tx_test.go | 18 +- utils_internal_test.go | 14 +- 27 files changed, 1909 insertions(+), 1648 deletions(-) create mode 100644 test/glue.go diff --git a/api_test.go b/api_test.go index 1c5ae6f24..3fc6f464c 100644 --- a/api_test.go +++ b/api_test.go @@ -23,48 +23,25 @@ import ( "time" "github.com/golang-jwt/jwt" - pilosa "github.com/featurebasedb/featurebase/v3" - "github.com/featurebasedb/featurebase/v3/authn" - "github.com/featurebasedb/featurebase/v3/boltdb" - "github.com/featurebasedb/featurebase/v3/roaring" - "github.com/featurebasedb/featurebase/v3/server" - "github.com/featurebasedb/featurebase/v3/shardwidth" - "github.com/featurebasedb/featurebase/v3/test" - . "github.com/featurebasedb/featurebase/v3/vprint" // nolint:staticcheck + pilosa "github.com/molecula/featurebase/v3" + "github.com/molecula/featurebase/v3/authn" + "github.com/molecula/featurebase/v3/roaring" + "github.com/molecula/featurebase/v3/server" + "github.com/molecula/featurebase/v3/shardwidth" + "github.com/molecula/featurebase/v3/test" + . "github.com/molecula/featurebase/v3/vprint" // nolint:staticcheck "golang.org/x/sync/errgroup" ) func TestAPI_Import(t *testing.T) { - c := test.MustRunCluster(t, 3, - []server.CommandOption{ - server.OptCommandServerOptions( - pilosa.OptServerNodeID("node0"), - pilosa.OptServerClusterHasher(&offsetModHasher{}), - pilosa.OptServerOpenTranslateStore(boltdb.OpenTranslateStore), - pilosa.OptServerOpenTranslateReader(pilosa.GetOpenTranslateReaderFunc(nil)), - )}, - []server.CommandOption{ - server.OptCommandServerOptions( - pilosa.OptServerNodeID("node1"), - pilosa.OptServerClusterHasher(&offsetModHasher{}), - pilosa.OptServerOpenTranslateStore(boltdb.OpenTranslateStore), - pilosa.OptServerOpenTranslateReader(pilosa.GetOpenTranslateReaderFunc(nil)), - )}, - []server.CommandOption{ - server.OptCommandServerOptions( - pilosa.OptServerNodeID("node2"), - pilosa.OptServerClusterHasher(&offsetModHasher{}), - pilosa.OptServerOpenTranslateStore(boltdb.OpenTranslateStore), - pilosa.OptServerOpenTranslateReader(pilosa.GetOpenTranslateReaderFunc(nil)), - )}, - ) + c := test.MustRunCluster(t, 3) defer c.Close() m0 := c.GetNode(0) m1 := c.GetNode(1) - indexNames := map[bool]string{false: "i", true: "ki"} + indexNames := map[bool]string{false: c.Idx("u"), true: c.Idx("k")} fieldNames := map[bool]string{false: "f", true: "kf"} ctx := context.Background() @@ -104,7 +81,7 @@ func TestAPI_Import(t *testing.T) { t.Run("RowIDColumnKey", func(t *testing.T) { // Import data with keys to the primary and verify that it gets - // translated and forwarded to the owner of shard 0 (node1; because of offsetModHasher) + // translated and forwarded to the owner of shard 0 req := &pilosa.ImportRequest{ Index: indexNames[true], Field: fieldNames[false], @@ -152,7 +129,7 @@ func TestAPI_Import(t *testing.T) { } }) t.Run("ExpectedErrors", func(t *testing.T) { - t.Skip() // skipping due to change partitioning strategy + t.Skip("partitioning strategy changed, test not supported") // skipping due to change partitioning strategy ctx := context.Background() for ik, indexName := range indexNames { for fk, fieldName := range fieldNames { @@ -224,26 +201,7 @@ func TestAPI_Import(t *testing.T) { } func TestAPI_ImportValue(t *testing.T) { - c := test.MustRunCluster(t, 3, - []server.CommandOption{ - server.OptCommandServerOptions( - pilosa.OptServerNodeID("node0"), - pilosa.OptServerClusterHasher(&offsetModHasher{}), - pilosa.OptServerOpenTranslateReader(pilosa.GetOpenTranslateReaderFunc(nil)), - )}, - []server.CommandOption{ - server.OptCommandServerOptions( - pilosa.OptServerNodeID("node1"), - pilosa.OptServerClusterHasher(&offsetModHasher{}), - pilosa.OptServerOpenTranslateReader(pilosa.GetOpenTranslateReaderFunc(nil)), - )}, - []server.CommandOption{ - server.OptCommandServerOptions( - pilosa.OptServerNodeID("node2"), - pilosa.OptServerClusterHasher(&offsetModHasher{}), - pilosa.OptServerOpenTranslateReader(pilosa.GetOpenTranslateReaderFunc(nil)), - )}, - ) + c := test.MustRunCluster(t, 3) defer c.Close() coord := c.GetPrimary() @@ -253,7 +211,7 @@ func TestAPI_ImportValue(t *testing.T) { t.Run("ValColumnKey", func(t *testing.T) { ctx := context.Background() - index := "valck" + index := c.Idx("valck") field := "f" _, err := coord.API.CreateIndex(ctx, index, pilosa.IndexOptions{Keys: true}) @@ -275,7 +233,7 @@ func TestAPI_ImportValue(t *testing.T) { colKeys := []string{"col10", "col8", "col9", "col6", "col7", "col4", "col5", "col2", "col3", "col1"} // Import data with keys to the primary and verify that it gets - // translated and forwarded to the owner of shard 0 (node1; because of offsetModHasher) + // translated and forwarded to the owner of shard 0 req := &pilosa.ImportValueRequest{ Index: index, Field: field, @@ -293,18 +251,24 @@ func TestAPI_ImportValue(t *testing.T) { pql := fmt.Sprintf("Row(%s>0)", field) // Query node0. - if res, err := m0.API.Query(ctx, &pilosa.QueryRequest{Index: index, Query: pql}); err != nil { + res, err := m0.API.Query(ctx, &pilosa.QueryRequest{Index: index, Query: pql}) + if err != nil { t.Fatal(err) - } else if keys := res.Results[0].(*pilosa.Row).Keys; !reflect.DeepEqual(keys, colKeys) { + } + keys := res.Results[0].(*pilosa.Row).Keys + if !sameStringSlice(keys, colKeys) { t.Fatalf("unexpected column keys: %+v", keys) } // Query node1. if err := test.RetryUntil(5*time.Second, func() error { - if res, err := m1.API.Query(ctx, &pilosa.QueryRequest{Index: index, Query: pql}); err != nil { - return err - } else if keys := res.Results[0].(*pilosa.Row).Keys; !reflect.DeepEqual(keys, colKeys) { - return fmt.Errorf("unexpected column keys: %+v", keys) + res, err := m1.API.Query(ctx, &pilosa.QueryRequest{Index: index, Query: pql}) + if err != nil { + t.Fatal(err) + } + keys := res.Results[0].(*pilosa.Row).Keys + if !sameStringSlice(keys, colKeys) { + t.Fatalf("unexpected column keys: %+v", keys) } return nil }); err != nil { @@ -314,7 +278,7 @@ func TestAPI_ImportValue(t *testing.T) { t.Run("ValIntEmpty", func(t *testing.T) { ctx := context.Background() - index := "valintempty" + index := c.Idx("valintempty") field := "fld" createIndexForTest(index, coord, t) createFieldForTest(index, field, coord, t) @@ -387,7 +351,7 @@ func TestAPI_ImportValue(t *testing.T) { colIDs = append(colIDs, uint64(i)) } // Import data with keys to node1 and verify that it gets translated and - // forwarded to the owner of shard 0 (node0; because of offsetModHasher) + // forwarded to the owner of shard 0 req := &pilosa.ImportValueRequest{ Index: index, Field: field, @@ -410,7 +374,7 @@ func TestAPI_ImportValue(t *testing.T) { t.Run("ValDecimalFieldNegativeScale", func(t *testing.T) { ctx := context.Background() - index := "valdecneg" + index := c.Idx("valdecneg") field := "fdecneg" _, err := m0.API.CreateIndex(ctx, index, pilosa.IndexOptions{}) @@ -424,9 +388,9 @@ func TestAPI_ImportValue(t *testing.T) { }) t.Run("ValTimestampField", func(t *testing.T) { - t.Skip() // skipping due to change partitioning strategy + t.Skip("partition strategy change invalidated") // skipping due to change partitioning strategy ctx := context.Background() - index := "valts" + index := c.Idx("valts") field := "fts" _, err := m1.API.CreateIndex(ctx, index, pilosa.IndexOptions{}) @@ -447,7 +411,7 @@ func TestAPI_ImportValue(t *testing.T) { } // Import data with keys to node1 and verify that it gets translated and - // forwarded to the owner of shard 0 (node0; because of offsetModHasher) + // forwarded to the owner of shard 0 req := &pilosa.ImportValueRequest{ Index: index, Field: field, @@ -472,9 +436,9 @@ func TestAPI_ImportValue(t *testing.T) { }) t.Run("ValStringField", func(t *testing.T) { - t.Skip() // skipping due to change partitioning strategy + t.Skip("partition strategy change invalidated") // skipping due to change partitioning strategy ctx := context.Background() - index := "valstr" + index := c.Idx("valstr") field := "fstr" fgnIndex := "fgnvalstr" @@ -506,8 +470,7 @@ func TestAPI_ImportValue(t *testing.T) { } // Import data with keys to the node0 and verify that it gets translated - // and forwarded to the owner of shard 0 (node1; because of - // offsetModHasher) + // and forwarded to the owner of shard 0 req := &pilosa.ImportValueRequest{ Index: index, Field: field, @@ -534,17 +497,10 @@ func TestAPI_ImportValue(t *testing.T) { func TestAPI_Ingest(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - c := test.MustRunCluster(t, 1, - []server.CommandOption{ - server.OptCommandServerOptions( - pilosa.OptServerNodeID("node0"), - pilosa.OptServerClusterHasher(&offsetModHasher{}), - pilosa.OptServerOpenTranslateReader(pilosa.GetOpenTranslateReaderFunc(nil)), - )}, - ) + c := test.MustRunCluster(t, 1) defer c.Close() coord := c.GetPrimary() - index := "ingest" + index := c.Idx() setField := "set" timeField := "tq" intField := "int" @@ -654,7 +610,7 @@ func TestAPI_Ingest(t *testing.T) { }, }, } - if err := coord.API.ImportRoaringShard(context.Background(), "ingest", 8, request); err != nil { + if err := coord.API.ImportRoaringShard(context.Background(), c.Idx(), 8, request); err != nil { t.Fatalf("ingesting: %v", err) } @@ -666,19 +622,19 @@ func TestAPI_Ingest(t *testing.T) { return res } - res := mustQuery(t, "ingest", "Row(set=0)") + res := mustQuery(t, c.Idx(), "Row(set=0)") r := res.Results[0].(*pilosa.Row).Columns() if len(r) != 1 || r[0] != pilosa.ShardWidth*8+7 { t.Fatalf("expected row with pilosa.ShardWidth*8+7 set, got %d", r) } - res = mustQuery(t, "ingest", "Row(set=1)") + res = mustQuery(t, c.Idx(), "Row(set=1)") r = res.Results[0].(*pilosa.Row).Columns() if len(r) != 1 || r[0] != pilosa.ShardWidth*8+7 { t.Fatalf("expected row with pilosa.ShardWidth*8+7 set, got %d", r) } - res = mustQuery(t, "ingest", "Row(int==1)") + res = mustQuery(t, c.Idx(), "Row(int==1)") r = res.Results[0].(*pilosa.Row).Columns() if len(r) != 1 || r[0] != pilosa.ShardWidth*8+7 { t.Fatalf("expected row with, pilosa.ShardWidth*8+7 set, got %d", r) @@ -699,23 +655,23 @@ func TestAPI_Ingest(t *testing.T) { }, }, } - if err := coord.API.ImportRoaringShard(context.Background(), "ingest", 8, request); err != nil { + if err := coord.API.ImportRoaringShard(context.Background(), c.Idx(), 8, request); err != nil { t.Fatalf("ingesting: %v", err) } - res = mustQuery(t, "ingest", "Row(set=0)") + res = mustQuery(t, c.Idx(), "Row(set=0)") r = res.Results[0].(*pilosa.Row).Columns() if len(r) != 0 { t.Fatalf("expected no values after clearing, got: %v", r) } - res = mustQuery(t, "ingest", "Row(set=1)") + res = mustQuery(t, c.Idx(), "Row(set=1)") r = res.Results[0].(*pilosa.Row).Columns() if len(r) != 0 { t.Fatalf("expected no values after clearing, got: %v", r) } - res = mustQuery(t, "ingest", "Row(int==1)") + res = mustQuery(t, c.Idx(), "Row(int==1)") r = res.Results[0].(*pilosa.Row).Columns() if len(r) != 0 { t.Fatalf("expected no values after clearing, got: %v", r) @@ -747,14 +703,7 @@ func BenchmarkIngest(b *testing.B) { data := ingestBenchmarkHelper() ctx, cancel := context.WithCancel(context.Background()) defer cancel() - c := test.MustRunCluster(b, 1, - []server.CommandOption{ - server.OptCommandServerOptions( - pilosa.OptServerNodeID("node0"), - pilosa.OptServerClusterHasher(&offsetModHasher{}), - pilosa.OptServerOpenTranslateReader(pilosa.GetOpenTranslateReaderFunc(nil)), - )}, - ) + c := test.MustRunCluster(b, 1) defer c.Close() coord := c.GetPrimary() @@ -762,7 +711,7 @@ func BenchmarkIngest(b *testing.B) { // m1 := c.GetNode(1) // m2 := c.GetNode(2) - index := "ingest" + index := c.Idx() setField := "set" intField := "int" tqField := "tq" @@ -798,24 +747,8 @@ func BenchmarkIngest(b *testing.B) { } } -// offsetModHasher represents a simple, mod-based hashing offset by 1. -type offsetModHasher struct{} - -func (*offsetModHasher) Hash(key uint64, n int) int { - return int(key+1) % n -} - -func (*offsetModHasher) Name() string { return "mod" } - func TestAPI_ClearFlagForImportAndImportValues(t *testing.T) { - c := test.MustRunCluster(t, 1, - []server.CommandOption{ - server.OptCommandServerOptions( - pilosa.OptServerNodeID("node0"), - pilosa.OptServerClusterHasher(&offsetModHasher{}), - pilosa.OptServerOpenTranslateReader(pilosa.GetOpenTranslateReaderFunc(nil)), - )}, - ) + c := test.MustRunCluster(t, 1) defer c.Close() // plan: @@ -828,7 +761,7 @@ func TestAPI_ClearFlagForImportAndImportValues(t *testing.T) { m0api := m0.API ctx := context.Background() - index := "i" + index := c.Idx() fieldAcct0 := "acct0" opts := pilosa.OptFieldTypeInt(-1000, 1000) @@ -1072,7 +1005,9 @@ type mutexCheckField struct { } func TestAPI_MutexCheck(t *testing.T) { - c := test.MustNewCluster(t, 3) + // Can't share this one, because it has to get custom option settings and needs + // replication. + c := test.MustUnsharedCluster(t, 3) for _, c := range c.Nodes { c.Config.Cluster.ReplicaN = 2 } @@ -1094,7 +1029,7 @@ func TestAPI_MutexCheck(t *testing.T) { ctx := context.Background() for _, keyedIndex := range []bool{false, true} { - indexName := fmt.Sprintf("i%t", keyedIndex) + indexName := c.Idx(map[bool]string{false: "u", true: "k"}[keyedIndex]) index, err := m0.API.CreateIndex(ctx, indexName, pilosa.IndexOptions{Keys: keyedIndex, TrackExistence: true}) if err != nil { t.Fatalf("creating index: %v", err) @@ -1446,14 +1381,14 @@ func createFieldForTest(index string, field string, coord *test.Command, t *test func TestVariousApiTranslateCalls(t *testing.T) { for i := 1; i < 8; i += 3 { - m := test.MustRunCluster(t, i) - defer m.Close() - node := m.GetNode(0) + c := test.MustRunCluster(t, i) + defer c.Close() + node := c.GetNode(0) api := node.API // this should never actually get used because we're testing for errors here r := strings.NewReader("") // test index - idx, err := api.Holder().CreateIndex("index", pilosa.IndexOptions{}) + idx, err := api.Holder().CreateIndex(c.Idx(), pilosa.IndexOptions{}) if err != nil { t.Fatalf("%v: could not create test index", err) } @@ -1471,8 +1406,8 @@ func TestVariousApiTranslateCalls(t *testing.T) { t.Run("translateIndexDbOnNilTranslateStore", func(t *testing.T) { - err := api.TranslateIndexDB(context.Background(), "index", 0, r) - expected := fmt.Errorf("index %q has no translate store", "index") + err := api.TranslateIndexDB(context.Background(), c.Idx(), 0, r) + expected := fmt.Errorf("index %q has no translate store", c.Idx()) if !reflect.DeepEqual(err, expected) { t.Fatalf("expected '%#v', got '%#v'", expected, err) } @@ -1489,8 +1424,8 @@ func TestVariousApiTranslateCalls(t *testing.T) { t.Run("translateFieldDbOnNilField", func(t *testing.T) { - err := api.TranslateFieldDB(context.Background(), "index", "nonExistentField", r) - expected := fmt.Errorf("field %q/%q not found", "index", "nonExistentField") + err := api.TranslateFieldDB(context.Background(), c.Idx(), "nonExistentField", r) + expected := fmt.Errorf("field %q/%q not found", c.Idx(), "nonExistentField") if !reflect.DeepEqual(err, expected) { t.Fatalf("expected '%#v', got '%#v'", expected, err) } @@ -1498,7 +1433,7 @@ func TestVariousApiTranslateCalls(t *testing.T) { t.Run("translateFieldDbNilField_keys", func(t *testing.T) { - err := api.TranslateFieldDB(context.Background(), "index", "_keys", r) + err := api.TranslateFieldDB(context.Background(), c.Idx(), "_keys", r) if err != nil { t.Fatalf("expected 'nil', got '%#v'", err) } @@ -1508,8 +1443,8 @@ func TestVariousApiTranslateCalls(t *testing.T) { stores, which is a bug, but one that we will eventually fix. when we do, this test might come in handy t.Run("translateFieldDbOnNilTranslateStore", func(t *testing.T) { - err := api.TranslateFieldDB(context.Background(), "index", "field", r) - expected := fmt.Errorf("field %q/%q has no translate store", "index", "field") + err := api.TranslateFieldDB(context.Background(), c.Idx(), "field", r) + expected := fmt.Errorf("field %q/%q has no translate store", c.Idx(), "field") if !reflect.DeepEqual(err, expected) { t.Fatalf("expected '%#v', got '%#v'", expected, err) } @@ -1529,7 +1464,7 @@ func TestAPI_CreateField(t *testing.T) { nodes[i] = c.GetNode(i) } - if _, err := nodes[0].API.CreateIndex(ctx, "i", pilosa.IndexOptions{}); err != nil { + if _, err := nodes[0].API.CreateIndex(ctx, c.Idx(), pilosa.IndexOptions{}); err != nil { t.Fatal(err) } eg, ctx := errgroup.WithContext(context.Background()) @@ -1537,7 +1472,7 @@ func TestAPI_CreateField(t *testing.T) { node := n eg.Go(func() error { for i := 0; i < 10; i++ { - _, err := node.API.CreateField(ctx, "i", fmt.Sprintf("f%d", i)) + _, err := node.API.CreateField(ctx, c.Idx(), fmt.Sprintf("f%d", i)) if err != nil && !errors.Is(err, pilosa.ErrFieldExists) { return err } @@ -1557,19 +1492,12 @@ func TestAPI_CreateField(t *testing.T) { func TestAPI_RBFDebugInfo(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - c := test.MustRunCluster(t, 1, - []server.CommandOption{ - server.OptCommandServerOptions( - pilosa.OptServerNodeID("node0"), - pilosa.OptServerClusterHasher(&offsetModHasher{}), - pilosa.OptServerOpenTranslateReader(pilosa.GetOpenTranslateReaderFunc(nil)), - )}, - ) + c := test.MustRunCluster(t, 1) defer c.Close() coord := c.GetPrimary() - if _, err := coord.API.CreateIndex(ctx, "i", pilosa.IndexOptions{}); err != nil { + if _, err := coord.API.CreateIndex(ctx, c.Idx(), pilosa.IndexOptions{}); err != nil { t.Fatal(err) } else if infos := coord.API.RBFDebugInfo(); infos == nil { t.Fatal("expected info") @@ -1699,25 +1627,22 @@ f9Oeos0UUothgiDktdQHxdNEwLjQf7lJJBzV+5OtwswCWA== config.TLS.CertificateKeyPath = writeTestFile(t, "certKey.pem", localhostKey) config.TLS.CertificatePath = writeTestFile(t, "cert.pem", localhostCert) - c := test.MustRunCluster(t, 3, + c := test.MustRunUnsharedCluster(t, 3, []server.CommandOption{ server.OptCommandServerOptions( pilosa.OptServerNodeID("node0"), - pilosa.OptServerClusterHasher(&test.ModHasher{}), ), server.OptCommandConfig(config), }, []server.CommandOption{ server.OptCommandServerOptions( pilosa.OptServerNodeID("node1"), - pilosa.OptServerClusterHasher(&test.ModHasher{}), ), server.OptCommandConfig(config), }, []server.CommandOption{ server.OptCommandServerOptions( pilosa.OptServerNodeID("node2"), - pilosa.OptServerClusterHasher(&test.ModHasher{}), ), server.OptCommandConfig(config), }, @@ -1727,6 +1652,8 @@ f9Oeos0UUothgiDktdQHxdNEwLjQf7lJJBzV+5OtwswCWA== primaryAPI := c.GetPrimary().API // needs internal/cluster/message + // Note: This indexName wouldn't be safe on a shared cluster, but we have to use an + // unshared cluster to set up the auth config anyway. indexName := "test" _, err := primaryAPI.CreateIndex(adminCtx, indexName, pilosa.IndexOptions{}) if err != nil { diff --git a/client/client_it_test.go b/client/client_it_test.go index 3fff0b003..078b17501 100644 --- a/client/client_it_test.go +++ b/client/client_it_test.go @@ -71,7 +71,7 @@ func TestClientAgainstCluster(t *testing.T) { t.Run(testName, func(t *testing.T) { // Start size.replicaN cluster - c := test.MustNewCluster(t, size) + c := test.MustUnsharedCluster(t, size) for _, n := range c.Nodes { n.Config.Cluster.ReplicaN = replicaN } diff --git a/cluster_internal_test.go b/cluster_internal_test.go index 528c9b7be..beef097e0 100644 --- a/cluster_internal_test.go +++ b/cluster_internal_test.go @@ -10,11 +10,9 @@ import ( "testing/quick" "time" - "github.com/davecgh/go-spew/spew" - "github.com/featurebasedb/featurebase/v3/disco" - pnet "github.com/featurebasedb/featurebase/v3/net" - "github.com/featurebasedb/featurebase/v3/roaring" - _ "github.com/featurebasedb/featurebase/v3/vprint" + "github.com/molecula/featurebase/v3/disco" + pnet "github.com/molecula/featurebase/v3/net" + "github.com/molecula/featurebase/v3/roaring" ) // Ensure the cluster can fairly distribute partitions across the nodes. @@ -25,7 +23,7 @@ func TestCluster_Owners(t *testing.T) { {URI: NewTestURIFromHostPort("serverB", 1000)}, {URI: NewTestURIFromHostPort("serverC", 1000)}, }), - Hasher: NewTestModHasher(), + Hasher: &disco.Jmphasher{}, ReplicaN: 2, } @@ -34,14 +32,24 @@ func TestCluster_Owners(t *testing.T) { // Create a snapshot of the cluster to use for node/partition calculations. snap := c.NewSnapshot() - // Verify nodes are distributed. - if a := snap.PartitionNodes(0); !reflect.DeepEqual(a, []*disco.Node{cNodes[0], cNodes[1]}) { - t.Fatalf("unexpected owners: %s", spew.Sdump(a)) + assigned := make(map[int]int) + for i := 0; i < 256; i++ { + nodes := snap.PartitionNodes(i) + for _, node := range nodes { + for j, n := range cNodes { + if n == node { + assigned[j]++ + } + } + } } - - // Verify nodes go around the ring. - if a := snap.PartitionNodes(2); !reflect.DeepEqual(a, []*disco.Node{cNodes[2], cNodes[0]}) { - t.Fatalf("unexpected owners: %s", spew.Sdump(a)) + expected := float64((256.0 * 2) / 3) // each partition is on two nodes, there's three nodes + for k, v := range assigned { + ratio := float64(v) / expected + // Empirically, we expect 167/171/174 + if ratio < 0.97 || ratio > 1.03 { + t.Fatalf("node %d has %d assigned partitions, expected about %.1f", k, v, expected) + } } } @@ -98,10 +106,18 @@ func TestCluster_ContainsShards(t *testing.T) { // Create a snapshot of the cluster to use for node/partition calculations. snap := c.NewSnapshot() - shards := snap.ContainsShards("test", roaring.NewBitmap(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10), cNodes[2]) - - if !reflect.DeepEqual(shards, []uint64{0, 2, 3, 5, 6, 9, 10}) { - t.Fatalf("unexpected shars for node's index: %v", shards) + availableShards := roaring.NewBitmap(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10) + nodeCounts := make(map[uint64]int) + for _, n := range cNodes { + shards := snap.ContainsShards("test", availableShards, n) + for _, shard := range shards { + nodeCounts[shard]++ + } + } + for shard, count := range nodeCounts { + if count != 3 { + t.Fatalf("shard %d on %d nodes, expected 3", shard, count) + } } } diff --git a/ctl/import_test.go b/ctl/import_test.go index 1042af992..3364d3efe 100644 --- a/ctl/import_test.go +++ b/ctl/import_test.go @@ -217,18 +217,18 @@ func TestImportCommand_RunKeys(t *testing.T) { cmd := cluster.GetNode(0) cm.Host = cmd.API.Node().URI.HostPort() - resp, err := http.DefaultClient.Do(MustNewHTTPRequest("POST", "http://"+cm.Host+"/index/i", strings.NewReader(`{"options":{"keys": true}}`))) + resp, err := http.DefaultClient.Do(MustNewHTTPRequest("POST", fmt.Sprintf("http://%s/index/%i", cm.Host, cluster), strings.NewReader(`{"options":{"keys": true}}`))) if err != nil { t.Fatalf("posting request: %v", err) } resp.Body.Close() - resp, err = http.DefaultClient.Do(MustNewHTTPRequest("POST", "http://"+cm.Host+"/index/i/field/f", strings.NewReader(`{"options":{"keys": true}}`))) + resp, err = http.DefaultClient.Do(MustNewHTTPRequest("POST", fmt.Sprintf("http://%s/index/%i/field/f", cm.Host, cluster), strings.NewReader(`{"options":{"keys": true}}`))) if err != nil { t.Fatalf("posting request: %v", err) } resp.Body.Close() - cm.Index = "i" + cm.Index = cluster.Idx("i") cm.Field = "f" cm.Paths = []string{file.Name()} err = cm.Run(ctx) @@ -272,18 +272,18 @@ func TestImportCommand_KeyReplication(t *testing.T) { cm.Host = host0 - resp, err := http.DefaultClient.Do(MustNewHTTPRequest("POST", "http://"+cm.Host+"/index/i", strings.NewReader(`{"options":{"keys": true}}`))) + resp, err := http.DefaultClient.Do(MustNewHTTPRequest("POST", fmt.Sprintf("http://%s/index/%i", cm.Host, c), strings.NewReader(`{"options":{"keys": true}}`))) if err != nil { t.Fatalf("posting request: %v", err) } resp.Body.Close() - resp, err = http.DefaultClient.Do(MustNewHTTPRequest("POST", "http://"+cm.Host+"/index/i/field/f", strings.NewReader(`{"options":{"keys": true}}`))) + resp, err = http.DefaultClient.Do(MustNewHTTPRequest("POST", fmt.Sprintf("http://%s/index/%i/field/f", cm.Host, c), strings.NewReader(`{"options":{"keys": true}}`))) if err != nil { t.Fatalf("posting request: %v", err) } resp.Body.Close() - cm.Index = "i" + cm.Index = c.Idx("i") cm.Field = "f" cm.Paths = []string{file.Name()} err = cm.Run(ctx) @@ -295,7 +295,7 @@ func TestImportCommand_KeyReplication(t *testing.T) { for _, host := range []string{host0, host1} { if err := test.RetryUntil(2*time.Second, func() error { qry := "Count(Row(f=foo0))" - resp, err := http.DefaultClient.Do(MustNewHTTPRequest("POST", "http://"+host+"/index/i/query", strings.NewReader(qry))) + resp, err := http.DefaultClient.Do(MustNewHTTPRequest("POST", fmt.Sprintf("http://%s/index/%i/query", host, c), strings.NewReader(qry))) if err != nil { return fmt.Errorf("Querying data for validation: %s", err) } @@ -335,18 +335,18 @@ func TestImportCommand_RunValueKeys(t *testing.T) { cmd := cluster.GetNode(0) cm.Host = cmd.API.Node().URI.HostPort() - resp, err := http.DefaultClient.Do(MustNewHTTPRequest("POST", "http://"+cm.Host+"/index/i", strings.NewReader(`{"options":{"keys": true}}`))) + resp, err := http.DefaultClient.Do(MustNewHTTPRequest("POST", fmt.Sprintf("http://%s/index/%i", cm.Host, cluster), strings.NewReader(`{"options":{"keys": true}}`))) if err != nil { t.Fatalf("posting request: %v", err) } resp.Body.Close() - resp, err = http.DefaultClient.Do(MustNewHTTPRequest("POST", "http://"+cm.Host+"/index/i/field/f", strings.NewReader(`{"options":{"type": "int", "min": 0, "max": 100}}`))) + resp, err = http.DefaultClient.Do(MustNewHTTPRequest("POST", fmt.Sprintf("http://%s/index/%i/field/f", cm.Host, cluster), strings.NewReader(`{"options":{"type": "int", "min": 0, "max": 100}}`))) if err != nil { t.Fatalf("posting request: %v", err) } resp.Body.Close() - cm.Index = "i" + cm.Index = cluster.Idx("i") cm.Field = "f" cm.Paths = []string{file.Name()} err = cm.Run(ctx) @@ -463,18 +463,18 @@ func TestImportCommand_BugOverwriteValue(t *testing.T) { cm.Host = cmd.API.Node().URI.HostPort() - resp, err := http.DefaultClient.Do(MustNewHTTPRequest("POST", "http://"+cm.Host+"/index/i", strings.NewReader(""))) + resp, err := http.DefaultClient.Do(MustNewHTTPRequest("POST", fmt.Sprintf("http://%s/index/%i", cm.Host, cluster), strings.NewReader(""))) if err != nil { t.Fatalf("posting request: %v", err) } resp.Body.Close() - resp, err = http.DefaultClient.Do(MustNewHTTPRequest("POST", "http://"+cm.Host+"/index/i/field/f", strings.NewReader(`{"options":{"type": "int", "min": 0, "max":2147483648 }}`))) + resp, err = http.DefaultClient.Do(MustNewHTTPRequest("POST", fmt.Sprintf("http://%s/index/%i/field/f", cm.Host, cluster), strings.NewReader(`{"options":{"type": "int", "min": 0, "max":2147483648 }}`))) if err != nil { t.Fatalf("posting request: %v", err) } resp.Body.Close() - cm.Index = "i" + cm.Index = cluster.Idx("i") cm.Field = "f" cm.Paths = []string{file.Name()} err = cm.Run(ctx) @@ -525,18 +525,18 @@ func TestImportCommand_RunBool(t *testing.T) { cmd := cluster.GetNode(0) cm.Host = cmd.API.Node().URI.HostPort() - resp, err := http.DefaultClient.Do(MustNewHTTPRequest("POST", "http://"+cm.Host+"/index/i", strings.NewReader(""))) + resp, err := http.DefaultClient.Do(MustNewHTTPRequest("POST", fmt.Sprintf("http://%s/index/%i", cm.Host, cluster), strings.NewReader(""))) if err != nil { t.Fatalf("posting request: %v", err) } resp.Body.Close() - resp, err = http.DefaultClient.Do(MustNewHTTPRequest("POST", "http://"+cm.Host+"/index/i/field/f", strings.NewReader(`{"options":{"type": "bool"}}`))) + resp, err = http.DefaultClient.Do(MustNewHTTPRequest("POST", fmt.Sprintf("http://%s/index/%i/field/f", cm.Host, cluster), strings.NewReader(`{"options":{"type": "bool"}}`))) if err != nil { t.Fatalf("posting request: %v", err) } resp.Body.Close() - cm.Index = "i" + cm.Index = cluster.Idx("i") cm.Field = "f" t.Run("Valid", func(t *testing.T) { @@ -711,6 +711,7 @@ func TestImport_AuthOn(t *testing.T) { t.Fatal(err) } + // note: cluster isn't shared because of custom opts cluster := test.MustRunCluster(t, clusterSize, commandOpts...) defer cluster.Close() cmd := cluster.GetNode(0) diff --git a/dbshard_test.go b/dbshard_test.go index 8ee5fa7a8..f3945cb9a 100644 --- a/dbshard_test.go +++ b/dbshard_test.go @@ -5,34 +5,23 @@ package pilosa_test import ( "context" "fmt" - "reflect" "testing" - pilosa "github.com/featurebasedb/featurebase/v3" - "github.com/featurebasedb/featurebase/v3/boltdb" - "github.com/featurebasedb/featurebase/v3/server" - "github.com/featurebasedb/featurebase/v3/test" - . "github.com/featurebasedb/featurebase/v3/vprint" // nolint:staticcheck + pilosa "github.com/molecula/featurebase/v3" + "github.com/molecula/featurebase/v3/test" + . "github.com/molecula/featurebase/v3/vprint" // nolint:staticcheck ) func TestAPI_SimplerOneNode_ImportColumnKey(t *testing.T) { - c := test.MustRunCluster(t, 1, - []server.CommandOption{ - server.OptCommandServerOptions( - pilosa.OptServerNodeID("node0"), - pilosa.OptServerClusterHasher(&offsetModHasher{}), - pilosa.OptServerOpenTranslateStore(boltdb.OpenTranslateStore), - pilosa.OptServerOpenTranslateReader(pilosa.GetOpenTranslateReaderFunc(nil)), - )}, - ) + c := test.MustRunCluster(t, 1) defer c.Close() m0 := c.GetNode(0) t.Run("RowIDColumnKey", func(t *testing.T) { ctx := context.Background() - indexName := "rick" + indexName := c.Idx() fieldName := "f" index, err := m0.API.CreateIndex(ctx, indexName, pilosa.IndexOptions{Keys: true, TrackExistence: true}) @@ -66,7 +55,7 @@ func TestAPI_SimplerOneNode_ImportColumnKey(t *testing.T) { colKeys := []string{"col10", "col8", "col9", "col6", "col7", "col4", "col5", "col2", "col3", "col1"} // Import data with keys to the primary and verify that it gets - // translated and forwarded to the owner of shard 0 (node1; because of offsetModHasher) + // translated and forwarded to the owner of shard 0 req := &pilosa.ImportRequest{ Index: indexName, IndexCreatedAt: index.CreatedAt(), @@ -89,9 +78,12 @@ func TestAPI_SimplerOneNode_ImportColumnKey(t *testing.T) { pql := fmt.Sprintf("Row(%s=%d)", fieldName, rowID) // Query node0. - if res, err := m0.API.Query(ctx, &pilosa.QueryRequest{Index: indexName, Query: pql}); err != nil { + res, err := m0.API.Query(ctx, &pilosa.QueryRequest{Index: indexName, Query: pql}) + if err != nil { t.Fatal(err) - } else if keys := res.Results[0].(*pilosa.Row).Keys; !reflect.DeepEqual(keys, colKeys) { + } + keys := res.Results[0].(*pilosa.Row).Keys + if !sameStringSlice(keys, colKeys) { t.Fatalf("unexpected column keys: %#v", keys) } }) diff --git a/delete_test.go b/delete_test.go index 2b4e7035f..1ebb7bdc4 100644 --- a/delete_test.go +++ b/delete_test.go @@ -6,6 +6,7 @@ import ( "context" "fmt" "math" + "sort" "testing" "time" @@ -16,7 +17,9 @@ import ( ) func TestExecutor_DeleteRecords(t *testing.T) { - indexName := "i" + c := test.MustRunCluster(t, 1) + indexName := c.Idx() + defer c.Close() setup := func(t *testing.T, r *require.Assertions, c *test.Cluster) { t.Helper() c.CreateField(t, indexName, pilosa.IndexOptions{TrackExistence: true}, "setfield") @@ -111,13 +114,6 @@ func TestExecutor_DeleteRecords(t *testing.T) { } require := require.New(t) t.Run("DeleteRecords", func(t *testing.T) { - c := test.MustNewCluster(t, 1) - for _, n := range c.Nodes { - n.Config.Cluster.ReplicaN = 1 - } - err := c.Start() - require.NoError(err, "Start cluster DeleteRecords") - defer c.Close() t.Run("Delete", func(t *testing.T) { setup(t, require, c) @@ -144,7 +140,9 @@ func TestExecutor_DeleteRecords(t *testing.T) { resp := c.Query(t, indexName, `Extract(All())`) m := resp.Results[0].(pilosa.ExtractedTable) before := convertKey(m.Columns) - require.Equal([]string{"one", "A", "B", "C", "D", "two"}, before, "these keyed records before") + sort.Strings(before) + expected := []string{"A", "B", "C", "D", "one", "two"} + require.Equal(expected, before, "these keyed records before") resp = c.Query(t, indexName, `Delete(ConstRow(columns=["A","one"]))`) require.NotEmpty(resp.Results) require.Equal(true, resp.Results[0], "Change should have happened") @@ -152,6 +150,7 @@ func TestExecutor_DeleteRecords(t *testing.T) { resp = c.Query(t, indexName, `Extract(All())`) m = resp.Results[0].(pilosa.ExtractedTable) after := convertKey(m.Columns) + sort.Strings(after) require.Equal([]string{"B", "C", "D", "two"}, after, "these keyed records after delete") //validate that column keys got deleted node := c.GetNode(0) @@ -240,13 +239,9 @@ func TestExecutor_DeleteRecords(t *testing.T) { }) }) t.Run("DeleteRecordsBigWithRestart", func(t *testing.T) { - c := test.MustNewCluster(t, 1) - for _, n := range c.Nodes { - n.Config.Cluster.ReplicaN = 1 - } - err := c.Start() + // restarting doesn't work correctly for a shared cluster + c := test.MustRunUnsharedCluster(t, 1) defer c.Close() - require.NoError(err, "Start cluster DeleteRecordsBig") setupBig(t, require, c, 16) defer tearDown(t, require, c) node := c.GetNode(0) @@ -258,7 +253,7 @@ func TestExecutor_DeleteRecords(t *testing.T) { require.NotNil(resp, "Response should not be nil") require.NotEmpty(resp.Results) require.Equal(uint64(0), resp.Results[0], "Should have removed") - err = node.Reopen() + err := node.Reopen() require.NoError(err, "restart cluster DeleteRecordsBig") err = c.AwaitState(disco.ClusterStateNormal, 10*time.Second) require.NoError(err, "backToNormal") diff --git a/executor.go b/executor.go index fb7039d8b..49c1f38ff 100644 --- a/executor.go +++ b/executor.go @@ -3052,7 +3052,23 @@ func (e *executor) executeGroupBy(ctx context.Context, qcx *Qcx, index string, c if err := ctx.Err(); err != nil { return err } - return mergeGroupCounts(other, findGroupCounts(v), limit) + x := mergeGroupCounts(other, findGroupCounts(v), limit) + for i := range x { + gc := &x[i] + for j := range gc.Group { + fr := &gc.Group[j] + if fr.FieldOptions == nil { + // oops, options were omitted possibly by a remote. try to + // guess them from our local options + field := e.Holder.Field(index, fr.Field) + if field != nil { + options := field.Options() + fr.FieldOptions = &options + } + } + } + } + return x } // Get full result set. other, err := e.mapReduce(ctx, index, shards, c, opt, mapFn, reduceFn) diff --git a/executor_internal_test.go b/executor_internal_test.go index 96f049724..2f3cb45cd 100644 --- a/executor_internal_test.go +++ b/executor_internal_test.go @@ -7,6 +7,7 @@ import ( "encoding/json" "fmt" "reflect" + "sort" "strconv" "testing" "time" @@ -16,6 +17,30 @@ import ( "github.com/stretchr/testify/assert" ) +// AssertEqual checks a given RowIdentifiers against expected values. +func (r *RowIdentifiers) AssertEqual(tb testing.TB, other *RowIdentifiers) { + sort.Slice(r.Rows, func(i, j int) bool { return r.Rows[i] < r.Rows[j] }) + sort.Slice(other.Rows, func(i, j int) bool { return other.Rows[i] < other.Rows[j] }) + if len(r.Rows) != len(other.Rows) { + tb.Fatalf("row ID mismatch: got %d, expected %d", r.Rows, other.Rows) + } + for i := range r.Rows { + if r.Rows[i] != other.Rows[i] { + tb.Fatalf("row ID mismatch: got %d, expected %d", r.Rows, other.Rows) + } + } + sort.Strings(r.Keys) + sort.Strings(other.Keys) + if len(r.Keys) != len(other.Keys) { + tb.Fatalf("row keys mismatch: got %s, expected %s", r.Keys, other.Keys) + } + for i := range r.Keys { + if r.Keys[i] != other.Keys[i] { + tb.Fatalf("row keys mismatch: got %s, expected %s", r.Keys, other.Keys) + } + } +} + func TestExecutor_TranslateRowsOnBool(t *testing.T) { path, _ := testhook.TempDirInDir(t, *TempDir, "pilosa-executor-") holder := NewHolder(path, mustHolderConfig()) diff --git a/executor_test.go b/executor_test.go index 680287a8b..331080feb 100644 --- a/executor_test.go +++ b/executor_test.go @@ -5,7 +5,6 @@ package pilosa_test import ( "bytes" "context" - "crypto/md5" "database/sql" "encoding/csv" "encoding/json" @@ -35,13 +34,18 @@ import ( "github.com/featurebasedb/featurebase/v3/testhook" . "github.com/featurebasedb/featurebase/v3/vprint" // nolint:staticcheck "github.com/google/go-cmp/cmp" - "github.com/google/go-cmp/cmp/cmpopts" + pilosa "github.com/molecula/featurebase/v3" + "github.com/molecula/featurebase/v3/ctl" + "github.com/molecula/featurebase/v3/disco" + "github.com/molecula/featurebase/v3/pql" + "github.com/molecula/featurebase/v3/proto" + "github.com/molecula/featurebase/v3/server" + "github.com/molecula/featurebase/v3/test" + "github.com/molecula/featurebase/v3/testhook" + . "github.com/molecula/featurebase/v3/vprint" // nolint:staticcheck "github.com/pkg/errors" ) -// writable initializes Tx that update, use !writable for read-only. -const writable = true - var ( TempDir = getTempDirString() ) @@ -60,10 +64,7 @@ func getTempDirString() (td *string) { func TestExecutor(t *testing.T) { c := test.MustRunCluster(t, 1) - defer func() { - t.Logf("TestExecutor: closing cluster") - c.Close() - }() + defer c.Close() // Ensure a row query can be executed. t.Run("ExecuteRow", func(t *testing.T) { t.Run("RowIDColumnID", func(t *testing.T) { @@ -86,7 +87,8 @@ func TestExecutor(t *testing.T) { readQueries := []string{`Row(f=1)`} responses := runCallTest(c, t, writeQuery, readQueries, &pilosa.IndexOptions{Keys: true}) - if keys := responses[0].Results[0].(*pilosa.Row).Keys; !reflect.DeepEqual(keys, []string{"one-hundred", "two-hundred"}) { + keys := responses[0].Results[0].(*pilosa.Row).Keys + if !sameStringSlice(keys, []string{"one-hundred", "two-hundred"}) { t.Fatalf("unexpected keys: %+v", keys) } }) @@ -113,10 +115,9 @@ func TestExecutor(t *testing.T) { responses := runCallTest(c, t, writeQuery, readQueries, &pilosa.IndexOptions{Keys: true}, pilosa.OptFieldKeys()) - if diff := cmp.Diff(responses[0].Results, []interface{}{ - &pilosa.Row{Keys: []string{"bat", "foo"}}, - }, cmpopts.IgnoreUnexported(pilosa.Row{})); diff != "" { - t.Fatal(diff) + keys := responses[0].Results[0].(*pilosa.Row).Keys + if !sameStringSlice(keys, []string{"bat", "foo"}) { + t.Fatalf("unexpected keys: %+v", keys) } }) }) @@ -132,7 +133,8 @@ func TestExecutor(t *testing.T) { readQueries := []string{`Difference(Row(f=10), Row(f=11))`} responses := runCallTest(c, t, writeQuery, readQueries, &pilosa.IndexOptions{Keys: true}) - if keys := responses[0].Results[0].(*pilosa.Row).Keys; !reflect.DeepEqual(keys, []string{"three", "one"}) { + keys := responses[0].Results[0].(*pilosa.Row).Keys + if !sameStringSlice(keys, []string{"three", "one"}) { t.Fatalf("unexpected keys: %+v", keys) } }) @@ -163,7 +165,8 @@ func TestExecutor(t *testing.T) { responses := runCallTest(c, t, writeQuery, readQueries, &pilosa.IndexOptions{Keys: true}, pilosa.OptFieldKeys()) - if keys := responses[0].Results[0].(*pilosa.Row).Keys; !reflect.DeepEqual(keys, []string{"one", "three"}) { + keys := responses[0].Results[0].(*pilosa.Row).Keys + if !sameStringSlice(keys, []string{"one", "three"}) { t.Fatalf("unexpected keys: %+v", keys) } }) @@ -181,7 +184,8 @@ func TestExecutor(t *testing.T) { readQueries := []string{`Intersect(Row(f=10), Row(f=11))`} responses := runCallTest(c, t, writeQuery, readQueries, &pilosa.IndexOptions{Keys: true}) - if keys := responses[0].Results[0].(*pilosa.Row).Keys; !reflect.DeepEqual(keys, []string{"one", "two-hundred"}) { + keys := responses[0].Results[0].(*pilosa.Row).Keys + if !sameStringSlice(keys, []string{"one", "two-hundred"}) { t.Fatalf("unexpected keys: %+v", keys) } }) @@ -214,7 +218,8 @@ func TestExecutor(t *testing.T) { responses := runCallTest(c, t, writeQuery, readQueries, &pilosa.IndexOptions{Keys: true}, pilosa.OptFieldKeys()) - if keys := responses[0].Results[0].(*pilosa.Row).Keys; !reflect.DeepEqual(keys, []string{"one", "two-hundred"}) { + keys := responses[0].Results[0].(*pilosa.Row).Keys + if !sameStringSlice(keys, []string{"one", "two-hundred"}) { t.Fatalf("unexpected keys: %+v", keys) } }) @@ -232,7 +237,8 @@ func TestExecutor(t *testing.T) { readQueries := []string{`Union(Row(f=10), Row(f=11))`} responses := runCallTest(c, t, writeQuery, readQueries, &pilosa.IndexOptions{Keys: true}) - if keys := responses[0].Results[0].(*pilosa.Row).Keys; !reflect.DeepEqual(keys, []string{"one", "two-hundred", "one-hundred", "two"}) { + keys := responses[0].Results[0].(*pilosa.Row).Keys + if !sameStringSlice(keys, []string{"one", "two-hundred", "one-hundred", "two"}) { t.Fatalf("unexpected keys: %+v", keys) } }) @@ -265,7 +271,8 @@ func TestExecutor(t *testing.T) { responses := runCallTest(c, t, writeQuery, readQueries, &pilosa.IndexOptions{Keys: true}, pilosa.OptFieldKeys()) - if keys := responses[0].Results[0].(*pilosa.Row).Keys; !reflect.DeepEqual(keys, []string{"two-hundred", "two", "one-hundred", "one"}) { + keys := responses[0].Results[0].(*pilosa.Row).Keys + if !sameStringSlice(keys, []string{"two-hundred", "two", "one-hundred", "one"}) { t.Fatalf("unexpected keys: %+v", keys) } }) @@ -283,7 +290,8 @@ func TestExecutor(t *testing.T) { readQueries := []string{`Xor(Row(f=10), Row(f=11))`} responses := runCallTest(c, t, writeQuery, readQueries, &pilosa.IndexOptions{Keys: true}) - if keys := responses[0].Results[0].(*pilosa.Row).Keys; !reflect.DeepEqual(keys, []string{"two", "one-hundred"}) { + keys := responses[0].Results[0].(*pilosa.Row).Keys + if !sameStringSlice(keys, []string{"two", "one-hundred"}) { t.Fatalf("unexpected keys: %+v", keys) } }) @@ -316,7 +324,8 @@ func TestExecutor(t *testing.T) { responses := runCallTest(c, t, writeQuery, readQueries, &pilosa.IndexOptions{Keys: true}, pilosa.OptFieldKeys()) - if keys := responses[0].Results[0].(*pilosa.Row).Keys; !reflect.DeepEqual(keys, []string{"two", "one-hundred"}) { + keys := responses[0].Results[0].(*pilosa.Row).Keys + if !sameStringSlice(keys, []string{"two", "one-hundred"}) { t.Fatalf("unexpected keys: %+v", keys) } }) @@ -538,13 +547,15 @@ func TestExecutor(t *testing.T) { pilosa.OptFieldTypeTime(pilosa.TimeQuantum("YMDH"), "0")) t.Run("Standard", func(t *testing.T) { - if keys := responses[0].Results[0].(*pilosa.Row).Keys; !reflect.DeepEqual(keys, []string{"six", "four", "five", "seven", "two", "three"}) { + keys := responses[0].Results[0].(*pilosa.Row).Keys + if !sameStringSlice(keys, []string{"six", "four", "five", "seven", "two", "three"}) { t.Fatalf("unexpected keys: %+v", keys) } }) t.Run("Clear", func(t *testing.T) { - if keys := responses[2].Results[0].(*pilosa.Row).Keys; !reflect.DeepEqual(keys, []string{"six", "four", "five", "seven", "three"}) { + keys := responses[2].Results[0].(*pilosa.Row).Keys + if !sameStringSlice(keys, []string{"six", "four", "five", "seven", "three"}) { t.Fatalf("unexpected keys: %+v", keys) } }) @@ -608,13 +619,15 @@ func TestExecutor(t *testing.T) { pilosa.OptFieldKeys()) t.Run("Standard", func(t *testing.T) { - if keys := responses[0].Results[0].(*pilosa.Row).Keys; !reflect.DeepEqual(keys, []string{"three", "two", "five", "seven", "six", "four"}) { + keys := responses[0].Results[0].(*pilosa.Row).Keys + if !sameStringSlice(keys, []string{"three", "two", "five", "seven", "six", "four"}) { t.Fatalf("unexpected keys: %+v", keys) } }) t.Run("Clear", func(t *testing.T) { - if keys := responses[2].Results[0].(*pilosa.Row).Keys; !reflect.DeepEqual(keys, []string{"three", "five", "seven", "six", "four"}) { + keys := responses[2].Results[0].(*pilosa.Row).Keys + if !sameStringSlice(keys, []string{"three", "five", "seven", "six", "four"}) { t.Fatalf("unexpected keys: %+v", keys) } }) @@ -723,13 +736,15 @@ func TestExecutor(t *testing.T) { pilosa.OptFieldTypeTime(pilosa.TimeQuantum("YMDH"), "0")) t.Run("Standard", func(t *testing.T) { - if keys := responses[0].Results[0].(*pilosa.Row).Keys; !reflect.DeepEqual(keys, []string{"two", "three", "seven", "four", "five", "six"}) { + keys := responses[0].Results[0].(*pilosa.Row).Keys + if !sameStringSlice(keys, []string{"two", "three", "seven", "four", "five", "six"}) { t.Fatalf("unexpected keys: %+v", keys) } }) t.Run("Clear", func(t *testing.T) { - if keys := responses[2].Results[0].(*pilosa.Row).Keys; !reflect.DeepEqual(keys, []string{"three", "seven", "four", "five", "six"}) { + keys := responses[2].Results[0].(*pilosa.Row).Keys + if !sameStringSlice(keys, []string{"three", "seven", "four", "five", "six"}) { t.Fatalf("unexpected keys: %+v", keys) } }) @@ -793,13 +808,15 @@ func TestExecutor(t *testing.T) { pilosa.OptFieldKeys()) t.Run("Standard", func(t *testing.T) { - if keys := responses[0].Results[0].(*pilosa.Row).Keys; !reflect.DeepEqual(keys, []string{"three", "five", "six", "two", "seven", "four"}) { + keys := responses[0].Results[0].(*pilosa.Row).Keys + if !sameStringSlice(keys, []string{"three", "five", "six", "two", "seven", "four"}) { t.Fatalf("unexpected keys: %+v", keys) } }) t.Run("Clear", func(t *testing.T) { - if keys := responses[2].Results[0].(*pilosa.Row).Keys; !reflect.DeepEqual(keys, []string{"three", "five", "six", "seven", "four"}) { + keys := responses[2].Results[0].(*pilosa.Row).Keys + if !sameStringSlice(keys, []string{"three", "five", "six", "seven", "four"}) { t.Fatalf("unexpected keys: %+v", keys) } }) @@ -858,7 +875,8 @@ func TestExecutor(t *testing.T) { TrackExistence: true, Keys: true, }) - if keys := responses[0].Results[0].(*pilosa.Row).Keys; !reflect.DeepEqual(keys, []string{"three", "sw1"}) { + keys := responses[0].Results[0].(*pilosa.Row).Keys + if !sameStringSlice(keys, []string{"three", "sw1"}) { t.Fatalf("unexpected keys: %+v", keys) } }) @@ -889,7 +907,8 @@ func TestExecutor(t *testing.T) { TrackExistence: true, Keys: true, }, pilosa.OptFieldKeys()) - if keys := responses[0].Results[0].(*pilosa.Row).Keys; !reflect.DeepEqual(keys, []string{"sw1", "three"}) { + keys := responses[0].Results[0].(*pilosa.Row).Keys + if !sameStringSlice(keys, []string{"sw1", "three"}) { t.Fatalf("unexpected keys: %+v", keys) } }) @@ -1062,9 +1081,8 @@ func TestExecutor(t *testing.T) { for i := range responses { t.Run(fmt.Sprintf("response-%d", i), func(t *testing.T) { - if rows := responses[i].Results[0].(pilosa.RowIdentifiers).Rows; !reflect.DeepEqual(rows, expResults[i]) { - t.Fatalf("unexpected rows: %+v", rows) - } + rows := responses[i].Results[0].(pilosa.RowIdentifiers) + rows.AssertEqual(t, &pilosa.RowIdentifiers{Rows: expResults[i]}) }) } }) @@ -1077,7 +1095,7 @@ func TestExecutor(t *testing.T) { ts := func(t time.Time) int64 { return t.Unix() * 1e+9 } - indexName := "tq_range" + indexName := c.Idx("tq_range") c.CreateField(t, indexName, pilosa.IndexOptions{Keys: true, TrackExistence: true}, "f1", pilosa.OptFieldKeys(), pilosa.OptFieldTypeTime(pilosa.TimeQuantum("D"), "0")) c.ImportTimeQuantumKey(t, indexName, "f1", []test.TimeQuantumKey{ // from edge cases @@ -1140,7 +1158,7 @@ C6 func runCallTest(c *test.Cluster, t *testing.T, writeQuery string, readQueries []string, indexOptions *pilosa.IndexOptions, fieldOption ...pilosa.FieldOption) []pilosa.QueryResponse { t.Helper() - indexName := fmt.Sprintf("i_%x", md5.Sum([]byte(t.Name()))) + indexName := c.Idx(t.Name()) if indexOptions == nil { indexOptions = &pilosa.IndexOptions{} @@ -1188,14 +1206,14 @@ func TestExecutor_Execute_ConstRow(t *testing.T) { c := test.MustRunCluster(t, 3) defer c.Close() - c.CreateField(t, "i", pilosa.IndexOptions{}, "h") - c.ImportBits(t, "i", "h", [][2]uint64{ + c.CreateField(t, c.Idx(), pilosa.IndexOptions{}, "h") + c.ImportBits(t, c.Idx(), "h", [][2]uint64{ {1, 2}, {3, 4}, {5, 6}, }) - resp := c.Query(t, "i", `ConstRow(columns=[2,6])`) + resp := c.Query(t, c.Idx(), `ConstRow(columns=[2,6])`) expect := []uint64{2, 6} got := resp.Results[0].(*pilosa.Row).Columns() if !reflect.DeepEqual(expect, got) { @@ -1210,13 +1228,13 @@ func TestExecutor_Execute_Difference(t *testing.T) { defer c.Close() hldr := c.GetHolder(0) - hldr.SetBit("i", "general", 10, 1) - hldr.SetBit("i", "general", 10, 2) - hldr.SetBit("i", "general", 10, 3) - hldr.SetBit("i", "general", 11, 2) - hldr.SetBit("i", "general", 11, 4) + hldr.SetBit(c.Idx(), "general", 10, 1) + hldr.SetBit(c.Idx(), "general", 10, 2) + hldr.SetBit(c.Idx(), "general", 10, 3) + hldr.SetBit(c.Idx(), "general", 11, 2) + hldr.SetBit(c.Idx(), "general", 11, 4) - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Difference(Row(general=10), Row(general=11))`}); err != nil { + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Difference(Row(general=10), Row(general=11))`}); err != nil { t.Fatal(err) } else if columns := res.Results[0].(*pilosa.Row).Columns(); !reflect.DeepEqual(columns, []uint64{1, 3}) { t.Fatalf("unexpected columns: %+v", columns) @@ -1229,9 +1247,9 @@ func TestExecutor_Execute_Empty_Difference(t *testing.T) { c := test.MustRunCluster(t, 1) defer c.Close() hldr := c.GetHolder(0) - hldr.SetBit("i", "general", 10, 1) + hldr.SetBit(c.Idx(), "general", 10, 1) - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Difference()`}); err == nil { + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Difference()`}); err == nil { t.Fatalf("Empty Difference query should give error, but got %v", res) } } @@ -1242,14 +1260,14 @@ func TestExecutor_Execute_Intersect(t *testing.T) { c := test.MustRunCluster(t, 1) defer c.Close() hldr := c.GetHolder(0) - hldr.SetBit("i", "general", 10, 1) - hldr.SetBit("i", "general", 10, ShardWidth+1) - hldr.SetBit("i", "general", 10, ShardWidth+2) - hldr.SetBit("i", "general", 11, 1) - hldr.SetBit("i", "general", 11, 2) - hldr.SetBit("i", "general", 11, ShardWidth+2) + hldr.SetBit(c.Idx(), "general", 10, 1) + hldr.SetBit(c.Idx(), "general", 10, ShardWidth+1) + hldr.SetBit(c.Idx(), "general", 10, ShardWidth+2) + hldr.SetBit(c.Idx(), "general", 11, 1) + hldr.SetBit(c.Idx(), "general", 11, 2) + hldr.SetBit(c.Idx(), "general", 11, ShardWidth+2) - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Intersect(Row(general=10), Row(general=11))`}); err != nil { + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Intersect(Row(general=10), Row(general=11))`}); err != nil { t.Fatal(err) } else if columns := res.Results[0].(*pilosa.Row).Columns(); !reflect.DeepEqual(columns, []uint64{1, ShardWidth + 2}) { t.Fatalf("unexpected columns: %+v", columns) @@ -1262,7 +1280,7 @@ func TestExecutor_Execute_Empty_Intersect(t *testing.T) { c := test.MustRunCluster(t, 1) defer c.Close() - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Intersect()`}); err == nil { + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Intersect()`}); err == nil { t.Fatalf("Empty Intersect query should give error, but got %v", res) } } @@ -1273,14 +1291,14 @@ func TestExecutor_Execute_Union(t *testing.T) { c := test.MustRunCluster(t, 1) defer c.Close() hldr := c.GetHolder(0) - hldr.SetBit("i", "general", 10, 0) - hldr.SetBit("i", "general", 10, ShardWidth+1) - hldr.SetBit("i", "general", 10, ShardWidth+2) + hldr.SetBit(c.Idx(), "general", 10, 0) + hldr.SetBit(c.Idx(), "general", 10, ShardWidth+1) + hldr.SetBit(c.Idx(), "general", 10, ShardWidth+2) - hldr.SetBit("i", "general", 11, 2) - hldr.SetBit("i", "general", 11, ShardWidth+2) + hldr.SetBit(c.Idx(), "general", 11, 2) + hldr.SetBit(c.Idx(), "general", 11, ShardWidth+2) - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Union(Row(general=10), Row(general=11))`}); err != nil { + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Union(Row(general=10), Row(general=11))`}); err != nil { t.Fatal(err) } else if columns := res.Results[0].(*pilosa.Row).Columns(); !reflect.DeepEqual(columns, []uint64{0, 2, ShardWidth + 1, ShardWidth + 2}) { t.Fatalf("unexpected columns: %+v", columns) @@ -1293,9 +1311,9 @@ func TestExecutor_Execute_Empty_Union(t *testing.T) { c := test.MustRunCluster(t, 1) defer c.Close() hldr := c.GetHolder(0) - hldr.SetBit("i", "general", 10, 0) + hldr.SetBit(c.Idx(), "general", 10, 0) - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Union()`}); err != nil { + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Union()`}); err != nil { t.Fatal(err) } else if columns := res.Results[0].(*pilosa.Row).Columns(); !reflect.DeepEqual(columns, []uint64{}) { t.Fatalf("unexpected columns: %+v", columns) @@ -1309,14 +1327,14 @@ func TestExecutor_Execute_Xor(t *testing.T) { defer c.Close() hldr := c.GetHolder(0) - hldr.SetBit("i", "general", 10, 0) - hldr.SetBit("i", "general", 10, ShardWidth+1) - hldr.SetBit("i", "general", 10, ShardWidth+2) + hldr.SetBit(c.Idx(), "general", 10, 0) + hldr.SetBit(c.Idx(), "general", 10, ShardWidth+1) + hldr.SetBit(c.Idx(), "general", 10, ShardWidth+2) - hldr.SetBit("i", "general", 11, 2) - hldr.SetBit("i", "general", 11, ShardWidth+2) + hldr.SetBit(c.Idx(), "general", 11, 2) + hldr.SetBit(c.Idx(), "general", 11, ShardWidth+2) - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Xor(Row(general=10), Row(general=11))`}); err != nil { + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Xor(Row(general=10), Row(general=11))`}); err != nil { t.Fatal(err) } else if columns := res.Results[0].(*pilosa.Row).Columns(); !reflect.DeepEqual(columns, []uint64{0, 2, ShardWidth + 1}) { t.Fatalf("unexpected columns: %+v", columns) @@ -1332,11 +1350,11 @@ func TestExecutor_Execute_Count(t *testing.T) { defer c.Close() hldr := c.GetHolder(0) - hldr.SetBit("i", "f", 10, 3) - hldr.SetBit("i", "f", 10, ShardWidth+1) - hldr.SetBit("i", "f", 10, ShardWidth+2) + hldr.SetBit(c.Idx(), "f", 10, 3) + hldr.SetBit(c.Idx(), "f", 10, ShardWidth+1) + hldr.SetBit(c.Idx(), "f", 10, ShardWidth+2) - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Count(Row(f=10))`}); err != nil { + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Count(Row(f=10))`}); err != nil { t.Fatal(err) } else if res.Results[0] != uint64(3) { t.Fatalf("unexpected n: %d", res.Results[0]) @@ -1348,28 +1366,28 @@ func TestExecutor_Execute_Count(t *testing.T) { // Ensure a set query can be executed. func TestExecutor_Execute_Set(t *testing.T) { t.Run("RowIDColumnID", func(t *testing.T) { - cluster := test.MustRunCluster(t, 1) - defer cluster.Close() - cmd := cluster.GetNode(0) - hldr := cluster.GetHolder(0) - hldr.SetBit("i", "f", 1, 0) // creates and commits a Tx internally. + c := test.MustRunCluster(t, 1) + defer c.Close() + cmd := c.GetNode(0) + hldr := c.GetHolder(0) + hldr.SetBit(c.Idx(), "f", 1, 0) // creates and commits a Tx internally. t.Run("OK", func(t *testing.T) { - hldr.ClearBit("i", "f", 11, 1) - if n := hldr.Row("i", "f", 11).Count(); n != 0 { + hldr.ClearBit(c.Idx(), "f", 11, 1) + if n := hldr.Row(c.Idx(), "f", 11).Count(); n != 0 { t.Fatalf("unexpected row count: %d", n) } - if res, err := cmd.API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Set(1, f=11)`}); err != nil { + if res, err := cmd.API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Set(1, f=11)`}); err != nil { t.Fatal(err) } else if !res.Results[0].(bool) { t.Fatalf("expected column changed") } - if n := hldr.Row("i", "f", 11).Count(); n != 1 { + if n := hldr.Row(c.Idx(), "f", 11).Count(); n != 1 { t.Fatalf("unexpected row count: %d", n) } - if res, err := cmd.API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Set(1, f=11)`}); err != nil { + if res, err := cmd.API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Set(1, f=11)`}); err != nil { t.Fatal(err) } else if res.Results[0].(bool) { t.Fatalf("expected column unchanged") @@ -1377,53 +1395,53 @@ func TestExecutor_Execute_Set(t *testing.T) { }) t.Run("ErrInvalidColValueType", func(t *testing.T) { - if _, err := cmd.API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Set("foo", f=1)`}); err == nil || !strings.Contains(err.Error(), "unkeyed index") { + if _, err := cmd.API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Set("foo", f=1)`}); err == nil || !strings.Contains(err.Error(), "unkeyed index") { t.Fatalf("The error is: '%v'", err) } }) t.Run("ErrInvalidRowValueType", func(t *testing.T) { - if _, err := cmd.API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Set(2, f="bar")`}); err == nil || !strings.Contains(err.Error(), "cannot create keys on unkeyed field") { + if _, err := cmd.API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Set(2, f="bar")`}); err == nil || !strings.Contains(err.Error(), "cannot create keys on unkeyed field") { t.Fatal(err) } }) }) t.Run("RowKeyColumnKey", func(t *testing.T) { - cluster := test.MustRunCluster(t, 1) - defer cluster.Close() - cmd := cluster.GetNode(0) - hldr := cluster.GetHolder(0) - idx := hldr.MustCreateIndexIfNotExists("i", pilosa.IndexOptions{Keys: true}) + c := test.MustRunCluster(t, 1) + defer c.Close() + cmd := c.GetNode(0) + hldr := c.GetHolder(0) + idx := hldr.MustCreateIndexIfNotExists(c.Idx(), pilosa.IndexOptions{Keys: true}) t.Run("OK", func(t *testing.T) { - hldr.SetBit("i", "f", 1, 0) // creates and Commits a Tx internally. - if n := hldr.Row("i", "f", 11).Count(); n != 0 { + hldr.SetBit(c.Idx(), "f", 1, 0) // creates and Commits a Tx internally. + if n := hldr.Row(c.Idx(), "f", 11).Count(); n != 0 { t.Fatalf("unexpected row count: %d", n) } - if res, err := cmd.API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Set("foo", f=11)`}); err != nil { + if res, err := cmd.API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Set("foo", f=11)`}); err != nil { t.Fatal(err) } else if !res.Results[0].(bool) { t.Fatalf("expected column changed") } - if n := hldr.Row("i", "f", 11).Count(); n != 1 { + if n := hldr.Row(c.Idx(), "f", 11).Count(); n != 1 { t.Fatalf("unexpected row count: %d", n) } - if res, err := cmd.API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Set("foo", f=11)`}); err != nil { + if res, err := cmd.API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Set("foo", f=11)`}); err != nil { t.Fatal(err) } else if res.Results[0].(bool) { t.Fatalf("expected column unchanged") } - if res, err := cmd.API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Set(2, f=11)`}); err != nil { + if res, err := cmd.API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Set(2, f=11)`}); err != nil { t.Fatal(err) } else if !res.Results[0].(bool) { t.Fatalf("expected column changed with integer column key") } - if res, err := cmd.API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Set(2, f=11)`}); err != nil { + if res, err := cmd.API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Set(2, f=11)`}); err != nil { t.Fatal(err) } else if res.Results[0].(bool) { t.Fatalf("expected column unchanged with integer column key") @@ -1431,7 +1449,7 @@ func TestExecutor_Execute_Set(t *testing.T) { }) t.Run("ErrInvalidColValueType", func(t *testing.T) { - hldr.SetBit("i", "f", 1, 0) // creates and Commits a Tx internally. + hldr.SetBit(c.Idx(), "f", 1, 0) // creates and Commits a Tx internally. if err := idx.DeleteField("f"); err != nil { t.Fatal(err) @@ -1441,11 +1459,11 @@ func TestExecutor_Execute_Set(t *testing.T) { t.Fatal(err) } - if _, err := cmd.API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Set(2.1, f=1)`}); err == nil || !strings.Contains(err.Error(), "parse error") { + if _, err := cmd.API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Set(2.1, f=1)`}); err == nil || !strings.Contains(err.Error(), "parse error") { t.Fatal(err) } - if res, err := cmd.API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Set(2, f=1)`}); err != nil { + if res, err := cmd.API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Set(2, f=1)`}); err != nil { t.Fatal(err) } else if !res.Results[0].(bool) { t.Fatalf("expected column changed with integer column key") @@ -1453,15 +1471,15 @@ func TestExecutor_Execute_Set(t *testing.T) { }) t.Run("ErrInvalidRowValueType", func(t *testing.T) { - idx := hldr.MustCreateIndexIfNotExists("inokey", pilosa.IndexOptions{}) + idx := hldr.MustCreateIndexIfNotExists(c.Idx("inokey"), pilosa.IndexOptions{}) if _, err := idx.CreateField("f", pilosa.OptFieldTypeDefault(), pilosa.OptFieldKeys()); err != nil { t.Fatal(err) } - if _, err := cmd.API.Query(context.Background(), &pilosa.QueryRequest{Index: "inokey", Query: `Set(2, f=1.2)`}); err == nil || !strings.Contains(err.Error(), "invalid value") { + if _, err := cmd.API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx("inokey"), Query: `Set(2, f=1.2)`}); err == nil || !strings.Contains(err.Error(), "invalid value") { t.Fatal(err) } - if res, err := cmd.API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Set(2, f=9)`}); err != nil { + if res, err := cmd.API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Set(2, f=9)`}); err != nil { t.Fatal(err) } else if !res.Results[0].(bool) { t.Fatalf("expected column changed with integer column key") @@ -1479,41 +1497,41 @@ func TestExecutor_Execute_SetBool(t *testing.T) { hldr := c.GetHolder(0) // Create fields. - index := hldr.MustCreateIndexIfNotExists("i", pilosa.IndexOptions{}) + index := hldr.MustCreateIndexIfNotExists(c.Idx(), pilosa.IndexOptions{}) if _, err := index.CreateFieldIfNotExists("f", pilosa.OptFieldTypeBool()); err != nil { t.Fatal(err) } // Set a true bit. - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Set(100, f=true)`}); err != nil { + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Set(100, f=true)`}); err != nil { t.Fatal(err) } else if !res.Results[0].(bool) { t.Fatalf("expected column changed") } // Set the same bit to true again verify nothing changed. - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Set(100, f=true)`}); err != nil { + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Set(100, f=true)`}); err != nil { t.Fatal(err) } else if res.Results[0].(bool) { t.Fatalf("expected column to be unchanged") } // Set the same bit to false. - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Set(100, f=false)`}); err != nil { + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Set(100, f=false)`}); err != nil { t.Fatal(err) } else if !res.Results[0].(bool) { t.Fatalf("expected column changed") } // Ensure that the false row is set. - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Row(f=false)`}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Row(f=false)`}); err != nil { t.Fatal(err) } else if columns := result.Results[0].(*pilosa.Row).Columns(); !reflect.DeepEqual(columns, []uint64{100}) { t.Fatalf("unexpected colums: %+v", columns) } // Ensure that the true row is empty. - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Row(f=true)`}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Row(f=true)`}); err != nil { t.Fatal(err) } else if columns := result.Results[0].(*pilosa.Row).Columns(); !reflect.DeepEqual(columns, []uint64{}) { t.Fatalf("unexpected colums: %+v", columns) @@ -1525,18 +1543,18 @@ func TestExecutor_Execute_SetBool(t *testing.T) { hldr := c.GetHolder(0) // Create fields. - index := hldr.MustCreateIndexIfNotExists("i", pilosa.IndexOptions{}) + index := hldr.MustCreateIndexIfNotExists(c.Idx(), pilosa.IndexOptions{}) if _, err := index.CreateFieldIfNotExists("f", pilosa.OptFieldTypeBool()); err != nil { t.Fatal(err) } // Set bool using a string value. - if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Set(100, f="true")`}); err == nil { + if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Set(100, f="true")`}); err == nil { t.Fatalf("expected invalid bool type error") } // Set bool using an integer. - if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Set(100, f=1)`}); err == nil { + if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Set(100, f=1)`}); err == nil { t.Fatalf("expected invalid bool type error") } @@ -1551,32 +1569,32 @@ func TestExecutor_Execute_SetDecimal(t *testing.T) { hldr := c.GetHolder(0) // Create fields. - index := hldr.MustCreateIndexIfNotExists("i", pilosa.IndexOptions{}) + index := hldr.MustCreateIndexIfNotExists(c.Idx(), pilosa.IndexOptions{}) if _, err := index.CreateFieldIfNotExists("f", pilosa.OptFieldTypeDecimal(2)); err != nil { t.Fatal(err) } // Set a value. - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Set(1000, f=1.5)`}); err != nil { + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Set(1000, f=1.5)`}); err != nil { t.Fatal(err) } else if !res.Results[0].(bool) { t.Fatalf("expected column changed") } // Set the same value again verify nothing changed. - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Set(1000, f=1.5)`}); err != nil { + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Set(1000, f=1.5)`}); err != nil { t.Fatal(err) } else if res.Results[0].(bool) { t.Fatalf("expected column to be unchanged") } - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Row(f == 1.5)`}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Row(f == 1.5)`}); err != nil { t.Fatal(err) } else if columns := result.Results[0].(*pilosa.Row).Columns(); !reflect.DeepEqual(columns, []uint64{1000}) { t.Fatalf("unexpected colums: %+v", columns) } - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Row(f > 1.4999)`}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Row(f > 1.4999)`}); err != nil { t.Fatal(err) } else if columns := result.Results[0].(*pilosa.Row).Columns(); !reflect.DeepEqual(columns, []uint64{1000}) { t.Fatalf("unexpected colums: %+v", columns) @@ -1588,13 +1606,13 @@ func TestExecutor_Execute_SetDecimal(t *testing.T) { hldr := c.GetHolder(0) // Create fields. - index := hldr.MustCreateIndexIfNotExists("i", pilosa.IndexOptions{}) + index := hldr.MustCreateIndexIfNotExists(c.Idx(), pilosa.IndexOptions{}) if _, err := index.CreateFieldIfNotExists("f", pilosa.OptFieldTypeDecimal(2)); err != nil { t.Fatal(err) } // Set decimal using a string value. - if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Set(1000, f="1.5")`}); err == nil { + if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Set(1000, f="1.5")`}); err == nil { t.Fatalf("expected invalid decimal type error") } }) @@ -1607,9 +1625,9 @@ func TestExecutor_Execute_OldPQL(t *testing.T) { hldr := c.GetHolder(0) // set a bit so the view gets created. - hldr.SetBit("i", "f", 1, 0) + hldr.SetBit(c.Idx(), "f", 1, 0) - if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `SetBit(frame=f, row=11, col=1)`}); err == nil || errors.Cause(err).Error() != "unknown call: SetBit" { + if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `SetBit(frame=f, row=11, col=1)`}); err == nil || errors.Cause(err).Error() != "unknown call: SetBit" { t.Fatalf("Expected error: 'unknown call: SetBit', got: %v. Full: %v", errors.Cause(err), err) } } @@ -1622,7 +1640,7 @@ func TestExecutor_Execute_SetValue(t *testing.T) { hldr := c.GetHolder(0) // Create fields. - index := hldr.MustCreateIndexIfNotExists("i", pilosa.IndexOptions{}) + index := hldr.MustCreateIndexIfNotExists(c.Idx(), pilosa.IndexOptions{}) if _, err := index.CreateFieldIfNotExists("f", pilosa.OptFieldTypeInt(math.MinInt64, math.MaxInt64)); err != nil { t.Fatal(err) } else if _, err := index.CreateFieldIfNotExists("xxx", pilosa.OptFieldTypeDefault()); err != nil { @@ -1630,9 +1648,9 @@ func TestExecutor_Execute_SetValue(t *testing.T) { } // Set bsiGroup values. - if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Set(10, f=25)`}); err != nil { + if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Set(10, f=25)`}); err != nil { t.Fatal(err) - } else if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Set(100, f=10)`}); err != nil { + } else if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Set(100, f=10)`}); err != nil { t.Fatal(err) } @@ -1641,7 +1659,7 @@ func TestExecutor_Execute_SetValue(t *testing.T) { qcx := idx.Txf().NewQcx() defer qcx.Abort() - f := hldr.Field("i", "f") + f := hldr.Field(c.Idx(), "f") if value, exists, err := f.Value(qcx, 10); err != nil { t.Fatal(err) } else if !exists { @@ -1664,25 +1682,25 @@ func TestExecutor_Execute_SetValue(t *testing.T) { defer c.Close() hldr := c.GetHolder(0) - index := hldr.MustCreateIndexIfNotExists("i", pilosa.IndexOptions{}) + index := hldr.MustCreateIndexIfNotExists(c.Idx(), pilosa.IndexOptions{}) if _, err := index.CreateFieldIfNotExists("f", pilosa.OptFieldTypeInt(math.MinInt64, math.MaxInt64)); err != nil { t.Fatal(err) } t.Run("ColumnBSIGroupRequired", func(t *testing.T) { - if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Set(f=100)`}); err == nil || errors.Cause(err).Error() != `Set() column argument 'col' required` { + if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Set(f=100)`}); err == nil || errors.Cause(err).Error() != `Set() column argument 'col' required` { t.Fatalf("unexpected error: %s", err) } }) t.Run("ColumnBSIGroupValue", func(t *testing.T) { - if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Set("bad_column", f=100)`}); err == nil || !strings.Contains(err.Error(), "unkeyed index") { + if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Set("bad_column", f=100)`}); err == nil || !strings.Contains(err.Error(), "unkeyed index") { t.Fatalf("unexpected error: %s", err) } }) t.Run("InvalidBSIGroupValueType", func(t *testing.T) { - if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Set(10, f="hello")`}); err == nil || !strings.Contains(err.Error(), "cannot create keys on unkeyed field") { + if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Set(10, f="hello")`}); err == nil || !strings.Contains(err.Error(), "cannot create keys on unkeyed field") { t.Fatalf("unexpected error: %s", err) } }) @@ -1694,7 +1712,7 @@ func TestExecutor_Execute_SetValue(t *testing.T) { hldr := c.GetHolder(0) // Create fields. - index := hldr.MustCreateIndexIfNotExists("i", pilosa.IndexOptions{}) + index := hldr.MustCreateIndexIfNotExists(c.Idx(), pilosa.IndexOptions{}) if _, err := index.CreateFieldIfNotExists("f", pilosa.OptFieldTypeTimestamp(pilosa.DefaultEpoch, pilosa.TimeUnitSeconds)); err != nil { t.Fatal(err) } else if _, err := index.CreateFieldIfNotExists("xxx", pilosa.OptFieldTypeDefault()); err != nil { @@ -1702,9 +1720,9 @@ func TestExecutor_Execute_SetValue(t *testing.T) { } // Set bsiGroup values. - if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Set(10, f='2000-01-01T00:00:00.000000000Z')`}); err != nil { + if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Set(10, f='2000-01-01T00:00:00.000000000Z')`}); err != nil { t.Fatal(err) - } else if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Set(100, f='2000-01-02T00:00:00Z')`}); err != nil { + } else if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Set(100, f='2000-01-02T00:00:00Z')`}); err != nil { t.Fatal(err) } @@ -1713,7 +1731,7 @@ func TestExecutor_Execute_SetValue(t *testing.T) { qcx := idx.Txf().NewQcx() defer qcx.Abort() - f := hldr.Field("i", "f") + f := hldr.Field(c.Idx(), "f") if value, exists, err := f.Value(qcx, 10); err != nil { t.Fatal(err) } else if !exists { @@ -1776,9 +1794,9 @@ func TestExecutor_ExecuteTopK(t *testing.T) { for _, tst := range tests { t.Run(tst.fieldName, func(t *testing.T) { pilosa.OptFieldTypeMutex(pilosa.CacheTypeRanked, 10) - c.CreateField(t, "i", pilosa.IndexOptions{TrackExistence: true}, tst.fieldName) - c.ImportBits(t, "i", tst.fieldName, tst.bits) - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: tst.query}); err != nil { + c.CreateField(t, c.Idx(), pilosa.IndexOptions{TrackExistence: true}, tst.fieldName) + c.ImportBits(t, c.Idx(), tst.fieldName, tst.bits) + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: tst.query}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual(result.Results, []interface{}{&pilosa.PairsField{ Pairs: []pilosa.Pair{ @@ -1799,11 +1817,11 @@ func TestExecutor_Execute_TopK_Time(t *testing.T) { isStandardEnabled := []bool{true, false} - for i, enabled := range isStandardEnabled { + for _, enabled := range isStandardEnabled { // Load some test data into a time field. - idx := fmt.Sprintf("i%d", i) - c.CreateField(t, idx, pilosa.IndexOptions{TrackExistence: true}, "f", pilosa.OptFieldTypeTime("YMD", "0", enabled)) - c.Query(t, idx, ` + index := c.Idx(fmt.Sprintf("%t", enabled)) + c.CreateField(t, index, pilosa.IndexOptions{TrackExistence: true}, "f", pilosa.OptFieldTypeTime("YMD", "0", enabled)) + c.Query(t, index, ` Set(0, f=0, 2016-01-02T00:00) Set(0, f=1, 2016-01-02T00:00) Set(0, f=0, 2016-01-03T00:00) @@ -1813,7 +1831,7 @@ func TestExecutor_Execute_TopK_Time(t *testing.T) { `) // Execute query. - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: idx, Query: `TopK(f, k=3, from=2016-01-01T00:00, to=2016-01-11T00:00)`}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: index, Query: `TopK(f, k=3, from=2016-01-01T00:00, to=2016-01-11T00:00)`}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual(result.Results, []interface{}{&pilosa.PairsField{ Pairs: []pilosa.Pair{ @@ -1835,13 +1853,13 @@ func TestExecutor_Execute_TopN(t *testing.T) { hldr := c.GetHolder(0) // Set columns for rows 0, 10, & 20 across two shards. - if idx, err := hldr.CreateIndex("i", pilosa.IndexOptions{}); err != nil { + if idx, err := hldr.CreateIndex(c.Idx(), pilosa.IndexOptions{}); err != nil { t.Fatal(err) } else if _, err := idx.CreateField("f", pilosa.OptFieldTypeDefault()); err != nil { t.Fatal(err) } else if _, err := idx.CreateField("other", pilosa.OptFieldTypeDefault()); err != nil { t.Fatal(err) - } else if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: ` + } else if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: ` Set(0, f=0) Set(1, f=0) Set(` + strconv.Itoa(ShardWidth) + `, f=0) @@ -1860,7 +1878,7 @@ func TestExecutor_Execute_TopN(t *testing.T) { t.Fatalf("recalculating caches: %v", err) } - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `TopN(f, n=2)`}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `TopN(f, n=2)`}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual(result.Results[0], &pilosa.PairsField{ Pairs: []pilosa.Pair{ @@ -1879,13 +1897,13 @@ func TestExecutor_Execute_TopN(t *testing.T) { hldr := c.GetHolder(0) // Set columns for rows 0, 10, & 20 across two shards. - if idx, err := hldr.CreateIndex("i", pilosa.IndexOptions{Keys: true}); err != nil { + if idx, err := hldr.CreateIndex(c.Idx(), pilosa.IndexOptions{Keys: true}); err != nil { t.Fatal(err) } else if _, err := idx.CreateField("f"); err != nil { t.Fatal(err) } else if _, err := idx.CreateField("other"); err != nil { t.Fatal(err) - } else if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: ` + } else if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: ` Set("zero", f=0) Set("one", f=0) Set("sw", f=0) @@ -1904,7 +1922,7 @@ func TestExecutor_Execute_TopN(t *testing.T) { t.Fatalf("recalculating caches: %v", err) } - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `TopN(f, n=2)`}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `TopN(f, n=2)`}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual(result.Results[0], &pilosa.PairsField{ Pairs: []pilosa.Pair{ @@ -1923,13 +1941,13 @@ func TestExecutor_Execute_TopN(t *testing.T) { hldr := c.GetHolder(0) // Set columns for rows 0, 10, & 20 across two shards. - if idx, err := hldr.CreateIndex("i", pilosa.IndexOptions{Keys: true}); err != nil { + if idx, err := hldr.CreateIndex(c.Idx(), pilosa.IndexOptions{Keys: true}); err != nil { t.Fatal(err) } else if _, err := idx.CreateField("f", pilosa.OptFieldKeys()); err != nil { t.Fatal(err) } else if _, err := idx.CreateField("other", pilosa.OptFieldKeys()); err != nil { t.Fatal(err) - } else if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: ` + } else if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: ` Set("zero", f="zero") Set("one", f="zero") Set("sw", f="zero") @@ -1948,7 +1966,7 @@ func TestExecutor_Execute_TopN(t *testing.T) { t.Fatalf("recalculating caches: %v", err) } - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `TopN(f, n=2)`}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `TopN(f, n=2)`}); err != nil { t.Fatal(err) } else { if !reflect.DeepEqual(result.Results[0], &pilosa.PairsField{ @@ -1969,13 +1987,13 @@ func TestExecutor_Execute_TopN(t *testing.T) { hldr := c.GetHolder(0) // Set columns for rows 0, 10, & 20 across two shards. - if idx, err := hldr.CreateIndex("i", pilosa.IndexOptions{Keys: true}); err != nil { + if idx, err := hldr.CreateIndex(c.Idx(), pilosa.IndexOptions{Keys: true}); err != nil { t.Fatal(err) } else if _, err := idx.CreateField("f", pilosa.OptFieldTypeDefault(), pilosa.OptFieldKeys()); err != nil { t.Fatal(err) } else if _, err := idx.CreateField("other", pilosa.OptFieldTypeDefault(), pilosa.OptFieldKeys()); err != nil { t.Fatal(err) - } else if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: ` + } else if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: ` Set("a", f="foo") Set("b", f="foo") Set("c", f="foo") @@ -1994,7 +2012,7 @@ func TestExecutor_Execute_TopN(t *testing.T) { t.Fatalf("recalculating caches: %v", err) } - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `TopN(f, n=2)`}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `TopN(f, n=2)`}); err != nil { t.Fatal(err) } else if diff := cmp.Diff(result.Results, []interface{}{ &pilosa.PairsField{ @@ -2015,11 +2033,11 @@ func TestExecutor_Execute_TopN(t *testing.T) { hldr := c.GetHolder(0) // Set data on the "f" field. - if idx, err := hldr.CreateIndex("i", pilosa.IndexOptions{}); err != nil { + if idx, err := hldr.CreateIndex(c.Idx(), pilosa.IndexOptions{}); err != nil { t.Fatal(err) } else if _, err := idx.CreateField("f", pilosa.OptFieldTypeDefault()); err != nil { t.Fatal(err) - } else if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: ` + } else if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: ` Set(0, f=0) Set(0, f=1) `}); err != nil { @@ -2029,7 +2047,7 @@ func TestExecutor_Execute_TopN(t *testing.T) { } // Attempt to query the "g" field. - if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `TopN(g, n=2)`}); err == nil || err.Error() != `executing: field "g" not found` { + if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `TopN(g, n=2)`}); err == nil || err.Error() != `executing: field "g" not found` { t.Fatalf("unexpected error: %v", err) } }) @@ -2040,11 +2058,11 @@ func TestExecutor_Execute_TopN(t *testing.T) { hldr := c.GetHolder(0) // Create BSI "f" field. - if idx, err := hldr.CreateIndex("i", pilosa.IndexOptions{}); err != nil { + if idx, err := hldr.CreateIndex(c.Idx(), pilosa.IndexOptions{}); err != nil { t.Fatal(err) } else if _, err := idx.CreateField("f", pilosa.OptFieldTypeInt(0, 100)); err != nil { t.Fatal(err) - } else if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `TopN(f, n=2)`}); err == nil || !strings.Contains(err.Error(), `finding top results: mapping on primary node: cannot compute TopN() on integer, decimal, or timestamp field: "f"`) { + } else if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `TopN(f, n=2)`}); err == nil || !strings.Contains(err.Error(), `finding top results: mapping on primary node: cannot compute TopN() on integer, decimal, or timestamp field: "f"`) { t.Fatalf("unexpected error: %v", err) } }) @@ -2054,16 +2072,16 @@ func TestExecutor_Execute_TopN(t *testing.T) { defer c.Close() hldr := c.GetHolder(0) - if idx, err := hldr.CreateIndex("i", pilosa.IndexOptions{}); err != nil { + if idx, err := hldr.CreateIndex(c.Idx(), pilosa.IndexOptions{}); err != nil { t.Fatal(err) } else if _, err := idx.CreateField("f", pilosa.OptFieldTypeSet(pilosa.CacheTypeNone, 0)); err != nil { t.Fatal(err) - } else if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: ` + } else if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: ` Set(0, f=0) Set(0, f=1) `}); err != nil { t.Fatal(err) - } else if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `TopN(f, n=2)`}); err == nil || !strings.Contains(err.Error(), `finding top results: mapping on primary node: cannot compute TopN(), field has no cache: "f"`) { + } else if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `TopN(f, n=2)`}); err == nil || !strings.Contains(err.Error(), `finding top results: mapping on primary node: cannot compute TopN(), field has no cache: "f"`) { t.Fatalf("unexpected error: %v", err) } }) @@ -2075,15 +2093,15 @@ func TestExecutor_Execute_TopN_fill(t *testing.T) { hldr := c.GetHolder(0) // Set columns for rows 0, 10, & 20 across two shards. - hldr.SetBit("i", "f", 0, 0) - hldr.SetBit("i", "f", 0, 1) - hldr.SetBit("i", "f", 0, 2) - hldr.SetBit("i", "f", 0, ShardWidth) - hldr.SetBit("i", "f", 1, ShardWidth+2) - hldr.SetBit("i", "f", 1, ShardWidth) + hldr.SetBit(c.Idx(), "f", 0, 0) + hldr.SetBit(c.Idx(), "f", 0, 1) + hldr.SetBit(c.Idx(), "f", 0, 2) + hldr.SetBit(c.Idx(), "f", 0, ShardWidth) + hldr.SetBit(c.Idx(), "f", 1, ShardWidth+2) + hldr.SetBit(c.Idx(), "f", 1, ShardWidth) // Execute query. - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `TopN(f, n=1)`}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `TopN(f, n=1)`}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual(result.Results, []interface{}{&pilosa.PairsField{ Pairs: []pilosa.Pair{ @@ -2101,26 +2119,26 @@ func TestExecutor_Execute_TopN_fill_small(t *testing.T) { defer c.Close() hldr := c.GetHolder(0) - hldr.SetBit("i", "f", 0, 0) - hldr.SetBit("i", "f", 0, ShardWidth) - hldr.SetBit("i", "f", 0, 2*ShardWidth) - hldr.SetBit("i", "f", 0, 3*ShardWidth) - hldr.SetBit("i", "f", 0, 4*ShardWidth) + hldr.SetBit(c.Idx(), "f", 0, 0) + hldr.SetBit(c.Idx(), "f", 0, ShardWidth) + hldr.SetBit(c.Idx(), "f", 0, 2*ShardWidth) + hldr.SetBit(c.Idx(), "f", 0, 3*ShardWidth) + hldr.SetBit(c.Idx(), "f", 0, 4*ShardWidth) - hldr.SetBit("i", "f", 1, 0) - hldr.SetBit("i", "f", 1, 1) + hldr.SetBit(c.Idx(), "f", 1, 0) + hldr.SetBit(c.Idx(), "f", 1, 1) - hldr.SetBit("i", "f", 2, ShardWidth) - hldr.SetBit("i", "f", 2, ShardWidth+1) + hldr.SetBit(c.Idx(), "f", 2, ShardWidth) + hldr.SetBit(c.Idx(), "f", 2, ShardWidth+1) - hldr.SetBit("i", "f", 3, 2*ShardWidth) - hldr.SetBit("i", "f", 3, 2*ShardWidth+1) + hldr.SetBit(c.Idx(), "f", 3, 2*ShardWidth) + hldr.SetBit(c.Idx(), "f", 3, 2*ShardWidth+1) - hldr.SetBit("i", "f", 4, 3*ShardWidth) - hldr.SetBit("i", "f", 4, 3*ShardWidth+1) + hldr.SetBit(c.Idx(), "f", 4, 3*ShardWidth) + hldr.SetBit(c.Idx(), "f", 4, 3*ShardWidth+1) // Execute query. - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `TopN(f, n=1)`}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `TopN(f, n=1)`}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual(result.Results, []interface{}{&pilosa.PairsField{ Pairs: []pilosa.Pair{ @@ -2139,19 +2157,19 @@ func TestExecutor_Execute_TopN_Src(t *testing.T) { hldr := c.GetHolder(0) // Set columns for rows 0, 10, & 20 across two shards. - hldr.SetBit("i", "f", 0, 0) - hldr.SetBit("i", "f", 0, 1) - hldr.SetBit("i", "f", 0, ShardWidth) - hldr.SetBit("i", "f", 10, ShardWidth) - hldr.SetBit("i", "f", 10, ShardWidth+1) - hldr.SetBit("i", "f", 20, ShardWidth) - hldr.SetBit("i", "f", 20, ShardWidth+1) - hldr.SetBit("i", "f", 20, ShardWidth+2) + hldr.SetBit(c.Idx(), "f", 0, 0) + hldr.SetBit(c.Idx(), "f", 0, 1) + hldr.SetBit(c.Idx(), "f", 0, ShardWidth) + hldr.SetBit(c.Idx(), "f", 10, ShardWidth) + hldr.SetBit(c.Idx(), "f", 10, ShardWidth+1) + hldr.SetBit(c.Idx(), "f", 20, ShardWidth) + hldr.SetBit(c.Idx(), "f", 20, ShardWidth+1) + hldr.SetBit(c.Idx(), "f", 20, ShardWidth+2) // Create an intersecting row. - hldr.SetBit("i", "other", 100, ShardWidth) - hldr.SetBit("i", "other", 100, ShardWidth+1) - hldr.SetBit("i", "other", 100, ShardWidth+2) + hldr.SetBit(c.Idx(), "other", 100, ShardWidth) + hldr.SetBit(c.Idx(), "other", 100, ShardWidth+1) + hldr.SetBit(c.Idx(), "other", 100, ShardWidth+2) err := c.GetNode(0).RecalculateCaches(t) if err != nil { @@ -2159,7 +2177,7 @@ func TestExecutor_Execute_TopN_Src(t *testing.T) { } // Execute query. - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `TopN(f, Row(other=100), n=3)`}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `TopN(f, Row(other=100), n=3)`}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual(result.Results, []interface{}{&pilosa.PairsField{ Pairs: []pilosa.Pair{ @@ -2181,7 +2199,7 @@ func TestExecutor_Execute_MinMax(t *testing.T) { defer c.Close() hldr := c.GetHolder(0) - idx, err := hldr.CreateIndex("i", pilosa.IndexOptions{}) + idx, err := hldr.CreateIndex(c.Idx(), pilosa.IndexOptions{}) if err != nil { t.Fatal(err) } @@ -2203,7 +2221,7 @@ func TestExecutor_Execute_MinMax(t *testing.T) { t.Fatal(err) } - if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: fmt.Sprintf(` + if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: fmt.Sprintf(` Set(10, %s=%d) `, fld, test.set)}); err != nil { t.Fatal(err) @@ -2213,7 +2231,7 @@ func TestExecutor_Execute_MinMax(t *testing.T) { t.Run("Min", func(t *testing.T) { pql = fmt.Sprintf(`Min(field=%s)`, fld) - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: pql}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: pql}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual(result.Results[0], pilosa.ValCount{Val: test.set, Count: 1}) { t.Fatalf("unexpected min result, test %d: %s", i, spew.Sdump(result)) @@ -2222,7 +2240,7 @@ func TestExecutor_Execute_MinMax(t *testing.T) { t.Run("Max", func(t *testing.T) { pql = fmt.Sprintf(`Max(field=%s)`, fld) - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: pql}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: pql}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual(result.Results[0], pilosa.ValCount{Val: test.set, Count: 1}) { t.Fatalf("unexpected max result, test %d: %s", i, spew.Sdump(result)) @@ -2231,7 +2249,7 @@ func TestExecutor_Execute_MinMax(t *testing.T) { t.Run("Min", func(t *testing.T) { pql = fmt.Sprintf(`Min(field="%s")`, fld) - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: pql}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: pql}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual(result.Results[0], pilosa.ValCount{Val: test.set, Count: 1}) { t.Fatalf("unexpected min result, test %d: %s", i, spew.Sdump(result)) @@ -2240,7 +2258,7 @@ func TestExecutor_Execute_MinMax(t *testing.T) { t.Run("Max", func(t *testing.T) { pql = fmt.Sprintf(`Max(field="%s")`, fld) - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: pql}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: pql}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual(result.Results[0], pilosa.ValCount{Val: test.set, Count: 1}) { t.Fatalf("unexpected max result, test %d: %s", i, spew.Sdump(result)) @@ -2249,7 +2267,7 @@ func TestExecutor_Execute_MinMax(t *testing.T) { t.Run("Min", func(t *testing.T) { pql = fmt.Sprintf(`Min(%s)`, fld) - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: pql}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: pql}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual(result.Results[0], pilosa.ValCount{Val: test.set, Count: 1}) { t.Fatalf("unexpected min result, test %d: %s", i, spew.Sdump(result)) @@ -2258,7 +2276,7 @@ func TestExecutor_Execute_MinMax(t *testing.T) { t.Run("Max", func(t *testing.T) { pql = fmt.Sprintf(`Max(%s)`, fld) - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: pql}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: pql}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual(result.Results[0], pilosa.ValCount{Val: test.set, Count: 1}) { t.Fatalf("unexpected max result, test %d: %s", i, spew.Sdump(result)) @@ -2273,7 +2291,7 @@ func TestExecutor_Execute_MinMax(t *testing.T) { defer c.Close() hldr := c.GetHolder(0) - idx, err := hldr.CreateIndex("i", pilosa.IndexOptions{}) + idx, err := hldr.CreateIndex(c.Idx(), pilosa.IndexOptions{}) if err != nil { t.Fatal(err) } @@ -2320,28 +2338,28 @@ func TestExecutor_Execute_MinMax(t *testing.T) { if _, err := idx.CreateFieldIfNotExists("z", pilosa.OptFieldTypeDefault()); err != nil { t.Fatal(err) } - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Set(1, z=0)`}); err != nil { + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Set(1, z=0)`}); err != nil { t.Fatal(err) } else if !res.Results[0].(bool) { t.Fatalf("expected column changed") } // set things in other shards, that won't have decimal values - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Set(1234567, z=0)`}); err != nil { + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Set(1234567, z=0)`}); err != nil { t.Fatal(err) } else if !res.Results[0].(bool) { t.Fatalf("expected column changed") } - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Set(2345678, z=0)`}); err != nil { + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Set(2345678, z=0)`}); err != nil { t.Fatal(err) } else if !res.Results[0].(bool) { t.Fatalf("expected column changed") } - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Set(3456789, z=0)`}); err != nil { + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Set(3456789, z=0)`}); err != nil { t.Fatal(err) } else if !res.Results[0].(bool) { t.Fatalf("expected column changed") } - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Set(4567890, z=0)`}); err != nil { + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Set(4567890, z=0)`}); err != nil { t.Fatal(err) } else if !res.Results[0].(bool) { t.Fatalf("expected column changed") @@ -2353,7 +2371,7 @@ func TestExecutor_Execute_MinMax(t *testing.T) { t.Fatal(err) } - if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: fmt.Sprintf(` + if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: fmt.Sprintf(` Set(6700000, %s=%s) `, fld, test.set)}); err != nil { t.Fatal(err) @@ -2363,7 +2381,7 @@ func TestExecutor_Execute_MinMax(t *testing.T) { t.Run("Min", func(t *testing.T) { pql = fmt.Sprintf(`Min(field=%s)`, fld) - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: pql}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: pql}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual(result.Results[0], pilosa.ValCount{DecimalVal: &test.exp, Count: 1}) { t.Fatalf("unexpected min result, test %d: %s", i, spew.Sdump(result)) @@ -2372,7 +2390,7 @@ func TestExecutor_Execute_MinMax(t *testing.T) { t.Run("Max", func(t *testing.T) { pql = fmt.Sprintf(`Max(field=%s)`, fld) - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: pql}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: pql}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual(result.Results[0], pilosa.ValCount{DecimalVal: &test.exp, Count: 1}) { t.Fatalf("unexpected max result, test %d: %s", i, spew.Sdump(result)) @@ -2381,7 +2399,7 @@ func TestExecutor_Execute_MinMax(t *testing.T) { t.Run("Min", func(t *testing.T) { pql = fmt.Sprintf(`Min(%s)`, fld) - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: pql}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: pql}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual(result.Results[0], pilosa.ValCount{DecimalVal: &test.exp, Count: 1}) { t.Fatalf("unexpected min result, test %d: %s", i, spew.Sdump(result)) @@ -2390,7 +2408,7 @@ func TestExecutor_Execute_MinMax(t *testing.T) { t.Run("Max", func(t *testing.T) { pql = fmt.Sprintf(`Max(%s)`, fld) - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: pql}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: pql}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual(result.Results[0], pilosa.ValCount{DecimalVal: &test.exp, Count: 1}) { t.Fatalf("unexpected max result, test %d: %s", i, spew.Sdump(result)) @@ -2405,7 +2423,7 @@ func TestExecutor_Execute_MinMax(t *testing.T) { defer c.Close() hldr := c.GetHolder(0) - idx, err := hldr.CreateIndex("i", pilosa.IndexOptions{}) + idx, err := hldr.CreateIndex(c.Idx(), pilosa.IndexOptions{}) if err != nil { t.Fatal(err) } @@ -2424,7 +2442,7 @@ func TestExecutor_Execute_MinMax(t *testing.T) { t.Run("MinMaxField_"+fld, func(t *testing.T) { if _, err := idx.CreateField(fld, pilosa.OptFieldTypeTimestamp(test.epoch, pilosa.TimeUnitSeconds)); err != nil { t.Fatal(err) - } else if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: fmt.Sprintf(`Set(10, %s="%s")`, fld, test.set.Format(time.RFC3339))}); err != nil { + } else if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: fmt.Sprintf(`Set(10, %s="%s")`, fld, test.set.Format(time.RFC3339))}); err != nil { t.Fatal(err) } @@ -2432,7 +2450,7 @@ func TestExecutor_Execute_MinMax(t *testing.T) { t.Run("Min", func(t *testing.T) { pql = fmt.Sprintf(`Min(field=%s)`, fld) - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: pql}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: pql}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual(result.Results[0], pilosa.ValCount{TimestampVal: test.set, Count: 1}) { t.Fatalf("unexpected min result, test %d: %s", i, spew.Sdump(result)) @@ -2441,7 +2459,7 @@ func TestExecutor_Execute_MinMax(t *testing.T) { t.Run("Max", func(t *testing.T) { pql = fmt.Sprintf(`Max(field=%s)`, fld) - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: pql}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: pql}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual(result.Results[0], pilosa.ValCount{TimestampVal: test.set, Count: 1}) { t.Fatalf("unexpected max result, test %d: %s", i, spew.Sdump(result)) @@ -2450,7 +2468,7 @@ func TestExecutor_Execute_MinMax(t *testing.T) { t.Run("Min", func(t *testing.T) { pql = fmt.Sprintf(`Min(field="%s")`, fld) - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: pql}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: pql}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual(result.Results[0], pilosa.ValCount{TimestampVal: test.set, Count: 1}) { t.Fatalf("unexpected min result, test %d: %s", i, spew.Sdump(result)) @@ -2459,7 +2477,7 @@ func TestExecutor_Execute_MinMax(t *testing.T) { t.Run("Max", func(t *testing.T) { pql = fmt.Sprintf(`Max(field="%s")`, fld) - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: pql}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: pql}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual(result.Results[0], pilosa.ValCount{TimestampVal: test.set, Count: 1}) { t.Fatalf("unexpected max result, test %d: %s", i, spew.Sdump(result)) @@ -2468,7 +2486,7 @@ func TestExecutor_Execute_MinMax(t *testing.T) { t.Run("Min", func(t *testing.T) { pql = fmt.Sprintf(`Min(%s)`, fld) - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: pql}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: pql}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual(result.Results[0], pilosa.ValCount{TimestampVal: test.set, Count: 1}) { t.Fatalf("unexpected min result, test %d: %s", i, spew.Sdump(result)) @@ -2477,7 +2495,7 @@ func TestExecutor_Execute_MinMax(t *testing.T) { t.Run("Max", func(t *testing.T) { pql = fmt.Sprintf(`Max(%s)`, fld) - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: pql}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: pql}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual(result.Results[0], pilosa.ValCount{TimestampVal: test.set, Count: 1}) { t.Fatalf("unexpected max result, test %d: %s", i, spew.Sdump(result)) @@ -2493,7 +2511,7 @@ func TestExecutor_Execute_MinMax(t *testing.T) { defer c.Close() hldr := c.GetHolder(0) - idx, err := hldr.CreateIndex("i", pilosa.IndexOptions{}) + idx, err := hldr.CreateIndex(c.Idx(), pilosa.IndexOptions{}) if err != nil { t.Fatal(err) } @@ -2506,7 +2524,7 @@ func TestExecutor_Execute_MinMax(t *testing.T) { t.Fatal(err) } - if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: ` + if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: ` Set(0, x=0) Set(3, x=0) Set(` + strconv.Itoa(ShardWidth+1) + `, x=0) @@ -2543,7 +2561,7 @@ func TestExecutor_Execute_MinMax(t *testing.T) { } else { pql = fmt.Sprintf(`Min(%s, field=f)`, tt.filter) } - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: pql}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: pql}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual(result.Results[0], pilosa.ValCount{Val: tt.exp, Count: tt.cnt}) { t.Fatalf("unexpected result, test %d: %s", i, spew.Sdump(result)) @@ -2557,7 +2575,7 @@ func TestExecutor_Execute_MinMax(t *testing.T) { defer c.Close() hldr := c.GetHolder(0) - idx, err := hldr.CreateIndex("i", pilosa.IndexOptions{Keys: true}) + idx, err := hldr.CreateIndex(c.Idx(), pilosa.IndexOptions{Keys: true}) if err != nil { t.Fatal(err) } @@ -2570,7 +2588,7 @@ func TestExecutor_Execute_MinMax(t *testing.T) { t.Fatal(err) } - if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: ` + if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: ` Set("zero", x=0) Set("three", x=0) Set("sw1", x=0) @@ -2607,7 +2625,7 @@ func TestExecutor_Execute_MinMax(t *testing.T) { } else { pql = fmt.Sprintf(`Min(%s, field=f)`, tt.filter) } - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: pql}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: pql}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual(result.Results[0], pilosa.ValCount{Val: tt.exp, Count: tt.cnt}) { t.Fatalf("unexpected result, test %d: %s", i, spew.Sdump(result)) @@ -2633,7 +2651,7 @@ func TestExecutor_Execute_MinMax(t *testing.T) { } else { pql = fmt.Sprintf(`Max(%s, field=f)`, tt.filter) } - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: pql}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: pql}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual(result.Results[0], pilosa.ValCount{Val: tt.exp, Count: tt.cnt}) { t.Fatalf("unexpected result, test %d: %s", i, spew.Sdump(result)) @@ -2650,7 +2668,7 @@ func TestExecutor_Execute_MinMaxRow(t *testing.T) { defer c.Close() hldr := c.GetHolder(0) - idx, err := hldr.CreateIndex("i", pilosa.IndexOptions{}) + idx, err := hldr.CreateIndex(c.Idx(), pilosa.IndexOptions{}) if err != nil { t.Fatal(err) } @@ -2659,7 +2677,7 @@ func TestExecutor_Execute_MinMaxRow(t *testing.T) { t.Fatal(err) } - if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: ` + if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: ` Set(0, f=7000) Set(3, f=50) Set(` + strconv.Itoa(ShardWidth+1) + `, f=10000) @@ -2670,7 +2688,7 @@ func TestExecutor_Execute_MinMaxRow(t *testing.T) { } t.Run("MinRow", func(t *testing.T) { - result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: "MinRow(field=f)"}) + result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: "MinRow(field=f)"}) if err != nil { t.Fatal(err) } @@ -2683,13 +2701,13 @@ func TestExecutor_Execute_MinMaxRow(t *testing.T) { } }) t.Run("MinRowNonExistent", func(t *testing.T) { - _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: "MinRow(field=fake)"}) + _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: "MinRow(field=fake)"}) if got, exp := err.Error(), "executing: executeMinRow: mapping on primary node: field not found"; got != exp { t.Fatalf("expected %v, got %v", exp, got) } }) t.Run("MaxRow", func(t *testing.T) { - result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: "MaxRow(field=f)"}) + result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: "MaxRow(field=f)"}) if err != nil { t.Fatal(err) } @@ -2702,7 +2720,7 @@ func TestExecutor_Execute_MinMaxRow(t *testing.T) { } }) t.Run("MaxRowNonExistent", func(t *testing.T) { - _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: "MaxRow(field=fake)"}) + _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: "MaxRow(field=fake)"}) if got, exp := err.Error(), "executing: executeMaxRow: mapping on primary node: field not found"; got != exp { t.Fatalf("expected %v, got %v", exp, got) } @@ -2714,7 +2732,7 @@ func TestExecutor_Execute_MinMaxRow(t *testing.T) { defer c.Close() hldr := c.GetHolder(0) - idx, err := hldr.CreateIndex("i", pilosa.IndexOptions{}) + idx, err := hldr.CreateIndex(c.Idx(), pilosa.IndexOptions{}) if err != nil { t.Fatal(err) } @@ -2723,7 +2741,7 @@ func TestExecutor_Execute_MinMaxRow(t *testing.T) { t.Fatal(err) } - if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: ` + if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: ` Set(0, f="seven-thousand") Set(3, f="fifty") Set(` + strconv.Itoa(ShardWidth+1) + `, f="ten-thousand") @@ -2734,7 +2752,7 @@ func TestExecutor_Execute_MinMaxRow(t *testing.T) { } t.Run("MinRow", func(t *testing.T) { - result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: "MinRow(field=f)"}) + result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: "MinRow(field=f)"}) if err != nil { t.Fatal(err) } @@ -2748,7 +2766,7 @@ func TestExecutor_Execute_MinMaxRow(t *testing.T) { }) t.Run("MaxRow", func(t *testing.T) { - result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: "MaxRow(field=f)"}) + result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: "MaxRow(field=f)"}) if err != nil { t.Fatal(err) } @@ -2770,7 +2788,7 @@ func TestExecutor_Execute_Sum(t *testing.T) { defer c.Close() hldr := c.GetHolder(0) - idx, err := hldr.CreateIndex("i", pilosa.IndexOptions{}) + idx, err := hldr.CreateIndex(c.Idx(), pilosa.IndexOptions{}) if err != nil { t.Fatal(err) } @@ -2795,7 +2813,7 @@ func TestExecutor_Execute_Sum(t *testing.T) { t.Fatal(err) } - if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: ` + if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: ` Set(0, x=0) Set(` + strconv.Itoa(ShardWidth+1) + `, x=0) @@ -2816,7 +2834,7 @@ func TestExecutor_Execute_Sum(t *testing.T) { t.Run("Integer", func(t *testing.T) { t.Run("NoFilter", func(t *testing.T) { - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Sum(field=foo)`}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Sum(field=foo)`}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual(result.Results[0], pilosa.ValCount{Val: 200, Count: 5}) { t.Fatalf("unexpected result: %s", spew.Sdump(result)) @@ -2824,7 +2842,7 @@ func TestExecutor_Execute_Sum(t *testing.T) { }) t.Run("NoFilter", func(t *testing.T) { - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Sum(field="foo")`}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Sum(field="foo")`}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual(result.Results[0], pilosa.ValCount{Val: 200, Count: 5}) { t.Fatalf("unexpected result: %s", spew.Sdump(result)) @@ -2832,7 +2850,7 @@ func TestExecutor_Execute_Sum(t *testing.T) { }) t.Run("NoFilter", func(t *testing.T) { - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Sum(foo)`}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Sum(foo)`}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual(result.Results[0], pilosa.ValCount{Val: 200, Count: 5}) { t.Fatalf("unexpected result: %s", spew.Sdump(result)) @@ -2840,7 +2858,7 @@ func TestExecutor_Execute_Sum(t *testing.T) { }) t.Run("WithFilter", func(t *testing.T) { - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Sum(Row(x=0), field=foo)`}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Sum(Row(x=0), field=foo)`}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual(result.Results[0], pilosa.ValCount{Val: 80, Count: 2}) { t.Fatalf("unexpected result: %s", spew.Sdump(result)) @@ -2848,7 +2866,7 @@ func TestExecutor_Execute_Sum(t *testing.T) { }) t.Run("WithFilter", func(t *testing.T) { - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Sum(foo, Row(x=0))`}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Sum(foo, Row(x=0))`}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual(result.Results[0], pilosa.ValCount{Val: 80, Count: 2}) { t.Fatalf("unexpected result: %s", spew.Sdump(result)) @@ -2857,7 +2875,7 @@ func TestExecutor_Execute_Sum(t *testing.T) { }) t.Run("SumNonExistent", func(t *testing.T) { - _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Sum(field=fake)`}) + _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Sum(field=fake)`}) if err.Error() != "executing: executeSum: mapping on primary node: field not found" { t.Fatal(err) } @@ -2865,7 +2883,7 @@ func TestExecutor_Execute_Sum(t *testing.T) { t.Run("Decimal", func(t *testing.T) { t.Run("NoFilter", func(t *testing.T) { - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Sum(field=dec)`}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Sum(field=dec)`}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual(result.Results[0], pilosa.ValCount{DecimalVal: pql.NewDecimal(700007, 3).Clone(), Count: 3}) { t.Fatalf("unexpected result: %s", spew.Sdump(result)) @@ -2873,7 +2891,7 @@ func TestExecutor_Execute_Sum(t *testing.T) { }) t.Run("WithFilter", func(t *testing.T) { - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Sum(Row(x=0), field=dec)`}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Sum(Row(x=0), field=dec)`}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual(result.Results[0], pilosa.ValCount{DecimalVal: pql.NewDecimal(500005, 3).Clone(), Count: 2}) { t.Fatalf("unexpected result: %s", spew.Sdump(result)) @@ -2881,7 +2899,7 @@ func TestExecutor_Execute_Sum(t *testing.T) { }) t.Run("NoFilter", func(t *testing.T) { - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Sum(dec)`}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Sum(dec)`}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual(result.Results[0], pilosa.ValCount{DecimalVal: pql.NewDecimal(700007, 3).Clone(), Count: 3}) { t.Fatalf("unexpected result: %s", spew.Sdump(result)) @@ -2889,7 +2907,7 @@ func TestExecutor_Execute_Sum(t *testing.T) { }) t.Run("WithFilter", func(t *testing.T) { - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Sum(dec, Row(x=0))`}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Sum(dec, Row(x=0))`}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual(result.Results[0], pilosa.ValCount{DecimalVal: pql.NewDecimal(500005, 3).Clone(), Count: 2}) { t.Fatalf("unexpected result: %s", spew.Sdump(result)) @@ -2904,7 +2922,7 @@ func TestExecutor_Execute_Sum(t *testing.T) { defer c.Close() hldr := c.GetHolder(0) - idx, err := hldr.CreateIndex("i", pilosa.IndexOptions{Keys: true}) + idx, err := hldr.CreateIndex(c.Idx(), pilosa.IndexOptions{Keys: true}) if err != nil { t.Fatal(err) } @@ -2925,7 +2943,7 @@ func TestExecutor_Execute_Sum(t *testing.T) { t.Fatal(err) } - if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: ` + if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: ` Set("zero", x=0) Set("sw1", x=0) @@ -2941,7 +2959,7 @@ func TestExecutor_Execute_Sum(t *testing.T) { } t.Run("NoFilter", func(t *testing.T) { - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Sum(field=foo)`}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Sum(field=foo)`}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual(result.Results[0], pilosa.ValCount{Val: 200, Count: 5}) { t.Fatalf("unexpected result: %s", spew.Sdump(result)) @@ -2949,7 +2967,7 @@ func TestExecutor_Execute_Sum(t *testing.T) { }) t.Run("WithFilter", func(t *testing.T) { - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Sum(Row(x=0), field=foo)`}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Sum(Row(x=0), field=foo)`}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual(result.Results[0], pilosa.ValCount{Val: 80, Count: 2}) { t.Fatalf("unexpected result: %s", spew.Sdump(result)) @@ -2964,7 +2982,7 @@ func TestExecutor_DecimalArgs(t *testing.T) { defer c.Close() hldr := c.GetHolder(0) - idx, err := hldr.CreateIndex("i", pilosa.IndexOptions{}) + idx, err := hldr.CreateIndex(c.Idx(), pilosa.IndexOptions{}) if err != nil { t.Fatal(err) } @@ -2982,7 +3000,7 @@ func TestExecutor_DecimalArgs(t *testing.T) { t.Fatal(err) } - if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: ` + if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: ` Set(0, f=0) `}); err != nil { t.Fatal(err) @@ -2995,7 +3013,7 @@ func TestExecutor_Execute_Row_BSIGroup(t *testing.T) { defer c.Close() hldr := c.GetHolder(0) - idx, err := hldr.CreateIndex("i", pilosa.IndexOptions{TrackExistence: true}) + idx, err := hldr.CreateIndex(c.Idx(), pilosa.IndexOptions{TrackExistence: true}) if err != nil { t.Fatal(err) } @@ -3020,7 +3038,7 @@ func TestExecutor_Execute_Row_BSIGroup(t *testing.T) { t.Fatal(err) } - if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: ` + if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: ` Set(0, f=0) Set(` + strconv.Itoa(ShardWidth+1) + `, f=0) @@ -3039,7 +3057,7 @@ func TestExecutor_Execute_Row_BSIGroup(t *testing.T) { t.Run("EQ", func(t *testing.T) { // EQ null - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Row(other == null)`}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Row(other == null)`}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual([]uint64{1, 50, @@ -3051,14 +3069,14 @@ func TestExecutor_Execute_Row_BSIGroup(t *testing.T) { t.Fatalf("unexpected result: %#v", result.Results[0].(*pilosa.Row).Columns()) } // EQ - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Row(foo == 20)`}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Row(foo == 20)`}); err != nil { t.Fatal(err) } else if got, exp := result.Results[0].(*pilosa.Row).Columns(), []uint64{50, (5 * ShardWidth) + 100}; !reflect.DeepEqual(exp, got) { t.Fatalf("Query().Row.Columns=%#v, expected %#v", got, exp) } // EQ (single = form) - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Row(foo = 20)`}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Row(foo = 20)`}); err != nil { t.Fatal(err) } else if got, exp := result.Results[0].(*pilosa.Row).Columns(), []uint64{50, (5 * ShardWidth) + 100}; !reflect.DeepEqual(exp, got) { t.Fatalf("Query().Row.Columns=%#v, expected %#v", got, exp) @@ -3067,19 +3085,19 @@ func TestExecutor_Execute_Row_BSIGroup(t *testing.T) { t.Run("NEQ", func(t *testing.T) { // NEQ null - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Row(other != null)`}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Row(other != null)`}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual([]uint64{0}, result.Results[0].(*pilosa.Row).Columns()) { t.Fatalf("unexpected result: %#v", result.Results[0].(*pilosa.Row).Columns()) } // NEQ - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Row(foo != 20)`}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Row(foo != 20)`}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual([]uint64{ShardWidth, ShardWidth + 1, ShardWidth + 2}, result.Results[0].(*pilosa.Row).Columns()) { t.Fatalf("unexpected result: %#v", result.Results[0].(*pilosa.Row).Columns()) } // NEQ - - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Row(other != -20)`}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Row(other != -20)`}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual([]uint64{0}, result.Results[0].(*pilosa.Row).Columns()) { t.Fatalf("unexpected result: %#v", result.Results[0].(*pilosa.Row).Columns()) @@ -3087,7 +3105,7 @@ func TestExecutor_Execute_Row_BSIGroup(t *testing.T) { }) t.Run("LT", func(t *testing.T) { - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Row(foo < 20)`}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Row(foo < 20)`}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual([]uint64{ShardWidth + 2}, result.Results[0].(*pilosa.Row).Columns()) { t.Fatalf("unexpected result: %s", spew.Sdump(result)) @@ -3095,7 +3113,7 @@ func TestExecutor_Execute_Row_BSIGroup(t *testing.T) { }) t.Run("LTE", func(t *testing.T) { - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Row(foo <= 20)`}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Row(foo <= 20)`}); err != nil { t.Fatal(err) } else if got, exp := result.Results[0].(*pilosa.Row).Columns(), []uint64{50, ShardWidth + 2, (5 * ShardWidth) + 100}; !reflect.DeepEqual(got, exp) { t.Fatalf("unexpected result: got=%v, exp=%v", got, exp) @@ -3103,7 +3121,7 @@ func TestExecutor_Execute_Row_BSIGroup(t *testing.T) { }) t.Run("GT", func(t *testing.T) { - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Row(foo > 20)`}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Row(foo > 20)`}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual([]uint64{ShardWidth, ShardWidth + 1}, result.Results[0].(*pilosa.Row).Columns()) { t.Fatalf("unexpected result: %v", result.Results[0].(*pilosa.Row).Columns()) @@ -3111,7 +3129,7 @@ func TestExecutor_Execute_Row_BSIGroup(t *testing.T) { }) t.Run("GTE", func(t *testing.T) { - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Row(foo >= 20)`}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Row(foo >= 20)`}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual([]uint64{50, ShardWidth, ShardWidth + 1, (5 * ShardWidth) + 100}, result.Results[0].(*pilosa.Row).Columns()) { t.Fatalf("unexpected result: %v", result.Results[0].(*pilosa.Row).Columns()) @@ -3144,7 +3162,7 @@ func TestExecutor_Execute_Row_BSIGroup(t *testing.T) { if test.exp { expected = []uint64{0} } - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: test.q}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: test.q}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual(expected, result.Results[0].(*pilosa.Row).Columns()) { t.Fatalf("unexpected result for query: %s (%#v)", test.q, result.Results[0].(*pilosa.Row).Columns()) @@ -3156,7 +3174,7 @@ func TestExecutor_Execute_Row_BSIGroup(t *testing.T) { // Ensure that the NotNull code path gets run. t.Run("NotNull", func(t *testing.T) { - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Row(0 <= other <= 1000)`}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Row(0 <= other <= 1000)`}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual([]uint64{0}, result.Results[0].(*pilosa.Row).Columns()) { t.Fatalf("unexpected result: %s", spew.Sdump(result)) @@ -3164,7 +3182,7 @@ func TestExecutor_Execute_Row_BSIGroup(t *testing.T) { }) t.Run("BelowMin", func(t *testing.T) { - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Row(foo == 0)`}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Row(foo == 0)`}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual([]uint64{}, result.Results[0].(*pilosa.Row).Columns()) { t.Fatalf("unexpected result: %s", spew.Sdump(result)) @@ -3172,7 +3190,7 @@ func TestExecutor_Execute_Row_BSIGroup(t *testing.T) { }) t.Run("AboveMax", func(t *testing.T) { - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Row(foo == 200)`}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Row(foo == 200)`}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual([]uint64{}, result.Results[0].(*pilosa.Row).Columns()) { t.Fatalf("unexpected result: %s", spew.Sdump(result)) @@ -3180,7 +3198,7 @@ func TestExecutor_Execute_Row_BSIGroup(t *testing.T) { }) t.Run("LTAboveMax", func(t *testing.T) { - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Row(edge < 200)`}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Row(edge < 200)`}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual([]uint64{0, 1}, result.Results[0].(*pilosa.Row).Columns()) { t.Fatalf("unexpected result: %s", spew.Sdump(result.Results[0].(*pilosa.Row).Columns())) @@ -3188,7 +3206,7 @@ func TestExecutor_Execute_Row_BSIGroup(t *testing.T) { }) t.Run("GTBelowMin", func(t *testing.T) { - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Row(edge > -1000)`}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Row(edge > -1000)`}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual([]uint64{0, 1}, result.Results[0].(*pilosa.Row).Columns()) { t.Fatalf("unexpected result: %s", spew.Sdump(result.Results[0].(*pilosa.Row).Columns())) @@ -3196,7 +3214,7 @@ func TestExecutor_Execute_Row_BSIGroup(t *testing.T) { }) t.Run("ErrFieldNotFound", func(t *testing.T) { - if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Row(bad_field >= 20)`}); errors.Cause(err) != pilosa.ErrFieldNotFound { + if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Row(bad_field >= 20)`}); errors.Cause(err) != pilosa.ErrFieldNotFound { t.Fatal(err) } }) @@ -3208,7 +3226,7 @@ func TestExecutor_Execute_Row_BSIGroupEdge(t *testing.T) { defer c.Close() hldr := c.GetHolder(0) - idx, err := hldr.CreateIndex("i", pilosa.IndexOptions{}) + idx, err := hldr.CreateIndex(c.Idx(), pilosa.IndexOptions{}) if err != nil { t.Fatal(err) } @@ -3221,13 +3239,13 @@ func TestExecutor_Execute_Row_BSIGroupEdge(t *testing.T) { // Set a value at the edge of bitDepth (i.e. 2^n-1; here, n=3). // It must also be the max value in the field; in other words, // set the value to bsiGroup.bitDepthMax(). - if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: ` + if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: ` Set(100, f1=7) `}); err != nil { t.Fatal(err) } - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Row(f1 < 10)`}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Row(f1 < 10)`}); err != nil { t.Fatal(err) } else if got, exp := result.Results[0].(*pilosa.Row).Columns(), []uint64{100}; !reflect.DeepEqual(got, exp) { t.Fatalf("unexpected result: got=%v, exp=%v", got, exp) @@ -3242,13 +3260,13 @@ func TestExecutor_Execute_Row_BSIGroupEdge(t *testing.T) { // Set a value at the negative edge of bitDepth (i.e. -(2^n-1); here, n=3). // It must also be the min value in the field; in other words, // set the value to bsiGroup.bitDepthMin(). - if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: ` + if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: ` Set(200, f2=-7) `}); err != nil { t.Fatal(err) } - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Row(f2 > -10)`}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Row(f2 > -10)`}); err != nil { t.Fatal(err) } else if got, exp := result.Results[0].(*pilosa.Row).Columns(), []uint64{200}; !reflect.DeepEqual(got, exp) { t.Fatalf("unexpected result: got=%v, exp=%v", got, exp) @@ -3261,7 +3279,7 @@ func TestExecutor_Execute_Row_BSIGroupEdge(t *testing.T) { } // Set a value anywhere in range. - if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: ` + if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: ` Set(300, f3=10) `}); err != nil { t.Fatal(err) @@ -3280,7 +3298,7 @@ func TestExecutor_Execute_Row_BSIGroupEdge(t *testing.T) { for i, test := range tests { pql := fmt.Sprintf("Row(%d < f3 < %d)", test.predA, test.predB) - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: pql}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: pql}); err != nil { t.Fatal(err) } else if got, exp := result.Results[0].(*pilosa.Row).Columns(), []uint64{}; !reflect.DeepEqual(got, exp) { t.Fatalf("test %d unexpected result: got=%v, exp=%v", i, got, exp) @@ -3295,7 +3313,7 @@ func TestExecutor_Execute_Range_BSIGroup_Deprecated(t *testing.T) { defer c.Close() hldr := c.GetHolder(0) - idx, err := hldr.CreateIndex("i", pilosa.IndexOptions{}) + idx, err := hldr.CreateIndex(c.Idx(), pilosa.IndexOptions{}) if err != nil { t.Fatal(err) } @@ -3320,7 +3338,7 @@ func TestExecutor_Execute_Range_BSIGroup_Deprecated(t *testing.T) { t.Fatal(err) } - if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: ` + if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: ` Set(0, f=0) Set(` + strconv.Itoa(ShardWidth+1) + `, f=0) @@ -3338,7 +3356,7 @@ func TestExecutor_Execute_Range_BSIGroup_Deprecated(t *testing.T) { } t.Run("EQ", func(t *testing.T) { - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Range(foo == 20)`}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Range(foo == 20)`}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual([]uint64{50, (5 * ShardWidth) + 100}, result.Results[0].(*pilosa.Row).Columns()) { t.Fatalf("unexpected result: %s", spew.Sdump(result)) @@ -3347,19 +3365,19 @@ func TestExecutor_Execute_Range_BSIGroup_Deprecated(t *testing.T) { t.Run("NEQ", func(t *testing.T) { // NEQ null - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Range(other != null)`}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Range(other != null)`}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual([]uint64{0}, result.Results[0].(*pilosa.Row).Columns()) { t.Fatalf("unexpected result: %s", spew.Sdump(result)) } // NEQ - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Range(foo != 20)`}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Range(foo != 20)`}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual([]uint64{ShardWidth, ShardWidth + 1, ShardWidth + 2}, result.Results[0].(*pilosa.Row).Columns()) { t.Fatalf("unexpected result: %s", spew.Sdump(result)) } // NEQ - - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Range(other != -20)`}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Range(other != -20)`}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual([]uint64{0}, result.Results[0].(*pilosa.Row).Columns()) { t.Fatalf("unexpected result: %v", result.Results[0].(*pilosa.Row).Columns()) @@ -3367,7 +3385,7 @@ func TestExecutor_Execute_Range_BSIGroup_Deprecated(t *testing.T) { }) t.Run("LT", func(t *testing.T) { - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Range(foo < 20)`}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Range(foo < 20)`}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual([]uint64{ShardWidth + 2}, result.Results[0].(*pilosa.Row).Columns()) { t.Fatalf("unexpected result: %s", spew.Sdump(result)) @@ -3375,7 +3393,7 @@ func TestExecutor_Execute_Range_BSIGroup_Deprecated(t *testing.T) { }) t.Run("LTE", func(t *testing.T) { - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Range(foo <= 20)`}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Range(foo <= 20)`}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual([]uint64{50, ShardWidth + 2, (5 * ShardWidth) + 100}, result.Results[0].(*pilosa.Row).Columns()) { t.Fatalf("unexpected result: %s", spew.Sdump(result)) @@ -3383,7 +3401,7 @@ func TestExecutor_Execute_Range_BSIGroup_Deprecated(t *testing.T) { }) t.Run("GT", func(t *testing.T) { - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Range(foo > 20)`}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Range(foo > 20)`}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual([]uint64{ShardWidth, ShardWidth + 1}, result.Results[0].(*pilosa.Row).Columns()) { t.Fatalf("unexpected result: %s", spew.Sdump(result)) @@ -3391,7 +3409,7 @@ func TestExecutor_Execute_Range_BSIGroup_Deprecated(t *testing.T) { }) t.Run("GTE", func(t *testing.T) { - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Range(foo >= 20)`}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Range(foo >= 20)`}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual([]uint64{50, ShardWidth, ShardWidth + 1, (5 * ShardWidth) + 100}, result.Results[0].(*pilosa.Row).Columns()) { t.Fatalf("unexpected result: %s", spew.Sdump(result)) @@ -3399,7 +3417,7 @@ func TestExecutor_Execute_Range_BSIGroup_Deprecated(t *testing.T) { }) t.Run("BETWEEN", func(t *testing.T) { - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Range(0 < other < 1000)`}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Range(0 < other < 1000)`}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual([]uint64{}, result.Results[0].(*pilosa.Row).Columns()) { t.Fatalf("unexpected result: %s", spew.Sdump(result)) @@ -3408,7 +3426,7 @@ func TestExecutor_Execute_Range_BSIGroup_Deprecated(t *testing.T) { // Ensure that the NotNull code path gets run. t.Run("NotNull", func(t *testing.T) { - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Range(0 <= other <= 1000)`}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Range(0 <= other <= 1000)`}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual([]uint64{0}, result.Results[0].(*pilosa.Row).Columns()) { t.Fatalf("unexpected result: %s", spew.Sdump(result)) @@ -3416,7 +3434,7 @@ func TestExecutor_Execute_Range_BSIGroup_Deprecated(t *testing.T) { }) t.Run("BelowMin", func(t *testing.T) { - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Range(foo == 0)`}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Range(foo == 0)`}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual([]uint64{}, result.Results[0].(*pilosa.Row).Columns()) { t.Fatalf("unexpected result: %s", spew.Sdump(result)) @@ -3424,7 +3442,7 @@ func TestExecutor_Execute_Range_BSIGroup_Deprecated(t *testing.T) { }) t.Run("AboveMax", func(t *testing.T) { - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Range(foo == 200)`}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Range(foo == 200)`}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual([]uint64{}, result.Results[0].(*pilosa.Row).Columns()) { t.Fatalf("unexpected result: %s", spew.Sdump(result)) @@ -3432,7 +3450,7 @@ func TestExecutor_Execute_Range_BSIGroup_Deprecated(t *testing.T) { }) t.Run("LTAboveMax", func(t *testing.T) { - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Range(edge < 200)`}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Range(edge < 200)`}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual([]uint64{0, 1}, result.Results[0].(*pilosa.Row).Columns()) { t.Fatalf("unexpected result: %s", spew.Sdump(result.Results[0].(*pilosa.Row).Columns())) @@ -3440,7 +3458,7 @@ func TestExecutor_Execute_Range_BSIGroup_Deprecated(t *testing.T) { }) t.Run("GTBelowMin", func(t *testing.T) { - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Range(edge > -1200)`}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Range(edge > -1200)`}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual([]uint64{0, 1}, result.Results[0].(*pilosa.Row).Columns()) { t.Fatalf("unexpected result: %s", spew.Sdump(result.Results[0].(*pilosa.Row).Columns())) @@ -3448,7 +3466,7 @@ func TestExecutor_Execute_Range_BSIGroup_Deprecated(t *testing.T) { }) t.Run("ErrFieldNotFound", func(t *testing.T) { - if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Range(bad_field >= 20)`}); errors.Cause(err) != pilosa.ErrFieldNotFound { + if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Range(bad_field >= 20)`}); errors.Cause(err) != pilosa.ErrFieldNotFound { t.Fatal(err) } }) @@ -3456,37 +3474,41 @@ func TestExecutor_Execute_Range_BSIGroup_Deprecated(t *testing.T) { // Ensure a remote query can return a row. func TestExecutor_Execute_Remote_Row(t *testing.T) { - c := test.MustRunCluster(t, 3, - []server.CommandOption{ - server.OptCommandServerOptions(pilosa.OptServerNodeID("node0"), pilosa.OptServerClusterHasher(&test.ModHasher{}))}, - []server.CommandOption{ - server.OptCommandServerOptions(pilosa.OptServerNodeID("node1"), pilosa.OptServerClusterHasher(&test.ModHasher{}))}, - []server.CommandOption{ - server.OptCommandServerOptions(pilosa.OptServerNodeID("node2"), pilosa.OptServerClusterHasher(&test.ModHasher{}))}, - ) + c := test.MustRunCluster(t, 3) defer c.Close() - hldr0 := c.GetHolder(0) hldr1 := c.GetHolder(1) - hldr2 := c.GetHolder(2) + child := c.Idx("c") + parent := c.Idx("p") - _, err := c.GetPrimary().API.CreateIndex(context.Background(), "i", pilosa.IndexOptions{}) + _, err := c.GetPrimary().API.CreateIndex(context.Background(), c.Idx(), pilosa.IndexOptions{}) if err != nil { t.Fatalf("creating index: %v", err) } - _, err = c.GetPrimary().API.CreateField(context.Background(), "i", "f", pilosa.OptFieldTypeSet(pilosa.DefaultCacheType, pilosa.DefaultCacheSize)) + _, err = c.GetPrimary().API.CreateField(context.Background(), c.Idx(), "f", pilosa.OptFieldTypeSet(pilosa.DefaultCacheType, pilosa.DefaultCacheSize)) if err != nil { t.Fatalf("creating field: %v", err) } - hldr0.MustSetBits("i", "f", 10, ShardWidth+1, ShardWidth+2, (3*ShardWidth)+4) - hldr2.SetBit("i", "f", 10, 1) - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Row(f=10)`}); err != nil { + client := MustNewClient(c.GetNode(0).URL(), pilosa.GetHTTPClient(nil)) + req := &pilosa.ImportRequest{ + Index: c.Idx(), + Field: "f", + RowIDs: []uint64{10, 10, 10, 10}, + ColumnIDs: []uint64{1, ShardWidth + 1, ShardWidth + 2, (3 * ShardWidth) + 4}, + Shard: ^uint64(0), + } + err = client.Import(context.Background(), nil, req, &pilosa.ImportOptions{}) + if err != nil { + t.Fatalf("importing data: %v", err) + } + + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Row(f=10)`}); err != nil { t.Fatal(err) } else if columns := res.Results[0].(*pilosa.Row).Columns(); !reflect.DeepEqual(columns, []uint64{1, ShardWidth + 1, ShardWidth + 2, (3 * ShardWidth) + 4}) { t.Fatalf("unexpected columns: %+v", columns) } t.Run("Count", func(t *testing.T) { - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Count(Row(f=10))`}); err != nil { + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Count(Row(f=10))`}); err != nil { t.Fatal(err) } else if res.Results[0] != uint64(4) { t.Fatalf("unexpected n: %d", res.Results[0]) @@ -3494,36 +3516,38 @@ func TestExecutor_Execute_Remote_Row(t *testing.T) { }) t.Run("Remote SetBit", func(t *testing.T) { - if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: fmt.Sprintf(`Set(%d, f=7)`, pilosa.ShardWidth+1)}); err != nil { + if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: fmt.Sprintf(`Set(%d, f=7)`, pilosa.ShardWidth+1)}); err != nil { t.Fatalf("querying remote: %v", err) } - if !reflect.DeepEqual(hldr0.Row("i", "f", 7).Columns(), []uint64{pilosa.ShardWidth + 1}) { - t.Fatalf("unexpected cols from row 7: %v", hldr1.Row("i", "f", 7).Columns()) + // We shouldn't need to specify hldr1, and which holder we need varies in a way that is clearly broken. + if !reflect.DeepEqual(hldr1.Row(c.Idx(), "f", 7).Columns(), []uint64{pilosa.ShardWidth + 1}) { + t.Fatalf("unexpected cols from row 7: %v", hldr1.Row(c.Idx(), "f", 7).Columns()) } }) t.Run("remote with timestamp", func(t *testing.T) { - _, err = c.GetPrimary().API.CreateField(context.Background(), "i", "z", pilosa.OptFieldTypeTime("Y", "0")) + _, err = c.GetPrimary().API.CreateField(context.Background(), c.Idx(), "z", pilosa.OptFieldTypeTime("Y", "0")) if err != nil { t.Fatalf("creating field: %v", err) } - if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: fmt.Sprintf(`Set(%d, z=5, 2010-07-08T00:00)`, pilosa.ShardWidth+1)}); err != nil { - t.Fatalf("quuerying remote: %v", err) + if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: fmt.Sprintf(`Set(%d, z=5, 2010-07-08T00:00)`, pilosa.ShardWidth+1)}); err != nil { + t.Fatalf("querying remote: %v", err) } - if !reflect.DeepEqual(hldr0.RowTime("i", "z", 5, time.Date(2010, time.January, 1, 0, 0, 0, 0, time.UTC), "Y").Columns(), []uint64{pilosa.ShardWidth + 1}) { - t.Fatalf("unexpected cols from row 7: %v", hldr1.RowTime("i", "z", 5, time.Date(2010, time.January, 1, 0, 0, 0, 0, time.UTC), "Y").Columns()) + // We shouldn't need to specify hldr1, and which holder we need varies in a way that is clearly broken. + if !reflect.DeepEqual(hldr1.RowTime(c.Idx(), "z", 5, time.Date(2010, time.January, 1, 0, 0, 0, 0, time.UTC), "Y").Columns(), []uint64{pilosa.ShardWidth + 1}) { + t.Fatalf("unexpected cols from row 7: %v", hldr1.RowTime(c.Idx(), "z", 5, time.Date(2010, time.January, 1, 0, 0, 0, 0, time.UTC), "Y").Columns()) } }) t.Run("remote topn", func(t *testing.T) { - _, err = c.GetPrimary().API.CreateField(context.Background(), "i", "fn", pilosa.OptFieldTypeSet(pilosa.CacheTypeRanked, 100)) + _, err = c.GetPrimary().API.CreateField(context.Background(), c.Idx(), "fn", pilosa.OptFieldTypeSet(pilosa.CacheTypeRanked, 100)) if err != nil { t.Fatalf("creating field: %v", err) } - if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: ` + if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: ` Set(500001, fn=5) Set(1500001, fn=5) Set(2500001, fn=5) @@ -3538,7 +3562,7 @@ func TestExecutor_Execute_Remote_Row(t *testing.T) { } if res, err := c.GetNode(1).API.Query(context.Background(), &pilosa.QueryRequest{ - Index: "i", + Index: c.Idx(), Query: `TopN(fn, n=3)`, }); err != nil { t.Fatalf("topn querying: %v", err) @@ -3556,7 +3580,7 @@ func TestExecutor_Execute_Remote_Row(t *testing.T) { t.Run("remote groupBy", func(t *testing.T) { if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{ - Index: "i", + Index: c.Idx(), Query: `GroupBy(Rows(f))`, }); err != nil { t.Fatalf("GroupBy querying: %v", err) @@ -3572,14 +3596,14 @@ func TestExecutor_Execute_Remote_Row(t *testing.T) { t.Run("json format groupBy on timestamps", func(t *testing.T) { //SUP-138 - c.CreateField(t, "t", pilosa.IndexOptions{TrackExistence: true}, "timestamp", pilosa.OptFieldTypeTimestamp(pilosa.DefaultEpoch, pilosa.TimeUnitSeconds)) - c.Query(t, "t", ` + c.CreateField(t, c.Idx("t"), pilosa.IndexOptions{TrackExistence: true}, "timestamp", pilosa.OptFieldTypeTimestamp(pilosa.DefaultEpoch, pilosa.TimeUnitSeconds)) + c.Query(t, c.Idx("t"), ` Set(8, timestamp='2021-01-27T08:00:00Z') Set(9, timestamp='2000-01-27T09:00:00Z') Set(10, timestamp='2000-01-27T10:00:00Z') `) if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{ - Index: "t", + Index: c.Idx("t"), Query: `GroupBy(Rows(timestamp))`, }); err != nil { t.Fatalf("GroupBy querying: %v", err) @@ -3593,11 +3617,11 @@ func TestExecutor_Execute_Remote_Row(t *testing.T) { }) t.Run("remote groupBy on ints", func(t *testing.T) { - _, err = c.GetPrimary().API.CreateField(context.Background(), "i", "fint", pilosa.OptFieldTypeInt(-1000, 1000)) + _, err = c.GetPrimary().API.CreateField(context.Background(), c.Idx(), "fint", pilosa.OptFieldTypeInt(-1000, 1000)) if err != nil { t.Fatalf("creating field: %v", err) } - if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: ` + if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: ` Set(0, fint=1) Set(1, fint=2) @@ -3616,7 +3640,7 @@ func TestExecutor_Execute_Remote_Row(t *testing.T) { } if res, err := c.GetNode(1).API.Query(context.Background(), &pilosa.QueryRequest{ - Index: "i", + Index: c.Idx(), Query: `GroupBy(Rows(fint), limit=4, filter=Union(Row(fint < 1), Row(fint > 2)))`, }); err != nil { t.Fatalf("GroupBy querying: %v", err) @@ -3635,11 +3659,11 @@ func TestExecutor_Execute_Remote_Row(t *testing.T) { }) t.Run("groupBy on ints with offset regression", func(t *testing.T) { - _, err = c.GetPrimary().API.CreateField(context.Background(), "i", "hint", pilosa.OptFieldTypeInt(1, 1000)) + _, err = c.GetPrimary().API.CreateField(context.Background(), c.Idx(), "hint", pilosa.OptFieldTypeInt(1, 1000)) if err != nil { t.Fatalf("creating field: %v", err) } - if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: ` + if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: ` Set(0, hint=1) Set(1, hint=2) Set(2, hint=3) @@ -3648,7 +3672,7 @@ func TestExecutor_Execute_Remote_Row(t *testing.T) { } if res, err := c.GetNode(1).API.Query(context.Background(), &pilosa.QueryRequest{ - Index: "i", + Index: c.Idx(), Query: `GroupBy(Rows(hint))`, }); err != nil { t.Fatalf("GroupBy querying: %v", err) @@ -3666,16 +3690,16 @@ func TestExecutor_Execute_Remote_Row(t *testing.T) { }) t.Run("Row on ints with ASSIGN condition", func(t *testing.T) { - _, err := c.GetPrimary().API.CreateIndex(context.Background(), "intidx", pilosa.IndexOptions{}) + _, err := c.GetPrimary().API.CreateIndex(context.Background(), c.Idx("intidx"), pilosa.IndexOptions{}) if err != nil { t.Fatalf("creating index: %v", err) } - _, err = c.GetPrimary().API.CreateField(context.Background(), "intidx", "gint", pilosa.OptFieldTypeInt(-1000, 1000)) + _, err = c.GetPrimary().API.CreateField(context.Background(), c.Idx("intidx"), "gint", pilosa.OptFieldTypeInt(-1000, 1000)) if err != nil { t.Fatalf("creating field: %v", err) } - if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "intidx", Query: ` + if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx("intidx"), Query: ` Set(1000, gint=1) Set(2000, gint=2) Set(3000, gint=3) @@ -3684,7 +3708,7 @@ func TestExecutor_Execute_Remote_Row(t *testing.T) { } if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{ - Index: "intidx", + Index: c.Idx("intidx"), Query: `Row(gint=2)Row(gint==1)`, }); err != nil { t.Fatalf("Row querying: %v", err) @@ -3701,16 +3725,16 @@ func TestExecutor_Execute_Remote_Row(t *testing.T) { }) t.Run("Row on decimals with ASSIGN condition", func(t *testing.T) { - _, err := c.GetPrimary().API.CreateIndex(context.Background(), "decidx", pilosa.IndexOptions{}) + _, err := c.GetPrimary().API.CreateIndex(context.Background(), c.Idx("decidx"), pilosa.IndexOptions{}) if err != nil { t.Fatalf("creating index: %v", err) } - _, err = c.GetPrimary().API.CreateField(context.Background(), "decidx", "fdec", pilosa.OptFieldTypeDecimal(0)) + _, err = c.GetPrimary().API.CreateField(context.Background(), c.Idx("decidx"), "fdec", pilosa.OptFieldTypeDecimal(0)) if err != nil { t.Fatalf("creating field: %v", err) } - if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "decidx", Query: ` + if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx("decidx"), Query: ` Set(11, fdec=1.1) Set(22, fdec=2.2) Set(33, fdec=3.3) @@ -3719,7 +3743,7 @@ func TestExecutor_Execute_Remote_Row(t *testing.T) { } if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{ - Index: "decidx", + Index: c.Idx("decidx"), Query: `Row(fdec=2.2)Row(fdec==1.1)`, }); err != nil { t.Fatalf("Row querying: %v", err) @@ -3735,27 +3759,27 @@ func TestExecutor_Execute_Remote_Row(t *testing.T) { }) t.Run("Row on foreign key with ASSIGN condition", func(t *testing.T) { - _, err := c.GetPrimary().API.CreateIndex(context.Background(), "parent", pilosa.IndexOptions{Keys: true}) + _, err := c.GetPrimary().API.CreateIndex(context.Background(), parent, pilosa.IndexOptions{Keys: true}) if err != nil { t.Fatalf("creating index: %v", err) } - _, err = c.GetPrimary().API.CreateField(context.Background(), "parent", "general", pilosa.OptFieldTypeSet(pilosa.DefaultCacheType, pilosa.DefaultCacheSize)) + _, err = c.GetPrimary().API.CreateField(context.Background(), parent, "general", pilosa.OptFieldTypeSet(pilosa.DefaultCacheType, pilosa.DefaultCacheSize)) if err != nil { t.Fatalf("creating field: %v", err) } - _, err = c.GetPrimary().API.CreateIndex(context.Background(), "child", pilosa.IndexOptions{Keys: false}) + _, err = c.GetPrimary().API.CreateIndex(context.Background(), child, pilosa.IndexOptions{Keys: false}) if err != nil { t.Fatalf("creating index: %v", err) } - _, err = c.GetPrimary().API.CreateField(context.Background(), "child", "parentid", - pilosa.OptFieldForeignIndex("parent"), + _, err = c.GetPrimary().API.CreateField(context.Background(), child, "parentid", + pilosa.OptFieldForeignIndex(parent), pilosa.OptFieldTypeInt(-9223372036854775808, 9223372036854775807), ) if err != nil { t.Fatalf("creating field: %v", err) } - if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "child", Query: ` + if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: child, Query: ` Set(1, parentid="one") Set(2, parentid="two") Set(3, parentid="three") @@ -3764,7 +3788,7 @@ func TestExecutor_Execute_Remote_Row(t *testing.T) { } if res, err := c.GetNode(1).API.Query(context.Background(), &pilosa.QueryRequest{ - Index: "child", + Index: child, Query: `Row(parentid="two")Row(parentid=="one")`, }); err != nil { t.Fatalf("Row querying: %v", err) @@ -3783,7 +3807,7 @@ func TestExecutor_Execute_Remote_Row(t *testing.T) { // Ensure executor returns an error if too many writes are in a single request. func TestExecutor_Execute_ErrMaxWritesPerRequest(t *testing.T) { - c := test.MustNewCluster(t, 1) + c := test.MustUnsharedCluster(t, 1) defer c.Close() c.GetIdleNode(0).Config.MaxWritesPerRequest = 3 err := c.Start() @@ -3791,8 +3815,8 @@ func TestExecutor_Execute_ErrMaxWritesPerRequest(t *testing.T) { t.Fatal(err) } hldr := c.GetHolder(0) - hldr.MustCreateIndexIfNotExists("i", pilosa.IndexOptions{}) - if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Set() Clear() Set() Set()`}); errors.Cause(err) != pilosa.ErrTooManyWrites { + hldr.MustCreateIndexIfNotExists(c.Idx(), pilosa.IndexOptions{}) + if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Set() Clear() Set() Set()`}); errors.Cause(err) != pilosa.ErrTooManyWrites { t.Fatalf("unexpected error: %s", err) } } @@ -3834,7 +3858,7 @@ func TestExecutor_Time_Clear_Quantums(t *testing.T) { for i, tt := range rangeTests { t.Run(fmt.Sprintf("#%d Quantum %s", i+1, tt.quantum), func(t *testing.T) { // Create index. - indexName := strings.ToLower(string(tt.quantum)) + indexName := c.Idx(strings.ToLower(string(tt.quantum))) index := hldr.MustCreateIndexIfNotExists(indexName, pilosa.IndexOptions{}) // Create field. if _, err := index.CreateFieldIfNotExists("f", pilosa.OptFieldTypeTime(tt.quantum, "0")); err != nil { @@ -3867,6 +3891,8 @@ func TestReopenCluster(t *testing.T) { conf.Cluster.ReplicaN = 2 commandOpts[i] = append(commandOpts[i], server.OptCommandConfig(conf)) } + // Note: This cluster won't be shared because of the provided options. Which is good because + // we're reopening something, which breaks clusters. c := test.MustRunCluster(t, 3, commandOpts...) defer c.Close() c.CreateField(t, "users", pilosa.IndexOptions{Keys: true, TrackExistence: true}, "likenums") @@ -3913,15 +3939,11 @@ func TestReopenCluster(t *testing.T) { // Ensure an existence field is maintained. func TestExecutor_Execute_Existence(t *testing.T) { t.Run("Row", func(t *testing.T) { - c := test.MustRunCluster(t, 1, []server.CommandOption{ - server.OptCommandServerOptions( - pilosa.OptServerOpenTranslateStore(boltdb.OpenTranslateStore), - pilosa.OptServerOpenTranslateReader(pilosa.GetOpenTranslateReaderFunc(nil)), - ), - }) + // Unshared because we're going to reopen it + c := test.MustRunUnsharedCluster(t, 1) defer c.Close() hldr := c.GetHolder(0) - index := hldr.MustCreateIndexIfNotExists("i", pilosa.IndexOptions{TrackExistence: true}) + index := hldr.MustCreateIndexIfNotExists(c.Idx(), pilosa.IndexOptions{TrackExistence: true}) _, err := index.CreateField("f", pilosa.OptFieldTypeDefault()) if err != nil { @@ -3930,7 +3952,7 @@ func TestExecutor_Execute_Existence(t *testing.T) { node0 := c.GetNode(0) // Set bits. - if _, err := node0.API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `` + + if _, err := node0.API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `` + fmt.Sprintf("Set(%d, f=%d)\n", 3, 10) + fmt.Sprintf("Set(%d, f=%d)\n", ShardWidth+1, 10) + fmt.Sprintf("Set(%d, f=%d)\n", ShardWidth+2, 20), @@ -3938,13 +3960,13 @@ func TestExecutor_Execute_Existence(t *testing.T) { t.Fatal(err) } - if res, err := node0.API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Row(f=10)`}); err != nil { + if res, err := node0.API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Row(f=10)`}); err != nil { t.Fatal(err) } else if bits := res.Results[0].(*pilosa.Row).Columns(); !reflect.DeepEqual(bits, []uint64{3, ShardWidth + 1}) { t.Fatalf("unexpected columns: %+v", bits) } - if res, err := node0.API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Not(Row(f=10))`}); err != nil { + if res, err := node0.API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Not(Row(f=10))`}); err != nil { t.Fatal(err) } else if bits := res.Results[0].(*pilosa.Row).Columns(); !reflect.DeepEqual(bits, []uint64{ShardWidth + 2}) { t.Fatalf("unexpected columns after Not: %+v", bits) @@ -3960,10 +3982,10 @@ func TestExecutor_Execute_Existence(t *testing.T) { } hldr2 := c.GetHolder(0) - index2 := hldr2.Index("i") + index2 := hldr2.Index(c.Idx()) _ = index2 - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Not(Row(f=10))`}); err != nil { + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Not(Row(f=10))`}); err != nil { t.Fatal(err) } else if bits := res.Results[0].(*pilosa.Row).Columns(); !reflect.DeepEqual(bits, []uint64{ShardWidth + 2}) { t.Fatalf("unexpected columns after reopen: %+v", bits) @@ -3985,10 +4007,10 @@ func TestExecutor_Execute_FieldValue(t *testing.T) { node1 := c.GetNode(1) // Index with IDs - c.CreateField(t, "i", pilosa.IndexOptions{Keys: false}, "f", pilosa.OptFieldTypeInt(-1100, 1000)) - c.CreateField(t, "i", pilosa.IndexOptions{Keys: false}, "dec", pilosa.OptFieldTypeDecimal(3)) + c.CreateField(t, c.Idx(), pilosa.IndexOptions{Keys: false}, "f", pilosa.OptFieldTypeInt(-1100, 1000)) + c.CreateField(t, c.Idx(), pilosa.IndexOptions{Keys: false}, "dec", pilosa.OptFieldTypeDecimal(3)) - if _, err := node0.API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: ` + if _, err := node0.API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: ` Set(1, f=3) Set(2, f=-4) Set(` + strconv.Itoa(ShardWidth+1) + `, f=3) @@ -3999,10 +4021,10 @@ func TestExecutor_Execute_FieldValue(t *testing.T) { } // Index with Keys - c.CreateField(t, "ik", pilosa.IndexOptions{Keys: true}, "f", pilosa.OptFieldTypeInt(-1100, 1000)) - c.CreateField(t, "ik", pilosa.IndexOptions{Keys: true}, "dec", pilosa.OptFieldTypeDecimal(3)) + c.CreateField(t, c.Idx("ik"), pilosa.IndexOptions{Keys: true}, "f", pilosa.OptFieldTypeInt(-1100, 1000)) + c.CreateField(t, c.Idx("ik"), pilosa.IndexOptions{Keys: true}, "dec", pilosa.OptFieldTypeDecimal(3)) - if _, err := node0.API.Query(context.Background(), &pilosa.QueryRequest{Index: "ik", Query: ` + if _, err := node0.API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx("ik"), Query: ` Set("one", f=3) Set("two", f=-4) Set("one", dec=12.985) @@ -4018,24 +4040,24 @@ func TestExecutor_Execute_FieldValue(t *testing.T) { expErr string }{ // IDs - {index: "i", qry: "FieldValue(field=f, column=1)", expVal: int64(3)}, - {index: "i", qry: "FieldValue(field=f, column=2)", expVal: int64(-4)}, - {index: "i", qry: "FieldValue(field=f, column=" + strconv.Itoa(ShardWidth+1) + ")", expVal: int64(3)}, + {index: c.Idx(), qry: "FieldValue(field=f, column=1)", expVal: int64(3)}, + {index: c.Idx(), qry: "FieldValue(field=f, column=2)", expVal: int64(-4)}, + {index: c.Idx(), qry: "FieldValue(field=f, column=" + strconv.Itoa(ShardWidth+1) + ")", expVal: int64(3)}, - {index: "i", qry: "FieldValue(field=dec, column=1)", expVal: pql.NewDecimal(12985, 3)}, - {index: "i", qry: "FieldValue(field=dec, column=2)", expVal: pql.NewDecimal(-4234, 3)}, + {index: c.Idx(), qry: "FieldValue(field=dec, column=1)", expVal: pql.NewDecimal(12985, 3)}, + {index: c.Idx(), qry: "FieldValue(field=dec, column=2)", expVal: pql.NewDecimal(-4234, 3)}, // Keys - {index: "ik", qry: "FieldValue(field=f, column='one')", expVal: int64(3)}, - {index: "ik", qry: "FieldValue(field=f, column='two')", expVal: int64(-4)}, + {index: c.Idx("ik"), qry: "FieldValue(field=f, column='one')", expVal: int64(3)}, + {index: c.Idx("ik"), qry: "FieldValue(field=f, column='two')", expVal: int64(-4)}, - {index: "ik", qry: "FieldValue(field=dec, column='one')", expVal: pql.NewDecimal(12985, 3)}, - {index: "ik", qry: "FieldValue(field=dec, column='two')", expVal: pql.NewDecimal(-4234, 3)}, + {index: c.Idx("ik"), qry: "FieldValue(field=dec, column='one')", expVal: pql.NewDecimal(12985, 3)}, + {index: c.Idx("ik"), qry: "FieldValue(field=dec, column='two')", expVal: pql.NewDecimal(-4234, 3)}, // Errors - {index: "i", qry: "FieldValue()", expErr: pilosa.ErrFieldRequired.Error()}, - {index: "i", qry: "FieldValue(field=dec)", expErr: pilosa.ErrColumnRequired.Error()}, - {index: "ik", qry: "FieldValue(field=f)", expErr: pilosa.ErrColumnRequired.Error()}, + {index: c.Idx(), qry: "FieldValue()", expErr: pilosa.ErrFieldRequired.Error()}, + {index: c.Idx(), qry: "FieldValue(field=dec)", expErr: pilosa.ErrColumnRequired.Error()}, + {index: c.Idx("ik"), qry: "FieldValue(field=f)", expErr: pilosa.ErrColumnRequired.Error()}, } for n, node := range []*test.Command{node0, node1} { for i, test := range tests { @@ -4074,8 +4096,8 @@ func TestExecutor_Execute_Limit(t *testing.T) { c := test.MustRunCluster(t, 3) defer c.Close() - c.CreateField(t, "i", pilosa.IndexOptions{TrackExistence: true}, "f") - c.ImportBits(t, "i", "f", [][2]uint64{ + c.CreateField(t, c.Idx(), pilosa.IndexOptions{TrackExistence: true}, "f") + c.ImportBits(t, c.Idx(), "f", [][2]uint64{ {1, 0}, {1, 1}, {1, ShardWidth + 1}, @@ -4090,7 +4112,7 @@ func TestExecutor_Execute_Limit(t *testing.T) { expect = expect[:limit] } - resp := c.Query(t, "i", fmt.Sprintf("Limit(All(), limit=%d)", limit)) + resp := c.Query(t, c.Idx(), fmt.Sprintf("Limit(All(), limit=%d)", limit)) if len(resp.Results) != 1 { t.Fatalf("limit=%d: expected 1 result but got %v", limit, resp.Results) } @@ -4113,7 +4135,7 @@ func TestExecutor_Execute_Limit(t *testing.T) { expect = columns[offset:] } - resp := c.Query(t, "i", fmt.Sprintf("Limit(All(), offset=%d)", offset)) + resp := c.Query(t, c.Idx(), fmt.Sprintf("Limit(All(), offset=%d)", offset)) if len(resp.Results) != 1 { t.Fatalf("offset=%d: expected 1 result but got %v", offset, resp.Results) } @@ -4140,7 +4162,7 @@ func TestExecutor_Execute_Limit(t *testing.T) { expect = expect[:limit] } - resp := c.Query(t, "i", fmt.Sprintf("Limit(All(), limit=%d, offset=%d)", limit, offset)) + resp := c.Query(t, c.Idx(), fmt.Sprintf("Limit(All(), limit=%d, offset=%d)", limit, offset)) if len(resp.Results) != 1 { t.Fatalf("limit=%d,offset=%d: expected 1 result but got %v", limit, offset, resp.Results) } @@ -4167,7 +4189,7 @@ func TestExecutor_Execute_Limit(t *testing.T) { expect = expect[:limit] } - resp := c.Query(t, "i", fmt.Sprintf("Limit(Limit(All(), offset=%d), limit=%d)", offset, limit)) + resp := c.Query(t, c.Idx(), fmt.Sprintf("Limit(Limit(All(), offset=%d), limit=%d)", offset, limit)) if len(resp.Results) != 1 { t.Fatalf("limit=%d,offset=%d: expected 1 result but got %v", limit, offset, resp.Results) } @@ -4184,7 +4206,7 @@ func TestExecutor_Execute_Limit(t *testing.T) { }) t.Run("Extract", func(t *testing.T) { - resp := c.Query(t, "i", "Extract(Limit(All(), limit=1))") + resp := c.Query(t, c.Idx(), "Extract(Limit(All(), limit=1))") if len(resp.Results) != 1 { t.Fatalf("expected 1 result but got %d", len(resp.Results)) } @@ -4215,18 +4237,18 @@ func TestExecutor_Sort(t *testing.T) { c := test.MustRunCluster(t, 1) defer c.Close() - c.CreateField(t, "i", pilosa.IndexOptions{TrackExistence: true}, "bsint", pilosa.OptFieldTypeInt(math.MinInt64, math.MaxInt64)) - c.Query(t, "i", ` + c.CreateField(t, c.Idx(), pilosa.IndexOptions{TrackExistence: true}, "bsint", pilosa.OptFieldTypeInt(math.MinInt64, math.MaxInt64)) + c.Query(t, c.Idx(), ` Set(0, bsint = 1) Set(1, bsint = -1) Set(2, bsint = 2) Set(3, bsint = -2) - Set(4, bsint = 2) - Set(5, bsint = 3) + Set(4, bsint = 3) + Set(5, bsint = 4) `) - c.CreateField(t, "i", pilosa.IndexOptions{TrackExistence: true}, "bool", pilosa.OptFieldTypeBool()) - c.Query(t, "i", ` + c.CreateField(t, c.Idx(), pilosa.IndexOptions{TrackExistence: true}, "bool", pilosa.OptFieldTypeBool()) + c.Query(t, c.Idx(), ` Set(0, bool=true) Set(1, bool=false) Set(2, bool=false) @@ -4235,8 +4257,8 @@ func TestExecutor_Sort(t *testing.T) { Set(5, bool=true) `) - c.CreateField(t, "i", pilosa.IndexOptions{TrackExistence: true}, "keymutex", pilosa.OptFieldKeys(), pilosa.OptFieldTypeMutex(pilosa.CacheTypeRanked, 5000)) - c.Query(t, "i", ` + c.CreateField(t, c.Idx(), pilosa.IndexOptions{TrackExistence: true}, "keymutex", pilosa.OptFieldKeys(), pilosa.OptFieldTypeMutex(pilosa.CacheTypeRanked, 5000)) + c.Query(t, c.Idx(), ` Set(0, keymutex="h") Set(1, keymutex="xyzzy") Set(2, keymutex="ra") @@ -4246,13 +4268,13 @@ func TestExecutor_Sort(t *testing.T) { `) queries := []string{ - "Extract(Sort(Row(bsint > 1), field = bsint, limit = 2, offset = 1), Rows(bsint))", + "Extract(Sort(Row(bsint > 1), field = bsint, limit = 2, offset = 1), Rows(bsint))", "Extract(Sort(Row(bsint < -1), field = bool, limit = 1, sort-desc = true), Rows(bool))", "Extract(Sort(All(), field = keymutex, limit = 1), Rows(keymutex))", } - expect := []interface{}{ - pilosa.ExtractedTable{ + expect := []pilosa.ExtractedTable{ + { Fields: []pilosa.ExtractedTableField{ { Name: "bsint", @@ -4263,18 +4285,18 @@ func TestExecutor_Sort(t *testing.T) { { Column: pilosa.KeyOrID{ID: 4}, Rows: []interface{}{ - int64(2), + int64(3), }, }, { Column: pilosa.KeyOrID{ID: 5}, Rows: []interface{}{ - int64(3), + int64(4), }, }, }, }, - pilosa.ExtractedTable{ + { Fields: []pilosa.ExtractedTableField{ { Name: "bool", @@ -4290,7 +4312,7 @@ func TestExecutor_Sort(t *testing.T) { }, }, }, - pilosa.ExtractedTable{ + { Fields: []pilosa.ExtractedTableField{ { Name: "keymutex", @@ -4309,7 +4331,7 @@ func TestExecutor_Sort(t *testing.T) { } for i, q := range queries { - resp := c.Query(t, "i", q) + resp := c.Query(t, c.Idx(), q) if !reflect.DeepEqual(expect[i], resp.Results[0]) { t.Errorf("expected %v but got %v", expect[i], resp.Results[0]) } @@ -4324,7 +4346,7 @@ func TestExecutor_Execute_All(t *testing.T) { c := test.MustRunCluster(t, 1) defer c.Close() hldr := c.GetHolder(0) - index := hldr.MustCreateIndexIfNotExists("i", pilosa.IndexOptions{TrackExistence: true}) + index := hldr.MustCreateIndexIfNotExists(c.Idx(), pilosa.IndexOptions{TrackExistence: true}) fld, err := index.CreateField("f", pilosa.OptFieldTypeDefault()) if err != nil { t.Fatal(err) @@ -4370,7 +4392,7 @@ func TestExecutor_Execute_All(t *testing.T) { } PanicOn(qcx.Finish()) - i0, err := m0.API.Index(context.Background(), "i") + i0, err := m0.API.Index(context.Background(), c.Idx()) PanicOn(err) if i0 == nil { PanicOn("nil index i0?") @@ -4397,7 +4419,7 @@ func TestExecutor_Execute_All(t *testing.T) { {qry: fmt.Sprintf("All(limit=%d, offset=2)", bitCount-3), expCols: req.ColumnIDs[2 : bitCount-1], expCnt: uint64(bitCount - 3)}, } for i, test := range tests { - if res, err := m0.API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: test.qry}); err != nil { + if res, err := m0.API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: test.qry}); err != nil { t.Fatal(err) } else if cnt := res.Results[0].(*pilosa.Row).Count(); cnt != test.expCnt { t.Fatalf("test %d, unexpected count, got: %d, but expected: %d", i, cnt, test.expCnt) @@ -4413,15 +4435,10 @@ func TestExecutor_Execute_All(t *testing.T) { }) t.Run("ColumnKey", func(t *testing.T) { - c := test.MustRunCluster(t, 1, []server.CommandOption{ - server.OptCommandServerOptions( - pilosa.OptServerOpenTranslateStore(boltdb.OpenTranslateStore), - pilosa.OptServerOpenTranslateReader(pilosa.GetOpenTranslateReaderFunc(nil)), - ), - }) + c := test.MustRunCluster(t, 1) defer c.Close() hldr := c.GetHolder(0) - index := hldr.MustCreateIndexIfNotExists("i", pilosa.IndexOptions{TrackExistence: true, Keys: true}) + index := hldr.MustCreateIndexIfNotExists(c.Idx(), pilosa.IndexOptions{TrackExistence: true, Keys: true}) fld, err := index.CreateField("f", pilosa.OptFieldTypeDefault()) if err != nil { t.Fatal(err) @@ -4466,7 +4483,7 @@ func TestExecutor_Execute_All(t *testing.T) { {qry: "All(limit=4, offset=5)", expCols: nil, expCnt: 0}, } for i, test := range tests { - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: test.qry}); err != nil { + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: test.qry}); err != nil { t.Fatal(err) } else if cnt := len(res.Results[0].(*pilosa.Row).Keys); uint64(cnt) != test.expCnt { t.Fatalf("test %d, unexpected count, got: %d, but expected: %d", i, cnt, test.expCnt) @@ -4486,12 +4503,12 @@ func TestExecutor_Execute_All(t *testing.T) { c := test.MustRunCluster(t, 1) defer c.Close() hldr := c.GetHolder(0) - index := hldr.MustCreateIndexIfNotExists("i", pilosa.IndexOptions{TrackExistence: true}) + index := hldr.MustCreateIndexIfNotExists(c.Idx(), pilosa.IndexOptions{TrackExistence: true}) _, err := index.CreateField("f", pilosa.OptFieldTypeDefault()) if err != nil { t.Fatal(err) } - if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: ` + if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: ` Set(3001, f=3) Set(5001, f=5) Set(5002, f=5) @@ -4500,7 +4517,7 @@ Set(5002, f=5) } expCols := []uint64{5001, 5002} - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: "Intersect(All(), Row(f=5))"}); err != nil { + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: "Intersect(All(), Row(f=5))"}); err != nil { t.Fatal(err) } else if cols := res.Results[0].(*pilosa.Row).Columns(); !reflect.DeepEqual(cols, expCols) { t.Fatalf("unexpected columns, got: %v, but expected: %v", cols, expCols) @@ -4514,14 +4531,14 @@ func TestExecutor_Execute_ClearRow(t *testing.T) { c := test.MustRunCluster(t, 1) defer c.Close() hldr := c.GetHolder(0) - index := hldr.MustCreateIndexIfNotExists("i", pilosa.IndexOptions{TrackExistence: true}) + index := hldr.MustCreateIndexIfNotExists(c.Idx(), pilosa.IndexOptions{TrackExistence: true}) _, err := index.CreateField("f", pilosa.OptFieldTypeInt(math.MinInt64, math.MaxInt64)) if err != nil { t.Fatal(err) } // Ensure that clearing a row raises an error. - if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `ClearRow(f=1)`}); err == nil { + if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `ClearRow(f=1)`}); err == nil { t.Fatal("expected clear row to return an error") } }) @@ -4530,7 +4547,7 @@ func TestExecutor_Execute_ClearRow(t *testing.T) { c := test.MustRunCluster(t, 1) defer c.Close() hldr := c.GetHolder(0) - index := hldr.MustCreateIndexIfNotExists("i", pilosa.IndexOptions{TrackExistence: true}) + index := hldr.MustCreateIndexIfNotExists(c.Idx(), pilosa.IndexOptions{TrackExistence: true}) _, err := index.CreateField("f", pilosa.OptFieldTypeDefault()) if err != nil { t.Fatal(err) @@ -4560,7 +4577,7 @@ func TestExecutor_Execute_ClearRow(t *testing.T) { ` // Set bits. - if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: cc}); err != nil { + if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: cc}); err != nil { t.Fatal(err) } @@ -4569,7 +4586,7 @@ func TestExecutor_Execute_ClearRow(t *testing.T) { } // Check the TopN results. - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `TopN(f, n=5)`}); err != nil { + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `TopN(f, n=5)`}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual(res.Results, []interface{}{&pilosa.PairsField{ Pairs: []pilosa.Pair{ @@ -4583,14 +4600,14 @@ func TestExecutor_Execute_ClearRow(t *testing.T) { } // Clear the row and ensure we get a `true` response. - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `ClearRow(f=2)`}); err != nil { + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `ClearRow(f=2)`}); err != nil { t.Fatal(err) } else if res := res.Results[0].(bool); !res { t.Fatalf("unexpected clear row result: %+v", res) } // Ensure that the cleared row doesn't show up in TopN (i.e. it was removed from the cache). - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `TopN(f, n=5)`}); err != nil { + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `TopN(f, n=5)`}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual(res.Results, []interface{}{&pilosa.PairsField{ Pairs: []pilosa.Pair{ @@ -4610,7 +4627,7 @@ func TestExecutor_Execute_SetRow(t *testing.T) { c := test.MustRunCluster(t, 1) defer c.Close() hldr := c.GetHolder(0) - index := hldr.MustCreateIndexIfNotExists("i", pilosa.IndexOptions{TrackExistence: true}) + index := hldr.MustCreateIndexIfNotExists(c.Idx(), pilosa.IndexOptions{TrackExistence: true}) if _, err := index.CreateField("f", pilosa.OptFieldTypeDefault()); err != nil { t.Fatal(err) } @@ -4619,7 +4636,7 @@ func TestExecutor_Execute_SetRow(t *testing.T) { } // Set bits. - if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `` + + if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `` + fmt.Sprintf("Set(%d, f=%d)\n", 3, 10) + fmt.Sprintf("Set(%d, f=%d)\n", ShardWidth-1, 10) + fmt.Sprintf("Set(%d, f=%d)\n", ShardWidth+1, 10), @@ -4627,35 +4644,35 @@ func TestExecutor_Execute_SetRow(t *testing.T) { t.Fatal(err) } - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Row(f=10)`}); err != nil { + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Row(f=10)`}); err != nil { t.Fatal(err) } else if bits := res.Results[0].(*pilosa.Row).Columns(); !reflect.DeepEqual(bits, []uint64{3, ShardWidth - 1, ShardWidth + 1}) { t.Fatalf("unexpected columns: %+v", bits) } // Store row 10 into a different row. - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Store(Row(f=10), tmp=20)`}); err != nil { + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Store(Row(f=10), tmp=20)`}); err != nil { t.Fatal(err) } else if res := res.Results[0].(bool); !res { t.Fatalf("unexpected set row result: %+v", res) } // Ensure the row was populated. - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Row(tmp=20)`}); err != nil { + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Row(tmp=20)`}); err != nil { t.Fatal(err) } else if bits := res.Results[0].(*pilosa.Row).Columns(); !reflect.DeepEqual(bits, []uint64{3, ShardWidth - 1, ShardWidth + 1}) { t.Fatalf("unexpected columns: %+v", bits) } // Store row 10 into a table which doesn't exist. - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Store(Row(f=10), nonexistent=20)`}); err != nil { + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Store(Row(f=10), nonexistent=20)`}); err != nil { t.Fatal(err) } else if res := res.Results[0].(bool); !res { t.Fatalf("unexpected set row result: %+v", res) } // Ensure the row was populated. - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Row(nonexistent=20)`}); err != nil { + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Row(nonexistent=20)`}); err != nil { t.Fatal(err) } else if bits := res.Results[0].(*pilosa.Row).Columns(); !reflect.DeepEqual(bits, []uint64{3, ShardWidth - 1, ShardWidth + 1}) { t.Fatalf("unexpected columns: %+v", bits) @@ -4665,14 +4682,14 @@ func TestExecutor_Execute_SetRow(t *testing.T) { c := test.MustRunCluster(t, 1) defer c.Close() hldr := c.GetHolder(0) - idx := hldr.MustCreateIndexIfNotExists("i", pilosa.IndexOptions{TrackExistence: true}) + idx := hldr.MustCreateIndexIfNotExists(c.Idx(), pilosa.IndexOptions{TrackExistence: true}) _, err := idx.CreateField("f", pilosa.OptFieldTypeDefault()) if err != nil { t.Fatal(err) } // Set bits. - if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `` + + if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `` + fmt.Sprintf("Set(%d, f=%d)\n", 3, 10) + fmt.Sprintf("Set(%d, f=%d)\n", ShardWidth-1, 10) + fmt.Sprintf("Set(%d, f=%d)\n", ShardWidth+1, 10), @@ -4680,35 +4697,35 @@ func TestExecutor_Execute_SetRow(t *testing.T) { t.Fatal(err) } - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Row(f=10)`}); err != nil { + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Row(f=10)`}); err != nil { t.Fatal(err) } else if bits := res.Results[0].(*pilosa.Row).Columns(); !reflect.DeepEqual(bits, []uint64{3, ShardWidth - 1, ShardWidth + 1}) { t.Fatalf("unexpected columns: %+v", bits) } // Store row 9 (which doesn't exist) into a different row. - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Store(Row(f=9), f=20)`}); err != nil { + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Store(Row(f=9), f=20)`}); err != nil { t.Fatal(err) } else if res := res.Results[0].(bool); !res { t.Fatalf("unexpected set row result: %+v", res) } // Ensure the row was populated. - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Row(f=20)`}); err != nil { + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Row(f=20)`}); err != nil { t.Fatal(err) } else if bits := res.Results[0].(*pilosa.Row).Columns(); !reflect.DeepEqual(bits, []uint64{}) { t.Fatalf("unexpected columns: %+v", bits) } // Store row 9 (which doesn't exist) into a row that does exist. - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Store(Row(f=9), f=10)`}); err != nil { + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Store(Row(f=9), f=10)`}); err != nil { t.Fatal(err) } else if res := res.Results[0].(bool); !res { t.Fatalf("unexpected set row result: %+v", res) } // Ensure the row was populated. - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Row(f=10)`}); err != nil { + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Row(f=10)`}); err != nil { t.Fatal(err) } else if bits := res.Results[0].(*pilosa.Row).Columns(); !reflect.DeepEqual(bits, []uint64{}) { t.Fatalf("unexpected columns: %+v", bits) @@ -4718,14 +4735,14 @@ func TestExecutor_Execute_SetRow(t *testing.T) { c := test.MustRunCluster(t, 1) defer c.Close() hldr := c.GetHolder(0) - index := hldr.MustCreateIndexIfNotExists("i", pilosa.IndexOptions{TrackExistence: true}) + index := hldr.MustCreateIndexIfNotExists(c.Idx(), pilosa.IndexOptions{TrackExistence: true}) _, err := index.CreateField("f", pilosa.OptFieldTypeDefault()) if err != nil { t.Fatal(err) } // Set bits. - if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `` + + if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `` + fmt.Sprintf("Set(%d, f=%d)\n", 3, 10) + fmt.Sprintf("Set(%d, f=%d)\n", ShardWidth-1, 10) + fmt.Sprintf("Set(%d, f=%d)\n", ShardWidth+1, 10) + @@ -4735,21 +4752,21 @@ func TestExecutor_Execute_SetRow(t *testing.T) { t.Fatal(err) } - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Row(f=20)`}); err != nil { + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Row(f=20)`}); err != nil { t.Fatal(err) } else if bits := res.Results[0].(*pilosa.Row).Columns(); !reflect.DeepEqual(bits, []uint64{1, ShardWidth + 1}) { t.Fatalf("unexpected columns: %+v", bits) } // Store row 10 into an existing row. - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Store(Row(f=10), f=20)`}); err != nil { + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Store(Row(f=10), f=20)`}); err != nil { t.Fatal(err) } else if res := res.Results[0].(bool); !res { t.Fatalf("unexpected set row result: %+v", res) } // Ensure the row was populated. - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Row(f=20)`}); err != nil { + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Row(f=20)`}); err != nil { t.Fatal(err) } else if bits := res.Results[0].(*pilosa.Row).Columns(); !reflect.DeepEqual(bits, []uint64{3, ShardWidth - 1, ShardWidth + 1}) { t.Fatalf("unexpected columns: %+v", bits) @@ -4759,45 +4776,45 @@ func TestExecutor_Execute_SetRow(t *testing.T) { c := test.MustRunCluster(t, 1) defer c.Close() hldr := c.GetHolder(0) - index := hldr.MustCreateIndexIfNotExists("i", pilosa.IndexOptions{TrackExistence: true}) + index := hldr.MustCreateIndexIfNotExists(c.Idx(), pilosa.IndexOptions{TrackExistence: true}) if _, err := index.CreateField("f", pilosa.OptFieldTypeDefault(), pilosa.OptFieldKeys()); err != nil { t.Fatal(err) } // Set bits. - if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Set(1, f="a")`}); err != nil { + if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Set(1, f="a")`}); err != nil { t.Fatal(err) } - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Row(f="a")`}); err != nil { + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Row(f="a")`}); err != nil { t.Fatal(err) } else if bits := res.Results[0].(*pilosa.Row).Columns(); !reflect.DeepEqual(bits, []uint64{1}) { t.Fatalf("unexpected columns: %+v", bits) } // Store row a into a different row. - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Store(Row(f="a"), f="b")`}); err != nil { + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Store(Row(f="a"), f="b")`}); err != nil { t.Fatal(err) } else if res := res.Results[0].(bool); !res { t.Fatalf("unexpected set row result: %+v", res) } // Ensure the row was populated. - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Row(f="b")`}); err != nil { + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Row(f="b")`}); err != nil { t.Fatal(err) } else if bits := res.Results[0].(*pilosa.Row).Columns(); !reflect.DeepEqual(bits, []uint64{1}) { t.Fatalf("unexpected columns: %+v", bits) } // Store row 10 into a table which doesn't exist. - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Store(Row(f="a"), nonexistent="c")`}); err != nil { + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Store(Row(f="a"), nonexistent="c")`}); err != nil { t.Fatal(err) } else if res := res.Results[0].(bool); !res { t.Fatalf("unexpected set row result: %+v", res) } // Ensure the row was populated. - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Row(nonexistent="c")`}); err != nil { + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Row(nonexistent="c")`}); err != nil { t.Fatal(err) } else if bits := res.Results[0].(*pilosa.Row).Columns(); !reflect.DeepEqual(bits, []uint64{1}) { t.Fatalf("unexpected columns: %+v", bits) @@ -4806,7 +4823,7 @@ func TestExecutor_Execute_SetRow(t *testing.T) { } func benchmarkExistence(nn bool, b *testing.B) { - c := test.MustNewCluster(b, 1) + c := test.MustUnsharedCluster(b, 1) var err error c.GetIdleNode(0).Config.DataDir, err = testhook.TempDirInDir(b, *TempDir, "benchmarkExistence") if err != nil { @@ -4819,7 +4836,7 @@ func benchmarkExistence(nn bool, b *testing.B) { defer c.Close() hldr := c.GetHolder(0) - indexName := "i" + indexName := c.Idx() fieldName := "f" index := hldr.MustCreateIndexIfNotExists(indexName, pilosa.IndexOptions{TrackExistence: nn}) @@ -4859,8 +4876,8 @@ func TestExecutor_Execute_Extract(t *testing.T) { c := test.MustRunCluster(t, 3) defer c.Close() - c.CreateField(t, "i", pilosa.IndexOptions{TrackExistence: true}, "set") - c.ImportBits(t, "i", "set", [][2]uint64{ + c.CreateField(t, c.Idx(), pilosa.IndexOptions{TrackExistence: true}, "set") + c.ImportBits(t, c.Idx(), "set", [][2]uint64{ {0, 1}, {0, 2}, {3, 1}, @@ -4868,72 +4885,72 @@ func TestExecutor_Execute_Extract(t *testing.T) { {4, 4 * ShardWidth}, {5, ShardWidth}, }) - c.Query(t, "i", fmt.Sprintf("Clear(%d, set=5)", ShardWidth)) + c.Query(t, c.Idx(), fmt.Sprintf("Clear(%d, set=5)", ShardWidth)) - c.CreateField(t, "i", pilosa.IndexOptions{TrackExistence: true}, "keyset", pilosa.OptFieldKeys()) - c.Query(t, "i", ` + c.CreateField(t, c.Idx(), pilosa.IndexOptions{TrackExistence: true}, "keyset", pilosa.OptFieldKeys()) + c.Query(t, c.Idx(), ` Set(0, keyset="h") Set(1, keyset="xyzzy") Set(0, keyset="plugh") `) - c.CreateField(t, "i", pilosa.IndexOptions{TrackExistence: true}, "mutex", pilosa.OptFieldTypeMutex(pilosa.CacheTypeRanked, 5000)) - c.ImportBits(t, "i", "mutex", [][2]uint64{ + c.CreateField(t, c.Idx(), pilosa.IndexOptions{TrackExistence: true}, "mutex", pilosa.OptFieldTypeMutex(pilosa.CacheTypeRanked, 5000)) + c.ImportBits(t, c.Idx(), "mutex", [][2]uint64{ {0, 1}, {0, 2}, {4, 4 * ShardWidth}, }) - c.CreateField(t, "i", pilosa.IndexOptions{TrackExistence: true}, "keymutex", pilosa.OptFieldKeys(), pilosa.OptFieldTypeMutex(pilosa.CacheTypeRanked, 5000)) - c.Query(t, "i", ` + c.CreateField(t, c.Idx(), pilosa.IndexOptions{TrackExistence: true}, "keymutex", pilosa.OptFieldKeys(), pilosa.OptFieldTypeMutex(pilosa.CacheTypeRanked, 5000)) + c.Query(t, c.Idx(), ` Set(0, keymutex="h") Set(1, keymutex="xyzzy") Set(3, keymutex="plugh") `) - c.CreateField(t, "i", pilosa.IndexOptions{TrackExistence: true}, "time", pilosa.OptFieldTypeTime("YMDH", "0")) - c.Query(t, "i", ` + c.CreateField(t, c.Idx(), pilosa.IndexOptions{TrackExistence: true}, "time", pilosa.OptFieldTypeTime("YMDH", "0")) + c.Query(t, c.Idx(), ` Set(0, time=1, 2016-01-01T00:00) Set(1, time=2, 2017-01-01T00:00) Set(3, time=3, 2018-01-01T00:00) `) - c.CreateField(t, "i", pilosa.IndexOptions{TrackExistence: true}, "keytime", pilosa.OptFieldKeys(), pilosa.OptFieldTypeTime("YMDH", "0")) - c.Query(t, "i", ` + c.CreateField(t, c.Idx(), pilosa.IndexOptions{TrackExistence: true}, "keytime", pilosa.OptFieldKeys(), pilosa.OptFieldTypeTime("YMDH", "0")) + c.Query(t, c.Idx(), ` Set(0, keytime="h", 2016-01-01T00:00) Set(1, keytime="xyzzy", 2017-01-01T00:00) Set(0, keytime="plugh", 2018-01-01T00:00) `) - c.CreateField(t, "i", pilosa.IndexOptions{TrackExistence: true}, "bsint", pilosa.OptFieldTypeInt(-100, 100)) - c.Query(t, "i", ` + c.CreateField(t, c.Idx(), pilosa.IndexOptions{TrackExistence: true}, "bsint", pilosa.OptFieldTypeInt(-100, 100)) + c.Query(t, c.Idx(), ` Set(0, bsint=1) Set(1, bsint=-1) Set(3, bsint=2) `) - c.CreateField(t, "i", pilosa.IndexOptions{TrackExistence: true}, "bsidecimal", pilosa.OptFieldTypeDecimal(2)) - c.Query(t, "i", ` + c.CreateField(t, c.Idx(), pilosa.IndexOptions{TrackExistence: true}, "bsidecimal", pilosa.OptFieldTypeDecimal(2)) + c.Query(t, c.Idx(), ` Set(0, bsidecimal=0.01) Set(1, bsidecimal=1.00) Set(3, bsidecimal=-1.01) `) - c.CreateField(t, "i", pilosa.IndexOptions{TrackExistence: true}, "timestamp", pilosa.OptFieldTypeTimestamp(pilosa.DefaultEpoch, pilosa.TimeUnitSeconds)) - c.Query(t, "i", ` + c.CreateField(t, c.Idx(), pilosa.IndexOptions{TrackExistence: true}, "timestamp", pilosa.OptFieldTypeTimestamp(pilosa.DefaultEpoch, pilosa.TimeUnitSeconds)) + c.Query(t, c.Idx(), ` Set(0, timestamp='2000-01-01T00:00:00Z') Set(1, timestamp='2000-01-01T00:00:01Z') Set(3, timestamp='2000-01-01T00:00:03Z') `) - c.CreateField(t, "i", pilosa.IndexOptions{TrackExistence: true}, "bool", pilosa.OptFieldTypeBool()) - c.Query(t, "i", ` + c.CreateField(t, c.Idx(), pilosa.IndexOptions{TrackExistence: true}, "bool", pilosa.OptFieldTypeBool()) + c.Query(t, c.Idx(), ` Set(0, bool=true) Set(1, bool=false) Set(3, bool=true) `) - resp := c.Query(t, "i", `Extract(All(), Rows(set), Rows(keyset), Rows(mutex), Rows(keymutex), Rows(time), Rows(keytime), Rows(bsint), Rows(bsidecimal), Rows(timestamp), Rows(bool))`) + resp := c.Query(t, c.Idx(), `Extract(All(), Rows(set), Rows(keyset), Rows(mutex), Rows(keymutex), Rows(time), Rows(keytime), Rows(bsint), Rows(bsidecimal), Rows(timestamp), Rows(bool))`) expect := []interface{}{ pilosa.ExtractedTable{ Fields: []pilosa.ExtractedTableField{ @@ -5106,8 +5123,8 @@ func TestExecutor_Execute_Extract_Keyed(t *testing.T) { c := test.MustRunCluster(t, 3) defer c.Close() - c.CreateField(t, "i", pilosa.IndexOptions{TrackExistence: true, Keys: true}, "set") - c.Query(t, "i", ` + c.CreateField(t, c.Idx(), pilosa.IndexOptions{TrackExistence: true, Keys: true}, "set") + c.Query(t, c.Idx(), ` Set("h", set=1) Set("h", set=2) Set("xyzzy", set=2) @@ -5115,7 +5132,7 @@ func TestExecutor_Execute_Extract_Keyed(t *testing.T) { Clear("plugh", set=1) `) - resp := c.Query(t, "i", `Extract(All(), Rows(set))`) + resp := c.Query(t, c.Idx(), `Extract(All(), Rows(set))`) expect := []interface{}{ pilosa.ExtractedTable{ Fields: []pilosa.ExtractedTableField{ @@ -5124,13 +5141,9 @@ func TestExecutor_Execute_Extract_Keyed(t *testing.T) { Type: "[]uint64", }, }, + // The order of these probably shouldn't matter, but currently depends indirectly on the + // index. Columns: []pilosa.ExtractedTableColumn{ - { - Column: pilosa.KeyOrID{Keyed: true, Key: "plugh"}, - Rows: []interface{}{ - []uint64{}, - }, - }, { Column: pilosa.KeyOrID{Keyed: true, Key: "h"}, Rows: []interface{}{ @@ -5148,6 +5161,12 @@ func TestExecutor_Execute_Extract_Keyed(t *testing.T) { }, }, }, + { + Column: pilosa.KeyOrID{Keyed: true, Key: "plugh"}, + Rows: []interface{}{ + []uint64{}, + }, + }, }, }, } @@ -5161,8 +5180,8 @@ func TestExecutor_Execute_MaxMemory(t *testing.T) { c := test.MustRunCluster(t, 3) defer c.Close() - c.CreateField(t, "i", pilosa.IndexOptions{TrackExistence: true}, "set") - c.ImportBits(t, "i", "set", [][2]uint64{ + c.CreateField(t, c.Idx(), pilosa.IndexOptions{TrackExistence: true}, "set") + c.ImportBits(t, c.Idx(), "set", [][2]uint64{ {0, 1}, {0, 2}, {3, 1}, @@ -5170,10 +5189,10 @@ func TestExecutor_Execute_MaxMemory(t *testing.T) { {4, 4 * ShardWidth}, {5, ShardWidth}, }) - c.Query(t, "i", fmt.Sprintf("Clear(%d, set=5)", ShardWidth)) + c.Query(t, c.Idx(), fmt.Sprintf("Clear(%d, set=5)", ShardWidth)) resp := c.GetPrimary().QueryAPI(t, &pilosa.QueryRequest{ - Index: "i", + Index: c.Idx(), Query: `Extract(All(), Rows(set))`, MaxMemory: 1000, }) @@ -5230,8 +5249,8 @@ func TestExecutor_Execute_MaxMemory(t *testing.T) { func TestExecutor_Execute_Rows(t *testing.T) { c := test.MustRunCluster(t, 3) defer c.Close() - c.CreateField(t, "i", pilosa.IndexOptions{}, "general") - c.ImportBits(t, "i", "general", [][2]uint64{ + c.CreateField(t, c.Idx(), pilosa.IndexOptions{}, "general") + c.ImportBits(t, c.Idx(), "general", [][2]uint64{ {10, 0}, {10, ShardWidth + 1}, {11, 2}, @@ -5241,63 +5260,41 @@ func TestExecutor_Execute_Rows(t *testing.T) { {13, 3}, }) - rows := c.Query(t, "i", `Rows(general)`).Results[0].(pilosa.RowIdentifiers) - if !reflect.DeepEqual(rows.Rows, []uint64{10, 11, 12, 13}) { - t.Fatalf("unexpected rows: %+v", rows.Rows) - } else if rows.Keys != nil { - t.Fatalf("unexpected keys: %+v", rows.Keys) - } + rows := c.Query(t, c.Idx(), `Rows(general)`).Results[0].(pilosa.RowIdentifiers) + rows.AssertEqual(t, &pilosa.RowIdentifiers{Rows: []uint64{10, 11, 12, 13}}) // backwards compatibility // TODO: remove at Pilosa 2.0 - rows = c.Query(t, "i", `Rows(field=general)`).Results[0].(pilosa.RowIdentifiers) - if !reflect.DeepEqual(rows.Rows, []uint64{10, 11, 12, 13}) { - t.Fatalf("unexpected rows: %+v", rows.Rows) - } else if rows.Keys != nil { - t.Fatalf("unexpected keys: %+v", rows.Keys) - } + rows = c.Query(t, c.Idx(), `Rows(field=general)`).Results[0].(pilosa.RowIdentifiers) + rows.AssertEqual(t, &pilosa.RowIdentifiers{Rows: []uint64{10, 11, 12, 13}}) - rows = c.Query(t, "i", `Rows(general, limit=2)`).Results[0].(pilosa.RowIdentifiers) - if !reflect.DeepEqual(rows.Rows, []uint64{10, 11}) { - t.Fatalf("unexpected rows: %+v", rows.Rows) - } else if rows.Keys != nil { - t.Fatalf("unexpected keys: %+v", rows.Keys) - } + rows = c.Query(t, c.Idx(), `Rows(general, limit=2)`).Results[0].(pilosa.RowIdentifiers) + rows.AssertEqual(t, &pilosa.RowIdentifiers{Rows: []uint64{10, 11}}) - rows = c.Query(t, "i", `Rows(general, previous=10,limit=2)`).Results[0].(pilosa.RowIdentifiers) - if !reflect.DeepEqual(rows.Rows, []uint64{11, 12}) { - t.Fatalf("unexpected rows: %+v", rows.Rows) - } else if rows.Keys != nil { - t.Fatalf("unexpected keys: %+v", rows.Keys) - } + rows = c.Query(t, c.Idx(), `Rows(general, previous=10,limit=2)`).Results[0].(pilosa.RowIdentifiers) + rows.AssertEqual(t, &pilosa.RowIdentifiers{Rows: []uint64{11, 12}}) - rows = c.Query(t, "i", `Rows(general, column=2)`).Results[0].(pilosa.RowIdentifiers) - if !reflect.DeepEqual(rows.Rows, []uint64{11, 12}) { - t.Fatalf("unexpected rows: %+v", rows.Rows) - } else if rows.Keys != nil { - t.Fatalf("unexpected keys: %+v", rows.Keys) - } + rows = c.Query(t, c.Idx(), `Rows(general, column=2)`).Results[0].(pilosa.RowIdentifiers) + rows.AssertEqual(t, &pilosa.RowIdentifiers{Rows: []uint64{11, 12}}) } // Ensure that an empty time field returns empty Rows(). func TestExecutor_Execute_RowsTimeEmpty(t *testing.T) { c := test.MustRunCluster(t, 1) defer c.Close() - c.CreateField(t, "i", pilosa.IndexOptions{}, "x", pilosa.OptFieldTypeTime(pilosa.TimeQuantum("YMD"), "0", true)) - rows := c.Query(t, "i", `Rows(x, from=1999-12-31T00:00, to=2002-01-01T03:00)`).Results[0].(pilosa.RowIdentifiers).Rows - if !reflect.DeepEqual(rows, []uint64{}) { - t.Fatalf("unexpected rows: %+v", rows) - } + c.CreateField(t, c.Idx(), pilosa.IndexOptions{}, "x", pilosa.OptFieldTypeTime(pilosa.TimeQuantum("YMD"), "0", true)) + rows := c.Query(t, c.Idx(), `Rows(x, from=1999-12-31T00:00, to=2002-01-01T03:00)`).Results[0].(pilosa.RowIdentifiers) + rows.AssertEqual(t, &pilosa.RowIdentifiers{}) } func TestExecutor_Execute_Query_Error(t *testing.T) { c := test.MustRunCluster(t, 1) defer c.Close() - c.CreateField(t, "i", pilosa.IndexOptions{}, "general") - c.CreateField(t, "i", pilosa.IndexOptions{}, "integer", pilosa.OptFieldTypeInt(-1000, 1000)) - c.CreateField(t, "i", pilosa.IndexOptions{}, "decimal", pilosa.OptFieldTypeDecimal(2)) - c.CreateField(t, "i", pilosa.IndexOptions{}, "bool", pilosa.OptFieldTypeBool()) - c.CreateField(t, "i", pilosa.IndexOptions{}, "keys", pilosa.OptFieldKeys()) + c.CreateField(t, c.Idx(), pilosa.IndexOptions{}, "general") + c.CreateField(t, c.Idx(), pilosa.IndexOptions{}, "integer", pilosa.OptFieldTypeInt(-1000, 1000)) + c.CreateField(t, c.Idx(), pilosa.IndexOptions{}, "decimal", pilosa.OptFieldTypeDecimal(2)) + c.CreateField(t, c.Idx(), pilosa.IndexOptions{}, "bool", pilosa.OptFieldTypeBool()) + c.CreateField(t, c.Idx(), pilosa.IndexOptions{}, "keys", pilosa.OptFieldKeys()) tests := []struct { query string @@ -5368,7 +5365,7 @@ func TestExecutor_Execute_Query_Error(t *testing.T) { for i, test := range tests { t.Run(fmt.Sprintf("%d", i), func(t *testing.T) { r, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{ - Index: "i", + Index: c.Idx(), Query: test.query, }) if err == nil { @@ -5384,15 +5381,15 @@ func TestExecutor_Execute_Query_Error(t *testing.T) { func TestExecutor_GroupByStrings(t *testing.T) { c := test.MustRunCluster(t, 1) defer c.Close() - c.CreateField(t, "istring", pilosa.IndexOptions{Keys: true}, "generals", pilosa.OptFieldKeys()) - c.CreateField(t, "istring", pilosa.IndexOptions{Keys: true}, "v", pilosa.OptFieldTypeInt(0, 1000)) - c.CreateField(t, "istring", pilosa.IndexOptions{Keys: true}, "vv", pilosa.OptFieldTypeInt(0, 1000)) - c.CreateField(t, "istring", pilosa.IndexOptions{Keys: true}, "nv", pilosa.OptFieldTypeInt(-1000, 1000)) - c.CreateField(t, "istring", pilosa.IndexOptions{Keys: true}, "dv", pilosa.OptFieldTypeDecimal(2)) - c.CreateField(t, "istring", pilosa.IndexOptions{Keys: true}, "ndv", pilosa.OptFieldTypeDecimal(1)) + c.CreateField(t, c.Idx(), pilosa.IndexOptions{Keys: true}, "generals", pilosa.OptFieldKeys()) + c.CreateField(t, c.Idx(), pilosa.IndexOptions{Keys: true}, "v", pilosa.OptFieldTypeInt(0, 1000)) + c.CreateField(t, c.Idx(), pilosa.IndexOptions{Keys: true}, "vv", pilosa.OptFieldTypeInt(0, 1000)) + c.CreateField(t, c.Idx(), pilosa.IndexOptions{Keys: true}, "nv", pilosa.OptFieldTypeInt(-1000, 1000)) + c.CreateField(t, c.Idx(), pilosa.IndexOptions{Keys: true}, "dv", pilosa.OptFieldTypeDecimal(2)) + c.CreateField(t, c.Idx(), pilosa.IndexOptions{Keys: true}, "ndv", pilosa.OptFieldTypeDecimal(1)) if err := c.GetNode(0).API.Import(context.Background(), nil, &pilosa.ImportRequest{ - Index: "istring", + Index: c.Idx(), Field: "generals", Shard: 0, RowKeys: []string{"r1", "r2", "r1", "r2", "r1", "r2", "r1", "r2", "r1", "r2"}, @@ -5409,7 +5406,7 @@ func TestExecutor_GroupByStrings(t *testing.T) { var dv1, dv2, dv3, dv4, dv5, dv6, dv7, dv8, dv9, dv10 int64 = 111, 222, 333, 444, 555, 666, 777, 888, 999, 1000 var ndv1, ndv2, ndv3, ndv4, ndv5, ndv6, ndv7, ndv8, ndv9, ndv10 int64 = -111, -222, -333, -444, -555, -666, -777, -888, -999, -1000 if err := m0.API.ImportValue(context.Background(), qcx, &pilosa.ImportValueRequest{ - Index: "istring", + Index: c.Idx(), Field: "v", Shard: 0, ColumnKeys: []string{"c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "c10"}, @@ -5419,7 +5416,7 @@ func TestExecutor_GroupByStrings(t *testing.T) { } if err := m0.API.ImportValue(context.Background(), qcx, &pilosa.ImportValueRequest{ - Index: "istring", + Index: c.Idx(), Field: "vv", Shard: 0, ColumnKeys: []string{"c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "c10"}, @@ -5429,7 +5426,7 @@ func TestExecutor_GroupByStrings(t *testing.T) { } if err := m0.API.ImportValue(context.Background(), qcx, &pilosa.ImportValueRequest{ - Index: "istring", + Index: c.Idx(), Field: "nv", Shard: 0, ColumnKeys: []string{"c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "c10"}, @@ -5439,7 +5436,7 @@ func TestExecutor_GroupByStrings(t *testing.T) { } if err := m0.API.ImportValue(context.Background(), qcx, &pilosa.ImportValueRequest{ - Index: "istring", + Index: c.Idx(), Field: "dv", Shard: 0, ColumnKeys: []string{"c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "c10"}, @@ -5449,7 +5446,7 @@ func TestExecutor_GroupByStrings(t *testing.T) { } if err := m0.API.ImportValue(context.Background(), qcx, &pilosa.ImportValueRequest{ - Index: "istring", + Index: c.Idx(), Field: "ndv", Shard: 0, ColumnKeys: []string{"c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "c10"}, @@ -5638,7 +5635,7 @@ func TestExecutor_GroupByStrings(t *testing.T) { for i, tst := range tests { t.Run(fmt.Sprintf("%s%d", tst.query, i), func(t *testing.T) { r, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{ - Index: "istring", + Index: c.Idx(), Query: tst.query, }) if err != nil { @@ -5654,17 +5651,17 @@ func TestExecutor_Execute_Rows_Keys(t *testing.T) { c := test.MustRunCluster(t, 1) defer c.Close() - _, err := c.GetNode(0).API.CreateIndex(context.Background(), "i", pilosa.IndexOptions{Keys: true}) + _, err := c.GetNode(0).API.CreateIndex(context.Background(), c.Idx(), pilosa.IndexOptions{Keys: true}) if err != nil { t.Fatalf("creating index: %v", err) } - _, err = c.GetNode(0).API.CreateField(context.Background(), "i", "f", pilosa.OptFieldKeys()) + _, err = c.GetNode(0).API.CreateField(context.Background(), c.Idx(), "f", pilosa.OptFieldKeys()) if err != nil { t.Fatalf("creating field: %v", err) } - _, err = c.GetNode(0).API.CreateField(context.Background(), "i", "f_id") + _, err = c.GetNode(0).API.CreateField(context.Background(), c.Idx(), "f_id") if err != nil { t.Fatalf("creating field: %v", err) } @@ -5683,7 +5680,7 @@ func TestExecutor_Execute_Rows_Keys(t *testing.T) { } } _, err = c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{ - Index: "i", + Index: c.Idx(), Query: query.String(), }) if err != nil { @@ -5787,7 +5784,7 @@ func TestExecutor_Execute_Rows_Keys(t *testing.T) { for i, test := range tests { t.Run(fmt.Sprintf("#%d_%s", i, test.q), func(t *testing.T) { - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: test.q}); err != nil { + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: test.q}); err != nil { if !strings.HasPrefix(err.Error(), test.expErr) { t.Fatal(err) } @@ -5821,21 +5818,24 @@ func TestExecutor_Execute_Rows_Keys(t *testing.T) { func TestExecutor_ForeignIndex(t *testing.T) { c := test.MustRunCluster(t, 1) defer c.Close() + child := c.Idx("c") + parent := c.Idx("p") + stepChild := c.Idx("d") - c.CreateField(t, "parent", pilosa.IndexOptions{Keys: true}, "general") - c.CreateField(t, "child", pilosa.IndexOptions{}, "parent_id", + c.CreateField(t, parent, pilosa.IndexOptions{Keys: true}, "general") + c.CreateField(t, child, pilosa.IndexOptions{}, "parent_id", pilosa.OptFieldTypeInt(0, math.MaxInt64), - pilosa.OptFieldForeignIndex("parent"), + pilosa.OptFieldForeignIndex(parent), ) - c.CreateField(t, "child", pilosa.IndexOptions{}, "parent_set_id", - pilosa.OptFieldForeignIndex("parent"), + c.CreateField(t, child, pilosa.IndexOptions{}, "parent_set_id", + pilosa.OptFieldForeignIndex(parent), ) - c.CreateField(t, "child", pilosa.IndexOptions{}, "color", + c.CreateField(t, child, pilosa.IndexOptions{}, "color", pilosa.OptFieldKeys(), ) // stepchild/other field needs to have usesKeys=true - crashSchemaJson := `{"indexes": [{"name": "stepparent","createdAt": 1611247966371721700,"options": {"keys": true,"trackExistence": true},"shardWidth": 1048576},{"name": "stepchild","createdAt": 1611247953796662800,"options": {"keys": true,"trackExistence": true},"shardWidth": 1048576,"fields": [{"name": "parent_id","createdAt": 1611247953797265700,"options": {"type": "int","base": 0,"bitDepth": 28,"min": -9223372036854776000,"max": 9223372036854776000,"keys": false,"foreignIndex": "stepparent"}},{"name": "other","createdAt": 1611247953796814000,"options": {"type": "int","base": 0,"bitDepth": 17,"min": -9223372036854776000,"max": 9223372036854776000,"keys": true,"foreignIndex": ""}}]}]}` + crashSchemaJson := fmt.Sprintf(`{"indexes": [{"name": "%q","createdAt": 1611247966371721700,"options": {"keys": true,"trackExistence": true},"shardWidth": 1048576},{"name": "%d","createdAt": 1611247953796662800,"options": {"keys": true,"trackExistence": true},"shardWidth": 1048576,"fields": [{"name": "parent_id","createdAt": 1611247953797265700,"options": {"type": "int","base": 0,"bitDepth": 28,"min": -9223372036854776000,"max": 9223372036854776000,"keys": false,"foreignIndex": "%q"}},{"name": "other","createdAt": 1611247953796814000,"options": {"type": "int","base": 0,"bitDepth": 17,"min": -9223372036854776000,"max": 9223372036854776000,"keys": true,"foreignIndex": ""}}]}]}`, c, c, c) crashSchema := &pilosa.Schema{} err := json.Unmarshal([]byte(crashSchemaJson), &crashSchema) @@ -5848,7 +5848,7 @@ func TestExecutor_ForeignIndex(t *testing.T) { } // Populate parent data. - c.Query(t, "parent", fmt.Sprintf(` + c.Query(t, parent, fmt.Sprintf(` Set("one", general=1) Set("two", general=1) Set("three", general=1) @@ -5862,13 +5862,13 @@ func TestExecutor_ForeignIndex(t *testing.T) { `, ShardWidth, ShardWidth)) // Populate child data. - c.Query(t, "child", fmt.Sprintf(` + c.Query(t, child, fmt.Sprintf(` Set(1, parent_id="one") Set(2, parent_id="two") Set(%d, parent_id="one") Set(4, parent_id="twenty-one") `, ShardWidth)) - c.Query(t, "child", fmt.Sprintf(` + c.Query(t, child, fmt.Sprintf(` Set(1, parent_set_id="one") Set(2, parent_set_id="two") Set(%d, parent_set_id="one") @@ -5876,43 +5876,43 @@ func TestExecutor_ForeignIndex(t *testing.T) { `, ShardWidth)) // Populate color data. - c.Query(t, "child", fmt.Sprintf(` + c.Query(t, child, fmt.Sprintf(` Set(1, color="red") Set(2, color="blue") Set(%d, color="blue") Set(4, color="red") `, ShardWidth)) - distinct := c.Query(t, "child", `Distinct(index="child", field="parent_id")`).Results[0].(pilosa.SignedRow) + distinct := c.Query(t, child, fmt.Sprintf(`Distinct(index=%c, field="parent_id")`, c)).Results[0].(pilosa.SignedRow) if !sameStringSlice(distinct.Pos.Keys, []string{"one", "two", "twenty-one"}) { t.Fatalf("unexpected keys: %v", distinct.Pos.Keys) } - row := c.Query(t, "child", `Distinct(index="child", field="parent_set_id")`).Results[0].(*pilosa.Row) + row := c.Query(t, child, fmt.Sprintf(`Distinct(index=%c, field="parent_set_id")`, c)).Results[0].(*pilosa.Row) if !sameStringSlice(row.Keys, []string{"one", "two", "twenty-one"}) { t.Fatalf("unexpected keys: %v", row.Keys) } - crash := c.Query(t, "stepchild", `Distinct(Row(parent_id=3), field=other)`).Results[0].(pilosa.SignedRow) + crash := c.Query(t, stepChild, `Distinct(Row(parent_id=3), field=other)`).Results[0].(pilosa.SignedRow) if !sameStringSlice(crash.Pos.Keys, []string{}) { // empty result; error condition does not require data t.Fatalf("unexpected columns: %v", crash.Pos.Keys) } - eq := c.Query(t, "child", `Row(parent_id=="one")`).Results[0].(*pilosa.Row) + eq := c.Query(t, child, `Row(parent_id=="one")`).Results[0].(*pilosa.Row) if !reflect.DeepEqual(eq.Columns(), []uint64{1, ShardWidth}) { t.Fatalf("unexpected columns: %v", eq.Columns()) } - neq := c.Query(t, "child", `Row(parent_id!="one")`).Results[0].(*pilosa.Row) + neq := c.Query(t, child, `Row(parent_id!="one")`).Results[0].(*pilosa.Row) if !reflect.DeepEqual(neq.Columns(), []uint64{2, 4}) { t.Fatalf("unexpected columns: %v", neq.Columns()) } - join := c.Query(t, "parent", fmt.Sprintf(`Intersect(Row(general=%d), Distinct(Row(color="blue"), index="child", field="parent_id"))`, ShardWidth)).Results[0].(*pilosa.Row) + join := c.Query(t, parent, fmt.Sprintf(`Intersect(Row(general=%d), Distinct(Row(color="blue"), index=%c, field="parent_id"))`, ShardWidth, c)).Results[0].(*pilosa.Row) if !reflect.DeepEqual(join.Keys, []string{"one"}) { t.Fatalf("unexpected keys: %v", join.Keys) } - join = c.Query(t, "parent", fmt.Sprintf(`Intersect(Row(general=%d), Distinct(Row(color="blue"), index="child", field="parent_set_id"))`, ShardWidth)).Results[0].(*pilosa.Row) + join = c.Query(t, parent, fmt.Sprintf(`Intersect(Row(general=%d), Distinct(Row(color="blue"), index=%c, field="parent_set_id"))`, ShardWidth, c)).Results[0].(*pilosa.Row) if !reflect.DeepEqual(join.Keys, []string{"one"}) { t.Fatalf("unexpected keys: %v", join.Keys) } @@ -5946,9 +5946,9 @@ func sameStringSlice(x, y []string) bool { func TestExecutor_Execute_DistinctFailure(t *testing.T) { c := test.MustRunCluster(t, 1) defer c.Close() - c.CreateField(t, "i", pilosa.IndexOptions{}, "general") - c.CreateField(t, "i", pilosa.IndexOptions{}, "v", pilosa.OptFieldTypeInt(0, 1000)) - c.ImportBits(t, "i", "general", [][2]uint64{ + c.CreateField(t, c.Idx(), pilosa.IndexOptions{}, "general") + c.CreateField(t, c.Idx(), pilosa.IndexOptions{}, "v", pilosa.OptFieldTypeInt(0, 1000)) + c.ImportBits(t, c.Idx(), "general", [][2]uint64{ {10, 0}, {10, 1}, {10, ShardWidth + 1}, @@ -5958,14 +5958,14 @@ func TestExecutor_Execute_DistinctFailure(t *testing.T) { {12, ShardWidth + 2}, }) - if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Set(0, v=10)`}); err != nil { + if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Set(0, v=10)`}); err != nil { t.Fatal(err) - } else if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Set(1, v=100)`}); err != nil { + } else if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Set(1, v=100)`}); err != nil { t.Fatal(err) } t.Run("BasicDistinct", func(t *testing.T) { - if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Distinct(field="v")`}); err != nil { + if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Distinct(field="v")`}); err != nil { t.Fatalf("unexpected error: \"%v\"", err) } }) @@ -5975,11 +5975,11 @@ func TestExecutor_Execute_GroupBy(t *testing.T) { groupByTest := func(t *testing.T, clusterSize int) { c := test.MustRunCluster(t, clusterSize) defer c.Close() - c.CreateField(t, "i", pilosa.IndexOptions{}, "general") - c.CreateField(t, "i", pilosa.IndexOptions{}, "sub") - c.CreateField(t, "i", pilosa.IndexOptions{}, "tq", pilosa.OptFieldTypeTime("YMDH", "0")) - c.CreateField(t, "i", pilosa.IndexOptions{}, "v", pilosa.OptFieldTypeInt(0, 1000)) - c.ImportBits(t, "i", "general", [][2]uint64{ + c.CreateField(t, c.Idx(), pilosa.IndexOptions{}, "general") + c.CreateField(t, c.Idx(), pilosa.IndexOptions{}, "sub") + c.CreateField(t, c.Idx(), pilosa.IndexOptions{}, "tq", pilosa.OptFieldTypeTime("YMDH", "0")) + c.CreateField(t, c.Idx(), pilosa.IndexOptions{}, "v", pilosa.OptFieldTypeInt(0, 1000)) + c.ImportBits(t, c.Idx(), "general", [][2]uint64{ {10, 0}, {10, 1}, {10, ShardWidth + 1}, @@ -5989,7 +5989,7 @@ func TestExecutor_Execute_GroupBy(t *testing.T) { {12, ShardWidth + 2}, }) - c.ImportBits(t, "i", "sub", [][2]uint64{ + c.ImportBits(t, c.Idx(), "sub", [][2]uint64{ {100, 0}, {100, 1}, {100, 3}, @@ -5999,16 +5999,16 @@ func TestExecutor_Execute_GroupBy(t *testing.T) { {110, 0}, }) - if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Set(0, v=10)`}); err != nil { + if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Set(0, v=10)`}); err != nil { t.Fatal(err) - } else if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Set(1, v=100)`}); err != nil { + } else if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Set(1, v=100)`}); err != nil { t.Fatal(err) - } else if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: fmt.Sprintf(`Set(%d, v=100)`, ShardWidth+10)}); err != nil { // Workaround distinct bug where v must be set in every shard + } else if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: fmt.Sprintf(`Set(%d, v=100)`, ShardWidth+10)}); err != nil { // Workaround distinct bug where v must be set in every shard t.Fatal(err) } t.Run("No Field List Arguments", func(t *testing.T) { - if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `GroupBy()`}); err != nil { + if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `GroupBy()`}); err != nil { if !strings.Contains(err.Error(), "need at least one child call") { t.Fatalf("unexpected error: \"%v\"", err) } @@ -6016,7 +6016,7 @@ func TestExecutor_Execute_GroupBy(t *testing.T) { }) t.Run("Unknown Field ", func(t *testing.T) { - if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `GroupBy(Rows(missing))`}); err != nil { + if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `GroupBy(Rows(missing))`}); err != nil { if errors.Cause(err) != pilosa.ErrFieldNotFound { t.Fatalf("unexpected error\n\"%s\" not returned instead \n\"%s\"", pilosa.ErrFieldNotFound, err) } @@ -6033,7 +6033,7 @@ func TestExecutor_Execute_GroupBy(t *testing.T) { {Group: []pilosa.FieldRow{{Field: "general", RowID: 12}, {Field: "sub", RowID: 110}}, Count: 1}, } - results := c.Query(t, "i", `GroupBy(Rows(field=general), Rows(sub))`).Results[0].(*pilosa.GroupCounts).Groups() + results := c.Query(t, c.Idx(), `GroupBy(Rows(field=general), Rows(sub))`).Results[0].(*pilosa.GroupCounts).Groups() test.CheckGroupBy(t, expected, results) }) @@ -6045,7 +6045,7 @@ func TestExecutor_Execute_GroupBy(t *testing.T) { {Group: []pilosa.FieldRow{{Field: "general", RowID: 12}, {Field: "sub", RowID: 110}}, Count: 1}, } - results := c.Query(t, "i", `GroupBy(Rows(general), Rows(sub))`).Results[0].(*pilosa.GroupCounts).Groups() + results := c.Query(t, c.Idx(), `GroupBy(Rows(general), Rows(sub))`).Results[0].(*pilosa.GroupCounts).Groups() test.CheckGroupBy(t, expected, results) }) @@ -6055,7 +6055,7 @@ func TestExecutor_Execute_GroupBy(t *testing.T) { {Group: []pilosa.FieldRow{{Field: "general", RowID: 10}, {Field: "sub", RowID: 110}}, Count: 1}, } - results := c.Query(t, "i", `GroupBy(Rows(general), Rows(sub), filter=Row(general=10))`).Results[0].(*pilosa.GroupCounts).Groups() + results := c.Query(t, c.Idx(), `GroupBy(Rows(general), Rows(sub), filter=Row(general=10))`).Results[0].(*pilosa.GroupCounts).Groups() test.CheckGroupBy(t, expected, results) }) @@ -6065,7 +6065,7 @@ func TestExecutor_Execute_GroupBy(t *testing.T) { {Group: []pilosa.FieldRow{{Field: "general", RowID: 10}, {Field: "sub", RowID: 110}}, Count: 1, Agg: 10}, } - results := c.Query(t, "i", `GroupBy(Rows(general), Rows(sub), aggregate=Sum(field=v))`).Results[0].(*pilosa.GroupCounts).Groups() + results := c.Query(t, c.Idx(), `GroupBy(Rows(general), Rows(sub), aggregate=Sum(field=v))`).Results[0].(*pilosa.GroupCounts).Groups() test.CheckGroupBy(t, expected, results) }) @@ -6077,7 +6077,7 @@ func TestExecutor_Execute_GroupBy(t *testing.T) { {Group: []pilosa.FieldRow{{Field: "general", RowID: 12}, {Field: "sub", RowID: 110}}, Count: 1, Agg: 0}, } - results := c.Query(t, "i", `GroupBy(Rows(general), Rows(sub), aggregate=Count(Distinct(field=v)))`).Results[0].(*pilosa.GroupCounts).Groups() + results := c.Query(t, c.Idx(), `GroupBy(Rows(general), Rows(sub), aggregate=Count(Distinct(field=v)))`).Results[0].(*pilosa.GroupCounts).Groups() test.CheckGroupBy(t, expected, results) }) @@ -6086,7 +6086,7 @@ func TestExecutor_Execute_GroupBy(t *testing.T) { {Group: []pilosa.FieldRow{{Field: "general", RowID: 10}, {Field: "sub", RowID: 100}}, Count: 1, Agg: 1}, } - results := c.Query(t, "i", `GroupBy(Rows(general), Rows(sub), filter=Row(v > 10), aggregate=Count(Distinct(field=v)))`).Results[0].(*pilosa.GroupCounts).Groups() + results := c.Query(t, c.Idx(), `GroupBy(Rows(general), Rows(sub), filter=Row(v > 10), aggregate=Count(Distinct(field=v)))`).Results[0].(*pilosa.GroupCounts).Groups() test.CheckGroupBy(t, expected, results) }) @@ -6098,7 +6098,7 @@ func TestExecutor_Execute_GroupBy(t *testing.T) { {Group: []pilosa.FieldRow{{Field: "general", RowID: 12}, {Field: "sub", RowID: 110}}, Count: 1, Agg: 0}, } - results := c.Query(t, "i", `GroupBy(Rows(general), Rows(sub), aggregate=Count(Distinct(Row(v > 10), field=v)))`).Results[0].(*pilosa.GroupCounts).Groups() + results := c.Query(t, c.Idx(), `GroupBy(Rows(general), Rows(sub), aggregate=Count(Distinct(Row(v > 10), field=v)))`).Results[0].(*pilosa.GroupCounts).Groups() test.CheckGroupBy(t, expected, results) }) @@ -6108,7 +6108,7 @@ func TestExecutor_Execute_GroupBy(t *testing.T) { {Group: []pilosa.FieldRow{{Field: "general", RowID: 12}}, Count: 2}, } - results := c.Query(t, "i", `GroupBy(Rows(general, previous=10))`).Results[0].(*pilosa.GroupCounts).Groups() + results := c.Query(t, c.Idx(), `GroupBy(Rows(general, previous=10))`).Results[0].(*pilosa.GroupCounts).Groups() test.CheckGroupBy(t, expected, results) }) @@ -6117,18 +6117,18 @@ func TestExecutor_Execute_GroupBy(t *testing.T) { {Group: []pilosa.FieldRow{{Field: "general", RowID: 11}}, Count: 2}, } - results := c.Query(t, "i", `GroupBy(Rows(general, previous=10), limit=1)`).Results[0].(*pilosa.GroupCounts).Groups() + results := c.Query(t, c.Idx(), `GroupBy(Rows(general, previous=10), limit=1)`).Results[0].(*pilosa.GroupCounts).Groups() test.CheckGroupBy(t, expected, results) }) - c.CreateField(t, "i", pilosa.IndexOptions{}, "a") - c.CreateField(t, "i", pilosa.IndexOptions{}, "b") - c.ImportBits(t, "i", "a", [][2]uint64{ + c.CreateField(t, c.Idx(), pilosa.IndexOptions{}, "a") + c.CreateField(t, c.Idx(), pilosa.IndexOptions{}, "b") + c.ImportBits(t, c.Idx(), "a", [][2]uint64{ {0, 1}, {1, ShardWidth + 1}, }) - c.ImportBits(t, "i", "b", [][2]uint64{ + c.ImportBits(t, c.Idx(), "b", [][2]uint64{ {0, ShardWidth + 1}, {1, 1}, }) @@ -6138,27 +6138,27 @@ func TestExecutor_Execute_GroupBy(t *testing.T) { {Group: []pilosa.FieldRow{{Field: "a", RowID: 0}, {Field: "b", RowID: 1}}, Count: 1}, } - results := c.Query(t, "i", `GroupBy(Rows(a), Rows(b), limit=1)`).Results[0].(*pilosa.GroupCounts).Groups() + results := c.Query(t, c.Idx(), `GroupBy(Rows(a), Rows(b), limit=1)`).Results[0].(*pilosa.GroupCounts).Groups() test.CheckGroupBy(t, expected, results) }) // set the same bits in a single shard in three fields - c.CreateField(t, "i", pilosa.IndexOptions{}, "wa") - c.CreateField(t, "i", pilosa.IndexOptions{}, "wb") - c.CreateField(t, "i", pilosa.IndexOptions{}, "wc") - c.ImportBits(t, "i", "wa", [][2]uint64{ + c.CreateField(t, c.Idx(), pilosa.IndexOptions{}, "wa") + c.CreateField(t, c.Idx(), pilosa.IndexOptions{}, "wb") + c.CreateField(t, c.Idx(), pilosa.IndexOptions{}, "wc") + c.ImportBits(t, c.Idx(), "wa", [][2]uint64{ {0, 0}, {0, 1}, {0, 2}, // all {1, 1}, // odds {2, 0}, {2, 2}, // evens {3, 3}, // no overlap }) - c.ImportBits(t, "i", "wb", [][2]uint64{ + c.ImportBits(t, c.Idx(), "wb", [][2]uint64{ {0, 0}, {0, 1}, {0, 2}, {1, 1}, {2, 0}, {2, 2}, {3, 3}, }) - c.ImportBits(t, "i", "wc", [][2]uint64{ + c.ImportBits(t, c.Idx(), "wc", [][2]uint64{ {0, 0}, {0, 1}, {0, 2}, {1, 1}, {2, 0}, {2, 2}, @@ -6166,7 +6166,7 @@ func TestExecutor_Execute_GroupBy(t *testing.T) { }) t.Run("test wrapping with previous", func(t *testing.T) { - results := c.Query(t, "i", `GroupBy(Rows(wa), Rows(wb), Rows(wc, previous=1), limit=3)`).Results[0].(*pilosa.GroupCounts).Groups() + results := c.Query(t, c.Idx(), `GroupBy(Rows(wa), Rows(wb), Rows(wc, previous=1), limit=3)`).Results[0].(*pilosa.GroupCounts).Groups() expected := []pilosa.GroupCount{ {Group: []pilosa.FieldRow{{Field: "wa", RowID: 0}, {Field: "wb", RowID: 0}, {Field: "wc", RowID: 2}}, Count: 2}, {Group: []pilosa.FieldRow{{Field: "wa", RowID: 0}, {Field: "wb", RowID: 1}, {Field: "wc", RowID: 0}}, Count: 1}, @@ -6176,14 +6176,14 @@ func TestExecutor_Execute_GroupBy(t *testing.T) { }) t.Run("test previous is last result", func(t *testing.T) { - results := c.Query(t, "i", `GroupBy(Rows(wa, previous=3), Rows(wb, previous=3), Rows(wc, previous=3), limit=3)`).Results[0].(*pilosa.GroupCounts).Groups() + results := c.Query(t, c.Idx(), `GroupBy(Rows(wa, previous=3), Rows(wb, previous=3), Rows(wc, previous=3), limit=3)`).Results[0].(*pilosa.GroupCounts).Groups() if len(results) > 0 { t.Fatalf("expected no results because previous specified last result") } }) t.Run("test wrapping multiple", func(t *testing.T) { - results := c.Query(t, "i", `GroupBy(Rows(wa), Rows(wb, previous=2), Rows(wc, previous=2), limit=1)`).Results[0].(*pilosa.GroupCounts).Groups() + results := c.Query(t, c.Idx(), `GroupBy(Rows(wa), Rows(wb, previous=2), Rows(wc, previous=2), limit=1)`).Results[0].(*pilosa.GroupCounts).Groups() expected := []pilosa.GroupCount{ {Group: []pilosa.FieldRow{{Field: "wa", RowID: 1}, {Field: "wb", RowID: 0}, {Field: "wc", RowID: 0}}, Count: 1}, } @@ -6192,22 +6192,22 @@ func TestExecutor_Execute_GroupBy(t *testing.T) { // test multiple shards with distinct results (different rows) and same // rows to ensure ordering, limit behavior and correctness - c.CreateField(t, "i", pilosa.IndexOptions{}, "ma") - c.CreateField(t, "i", pilosa.IndexOptions{}, "mb") - c.ImportBits(t, "i", "ma", [][2]uint64{ + c.CreateField(t, c.Idx(), pilosa.IndexOptions{}, "ma") + c.CreateField(t, c.Idx(), pilosa.IndexOptions{}, "mb") + c.ImportBits(t, c.Idx(), "ma", [][2]uint64{ {0, 0}, {1, ShardWidth}, {2, 0}, {3, ShardWidth}, }) - c.ImportBits(t, "i", "mb", [][2]uint64{ + c.ImportBits(t, c.Idx(), "mb", [][2]uint64{ {0, 0}, {1, ShardWidth}, {2, 0}, {3, ShardWidth}, }) t.Run("distinct rows in different shards", func(t *testing.T) { - results := c.Query(t, "i", `GroupBy(Rows(ma), Rows(mb), limit=5)`).Results[0].(*pilosa.GroupCounts).Groups() + results := c.Query(t, c.Idx(), `GroupBy(Rows(ma), Rows(mb), limit=5)`).Results[0].(*pilosa.GroupCounts).Groups() expected := []pilosa.GroupCount{ {Group: []pilosa.FieldRow{{Field: "ma", RowID: 0}, {Field: "mb", RowID: 0}}, Count: 1}, {Group: []pilosa.FieldRow{{Field: "ma", RowID: 0}, {Field: "mb", RowID: 2}}, Count: 1}, @@ -6219,7 +6219,7 @@ func TestExecutor_Execute_GroupBy(t *testing.T) { }) t.Run("distinct rows in different shards with row limit", func(t *testing.T) { - results := c.Query(t, "i", `GroupBy(Rows(ma), Rows(mb, limit=2), limit=5)`).Results[0].(*pilosa.GroupCounts).Groups() + results := c.Query(t, c.Idx(), `GroupBy(Rows(ma), Rows(mb, limit=2), limit=5)`).Results[0].(*pilosa.GroupCounts).Groups() expected := []pilosa.GroupCount{ {Group: []pilosa.FieldRow{{Field: "ma", RowID: 0}, {Field: "mb", RowID: 0}}, Count: 1}, {Group: []pilosa.FieldRow{{Field: "ma", RowID: 1}, {Field: "mb", RowID: 1}}, Count: 1}, @@ -6230,7 +6230,7 @@ func TestExecutor_Execute_GroupBy(t *testing.T) { }) t.Run("distinct rows in different shards with column arg", func(t *testing.T) { - results := c.Query(t, "i", fmt.Sprintf(`GroupBy(Rows(ma), Rows(mb, column=%d), limit=5)`, ShardWidth)).Results[0].(*pilosa.GroupCounts).Groups() + results := c.Query(t, c.Idx(), fmt.Sprintf(`GroupBy(Rows(ma), Rows(mb, column=%d), limit=5)`, ShardWidth)).Results[0].(*pilosa.GroupCounts).Groups() expected := []pilosa.GroupCount{ {Group: []pilosa.FieldRow{{Field: "ma", RowID: 1}, {Field: "mb", RowID: 1}}, Count: 1}, {Group: []pilosa.FieldRow{{Field: "ma", RowID: 1}, {Field: "mb", RowID: 3}}, Count: 1}, @@ -6240,22 +6240,22 @@ func TestExecutor_Execute_GroupBy(t *testing.T) { test.CheckGroupBy(t, expected, results) }) - c.CreateField(t, "i", pilosa.IndexOptions{}, "na") - c.CreateField(t, "i", pilosa.IndexOptions{}, "nb") - c.ImportBits(t, "i", "na", [][2]uint64{ + c.CreateField(t, c.Idx(), pilosa.IndexOptions{}, "na") + c.CreateField(t, c.Idx(), pilosa.IndexOptions{}, "nb") + c.ImportBits(t, c.Idx(), "na", [][2]uint64{ {0, 0}, {0, ShardWidth}, {1, 0}, {1, ShardWidth}, }) - c.ImportBits(t, "i", "nb", [][2]uint64{ + c.ImportBits(t, c.Idx(), "nb", [][2]uint64{ {0, 0}, {0, ShardWidth}, {1, 0}, {1, ShardWidth}, }) t.Run("same rows in different shards", func(t *testing.T) { - results := c.Query(t, "i", `GroupBy(Rows(na), Rows(nb))`).Results[0].(*pilosa.GroupCounts).Groups() + results := c.Query(t, c.Idx(), `GroupBy(Rows(na), Rows(nb))`).Results[0].(*pilosa.GroupCounts).Groups() expected := []pilosa.GroupCount{ {Group: []pilosa.FieldRow{{Field: "na", RowID: 0}, {Field: "nb", RowID: 0}}, Count: 2}, {Group: []pilosa.FieldRow{{Field: "na", RowID: 0}, {Field: "nb", RowID: 1}}, Count: 2}, @@ -6268,22 +6268,22 @@ func TestExecutor_Execute_GroupBy(t *testing.T) { // test paging over results using previous. set the same bits in three // fields - c.CreateField(t, "i", pilosa.IndexOptions{}, "ppa") - c.CreateField(t, "i", pilosa.IndexOptions{}, "ppb") - c.CreateField(t, "i", pilosa.IndexOptions{}, "ppc") - c.ImportBits(t, "i", "ppa", [][2]uint64{ + c.CreateField(t, c.Idx(), pilosa.IndexOptions{}, "ppa") + c.CreateField(t, c.Idx(), pilosa.IndexOptions{}, "ppb") + c.CreateField(t, c.Idx(), pilosa.IndexOptions{}, "ppc") + c.ImportBits(t, c.Idx(), "ppa", [][2]uint64{ {0, 0}, {1, 0}, {2, 0}, {3, 0}, {3, 91000}, {3, ShardWidth}, {3, ShardWidth * 2}, {3, ShardWidth * 3}, }) - c.ImportBits(t, "i", "ppb", [][2]uint64{ + c.ImportBits(t, c.Idx(), "ppb", [][2]uint64{ {0, 0}, {1, 0}, {2, 0}, {3, 0}, {3, 91000}, {3, ShardWidth}, {3, ShardWidth * 2}, {3, ShardWidth * 3}, }) - c.ImportBits(t, "i", "ppc", [][2]uint64{ + c.ImportBits(t, c.Idx(), "ppc", [][2]uint64{ {0, 0}, {1, 0}, {2, 0}, @@ -6292,12 +6292,12 @@ func TestExecutor_Execute_GroupBy(t *testing.T) { t.Run("test wrapping with previous", func(t *testing.T) { totalResults := make([]pilosa.GroupCount, 0) - results := c.Query(t, "i", `GroupBy(Rows(ppa), Rows(ppb), Rows(ppc), limit=3)`).Results[0].(*pilosa.GroupCounts).Groups() + results := c.Query(t, c.Idx(), `GroupBy(Rows(ppa), Rows(ppb), Rows(ppc), limit=3)`).Results[0].(*pilosa.GroupCounts).Groups() totalResults = append(totalResults, results...) for len(totalResults) < 64 { lastGroup := results[len(results)-1].Group query := fmt.Sprintf("GroupBy(Rows(ppa, previous=%d), Rows(ppb, previous=%d), Rows(ppc, previous=%d), limit=3)", lastGroup[0].RowID, lastGroup[1].RowID, lastGroup[2].RowID) - results = c.Query(t, "i", query).Results[0].(*pilosa.GroupCounts).Groups() + results = c.Query(t, c.Idx(), query).Results[0].(*pilosa.GroupCounts).Groups() totalResults = append(totalResults, results...) } @@ -6311,9 +6311,9 @@ func TestExecutor_Execute_GroupBy(t *testing.T) { }) // test row keys - c.CreateField(t, "i", pilosa.IndexOptions{}, "generalk", pilosa.OptFieldKeys()) - c.CreateField(t, "i", pilosa.IndexOptions{}, "subk", pilosa.OptFieldKeys()) - c.Query(t, "i", ` + c.CreateField(t, c.Idx(), pilosa.IndexOptions{}, "generalk", pilosa.OptFieldKeys()) + c.CreateField(t, c.Idx(), pilosa.IndexOptions{}, "subk", pilosa.OptFieldKeys()) + c.Query(t, c.Idx(), ` Set(0, generalk="ten") Set(1, generalk="ten") Set(1001, generalk="ten") @@ -6339,19 +6339,19 @@ func TestExecutor_Execute_GroupBy(t *testing.T) { {Group: []pilosa.FieldRow{{Field: "generalk", RowID: 3, RowKey: "twelve"}, {Field: "subk", RowID: 2, RowKey: "one-hundred-ten"}}, Count: 1}, } - results := c.Query(t, "i", `GroupBy(Rows(generalk), Rows(subk))`).Results[0].(*pilosa.GroupCounts).Groups() + results := c.Query(t, c.Idx(), `GroupBy(Rows(generalk), Rows(subk))`).Results[0].(*pilosa.GroupCounts).Groups() test.CheckGroupBy(t, expected, results) }) // Foreign Index - c.CreateField(t, "fip", pilosa.IndexOptions{Keys: true}, "parent") - c.CreateField(t, "fic", pilosa.IndexOptions{}, "child", + c.CreateField(t, c.Idx("fip"), pilosa.IndexOptions{Keys: true}, "parent") + c.CreateField(t, c.Idx("fic"), pilosa.IndexOptions{}, "child", pilosa.OptFieldTypeInt(0, math.MaxInt64), - pilosa.OptFieldForeignIndex("fip"), + pilosa.OptFieldForeignIndex(c.Idx("fip")), ) // Set data on the parent so we have some index keys. - c.Query(t, "fip", ` + c.Query(t, c.Idx("fip"), ` Set("one", parent=1) Set("two", parent=2) Set("three", parent=3) @@ -6359,7 +6359,7 @@ func TestExecutor_Execute_GroupBy(t *testing.T) { Set("five", parent=5) `) // Set data on the child to align with the foreign index keys. - c.Query(t, "fic", ` + c.Query(t, c.Idx("fic"), ` Set(1, child="one") Set(2, child="one") Set(3, child="one") @@ -6379,22 +6379,22 @@ func TestExecutor_Execute_GroupBy(t *testing.T) { {Group: []pilosa.FieldRow{{Field: "child", RowKey: "five"}}, Count: 1}, } - results := c.Query(t, "fic", `GroupBy(Rows(child), sort="count desc")`).Results[0].(*pilosa.GroupCounts).Groups() + results := c.Query(t, c.Idx("fic"), `GroupBy(Rows(child), sort="count desc")`).Results[0].(*pilosa.GroupCounts).Groups() test.CheckGroupByOnKey(t, expected, results) }) // SUP-139: GroupBy returns incorrect results when two or more Integer Range Fields are used to define the grouping t.Run("CountByIntegersWithMinMax", func(t *testing.T) { - c.CreateField(t, "cbimm", pilosa.IndexOptions{}, "year", pilosa.OptFieldTypeInt(2019, 2020)) - c.CreateField(t, "cbimm", pilosa.IndexOptions{}, "quarter", pilosa.OptFieldTypeInt(1, 4)) + c.CreateField(t, c.Idx("cbimm"), pilosa.IndexOptions{}, "year", pilosa.OptFieldTypeInt(2019, 2020)) + c.CreateField(t, c.Idx("cbimm"), pilosa.IndexOptions{}, "quarter", pilosa.OptFieldTypeInt(1, 4)) - c.ImportIntID(t, "cbimm", "year", []test.IntID{{ID: 1, Val: 2019}, {ID: 2, Val: 2019}, {ID: 3, Val: 2019}, {ID: 4, Val: 2019}}) - c.ImportIntID(t, "cbimm", "quarter", []test.IntID{{ID: 1, Val: 1}, {ID: 2, Val: 1}, {ID: 3, Val: 1}, {ID: 4, Val: 2}}) + c.ImportIntID(t, c.Idx("cbimm"), "year", []test.IntID{{ID: 1, Val: 2019}, {ID: 2, Val: 2019}, {ID: 3, Val: 2019}, {ID: 4, Val: 2019}}) + c.ImportIntID(t, c.Idx("cbimm"), "quarter", []test.IntID{{ID: 1, Val: 1}, {ID: 2, Val: 1}, {ID: 3, Val: 1}, {ID: 4, Val: 2}}) year2019 := int64(2019) quarter1, quarter2 := int64(1), int64(2) - results := c.Query(t, "cbimm", `GroupBy(Rows(year), Rows(quarter))`).Results[0].(*pilosa.GroupCounts).Groups() + results := c.Query(t, c.Idx("cbimm"), `GroupBy(Rows(year), Rows(quarter))`).Results[0].(*pilosa.GroupCounts).Groups() test.CheckGroupBy(t, []pilosa.GroupCount{ @@ -6412,8 +6412,8 @@ func TestExecutor_Execute_GroupBy(t *testing.T) { }) // Create some time-quantum data: - c.Query(t, "i", "Set(0, tq=1, 2022-01-01T01:01)") - c.Query(t, "i", "Set(1, tq=1, 2021-01-01T01:01)") + c.Query(t, c.Idx(), "Set(0, tq=1, 2022-01-01T01:01)") + c.Query(t, c.Idx(), "Set(1, tq=1, 2021-01-01T01:01)") t.Run("GroupByWithTime", func(t *testing.T) { expected := map[string][]pilosa.GroupCount{ // no time specified @@ -6437,8 +6437,7 @@ func TestExecutor_Execute_GroupBy(t *testing.T) { } for query, want := range expected { - results := c.Query(t, "i", query).Results[0].(*pilosa.GroupCounts).Groups() - t.Logf("query %q", query) + results := c.Query(t, c.Idx(), query).Results[0].(*pilosa.GroupCounts).Groups() test.CheckGroupBy(t, want, results) } @@ -6452,7 +6451,7 @@ func TestExecutor_Execute_GroupBy(t *testing.T) { } func BenchmarkGroupBy(b *testing.B) { - c := test.MustNewCluster(b, 1) + c := test.MustUnsharedCluster(b, 1) var err error c.GetIdleNode(0).Config.DataDir, err = testhook.TempDirInDir(b, *TempDir, "benchmarkGroupBy-") if err != nil { @@ -6463,9 +6462,9 @@ func BenchmarkGroupBy(b *testing.B) { b.Fatalf("starting cluster: %v", err) } defer c.Close() - c.CreateField(b, "i", pilosa.IndexOptions{}, "a") - c.CreateField(b, "i", pilosa.IndexOptions{}, "b") - c.CreateField(b, "i", pilosa.IndexOptions{}, "c") + c.CreateField(b, c.Idx(), pilosa.IndexOptions{}, "a") + c.CreateField(b, c.Idx(), pilosa.IndexOptions{}, "b") + c.CreateField(b, c.Idx(), pilosa.IndexOptions{}, "c") // Set up identical representative data in 3 fields. In each row, we'll set // a certain bit pattern for 100 bits, then skip 1000 up to ShardWidth. bits := make([][2]uint64, 0) @@ -6488,15 +6487,15 @@ func BenchmarkGroupBy(b *testing.B) { i += 1000 } } - c.ImportBits(b, "i", "a", bits) - c.ImportBits(b, "i", "b", bits) - c.ImportBits(b, "i", "c", bits) + c.ImportBits(b, c.Idx(), "a", bits) + c.ImportBits(b, c.Idx(), "b", bits) + c.ImportBits(b, c.Idx(), "c", bits) b.Run("single shard group by", func(b *testing.B) { b.ResetTimer() b.ReportAllocs() for i := 0; i < b.N; i++ { - c.Query(b, "i", `GroupBy(Rows(a), Rows(b), Rows(c))`) + c.Query(b, c.Idx(), `GroupBy(Rows(a), Rows(b), Rows(c))`) } }) @@ -6504,7 +6503,7 @@ func BenchmarkGroupBy(b *testing.B) { b.ResetTimer() b.ReportAllocs() for i := 0; i < b.N; i++ { - c.Query(b, "i", `GroupBy(Rows(a), Rows(b), Rows(c), limit=4)`) + c.Query(b, c.Idx(), `GroupBy(Rows(a), Rows(b), Rows(c), limit=4)`) } }) @@ -6523,15 +6522,15 @@ func TestExecutor_Execute_Shift(t *testing.T) { c := test.MustRunCluster(t, 1) defer c.Close() hldr := c.GetHolder(0) - hldr.SetBit("i", "general", 10, 0) + hldr.SetBit(c.Idx(), "general", 10, 0) - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Shift(Row(general=10), n=1)`}); err != nil { + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Shift(Row(general=10), n=1)`}); err != nil { t.Fatal(err) } else if columns := res.Results[0].(*pilosa.Row).Columns(); !reflect.DeepEqual(columns, []uint64{1}) { t.Fatalf("unexpected columns: %+v", columns) } - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Shift(Shift(Row(general=10), n=1), n=1)`}); err != nil { + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Shift(Shift(Row(general=10), n=1), n=1)`}); err != nil { t.Fatal(err) } else if columns := res.Results[0].(*pilosa.Row).Columns(); !reflect.DeepEqual(columns, []uint64{2}) { t.Fatalf("unexpected columns: %+v", columns) @@ -6542,9 +6541,9 @@ func TestExecutor_Execute_Shift(t *testing.T) { c := test.MustRunCluster(t, 1) defer c.Close() hldr := c.GetHolder(0) - hldr.SetBit("i", "general", 10, 65535) + hldr.SetBit(c.Idx(), "general", 10, 65535) - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Shift(Row(general=10), n=1)`}); err != nil { + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Shift(Row(general=10), n=1)`}); err != nil { t.Fatal(err) } else if columns := res.Results[0].(*pilosa.Row).Columns(); !reflect.DeepEqual(columns, []uint64{65536}) { t.Fatalf("unexpected columns: %+v", columns) @@ -6561,22 +6560,22 @@ func TestExecutor_Execute_Shift(t *testing.T) { shift2 := []uint64{3, ShardWidth + 1, ShardWidth + 3} for _, bit := range orig { - hldr.SetBit("i", "general", 10, bit) + hldr.SetBit(c.Idx(), "general", 10, bit) } - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Shift(Row(general=10), n=1)`}); err != nil { + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Shift(Row(general=10), n=1)`}); err != nil { t.Fatal(err) } else if columns := res.Results[0].(*pilosa.Row).Columns(); !reflect.DeepEqual(columns, shift1) { t.Fatalf("unexpected shift by 1: expected: %+v, but got: %+v", shift1, columns) } - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Shift(Row(general=10), n=2)`}); err != nil { + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Shift(Row(general=10), n=2)`}); err != nil { t.Fatal(err) } else if columns := res.Results[0].(*pilosa.Row).Columns(); !reflect.DeepEqual(columns, shift2) { t.Fatalf("unexpected shift by 2: expected: %+v, but got: %+v", shift2, columns) } - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Shift(Shift(Row(general=10)))`}); err != nil { + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Shift(Shift(Row(general=10)))`}); err != nil { t.Fatal(err) } else if columns := res.Results[0].(*pilosa.Row).Columns(); !reflect.DeepEqual(columns, orig) { t.Fatalf("unexpected shift by 0: expected: %+v, but got: %+v", orig, columns) @@ -6587,18 +6586,18 @@ func TestExecutor_Execute_Shift(t *testing.T) { c := test.MustRunCluster(t, 1) defer c.Close() hldr := c.GetHolder(0) - hldr.SetBit("i", "general", 10, ShardWidth-2) //shardwidth -1 - hldr.SetBit("i", "general", 10, ShardWidth-1) //shardwidth - hldr.SetBit("i", "general", 10, ShardWidth) //shardwidth +1 - hldr.SetBit("i", "general", 10, ShardWidth+2) //shardwidth +3 + hldr.SetBit(c.Idx(), "general", 10, ShardWidth-2) //shardwidth -1 + hldr.SetBit(c.Idx(), "general", 10, ShardWidth-1) //shardwidth + hldr.SetBit(c.Idx(), "general", 10, ShardWidth) //shardwidth +1 + hldr.SetBit(c.Idx(), "general", 10, ShardWidth+2) //shardwidth +3 exp := []uint64{ShardWidth - 1, ShardWidth, ShardWidth + 1, ShardWidth + 3} - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Shift(Row(general=10), n=1)`}); err != nil { + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Shift(Row(general=10), n=1)`}); err != nil { t.Fatal(err) } else if columns := res.Results[0].(*pilosa.Row).Columns(); !reflect.DeepEqual(columns, exp) { t.Fatalf("unexpected columns: %+v", columns) } - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Shift(Shift(Row(general=10), n=1), n=1)`}); err != nil { + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `Shift(Shift(Row(general=10), n=1), n=1)`}); err != nil { t.Fatal(err) } else if columns := res.Results[0].(*pilosa.Row).Columns(); !reflect.DeepEqual(columns, []uint64{ShardWidth, ShardWidth + 1, ShardWidth + 2, ShardWidth + 4}) { t.Fatalf("unexpected columns: \n%+v\n%+v", columns, exp) @@ -6611,9 +6610,9 @@ func TestExecutor_Execute_IncludesColumn(t *testing.T) { c := test.MustRunCluster(t, 1) defer c.Close() hldr := c.GetHolder(0) - hldr.SetBit("i", "general", 10, 1) - hldr.SetBit("i", "general", 10, ShardWidth) - hldr.SetBit("i", "general", 10, 2*ShardWidth) + hldr.SetBit(c.Idx(), "general", 10, 1) + hldr.SetBit(c.Idx(), "general", 10, ShardWidth) + hldr.SetBit(c.Idx(), "general", 10, 2*ShardWidth) for i, tt := range []struct { col uint64 @@ -6627,7 +6626,7 @@ func TestExecutor_Execute_IncludesColumn(t *testing.T) { {(2 * ShardWidth) + 1, false}, } { t.Run(fmt.Sprint(i), func(t *testing.T) { - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: fmt.Sprintf("IncludesColumn(Row(general=10), column=%d)", tt.col)}); err != nil { + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: fmt.Sprintf("IncludesColumn(Row(general=10), column=%d)", tt.col)}); err != nil { t.Fatal(err) } else if tt.expIncluded && !res.Results[0].(bool) { t.Fatalf("expected to find column: %d", tt.col) @@ -6642,7 +6641,7 @@ func TestExecutor_Execute_IncludesColumn(t *testing.T) { defer c.Close() cmd := c.GetNode(0) hldr := c.GetHolder(0) - index := hldr.MustCreateIndexIfNotExists("i", pilosa.IndexOptions{Keys: true}) + index := hldr.MustCreateIndexIfNotExists(c.Idx(), pilosa.IndexOptions{Keys: true}) if _, err := index.CreateField("general", pilosa.OptFieldTypeDefault(), pilosa.OptFieldKeys()); err != nil { t.Fatal(err) } @@ -6650,7 +6649,7 @@ func TestExecutor_Execute_IncludesColumn(t *testing.T) { if _, err := cmd.API.Query( context.Background(), &pilosa.QueryRequest{ - Index: "i", + Index: c.Idx(), Query: `Set("one", general="ten") Set("eleven", general="ten") Set("twentyone", general="ten")`, }); err != nil { t.Fatal(err) @@ -6668,7 +6667,7 @@ func TestExecutor_Execute_IncludesColumn(t *testing.T) { {"twentytwo", false}, } { t.Run(fmt.Sprint(i), func(t *testing.T) { - if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: fmt.Sprintf("IncludesColumn(Row(general=ten), column=%s)", tt.col)}); err != nil { + if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: fmt.Sprintf("IncludesColumn(Row(general=ten), column=%s)", tt.col)}); err != nil { t.Fatal(err) } else if tt.expIncluded && !res.Results[0].(bool) { t.Fatalf("expected to find column: %s", tt.col) @@ -6682,11 +6681,11 @@ func TestExecutor_Execute_IncludesColumn(t *testing.T) { c := test.MustRunCluster(t, 1) defer c.Close() hldr := c.GetHolder(0) - hldr.SetBit("i", "general", 10, 1) + hldr.SetBit(c.Idx(), "general", 10, 1) t.Run("no column", func(t *testing.T) { expErr := "IncludesColumn call must specify a column" - if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `IncludesColumn(Row(general=10))`}); err == nil { + if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `IncludesColumn(Row(general=10))`}); err == nil { t.Fatalf("expected to get an error") } else if !strings.Contains(err.Error(), expErr) { t.Fatalf("expected error: %s, but got: %s", expErr, err.Error()) @@ -6695,7 +6694,7 @@ func TestExecutor_Execute_IncludesColumn(t *testing.T) { t.Run("no row query", func(t *testing.T) { expErr := "IncludesColumn call must specify a row query" - if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `IncludesColumn(column=1)`}); err == nil { + if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: `IncludesColumn(column=1)`}); err == nil { t.Fatalf("expected to get an error") } else if !strings.Contains(err.Error(), expErr) { t.Fatalf("expected error: %s, but got: %s", expErr, err.Error()) @@ -6709,7 +6708,7 @@ func TestExecutor_Execute_MinMaxCountEqual(t *testing.T) { defer c.Close() hldr := c.GetHolder(0) - idx, err := hldr.CreateIndex("i", pilosa.IndexOptions{}) + idx, err := hldr.CreateIndex(c.Idx(), pilosa.IndexOptions{}) if err != nil { t.Fatal(err) } @@ -6726,7 +6725,7 @@ func TestExecutor_Execute_MinMaxCountEqual(t *testing.T) { t.Fatal(err) } - if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: ` + if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: ` Set(0, f=3) Set(1, f=3) Set(2, f=4) @@ -6765,7 +6764,7 @@ func TestExecutor_Execute_MinMaxCountEqual(t *testing.T) { } else { pql = fmt.Sprintf(`Min(%s, field=f)`, tt.filter) } - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: pql}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: pql}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual(result.Results[0], pilosa.ValCount{Val: tt.exp, Count: tt.cnt}) { t.Fatalf("unexpected result, test %d: %s", i, spew.Sdump(result)) @@ -6774,14 +6773,14 @@ func TestExecutor_Execute_MinMaxCountEqual(t *testing.T) { }) t.Run("MinNonExistent", func(t *testing.T) { pql := `Min(field=fake)` - _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: pql}) + _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: pql}) if err.Error() != "executing: executeMin: mapping on primary node: field not found" { t.Fatal(err) } }) t.Run("MaxNonExistent", func(t *testing.T) { pql := `Max(field=fake)` - _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: pql}) + _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: pql}) if err.Error() != "executing: executeMax: mapping on primary node: field not found" { t.Fatal(err) } @@ -6802,7 +6801,7 @@ func TestExecutor_Execute_MinMaxCountEqual(t *testing.T) { } else { pql = fmt.Sprintf(`Min(%s, field=dec)`, tt.filter) } - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: pql}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: pql}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual(result.Results[0], pilosa.ValCount{DecimalVal: &tt.exp, Count: tt.cnt}) { t.Fatalf("unexpected result, test %d: %s", i, spew.Sdump(result.Results[0])) @@ -6825,7 +6824,7 @@ func TestExecutor_Execute_MinMaxCountEqual(t *testing.T) { } else { pql = fmt.Sprintf(`Max(%s, field=f)`, tt.filter) } - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: pql}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: pql}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual(result.Results[0], pilosa.ValCount{Val: tt.exp, Count: tt.cnt}) { t.Fatalf("unexpected result, test %d: %s", i, spew.Sdump(result)) @@ -6849,7 +6848,7 @@ func TestExecutor_Execute_MinMaxCountEqual(t *testing.T) { } else { pql = fmt.Sprintf(`Max(%s, field=dec)`, tt.filter) } - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: pql}); err != nil { + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: pql}); err != nil { t.Fatal(err) } else if !reflect.DeepEqual(result.Results[0], pilosa.ValCount{DecimalVal: &tt.exp, Count: tt.cnt}) { t.Fatalf("unexpected result, test %d: %s", i, spew.Sdump(result.Results[0])) @@ -6860,14 +6859,14 @@ func TestExecutor_Execute_MinMaxCountEqual(t *testing.T) { t.Run("MinMaxRangeError", func(t *testing.T) { // Min pql := `Set(4, dec=-92233720368547758.08)` - if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: pql}); err == nil { + if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: pql}); err == nil { t.Fatalf("expected error but got: nil") } else if errors.Cause(err) != pilosa.ErrDecimalOutOfRange { t.Fatalf("expected error: %s, but got: %s", pilosa.ErrDecimalOutOfRange, err) } // Max pql = `Set(4, dec=92233720368547758.07)` - if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: pql}); err == nil { + if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: c.Idx(), Query: pql}); err == nil { t.Fatalf("expected error but got: nil") } else if errors.Cause(err) != pilosa.ErrDecimalOutOfRange { t.Fatalf("expected error: %s, but got: %s", pilosa.ErrDecimalOutOfRange, err) @@ -6881,14 +6880,14 @@ func TestExecutor_Execute_NoIndex(t *testing.T) { c := test.MustRunCluster(t, 1) defer c.Close() hldr := c.GetHolder(0) - index := hldr.MustCreateIndexIfNotExists("i", *indexOptions) + index := hldr.MustCreateIndexIfNotExists(c.Idx(), *indexOptions) _, err := index.CreateField("f") if err != nil { t.Fatal("should work") } if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{ - Index: "i", + Index: c.Idx(), Query: "Count(Distinct(Row(gpu_tag='GTX'), index=systems, field=jarvis_id))", }); errors.Cause(err) != pilosa.ErrIndexNotFound { t.Fatal("expecting error: 'index systems does not exist'") @@ -6896,7 +6895,9 @@ func TestExecutor_Execute_NoIndex(t *testing.T) { } func TestExecutor_Execute_CountDistinct(t *testing.T) { - data, err := os.ReadFile("testdata/schema.json") + // This schema has indexes named e, p, and s. We can then + // use c.Idx(e) or Sprintf(%e, idx) to match these names up. + data, err := ioutil.ReadFile("testdata/schema.json") if err != nil { t.Fatal(err) } @@ -6910,6 +6911,10 @@ func TestExecutor_Execute_CountDistinct(t *testing.T) { if err := json.NewDecoder(bytes.NewReader(data)).Decode(schema); err != nil { t.Fatal(err) } + // convert index names to be test-specific + for i, idx := range schema.Indexes { + schema.Indexes[i].Name = c.Idx(idx.Name) + } if err := api.ApplySchema(context.TODO(), schema, false); err != nil { t.Fatal(err) @@ -6934,22 +6939,23 @@ func TestExecutor_Execute_CountDistinct(t *testing.T) { t.Fatal(err) } } + sites := c.Idx("s") // test query - Distinct of Distincts - pql := `Distinct( + pql := fmt.Sprintf(`Distinct( Intersect( Distinct( Intersect(Row(type=AntidotePoint)), - index=equipment, field=equip_id), + index=%e, field=equip_id), Distinct( Intersect(Row(type=TwoPoints)), - index=sites, field=equip_id) - ), index=power_ts, field=site_id)` + index=%s, field=equip_id) + ), index=%t, field=site_id)`, c, c, c) // Check if test query gives correct results (one column 100) t.Run("Distinct", func(t *testing.T) { resp, err := api.Query(context.TODO(), &pilosa.QueryRequest{ - Index: "sites", + Index: sites, Query: pql, }) if err != nil { @@ -6974,7 +6980,7 @@ func TestExecutor_Execute_CountDistinct(t *testing.T) { // Check if Count on test query gives correct, exactly 1 result t.Run("Count(Distinct)", func(t *testing.T) { resp, err := api.Query(context.TODO(), &pilosa.QueryRequest{ - Index: "sites", + Index: sites, Query: fmt.Sprintf("Count(%s)", pql), }) if err != nil { @@ -6992,7 +6998,7 @@ func TestExecutor_Execute_CountDistinct(t *testing.T) { // Check if GroupBy on test query gives correct, exactly 1 result t.Run("GroupBy(Distinct)", func(t *testing.T) { resp, err := api.Query(context.TODO(), &pilosa.QueryRequest{ - Index: "sites", + Index: sites, Query: fmt.Sprintf("GroupBy(Rows(type), filter=%s)", pql), }) if err != nil { @@ -7015,14 +7021,14 @@ func TestExecutor_Execute_CountDistinct(t *testing.T) { }) t.Run("Store(Distinct)", func(t *testing.T) { _, err = api.Query(context.TODO(), &pilosa.QueryRequest{ - Index: "sites", + Index: sites, Query: `Store(Distinct(field=equip_id), type="a")`, }) if err != nil { t.Fatal(err) } resp, err := api.Query(context.TODO(), &pilosa.QueryRequest{ - Index: "sites", + Index: sites, Query: `Row(type="a")`, }) if err != nil { @@ -7038,14 +7044,14 @@ func TestExecutor_Execute_CountDistinct(t *testing.T) { } _, err = api.Query(context.TODO(), &pilosa.QueryRequest{ - Index: "sites", + Index: sites, Query: `Store(Distinct(Row(type="TwoPoints"), field=equip_id), type="b")`, }) if err != nil { t.Fatal(err) } resp, err = api.Query(context.TODO(), &pilosa.QueryRequest{ - Index: "sites", + Index: sites, Query: `Row(type="b")`, }) if err != nil { @@ -7063,7 +7069,7 @@ func TestExecutor_Execute_CountDistinct(t *testing.T) { } func variousQueriesCountDistinctTimestamp(t *testing.T, c *test.Cluster) { - index := "test_index" + index := c.Idx("tsidx") field := "ts" // create an index and timestamp field @@ -7100,28 +7106,30 @@ func TestExecutor_BareDistinct(t *testing.T) { t.Helper() c := test.MustRunCluster(t, 3) defer c.Close() + // build a name that will match %c + indexName := c.Idx("c") - c.CreateField(t, "i", pilosa.IndexOptions{}, "ints", + c.CreateField(t, indexName, pilosa.IndexOptions{}, "ints", pilosa.OptFieldTypeInt(0, math.MaxInt64), ) - c.CreateField(t, "i", pilosa.IndexOptions{}, "filter") + c.CreateField(t, indexName, pilosa.IndexOptions{}, "filter") // Populate integer data. - c.Query(t, "i", fmt.Sprintf(` + c.Query(t, indexName, fmt.Sprintf(` Set(0, ints=1) Set(%d, ints=2) `, ShardWidth)) - c.Query(t, "i", fmt.Sprintf(` + c.Query(t, indexName, fmt.Sprintf(` Set(0, filter=1) Set(%d, filter=1) `, 65537)) for _, pql := range []string{ `Distinct(field="ints")`, - `Distinct(index="i", field="ints")`, + fmt.Sprintf(`Distinct(index=%c, field="ints")`, c), } { exp := []uint64{1, 2} - res := c.Query(t, "i", pql).Results[0].(pilosa.SignedRow) + res := c.Query(t, indexName, pql).Results[0].(pilosa.SignedRow) if got := res.Pos.Columns(); !reflect.DeepEqual(exp, got) { t.Fatalf("expected: %v, but got: %v", exp, got) } @@ -7143,6 +7151,11 @@ func TestExecutor_Execute_TopNDistinct(t *testing.T) { if err := json.NewDecoder(bytes.NewReader(data)).Decode(schema); err != nil { t.Fatal(err) } + // convert index names to be test-specific + for i, idx := range schema.Indexes { + schema.Indexes[i].Name = c.Idx(idx.Name) + } + if err := api.ApplySchema(context.TODO(), schema, false); err != nil { t.Fatal(err) } @@ -7154,12 +7167,12 @@ func TestExecutor_Execute_TopNDistinct(t *testing.T) { } } - pql := `TopN(type, Distinct(Row(type=AntidotePoint), index=power_ts, field=equip_id))` + pql := fmt.Sprintf(`TopN(type, Distinct(Row(type=AntidotePoint), index=%s, field=equip_id))`, c) // Check if test query gives correct results (one column 100) t.Run("TopN", func(t *testing.T) { resp, err := api.Query(context.TODO(), &pilosa.QueryRequest{ - Index: "equipment", + Index: c.Idx("e"), Query: pql, }) if err != nil { @@ -7182,12 +7195,12 @@ func Test_Executor_Execute_UnionRows(t *testing.T) { c := test.MustRunCluster(t, 3) defer c.Close() - c.CreateField(t, "i", pilosa.IndexOptions{}, "s", + c.CreateField(t, c.Idx(), pilosa.IndexOptions{}, "s", pilosa.OptFieldTypeSet(pilosa.CacheTypeRanked, 50000), ) // Populate data. - c.Query(t, "i", ` + c.Query(t, c.Idx(), ` Set(0, s=1) Set(1, s=2) Set(2, s=3) @@ -7195,10 +7208,10 @@ func Test_Executor_Execute_UnionRows(t *testing.T) { Set(3, s=5) `) - if res := c.Query(t, "i", `Count(UnionRows(TopN(s, n=1)))`); res.Results[0] != uint64(2) { + if res := c.Query(t, c.Idx(), `Count(UnionRows(TopN(s, n=1)))`); res.Results[0] != uint64(2) { t.Errorf("expected 2 columns, got %v", res.Results[0]) } - if res := c.Query(t, "i", `Count(UnionRows(Rows(s)))`); res.Results[0] != uint64(4) { + if res := c.Query(t, c.Idx(), `Count(UnionRows(Rows(s)))`); res.Results[0] != uint64(4) { t.Errorf("expected 4 columns, got %v", res.Results[0]) } } @@ -7218,6 +7231,10 @@ func TestTimelessClearRegression(t *testing.T) { if err := json.NewDecoder(bytes.NewReader(data)).Decode(schema); err != nil { t.Fatal(err) } + // convert index names to be test-specific + for i, idx := range schema.Indexes { + schema.Indexes[i].Name = c.Idx(idx.Name) + } if err := api.ApplySchema(context.TODO(), schema, false); err != nil { t.Fatal(err) } @@ -7248,7 +7265,7 @@ func TestMissingKeyRegression(t *testing.T) { c := test.MustRunCluster(t, 1) defer c.Close() - c.CreateField(t, "i", pilosa.IndexOptions{Keys: true, TrackExistence: true}, "f", pilosa.OptFieldKeys()) + c.CreateField(t, c.Idx(), pilosa.IndexOptions{Keys: true, TrackExistence: true}, "f", pilosa.OptFieldKeys()) tests := []struct { name string @@ -7312,7 +7329,7 @@ func TestMissingKeyRegression(t *testing.T) { for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { - resp := c.Query(t, "i", tc.query) + resp := c.Query(t, c.Idx(), tc.query) if len(resp.Results) != len(tc.expected) { t.Errorf("expected %d results but got %d", len(resp.Results), len(tc.expected)) return @@ -7345,13 +7362,17 @@ func TestVariousQueries(t *testing.T) { clusterSize := clusterSize // the VariousQueries tests should be able to run in parallel with each other. t.Run(fmt.Sprintf("%d-node", clusterSize), func(t *testing.T) { + // Unshared because we want to do the backup tests against these, which means we + // don't want them to have other indexes. t.Parallel() - c := test.MustRunCluster(t, clusterSize) + c := test.MustRunUnsharedCluster(t, clusterSize) defer c.Close() // put a variety of data into the cluster populateTestData(t, c) - backupTest(t, c, usersIndex) + t.Run("backup-users", func(t *testing.T) { + backupTest(t, c, usersIndex) + }) variousQueries(t, c) variousQueriesOnTimeFields(t, c) @@ -7360,7 +7381,9 @@ func TestVariousQueries(t *testing.T) { variousQueriesOnIntFields(t, c) variousQueriesOnTimestampFields(t, c) variousQueriesOnLargeEpoch(t, c) - backupTest(t, c, "") // test backup/restore of all indexes + t.Run("backup-full", func(t *testing.T) { + backupTest(t, c, "") // test backup/restore of all indexes + }) }) } } @@ -7370,12 +7393,11 @@ func backupTest(t *testing.T, c *test.Cluster, index string) { // integration-y query tests probably shouldn't be either. My goal // putting this here is to take advantage of already-existing // clusters and data. - sum := chkSumCluster(t, c) backupDir := backupCluster(t, c, index) - cnew := test.MustRunCluster(t, 3) // this way we test 1->3 3->3 5->3 + cnew := test.MustRunUnsharedCluster(t, 3) // this way we test 1->3 3->3 5->3 defer cnew.Close() restoreCluster(t, backupDir, cnew) @@ -8946,9 +8968,11 @@ func variousSingleShardQueries(t *testing.T, clusterSize int) { c := test.MustRunCluster(t, clusterSize) defer c.Close() + ev := c.Idx("e") + // Create and populate "likenums" similar to "likes", but without keys on the field. - c.CreateField(t, "events", pilosa.IndexOptions{Keys: false, TrackExistence: true}, "lostcount", pilosa.OptFieldTypeInt(0, 1000000000)) - c.ImportIntID(t, "events", "lostcount", []test.IntID{ + c.CreateField(t, ev, pilosa.IndexOptions{Keys: false, TrackExistence: true}, "lostcount", pilosa.OptFieldTypeInt(0, 1000000000)) + c.ImportIntID(t, ev, "lostcount", []test.IntID{ {Val: 0, ID: 1}, {Val: 1, ID: 2}, {Val: 0, ID: 3}, @@ -8961,8 +8985,8 @@ func variousSingleShardQueries(t *testing.T, clusterSize int) { {Val: 0, ID: 10}, }) - c.CreateField(t, "events", pilosa.IndexOptions{Keys: false, TrackExistence: true}, "jittermax", pilosa.OptFieldTypeInt(0, 1000000000)) - c.ImportIntID(t, "events", "jittermax", []test.IntID{ + c.CreateField(t, ev, pilosa.IndexOptions{Keys: false, TrackExistence: true}, "jittermax", pilosa.OptFieldTypeInt(0, 1000000000)) + c.ImportIntID(t, ev, "jittermax", []test.IntID{ {Val: 17, ID: 1}, {Val: 3, ID: 2}, {Val: 42, ID: 3}, @@ -8991,7 +9015,7 @@ func variousSingleShardQueries(t *testing.T, clusterSize int) { for i, tst := range tests { t.Run(fmt.Sprintf("%d-%s", i, tst.query), func(t *testing.T) { - tr := c.QueryGRPC(t, "events", tst.query) + tr := c.QueryGRPC(t, ev, tst.query) csvString, err := tableResponseToCSVString(tr) if err != nil { t.Fatal(err) @@ -9001,10 +9025,8 @@ func variousSingleShardQueries(t *testing.T, clusterSize int) { if got != tst.csvVerifier { t.Errorf("expected:\n%s\ngot:\n%s", tst.csvVerifier, got) } - }) } - } // tableResponseToCSV converts a generic TableResponse to a CSV format @@ -9196,8 +9218,8 @@ func TestExternalLookup(t *testing.T) { defer c.Close() // Populate a field with some data that can be used in queries. - c.CreateField(t, "i", pilosa.IndexOptions{TrackExistence: true}, "f") - c.ImportBits(t, "i", "f", [][2]uint64{ + c.CreateField(t, c.Idx(), pilosa.IndexOptions{TrackExistence: true}, "f") + c.ImportBits(t, c.Idx(), "f", [][2]uint64{ {1, 1}, {1, 3}, {2, 2}, @@ -9329,7 +9351,7 @@ func TestExternalLookup(t *testing.T) { t.Run(tc.name, func(t *testing.T) { t.Parallel() - result := c.Query(t, "i", tc.query) + result := c.Query(t, c.Idx(), tc.query) if !reflect.DeepEqual(result, tc.expect) { t.Errorf("expected %v but got %v", tc.expect, result) } @@ -9337,8 +9359,8 @@ func TestExternalLookup(t *testing.T) { } }) t.Run("Delete", func(t *testing.T) { - c.Query(t, "i", `ExternalLookup(All(), query="delete from lookup where id = ANY($1)", write=true)`) - res := c.Query(t, "i", `ExternalLookup(All(), query="select id from lookup where id = ANY($1)")`) + c.Query(t, c.Idx(), `ExternalLookup(All(), query="delete from lookup where id = ANY($1)", write=true)`) + res := c.Query(t, c.Idx(), `ExternalLookup(All(), query="select id from lookup where id = ANY($1)")`) tbl := res.Results[0].(pilosa.ExtractedTable) if len(tbl.Columns) != 0 { t.Errorf("unexpected remaining records: %v", tbl) @@ -9472,10 +9494,10 @@ func TestMinMaxTimestampVariableNode(t *testing.T) { // timestamp values on a cluster with `numNodes` nodes. // fails if the min or max values are not correct func MinMaxTimestampNodeTester(t *testing.T, numNodes int) { - index := "test_index" - field := "ts" c := test.MustRunCluster(t, numNodes) defer c.Close() + index := c.Idx("tsidx") + field := "ts" // create an index and timestamp field c.CreateField(t, index, pilosa.IndexOptions{TrackExistence: true}, field, pilosa.OptFieldTypeTimestamp(time.Unix(0, 0), "s")) @@ -9565,16 +9587,16 @@ func TestExecutor_Execute_ExtractWithTime(t *testing.T) { } c := test.MustRunCluster(t, 1) defer c.Close() - c.CreateField(t, "i", pilosa.IndexOptions{Keys: true, TrackExistence: true}, "segment", pilosa.OptFieldKeys(), pilosa.OptFieldTypeTime(pilosa.TimeQuantum("D"), "0")) - c.ImportTimeQuantumKey(t, "i", "segment", []test.TimeQuantumKey{ + c.CreateField(t, c.Idx(), pilosa.IndexOptions{Keys: true, TrackExistence: true}, "segment", pilosa.OptFieldKeys(), pilosa.OptFieldTypeTime(pilosa.TimeQuantum("D"), "0")) + c.ImportTimeQuantumKey(t, c.Idx(), "segment", []test.TimeQuantumKey{ // from edge cases {ColKey: "C1", RowKey: "R1", Ts: ts(time.Date(2022, 7, 1, 0, 0, 0, 0, time.UTC))}, {ColKey: "C2", RowKey: "R1", Ts: ts(time.Date(2022, 7, 3, 0, 0, 0, 0, time.UTC))}, }) t.Run("Extract With From Time", func(t *testing.T) { - resp := c.Query(t, "i", "Extract(All(), Rows(segment,from=2022-07-03T00:00))") - //resp := c.Query(t, "i", "Extract(All(), Rows(segment, from=))") + resp := c.Query(t, c.Idx(), "Extract(All(), Rows(segment,from=2022-07-03T00:00))") + //resp := c.Query(t, c.Idx(), "Extract(All(), Rows(segment, from=))") if len(resp.Results) != 1 { t.Fatalf("expected 1 result but got %d", len(resp.Results)) } @@ -9606,8 +9628,8 @@ func TestExecutor_Execute_ExtractWithTime(t *testing.T) { } }) t.Run("Extract With Time No Opt", func(t *testing.T) { - resp := c.Query(t, "i", "Extract(All(), Rows(segment))") - //resp := c.Query(t, "i", "Extract(All(), Rows(segment, from=))") + resp := c.Query(t, c.Idx(), "Extract(All(), Rows(segment))") + //resp := c.Query(t, c.Idx(), "Extract(All(), Rows(segment, from=))") if len(resp.Results) != 1 { t.Fatalf("expected 1 result but got %d", len(resp.Results)) } @@ -9640,8 +9662,8 @@ func TestExecutor_Execute_ExtractWithTime(t *testing.T) { }) t.Run("Extract With ToTime ", func(t *testing.T) { - resp := c.Query(t, "i", "Extract(All(), Rows(segment,to=2022-07-02T00:00))") - //resp := c.Query(t, "i", "Extract(All(), Rows(segment, from=))") + resp := c.Query(t, c.Idx(), "Extract(All(), Rows(segment,to=2022-07-02T00:00))") + //resp := c.Query(t, c.Idx(), "Extract(All(), Rows(segment, from=))") if len(resp.Results) != 1 { t.Fatalf("expected 1 result but got %d", len(resp.Results)) } @@ -9676,10 +9698,7 @@ func TestExecutor_Execute_ExtractWithTime(t *testing.T) { func TestExecutorTimeRange(t *testing.T) { c := test.MustRunCluster(t, 1) - defer func() { - t.Logf("TestTimeRange: closing cluster") - c.Close() - }() + defer c.Close() // test error path - field is a not a time field, from/to options not allowed in query t.Run("Field not a time field", func(t *testing.T) { @@ -9691,7 +9710,7 @@ func TestExecutorTimeRange(t *testing.T) { `Row(f=1, from=1999-12-31T00:00)`, `Row(f=1, to=2002-01-01T02:00)`, } - indexName := fmt.Sprintf("i_%x", md5.Sum([]byte(t.Name()))) + indexName := c.Idx(t.Name()) hldr := c.GetHolder(0) index, err := hldr.CreateIndex(indexName, pilosa.IndexOptions{}) if err != nil { diff --git a/holder_test.go b/holder_test.go index a827ba39c..1e962d739 100644 --- a/holder_test.go +++ b/holder_test.go @@ -218,7 +218,7 @@ func TestHolder_DeleteIndex(t *testing.T) { // Ensure holder can sync with a remote holder. func TestHolderSyncer_SyncHolder(t *testing.T) { - c := test.MustNewCluster(t, 2) + c := test.MustUnsharedCluster(t, 2) c.GetIdleNode(0).Config.Cluster.ReplicaN = 2 c.GetIdleNode(0).Config.AntiEntropy.Interval = 0 c.GetIdleNode(1).Config.Cluster.ReplicaN = 2 @@ -230,27 +230,27 @@ func TestHolderSyncer_SyncHolder(t *testing.T) { } defer c.Close() - _, err = c.GetNode(0).API.CreateIndex(context.Background(), "i", pilosa.IndexOptions{}) + _, err = c.GetNode(0).API.CreateIndex(context.Background(), c.Idx(), pilosa.IndexOptions{}) if err != nil { t.Fatalf("creating index i: %v", err) } - _, err = c.GetNode(0).API.CreateIndex(context.Background(), "y", pilosa.IndexOptions{}) + _, err = c.GetNode(0).API.CreateIndex(context.Background(), c.Idx("y"), pilosa.IndexOptions{}) if err != nil { t.Fatalf("creating index y: %v", err) } - _, err = c.GetNode(0).API.CreateField(context.Background(), "i", "f", pilosa.OptFieldTypeSet(pilosa.DefaultCacheType, pilosa.DefaultCacheSize)) + _, err = c.GetNode(0).API.CreateField(context.Background(), c.Idx(), "f", pilosa.OptFieldTypeSet(pilosa.DefaultCacheType, pilosa.DefaultCacheSize)) if err != nil { t.Fatalf("creating field f: %v", err) } - _, err = c.GetNode(0).API.CreateField(context.Background(), "i", "f0", pilosa.OptFieldTypeSet(pilosa.DefaultCacheType, pilosa.DefaultCacheSize)) + _, err = c.GetNode(0).API.CreateField(context.Background(), c.Idx(), "f0", pilosa.OptFieldTypeSet(pilosa.DefaultCacheType, pilosa.DefaultCacheSize)) if err != nil { t.Fatalf("creating field f0: %v", err) } - _, err = c.GetNode(0).API.CreateField(context.Background(), "y", "z", pilosa.OptFieldTypeMutex(pilosa.DefaultCacheType, pilosa.DefaultCacheSize)) + _, err = c.GetNode(0).API.CreateField(context.Background(), c.Idx("y"), "z", pilosa.OptFieldTypeMutex(pilosa.DefaultCacheType, pilosa.DefaultCacheSize)) if err != nil { t.Fatalf("creating field z in y: %v", err) } - _, err = c.GetNode(0).API.CreateField(context.Background(), "y", "b", pilosa.OptFieldTypeBool()) + _, err = c.GetNode(0).API.CreateField(context.Background(), c.Idx("y"), "b", pilosa.OptFieldTypeBool()) if err != nil { t.Fatalf("creating field b in y: %v", err) } @@ -259,29 +259,29 @@ func TestHolderSyncer_SyncHolder(t *testing.T) { hldr1 := &test.Holder{Holder: c.GetNode(1).Server.Holder()} // Set data on the local holder. - hldr0.SetBit("i", "f", 0, 10) - hldr0.SetBit("i", "f", 2, 20) - hldr0.SetBit("i", "f", 120, 10) - hldr0.SetBit("i", "f", 200, 4) + hldr0.SetBit(c.Idx(), "f", 0, 10) + hldr0.SetBit(c.Idx(), "f", 2, 20) + hldr0.SetBit(c.Idx(), "f", 120, 10) + hldr0.SetBit(c.Idx(), "f", 200, 4) - hldr0.SetBit("i", "f0", 9, ShardWidth+5) + hldr0.SetBit(c.Idx(), "f0", 9, ShardWidth+5) // Set a bit to create the fragment. - hldr0.SetBit("y", "z", 0, 0) - hldr0.SetBit("y", "b", 0, 0) // rowID = 0 means false + hldr0.SetBit(c.Idx("y"), "z", 0, 0) + hldr0.SetBit(c.Idx("y"), "b", 0, 0) // rowID = 0 means false // Set data on the remote holder. - hldr1.SetBit("i", "f", 0, 4000) - hldr1.SetBit("i", "f", 3, 10) - hldr1.SetBit("i", "f", 120, 10) + hldr1.SetBit(c.Idx(), "f", 0, 4000) + hldr1.SetBit(c.Idx(), "f", 3, 10) + hldr1.SetBit(c.Idx(), "f", 120, 10) - hldr1.SetBit("y", "z", 10, (3*ShardWidth)+4) - hldr1.SetBit("y", "z", 10, (3*ShardWidth)+5) - hldr1.SetBit("y", "z", 10, (3*ShardWidth)+7) + hldr1.SetBit(c.Idx("y"), "z", 10, (3*ShardWidth)+4) + hldr1.SetBit(c.Idx("y"), "z", 10, (3*ShardWidth)+5) + hldr1.SetBit(c.Idx("y"), "z", 10, (3*ShardWidth)+7) - hldr1.SetBit("y", "b", 1, (3*ShardWidth)+4) // true - hldr1.SetBit("y", "b", 0, (3*ShardWidth)+5) // false - hldr1.SetBit("y", "b", 1, (3*ShardWidth)+7) // true + hldr1.SetBit(c.Idx("y"), "b", 1, (3*ShardWidth)+4) // true + hldr1.SetBit(c.Idx("y"), "b", 0, (3*ShardWidth)+5) // false + hldr1.SetBit(c.Idx("y"), "b", 1, (3*ShardWidth)+7) // true err = c.GetNode(0).Server.SyncData() if err != nil { @@ -294,34 +294,34 @@ func TestHolderSyncer_SyncHolder(t *testing.T) { // Verify data is the same on both nodes. for i, hldr := range []*test.Holder{hldr0, hldr1} { - if a := hldr.Row("i", "f", 0).Columns(); !reflect.DeepEqual(a, []uint64{10, 4000}) { + if a := hldr.Row(c.Idx(), "f", 0).Columns(); !reflect.DeepEqual(a, []uint64{10, 4000}) { t.Errorf("unexpected columns(%d/0): %+v", i, a) } - if a := hldr.Row("i", "f", 2).Columns(); !reflect.DeepEqual(a, []uint64{20}) { + if a := hldr.Row(c.Idx(), "f", 2).Columns(); !reflect.DeepEqual(a, []uint64{20}) { t.Errorf("unexpected columns(%d/2): %+v", i, a) } - if a := hldr.Row("i", "f", 3).Columns(); !reflect.DeepEqual(a, []uint64{10}) { + if a := hldr.Row(c.Idx(), "f", 3).Columns(); !reflect.DeepEqual(a, []uint64{10}) { t.Errorf("unexpected columns(%d/3): %+v", i, a) } - if a := hldr.Row("i", "f", 120).Columns(); !reflect.DeepEqual(a, []uint64{10}) { + if a := hldr.Row(c.Idx(), "f", 120).Columns(); !reflect.DeepEqual(a, []uint64{10}) { t.Errorf("unexpected columns(%d/120): %+v", i, a) } - if a := hldr.Row("i", "f", 200).Columns(); !reflect.DeepEqual(a, []uint64{4}) { + if a := hldr.Row(c.Idx(), "f", 200).Columns(); !reflect.DeepEqual(a, []uint64{4}) { t.Errorf("unexpected columns(%d/200): %+v", i, a) } - if a := hldr.Row("i", "f0", 9).Columns(); !reflect.DeepEqual(a, []uint64{ShardWidth + 5}) { + if a := hldr.Row(c.Idx(), "f0", 9).Columns(); !reflect.DeepEqual(a, []uint64{ShardWidth + 5}) { t.Errorf("unexpected columns(%d/d/f0): %+v", i, a) } - if a := hldr.Row("y", "z", 10).Columns(); !reflect.DeepEqual(a, []uint64{(3 * ShardWidth) + 4, (3 * ShardWidth) + 5, (3 * ShardWidth) + 7}) { + if a := hldr.Row(c.Idx("y"), "z", 10).Columns(); !reflect.DeepEqual(a, []uint64{(3 * ShardWidth) + 4, (3 * ShardWidth) + 5, (3 * ShardWidth) + 7}) { t.Errorf("unexpected columns(%d/y/z): %+v", i, a) } - if a := hldr.Row("y", "b", 0).Columns(); !reflect.DeepEqual(a, []uint64{0, (3 * ShardWidth) + 5}) { + if a := hldr.Row(c.Idx("y"), "b", 0).Columns(); !reflect.DeepEqual(a, []uint64{0, (3 * ShardWidth) + 5}) { t.Errorf("unexpected false columns(%d/y/b): %+v", i, a) } - if a := hldr.Row("y", "b", 1).Columns(); !reflect.DeepEqual(a, []uint64{(3 * ShardWidth) + 4, (3 * ShardWidth) + 7}) { + if a := hldr.Row(c.Idx("y"), "b", 1).Columns(); !reflect.DeepEqual(a, []uint64{(3 * ShardWidth) + 4, (3 * ShardWidth) + 7}) { t.Errorf("unexpected true columns(%d/y/b): %+v", i, a) } } @@ -330,7 +330,7 @@ func TestHolderSyncer_SyncHolder(t *testing.T) { // Ensure holder can sync with a remote holder and respects // the row boundaries of the block. func TestHolderSyncer_BlockIteratorLimits(t *testing.T) { - c := test.MustNewCluster(t, 3) + c := test.MustUnsharedCluster(t, 3) c.GetIdleNode(0).Config.Cluster.ReplicaN = 3 c.GetIdleNode(0).Config.AntiEntropy.Interval = 0 c.GetIdleNode(1).Config.Cluster.ReplicaN = 3 @@ -343,11 +343,11 @@ func TestHolderSyncer_BlockIteratorLimits(t *testing.T) { } defer c.Close() - _, err = c.GetNode(0).API.CreateIndex(context.Background(), "i", pilosa.IndexOptions{}) + _, err = c.GetNode(0).API.CreateIndex(context.Background(), c.Idx(), pilosa.IndexOptions{}) if err != nil { t.Fatalf("creating index i: %v", err) } - _, err = c.GetNode(0).API.CreateField(context.Background(), "i", "f", pilosa.OptFieldTypeSet(pilosa.DefaultCacheType, pilosa.DefaultCacheSize)) + _, err = c.GetNode(0).API.CreateField(context.Background(), c.Idx(), "f", pilosa.OptFieldTypeSet(pilosa.DefaultCacheType, pilosa.DefaultCacheSize)) if err != nil { t.Fatalf("creating field f: %v", err) } @@ -359,13 +359,13 @@ func TestHolderSyncer_BlockIteratorLimits(t *testing.T) { hldr2 := &test.Holder{Holder: c.GetNode(2).Server.Holder()} // Set data on the local holder. - hldr0.SetBit("i", "f", blockEdge-1, 10) - hldr0.SetBit("i", "f", blockEdge, 20) + hldr0.SetBit(c.Idx(), "f", blockEdge-1, 10) + hldr0.SetBit(c.Idx(), "f", blockEdge, 20) // Set the same data on one of the replicas // so that we have a quorum. - hldr1.SetBit("i", "f", blockEdge-1, 10) - hldr1.SetBit("i", "f", blockEdge, 20) + hldr1.SetBit(c.Idx(), "f", blockEdge-1, 10) + hldr1.SetBit(c.Idx(), "f", blockEdge, 20) // Leave the third replica empty to force a block merge. // @@ -376,10 +376,10 @@ func TestHolderSyncer_BlockIteratorLimits(t *testing.T) { // Verify data is the same on all nodes. for i, hldr := range []*test.Holder{hldr0, hldr1, hldr2} { - if a := hldr.Row("i", "f", blockEdge-1).Columns(); !reflect.DeepEqual(a, []uint64{10}) { + if a := hldr.Row(c.Idx(), "f", blockEdge-1).Columns(); !reflect.DeepEqual(a, []uint64{10}) { t.Errorf("unexpected columns(%d/block 0): %+v", i, a) } - if a := hldr.Row("i", "f", blockEdge).Columns(); !reflect.DeepEqual(a, []uint64{20}) { + if a := hldr.Row(c.Idx(), "f", blockEdge).Columns(); !reflect.DeepEqual(a, []uint64{20}) { t.Errorf("unexpected columns(%d/block 1): %+v", i, a) } } @@ -387,7 +387,7 @@ func TestHolderSyncer_BlockIteratorLimits(t *testing.T) { // Ensure holder correctly handles clears during block sync. func TestHolderSyncer_Clears(t *testing.T) { - c := test.MustNewCluster(t, 3) + c := test.MustUnsharedCluster(t, 3) c.GetIdleNode(0).Config.Cluster.ReplicaN = 3 c.GetIdleNode(0).Config.AntiEntropy.Interval = 0 c.GetIdleNode(1).Config.Cluster.ReplicaN = 3 @@ -400,11 +400,11 @@ func TestHolderSyncer_Clears(t *testing.T) { } defer c.Close() - _, err = c.GetNode(0).API.CreateIndex(context.Background(), "i", pilosa.IndexOptions{}) + _, err = c.GetNode(0).API.CreateIndex(context.Background(), c.Idx(), pilosa.IndexOptions{}) if err != nil { t.Fatalf("creating index i: %v", err) } - _, err = c.GetNode(0).API.CreateField(context.Background(), "i", "f", pilosa.OptFieldTypeSet(pilosa.DefaultCacheType, pilosa.DefaultCacheSize)) + _, err = c.GetNode(0).API.CreateField(context.Background(), c.Idx(), "f", pilosa.OptFieldTypeSet(pilosa.DefaultCacheType, pilosa.DefaultCacheSize)) if err != nil { t.Fatalf("creating field f: %v", err) } @@ -415,13 +415,13 @@ func TestHolderSyncer_Clears(t *testing.T) { // Set data on the local holder that should be cleared // because it's the only instance of this value. - hldr0.SetBit("i", "f", 0, 30) + hldr0.SetBit(c.Idx(), "f", 0, 30) // Set similar data on the replicas, but // different from what's on local. This should end // up being set on all replicas - hldr1.SetBit("i", "f", 0, 20) - hldr2.SetBit("i", "f", 0, 20) + hldr1.SetBit(c.Idx(), "f", 0, 20) + hldr2.SetBit(c.Idx(), "f", 0, 20) err = c.GetNode(0).Server.SyncData() if err != nil { @@ -430,7 +430,7 @@ func TestHolderSyncer_Clears(t *testing.T) { // Verify data is the same on all nodes. for i, hldr := range []*test.Holder{hldr0, hldr1, hldr2} { - if a := hldr.Row("i", "f", 0).Columns(); !reflect.DeepEqual(a, []uint64{20}) { + if a := hldr.Row(c.Idx(), "f", 0).Columns(); !reflect.DeepEqual(a, []uint64{20}) { t.Errorf("unexpected columns(%d): %+v", i, a) } } @@ -438,7 +438,7 @@ func TestHolderSyncer_Clears(t *testing.T) { // Ensure holder can sync time quantum views with a remote holder. func TestHolderSyncer_TimeQuantum(t *testing.T) { - c := test.MustNewCluster(t, 2) + c := test.MustUnsharedCluster(t, 2) c.GetIdleNode(0).Config.Cluster.ReplicaN = 2 c.GetIdleNode(0).Config.AntiEntropy.Interval = 0 c.GetIdleNode(1).Config.Cluster.ReplicaN = 2 @@ -451,11 +451,11 @@ func TestHolderSyncer_TimeQuantum(t *testing.T) { quantum := "D" - _, err = c.GetNode(0).API.CreateIndex(context.Background(), "i", pilosa.IndexOptions{}) + _, err = c.GetNode(0).API.CreateIndex(context.Background(), c.Idx(), pilosa.IndexOptions{}) if err != nil { t.Fatalf("creating index i: %v", err) } - _, err = c.GetNode(0).API.CreateField(context.Background(), "i", "f", pilosa.OptFieldTypeTime(pilosa.TimeQuantum(quantum), "0")) + _, err = c.GetNode(0).API.CreateField(context.Background(), c.Idx(), "f", pilosa.OptFieldTypeTime(pilosa.TimeQuantum(quantum), "0")) if err != nil { t.Fatalf("creating field f: %v", err) } @@ -466,11 +466,11 @@ func TestHolderSyncer_TimeQuantum(t *testing.T) { // Set data on the local holder for node0. t1 := time.Date(2018, 8, 1, 12, 30, 0, 0, time.UTC) t2 := time.Date(2018, 8, 2, 12, 30, 0, 0, time.UTC) - hldr0.SetBitTime("i", "f", 0, 1, &t1) - hldr0.SetBitTime("i", "f", 0, 2, &t2) + hldr0.SetBitTime(c.Idx(), "f", 0, 1, &t1) + hldr0.SetBitTime(c.Idx(), "f", 0, 2, &t2) // Set data on node1. - hldr1.SetBitTime("i", "f", 0, 22, &t2) + hldr1.SetBitTime(c.Idx(), "f", 0, 22, &t2) err = c.GetNode(0).Server.SyncData() if err != nil { @@ -479,10 +479,10 @@ func TestHolderSyncer_TimeQuantum(t *testing.T) { // Verify data is the same on both nodes. for i, hldr := range []*test.Holder{hldr0, hldr1} { - if a := hldr.RowTime("i", "f", 0, t1, quantum).Columns(); !reflect.DeepEqual(a, []uint64{1}) { + if a := hldr.RowTime(c.Idx(), "f", 0, t1, quantum).Columns(); !reflect.DeepEqual(a, []uint64{1}) { t.Errorf("unexpected columns(%d/0): %+v", i, a) } - if a := hldr.RowTime("i", "f", 0, t2, quantum).Columns(); !reflect.DeepEqual(a, []uint64{2, 22}) { + if a := hldr.RowTime(c.Idx(), "f", 0, t2, quantum).Columns(); !reflect.DeepEqual(a, []uint64{2, 22}) { t.Errorf("unexpected columns(%d/0): %+v", i, a) } } @@ -491,7 +491,7 @@ func TestHolderSyncer_TimeQuantum(t *testing.T) { // Ensure holder can sync integer views with a remote holder. func TestHolderSyncer_IntField(t *testing.T) { t.Run("BasicSync", func(t *testing.T) { - c := test.MustNewCluster(t, 2) + c := test.MustUnsharedCluster(t, 2) c.GetIdleNode(0).Config.Cluster.ReplicaN = 2 c.GetIdleNode(0).Config.AntiEntropy.Interval = 0 c.GetIdleNode(1).Config.Cluster.ReplicaN = 2 @@ -503,12 +503,12 @@ func TestHolderSyncer_IntField(t *testing.T) { defer c.Close() var idx0 *pilosa.Index - idx0, err = c.GetNode(0).API.CreateIndex(context.Background(), "i", pilosa.IndexOptions{}) + idx0, err = c.GetNode(0).API.CreateIndex(context.Background(), c.Idx(), pilosa.IndexOptions{}) _ = idx0 if err != nil { t.Fatalf("creating index i: %v", err) } - _, err = c.GetNode(0).API.CreateField(context.Background(), "i", "f", pilosa.OptFieldTypeInt(0, 100)) + _, err = c.GetNode(0).API.CreateField(context.Background(), c.Idx(), "f", pilosa.OptFieldTypeInt(0, 100)) if err != nil { t.Fatalf("creating field f: %v", err) } @@ -517,12 +517,12 @@ func TestHolderSyncer_IntField(t *testing.T) { hldr1 := &test.Holder{Holder: c.GetNode(1).Server.Holder()} // Set data on the local holder for node0. columnID=1, value=1 - hldr0.SetValue("i", "f", 1, 1) + hldr0.SetValue(c.Idx(), "f", 1, 1) // in c0 expect the 1 bit // Set data on node1. columnID=2, value=2 - idx1 := hldr1.SetValue("i", "f", 2, 2) + idx1 := hldr1.SetValue(c.Idx(), "f", 2, 2) _ = idx1 err = c.GetNode(0).Server.SyncData() @@ -537,11 +537,11 @@ func TestHolderSyncer_IntField(t *testing.T) { // Verify data is the same on both nodes. for i, hldr := range []*test.Holder{hldr0, hldr1} { - if a, exists := hldr.Value("i", "f", 1); !exists || a != 1 { + if a, exists := hldr.Value(c.Idx(), "f", 1); !exists || a != 1 { // expects exists==true, a==1 t.Errorf("unexpected value(node%d/0): a:%d, exists: %v", i, a, exists) } - if a, exists := hldr.Value("i", "f", 2); exists { + if a, exists := hldr.Value(c.Idx(), "f", 2); exists { t.Errorf("unexpected value(node%d/1): a:%d, exists: %v", i, a, exists) } } @@ -549,7 +549,7 @@ func TestHolderSyncer_IntField(t *testing.T) { t.Run("MultiShard", func(t *testing.T) { t.Skip() // skipping due to changed partitioning strategy - c := test.MustNewCluster(t, 2) + c := test.MustUnsharedCluster(t, 2) c.GetIdleNode(0).Config.Cluster.ReplicaN = 2 c.GetIdleNode(0).Config.AntiEntropy.Interval = 0 c.GetIdleNode(1).Config.Cluster.ReplicaN = 2 @@ -562,12 +562,12 @@ func TestHolderSyncer_IntField(t *testing.T) { var idx0 *pilosa.Index _ = idx0 - idx0, err = c.GetNode(0).API.CreateIndex(context.Background(), "i", pilosa.IndexOptions{}) + idx0, err = c.GetNode(0).API.CreateIndex(context.Background(), c.Idx(), pilosa.IndexOptions{}) _ = idx0 if err != nil { t.Fatalf("creating index i: %v", err) } - _, err = c.GetNode(0).API.CreateField(context.Background(), "i", "f", pilosa.OptFieldTypeInt(math.MinInt64, math.MaxInt64)) + _, err = c.GetNode(0).API.CreateField(context.Background(), c.Idx(), "f", pilosa.OptFieldTypeInt(math.MinInt64, math.MaxInt64)) if err != nil { t.Fatalf("creating field f: %v", err) } @@ -576,18 +576,18 @@ func TestHolderSyncer_IntField(t *testing.T) { hldr1 := &test.Holder{Holder: c.GetNode(1).Server.Holder()} // Set data on the local holder for node0. - hldr0.SetValue("i", "f", 1*pilosa.ShardWidth, 11) - hldr0.SetValue("i", "f", 3*pilosa.ShardWidth, 32) - hldr0.SetValue("i", "f", 4*pilosa.ShardWidth, math.MinInt32) - hldr0.SetValue("i", "f", 7*pilosa.ShardWidth, math.MinInt32) + hldr0.SetValue(c.Idx(), "f", 1*pilosa.ShardWidth, 11) + hldr0.SetValue(c.Idx(), "f", 3*pilosa.ShardWidth, 32) + hldr0.SetValue(c.Idx(), "f", 4*pilosa.ShardWidth, math.MinInt32) + hldr0.SetValue(c.Idx(), "f", 7*pilosa.ShardWidth, math.MinInt32) // Set data on node1. - hldr1.SetValue("i", "f", 0*pilosa.ShardWidth, 2) - hldr1.SetValue("i", "f", 2*pilosa.ShardWidth, 22) - hldr1.SetValue("i", "f", 4*pilosa.ShardWidth, math.MaxInt32) - hldr1.SetValue("i", "f", 7*pilosa.ShardWidth, math.MaxInt32) + hldr1.SetValue(c.Idx(), "f", 0*pilosa.ShardWidth, 2) + hldr1.SetValue(c.Idx(), "f", 2*pilosa.ShardWidth, 22) + hldr1.SetValue(c.Idx(), "f", 4*pilosa.ShardWidth, math.MaxInt32) + hldr1.SetValue(c.Idx(), "f", 7*pilosa.ShardWidth, math.MaxInt32) - // Primary for shards (for index "i"): + // Primary for shards (for index c.Idx()): // node0: [0,3,7] // node1: [1,2,4] @@ -604,10 +604,10 @@ func TestHolderSyncer_IntField(t *testing.T) { // Verify data is the same on both nodes. for i, hldr := range []*test.Holder{hldr0, hldr1} { - if a := hldr.Range("i", "f", pql.GT, 0); !reflect.DeepEqual(a.Columns(), []uint64{2 * pilosa.ShardWidth, 3 * pilosa.ShardWidth, 4 * pilosa.ShardWidth}) { + if a := hldr.Range(c.Idx(), "f", pql.GT, 0); !reflect.DeepEqual(a.Columns(), []uint64{2 * pilosa.ShardWidth, 3 * pilosa.ShardWidth, 4 * pilosa.ShardWidth}) { t.Errorf("unexpected columns(node%d/0): %d", i, a.Columns()) } - if a := hldr.Range("i", "f", pql.LT, 0); !reflect.DeepEqual(a.Columns(), []uint64{7 * pilosa.ShardWidth}) { + if a := hldr.Range(c.Idx(), "f", pql.LT, 0); !reflect.DeepEqual(a.Columns(), []uint64{7 * pilosa.ShardWidth}) { t.Errorf("unexpected columns(node%d/0): %d", i, a.Columns()) } } diff --git a/http_handler_test.go b/http_handler_test.go index eb7d9f4b6..6a055cacf 100644 --- a/http_handler_test.go +++ b/http_handler_test.go @@ -173,10 +173,11 @@ func TestUpdateFieldTTL(t *testing.T) { }, } + indexName := c.Idx("s") for i, test := range tests { t.Run(test.name, func(t *testing.T) { - c.CreateField(t, "ttltest", pilosa.IndexOptions{}, test.name, pilosa.OptFieldTypeTime(pilosa.TimeQuantum("YMD"), test.ttl)) - nodeURL := c.Nodes[0].URL() + "/index/ttltest/field/" + test.field + c.CreateField(t, indexName, pilosa.IndexOptions{}, test.name, pilosa.OptFieldTypeTime(pilosa.TimeQuantum("YMD"), test.ttl)) + nodeURL := fmt.Sprintf("%s/index/%s/field/%s", c.Nodes[0].URL(), c, test.field) req, err := gohttp.NewRequest("PATCH", nodeURL, strings.NewReader(test.ttlOption)) if err != nil { t.Fatal(err) @@ -215,12 +216,21 @@ func TestUpdateFieldTTL(t *testing.T) { if err != nil { t.Fatalf("getting schema: %v", err) } - if ii[0].Fields[i].Name == test.name { - if ii[0].Fields[i].Options.TTL != test.expTTL { - t.Errorf("expected TTL: '%s', got: '%s'", test.expTTL, ii[0].Fields[i].Options.TTL) + for _, idx := range ii { + if idx.Name == indexName { + if len(idx.Fields) <= i { + t.Fatalf("expected %d fields, last %s, got %d fields", + i, test.name, len(idx.Fields)) + } + if idx.Fields[i].Name == test.name { + if idx.Fields[i].Options.TTL != test.expTTL { + t.Errorf("expected noStandardView value: '%s', got: '%s'", test.expTTL, idx.Fields[i].Options.TTL) + } + } else { + t.Errorf("unexpected field: '%s', got: '%s'", test.name, idx.Fields[i].Name) + } + break } - } else { - t.Errorf("unexpected field: '%s', got: '%s'", test.name, ii[0].Fields[i].Name) } } @@ -278,11 +288,13 @@ func TestUpdateFieldNoStandardView(t *testing.T) { expNoStandardView: false, }, } + // "s" to make it match %s behavior of a cluster + indexName := c.Idx("s") for i, test := range tests { t.Run(test.name, func(t *testing.T) { - c.CreateField(t, "ttltest", pilosa.IndexOptions{}, test.name, pilosa.OptFieldTypeTime(pilosa.TimeQuantum("YMD"), "0")) - nodeURL := c.Nodes[0].URL() + "/index/ttltest/field/" + test.field + c.CreateField(t, indexName, pilosa.IndexOptions{}, test.name, pilosa.OptFieldTypeTime(pilosa.TimeQuantum("YMD"), "0")) + nodeURL := fmt.Sprintf("%s/index/%s/field/%s", c.Nodes[0].URL(), c, test.field) req, err := gohttp.NewRequest("PATCH", nodeURL, strings.NewReader(test.fieldOption)) if err != nil { t.Fatal(err) @@ -317,33 +329,34 @@ func TestUpdateFieldNoStandardView(t *testing.T) { if err != nil { t.Fatalf("getting schema: %v", err) } - if ii[0].Fields[i].Name == test.name { - if ii[0].Fields[i].Options.NoStandardView != test.expNoStandardView { - t.Errorf("expected noStandardView value: '%t', got: '%t'", test.expNoStandardView, ii[0].Fields[i].Options.NoStandardView) + for _, idx := range ii { + if idx.Name == indexName { + if len(idx.Fields) <= i { + t.Fatalf("expected %d fields, last %s, got %d fields", + i, test.name, len(idx.Fields)) + } + if idx.Fields[i].Name == test.name { + if idx.Fields[i].Options.NoStandardView != test.expNoStandardView { + t.Errorf("expected noStandardView value: '%t', got: '%t'", test.expNoStandardView, idx.Fields[i].Options.NoStandardView) + } + } else { + t.Errorf("unexpected field: '%s', got: '%s'", test.name, idx.Fields[i].Name) + } + break } - } else { - t.Errorf("unexpected field: '%s', got: '%s'", test.name, ii[0].Fields[i].Name) } } - }) } } func TestIngestSchemaHandler(t *testing.T) { - c := test.MustRunCluster(t, 3, - []server.CommandOption{ - server.OptCommandServerOptions(pilosa.OptServerNodeID("node0"), pilosa.OptServerClusterHasher(&test.ModHasher{}))}, - []server.CommandOption{ - server.OptCommandServerOptions(pilosa.OptServerNodeID("node1"), pilosa.OptServerClusterHasher(&test.ModHasher{}))}, - []server.CommandOption{ - server.OptCommandServerOptions(pilosa.OptServerNodeID("node2"), pilosa.OptServerClusterHasher(&test.ModHasher{}))}, - ) + c := test.MustRunCluster(t, 3) defer c.Close() - schema := ` + schema := fmt.Sprintf(` { - "index-name": "example", + "index-name": "%s", "primary-key-type": "string", "index-action": "create", "fields": [ @@ -408,7 +421,7 @@ func TestIngestSchemaHandler(t *testing.T) { } ] } -` +`, c) m := c.GetPrimary() schemaURL := fmt.Sprintf("%s/internal/schema", m.URL()) resp := test.Do(t, "POST", schemaURL, string(schema)) @@ -425,15 +438,16 @@ func TestIngestSchemaHandler(t *testing.T) { func TestPostFieldWithTTL(t *testing.T) { c := test.MustRunCluster(t, 1) defer c.Close() + indexName := c.Idx("%s") - schema := ` + schema := fmt.Sprintf(` { - "index-name": "ttl_test", + "index-name": "%s", "primary-key-type": "string", "index-action": "create", "fields":[] } - ` + `, c) m := c.GetPrimary() schemaURL := fmt.Sprintf("%s/internal/schema", m.URL()) resp := test.Do(t, "POST", schemaURL, string(schema)) @@ -451,7 +465,7 @@ func TestPostFieldWithTTL(t *testing.T) { }{ { name: "t1_48h", - url: fmt.Sprintf("%s/index/ttl_test/field/t1_48h", m.URL()), + url: fmt.Sprintf("%s/index/%s/field/t1_48h", m.URL(), c), option: `{ "options": {"timeQuantum":"YMDH","type":"time","ttl":"48h" }}`, expStatus: 200, expErr: `"success":true`, @@ -459,28 +473,28 @@ func TestPostFieldWithTTL(t *testing.T) { }, { name: "t2_unknown_unit", - url: fmt.Sprintf("%s/index/ttl_test/field/t2_unknown_unit", m.URL()), + url: fmt.Sprintf("%s/index/%s/field/t2_unknown_unit", m.URL(), c), option: `{ "options": {"timeQuantum":"YMDH","type":"time","ttl":"24abc" }}`, expStatus: 400, expErr: "cannot parse ttl", }, { name: "t3_invalid", - url: fmt.Sprintf("%s/index/ttl_test/field/t3_invalid", m.URL()), + url: fmt.Sprintf("%s/index/%s/field/t3_invalid", m.URL(), c), option: `{ "options": {"timeQuantum":"YMDH","type":"time","ttl":"abcdef" }}`, expStatus: 400, expErr: "cannot parse ttl", }, { name: "t4_invalid_empty", - url: fmt.Sprintf("%s/index/ttl_test/field/t4_invalid_empty", m.URL()), + url: fmt.Sprintf("%s/index/%s/field/t4_invalid_empty", m.URL(), c), option: `{ "options": {"timeQuantum":"YMDH","type":"time","ttl":"" }}`, expStatus: 400, expErr: "cannot parse ttl", }, { name: "t5_negative", - url: fmt.Sprintf("%s/index/ttl_test/field/t5_negative", m.URL()), + url: fmt.Sprintf("%s/index/%s/field/t5_negative", m.URL(), c), option: `{ "options": {"timeQuantum":"YMDH","type":"time","ttl":"-24h" }}`, expStatus: 400, expErr: "ttl can't be negative", @@ -508,12 +522,21 @@ func TestPostFieldWithTTL(t *testing.T) { t.Fatalf("getting schema: %v", err) } - if ii[0].Fields[i].Name == test_i.name { - if ii[0].Fields[i].Options.TTL != test_i.expTTL { - t.Errorf("expected TTL: '%s', got: '%s'", test_i.expTTL, ii[0].Fields[i].Options.TTL) + for _, idx := range ii { + if idx.Name == indexName { + if len(idx.Fields) <= i { + t.Fatalf("expected %d fields, last %s, got %d fields", + i, test_i.name, len(idx.Fields)) + } + if idx.Fields[i].Name == test_i.name { + if idx.Fields[i].Options.TTL != test_i.expTTL { + t.Errorf("expected TTL: '%s', got: '%s'", test_i.expTTL, idx.Fields[i].Options.TTL) + } + } else { + t.Errorf("unexpected field: '%s', got: '%s'", test_i.name, idx.Fields[i].Name) + } + break } - } else { - t.Errorf("unexpected field: '%s', got: '%s'", test_i.name, ii[0].Fields[i].Name) } } } @@ -525,9 +548,9 @@ func TestGetViewAndDelete(t *testing.T) { c := test.MustRunCluster(t, 1) defer c.Close() - schema := ` + schema := fmt.Sprintf(` { - "index-name": "example", + "index-name": "%s", "primary-key-type": "string", "index-action": "create", "fields": [ @@ -540,7 +563,7 @@ func TestGetViewAndDelete(t *testing.T) { } ] } - ` + `, c) m := c.GetPrimary() schemaURL := fmt.Sprintf("%s/internal/schema", m.URL()) resp := test.Do(t, "POST", schemaURL, string(schema)) @@ -549,7 +572,7 @@ func TestGetViewAndDelete(t *testing.T) { } // Send sample data - postQueryUrl := fmt.Sprintf("%s/index/example/query", m.URL()) + postQueryUrl := fmt.Sprintf("%s/index/%s/query", m.URL(), c) queryOption := ` Set(1,test_view=1,2001-02-03T04:05) ` @@ -568,7 +591,7 @@ func TestGetViewAndDelete(t *testing.T) { } // Call view to get data - viewUrl := fmt.Sprintf("%s/index/example/field/test_view/view", m.URL()) + viewUrl := fmt.Sprintf("%s/index/%s/field/test_view/view", m.URL(), c) respView := test.Do(t, "GET", viewUrl, "") if respView.StatusCode != gohttp.StatusOK { t.Errorf("view handler, status: %d, body=%s", respView.StatusCode, respView.Body) @@ -598,7 +621,7 @@ func TestGetViewAndDelete(t *testing.T) { } // call delete on view standard_2001020304 - deleteViewUrl := fmt.Sprintf("%s/index/example/field/test_view/view/standard_2001020304", m.URL()) + deleteViewUrl := fmt.Sprintf("%s/index/%s/field/test_view/view/standard_2001020304", m.URL(), c) respDelete := test.Do(t, "DELETE", deleteViewUrl, "") if respDelete.StatusCode != gohttp.StatusOK { t.Errorf("delete handler, status: %d, body=%s", respDelete.StatusCode, respDelete.Body) @@ -608,7 +631,7 @@ func TestGetViewAndDelete(t *testing.T) { expectedViewNames = expectedViewNames[:len(expectedViewNames)-1] // call view again - viewUrl = fmt.Sprintf("%s/index/example/field/test_view/view", m.URL()) + viewUrl = fmt.Sprintf("%s/index/%s/field/test_view/view", m.URL(), c) respView = test.Do(t, "GET", viewUrl, "") if respView.StatusCode != gohttp.StatusOK { t.Errorf("view handler after delete, status: %d, body=%s", respView.StatusCode, respView.Body) @@ -641,9 +664,9 @@ func TestTranslationHandlers(t *testing.T) { c := test.MustRunCluster(t, 1) defer c.Close() - schema := ` + schema := fmt.Sprintf(` { - "index-name": "example", + "index-name": "%s", "primary-key-type": "string", "index-action": "create", "fields": [ @@ -657,7 +680,7 @@ func TestTranslationHandlers(t *testing.T) { } ] } -` +`, c) m := c.GetPrimary() schemaURL := fmt.Sprintf("%s/internal/schema", m.URL()) resp := test.Do(t, "POST", schemaURL, string(schema)) @@ -665,9 +688,9 @@ func TestTranslationHandlers(t *testing.T) { t.Errorf("invalid status: %d, body=%s", resp.StatusCode, resp.Body) } baseURLs := []string{ - fmt.Sprintf("%s/internal/translate/index/example/", m.URL()), - fmt.Sprintf("%s/internal/translate/field/example/stringset/", m.URL()), - fmt.Sprintf("%s/internal/translate/field/example/nonexistent/", m.URL()), + fmt.Sprintf("%s/internal/translate/index/%s/", m.URL(), c), + fmt.Sprintf("%s/internal/translate/field/%s/stringset/", m.URL(), c), + fmt.Sprintf("%s/internal/translate/field/%s/nonexistent/", m.URL(), c), } for _, url := range baseURLs { expectFailure := strings.HasSuffix(url, "/nonexistent/") diff --git a/index_test.go b/index_test.go index 3b81e7067..a60b948c5 100644 --- a/index_test.go +++ b/index_test.go @@ -261,7 +261,7 @@ func isNotFoundError(err error) bool { // This is a regression test after a customer experienced the same deadlock. // For details, check out https://molecula.atlassian.net/browse/CORE-919 func TestIndex_RecreateFieldOnRestart(t *testing.T) { - c := test.MustRunCluster(t, 1) + c := test.MustRunUnsharedCluster(t, 1) defer c.Close() // create index diff --git a/internal_client_test.go b/internal_client_test.go index 6e1306e91..97bf4d61f 100644 --- a/internal_client_test.go +++ b/internal_client_test.go @@ -15,99 +15,99 @@ import ( "time" "github.com/davecgh/go-spew/spew" - pilosa "github.com/featurebasedb/featurebase/v3" - "github.com/featurebasedb/featurebase/v3/authn" - "github.com/featurebasedb/featurebase/v3/disco" - "github.com/featurebasedb/featurebase/v3/encoding/proto" - "github.com/featurebasedb/featurebase/v3/pql" - "github.com/featurebasedb/featurebase/v3/server" - "github.com/featurebasedb/featurebase/v3/test" - "github.com/featurebasedb/featurebase/v3/vprint" + pilosa "github.com/molecula/featurebase/v3" + "github.com/molecula/featurebase/v3/authn" + "github.com/molecula/featurebase/v3/disco" + "github.com/molecula/featurebase/v3/encoding/proto" + "github.com/molecula/featurebase/v3/pql" + "github.com/molecula/featurebase/v3/test" + "github.com/molecula/featurebase/v3/vprint" "github.com/pkg/errors" "github.com/ricochet2200/go-disk-usage/du" ) // Test distributed TopN Row count across 3 nodes. func TestClient_MultiNode(t *testing.T) { - c := test.MustRunCluster(t, 3, - []server.CommandOption{ - server.OptCommandServerOptions(pilosa.OptServerNodeID("node0"), pilosa.OptServerClusterHasher(&test.ModHasher{}))}, - []server.CommandOption{ - server.OptCommandServerOptions(pilosa.OptServerNodeID("node1"), pilosa.OptServerClusterHasher(&test.ModHasher{}))}, - []server.CommandOption{ - server.OptCommandServerOptions(pilosa.OptServerNodeID("node2"), pilosa.OptServerClusterHasher(&test.ModHasher{}))}, - ) + c := test.MustRunCluster(t, 3) defer c.Close() - hldr0 := c.GetHolder(0) - hldr1 := c.GetHolder(1) - hldr2 := c.GetHolder(2) - - // Create a dispersed set of bitmaps across 3 nodes such that each - // individual node and shard width increment would reveal a different TopN. - shardNums := []uint64{1, 2, 6} - - // This was generated with: - // `owns := s[i].Handler.Handler.API.Cluster.OwnsShards("i", 20, s[i].HostURI())` - owns := [][]uint64{ - {1, 3, 4, 8, 10, 13, 17, 19}, - {2, 5, 7, 11, 12, 14, 18}, - {0, 6, 9, 15, 16, 20}, - } - - for i, num := range shardNums { - ownsNum := false - for _, ownNum := range owns[i] { - if ownNum == num { - ownsNum = true - break - } - } - if !ownsNum { - t.Fatalf("Trying to use shard %d on host %s, but it doesn't own that shard. It owns %v", num, c.GetNode(i).URL(), owns) - } - } - - baseBit0 := pilosa.ShardWidth * shardNums[0] - baseBit1 := pilosa.ShardWidth * shardNums[1] - baseBit2 := pilosa.ShardWidth * shardNums[2] - - maxShard := uint64(0) - for _, x := range shardNums { - if x > maxShard { - maxShard = x - } - } - _, err := c.GetNode(0).API.CreateIndex(context.Background(), "i", pilosa.IndexOptions{}) + _, err := c.GetNode(0).API.CreateIndex(context.Background(), c.Idx(), pilosa.IndexOptions{}) if err != nil { t.Fatalf("creating index: %v", err) } - _, err = c.GetNode(0).API.CreateField(context.Background(), "i", "f", pilosa.OptFieldTypeSet(pilosa.DefaultCacheType, 100)) + _, err = c.GetNode(0).API.CreateField(context.Background(), c.Idx(), "f", pilosa.OptFieldTypeSet(pilosa.DefaultCacheType, 100)) if err != nil { t.Fatalf("creating field: %v", err) } - hldr0.MustSetBits("i", "f", 100, baseBit0+10) - hldr0.MustSetBits("i", "f", 4, baseBit0+10, baseBit0+11, baseBit0+12) - hldr0.MustSetBits("i", "f", 4, baseBit0+10, baseBit0+11, baseBit0+12, baseBit0+13, baseBit0+14, baseBit0+15) - hldr0.MustSetBits("i", "f", 2, baseBit0+1, baseBit0+2, baseBit0+3, baseBit0+4) - hldr0.MustSetBits("i", "f", 3, baseBit0+1, baseBit0+2, baseBit0+3, baseBit0+4, baseBit0+5) - hldr0.MustSetBits("i", "f", 22, baseBit0+1, baseBit0+2) + // Connect to each node to compare results. + client := make([]*Client, 3) + client[0] = MustNewClient(c.GetNode(0).URL(), pilosa.GetHTTPClient(nil)) + client[1] = MustNewClient(c.GetNode(1).URL(), pilosa.GetHTTPClient(nil)) + client[2] = MustNewClient(c.GetNode(2).URL(), pilosa.GetHTTPClient(nil)) - hldr1.MustSetBits("i", "f", 99, baseBit1+1, baseBit1+2, baseBit1+3, baseBit1+4) - hldr1.MustSetBits("i", "f", 100, baseBit1+1, baseBit1+2, baseBit1+3, baseBit1+4, baseBit1+5, baseBit1+6, baseBit1+7, baseBit1+8, baseBit1+9, baseBit1+10) - hldr1.MustSetBits("i", "f", 98, baseBit1+1, baseBit1+2, baseBit1+3, baseBit1+4, baseBit1+5, baseBit1+6) - hldr1.MustSetBits("i", "f", 1, baseBit1+4) - hldr1.MustSetBits("i", "f", 22, baseBit1+1, baseBit1+2, baseBit1+3, baseBit1+4, baseBit1+5) + b0 := uint64(ShardWidth * 0) + b1 := uint64(ShardWidth * 1) + b2 := uint64(ShardWidth * 2) - hldr2.MustSetBits("i", "f", 24, baseBit2+10, baseBit2+11, baseBit2+12, baseBit2+13, baseBit2+14) - hldr2.MustSetBits("i", "f", 20, baseBit2+10, baseBit2+11, baseBit2+12, baseBit2+13) - hldr2.MustSetBits("i", "f", 21, baseBit2+10) - hldr2.MustSetBits("i", "f", 100, baseBit2+10) - hldr2.MustSetBits("i", "f", 99, baseBit2+10, baseBit2+11, baseBit2+12) - hldr2.MustSetBits("i", "f", 98, baseBit2+10, baseBit2+11) - hldr2.MustSetBits("i", "f", 22, baseBit2+10, baseBit2+11, baseBit2+12) + // helper to let us avoid repeating the b0+, etc, over and over + collate := func(a, b, c []uint64) []uint64 { + d := make([]uint64, len(a)+len(b)+len(c)) + n := 0 + for _, v := range a { + d[n] = b0 + v + n++ + } + for _, v := range b { + d[n] = b1 + v + n++ + } + for _, v := range c { + d[n] = b2 + v + n++ + } + return d + } + // data set. part of the goal of this is to have different top counts using a single node than + // using all three nodes + rows := map[uint64][]uint64{ + 100: collate([]uint64{10}, []uint64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, []uint64{10}), + 4: collate([]uint64{10, 11, 12, 13, 14, 15}, nil, nil), + 2: collate([]uint64{1, 2, 3, 4}, nil, nil), + 3: collate([]uint64{1, 2, 3, 4, 5}, nil, nil), + 99: collate(nil, []uint64{1, 2, 3, 4}, []uint64{10, 11, 12}), + 98: collate(nil, []uint64{1, 2, 3, 4, 5, 6}, []uint64{10, 11}), + 22: collate([]uint64{1, 2}, []uint64{1, 2, 3, 4, 5}, []uint64{10, 11, 12}), + 1: collate(nil, []uint64{4}, nil), + 21: collate(nil, nil, []uint64{10}), + } + bits := 0 + for _, v := range rows { + bits += len(v) + } + rowIDs := make([]uint64, bits) + colIDs := make([]uint64, bits) + n := 0 + for k, cols := range rows { + for _, v := range cols { + rowIDs[n] = k + colIDs[n] = v + n++ + } + } + + req := &pilosa.ImportRequest{ + Index: c.Idx(), + Field: "f", + RowIDs: rowIDs, + ColumnIDs: colIDs, + Shard: ^uint64(0), + } + err = client[0].Import(context.Background(), nil, req, &pilosa.ImportOptions{}) + if err != nil { + t.Fatalf("importing data: %v", err) + } // Rebuild the RankCache. // We have to do this to avoid the 10-second cache invalidation delay // built into cache.Invalidate() @@ -124,19 +124,13 @@ func TestClient_MultiNode(t *testing.T) { t.Fatalf("recalculating cache: %v", err) } - // Connect to each node to compare results. - client := make([]*Client, 3) - client[0] = MustNewClient(c.GetNode(0).URL(), pilosa.GetHTTPClient(nil)) - client[1] = MustNewClient(c.GetNode(1).URL(), pilosa.GetHTTPClient(nil)) - client[2] = MustNewClient(c.GetNode(2).URL(), pilosa.GetHTTPClient(nil)) - topN := 4 queryRequest := &pilosa.QueryRequest{ Query: fmt.Sprintf(`TopN(f, n=%d)`, topN), Remote: false, } - result, err := client[0].Query(context.Background(), "i", queryRequest) + result, err := client[0].Query(context.Background(), c.Idx(), queryRequest) if err != nil { t.Fatal(err) } @@ -157,11 +151,11 @@ func TestClient_MultiNode(t *testing.T) { t.Fatalf("Invalid TopN result set: %s", spew.Sdump(result)) } - result1, err := client[1].Query(context.Background(), "i", queryRequest) + result1, err := client[1].Query(context.Background(), c.Idx(), queryRequest) if err != nil { t.Fatal(err) } - result2, err := client[2].Query(context.Background(), "i", queryRequest) + result2, err := client[2].Query(context.Background(), c.Idx(), queryRequest) if err != nil { t.Fatal(err) } @@ -181,16 +175,18 @@ func TestClient_Export(t *testing.T) { cluster := test.MustRunCluster(t, 1) defer cluster.Close() cmd := cluster.GetNode(0) + keyed := cluster.Idx("k") + unkeyed := cluster.Idx("u") host := cmd.URL() - cmd.MustCreateIndex(t, "keyed", pilosa.IndexOptions{Keys: true}) - cmd.MustCreateIndex(t, "unkeyed", pilosa.IndexOptions{Keys: false}) + cmd.MustCreateIndex(t, keyed, pilosa.IndexOptions{Keys: true}) + cmd.MustCreateIndex(t, unkeyed, pilosa.IndexOptions{Keys: false}) - cmd.MustCreateField(t, "keyed", "keyedf", pilosa.OptFieldTypeSet(pilosa.CacheTypeRanked, 1000), pilosa.OptFieldKeys()) - cmd.MustCreateField(t, "keyed", "unkeyedf", pilosa.OptFieldTypeSet(pilosa.CacheTypeRanked, 1000)) - cmd.MustCreateField(t, "unkeyed", "keyedf", pilosa.OptFieldTypeSet(pilosa.CacheTypeRanked, 1000), pilosa.OptFieldKeys()) - cmd.MustCreateField(t, "unkeyed", "unkeyedf", pilosa.OptFieldTypeSet(pilosa.CacheTypeRanked, 1000)) + cmd.MustCreateField(t, keyed, "keyedf", pilosa.OptFieldTypeSet(pilosa.CacheTypeRanked, 1000), pilosa.OptFieldKeys()) + cmd.MustCreateField(t, keyed, "unkeyedf", pilosa.OptFieldTypeSet(pilosa.CacheTypeRanked, 1000)) + cmd.MustCreateField(t, unkeyed, "keyedf", pilosa.OptFieldTypeSet(pilosa.CacheTypeRanked, 1000), pilosa.OptFieldKeys()) + cmd.MustCreateField(t, unkeyed, "unkeyedf", pilosa.OptFieldTypeSet(pilosa.CacheTypeRanked, 1000)) c := MustNewClient(host, pilosa.GetHTTPClient(nil)) data := []pilosa.Bit{ @@ -207,7 +203,7 @@ func TestClient_Export(t *testing.T) { t.Run("Export unkeyed,unkeyedf", func(t *testing.T) { // Populate data. for _, bit := range data { - _, err := c.Query(context.Background(), "unkeyed", &pilosa.QueryRequest{ + _, err := c.Query(context.Background(), unkeyed, &pilosa.QueryRequest{ Query: fmt.Sprintf(`Set(%d, unkeyedf=%d)`, bit.ColumnID, bit.RowID), Remote: false, }) @@ -220,7 +216,7 @@ func TestClient_Export(t *testing.T) { bw := bufio.NewWriter(buf) // Send export request. - if err := c.ExportCSV(context.Background(), "unkeyed", "unkeyedf", 0, bw); err != nil { + if err := c.ExportCSV(context.Background(), unkeyed, "unkeyedf", 0, bw); err != nil { t.Fatal(err) } @@ -241,7 +237,7 @@ func TestClient_Export(t *testing.T) { t.Run("Export unkeyed,keyedf", func(t *testing.T) { // Populate data. for _, bit := range data { - _, err := c.Query(context.Background(), "unkeyed", &pilosa.QueryRequest{ + _, err := c.Query(context.Background(), unkeyed, &pilosa.QueryRequest{ Query: fmt.Sprintf(`Set(%d, keyedf=%s)`, bit.ColumnID, bit.RowKey), Remote: false, }) @@ -254,7 +250,7 @@ func TestClient_Export(t *testing.T) { bw := bufio.NewWriter(buf) // Send export request. - if err := c.ExportCSV(context.Background(), "unkeyed", "keyedf", 0, bw); err != nil { + if err := c.ExportCSV(context.Background(), unkeyed, "keyedf", 0, bw); err != nil { t.Fatal(err) } @@ -275,7 +271,7 @@ func TestClient_Export(t *testing.T) { t.Run("Export keyed,unkeyedf", func(t *testing.T) { // Populate data. for _, bit := range data { - _, err := c.Query(context.Background(), "keyed", &pilosa.QueryRequest{ + _, err := c.Query(context.Background(), keyed, &pilosa.QueryRequest{ Query: fmt.Sprintf(`Set("%s", unkeyedf=%d)`, bit.ColumnKey, bit.RowID), Remote: false, }) @@ -289,34 +285,35 @@ func TestClient_Export(t *testing.T) { // Send export request for every partition. for i := 0; i < disco.DefaultPartitionN; i++ { - if err := c.ExportCSV(context.Background(), "keyed", "unkeyedf", uint64(i), bw); err != nil { + if err := c.ExportCSV(context.Background(), keyed, "unkeyedf", uint64(i), bw); err != nil { t.Fatal(err) } } got := buf.String() + gotSlice := strings.Split(got, "\n") // Expected output is not sorted because of key sharding. - exp := "" + - "2,col200\n" + - "2,col201\n" + - "2,col202\n" + - "2,col203\n" + - "1,col103\n" + - "1,col102\n" + - "1,col101\n" + - "1,col100\n" - - // Verify data. - if got != exp { - t.Fatalf("unexpected export data: %q, expected %q", got, exp) + expSlice := []string{ + "1,col103", + "1,col102", + "1,col101", + "1,col100", + "2,col200", + "2,col201", + "2,col202", + "2,col203", + "", + } + if !sameStringSlice(gotSlice, expSlice) { + t.Fatalf("unexpected results: %q", gotSlice) } }) t.Run("Export keyed,keyedf", func(t *testing.T) { // Populate data. for _, bit := range data { - _, err := c.Query(context.Background(), "keyed", &pilosa.QueryRequest{ + _, err := c.Query(context.Background(), keyed, &pilosa.QueryRequest{ Query: fmt.Sprintf(`Set("%s", keyedf=%s)`, bit.ColumnKey, bit.RowKey), Remote: false, }) @@ -330,27 +327,28 @@ func TestClient_Export(t *testing.T) { // Send export request. for i := 0; i < disco.DefaultPartitionN; i++ { - if err := c.ExportCSV(context.Background(), "keyed", "keyedf", uint64(i), bw); err != nil { + if err := c.ExportCSV(context.Background(), keyed, "keyedf", uint64(i), bw); err != nil { t.Fatal(err) } } got := buf.String() + gotSlice := strings.Split(got, "\n") - // Expected output is unsorted because of key sharding. - exp := "" + - "row2,col200\n" + - "row2,col201\n" + - "row2,col202\n" + - "row2,col203\n" + - "row1,col103\n" + - "row1,col102\n" + - "row1,col101\n" + - "row1,col100\n" - - // Verify data. - if got != exp { - t.Fatalf("unexpected export data: %q, expected %q", got, exp) + // Expected output is not sorted because of key sharding. + expSlice := []string{ + "row1,col103", + "row1,col102", + "row1,col101", + "row1,col100", + "row2,col200", + "row2,col201", + "row2,col202", + "row2,col203", + "", + } + if !sameStringSlice(gotSlice, expSlice) { + t.Fatalf("unexpected results: %q", gotSlice) } }) } @@ -363,16 +361,18 @@ func TestClient_Import(t *testing.T) { cmd := cluster.GetNode(0) host := cmd.URL() api := cmd.API + keyed := cluster.Idx("k") + unkeyed := cluster.Idx("u") - cmd.MustCreateIndex(t, "keyed", pilosa.IndexOptions{Keys: true}) - cmd.MustCreateIndex(t, "unkeyed", pilosa.IndexOptions{Keys: false}) + cmd.MustCreateIndex(t, keyed, pilosa.IndexOptions{Keys: true}) + cmd.MustCreateIndex(t, unkeyed, pilosa.IndexOptions{Keys: false}) - cmd.MustCreateField(t, "keyed", "keyedf", pilosa.OptFieldTypeSet(pilosa.CacheTypeNone, 0), pilosa.OptFieldKeys()) - cmd.MustCreateField(t, "keyed", "unkeyedf", pilosa.OptFieldTypeSet(pilosa.CacheTypeNone, 0)) - cmd.MustCreateField(t, "unkeyed", "keyedf", pilosa.OptFieldTypeSet(pilosa.CacheTypeNone, 0), pilosa.OptFieldKeys()) - cmd.MustCreateField(t, "unkeyed", "unkeyedf", pilosa.OptFieldTypeSet(pilosa.CacheTypeNone, 0)) + cmd.MustCreateField(t, keyed, "keyedf", pilosa.OptFieldTypeSet(pilosa.CacheTypeNone, 0), pilosa.OptFieldKeys()) + cmd.MustCreateField(t, keyed, "unkeyedf", pilosa.OptFieldTypeSet(pilosa.CacheTypeNone, 0)) + cmd.MustCreateField(t, unkeyed, "keyedf", pilosa.OptFieldTypeSet(pilosa.CacheTypeNone, 0), pilosa.OptFieldKeys()) + cmd.MustCreateField(t, unkeyed, "unkeyedf", pilosa.OptFieldTypeSet(pilosa.CacheTypeNone, 0)) - indexes := map[bool]string{true: "keyed", false: "unkeyed"} + indexes := map[bool]string{true: keyed, false: unkeyed} fields := map[bool]string{true: "keyedf", false: "unkeyedf"} recKeys := []string{"rec-a", "rec-b", "rec-c"} @@ -427,13 +427,13 @@ func TestClient_Import(t *testing.T) { } } - for keyed, indexName := range indexes { + for useKeys, indexName := range indexes { for _, fieldName := range fields { req := pilosa.ImportRequest{ Index: indexName, Field: fieldName, } - if indexName == "keyed" { + if indexName == keyed { req.ColumnKeys = recKeys req.Shard = ^uint64(0) } else { @@ -462,14 +462,14 @@ func TestClient_Import(t *testing.T) { if err != nil { t.Fatal(err) } - checkResults(results, keyed, 3) + checkResults(results, useKeys, 3) // Now clear a bit... req = pilosa.ImportRequest{ Index: indexName, Field: fieldName, } - if indexName == "keyed" { + if indexName == keyed { req.ColumnKeys = recKeys[2:] req.Shard = ^uint64(0) } else { @@ -504,32 +504,33 @@ func TestClient_Import(t *testing.T) { if err != nil { t.Fatal(err) } - checkResults(results, keyed, 2) + checkResults(results, useKeys, 2) } } } // Ensure client can bulk import data. func TestClient_ImportRoaring(t *testing.T) { - cluster := test.MustRunCluster(t, 3, - []server.CommandOption{ - server.OptCommandServerOptions(pilosa.OptServerReplicaN(3))}, - []server.CommandOption{ - server.OptCommandServerOptions(pilosa.OptServerReplicaN(3))}, - []server.CommandOption{ - server.OptCommandServerOptions(pilosa.OptServerReplicaN(3))}, - ) + cluster := test.MustUnsharedCluster(t, 3) + // Unshared because we want to set ReplicaN = 3 so we can verify data present on all nodes + for _, c := range cluster.Nodes { + c.Config.Cluster.ReplicaN = 3 + } + err := cluster.Start() + if err != nil { + t.Fatalf("starting cluster: %v", err) + } defer cluster.Close() - _, err := cluster.GetNode(0).API.CreateIndex(context.Background(), "i", pilosa.IndexOptions{}) + _, err = cluster.GetNode(0).API.CreateIndex(context.Background(), cluster.Idx(), pilosa.IndexOptions{}) if err != nil { t.Fatalf("creating index: %v", err) } - _, err = cluster.GetNode(0).API.CreateField(context.Background(), "i", "f", pilosa.OptFieldTypeSet(pilosa.CacheTypeRanked, 100)) + _, err = cluster.GetNode(0).API.CreateField(context.Background(), cluster.Idx(), "f", pilosa.OptFieldTypeSet(pilosa.CacheTypeRanked, 100)) if err != nil { t.Fatalf("creating field: %v", err) } - _, err = cluster.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: "Set(0, f=1)"}) + _, err = cluster.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: cluster.Idx(), Query: "Set(0, f=1)"}) if err != nil { t.Fatalf("querying: %v", err) } @@ -539,101 +540,101 @@ func TestClient_ImportRoaring(t *testing.T) { c := MustNewClient(host, pilosa.GetHTTPClient(nil)) // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 65537] roaringReq := makeImportRoaringRequest(false, "3B3001000100000900010000000100010009000100") - if err := c.ImportRoaring(context.Background(), &cluster.GetNode(0).API.Node().URI, "i", "f", 0, false, roaringReq); err != nil { + if err := c.ImportRoaring(context.Background(), &cluster.GetNode(0).API.Node().URI, cluster.Idx(), "f", 0, false, roaringReq); err != nil { t.Fatal(err) } hldr := test.Holder{Holder: cluster.GetNode(0).Server.Holder()} // Verify data on node 0. - if a := hldr.Row("i", "f", 0).Columns(); !reflect.DeepEqual(a, []uint64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 65537}) { + if a := hldr.Row(cluster.Idx(), "f", 0).Columns(); !reflect.DeepEqual(a, []uint64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 65537}) { t.Fatalf("unexpected columns: %+v", a) } - if a := hldr.Row("i", "f", 1).Columns(); !reflect.DeepEqual(a, []uint64{0}) { + if a := hldr.Row(cluster.Idx(), "f", 1).Columns(); !reflect.DeepEqual(a, []uint64{0}) { t.Fatalf("unexpected columns: %+v", a) } hldr2 := test.Holder{Holder: cluster.GetNode(1).Server.Holder()} // Verify data on node 1. - if a := hldr2.Row("i", "f", 0).Columns(); !reflect.DeepEqual(a, []uint64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 65537}) { + if a := hldr2.Row(cluster.Idx(), "f", 0).Columns(); !reflect.DeepEqual(a, []uint64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 65537}) { t.Fatalf("unexpected columns: %+v", a) } - if a := hldr2.Row("i", "f", 1).Columns(); !reflect.DeepEqual(a, []uint64{0}) { + if a := hldr2.Row(cluster.Idx(), "f", 1).Columns(); !reflect.DeepEqual(a, []uint64{0}) { t.Fatalf("unexpected columns: %+v", a) } // Ensure that sending a roaring import with the clear flag works as expected. // [65539, 65540] roaringReq = makeImportRoaringRequest(true, "3A30000001000000010001001000000003000400") - if err := c.ImportRoaring(context.Background(), &cluster.GetNode(0).API.Node().URI, "i", "f", 0, false, roaringReq); err != nil { + if err := c.ImportRoaring(context.Background(), &cluster.GetNode(0).API.Node().URI, cluster.Idx(), "f", 0, false, roaringReq); err != nil { t.Fatal(err) } // Verify data on node 0. - if a := hldr.Row("i", "f", 0).Columns(); !reflect.DeepEqual(a, []uint64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 65537}) { + if a := hldr.Row(cluster.Idx(), "f", 0).Columns(); !reflect.DeepEqual(a, []uint64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 65537}) { t.Fatalf("unexpected clear columns: %+v", a) } - if a := hldr.Row("i", "f", 1).Columns(); !reflect.DeepEqual(a, []uint64{0}) { + if a := hldr.Row(cluster.Idx(), "f", 1).Columns(); !reflect.DeepEqual(a, []uint64{0}) { t.Fatalf("unexpected clear columns: %+v", a) } // Verify data on node 1. - if a := hldr2.Row("i", "f", 0).Columns(); !reflect.DeepEqual(a, []uint64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 65537}) { + if a := hldr2.Row(cluster.Idx(), "f", 0).Columns(); !reflect.DeepEqual(a, []uint64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 65537}) { t.Fatalf("unexpected clear columns: %+v", a) } - if a := hldr2.Row("i", "f", 1).Columns(); !reflect.DeepEqual(a, []uint64{0}) { + if a := hldr2.Row(cluster.Idx(), "f", 1).Columns(); !reflect.DeepEqual(a, []uint64{0}) { t.Fatalf("unexpected clear columns: %+v", a) } // Ensure that sending a roaring import with the clear flag works as expected. // [4, 6, 65537, 65539] roaringReq = makeImportRoaringRequest(true, "3A300000020000000000010001000100180000001C0000000400060001000300") - if err := c.ImportRoaring(context.Background(), &cluster.GetNode(0).API.Node().URI, "i", "f", 0, false, roaringReq); err != nil { + if err := c.ImportRoaring(context.Background(), &cluster.GetNode(0).API.Node().URI, cluster.Idx(), "f", 0, false, roaringReq); err != nil { t.Fatal(err) } // Verify data on node 0. - if a := hldr.Row("i", "f", 0).Columns(); !reflect.DeepEqual(a, []uint64{1, 2, 3, 5, 7, 8, 9, 10}) { + if a := hldr.Row(cluster.Idx(), "f", 0).Columns(); !reflect.DeepEqual(a, []uint64{1, 2, 3, 5, 7, 8, 9, 10}) { t.Fatalf("unexpected clear columns: %+v", a) } - if a := hldr.Row("i", "f", 1).Columns(); !reflect.DeepEqual(a, []uint64{0}) { + if a := hldr.Row(cluster.Idx(), "f", 1).Columns(); !reflect.DeepEqual(a, []uint64{0}) { t.Fatalf("unexpected clear columns: %+v", a) } // Verify data on node 1. - if a := hldr2.Row("i", "f", 0).Columns(); !reflect.DeepEqual(a, []uint64{1, 2, 3, 5, 7, 8, 9, 10}) { + if a := hldr2.Row(cluster.Idx(), "f", 0).Columns(); !reflect.DeepEqual(a, []uint64{1, 2, 3, 5, 7, 8, 9, 10}) { t.Fatalf("unexpected clear columns: %+v", a) } - if a := hldr2.Row("i", "f", 1).Columns(); !reflect.DeepEqual(a, []uint64{0}) { + if a := hldr2.Row(cluster.Idx(), "f", 1).Columns(); !reflect.DeepEqual(a, []uint64{0}) { t.Fatalf("unexpected clear columns: %+v", a) } // Ensure that sending a roaring import with the clear flag works as expected. // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 65537] roaringReq = makeImportRoaringRequest(true, "3B3001000100000900010000000100010009000100") - if err := c.ImportRoaring(context.Background(), &cluster.GetNode(0).API.Node().URI, "i", "f", 0, false, roaringReq); err != nil { + if err := c.ImportRoaring(context.Background(), &cluster.GetNode(0).API.Node().URI, cluster.Idx(), "f", 0, false, roaringReq); err != nil { t.Fatal(err) } // Verify data on node 0. - if a := hldr.Row("i", "f", 0).Columns(); !reflect.DeepEqual(a, []uint64{}) { + if a := hldr.Row(cluster.Idx(), "f", 0).Columns(); !reflect.DeepEqual(a, []uint64{}) { t.Fatalf("unexpected clear columns: %+v", a) } - if a := hldr.Row("i", "f", 1).Columns(); !reflect.DeepEqual(a, []uint64{0}) { + if a := hldr.Row(cluster.Idx(), "f", 1).Columns(); !reflect.DeepEqual(a, []uint64{0}) { t.Fatalf("unexpected clear columns: %+v", a) } // Verify data on node 1. - if a := hldr2.Row("i", "f", 0).Columns(); !reflect.DeepEqual(a, []uint64{}) { + if a := hldr2.Row(cluster.Idx(), "f", 0).Columns(); !reflect.DeepEqual(a, []uint64{}) { t.Fatalf("unexpected clear columns: %+v", a) } - if a := hldr2.Row("i", "f", 1).Columns(); !reflect.DeepEqual(a, []uint64{0}) { + if a := hldr2.Row(cluster.Idx(), "f", 1).Columns(); !reflect.DeepEqual(a, []uint64{0}) { t.Fatalf("unexpected clear columns: %+v", a) } } // Ensure client can bulk import data with multiple views and not deadlock. func TestClient_ImportRoaring_MultiView(t *testing.T) { - cluster := test.MustNewCluster(t, 2) + cluster := test.MustUnsharedCluster(t, 2) for _, c := range cluster.Nodes { c.Config.Cluster.ReplicaN = 2 } @@ -645,15 +646,15 @@ func TestClient_ImportRoaring_MultiView(t *testing.T) { api := cluster.GetNode(0).API - _, err = api.CreateIndex(context.Background(), "i", pilosa.IndexOptions{}) + _, err = api.CreateIndex(context.Background(), cluster.Idx(), pilosa.IndexOptions{}) if err != nil { t.Fatalf("creating index: %v", err) } - _, err = api.CreateField(context.Background(), "i", "f", pilosa.OptFieldTypeSet(pilosa.CacheTypeRanked, 100)) + _, err = api.CreateField(context.Background(), cluster.Idx(), "f", pilosa.OptFieldTypeSet(pilosa.CacheTypeRanked, 100)) if err != nil { t.Fatalf("creating field: %v", err) } - _, err = api.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: "Set(0, f=1)"}) + _, err = api.Query(context.Background(), &pilosa.QueryRequest{Index: cluster.Idx(), Query: "Set(0, f=1)"}) if err != nil { t.Fatalf("querying: %v", err) } @@ -664,7 +665,7 @@ func TestClient_ImportRoaring_MultiView(t *testing.T) { req := &pilosa.ImportRoaringRequest{Views: map[string][]byte{}} req.Views["a"], _ = hex.DecodeString("3B3001000100000900010000000100010009000100") req.Views["b"], _ = hex.DecodeString("3B3001000100000900010000000100010009000100") - if err := c.ImportRoaring(context.Background(), &cluster.GetNode(0).API.Node().URI, "i", "f", 0, false, req); err != nil { + if err := c.ImportRoaring(context.Background(), &cluster.GetNode(0).API.Node().URI, cluster.Idx(), "f", 0, false, req); err != nil { t.Fatal(err) } } @@ -676,18 +677,20 @@ func TestClient_ImportKeys(t *testing.T) { defer cluster.Close() cmd := cluster.GetNode(0) host := cmd.URL() + keyed := cluster.Idx("k") + unkeyed := cluster.Idx("u") - cmd.MustCreateIndex(t, "keyed", pilosa.IndexOptions{Keys: true}) - cmd.MustCreateIndex(t, "unkeyed", pilosa.IndexOptions{Keys: false}) + cmd.MustCreateIndex(t, keyed, pilosa.IndexOptions{Keys: true}) + cmd.MustCreateIndex(t, unkeyed, pilosa.IndexOptions{Keys: false}) - cmd.MustCreateField(t, "keyed", "keyedf", pilosa.OptFieldTypeSet(pilosa.CacheTypeRanked, 1000), pilosa.OptFieldKeys()) - cmd.MustCreateField(t, "keyed", "unkeyedf", pilosa.OptFieldTypeSet(pilosa.CacheTypeRanked, 1000)) - cmd.MustCreateField(t, "unkeyed", "keyedf", pilosa.OptFieldTypeSet(pilosa.CacheTypeRanked, 1000), pilosa.OptFieldKeys()) + cmd.MustCreateField(t, keyed, "keyedf", pilosa.OptFieldTypeSet(pilosa.CacheTypeRanked, 1000), pilosa.OptFieldKeys()) + cmd.MustCreateField(t, keyed, "unkeyedf", pilosa.OptFieldTypeSet(pilosa.CacheTypeRanked, 1000)) + cmd.MustCreateField(t, unkeyed, "keyedf", pilosa.OptFieldTypeSet(pilosa.CacheTypeRanked, 1000), pilosa.OptFieldKeys()) // Send import request. c := MustNewClient(host, pilosa.GetHTTPClient(nil)) baseReq := &pilosa.ImportRequest{ - Index: "keyed", + Index: keyed, Field: "keyedf", ColumnKeys: []string{"eve", "alice", "bob", "eve", "alice", "eve"}, ColumnIDs: []uint64{1, 2, 3, 1, 2, 1}, @@ -697,14 +700,14 @@ func TestClient_ImportKeys(t *testing.T) { t.Run("Import keyed,keyed", func(t *testing.T) { req := baseReq.Clone() - req.Index = "keyed" + req.Index = keyed req.Field = "keyedf" req.ColumnIDs, req.RowIDs = nil, nil if err := c.Import(context.Background(), nil, req, &pilosa.ImportOptions{}); err != nil { t.Fatal(err) } resp := cmd.QueryAPI(t, &pilosa.QueryRequest{ - Index: "keyed", + Index: keyed, Query: "TopN(keyedf)", }) if pairs, ok := resp.Results[0].(*pilosa.PairsField); !ok { @@ -720,14 +723,14 @@ func TestClient_ImportKeys(t *testing.T) { t.Run("Import keyed,unkeyedf", func(t *testing.T) { req := baseReq.Clone() - req.Index = "keyed" + req.Index = keyed req.Field = "unkeyedf" req.ColumnIDs, req.RowKeys = nil, nil if err := c.Import(context.Background(), nil, req, &pilosa.ImportOptions{}); err != nil { t.Fatal(err) } resp := cmd.QueryAPI(t, &pilosa.QueryRequest{ - Index: "keyed", + Index: keyed, Query: "TopN(unkeyedf)", }) if pairs, ok := resp.Results[0].(*pilosa.PairsField); !ok { @@ -743,14 +746,14 @@ func TestClient_ImportKeys(t *testing.T) { t.Run("Import unkeyed,keyed", func(t *testing.T) { req := baseReq.Clone() - req.Index = "unkeyed" + req.Index = unkeyed req.Field = "keyedf" req.ColumnKeys, req.RowIDs = nil, nil if err := c.Import(context.Background(), nil, req, &pilosa.ImportOptions{}); err != nil { t.Fatal(err) } resp := cmd.QueryAPI(t, &pilosa.QueryRequest{ - Index: "unkeyed", + Index: unkeyed, Query: "TopN(keyedf)", }) if pairs, ok := resp.Results[0].(*pilosa.PairsField); !ok { @@ -772,10 +775,11 @@ func TestClient_ImportKeys(t *testing.T) { cmd1 := cluster.GetNode(1) host0 := cmd0.URL() host1 := cmd1.URL() + keyed := cluster.Idx("k") - cmd0.MustCreateIndex(t, "keyed", pilosa.IndexOptions{Keys: true}) - cmd0.MustCreateField(t, "keyed", "keyedf0", pilosa.OptFieldTypeSet(pilosa.CacheTypeRanked, 1000), pilosa.OptFieldKeys()) - cmd0.MustCreateField(t, "keyed", "keyedf1", pilosa.OptFieldTypeSet(pilosa.CacheTypeRanked, 1000), pilosa.OptFieldKeys()) + cmd0.MustCreateIndex(t, keyed, pilosa.IndexOptions{Keys: true}) + cmd0.MustCreateField(t, keyed, "keyedf0", pilosa.OptFieldTypeSet(pilosa.CacheTypeRanked, 1000), pilosa.OptFieldKeys()) + cmd0.MustCreateField(t, keyed, "keyedf1", pilosa.OptFieldTypeSet(pilosa.CacheTypeRanked, 1000), pilosa.OptFieldKeys()) // Send import request. c0 := MustNewClient(host0, pilosa.GetHTTPClient(nil)) @@ -784,7 +788,7 @@ func TestClient_ImportKeys(t *testing.T) { // Import to node0. t.Run("Import node0", func(t *testing.T) { req := &pilosa.ImportRequest{ - Index: "keyed", + Index: keyed, Field: "keyedf0", ColumnKeys: []string{"eve", "alice", "bob", "eve", "alice", "eve"}, RowKeys: []string{"green", "green", "green", "blue", "blue", "purple"}, @@ -793,7 +797,7 @@ func TestClient_ImportKeys(t *testing.T) { t.Fatal(err) } resp := cmd0.QueryAPI(t, &pilosa.QueryRequest{ - Index: "keyed", + Index: keyed, Query: "TopN(keyedf0)", }) if pairs, ok := resp.Results[0].(*pilosa.PairsField); !ok { @@ -810,7 +814,7 @@ func TestClient_ImportKeys(t *testing.T) { // Import to node1 (ensure import is routed to primary for translation). t.Run("Import node1", func(t *testing.T) { req := &pilosa.ImportRequest{ - Index: "keyed", + Index: keyed, Field: "keyedf1", ColumnKeys: []string{"eve", "alice", "bob", "eve", "alice", "eve"}, RowKeys: []string{"green", "green", "green", "blue", "blue", "purple"}, @@ -823,7 +827,7 @@ func TestClient_ImportKeys(t *testing.T) { time.Sleep(500 * time.Millisecond) resp := cmd1.QueryAPI(t, &pilosa.QueryRequest{ - Index: "keyed", + Index: keyed, Query: "TopN(keyedf1)", }) if pairs, ok := resp.Results[0].(*pilosa.PairsField); !ok { @@ -849,7 +853,7 @@ func TestClient_ImportKeys(t *testing.T) { fldName := "f" // Load bitmap into cache to ensure cache gets updated. - index := hldr.MustCreateIndexIfNotExists("i", pilosa.IndexOptions{Keys: true}) + index := hldr.MustCreateIndexIfNotExists(cluster.Idx(), pilosa.IndexOptions{Keys: true}) _, err := index.CreateFieldIfNotExists(fldName, pilosa.OptFieldTypeInt(-100, 100)) if err != nil { t.Fatal(err) @@ -858,7 +862,7 @@ func TestClient_ImportKeys(t *testing.T) { // Send import request. c := MustNewClient(host, pilosa.GetHTTPClient(nil)) req := &pilosa.ImportValueRequest{ - Index: "i", + Index: cluster.Idx(), Field: "f", ColumnKeys: []string{"col1", "col2", "col3"}, Values: []int64{-10, 20, 40}, @@ -873,7 +877,7 @@ func TestClient_ImportKeys(t *testing.T) { Remote: false, } - result, err := c.Query(context.Background(), "i", queryRequest) + result, err := c.Query(context.Background(), cluster.Idx(), queryRequest) if err != nil { t.Fatal(err) } @@ -884,7 +888,7 @@ func TestClient_ImportKeys(t *testing.T) { // Clear data. req = &pilosa.ImportValueRequest{ - Index: "i", + Index: cluster.Idx(), Field: "f", ColumnKeys: []string{"col2"}, Values: []int64{20}, @@ -899,7 +903,7 @@ func TestClient_ImportKeys(t *testing.T) { Remote: false, } - result, err = c.Query(context.Background(), "i", queryRequest) + result, err = c.Query(context.Background(), cluster.Idx(), queryRequest) if err != nil { t.Fatal(err) } @@ -924,7 +928,7 @@ func TestClient_ImportIDs(t *testing.T) { holder := cmd.Server.Holder() hldr := test.Holder{Holder: holder} - idxName := "i" + idxName := cluster.Idx() fldName := "f" // Load bitmap into cache to ensure cache gets updated. @@ -996,7 +1000,7 @@ func TestClient_ImportValue(t *testing.T) { fldName := "f" // Load bitmap into cache to ensure cache gets updated. - index := hldr.MustCreateIndexIfNotExists("i", pilosa.IndexOptions{}) + index := hldr.MustCreateIndexIfNotExists(cluster.Idx(), pilosa.IndexOptions{}) _, err := index.CreateFieldIfNotExists(fldName, pilosa.OptFieldTypeInt(-100, 100)) if err != nil { t.Fatal(err) @@ -1005,7 +1009,7 @@ func TestClient_ImportValue(t *testing.T) { // Send import request. c := MustNewClient(host, pilosa.GetHTTPClient(nil)) req := &pilosa.ImportValueRequest{ - Index: "i", + Index: cluster.Idx(), Field: "f", ColumnIDs: []uint64{1, 2, 3}, Values: []int64{-10, 20, 40}, @@ -1015,7 +1019,7 @@ func TestClient_ImportValue(t *testing.T) { } // Verify Sum. - if resp, err := c.Query(context.Background(), "i", &pilosa.QueryRequest{Query: `Sum(field=f)`}); err != nil { + if resp, err := c.Query(context.Background(), cluster.Idx(), &pilosa.QueryRequest{Query: `Sum(field=f)`}); err != nil { t.Fatal(err) } else if vc, ok := resp.Results[0].(pilosa.ValCount); !ok { t.Fatalf("expected ValCount; got %T", resp.Results[0]) @@ -1024,7 +1028,7 @@ func TestClient_ImportValue(t *testing.T) { } // Verify Max. - if resp, err := c.Query(context.Background(), "i", &pilosa.QueryRequest{Query: `Max(field=f)`}); err != nil { + if resp, err := c.Query(context.Background(), cluster.Idx(), &pilosa.QueryRequest{Query: `Max(field=f)`}); err != nil { t.Fatal(err) } else if vc, ok := resp.Results[0].(pilosa.ValCount); !ok { t.Fatalf("expected ValCount; got %T", resp.Results[0]) @@ -1037,14 +1041,14 @@ func TestClient_ImportValue(t *testing.T) { if err != nil { t.Fatal(err) } - preIUsage, err := c.GetIndexUsage(context.Background(), "i") + preIUsage, err := c.GetIndexUsage(context.Background(), cluster.Idx()) if err != nil { t.Fatal(err) } // Send import request. req = &pilosa.ImportValueRequest{ - Index: "i", + Index: cluster.Idx(), Field: "f", ColumnIDs: []uint64{1, 3}, Values: []int64{-10, 40}, @@ -1058,7 +1062,7 @@ func TestClient_ImportValue(t *testing.T) { if err != nil { t.Fatal(err) } - postIUsage, err := c.GetIndexUsage(context.Background(), "i") + postIUsage, err := c.GetIndexUsage(context.Background(), cluster.Idx()) if err != nil { t.Fatal(err) } @@ -1076,7 +1080,7 @@ func TestClient_ImportValue(t *testing.T) { } // Verify Sum. - if resp, err := c.Query(context.Background(), "i", &pilosa.QueryRequest{Query: `Sum(field=f)`}); err != nil { + if resp, err := c.Query(context.Background(), cluster.Idx(), &pilosa.QueryRequest{Query: `Sum(field=f)`}); err != nil { t.Fatal(err) } else if vc, ok := resp.Results[0].(pilosa.ValCount); !ok { t.Fatalf("expected ValCount; got %T", resp.Results[0]) @@ -1085,7 +1089,7 @@ func TestClient_ImportValue(t *testing.T) { } // Verify Max. - if resp, err := c.Query(context.Background(), "i", &pilosa.QueryRequest{Query: `Max(field=f)`}); err != nil { + if resp, err := c.Query(context.Background(), cluster.Idx(), &pilosa.QueryRequest{Query: `Max(field=f)`}); err != nil { t.Fatal(err) } else if vc, ok := resp.Results[0].(pilosa.ValCount); !ok { t.Fatalf("expected ValCount; got %T", resp.Results[0]) @@ -1104,7 +1108,7 @@ func TestClient_ImportExistence(t *testing.T) { hldr := test.Holder{Holder: holder} t.Run("Set", func(t *testing.T) { - idxName := "iset" + idxName := cluster.Idx("s") fldName := "fset" index := hldr.MustCreateIndexIfNotExists(idxName, pilosa.IndexOptions{TrackExistence: true}) @@ -1116,7 +1120,7 @@ func TestClient_ImportExistence(t *testing.T) { // Send import request. c := MustNewClient(host, pilosa.GetHTTPClient(nil)) req := &pilosa.ImportRequest{ - Index: "iset", + Index: cluster.Idx("s"), Field: "fset", ColumnIDs: []uint64{1, 5, 6}, RowIDs: []uint64{0, 0, 200}, @@ -1140,7 +1144,7 @@ func TestClient_ImportExistence(t *testing.T) { }) t.Run("Int", func(t *testing.T) { - idxName := "iint" + idxName := cluster.Idx("i") fldName := "fint" index := hldr.MustCreateIndexIfNotExists(idxName, pilosa.IndexOptions{TrackExistence: true}) @@ -1152,7 +1156,7 @@ func TestClient_ImportExistence(t *testing.T) { // Send import request. c := MustNewClient(host, pilosa.GetHTTPClient(nil)) req := &pilosa.ImportValueRequest{ - Index: "iint", + Index: cluster.Idx("i"), Field: "fint", ColumnIDs: []uint64{1, 2, 3}, Values: []int64{-10, 20, 40}, @@ -1186,13 +1190,13 @@ func TestClient_FragmentBlocks(t *testing.T) { holder := cmd.Server.Holder() hldr := test.Holder{Holder: holder} - hldr.SetBit("i", "f", 0, 1) - hldr.SetBit("i", "f", pilosa.HashBlockSize*3, 100) + hldr.SetBit(cluster.Idx(), "f", 0, 1) + hldr.SetBit(cluster.Idx(), "f", pilosa.HashBlockSize*3, 100) // Set a bit on a different shard. - hldr.SetBit("i", "f", 0, 1) + hldr.SetBit(cluster.Idx(), "f", 0, 1) c := MustNewClient(cmd.URL(), pilosa.GetHTTPClient(nil)) - blocks, err := c.FragmentBlocks(context.Background(), nil, "i", "f", "standard", 0) + blocks, err := c.FragmentBlocks(context.Background(), nil, cluster.Idx(), "f", "standard", 0) if err != nil { t.Fatal(err) } else if len(blocks) != 2 { @@ -1204,7 +1208,7 @@ func TestClient_FragmentBlocks(t *testing.T) { } // Verify data matches local blocks. - if a, err := cmd.API.FragmentBlocks(context.Background(), "i", "f", "standard", 0); err != nil { + if a, err := cmd.API.FragmentBlocks(context.Background(), cluster.Idx(), "f", "standard", 0); err != nil { t.Fatal(err) } else if !reflect.DeepEqual(a, blocks) { t.Fatalf("blocks mismatch:\n\nexp=%s\n\ngot=%s\n\n", spew.Sdump(a), spew.Sdump(blocks)) @@ -1238,7 +1242,7 @@ func TestClient_CreateTimeField(t *testing.T) { c := MustNewClient(cmd.URL(), pilosa.GetHTTPClient(nil)) - index := "cdf" + index := cluster.Idx() err := c.CreateIndex(context.Background(), index, pilosa.IndexOptions{}) if err != nil { t.Fatalf("creating index: %v", err) @@ -1278,7 +1282,7 @@ func TestClient_CreateDecimalField(t *testing.T) { c := MustNewClient(cmd.URL(), pilosa.GetHTTPClient(nil)) - index := "cdf" + index := cluster.Idx() err := c.CreateIndex(context.Background(), index, pilosa.IndexOptions{}) if err != nil { t.Fatalf("creating index: %v", err) @@ -1575,19 +1579,15 @@ func TestClient_ServerInfoHasBackend(t *testing.T) { pilosa.MustBackendToTxtype(si.StorageBackend) // panics if invalid } func TestClient_ImportRoaringExists(t *testing.T) { - cluster := test.MustNewCluster(t, 1) - err := cluster.Start() - if err != nil { - t.Fatalf("starting cluster: %v", err) - } + cluster := test.MustRunCluster(t, 1) defer cluster.Close() node := cluster.GetNode(0) - _, err = node.API.CreateIndex(context.Background(), "i", pilosa.IndexOptions{TrackExistence: true}) + _, err := node.API.CreateIndex(context.Background(), cluster.Idx(), pilosa.IndexOptions{TrackExistence: true}) if err != nil { t.Fatalf("creating index: %v", err) } - _, err = node.API.CreateField(context.Background(), "i", "f", pilosa.OptFieldTypeSet(pilosa.CacheTypeRanked, 100)) + _, err = node.API.CreateField(context.Background(), cluster.Idx(), "f", pilosa.OptFieldTypeSet(pilosa.CacheTypeRanked, 100)) if err != nil { t.Fatalf("creating field: %v", err) } @@ -1597,10 +1597,10 @@ func TestClient_ImportRoaringExists(t *testing.T) { // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 65537] roaringReq := makeImportRoaringRequest(false, "3B3001000100000900010000000100010009000100") - if err := c.ImportRoaring(context.Background(), &cluster.GetNode(0).API.Node().URI, "i", "f", 0, false, roaringReq); err != nil { + if err := c.ImportRoaring(context.Background(), &cluster.GetNode(0).API.Node().URI, cluster.Idx(), "f", 0, false, roaringReq); err != nil { t.Fatal(err) } - qr, err := node.API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: "All()"}) + qr, err := node.API.Query(context.Background(), &pilosa.QueryRequest{Index: cluster.Idx(), Query: "All()"}) if err != nil { t.Fatalf(" %v ", err) } @@ -1609,12 +1609,12 @@ func TestClient_ImportRoaringExists(t *testing.T) { t.Fatalf(" Row unexpected columns: got %+v expected: %+v", got, []uint64{}) } roaringReq.UpdateExistence = true - if err := c.ImportRoaring(context.Background(), &cluster.GetNode(0).API.Node().URI, "i", "f", 0, false, roaringReq); err != nil { + if err := c.ImportRoaring(context.Background(), &cluster.GetNode(0).API.Node().URI, cluster.Idx(), "f", 0, false, roaringReq); err != nil { t.Fatal(err) } expected := []uint64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 65537} - qr, err = node.API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: "All()"}) + qr, err = node.API.Query(context.Background(), &pilosa.QueryRequest{Index: cluster.Idx(), Query: "All()"}) if err != nil { t.Fatalf("Query error: %+v", err) } diff --git a/server/handler_test.go b/server/handler_test.go index 373f08000..bbda1599d 100644 --- a/server/handler_test.go +++ b/server/handler_test.go @@ -27,7 +27,7 @@ import ( ) func TestHandler_PostSchemaCluster(t *testing.T) { - cluster := test.MustRunCluster(t, 3) + cluster := test.MustRunUnsharedCluster(t, 3) defer cluster.Close() cmd := cluster.GetNode(0) h := cmd.Handler.(*pilosa.Handler).Handler @@ -66,7 +66,8 @@ func TestHandler_PostSchemaCluster(t *testing.T) { } func TestHandler_Endpoints(t *testing.T) { - cluster := test.MustRunCluster(t, 1) + // this test is full of hardcoded indexes and things + cluster := test.MustRunUnsharedCluster(t, 1) defer cluster.Close() cmd := cluster.GetNode(0) h := cmd.Handler.(*pilosa.Handler).Handler @@ -175,11 +176,8 @@ func TestHandler_Endpoints(t *testing.T) { i0 := hldr.MustCreateIndexIfNotExists("i0", pilosa.IndexOptions{}) const shard = 0 - tx0, err := holder.BeginTx(true, i0.Index, shard) - if err != nil { - t.Fatal(err) - } - defer tx0.Rollback() + tx0 := holder.Txf().NewWritableQcx() + defer tx0.Abort() if f, err := i0.CreateFieldIfNotExists("f1", pilosa.OptFieldTypeDefault()); err != nil { t.Fatal(err) } else if _, err := f.SetBit(tx0, 0, 0, nil); err != nil { @@ -188,22 +186,19 @@ func TestHandler_Endpoints(t *testing.T) { if _, err := i0.CreateFieldIfNotExists("f0", pilosa.OptFieldTypeDefault()); err != nil { t.Fatal(err) } - if err := tx0.Commit(); err != nil { + if err := tx0.Finish(); err != nil { t.Fatal(err) } i1 := hldr.MustCreateIndexIfNotExists("i1", pilosa.IndexOptions{}) - tx1, err := holder.BeginTx(true, i1.Index, shard) - if err != nil { - t.Fatal(err) - } - defer tx1.Rollback() + tx1 := holder.Txf().NewWritableQcx() + defer tx1.Abort() if f, err := i1.CreateFieldIfNotExists("f0", pilosa.OptFieldTypeDefault()); err != nil { t.Fatal(err) } else if _, err := f.SetBit(tx1, 0, 0, nil); err != nil { t.Fatal(err) } - if err := tx1.Commit(); err != nil { + if err := tx1.Finish(); err != nil { t.Fatal(err) } @@ -241,11 +236,8 @@ func TestHandler_Endpoints(t *testing.T) { // i2 is for SchemaDetails i2 := hldr.MustCreateIndexIfNotExists("i2", pilosa.IndexOptions{}) - tx2, err := holder.BeginTx(true, i2.Index, shard) - if err != nil { - t.Fatal(err) - } - defer tx2.Rollback() + tx2 := holder.Txf().NewWritableQcx() + defer tx2.Abort() if f, err := i2.CreateFieldIfNotExists("f0", pilosa.OptFieldTypeSet(pilosa.CacheTypeRanked, 1000)); err != nil { t.Fatal(err) } else if _, err := f.SetBit(tx2, 0, 0, nil); err != nil { @@ -290,7 +282,7 @@ func TestHandler_Endpoints(t *testing.T) { t.Fatal(err) } - if err := tx2.Commit(); err != nil { + if err := tx2.Finish(); err != nil { t.Fatal(err) } diff --git a/server/server_test.go b/server/server_test.go index 61997719c..dde3dad66 100644 --- a/server/server_test.go +++ b/server/server_test.go @@ -236,14 +236,14 @@ func TestConcurrentFieldCreation(t *testing.T) { } api0 := node0.API - if _, err := api0.CreateIndex(context.Background(), "i", pilosa.IndexOptions{}); err != nil { + if _, err := api0.CreateIndex(context.Background(), cluster.Idx(), pilosa.IndexOptions{}); err != nil { t.Fatalf("creating index: %v", err) } eg := errgroup.Group{} for i := 0; i < 100; i++ { i := i eg.Go(func() error { - if _, err := api0.CreateField(context.Background(), "i", fmt.Sprintf("f%d", i)); err != nil { + if _, err := api0.CreateField(context.Background(), cluster.Idx(), fmt.Sprintf("f%d", i)); err != nil { return err } return nil @@ -388,10 +388,10 @@ func TestMain_RecalculateCaches(t *testing.T) { // Create the schema. client0 := cluster.GetNode(0).Client() - if err := client0.CreateIndex(context.Background(), "i", pilosa.IndexOptions{}); err != nil && err != pilosa.ErrIndexExists { + if err := client0.CreateIndex(context.Background(), cluster.Idx(), pilosa.IndexOptions{}); err != nil && err != pilosa.ErrIndexExists { t.Fatal("create index:", err) } - if err := client0.CreateField(context.Background(), "i", "f"); err != nil { + if err := client0.CreateField(context.Background(), cluster.Idx(), "f"); err != nil { t.Fatal("create field:", err) } @@ -402,7 +402,7 @@ func TestMain_RecalculateCaches(t *testing.T) { data = append(data, fmt.Sprintf(`Set(%d, f=%d)`, columnID, rowID)) } } - if _, err := cluster.GetNode(0).Query(t, "i", "", strings.Join(data, "")); err != nil { + if _, err := cluster.GetNode(0).Query(t, cluster.Idx(), "", strings.Join(data, "")); err != nil { t.Fatal("setting columns:", err) } @@ -416,7 +416,7 @@ func TestMain_RecalculateCaches(t *testing.T) { // Run a TopN query on all nodes. The result should be the same as the target. for _, m := range cluster.Nodes { - res, err := m.Query(t, "i", "", `TopN(f)`) + res, err := m.Query(t, cluster.Idx(), "", `TopN(f)`) if err != nil { t.Fatal(err) } @@ -499,7 +499,7 @@ func (p uint64Slice) Len() int { return len(p) } func (p uint64Slice) Less(i, j int) bool { return p[i] < p[j] } func TestClusteringNodesReplica1(t *testing.T) { - cluster := test.MustRunCluster(t, 3) + cluster := test.MustRunUnsharedCluster(t, 3) defer cluster.Close() if err := cluster.AwaitState(disco.ClusterStateNormal, 100*time.Millisecond); err != nil { @@ -565,7 +565,7 @@ func TestClusteringNodesReplica2(t *testing.T) { // Because this test shuts down 2 nodes, it needs to start as a 5-node // cluster in order to retain enough available nodes for raft leader // election. - cluster := test.MustNewCluster(t, 5) + cluster := test.MustUnsharedCluster(t, 5) for _, c := range cluster.Nodes { c.Config.Cluster.ReplicaN = 2 } @@ -920,10 +920,11 @@ func TestClusterMinMaxSumDecimal(t *testing.T) { defer cluster.Close() cmd := cluster.GetNode(0) - cmd.MustCreateIndex(t, "testdec", pilosa.IndexOptions{Keys: true, TrackExistence: true}) - cmd.MustCreateField(t, "testdec", "adec", pilosa.OptFieldTypeDecimal(2)) + index := cluster.Idx("i") + cmd.MustCreateIndex(t, index, pilosa.IndexOptions{Keys: true, TrackExistence: true}) + cmd.MustCreateField(t, index, "adec", pilosa.OptFieldTypeDecimal(2)) - test.Do(t, "POST", cluster.GetNode(0).URL()+"/index/testdec/query", ` + test.Do(t, "POST", fmt.Sprintf("%s/index/%i/query", cmd.URL(), cluster), ` Set("a", adec=42.2) Set("b", adec=11.12) Set("c", adec=13.41) @@ -934,21 +935,21 @@ Set("g", adec=15.52) Set("h", adec=100.22) `) - result := test.Do(t, "POST", cluster.GetNode(0).URL()+"/index/testdec/query", "Sum(field=adec)") + result := test.Do(t, "POST", fmt.Sprintf("%s/index/%i/query", cmd.URL(), cluster), "Sum(field=adec)") if !strings.Contains(result.Body, `"decimalValue":305.59`) { t.Fatalf("expected decimal sum of 305.59, but got: '%s'", result.Body) } else if !strings.Contains(result.Body, `"count":8`) { t.Fatalf("expected count 8, but got: '%s'", result.Body) } - result = test.Do(t, "POST", cluster.GetNode(0).URL()+"/index/testdec/query", "Max(field=adec)") + result = test.Do(t, "POST", fmt.Sprintf("%s/index/%i/query", cmd.URL(), cluster), "Max(field=adec)") if !strings.Contains(result.Body, `"decimalValue":100.22`) { t.Fatalf("expected decimal max of 100.22, but got: '%s'", result.Body) } else if !strings.Contains(result.Body, `"count":1`) { t.Fatalf("expected count 1, but got: '%s'", result.Body) } - result = test.Do(t, "POST", cluster.GetNode(0).URL()+"/index/testdec/query", "Min(field=adec)") + result = test.Do(t, "POST", fmt.Sprintf("%s/index/%i/query", cmd.URL(), cluster), "Min(field=adec)") if !strings.Contains(result.Body, `"decimalValue":11.12`) { t.Fatalf("expected decimal min of 11.12, but got: '%s'", result.Body) } else if !strings.Contains(result.Body, `"count":1`) { @@ -984,7 +985,8 @@ func TestClusterCreatedAtRace(t *testing.T) { } for k := 0; k < iterations; k++ { t.Run(fmt.Sprintf("run-%d", k), func(t *testing.T) { - cluster := test.MustRunCluster(t, 4) + // needs fresh cluster so the index creations are new + cluster := test.MustRunUnsharedCluster(t, 4) defer cluster.Close() for _, com := range cluster.Nodes { @@ -1041,7 +1043,7 @@ func TestClusterCreatedAtRace(t *testing.T) { } func TestClusterQueryCountInDegraded(t *testing.T) { - cluster := test.MustNewCluster(t, 3) + cluster := test.MustUnsharedCluster(t, 3) for _, c := range cluster.Nodes { c.Config.Cluster.ReplicaN = 2 } diff --git a/server_test.go b/server_test.go index 225df84f8..4ea5f0286 100644 --- a/server_test.go +++ b/server_test.go @@ -22,7 +22,7 @@ func TestViewsRemovalTTL(t *testing.T) { // Create a client client := node.Client() - indexName := "i" + indexName := cluster.Idx() // Create indexes and field with ttl lasting 24 hours if err := client.CreateIndex(context.Background(), indexName, pilosa.IndexOptions{TrackExistence: true}); err != nil && err != pilosa.ErrIndexExists { @@ -196,7 +196,7 @@ func TestViewsRemovalStandard(t *testing.T) { // Create a client client := node.Client() - indexName := "i" + indexName := cluster.Idx() // Create indexes and field with ttl lasting 24 hours if err := client.CreateIndex(context.Background(), indexName, pilosa.IndexOptions{TrackExistence: true}); err != nil && err != pilosa.ErrIndexExists { diff --git a/sql/handler_test.go b/sql/handler_test.go index 8ac5d56cc..705feb427 100644 --- a/sql/handler_test.go +++ b/sql/handler_test.go @@ -7,9 +7,9 @@ import ( "math" "testing" - pilosa "github.com/featurebasedb/featurebase/v3" - "github.com/featurebasedb/featurebase/v3/sql" - "github.com/featurebasedb/featurebase/v3/test" + pilosa "github.com/molecula/featurebase/v3" + "github.com/molecula/featurebase/v3/sql" + "github.com/molecula/featurebase/v3/test" "vitess.io/vitess/go/vt/sqlparser" ) @@ -34,6 +34,9 @@ func TestHandler(t *testing.T) { } func TestSelectHandler_MapSelect(t *testing.T) { + // it's load-bearing that this is the only cluster in this directory right + // now, because that allows us to hardcode index names and not immediately + // die. cluster := test.MustRunCluster(t, 1) defer cluster.Close() api := cluster.GetNode(0).API diff --git a/sql3/planner/executionplanner_test.go b/sql3/planner/executionplanner_test.go index 83d005bba..0f1d7d1ea 100644 --- a/sql3/planner/executionplanner_test.go +++ b/sql3/planner/executionplanner_test.go @@ -22,7 +22,7 @@ func TestPlanner_Show(t *testing.T) { c := test.MustRunCluster(t, 1) defer c.Close() - index, err := c.GetHolder(0).CreateIndex("i", pilosa.IndexOptions{TrackExistence: true}) + index, err := c.GetHolder(0).CreateIndex(c.Idx("i"), pilosa.IndexOptions{TrackExistence: true}) if err != nil { t.Fatal(err) } @@ -33,7 +33,7 @@ func TestPlanner_Show(t *testing.T) { t.Fatal(err) } - index2, err := c.GetHolder(0).CreateIndex("i2", pilosa.IndexOptions{TrackExistence: false}) + index2, err := c.GetHolder(0).CreateIndex(c.Idx("l"), pilosa.IndexOptions{TrackExistence: false}) if err != nil { t.Fatal(err) } @@ -65,7 +65,7 @@ func TestPlanner_Show(t *testing.T) { }) t.Run("ShowColumns", func(t *testing.T) { - results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, `SHOW COLUMNS FROM i`) + results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, fmt.Sprintf(`SHOW COLUMNS FROM %i`, c)) if err != nil { t.Fatal(err) } @@ -94,7 +94,7 @@ func TestPlanner_Show(t *testing.T) { }) t.Run("ShowColumns2", func(t *testing.T) { - results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, `SHOW COLUMNS FROM i2`) + results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, fmt.Sprintf(`SHOW COLUMNS FROM %l`, c)) if err != nil { t.Fatal(err) } @@ -371,7 +371,7 @@ func TestPlanner_CoverCreateTable(t *testing.T) { // Ensure the schema field options match the expected options. for _, fld := range fields { t.Run(fmt.Sprintf("Field:%s", fld.name), func(t *testing.T) { - // Field `_id` isn't returned from FeatureBase in the schema, + // Field fmt.Sprintf(`_id`, c) isn't returned from FeatureBase in the schema, // but we do want to validate that its type is used to determine // whether or not the table is keyed. if fld.name == "_id" { @@ -532,7 +532,7 @@ func TestPlanner_AlterTable(t *testing.T) { c := test.MustRunCluster(t, 1) defer c.Close() - index, err := c.GetHolder(0).CreateIndex("i", pilosa.IndexOptions{TrackExistence: true}) + index, err := c.GetHolder(0).CreateIndex(c.Idx("i"), pilosa.IndexOptions{TrackExistence: true}) if err != nil { t.Fatal(err) } @@ -546,7 +546,7 @@ func TestPlanner_AlterTable(t *testing.T) { server := c.GetNode(0).Server t.Run("AlterTableDrop", func(t *testing.T) { - results, columns, err := sql_test.MustQueryRows(t, server, `alter table i drop column f`) + results, columns, err := sql_test.MustQueryRows(t, server, fmt.Sprintf(`alter table %i drop column f`, c)) if err != nil { t.Fatal(err) } @@ -560,7 +560,7 @@ func TestPlanner_AlterTable(t *testing.T) { }) t.Run("AlterTableAdd", func(t *testing.T) { - results, columns, err := sql_test.MustQueryRows(t, server, `alter table i add column f int`) + results, columns, err := sql_test.MustQueryRows(t, server, fmt.Sprintf(`alter table %i add column f int`, c)) if err != nil { t.Fatal(err) } @@ -575,7 +575,7 @@ func TestPlanner_AlterTable(t *testing.T) { t.Run("AlterTableRename", func(t *testing.T) { t.Skip("not yet implemented") - results, columns, err := sql_test.MustQueryRows(t, server, `alter table i rename column f to g`) + results, columns, err := sql_test.MustQueryRows(t, server, fmt.Sprintf(`alter table %i rename column f to g`, c)) if err != nil { t.Fatal(err) } @@ -593,7 +593,7 @@ func TestPlanner_DropTable(t *testing.T) { c := test.MustRunCluster(t, 1) defer c.Close() - index, err := c.GetHolder(0).CreateIndex("i", pilosa.IndexOptions{TrackExistence: true}) + index, err := c.GetHolder(0).CreateIndex(c.Idx("i"), pilosa.IndexOptions{TrackExistence: true}) if err != nil { t.Fatal(err) } @@ -605,7 +605,7 @@ func TestPlanner_DropTable(t *testing.T) { } t.Run("DropTable", func(t *testing.T) { - _, _, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, `DROP TABLE i`) + _, _, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, fmt.Sprintf(`DROP TABLE %i`, c)) if err != nil { t.Fatal(err) } @@ -616,7 +616,7 @@ func TestPlanner_ExpressionsInSelectListParen(t *testing.T) { c := test.MustRunCluster(t, 1) defer c.Close() - i0, err := c.GetHolder(0).CreateIndex("i0", pilosa.IndexOptions{TrackExistence: true}) + i0, err := c.GetHolder(0).CreateIndex(c.Idx("j"), pilosa.IndexOptions{TrackExistence: true}) if err != nil { t.Fatal(err) } @@ -627,7 +627,7 @@ func TestPlanner_ExpressionsInSelectListParen(t *testing.T) { t.Fatal(err) } - i1, err := c.GetHolder(0).CreateIndex("i1", pilosa.IndexOptions{TrackExistence: true}) + i1, err := c.GetHolder(0).CreateIndex(c.Idx("k"), pilosa.IndexOptions{TrackExistence: true}) if err != nil { t.Fatal(err) } @@ -640,7 +640,7 @@ func TestPlanner_ExpressionsInSelectListParen(t *testing.T) { // Populate with data. if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{ - Index: "i0", + Index: c.Idx("j"), Query: ` Set(1, a=10) Set(1, b=100) @@ -651,7 +651,7 @@ func TestPlanner_ExpressionsInSelectListParen(t *testing.T) { } t.Run("ParenOne", func(t *testing.T) { - results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, `SELECT (a != b) = false, _id FROM i0`) + results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, fmt.Sprintf(`SELECT (a != b) = false, _id FROM %j`, c)) if err != nil { t.Fatal(err) } @@ -672,7 +672,7 @@ func TestPlanner_ExpressionsInSelectListParen(t *testing.T) { }) t.Run("ParenTwo", func(t *testing.T) { - results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, `SELECT (a != b) = (false), _id FROM i0`) + results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, fmt.Sprintf(`SELECT (a != b) = (false), _id FROM %j`, c)) if err != nil { t.Fatal(err) } @@ -697,7 +697,7 @@ func TestPlanner_ExpressionsInSelectListLiterals(t *testing.T) { c := test.MustRunCluster(t, 1) defer c.Close() - i0, err := c.GetHolder(0).CreateIndex("i0", pilosa.IndexOptions{TrackExistence: true}) + i0, err := c.GetHolder(0).CreateIndex(c.Idx("j"), pilosa.IndexOptions{TrackExistence: true}) if err != nil { t.Fatal(err) } @@ -716,7 +716,7 @@ func TestPlanner_ExpressionsInSelectListLiterals(t *testing.T) { // Populate with data. if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{ - Index: "i0", + Index: c.Idx("j"), Query: ` Set(1, a=10) Set(1, b=100) @@ -730,7 +730,7 @@ func TestPlanner_ExpressionsInSelectListLiterals(t *testing.T) { } t.Run("LiteralsBool", func(t *testing.T) { - results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, `SELECT false = true, _id FROM i0`) + results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, fmt.Sprintf(`SELECT false = true, _id FROM %j`, c)) if err != nil { t.Fatal(err) } @@ -751,7 +751,7 @@ func TestPlanner_ExpressionsInSelectListLiterals(t *testing.T) { }) t.Run("LiteralsInt", func(t *testing.T) { - results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, `SELECT 1 + 2, _id FROM i0`) + results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, fmt.Sprintf(`SELECT 1 + 2, _id FROM %j`, c)) if err != nil { t.Fatal(err) } @@ -772,7 +772,7 @@ func TestPlanner_ExpressionsInSelectListLiterals(t *testing.T) { }) t.Run("LiteralsID", func(t *testing.T) { - results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, `SELECT _id + 2, _id FROM i0`) + results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, fmt.Sprintf(`SELECT _id + 2, _id FROM %j`, c)) if err != nil { t.Fatal(err) } @@ -793,7 +793,7 @@ func TestPlanner_ExpressionsInSelectListLiterals(t *testing.T) { }) t.Run("LiteralsDecimal", func(t *testing.T) { - results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, `SELECT d + 2.0, _id FROM i0`) + results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, fmt.Sprintf(`SELECT d + 2.0, _id FROM %j`, c)) if err != nil { t.Fatal(err) } @@ -814,7 +814,7 @@ func TestPlanner_ExpressionsInSelectListLiterals(t *testing.T) { }) t.Run("LiteralsString", func(t *testing.T) { - results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, `SELECT str || ' bar', _id FROM i0`) + results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, fmt.Sprintf(`SELECT str || ' bar', _id FROM %j`, c)) if err != nil { t.Fatal(err) } @@ -839,7 +839,7 @@ func TestPlanner_ExpressionsInSelectListCase(t *testing.T) { c := test.MustRunCluster(t, 1) defer c.Close() - i0, err := c.GetHolder(0).CreateIndex("i0", pilosa.IndexOptions{TrackExistence: true}) + i0, err := c.GetHolder(0).CreateIndex(c.Idx("j"), pilosa.IndexOptions{TrackExistence: true}) if err != nil { t.Fatal(err) } @@ -858,7 +858,7 @@ func TestPlanner_ExpressionsInSelectListCase(t *testing.T) { // Populate with data. if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{ - Index: "i0", + Index: c.Idx("j"), Query: ` Set(1, a=10) Set(1, b=100) @@ -872,7 +872,7 @@ func TestPlanner_ExpressionsInSelectListCase(t *testing.T) { } t.Run("CaseWithBase", func(t *testing.T) { - results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, `SELECT b, case b when 100 then 10 when 201 then 20 else 5 end, _id FROM i0`) + results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, fmt.Sprintf(`SELECT b, case b when 100 then 10 when 201 then 20 else 5 end, _id FROM %j`, c)) if err != nil { t.Fatal(err) } @@ -894,7 +894,7 @@ func TestPlanner_ExpressionsInSelectListCase(t *testing.T) { }) t.Run("CaseWithNoBase", func(t *testing.T) { - results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, `SELECT b, case when b = 100 then 10 when b = 201 then 20 else 5 end, _id FROM i0`) + results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, fmt.Sprintf(`SELECT b, case when b = 100 then 10 when b = 201 then 20 else 5 end, _id FROM %j`, c)) if err != nil { t.Fatal(err) } @@ -920,7 +920,7 @@ func TestPlanner_Select(t *testing.T) { c := test.MustRunCluster(t, 1) defer c.Close() - i0, err := c.GetHolder(0).CreateIndex("i0", pilosa.IndexOptions{TrackExistence: true}) + i0, err := c.GetHolder(0).CreateIndex(c.Idx("j"), pilosa.IndexOptions{TrackExistence: true}) if err != nil { t.Fatal(err) } @@ -931,7 +931,7 @@ func TestPlanner_Select(t *testing.T) { t.Fatal(err) } - i1, err := c.GetHolder(0).CreateIndex("i1", pilosa.IndexOptions{TrackExistence: true}) + i1, err := c.GetHolder(0).CreateIndex(c.Idx("k"), pilosa.IndexOptions{TrackExistence: true}) if err != nil { t.Fatal(err) } @@ -944,7 +944,7 @@ func TestPlanner_Select(t *testing.T) { // Populate with data. if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{ - Index: "i0", + Index: c.Idx("j"), Query: ` Set(1, a=10) Set(1, b=100) @@ -955,7 +955,7 @@ func TestPlanner_Select(t *testing.T) { } t.Run("UnqualifiedColumns", func(t *testing.T) { - results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, `SELECT a, b, _id FROM i0`) + results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, fmt.Sprintf(`SELECT a, b, _id FROM %j`, c)) if err != nil { t.Fatal(err) } @@ -977,7 +977,7 @@ func TestPlanner_Select(t *testing.T) { }) t.Run("QualifiedTableRef", func(t *testing.T) { - results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, `SELECT bar.a, bar.b, bar._id FROM i0 as bar`) + results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, fmt.Sprintf(`SELECT bar.a, bar.b, bar._id FROM %j as bar`, c)) if err != nil { t.Fatal(err) } @@ -999,7 +999,7 @@ func TestPlanner_Select(t *testing.T) { }) t.Run("AliasedUnqualifiedColumns", func(t *testing.T) { - results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, `SELECT a as foo, b as bar, _id as baz FROM i0`) + results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, fmt.Sprintf(`SELECT a as foo, b as bar, _id as baz FROM %j`, c)) if err != nil { t.Fatal(err) } @@ -1021,7 +1021,7 @@ func TestPlanner_Select(t *testing.T) { }) t.Run("QualifiedColumns", func(t *testing.T) { - results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, `SELECT i0._id, i0.a, i0.b FROM i0`) + results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, fmt.Sprintf(`SELECT %j._id, %j.a, %j.b FROM %j`, c, c, c, c)) if err != nil { t.Fatal(err) } @@ -1043,7 +1043,7 @@ func TestPlanner_Select(t *testing.T) { }) t.Run("UnqualifiedStar", func(t *testing.T) { - results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, `SELECT * FROM i0`) + results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, fmt.Sprintf(`SELECT * FROM %j`, c)) if err != nil { t.Fatal(err) } @@ -1065,7 +1065,7 @@ func TestPlanner_Select(t *testing.T) { }) t.Run("QualifiedStar", func(t *testing.T) { - results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, `SELECT i0.* FROM i0`) + results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, fmt.Sprintf(`SELECT %j.* FROM %j`, c, c)) if err != nil { t.Fatal(err) } @@ -1087,7 +1087,7 @@ func TestPlanner_Select(t *testing.T) { }) t.Run("NoIdentifier", func(t *testing.T) { - results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, `SELECT a, b FROM i0`) + results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, fmt.Sprintf(`SELECT a, b FROM %j`, c)) if err != nil { t.Fatal(err) } @@ -1108,7 +1108,7 @@ func TestPlanner_Select(t *testing.T) { }) t.Run("ErrFieldNotFound", func(t *testing.T) { - _, err := c.GetNode(0).Server.CompileExecutionPlan(context.Background(), `SELECT xyz FROM i0`) + _, err := c.GetNode(0).Server.CompileExecutionPlan(context.Background(), fmt.Sprintf(`SELECT xyz FROM %j`, c)) if err == nil || !strings.Contains(err.Error(), `column 'xyz' not found`) { t.Fatalf("unexpected error: %v", err) } @@ -1119,7 +1119,7 @@ func TestPlanner_SelectOrderBy(t *testing.T) { c := test.MustRunCluster(t, 1) defer c.Close() - i0, err := c.GetHolder(0).CreateIndex("i0", pilosa.IndexOptions{TrackExistence: true}) + i0, err := c.GetHolder(0).CreateIndex(c.Idx("j"), pilosa.IndexOptions{TrackExistence: true}) if err != nil { t.Fatal(err) } @@ -1132,7 +1132,7 @@ func TestPlanner_SelectOrderBy(t *testing.T) { // Populate with data. if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{ - Index: "i0", + Index: c.Idx("j"), Query: ` Set(1, a=10) Set(1, b=100) @@ -1143,7 +1143,7 @@ func TestPlanner_SelectOrderBy(t *testing.T) { } t.Run("OrderBy", func(t *testing.T) { - results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, `SELECT a, b, _id FROM i0 order by a desc`) + results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, fmt.Sprintf(`SELECT a, b, _id FROM %j order by a desc`, c)) if err != nil { t.Fatal(err) } @@ -1169,7 +1169,7 @@ func TestPlanner_SelectSelectSource(t *testing.T) { c := test.MustRunCluster(t, 1) defer c.Close() - i0, err := c.GetHolder(0).CreateIndex("i0", pilosa.IndexOptions{TrackExistence: true}) + i0, err := c.GetHolder(0).CreateIndex(c.Idx("j"), pilosa.IndexOptions{TrackExistence: true}) if err != nil { t.Fatal(err) } @@ -1182,7 +1182,7 @@ func TestPlanner_SelectSelectSource(t *testing.T) { // Populate with data. if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{ - Index: "i0", + Index: c.Idx("j"), Query: ` Set(1, a=10) Set(1, b=100) @@ -1193,7 +1193,7 @@ func TestPlanner_SelectSelectSource(t *testing.T) { } t.Run("ParenSource", func(t *testing.T) { - results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, `SELECT a, b, _id FROM (select * from i0)`) + results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, fmt.Sprintf(`SELECT a, b, _id FROM (select * from %j)`, c)) if err != nil { t.Fatal(err) } @@ -1215,7 +1215,7 @@ func TestPlanner_SelectSelectSource(t *testing.T) { }) t.Run("ParenSourceWithAlias", func(t *testing.T) { - results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, `SELECT foo.a, b, _id FROM (select * from i0) as foo`) + results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, fmt.Sprintf(`SELECT foo.a, b, _id FROM (select * from %j) as foo`, c)) if err != nil { t.Fatal(err) } @@ -1241,7 +1241,7 @@ func TestPlanner_In(t *testing.T) { c := test.MustRunCluster(t, 1) defer c.Close() - i0, err := c.GetHolder(0).CreateIndex("i0", pilosa.IndexOptions{TrackExistence: true}) + i0, err := c.GetHolder(0).CreateIndex(c.Idx("j"), pilosa.IndexOptions{TrackExistence: true}) if err != nil { t.Fatal(err) } @@ -1250,7 +1250,7 @@ func TestPlanner_In(t *testing.T) { t.Fatal(err) } - i1, err := c.GetHolder(0).CreateIndex("i1", pilosa.IndexOptions{TrackExistence: true}) + i1, err := c.GetHolder(0).CreateIndex(c.Idx("k"), pilosa.IndexOptions{TrackExistence: true}) if err != nil { t.Fatal(err) } @@ -1263,7 +1263,7 @@ func TestPlanner_In(t *testing.T) { // Populate with data. if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{ - Index: "i0", + Index: c.Idx("j"), Query: ` Set(1, a=10) Set(2, a=20) @@ -1273,7 +1273,7 @@ func TestPlanner_In(t *testing.T) { } if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{ - Index: "i1", + Index: c.Idx("k"), Query: ` Set(1, parentid=1) Set(1, x=100) @@ -1289,9 +1289,9 @@ func TestPlanner_In(t *testing.T) { t.Run("Count", func(t *testing.T) { t.Skip("Need to add join conditions to get this to pass") - results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, `SELECT i0._id, i0.a, i1._id, i1.parentid, i1.x FROM i0 INNER JOIN i1 ON i0._id = i1.parentid`) - //results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, `SELECT COUNT(*) FROM i0 INNER JOIN i1 ON i0._id = i1.parentid`) - //results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, `SELECT a FROM i0 where a = 20`) // SELECT COUNT(*) FROM i0 INNER JOIN i1 ON i0._id = i1.parentid + results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, fmt.Sprintf(`SELECT %j._id, %j.a, %k._id, %k.parentid, %k.x FROM %j INNER JOIN %k ON %j._id = %k.parentid`, c, c, c, c, c, c, c, c, c)) + //results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, fmt.Sprintf(`SELECT COUNT(*) FROM %j INNER JOIN %k ON %j._id = %k.parentid`, c, c, c, c)) + //results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, fmt.Sprintf(`SELECT a FROM %j where a = 20`, c)) // SELECT COUNT(*) FROM %j INNER JOIN %k ON %j._id = %k.parentid if err != nil { t.Fatal(err) } @@ -1310,8 +1310,8 @@ func TestPlanner_In(t *testing.T) { }) /*t.Run("Count", func(t *testing.T) { - //results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, `SELECT COUNT(*) FROM i0 INNER JOIN i1 ON i0._id = i1.parentid`) - results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, `SELECT COUNT(*) FROM i0 where i0._id in (select distinct parentid from i1)`) // SELECT COUNT(*) FROM i0 INNER JOIN i1 ON i0._id = i1.parentid + //results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, fmt.Sprintf(`SELECT COUNT(*) FROM %j INNER JOIN %k ON %j._id = %k.parentid`, c, c, c, c)) + results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, fmt.Sprintf(`SELECT COUNT(*) FROM %j where %j._id in (select distinct parentid from %k)`, c, c, c)) // SELECT COUNT(*) FROM %j INNER JOIN %k ON %j._id = %k.parentid if err != nil { t.Fatal(err) } @@ -1330,7 +1330,7 @@ func TestPlanner_In(t *testing.T) { }) t.Run("CountWithParentCondition", func(t *testing.T) { - results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, `SELECT COUNT(*) FROM i0 where i0._id in (select distinct parentid from i1) and i0.a = 10`) // SELECT COUNT(*) FROM i0 INNER JOIN i1 ON i0._id = i1.parentid WHERE i0.a = 10 + results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, fmt.Sprintf(`SELECT COUNT(*) FROM %j where %j._id in (select distinct parentid from %k) and %j.a = 10`, c, c, c, c)) // SELECT COUNT(*) FROM %j INNER JOIN %k ON %j._id = %k.parentid WHERE %j.a = 10 if err != nil { t.Fatal(err) } @@ -1349,7 +1349,7 @@ func TestPlanner_In(t *testing.T) { }) t.Run("CountWithParentAndChildCondition", func(t *testing.T) { - results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, `SELECT COUNT(*) FROM i0 where i0._id in (select distinct parentid from i1 where x = 200) and i0.a = 10`) // SELECT COUNT(*) FROM i0 INNER JOIN i1 ON i0._id = i1.parentid WHERE i0.a = 10 + results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, fmt.Sprintf(`SELECT COUNT(*) FROM %j where %j._id in (select distinct parentid from %k where x = 200) and %j.a = 10`, c, c, c, c)) // SELECT COUNT(*) FROM %j INNER JOIN %k ON %j._id = %k.parentid WHERE %j.a = 10 if err != nil { t.Fatal(err) } @@ -1372,7 +1372,7 @@ func TestPlanner_Distinct(t *testing.T) { c := test.MustRunCluster(t, 1) defer c.Close() - i0, err := c.GetHolder(0).CreateIndex("i0", pilosa.IndexOptions{TrackExistence: true}) + i0, err := c.GetHolder(0).CreateIndex(c.Idx("j"), pilosa.IndexOptions{TrackExistence: true}) if err != nil { t.Fatal(err) } @@ -1381,7 +1381,7 @@ func TestPlanner_Distinct(t *testing.T) { t.Fatal(err) } - i1, err := c.GetHolder(0).CreateIndex("i1", pilosa.IndexOptions{TrackExistence: true}) + i1, err := c.GetHolder(0).CreateIndex(c.Idx("k"), pilosa.IndexOptions{TrackExistence: true}) if err != nil { t.Fatal(err) } @@ -1394,7 +1394,7 @@ func TestPlanner_Distinct(t *testing.T) { // Populate with data. if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{ - Index: "i0", + Index: c.Idx("j"), Query: ` Set(1, a=10) Set(2, a=20) @@ -1404,7 +1404,7 @@ func TestPlanner_Distinct(t *testing.T) { } if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{ - Index: "i1", + Index: c.Idx("k"), Query: ` Set(1, parentid=1) Set(1, x=100) @@ -1419,7 +1419,7 @@ func TestPlanner_Distinct(t *testing.T) { } t.Run("SelectDistinct_id", func(t *testing.T) { - results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, `SELECT distinct _id from i0`) + results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, fmt.Sprintf(`SELECT distinct _id from %j`, c)) if err != nil { t.Fatal(err) } @@ -1441,7 +1441,7 @@ func TestPlanner_Distinct(t *testing.T) { t.Run("SelectDistinctNonId", func(t *testing.T) { t.Skip("WIP") - results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, `SELECT distinct parentid from i1`) + results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, fmt.Sprintf(`SELECT distinct parentid from %k`, c)) if err != nil { t.Fatal(err) } @@ -1462,7 +1462,7 @@ func TestPlanner_Distinct(t *testing.T) { }) t.Run("SelectDistinctMultiple", func(t *testing.T) { - results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, `select distinct _id, parentid from i1`) + results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, fmt.Sprintf(`select distinct _id, parentid from %k`, c)) if err != nil { t.Fatal(err) } @@ -1488,7 +1488,7 @@ func TestPlanner_SelectTop(t *testing.T) { c := test.MustRunCluster(t, 1) defer c.Close() - i0, err := c.GetHolder(0).CreateIndex("i0", pilosa.IndexOptions{TrackExistence: true}) + i0, err := c.GetHolder(0).CreateIndex(c.Idx("j"), pilosa.IndexOptions{TrackExistence: true}) if err != nil { t.Fatal(err) } @@ -1503,7 +1503,7 @@ func TestPlanner_SelectTop(t *testing.T) { // Populate with data. if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{ - Index: "i0", + Index: c.Idx("j"), Query: ` Set(1, a=10) Set(2, a=20) @@ -1516,7 +1516,7 @@ func TestPlanner_SelectTop(t *testing.T) { } t.Run("SelectTopStar", func(t *testing.T) { - results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, `select top(1) * from i0`) + results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, fmt.Sprintf(`select top(1) * from %j`, c)) if err != nil { t.Fatal(err) } @@ -1537,7 +1537,7 @@ func TestPlanner_SelectTop(t *testing.T) { }) t.Run("SelectTopNStar", func(t *testing.T) { - results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, `select topn(1) * from i0`) + results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, fmt.Sprintf(`select topn(1) * from %j`, c)) if err != nil { t.Fatal(err) } diff --git a/stats/stats_test.go b/stats/stats_test.go index 06f6f8de3..808408059 100644 --- a/stats/stats_test.go +++ b/stats/stats_test.go @@ -112,7 +112,9 @@ func TestStatsCount_TopN(t *testing.T) { } func TestStatsCount_Bitmap(t *testing.T) { - c := test.MustRunCluster(t, 1) + // Cluster has to be unhsared because we're mocking the stats which writes + // to a holder in use by other tests. + c := test.MustRunUnsharedCluster(t, 1) defer c.Close() hldr := test.Holder{Holder: c.GetNode(0).Server.Holder()} @@ -141,7 +143,8 @@ func TestStatsCount_Bitmap(t *testing.T) { } func TestStatsCount_APICalls(t *testing.T) { - cluster := test.MustRunCluster(t, 1) + // We can't share a cluster when we're modifying its stats counter. + cluster := test.MustRunUnsharedCluster(t, 1) defer cluster.Close() cmd := cluster.GetNode(0) h := cmd.Handler.(*pilosa.Handler).Handler diff --git a/test/cluster.go b/test/cluster.go index dc688f8ed..557906741 100644 --- a/test/cluster.go +++ b/test/cluster.go @@ -8,8 +8,10 @@ import ( "math" "sort" "strings" + "sync" "testing" "time" + "unicode" pilosa "github.com/featurebasedb/featurebase/v3" "github.com/featurebasedb/featurebase/v3/api/client" @@ -23,22 +25,86 @@ import ( "golang.org/x/sync/errgroup" ) -// modHasher represents a simple, mod-based hashing. -type ModHasher struct{} - -func (*ModHasher) Hash(key uint64, n int) int { return int(key) % n } - -func (*ModHasher) Name() string { return "mod" } - -// Cluster represents a Pilosa cluster (multiple Command instances) +// Cluster represents a per-test wrapper of a "real" cluster. +// Individual tests which request a cluster can get one of these +// back, wrapped with their test name. type Cluster struct { - Nodes []*Command - tb testing.TB + *ShareableCluster + tb testing.TB + indexName string + indexBytes []byte +} + +// Idx produces an index name suitable for this test's +// cluster, using the name itself, or the concatenation +// of that name and any provided strings, joined by underscores. +func (c *Cluster) Idx(of ...string) string { + if len(of) == 0 { + return c.indexName + } + for i := range of { + of[i] = indexName(of[i]) + } + return c.indexName + strings.Join(of, "_") +} + +// Format implements Formatter, allowing us to use clusters in +// format strings to handle the extremely common problem of "I +// want to embed the index name in this here string". Because we +// are horrible criminals, we append the rune, so you can use +// %i and %j to get index-name-plus-i and index-name-plus-j, +// respectively. We do assume that the rune works as a plain byte, +// though. +func (c *Cluster) Format(state fmt.State, r rune) { + c.indexBytes = append(c.indexBytes[:0], c.indexName...) + c.indexBytes = append(c.indexBytes, byte(r)) + _, _ = state.Write(c.indexBytes) +} + +func (c *Cluster) Close() error { + if c.shared { + // We're not going to actually close the cluster, BUT, we do want to + // delete and close all the indexes we might have just made. + h := c.GetHolder(0) + indexes := h.Indexes() + var lastErr error + api := c.Nodes[0].API + for _, idx := range indexes { + name := idx.Name() + if strings.HasPrefix(name, c.indexName) { + err := api.DeleteIndex(context.Background(), name) + if err != nil { + lastErr = err + } + } + } + return lastErr + } + if !c.started { + return errors.New("cluster not started yet") + } + return c.ShareableCluster.Close() +} + +func (c *Cluster) Start() error { + if c.started { + return errors.New("cluster already started") + } + c.started = true + return c.ShareableCluster.Start() +} + +// ShareableCluster represents a featurebase cluster (multiple Command instances) +// without test-specific overhead. +type ShareableCluster struct { + Nodes []*Command + started bool + shared bool } // Query executes an API.Query through one of the cluster's node's API. It fails // the test if there is an error. -func (c *Cluster) Query(t testing.TB, index, query string) pilosa.QueryResponse { +func (c *ShareableCluster) Query(t testing.TB, index, query string) pilosa.QueryResponse { t.Helper() if len(c.Nodes) == 0 { t.Fatal("must have at least one node in cluster to query") @@ -50,7 +116,7 @@ func (c *Cluster) Query(t testing.TB, index, query string) pilosa.QueryResponse // QueryHTTP executes a PQL query through the HTTP endpoint. It fails // the test for explicit errors, but returns an error which has the // response body if the HTTP call returns a non-OK status. -func (c *Cluster) QueryHTTP(t testing.TB, index, query string) (string, error) { +func (c *ShareableCluster) QueryHTTP(t testing.TB, index, query string) (string, error) { t.Helper() if len(c.Nodes) == 0 { t.Fatal("must have at least one node in cluster to query") @@ -61,7 +127,7 @@ func (c *Cluster) QueryHTTP(t testing.TB, index, query string) (string, error) { // QueryGRPC executes a PQL query through the GRPC endpoint. It fails the // test if there is an error. -func (c *Cluster) QueryGRPC(t testing.TB, index, query string) *proto.TableResponse { +func (c *ShareableCluster) QueryGRPC(t testing.TB, index, query string) *proto.TableResponse { t.Helper() if len(c.Nodes) == 0 { t.Fatal("must have at least one node in cluster to query") @@ -93,7 +159,7 @@ func (c *Cluster) QueryGRPC(t testing.TB, index, query string) *proto.TableRespo // starting; it's ok to reference each node by its index in the pre-sorted node // list. It's also safe to use this method after `MustRunCluster()` if the // cluster contains only one node. -func (c *Cluster) GetIdleNode(n int) *Command { +func (c *ShareableCluster) GetIdleNode(n int) *Command { return c.Nodes[n] } @@ -105,7 +171,7 @@ func (c *Cluster) GetIdleNode(n int) *Command { // `123`, `789`, then we actually want `GetNode(0)` to return `c.Nodes[1]`, and // `GetNode(1)` to return `c.Nodes[0]`. This method looks at all the node IDs, // sorts them, and then returns the node that the test expects. -func (c *Cluster) GetNode(n int) *Command { +func (c *ShareableCluster) GetNode(n int) *Command { // Put all the node IDs into a list to be sorted. ids := make([]nodePlace, len(c.Nodes)) for i := range c.Nodes { @@ -126,7 +192,7 @@ func (c *Cluster) GetNode(n int) *Command { // This used to be node0 in tests, but since implementing etcd, the primary // can be any node in the cluster, so we have to use this method in tests which // need to act on the primary. -func (c *Cluster) GetPrimary() *Command { +func (c *ShareableCluster) GetPrimary() *Command { for _, n := range c.Nodes { if n.IsPrimary() { return n @@ -136,7 +202,7 @@ func (c *Cluster) GetPrimary() *Command { } // GetNonPrimary gets first first non-primary node in the list of nodes. -func (c *Cluster) GetNonPrimary() *Command { +func (c *ShareableCluster) GetNonPrimary() *Command { for _, n := range c.Nodes { if !n.IsPrimary() { return n @@ -146,7 +212,7 @@ func (c *Cluster) GetNonPrimary() *Command { } // GetNonPrimaries gets all nodes except the primary. -func (c *Cluster) GetNonPrimaries() []*Command { +func (c *ShareableCluster) GetNonPrimaries() []*Command { rtn := make([]*Command, 0) for _, n := range c.Nodes { if !n.IsPrimary() { @@ -162,15 +228,15 @@ type nodePlace struct { idx int } -func (c *Cluster) GetHolder(n int) *Holder { +func (c *ShareableCluster) GetHolder(n int) *Holder { return &Holder{Holder: c.GetNode(n).Server.Holder()} } -func (c *Cluster) Len() int { +func (c *ShareableCluster) Len() int { return len(c.Nodes) } -func (c *Cluster) ImportBitsWithTimestamp(t testing.TB, index, field string, rowcols [][2]uint64, timestamps []int64) { +func (c *ShareableCluster) ImportBitsWithTimestamp(t testing.TB, index, field string, rowcols [][2]uint64, timestamps []int64) { t.Helper() byShard := make(map[uint64][][2]uint64) byShardTs := make(map[uint64][]int64) @@ -237,14 +303,15 @@ func (c *Cluster) ImportBitsWithTimestamp(t testing.TB, index, field string, row } } } -func (c *Cluster) ImportBits(t testing.TB, index, field string, rowcols [][2]uint64) { + +func (c *ShareableCluster) ImportBits(t testing.TB, index, field string, rowcols [][2]uint64) { var noTime []int64 c.ImportBitsWithTimestamp(t, index, field, rowcols, noTime) } // ImportKeyKey imports data into an index where both the index and // the field are using string keys. -func (c *Cluster) ImportKeyKey(t testing.TB, index, field string, valAndRecKeys [][2]string) { +func (c *ShareableCluster) ImportKeyKey(t testing.TB, index, field string, valAndRecKeys [][2]string) { t.Helper() importRequest := &pilosa.ImportRequest{ Index: index, @@ -273,7 +340,7 @@ type TimeQuantumKey struct { // ImportTimeQuantumKey imports data into an index where the index is keyd // and the field is a time-quantum -func (c *Cluster) ImportTimeQuantumKey(t testing.TB, index, field string, entries []TimeQuantumKey) { +func (c *ShareableCluster) ImportTimeQuantumKey(t testing.TB, index, field string, entries []TimeQuantumKey) { t.Helper() importRequest := &pilosa.ImportRequest{ Index: index, @@ -303,7 +370,7 @@ type IntKey struct { } // ImportIntKey imports int data into an index which uses string keys. -func (c *Cluster) ImportIntKey(t testing.TB, index, field string, pairs []IntKey) { +func (c *ShareableCluster) ImportIntKey(t testing.TB, index, field string, pairs []IntKey) { t.Helper() importRequest := &pilosa.ImportValueRequest{ Index: index, @@ -329,7 +396,7 @@ type IntID struct { } // ImportIntID imports data into an int field in an unkeyed index. -func (c *Cluster) ImportIntID(t testing.TB, index, field string, pairs []IntID) { +func (c *ShareableCluster) ImportIntID(t testing.TB, index, field string, pairs []IntID) { t.Helper() importRequest := &pilosa.ImportValueRequest{ Index: index, @@ -357,7 +424,7 @@ type KeyID struct { } //ImportIDKey imports data into an unkeyed set field in a keyed index. -func (c *Cluster) ImportIDKey(t testing.TB, index, field string, pairs []KeyID) { +func (c *ShareableCluster) ImportIDKey(t testing.TB, index, field string, pairs []KeyID) { t.Helper() importRequest := &pilosa.ImportRequest{ Index: index, @@ -378,7 +445,7 @@ func (c *Cluster) ImportIDKey(t testing.TB, index, field string, pairs []KeyID) } // CreateField creates the index (if necessary) and field specified. -func (c *Cluster) CreateField(t testing.TB, index string, iopts pilosa.IndexOptions, field string, fopts ...pilosa.FieldOption) *pilosa.Field { +func (c *ShareableCluster) CreateField(t testing.TB, index string, iopts pilosa.IndexOptions, field string, fopts ...pilosa.FieldOption) *pilosa.Field { t.Helper() idx, err := c.GetPrimary().API.CreateIndex(context.Background(), index, iopts) if err != nil && !strings.Contains(err.Error(), "index already exists") { @@ -403,11 +470,7 @@ func (c *Cluster) CreateField(t testing.TB, index string, iopts pilosa.IndexOpti } // Start runs a Cluster -func (c *Cluster) Start() error { - err := GetPortsGenConfigs(c.tb, c.Nodes) - if err != nil { - return errors.Wrap(err, "configuring cluster ports") - } +func (c *ShareableCluster) Start() error { var eg errgroup.Group for _, cc := range c.Nodes { cc := cc @@ -415,7 +478,7 @@ func (c *Cluster) Start() error { return cc.Start() }) } - err = eg.Wait() + err := eg.Wait() if err != nil { return errors.Wrap(err, "starting cluster") } @@ -423,7 +486,17 @@ func (c *Cluster) Start() error { } // Close stops a Cluster -func (c *Cluster) Close() error { +func (c *ShareableCluster) Close() error { + if c.shared { + for i := range c.Nodes { + holder := c.GetHolder(i) + indexes := holder.Indexes() + var indexNames []string + for _, idx := range indexes { + indexNames = append(indexNames, idx.Name()) + } + } + } for i, cc := range c.Nodes { if err := cc.Close(); err != nil { return errors.Wrapf(err, "stopping server %d", i) @@ -432,7 +505,10 @@ func (c *Cluster) Close() error { return nil } -func (c *Cluster) CloseAndRemoveNonPrimary() error { +func (c *ShareableCluster) CloseAndRemoveNonPrimary() error { + if c.shared { + return errors.New("can't close-and-remove in shared cluster") + } for i, n := range c.Nodes { if !n.IsPrimary() { return c.CloseAndRemove(i) @@ -441,7 +517,10 @@ func (c *Cluster) CloseAndRemoveNonPrimary() error { return errors.New("could not find non-primary node") } -func (c *Cluster) CloseAndRemove(n int) error { +func (c *ShareableCluster) CloseAndRemove(n int) error { + if c.shared { + return errors.New("can't close-and-remove in shared cluster") + } if n < 0 || n >= len(c.Nodes) { return fmt.Errorf("close/remove from cluster: index %d out of range (len %d)", n, len(c.Nodes)) } @@ -455,7 +534,7 @@ func (c *Cluster) CloseAndRemove(n int) error { // When this happens, we know etcd reached a combination of node states that // would imply this cluster state, but some nodes may not have caught up yet; // we just test that the coordinator thought the cluster was in the given state. -func (c *Cluster) AwaitPrimaryState(expectedState disco.ClusterState, timeout time.Duration) error { +func (c *ShareableCluster) AwaitPrimaryState(expectedState disco.ClusterState, timeout time.Duration) error { if len(c.Nodes) < 1 { return errors.New("can't await coordinator state on an empty cluster") } @@ -474,16 +553,15 @@ func (c *Cluster) AwaitPrimaryState(expectedState disco.ClusterState, timeout ti return errors.New("timed out waiting for cluster to have valid topology") } // we used up some of our timeout waiting for this - c.tb.Logf("had to wait %v for cluster topology", elapsed) timeout -= elapsed } - onlyCoordinator := &Cluster{Nodes: []*Command{primary}} + onlyCoordinator := &ShareableCluster{Nodes: []*Command{primary}} return onlyCoordinator.AwaitState(expectedState, timeout) } // ExceptionalState returns an error if any node in the cluster is not // in the expected state. -func (c *Cluster) ExceptionalState(expectedState disco.ClusterState) error { +func (c *ShareableCluster) ExceptionalState(expectedState disco.ClusterState) error { for _, node := range c.Nodes { state, err := node.API.State() if err != nil || state != expectedState { @@ -494,7 +572,7 @@ func (c *Cluster) ExceptionalState(expectedState disco.ClusterState) error { } // AwaitState waits for the whole cluster to reach a specified state. -func (c *Cluster) AwaitState(expectedState disco.ClusterState, timeout time.Duration) (err error) { +func (c *ShareableCluster) AwaitState(expectedState disco.ClusterState, timeout time.Duration) (err error) { if len(c.Nodes) < 1 { return errors.New("can't await state of an empty cluster") } @@ -512,7 +590,8 @@ func (c *Cluster) AwaitState(expectedState disco.ClusterState, timeout time.Dura elapsed, expectedState, err) } -// MustNewCluster creates a new cluster. If opts contains only one +// MustNewCluster creates a new cluster or returns an existing one. It never shares +// a cluster with non-empty opts. If opts contains only one // slice of command options, those options are used with every node. // If it is empty, default options are used. Otherwise, it must contain size // slices of command options, which are used with corresponding nodes. @@ -522,29 +601,111 @@ func MustNewCluster(tb testing.TB, size int, opts ...[]server.CommandOption) *Cl } tb.Helper() + shareable := len(opts) == 0 // We want tests to default to using the in-memory translate store, so we // prepend opts with that functional option. If a different translate store // has been specified, it will override this one. opts = prependOpts(opts, size) - c, err := newCluster(tb, size, opts...) + c, err := newCluster(tb, size, shareable, opts...) if err != nil { tb.Fatalf("new cluster: %v", err) } return c } -// newCluster creates a new cluster -func newCluster(tb testing.TB, size int, opts ...[]server.CommandOption) (*Cluster, error) { - if size == 0 { - return nil, errors.New("cluster must contain at least one node") +// MustUnsharedCluster creates a new cluster. If opts contains only one +// slice of command options, those options are used with every node. +// If it is empty, default options are used. Otherwise, it must contain size +// slices of command options, which are used with corresponding nodes. The +// new cluster is always unshared. +func MustUnsharedCluster(tb testing.TB, size int, opts ...[]server.CommandOption) *Cluster { + if size > 1 && !etcd.AllowCluster() { + tb.Skip("Testing PLG which does not allow clustering") } + tb.Helper() + // We want tests to default to using the in-memory translate store, so we + // prepend opts with that functional option. If a different translate store + // has been specified, it will override this one. + opts = prependOpts(opts, size) - if len(opts) != size && len(opts) != 0 && len(opts) != 1 { - return nil, errors.New("Slice of CommandOptions must be of length 0, 1, or equal to the number of cluster nodes") + c, err := newCluster(tb, size, false, opts...) + if err != nil { + tb.Fatalf("new cluster: %v", err) } + return c +} - cluster := &Cluster{Nodes: make([]*Command, size), tb: tb} +// MustRunUnsharedCluster creates a new cluster. If opts contains only one +// slice of command options, those options are used with every node. +// If it is empty, default options are used. Otherwise, it must contain size +// slices of command options, which are used with corresponding nodes. The +// new cluster is always unshared. The new cluster is started automatically, +// or the test is failed. +func MustRunUnsharedCluster(tb testing.TB, size int, opts ...[]server.CommandOption) *Cluster { + if size > 1 && !etcd.AllowCluster() { + tb.Skip("Testing PLG which does not allow clustering") + } + tb.Helper() + // We want tests to default to using the in-memory translate store, so we + // prepend opts with that functional option. If a different translate store + // has been specified, it will override this one. + opts = prependOpts(opts, size) + + c, err := newCluster(tb, size, false, opts...) + if err != nil { + tb.Fatalf("new cluster: %v", err) + } + err = c.Start() + if err != nil { + tb.Fatalf("starting cluster: %v", err) + } + return c +} + +type clusterCache struct { + mu sync.Mutex + clusters map[int]*ShareableCluster +} + +// CleanupClusters calls the close functions on any shared clusters that are +// still open. +func (c *clusterCache) CleanupClusters() { + for k, v := range c.clusters { + _ = v.Close() + delete(c.clusters, k) + } +} + +func (c *clusterCache) newCluster(tb testing.TB, size int) (*ShareableCluster, error) { + c.mu.Lock() + defer c.mu.Unlock() + if c := c.clusters[size]; c != nil { + return c, nil + } + // Make a whole-test wrapper so that the cluster we create will use the provided tb + // for nearly everything, but the call to TempDir inside NewCommand will pick up a + // persistent directory which outlives the provided TB. + newTB := NewWholeTestRun(tb) + if c.clusters == nil { + c.clusters = make(map[int]*ShareableCluster) + // tb should always be a wholeTestRun for clusterCache, and we need to + // register with that, so our cleanup happens *before* the deletion of + // the directories, otherwise etcd can fail to flush WAL files on + // exit, causing tests to fail. + newTB.Cleanup(c.CleanupClusters) + } + cluster, err := underlyingNewCluster(newTB, size) + if err != nil { + return nil, err + } + cluster.shared = true + c.clusters[size] = cluster + return cluster, nil +} + +func underlyingNewCluster(tb DirCleaner, size int, opts ...[]server.CommandOption) (*ShareableCluster, error) { + cluster := &ShareableCluster{Nodes: make([]*Command, size)} for i := 0; i < size; i++ { var commandOpts []server.CommandOption if len(opts) > 0 { @@ -555,17 +716,51 @@ func newCluster(tb testing.TB, size int, opts ...[]server.CommandOption) (*Clust cluster.Nodes[i] = m } - + // The GetPorts... stuff calls things elsewhere that want a plain testing.TB, + // and doesn't produce permanent directories, I think. + err := GetPortsGenConfigs(tb, cluster.Nodes) + if err != nil { + return nil, errors.Wrap(err, "configuring cluster ports") + } return cluster, nil } +var globalClusterCache clusterCache + +// newCluster creates a new cluster, using the shared cluster cache if no opts are +// specified. +func newCluster(tb testing.TB, size int, shareable bool, opts ...[]server.CommandOption) (*Cluster, error) { + if size == 0 { + return nil, errors.New("cluster must contain at least one node") + } + + if len(opts) != size && len(opts) != 0 && len(opts) != 1 { + return nil, errors.New("Slice of CommandOptions must be of length 0, 1, or equal to the number of cluster nodes") + } + + var shared *ShareableCluster + var err error + if !shareable { + shared, err = underlyingNewCluster(tb, size, opts...) + } else { + shared, err = globalClusterCache.newCluster(tb, size) + } + if err != nil { + return nil, err + } + return &Cluster{ShareableCluster: shared, tb: tb, indexName: indexName(tb.Name())}, nil +} + // MustRunCluster creates and starts a new cluster. The opts parameter // is slightly magical; see MustNewCluster. func MustRunCluster(tb testing.TB, size int, opts ...[]server.CommandOption) *Cluster { cluster := MustNewCluster(tb, size, opts...) - err := cluster.Start() - if err != nil { - tb.Fatalf("run cluster: %v", err) + if !cluster.started { + err := cluster.Start() + if err != nil { + tb.Fatalf("run cluster: %v", err) + } + cluster.started = true } return cluster } @@ -613,3 +808,19 @@ func prependTestServerOpts(opts []server.CommandOption) []server.CommandOption { } return append(defaultOpts, opts...) } + +func indexName(in string) string { + return strings.Map(func(r rune) rune { + if r < 127 { + switch { + case unicode.IsLetter(r): + return unicode.ToLower(r) + case unicode.IsNumber(r): + return r + case r == '/': + return '_' + } + } + return -1 + }, in) +} diff --git a/test/disco.go b/test/disco.go index ad6292c40..5d12c6986 100644 --- a/test/disco.go +++ b/test/disco.go @@ -6,7 +6,6 @@ import ( "fmt" "net" "strings" - "testing" "github.com/featurebasedb/featurebase/v3/etcd" "github.com/featurebasedb/featurebase/v3/server" @@ -56,7 +55,7 @@ func listenerWithURL() (listener *net.TCPListener, url string, err error) { // and modifies the configs of the provided Command objects // to point to these etcd configs. It uses etcd.GenEtcdConfigs, // which in turn creates temporary directories and the like. -func GetPortsGenConfigs(tb testing.TB, nodes []*Command) error { +func GetPortsGenConfigs(tb DirCleaner, nodes []*Command) error { clusterName, cfgs := etcd.GenEtcdConfigs(tb, len(nodes)) for i := range nodes { if nodes[i].Config == nil { diff --git a/test/glue.go b/test/glue.go new file mode 100644 index 000000000..60853bfb2 --- /dev/null +++ b/test/glue.go @@ -0,0 +1,129 @@ +// Copyright 2021 Molecula Corp. All rights reserved. +package test + +import ( + "fmt" + "log" + "os" + "sync" + "testing" + + "github.com/molecula/featurebase/v3/testhook" +) + +// glue lets us make a thing which isn't a testing.TB, but can be passed +// around to the functions that take testing.TB. + +// DirCleaner represents the subset of the testing.TB interface +// we care about, allowing us to take objects which behave like +// that without importing all of testing to get them. +type DirCleaner interface { + Helper() + Errorf(string, ...interface{}) + Fatalf(string, ...interface{}) + Fatal(...interface{}) + Logf(string, ...interface{}) + Name() string + TempDir() string + Cleanup(func()) + Skip(...interface{}) +} + +// Verify that a TB is a DirCleaner +var _ DirCleaner = testing.TB(nil) +var _ DirCleaner = &wholeTestRunWrapper{} + +// wholeTestRun is a thing that's shaped a bit like testing.TB, +// but it can be used across all the tests, running its cleanup functions +// at the very end of the testing process. this lets us create clusters +// using the same code and logic we would for per-test things, except +// substituting this, and then have a single global post-test-hook run +// their cleanup. +type wholeTestRun struct { + setup sync.Once + mu sync.Mutex + tempDirs []string + cleanupFuncs []func() +} + +// wholeTestRunWrapper is a test-specific thing that can refer to the +// global shared state, but also forwards everything *except* TempDir, +// Cleanup, and Logf to the tb it's created with. +type wholeTestRunWrapper struct { + testing.TB +} + +// globalT is a system-wide wholeTestRun. the first time it's used, for any +// reason, it registers a cleanup with testhook, which will run at the end +// of the TestMain stuff, but before any previously-registered cleanup +// functions (such as the auditor stuff) so it can ensure that everything's +// been deleted. Basically this exists to let us call `tb.TempDir` on +// things and get a directory which outlives the current test. +var globalT wholeTestRun + +// NewWholeTestRun produces a wholeTestRunWrapper around TB, which overrides +// a couple of the TB's methods to get whole-test-friendly behaviors. +func NewWholeTestRun(tb testing.TB) *wholeTestRunWrapper { + return &wholeTestRunWrapper{TB: tb} +} + +func (w *wholeTestRun) Teardown() { + w.mu.Lock() + defer w.mu.Unlock() + for _, fn := range w.cleanupFuncs { + fn() + } + fmt.Fprintf(os.Stderr, "tearing down: %d directories\n", len(w.tempDirs)) + for _, path := range w.tempDirs { + fmt.Fprintf(os.Stderr, "tearing down: deleting %s\n", path) + // disregard errors because we don't care that much about them; + // we assume RemoveAll probably works unless something's wrong. + // see the comments on the testing package's internal removeAll, + // which suggests the errors only happen on Windows, which we + // don't support. + _ = os.RemoveAll(path) + } +} + +func (w *wholeTestRun) Setup() { + w.setup.Do(func() { + testhook.RegisterPostTestHook(func() error { + w.Teardown() + return nil + }) + }) +} + +// We provide a Logf here because the wholeTestRunWrapper could +// be set as a tb-replacement for something which lasts past the +// test that created it. That shouldn't happen, probably. +func (w *wholeTestRunWrapper) Logf(msg string, args ...interface{}) { + log.Printf(msg, args...) +} + +func (w *wholeTestRun) TempDir(tb DirCleaner) string { + w.Setup() + w.mu.Lock() + defer w.mu.Unlock() + path, err := os.MkdirTemp("", "test-temp-") + if err != nil { + tb.Fatalf("creating temp dir: %v", err) + } + globalT.tempDirs = append(globalT.tempDirs, path) + return path +} + +func (w *wholeTestRun) Cleanup(fn func()) { + w.Setup() + w.mu.Lock() + defer w.mu.Unlock() + w.cleanupFuncs = append(w.cleanupFuncs, fn) +} + +func (w *wholeTestRunWrapper) TempDir() string { + return globalT.TempDir(w.TB) +} + +func (w *wholeTestRunWrapper) Cleanup(fn func()) { + globalT.Cleanup(fn) +} diff --git a/test/pilosa.go b/test/pilosa.go index d8515faa3..0bb0c3336 100644 --- a/test/pilosa.go +++ b/test/pilosa.go @@ -14,11 +14,10 @@ import ( "testing" "time" - pilosa "github.com/featurebasedb/featurebase/v3" - "github.com/featurebasedb/featurebase/v3/disco" - "github.com/featurebasedb/featurebase/v3/encoding/proto" - "github.com/featurebasedb/featurebase/v3/server" - "github.com/featurebasedb/featurebase/v3/testhook" + pilosa "github.com/molecula/featurebase/v3" + "github.com/molecula/featurebase/v3/disco" + "github.com/molecula/featurebase/v3/encoding/proto" + "github.com/molecula/featurebase/v3/server" ) // ////////////////////////////////////////////////////////////////////////////////// @@ -37,11 +36,8 @@ func OptAllowedOrigins(origins []string) server.CommandOption { } // newCommand returns a new instance of Main with a temporary data directory and random port. -func newCommand(tb testing.TB, opts ...server.CommandOption) *Command { - path, err := testhook.TempDir(tb, "pilosa-command-") - if err != nil { - panic(err) - } +func newCommand(tb DirCleaner, opts ...server.CommandOption) *Command { + path := tb.TempDir() // Set aggressive close timeout by default to avoid hanging tests. This was // a problem with PDK tests which used pilosa/client as well. We put it at the @@ -54,7 +50,7 @@ func newCommand(tb testing.TB, opts ...server.CommandOption) *Command { m := &Command{commandOptions: opts} m.Command = server.NewCommand(bytes.NewReader(nil), io.Discard, io.Discard, opts...) // pick etcd ports using a socket rather than a real port - err = GetPortsGenConfigs(tb, []*Command{m}) + err := GetPortsGenConfigs(tb, []*Command{m}) if err != nil { tb.Fatalf("generating config: %v", err) } @@ -81,7 +77,7 @@ func newCommand(tb testing.TB, opts ...server.CommandOption) *Command { } // NewCommandNode returns a new instance of Command with clustering enabled. -func NewCommandNode(tb testing.TB, opts ...server.CommandOption) *Command { +func NewCommandNode(tb DirCleaner, opts ...server.CommandOption) *Command { // We want tests to default to using the in-memory translate store, so we // prepend opts with that functional option. If a different translate store // has been specified, it will override this one. @@ -96,7 +92,7 @@ func RunCommand(t *testing.T) *Command { // prefer MustRunCluster since it sets up for using etcd using // the GenDisCoConfig(size) option. - return MustRunCluster(t, 1).GetNode(0) + return MustRunUnsharedCluster(t, 1).GetNode(0) } // Close closes the program and removes the underlying data directory. diff --git a/testdata/schema.json b/testdata/schema.json index 387336963..be253f9e3 100644 --- a/testdata/schema.json +++ b/testdata/schema.json @@ -1,7 +1,7 @@ { "indexes": [ { - "name": "equipment", + "name": "e", "options": { "keys": true, "trackExistence": true @@ -137,7 +137,7 @@ "shardWidth": 1048576 }, { - "name": "power_ts", + "name": "t", "options": { "keys": true, "trackExistence": true @@ -285,7 +285,7 @@ "shardWidth": 1048576 }, { - "name": "sites", + "name": "s", "options": { "keys": false, "trackExistence": true diff --git a/translator_test.go b/translator_test.go index 8feee4aee..8553a4389 100644 --- a/translator_test.go +++ b/translator_test.go @@ -12,12 +12,10 @@ import ( "time" "github.com/google/go-cmp/cmp" - pilosa "github.com/featurebasedb/featurebase/v3" - "github.com/featurebasedb/featurebase/v3/boltdb" - "github.com/featurebasedb/featurebase/v3/disco" - "github.com/featurebasedb/featurebase/v3/mock" - "github.com/featurebasedb/featurebase/v3/server" - "github.com/featurebasedb/featurebase/v3/test" + pilosa "github.com/molecula/featurebase/v3" + "github.com/molecula/featurebase/v3/disco" + "github.com/molecula/featurebase/v3/mock" + "github.com/molecula/featurebase/v3/test" "github.com/pkg/errors" "golang.org/x/sync/errgroup" ) @@ -151,32 +149,7 @@ func TestMultiTranslateEntryReader(t *testing.T) { } func TestTranslation_KeyNotFound(t *testing.T) { - c := test.MustRunCluster(t, 4, - []server.CommandOption{ - server.OptCommandServerOptions( - pilosa.OptServerNodeID("node0"), - pilosa.OptServerOpenTranslateStore(boltdb.OpenTranslateStore), - pilosa.OptServerOpenTranslateReader(pilosa.GetOpenTranslateReaderFunc(nil)), - )}, - []server.CommandOption{ - server.OptCommandServerOptions( - pilosa.OptServerNodeID("node1"), - pilosa.OptServerOpenTranslateStore(boltdb.OpenTranslateStore), - pilosa.OptServerOpenTranslateReader(pilosa.GetOpenTranslateReaderFunc(nil)), - )}, - []server.CommandOption{ - server.OptCommandServerOptions( - pilosa.OptServerNodeID("node2"), - pilosa.OptServerOpenTranslateStore(boltdb.OpenTranslateStore), - pilosa.OptServerOpenTranslateReader(pilosa.GetOpenTranslateReaderFunc(nil)), - )}, - []server.CommandOption{ - server.OptCommandServerOptions( - pilosa.OptServerNodeID("node3"), - pilosa.OptServerOpenTranslateStore(boltdb.OpenTranslateStore), - pilosa.OptServerOpenTranslateReader(pilosa.GetOpenTranslateReaderFunc(nil)), - )}, - ) + c := test.MustRunCluster(t, 4) defer c.Close() node0 := c.GetNode(0) @@ -185,19 +158,19 @@ func TestTranslation_KeyNotFound(t *testing.T) { node3 := c.GetNode(3) ctx := context.Background() - idx, fld := "i", "f" + index, fld := c.Idx(), "f" // Create an index with keys. - if _, err := node0.API.CreateIndex(ctx, idx, pilosa.IndexOptions{Keys: true}); err != nil { + if _, err := node0.API.CreateIndex(ctx, index, pilosa.IndexOptions{Keys: true}); err != nil { t.Fatal(err) } // Create an index with keys. - if _, err := node0.API.CreateField(ctx, idx, fld, pilosa.OptFieldKeys()); err != nil { + if _, err := node0.API.CreateField(ctx, index, fld, pilosa.OptFieldKeys()); err != nil { t.Fatal(err) } // write a new key and get id req, err := node0.API.Serializer.Marshal(&pilosa.TranslateKeysRequest{ - Index: idx, + Index: index, Field: fld, Keys: []string{"k1"}, NotWritable: false, @@ -217,7 +190,7 @@ func TestTranslation_KeyNotFound(t *testing.T) { // read non-existing key req, err = node3.API.Serializer.Marshal(&pilosa.TranslateKeysRequest{ - Index: idx, + Index: index, Field: fld, Keys: []string{"k2"}, NotWritable: true, @@ -235,7 +208,7 @@ func TestTranslation_KeyNotFound(t *testing.T) { } req, err = node1.API.Serializer.Marshal(&pilosa.TranslateKeysRequest{ - Index: idx, + Index: index, Keys: []string{"k2"}, NotWritable: true, }) @@ -252,7 +225,7 @@ func TestTranslation_KeyNotFound(t *testing.T) { } req, err = node2.API.Serializer.Marshal(&pilosa.TranslateKeysRequest{ - Index: idx, + Index: index, Field: fld, Keys: []string{"k2", "k1"}, NotWritable: false, @@ -307,37 +280,18 @@ func TestTranslation_Primary(t *testing.T) { // non-primary nodes are forwarded to the primary. t.Run("ForwardFieldKey", func(t *testing.T) { // Start a 2-node cluster. - c := test.MustRunCluster(t, 3, - []server.CommandOption{ - server.OptCommandServerOptions( - pilosa.OptServerNodeID("node0"), - pilosa.OptServerOpenTranslateStore(boltdb.OpenTranslateStore), - pilosa.OptServerOpenTranslateReader(pilosa.GetOpenTranslateReaderFunc(nil)), - )}, - []server.CommandOption{ - server.OptCommandServerOptions( - pilosa.OptServerNodeID("node1"), - pilosa.OptServerOpenTranslateStore(boltdb.OpenTranslateStore), - pilosa.OptServerOpenTranslateReader(pilosa.GetOpenTranslateReaderFunc(nil)), - )}, - []server.CommandOption{ - server.OptCommandServerOptions( - pilosa.OptServerNodeID("node2"), - pilosa.OptServerOpenTranslateStore(boltdb.OpenTranslateStore), - pilosa.OptServerOpenTranslateReader(pilosa.GetOpenTranslateReaderFunc(nil)), - )}, - ) + c := test.MustRunCluster(t, 3) defer c.Close() node0 := c.GetPrimary() node1 := c.GetNonPrimary() ctx := context.Background() - idx := "i" + index := c.Idx() fld := "f" // Create an index without keys. - if _, err := node1.API.CreateIndex(ctx, idx, + if _, err := node1.API.CreateIndex(ctx, index, pilosa.IndexOptions{ Keys: false, }); err != nil { @@ -345,7 +299,7 @@ func TestTranslation_Primary(t *testing.T) { } // Create a field with keys. - if _, err := node1.API.CreateField(ctx, idx, fld, + if _, err := node1.API.CreateField(ctx, index, fld, pilosa.OptFieldKeys(), ); err != nil { t.Fatal(err) @@ -357,7 +311,7 @@ func TestTranslation_Primary(t *testing.T) { // Send a translation request to node1 (non-primary). _, err := node1.API.Query(ctx, - &pilosa.QueryRequest{Index: idx, Query: pql}, + &pilosa.QueryRequest{Index: index, Query: pql}, ) if err != nil { t.Fatal(err) @@ -368,7 +322,7 @@ func TestTranslation_Primary(t *testing.T) { // Read the row and ensure the key was set. qry := fmt.Sprintf(`Row(%s="%s")`, fld, keys[i]) resp, err := node0.API.Query(ctx, - &pilosa.QueryRequest{Index: idx, Query: qry}, + &pilosa.QueryRequest{Index: index, Query: qry}, ) if err != nil { t.Fatal(err) @@ -383,53 +337,28 @@ func TestTranslation_Primary(t *testing.T) { } func TestTranslation_TranslateIDsOnCluster(t *testing.T) { - c := test.MustRunCluster(t, 4, - []server.CommandOption{ - server.OptCommandServerOptions( - pilosa.OptServerNodeID("node0"), - pilosa.OptServerOpenTranslateStore(boltdb.OpenTranslateStore), - pilosa.OptServerOpenTranslateReader(pilosa.GetOpenTranslateReaderFunc(nil)), - )}, - []server.CommandOption{ - server.OptCommandServerOptions( - pilosa.OptServerNodeID("node1"), - pilosa.OptServerOpenTranslateStore(boltdb.OpenTranslateStore), - pilosa.OptServerOpenTranslateReader(pilosa.GetOpenTranslateReaderFunc(nil)), - )}, - []server.CommandOption{ - server.OptCommandServerOptions( - pilosa.OptServerNodeID("node2"), - pilosa.OptServerOpenTranslateStore(boltdb.OpenTranslateStore), - pilosa.OptServerOpenTranslateReader(pilosa.GetOpenTranslateReaderFunc(nil)), - )}, - []server.CommandOption{ - server.OptCommandServerOptions( - pilosa.OptServerNodeID("node3"), - pilosa.OptServerOpenTranslateStore(boltdb.OpenTranslateStore), - pilosa.OptServerOpenTranslateReader(pilosa.GetOpenTranslateReaderFunc(nil)), - )}, - ) + c := test.MustRunCluster(t, 4) defer c.Close() coord := c.GetPrimary() other := c.GetNonPrimary() ctx := context.Background() - idx, fld := "i", "f" + index, fld := c.Idx(), "f" // Create an index with keys. - if _, err := coord.API.CreateIndex(ctx, idx, pilosa.IndexOptions{Keys: true}); err != nil { + if _, err := coord.API.CreateIndex(ctx, index, pilosa.IndexOptions{Keys: true}); err != nil { t.Fatal(err) } // Create an index with keys. - if _, err := coord.API.CreateField(ctx, idx, fld, pilosa.OptFieldKeys()); err != nil { + if _, err := coord.API.CreateField(ctx, index, fld, pilosa.OptFieldKeys()); err != nil { t.Fatal(err) } keys := []string{"k0", "k1", "k2", "k3", "k4", "k5", "k6", "k7", "k8", "k9"} // write a new key and get id req, err := coord.API.Serializer.Marshal(&pilosa.TranslateKeysRequest{ - Index: idx, + Index: index, Field: fld, Keys: keys, NotWritable: false, @@ -451,7 +380,7 @@ func TestTranslation_TranslateIDsOnCluster(t *testing.T) { // translate ids req, err = other.API.Serializer.Marshal(&pilosa.TranslateIDsRequest{ - Index: idx, + Index: index, Field: fld, IDs: ids, }) @@ -473,7 +402,7 @@ func TestTranslation_Cluster_CreateFind(t *testing.T) { c := test.MustRunCluster(t, 3) defer c.Close() - c.CreateField(t, "i", pilosa.IndexOptions{Keys: true}, "f", pilosa.OptFieldKeys()) + c.CreateField(t, c.Idx(), pilosa.IndexOptions{Keys: true}, "f", pilosa.OptFieldKeys()) ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() @@ -503,7 +432,7 @@ func TestTranslation_Cluster_CreateFind(t *testing.T) { for i, keys := range parts { i, keys := i, keys g.Go(func() error { - _, err := c.GetNode(i).API.CreateIndexKeys(ctx, "i", keys...) + _, err := c.GetNode(i).API.CreateIndexKeys(ctx, c.Idx(), keys...) return err }) } @@ -522,7 +451,7 @@ func TestTranslation_Cluster_CreateFind(t *testing.T) { } // Obtain authoritative translations for the keys. - translations, err := c.GetPrimary().API.FindIndexKeys(ctx, "i", keyList...) + translations, err := c.GetPrimary().API.FindIndexKeys(ctx, c.Idx(), keyList...) if err != nil { t.Errorf("obtaining authoritative translations: %v", err) return @@ -540,7 +469,7 @@ func TestTranslation_Cluster_CreateFind(t *testing.T) { x, api := i, n.API g.Go(func() (err error) { defer func() { err = errors.Wrapf(err, "translating on node %d", x) }() - localTranslations, err := api.FindIndexKeys(ctx, "i", keyList...) + localTranslations, err := api.FindIndexKeys(ctx, c.Idx(), keyList...) if err != nil { return errors.Wrap(err, "finding translations") } @@ -557,7 +486,7 @@ func TestTranslation_Cluster_CreateFind(t *testing.T) { x, api := i, n.API g.Go(func() (err error) { defer func() { err = errors.Wrapf(err, "translating on node %d", x) }() - localTranslations, err := api.CreateIndexKeys(ctx, "i", keyList...) + localTranslations, err := api.CreateIndexKeys(ctx, c.Idx(), keyList...) if err != nil { return errors.Wrap(err, "finding translations") } @@ -589,7 +518,7 @@ func TestTranslation_Cluster_CreateFind(t *testing.T) { for i, keys := range parts { i, keys := i, keys g.Go(func() error { - _, err := c.GetNode(i).API.CreateFieldKeys(ctx, "i", "f", keys...) + _, err := c.GetNode(i).API.CreateFieldKeys(ctx, c.Idx(), "f", keys...) return err }) } @@ -608,7 +537,7 @@ func TestTranslation_Cluster_CreateFind(t *testing.T) { } // Obtain authoritative translations for the keys. - translations, err := c.GetPrimary().API.FindFieldKeys(ctx, "i", "f", keyList...) + translations, err := c.GetPrimary().API.FindFieldKeys(ctx, c.Idx(), "f", keyList...) if err != nil { t.Errorf("obtaining authoritative translations: %v", err) return @@ -626,7 +555,7 @@ func TestTranslation_Cluster_CreateFind(t *testing.T) { x, api := i, n.API g.Go(func() (err error) { defer func() { err = errors.Wrapf(err, "translating on node %d", x) }() - localTranslations, err := api.FindFieldKeys(ctx, "i", "f", keyList...) + localTranslations, err := api.FindFieldKeys(ctx, c.Idx(), "f", keyList...) if err != nil { return errors.Wrap(err, "finding translations") } @@ -643,7 +572,7 @@ func TestTranslation_Cluster_CreateFind(t *testing.T) { x, api := i, n.API g.Go(func() (err error) { defer func() { err = errors.Wrapf(err, "translating on node %d", x) }() - localTranslations, err := api.CreateFieldKeys(ctx, "i", "f", keyList...) + localTranslations, err := api.CreateFieldKeys(ctx, c.Idx(), "f", keyList...) if err != nil { return errors.Wrap(err, "finding translations") } @@ -661,19 +590,20 @@ func TestTranslation_Cluster_CreateFind(t *testing.T) { func TestTranslation_Cluster_CreateFindUnkeyed(t *testing.T) { c := test.MustRunCluster(t, 3) defer c.Close() + i := c.Idx() - c.CreateField(t, "i", pilosa.IndexOptions{}, "f") + c.CreateField(t, i, pilosa.IndexOptions{}, "f") t.Run("Index", func(t *testing.T) { t.Run("Create", func(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() - _, err := c.GetNonPrimary().API.CreateIndexKeys(ctx, "i", "foo") + _, err := c.GetNonPrimary().API.CreateIndexKeys(ctx, i, "foo") if err == nil { t.Fatal("unexpected success") } - expect := `cannot create keys on unkeyed index "i"` + expect := fmt.Sprintf(`cannot create keys on unkeyed index "%s"`, i) if got := err.Error(); got != expect { t.Fatalf("expected error %q but got %q", expect, got) } @@ -682,11 +612,11 @@ func TestTranslation_Cluster_CreateFindUnkeyed(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() - _, err := c.GetNonPrimary().API.FindIndexKeys(ctx, "i", "foo") + _, err := c.GetNonPrimary().API.FindIndexKeys(ctx, i, "foo") if err == nil { t.Fatal("unexpected success") } - expect := `cannot find keys on unkeyed index "i"` + expect := fmt.Sprintf(`cannot find keys on unkeyed index "%s"`, i) if got := err.Error(); got != expect { t.Fatalf("expected error %q but got %q", expect, got) } @@ -697,7 +627,7 @@ func TestTranslation_Cluster_CreateFindUnkeyed(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() - _, err := c.GetNonPrimary().API.CreateFieldKeys(ctx, "i", "f", "foo") + _, err := c.GetNonPrimary().API.CreateFieldKeys(ctx, i, "f", "foo") if err == nil { t.Fatal("unexpected success") } @@ -710,7 +640,7 @@ func TestTranslation_Cluster_CreateFindUnkeyed(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() - _, err := c.GetNonPrimary().API.FindFieldKeys(ctx, "i", "f", "foo") + _, err := c.GetNonPrimary().API.FindFieldKeys(ctx, i, "f", "foo") if err == nil { t.Fatal("unexpected success") } diff --git a/tx_test.go b/tx_test.go index 08d04fa9a..460eba8f9 100644 --- a/tx_test.go +++ b/tx_test.go @@ -7,10 +7,9 @@ import ( "fmt" "testing" - pilosa "github.com/featurebasedb/featurebase/v3" - "github.com/featurebasedb/featurebase/v3/server" - "github.com/featurebasedb/featurebase/v3/test" - . "github.com/featurebasedb/featurebase/v3/vprint" // nolint:staticcheck + pilosa "github.com/molecula/featurebase/v3" + "github.com/molecula/featurebase/v3/test" + . "github.com/molecula/featurebase/v3/vprint" // nolint:staticcheck ) func queryIRABit(m0api *pilosa.API, acctOwnerID uint64, iraField string, iraRowID uint64, index string) (bit bool) { @@ -46,21 +45,14 @@ func queryBalances(m0api *pilosa.API, acctOwnerID uint64, fldAcct0, fldAcct1, in } func TestAPI_ImportAtomicRecord(t *testing.T) { - c := test.MustRunCluster(t, 1, - []server.CommandOption{ - server.OptCommandServerOptions( - pilosa.OptServerNodeID("node0"), - pilosa.OptServerClusterHasher(&offsetModHasher{}), - pilosa.OptServerOpenTranslateReader(pilosa.GetOpenTranslateReaderFunc(nil)), - )}, - ) + c := test.MustRunCluster(t, 1) defer c.Close() m0 := c.GetNode(0) m0api := m0.API ctx := context.Background() - index := "i" + index := c.Idx() fieldAcct0 := "acct0" fieldAcct1 := "acct1" diff --git a/utils_internal_test.go b/utils_internal_test.go index 387b3dbd6..a76b31363 100644 --- a/utils_internal_test.go +++ b/utils_internal_test.go @@ -17,7 +17,7 @@ import ( // NewTestCluster returns a cluster with n nodes and uses a mod-based hasher. func NewTestCluster(tb testing.TB, n int) *cluster { - if n > 1 && etcd.AllowCluster() { + if n > 1 && !etcd.AllowCluster() { tb.Skipf("cluster size %d not supported in unclustered mode", n) } path, err := testhook.TempDir(tb, "pilosa-cluster-") @@ -28,7 +28,7 @@ func NewTestCluster(tb testing.TB, n int) *cluster { availableShardFileFlushDuration.Set(100 * time.Millisecond) c := newCluster() c.ReplicaN = 1 - c.Hasher = NewTestModHasher() + c.Hasher = &disco.Jmphasher{} c.Path = path nodes := make([]*disco.Node, 0, n) @@ -63,16 +63,6 @@ func NewTestURIFromHostPort(host string, port uint16) pnet.URI { return *uri } -// ModHasher represents a simple, mod-based hashing. -type TestModHasher struct{} - -// NewTestModHasher returns a new instance of ModHasher with n buckets. -func NewTestModHasher() *TestModHasher { return &TestModHasher{} } - -func (*TestModHasher) Hash(key uint64, n int) int { return int(key) % n } - -func (*TestModHasher) Name() string { return "mod" } - func TestReplaceFirstFromBack(t *testing.T) { for name, test := range map[string]struct { input string