diff --git a/api_test.go b/api_test.go index 43577ddac..25b885957 100644 --- a/api_test.go +++ b/api_test.go @@ -24,7 +24,6 @@ import ( "github.com/golang-jwt/jwt" pilosa "github.com/molecula/featurebase/v3" "github.com/molecula/featurebase/v3/authn" - "github.com/molecula/featurebase/v3/boltdb" "github.com/molecula/featurebase/v3/roaring" "github.com/molecula/featurebase/v3/server" "github.com/molecula/featurebase/v3/shardwidth" @@ -35,35 +34,13 @@ import ( ) 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() @@ -103,7 +80,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], @@ -151,7 +128,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 { @@ -223,26 +200,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() @@ -252,7 +210,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}) @@ -274,7 +232,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, @@ -292,18 +250,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 { @@ -313,7 +277,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) @@ -386,7 +350,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, @@ -409,7 +373,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{}) @@ -423,9 +387,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{}) @@ -446,7 +410,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, @@ -471,9 +435,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" @@ -505,8 +469,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, @@ -533,17 +496,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" @@ -653,7 +609,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) } @@ -665,19 +621,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) @@ -698,23 +654,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) @@ -746,14 +702,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() @@ -761,7 +710,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" @@ -797,24 +746,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: @@ -827,7 +760,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) @@ -1071,7 +1004,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 } @@ -1093,7 +1028,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) @@ -1445,14 +1380,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) } @@ -1470,8 +1405,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) } @@ -1488,8 +1423,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) } @@ -1497,7 +1432,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) } @@ -1507,8 +1442,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) } @@ -1528,7 +1463,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()) @@ -1536,7 +1471,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 } @@ -1556,19 +1491,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") @@ -1698,25 +1626,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), }, @@ -1726,6 +1651,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 81c7013be..fc2516126 100644 --- a/client/client_it_test.go +++ b/client/client_it_test.go @@ -70,7 +70,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 ccd53026e..cdf19dee9 100644 --- a/cluster_internal_test.go +++ b/cluster_internal_test.go @@ -9,51 +9,11 @@ import ( "testing/quick" "time" - "github.com/davecgh/go-spew/spew" "github.com/molecula/featurebase/v3/disco" pnet "github.com/molecula/featurebase/v3/net" "github.com/molecula/featurebase/v3/roaring" - "github.com/molecula/featurebase/v3/testhook" - . "github.com/molecula/featurebase/v3/vprint" // nolint:staticcheck ) -// newHolderWithTempPath returns a new instance of Holder. -func newHolderWithTempPath(tb testing.TB, backend string) *Holder { - path, err := testhook.TempDirInDir(tb, *TempDir, "pilosa-holder-") - if err != nil { - panic(err) - } - cfg := mustHolderConfig() - cfg.StorageConfig.Backend = backend - h := NewHolder(path, cfg) - PanicOn(h.Open()) - testhook.Cleanup(tb, func() { - h.Close() - }) - return h -} - -// newIndexWithTempPath returns a new instance of Index. -func newIndexWithTempPath(tb testing.TB, name string) *Index { - path, err := testhook.TempDirInDir(tb, *TempDir, "pilosa-index-") - if err != nil { - panic(err) - } - cfg := DefaultHolderConfig() - cfg.StorageConfig.FsyncEnabled = false - cfg.RBFConfig.FsyncEnabled = false - h := NewHolder(path, cfg) - PanicOn(h.Open()) - index, err := h.CreateIndex(name, IndexOptions{}) - testhook.Cleanup(tb, func() { - h.Close() - }) - if err != nil { - panic(err) - } - return index -} - // Ensure the cluster can fairly distribute partitions across the nodes. func TestCluster_Owners(t *testing.T) { c := cluster{ @@ -62,7 +22,7 @@ func TestCluster_Owners(t *testing.T) { {URI: NewTestURIFromHostPort("serverB", 1000)}, {URI: NewTestURIFromHostPort("serverC", 1000)}, }), - Hasher: NewTestModHasher(), + Hasher: &disco.Jmphasher{}, ReplicaN: 2, } @@ -71,14 +31,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) + } } } @@ -135,10 +105,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 ac474353a..28ef65381 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 95ff92eea..533d9e9f2 100644 --- a/dbshard_test.go +++ b/dbshard_test.go @@ -4,34 +4,23 @@ package pilosa_test import ( "context" "fmt" - "reflect" "testing" pilosa "github.com/molecula/featurebase/v3" - "github.com/molecula/featurebase/v3/boltdb" - "github.com/molecula/featurebase/v3/server" "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}) @@ -65,7 +54,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(), @@ -88,9 +77,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 a7906f891..b92bc192b 100644 --- a/delete_test.go +++ b/delete_test.go @@ -5,6 +5,7 @@ import ( "context" "fmt" "math" + "sort" "testing" "time" @@ -15,7 +16,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") @@ -110,13 +113,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) @@ -143,7 +139,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") @@ -151,6 +149,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) @@ -239,13 +238,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) @@ -257,7 +252,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 29d792253..488e08349 100644 --- a/executor.go +++ b/executor.go @@ -3051,7 +3051,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 68c3c00de..d877a9ef4 100644 --- a/executor_internal_test.go +++ b/executor_internal_test.go @@ -6,6 +6,7 @@ import ( "encoding/json" "fmt" "reflect" + "sort" "strconv" "testing" "time" @@ -14,6 +15,30 @@ import ( "github.com/molecula/featurebase/v3/testhook" ) +// 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 64dc70818..bcedd4573 100644 --- a/executor_test.go +++ b/executor_test.go @@ -4,7 +4,6 @@ package pilosa_test import ( "bytes" "context" - "crypto/md5" "database/sql" "encoding/csv" "encoding/json" @@ -24,9 +23,7 @@ import ( "github.com/davecgh/go-spew/spew" "github.com/google/go-cmp/cmp" - "github.com/google/go-cmp/cmp/cmpopts" pilosa "github.com/molecula/featurebase/v3" - "github.com/molecula/featurebase/v3/boltdb" "github.com/molecula/featurebase/v3/ctl" "github.com/molecula/featurebase/v3/disco" "github.com/molecula/featurebase/v3/pql" @@ -38,9 +35,6 @@ import ( "github.com/pkg/errors" ) -// writable initializes Tx that update, use !writable for read-only. -const writable = true - var ( TempDir = getTempDirString() ) @@ -59,10 +53,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) { @@ -85,7 +76,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) } }) @@ -112,10 +104,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) } }) }) @@ -131,7 +122,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) } }) @@ -162,7 +154,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) } }) @@ -180,7 +173,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) } }) @@ -213,7 +207,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) } }) @@ -231,7 +226,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) } }) @@ -264,7 +260,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) } }) @@ -282,7 +279,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) } }) @@ -315,7 +313,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) } }) @@ -537,13 +536,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) } }) @@ -607,13 +608,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) } }) @@ -722,13 +725,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) } }) @@ -792,13 +797,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) } }) @@ -857,7 +864,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) } }) @@ -888,7 +896,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) } }) @@ -1061,9 +1070,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]}) }) } }) @@ -1076,7 +1084,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 @@ -1139,7 +1147,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{} @@ -1187,14 +1195,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) { @@ -1209,13 +1217,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) @@ -1228,9 +1236,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) } } @@ -1241,14 +1249,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) @@ -1261,7 +1269,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) } } @@ -1272,14 +1280,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) @@ -1292,9 +1300,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) @@ -1308,14 +1316,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) @@ -1331,11 +1339,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]) @@ -1347,28 +1355,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") @@ -1376,53 +1384,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") @@ -1430,7 +1438,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) @@ -1440,11 +1448,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") @@ -1452,15 +1460,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") @@ -1478,41 +1486,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) @@ -1524,18 +1532,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") } @@ -1550,32 +1558,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) @@ -1587,13 +1595,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") } }) @@ -1606,9 +1614,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) } } @@ -1621,7 +1629,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 { @@ -1629,9 +1637,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) } @@ -1640,7 +1648,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 { @@ -1663,25 +1671,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) } }) @@ -1693,7 +1701,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 { @@ -1701,9 +1709,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) } @@ -1712,7 +1720,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 { @@ -1775,9 +1783,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{ @@ -1798,11 +1806,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) @@ -1812,7 +1820,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{ @@ -1834,13 +1842,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) @@ -1859,7 +1867,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{ @@ -1878,13 +1886,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) @@ -1903,7 +1911,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{ @@ -1922,13 +1930,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") @@ -1947,7 +1955,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{ @@ -1968,13 +1976,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") @@ -1993,7 +2001,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{ @@ -2014,11 +2022,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 { @@ -2028,7 +2036,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) } }) @@ -2039,11 +2047,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) } }) @@ -2053,16 +2061,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) } }) @@ -2074,15 +2082,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{ @@ -2100,26 +2108,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{ @@ -2138,19 +2146,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 { @@ -2158,7 +2166,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{ @@ -2180,7 +2188,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) } @@ -2202,7 +2210,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) @@ -2212,7 +2220,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)) @@ -2221,7 +2229,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)) @@ -2230,7 +2238,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)) @@ -2239,7 +2247,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)) @@ -2248,7 +2256,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)) @@ -2257,7 +2265,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)) @@ -2272,7 +2280,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) } @@ -2319,28 +2327,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") @@ -2352,7 +2360,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) @@ -2362,7 +2370,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)) @@ -2371,7 +2379,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)) @@ -2380,7 +2388,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)) @@ -2389,7 +2397,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)) @@ -2404,7 +2412,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) } @@ -2423,7 +2431,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) } @@ -2431,7 +2439,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)) @@ -2440,7 +2448,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)) @@ -2449,7 +2457,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)) @@ -2458,7 +2466,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)) @@ -2467,7 +2475,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)) @@ -2476,7 +2484,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)) @@ -2492,7 +2500,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) } @@ -2505,7 +2513,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) @@ -2542,7 +2550,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)) @@ -2556,7 +2564,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) } @@ -2569,7 +2577,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) @@ -2606,7 +2614,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)) @@ -2632,7 +2640,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)) @@ -2649,7 +2657,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) } @@ -2658,7 +2666,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) @@ -2669,7 +2677,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) } @@ -2682,13 +2690,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) } @@ -2701,7 +2709,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) } @@ -2713,7 +2721,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) } @@ -2722,7 +2730,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") @@ -2733,7 +2741,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) } @@ -2747,7 +2755,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) } @@ -2769,7 +2777,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) } @@ -2794,7 +2802,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) @@ -2815,7 +2823,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)) @@ -2823,7 +2831,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)) @@ -2831,7 +2839,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)) @@ -2839,7 +2847,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)) @@ -2847,7 +2855,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)) @@ -2856,7 +2864,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) } @@ -2864,7 +2872,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)) @@ -2872,7 +2880,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)) @@ -2880,7 +2888,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)) @@ -2888,7 +2896,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)) @@ -2903,7 +2911,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) } @@ -2924,7 +2932,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) @@ -2940,7 +2948,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)) @@ -2948,7 +2956,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)) @@ -2963,7 +2971,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) } @@ -2981,7 +2989,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) @@ -2994,7 +3002,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) } @@ -3019,7 +3027,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) @@ -3038,7 +3046,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, @@ -3050,14 +3058,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) @@ -3066,19 +3074,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()) @@ -3086,7 +3094,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)) @@ -3094,7 +3102,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) @@ -3102,7 +3110,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()) @@ -3110,7 +3118,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()) @@ -3143,7 +3151,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()) @@ -3155,7 +3163,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)) @@ -3163,7 +3171,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)) @@ -3171,7 +3179,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)) @@ -3179,7 +3187,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())) @@ -3187,7 +3195,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())) @@ -3195,7 +3203,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) } }) @@ -3207,7 +3215,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) } @@ -3220,13 +3228,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) @@ -3241,13 +3249,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) @@ -3260,7 +3268,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) @@ -3279,7 +3287,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) @@ -3294,7 +3302,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) } @@ -3319,7 +3327,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) @@ -3337,7 +3345,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)) @@ -3346,19 +3354,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()) @@ -3366,7 +3374,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)) @@ -3374,7 +3382,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)) @@ -3382,7 +3390,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)) @@ -3390,7 +3398,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)) @@ -3398,7 +3406,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)) @@ -3407,7 +3415,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)) @@ -3415,7 +3423,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)) @@ -3423,7 +3431,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)) @@ -3431,7 +3439,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())) @@ -3439,7 +3447,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())) @@ -3447,7 +3455,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) } }) @@ -3455,37 +3463,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]) @@ -3493,36 +3505,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) @@ -3537,7 +3551,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) @@ -3555,7 +3569,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) @@ -3571,14 +3585,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) @@ -3592,11 +3606,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) @@ -3615,7 +3629,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) @@ -3634,11 +3648,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) @@ -3647,7 +3661,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) @@ -3665,16 +3679,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) @@ -3683,7 +3697,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) @@ -3700,16 +3714,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) @@ -3718,7 +3732,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) @@ -3734,27 +3748,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") @@ -3763,7 +3777,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) @@ -3782,7 +3796,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() @@ -3790,8 +3804,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) } } @@ -3833,7 +3847,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 { @@ -3866,6 +3880,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") @@ -3912,15 +3928,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 { @@ -3929,7 +3941,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), @@ -3937,13 +3949,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) @@ -3959,10 +3971,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) @@ -3984,10 +3996,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) @@ -3998,10 +4010,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) @@ -4017,24 +4029,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 { @@ -4073,8 +4085,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}, @@ -4089,7 +4101,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) } @@ -4112,7 +4124,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) } @@ -4139,7 +4151,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) } @@ -4166,7 +4178,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) } @@ -4183,7 +4195,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)) } @@ -4214,18 +4226,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) @@ -4234,8 +4246,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") @@ -4245,13 +4257,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", @@ -4262,18 +4274,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", @@ -4289,7 +4301,7 @@ func TestExecutor_Sort(t *testing.T) { }, }, }, - pilosa.ExtractedTable{ + { Fields: []pilosa.ExtractedTableField{ { Name: "keymutex", @@ -4308,7 +4320,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]) } @@ -4323,7 +4335,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) @@ -4369,7 +4381,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?") @@ -4396,7 +4408,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) @@ -4412,15 +4424,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) @@ -4465,7 +4472,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) @@ -4485,12 +4492,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) @@ -4499,7 +4506,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) @@ -4513,14 +4520,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") } }) @@ -4529,7 +4536,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) @@ -4559,7 +4566,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) } @@ -4568,7 +4575,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{ @@ -4582,14 +4589,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{ @@ -4609,7 +4616,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) } @@ -4618,7 +4625,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), @@ -4626,35 +4633,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) @@ -4664,14 +4671,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), @@ -4679,35 +4686,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) @@ -4717,14 +4724,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) + @@ -4734,21 +4741,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) @@ -4758,45 +4765,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) @@ -4805,7 +4812,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 { @@ -4818,7 +4825,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}) @@ -4858,8 +4865,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}, @@ -4867,72 +4874,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{ @@ -5105,8 +5112,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) @@ -5114,7 +5121,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{ @@ -5123,13 +5130,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{}{ @@ -5147,6 +5150,12 @@ func TestExecutor_Execute_Extract_Keyed(t *testing.T) { }, }, }, + { + Column: pilosa.KeyOrID{Keyed: true, Key: "plugh"}, + Rows: []interface{}{ + []uint64{}, + }, + }, }, }, } @@ -5160,8 +5169,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}, @@ -5169,10 +5178,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, }) @@ -5229,8 +5238,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}, @@ -5240,63 +5249,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 @@ -5367,7 +5354,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 { @@ -5383,15 +5370,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"}, @@ -5408,7 +5395,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"}, @@ -5418,7 +5405,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"}, @@ -5428,7 +5415,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"}, @@ -5438,7 +5425,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"}, @@ -5448,7 +5435,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"}, @@ -5637,7 +5624,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 { @@ -5653,17 +5640,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) } @@ -5682,7 +5669,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 { @@ -5786,7 +5773,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) } @@ -5820,21 +5807,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) @@ -5847,7 +5837,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) @@ -5861,13 +5851,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") @@ -5875,43 +5865,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) } @@ -5945,9 +5935,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}, @@ -5957,14 +5947,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) } }) @@ -5974,11 +5964,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}, @@ -5988,7 +5978,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}, @@ -5998,16 +5988,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) } @@ -6015,7 +6005,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) } @@ -6032,7 +6022,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) }) @@ -6044,7 +6034,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) }) @@ -6054,7 +6044,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) }) @@ -6064,7 +6054,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) }) @@ -6076,7 +6066,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) }) @@ -6085,7 +6075,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) }) @@ -6097,7 +6087,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) }) @@ -6107,7 +6097,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) }) @@ -6116,18 +6106,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}, }) @@ -6137,27 +6127,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}, @@ -6165,7 +6155,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}, @@ -6175,14 +6165,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}, } @@ -6191,22 +6181,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}, @@ -6218,7 +6208,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}, @@ -6229,7 +6219,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}, @@ -6239,22 +6229,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}, @@ -6267,22 +6257,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}, @@ -6291,12 +6281,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...) } @@ -6310,9 +6300,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") @@ -6338,19 +6328,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) @@ -6358,7 +6348,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") @@ -6378,22 +6368,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{ @@ -6411,8 +6401,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 @@ -6436,8 +6426,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) } @@ -6451,7 +6440,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 { @@ -6462,9 +6451,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) @@ -6487,15 +6476,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))`) } }) @@ -6503,7 +6492,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)`) } }) @@ -6522,15 +6511,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) @@ -6541,9 +6530,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) @@ -6560,22 +6549,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) @@ -6586,18 +6575,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) @@ -6610,9 +6599,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 @@ -6626,7 +6615,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) @@ -6641,7 +6630,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) } @@ -6649,7 +6638,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) @@ -6667,7 +6656,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) @@ -6681,11 +6670,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()) @@ -6694,7 +6683,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()) @@ -6708,7 +6697,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) } @@ -6725,7 +6714,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) @@ -6764,7 +6753,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)) @@ -6773,14 +6762,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) } @@ -6801,7 +6790,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])) @@ -6824,7 +6813,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)) @@ -6848,7 +6837,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])) @@ -6859,14 +6848,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) @@ -6880,14 +6869,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'") @@ -6895,6 +6884,8 @@ func TestExecutor_Execute_NoIndex(t *testing.T) { } func TestExecutor_Execute_CountDistinct(t *testing.T) { + // 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) @@ -6909,6 +6900,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) @@ -6933,22 +6928,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 { @@ -6973,7 +6969,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 { @@ -6991,7 +6987,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 { @@ -7014,14 +7010,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 { @@ -7037,14 +7033,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 { @@ -7062,7 +7058,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 @@ -7099,28 +7095,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) } @@ -7142,6 +7140,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) } @@ -7153,12 +7156,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 { @@ -7181,12 +7184,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) @@ -7194,10 +7197,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]) } } @@ -7217,6 +7220,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) } @@ -7247,7 +7254,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 @@ -7311,7 +7318,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 @@ -7344,13 +7351,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) @@ -7359,7 +7370,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 + }) }) } } @@ -7369,12 +7382,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) @@ -8945,9 +8957,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}, @@ -8960,8 +8974,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}, @@ -8990,7 +9004,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) @@ -9000,10 +9014,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 @@ -9195,8 +9207,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}, @@ -9328,7 +9340,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) } @@ -9336,8 +9348,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) @@ -9471,10 +9483,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")) @@ -9564,16 +9576,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)) } @@ -9605,8 +9617,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)) } @@ -9639,8 +9651,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)) } @@ -9675,10 +9687,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) { @@ -9690,7 +9699,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 dfa4c70d7..fe1367684 100644 --- a/holder_test.go +++ b/holder_test.go @@ -217,7 +217,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 @@ -229,27 +229,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) } @@ -258,29 +258,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 { @@ -293,34 +293,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) } } @@ -329,7 +329,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 @@ -342,11 +342,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) } @@ -358,13 +358,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. // @@ -375,10 +375,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) } } @@ -386,7 +386,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 @@ -399,11 +399,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) } @@ -414,13 +414,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 { @@ -429,7 +429,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) } } @@ -437,7 +437,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 @@ -450,11 +450,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) } @@ -465,11 +465,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 { @@ -478,10 +478,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) } } @@ -490,7 +490,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 @@ -502,12 +502,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) } @@ -516,12 +516,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() @@ -536,11 +536,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) } } @@ -548,7 +548,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 @@ -561,12 +561,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) } @@ -575,18 +575,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] @@ -603,10 +603,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 17bf55d3c..8650328cf 100644 --- a/http_handler_test.go +++ b/http_handler_test.go @@ -171,10 +171,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) @@ -212,12 +213,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) } } @@ -275,11 +285,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) @@ -313,33 +325,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": [ @@ -404,7 +417,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)) @@ -421,15 +434,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)) @@ -447,7 +461,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`, @@ -455,28 +469,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", @@ -504,12 +518,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) } } } @@ -521,9 +544,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": [ @@ -536,7 +559,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)) @@ -545,7 +568,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) ` @@ -564,7 +587,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) @@ -594,7 +617,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) @@ -604,7 +627,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) @@ -637,9 +660,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": [ @@ -653,7 +676,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)) @@ -661,9 +684,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 cf4955a67..b83ac9611 100644 --- a/index_test.go +++ b/index_test.go @@ -260,7 +260,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 22597fe2c..2bd248e75 100644 --- a/internal_client_test.go +++ b/internal_client_test.go @@ -19,7 +19,6 @@ import ( "github.com/molecula/featurebase/v3/disco" "github.com/molecula/featurebase/v3/encoding/proto" "github.com/molecula/featurebase/v3/pql" - "github.com/molecula/featurebase/v3/server" "github.com/molecula/featurebase/v3/test" "github.com/molecula/featurebase/v3/vprint" "github.com/pkg/errors" @@ -28,85 +27,86 @@ import ( // 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() @@ -123,19 +123,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) } @@ -156,11 +150,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) } @@ -180,16 +174,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{ @@ -206,7 +202,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, }) @@ -219,7 +215,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) } @@ -240,7 +236,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, }) @@ -253,7 +249,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) } @@ -274,7 +270,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, }) @@ -288,34 +284,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, }) @@ -329,27 +326,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) } }) } @@ -362,16 +360,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"} @@ -426,13 +426,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 { @@ -461,14 +461,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 { @@ -503,32 +503,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) } @@ -538,101 +539,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 } @@ -644,15 +645,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) } @@ -663,7 +664,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) } } @@ -675,18 +676,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}, @@ -696,14 +699,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 { @@ -719,14 +722,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 { @@ -742,14 +745,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 { @@ -771,10 +774,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)) @@ -783,7 +787,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"}, @@ -792,7 +796,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 { @@ -809,7 +813,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"}, @@ -822,7 +826,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 { @@ -848,7 +852,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) @@ -857,7 +861,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}, @@ -872,7 +876,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) } @@ -883,7 +887,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}, @@ -898,7 +902,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) } @@ -923,7 +927,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. @@ -995,7 +999,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) @@ -1004,7 +1008,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}, @@ -1014,7 +1018,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]) @@ -1023,7 +1027,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]) @@ -1036,14 +1040,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}, @@ -1057,7 +1061,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) } @@ -1075,7 +1079,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]) @@ -1084,7 +1088,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]) @@ -1103,7 +1107,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}) @@ -1115,7 +1119,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}, @@ -1139,7 +1143,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}) @@ -1151,7 +1155,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}, @@ -1185,13 +1189,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 { @@ -1203,7 +1207,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)) @@ -1237,7 +1241,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) @@ -1277,7 +1281,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) @@ -1574,19 +1578,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) } @@ -1596,10 +1596,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) } @@ -1608,12 +1608,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 792729d48..bae562472 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 0483fbfd8..f7e4dba7e 100644 --- a/server/server_test.go +++ b/server/server_test.go @@ -235,14 +235,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 @@ -387,10 +387,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) } @@ -401,7 +401,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) } @@ -415,7 +415,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) } @@ -498,7 +498,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 { @@ -564,7 +564,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 } @@ -919,10 +919,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) @@ -933,21 +934,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`) { @@ -983,7 +984,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 { @@ -1040,7 +1042,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 74ad6415a..d061a65e8 100644 --- a/server_test.go +++ b/server_test.go @@ -21,7 +21,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 { @@ -195,7 +195,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 d1bb86e45..ed9ca5a19 100644 --- a/sql/handler_test.go +++ b/sql/handler_test.go @@ -6,7 +6,7 @@ import ( "math" "testing" - "github.com/molecula/featurebase/v3" + pilosa "github.com/molecula/featurebase/v3" "github.com/molecula/featurebase/v3/sql" "github.com/molecula/featurebase/v3/test" "vitess.io/vitess/go/vt/sqlparser" @@ -33,6 +33,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 4515636c9..7194a883b 100644 --- a/stats/stats_test.go +++ b/stats/stats_test.go @@ -111,7 +111,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()} @@ -140,7 +142,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 16c8e2561..af8f44579 100644 --- a/test/cluster.go +++ b/test/cluster.go @@ -7,8 +7,10 @@ import ( "math" "sort" "strings" + "sync" "testing" "time" + "unicode" pilosa "github.com/molecula/featurebase/v3" "github.com/molecula/featurebase/v3/api/client" @@ -22,22 +24,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") @@ -49,7 +115,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") @@ -60,7 +126,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") @@ -92,7 +158,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] } @@ -104,7 +170,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 { @@ -125,7 +191,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 @@ -135,7 +201,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 @@ -145,7 +211,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() { @@ -161,15 +227,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) @@ -236,14 +302,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, @@ -272,7 +339,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, @@ -302,7 +369,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, @@ -328,7 +395,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, @@ -356,7 +423,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, @@ -377,7 +444,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") { @@ -402,11 +469,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 @@ -414,7 +477,7 @@ func (c *Cluster) Start() error { return cc.Start() }) } - err = eg.Wait() + err := eg.Wait() if err != nil { return errors.Wrap(err, "starting cluster") } @@ -422,7 +485,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) @@ -431,7 +504,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) @@ -440,7 +516,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)) } @@ -454,7 +533,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") } @@ -473,16 +552,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 { @@ -493,7 +571,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") } @@ -511,7 +589,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. @@ -521,29 +600,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 { @@ -554,17 +715,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 } @@ -612,3 +807,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 285c5b4f7..16f865f05 100644 --- a/test/disco.go +++ b/test/disco.go @@ -5,7 +5,6 @@ import ( "fmt" "net" "strings" - "testing" "github.com/molecula/featurebase/v3/etcd" "github.com/molecula/featurebase/v3/server" @@ -55,7 +54,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 186568374..0b1263443 100644 --- a/test/pilosa.go +++ b/test/pilosa.go @@ -17,7 +17,6 @@ import ( "github.com/molecula/featurebase/v3/disco" "github.com/molecula/featurebase/v3/encoding/proto" "github.com/molecula/featurebase/v3/server" - "github.com/molecula/featurebase/v3/testhook" ) //////////////////////////////////////////////////////////////////////////////////// @@ -36,11 +35,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 @@ -53,7 +49,7 @@ func newCommand(tb testing.TB, opts ...server.CommandOption) *Command { m := &Command{commandOptions: opts} m.Command = server.NewCommand(bytes.NewReader(nil), ioutil.Discard, ioutil.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) } @@ -80,7 +76,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. @@ -95,7 +91,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 79bc55ca9..343d97f25 100644 --- a/translator_test.go +++ b/translator_test.go @@ -12,10 +12,8 @@ import ( "github.com/google/go-cmp/cmp" pilosa "github.com/molecula/featurebase/v3" - "github.com/molecula/featurebase/v3/boltdb" "github.com/molecula/featurebase/v3/disco" "github.com/molecula/featurebase/v3/mock" - "github.com/molecula/featurebase/v3/server" "github.com/molecula/featurebase/v3/test" "github.com/pkg/errors" "golang.org/x/sync/errgroup" @@ -150,32 +148,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) @@ -184,19 +157,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, @@ -216,7 +189,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, @@ -234,7 +207,7 @@ func TestTranslation_KeyNotFound(t *testing.T) { } req, err = node1.API.Serializer.Marshal(&pilosa.TranslateKeysRequest{ - Index: idx, + Index: index, Keys: []string{"k2"}, NotWritable: true, }) @@ -251,7 +224,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, @@ -306,37 +279,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 { @@ -344,7 +298,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) @@ -356,7 +310,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) @@ -367,7 +321,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) @@ -382,53 +336,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, @@ -450,7 +379,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, }) @@ -472,7 +401,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() @@ -502,7 +431,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 }) } @@ -521,7 +450,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 @@ -539,7 +468,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") } @@ -556,7 +485,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") } @@ -588,7 +517,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 }) } @@ -607,7 +536,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 @@ -625,7 +554,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") } @@ -642,7 +571,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") } @@ -660,19 +589,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) } @@ -681,11 +611,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) } @@ -696,7 +626,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") } @@ -709,7 +639,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 117198c94..1401b3450 100644 --- a/tx_test.go +++ b/tx_test.go @@ -7,7 +7,6 @@ import ( "testing" pilosa "github.com/molecula/featurebase/v3" - "github.com/molecula/featurebase/v3/server" "github.com/molecula/featurebase/v3/test" . "github.com/molecula/featurebase/v3/vprint" // nolint:staticcheck ) @@ -45,21 +44,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 a7dcf4044..b57108fcc 100644 --- a/utils_internal_test.go +++ b/utils_internal_test.go @@ -16,7 +16,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-") @@ -27,7 +27,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) @@ -62,16 +62,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