mirror of
https://github.com/featurebasedb/featurebase.git
synced 2026-09-07 17:15:56 +00:00
address some coord/node0 test issues
This commit is contained in:
parent
315cad679d
commit
4380a05bbd
8 changed files with 114 additions and 89 deletions
30
api_test.go
30
api_test.go
|
|
@ -299,6 +299,7 @@ func TestAPI_ImportValue(t *testing.T) {
|
|||
)
|
||||
defer c.Close()
|
||||
|
||||
coord := c.GetCoordinator()
|
||||
m0 := c.GetNode(0)
|
||||
m1 := c.GetNode(1)
|
||||
|
||||
|
|
@ -307,11 +308,11 @@ func TestAPI_ImportValue(t *testing.T) {
|
|||
index := "valck"
|
||||
field := "f"
|
||||
|
||||
_, err := m0.API.CreateIndex(ctx, index, pilosa.IndexOptions{Keys: true})
|
||||
_, err := coord.API.CreateIndex(ctx, index, pilosa.IndexOptions{Keys: true})
|
||||
if err != nil {
|
||||
t.Fatalf("creating index: %v", err)
|
||||
}
|
||||
_, err = m0.API.CreateField(ctx, index, field, pilosa.OptFieldTypeInt(math.MinInt64, math.MaxInt64))
|
||||
_, err = coord.API.CreateField(ctx, index, field, pilosa.OptFieldTypeInt(math.MinInt64, math.MaxInt64))
|
||||
if err != nil {
|
||||
t.Fatalf("creating field: %v", err)
|
||||
}
|
||||
|
|
@ -334,8 +335,8 @@ func TestAPI_ImportValue(t *testing.T) {
|
|||
Values: values,
|
||||
}
|
||||
|
||||
qcx := m0.API.Txf().NewQcx()
|
||||
if err := m0.API.ImportValue(ctx, qcx, req); err != nil {
|
||||
qcx := coord.API.Txf().NewQcx()
|
||||
if err := coord.API.ImportValue(ctx, qcx, req); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
panicOn(qcx.Finish())
|
||||
|
|
@ -376,7 +377,7 @@ func TestAPI_ImportValue(t *testing.T) {
|
|||
t.Fatalf("creating field: %v", err)
|
||||
}
|
||||
|
||||
// Generate some keyed records.
|
||||
// Generate some records.
|
||||
values := []float64{}
|
||||
colIDs := []uint64{}
|
||||
for i := 0; i < 10; i++ {
|
||||
|
|
@ -384,8 +385,8 @@ func TestAPI_ImportValue(t *testing.T) {
|
|||
colIDs = append(colIDs, uint64(i))
|
||||
}
|
||||
|
||||
// Import data with keys to the coordinator (node0) and verify that it gets
|
||||
// translated and forwarded to the owner of shard 0 (node1; because of offsetModHasher)
|
||||
// Import data with keys to node1 and verify that it gets translated and
|
||||
// forwarded to the owner of shard 0 (node0; because of offsetModHasher)
|
||||
req := &pilosa.ImportValueRequest{
|
||||
Index: index,
|
||||
Field: field,
|
||||
|
|
@ -431,16 +432,16 @@ func TestAPI_ImportValue(t *testing.T) {
|
|||
|
||||
fgnIndex := "fgnvalstr"
|
||||
|
||||
_, err := m0.API.CreateIndex(ctx, index, pilosa.IndexOptions{})
|
||||
_, err := coord.API.CreateIndex(ctx, index, pilosa.IndexOptions{})
|
||||
if err != nil {
|
||||
t.Fatalf("creating index: %v", err)
|
||||
}
|
||||
|
||||
_, err = m0.API.CreateIndex(ctx, fgnIndex, pilosa.IndexOptions{Keys: true})
|
||||
_, err = coord.API.CreateIndex(ctx, fgnIndex, pilosa.IndexOptions{Keys: true})
|
||||
if err != nil {
|
||||
t.Fatalf("creating foreign index: %v", err)
|
||||
}
|
||||
_, err = m0.API.CreateField(ctx, index, field,
|
||||
_, err = coord.API.CreateField(ctx, index, field,
|
||||
pilosa.OptFieldTypeInt(0, math.MaxInt64),
|
||||
pilosa.OptFieldForeignIndex(fgnIndex),
|
||||
)
|
||||
|
|
@ -457,8 +458,9 @@ func TestAPI_ImportValue(t *testing.T) {
|
|||
colIDs = append(colIDs, uint64(i))
|
||||
}
|
||||
|
||||
// Import data with keys to the coordinator (node0) and verify that it gets
|
||||
// translated and forwarded to the owner of shard 0 (node1; because of offsetModHasher)
|
||||
// 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)
|
||||
req := &pilosa.ImportValueRequest{
|
||||
Index: index,
|
||||
Field: field,
|
||||
|
|
@ -473,8 +475,8 @@ func TestAPI_ImportValue(t *testing.T) {
|
|||
|
||||
pql := fmt.Sprintf(`Row(%s=="strval-110")`, field)
|
||||
|
||||
// Query node0.
|
||||
if res, err := m0.API.Query(ctx, &pilosa.QueryRequest{Index: index, Query: pql}); err != nil {
|
||||
// Query node1.
|
||||
if res, err := m1.API.Query(ctx, &pilosa.QueryRequest{Index: index, Query: pql}); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if ids := res.Results[0].(*pilosa.Row).Columns(); !reflect.DeepEqual(ids, []uint64{1}) {
|
||||
t.Fatalf("unexpected columns: observerd %+v; expected '%+v'", ids, []uint64{1})
|
||||
|
|
|
|||
|
|
@ -402,6 +402,9 @@ func check(dirs []string, cfg *FsckConfig, targetIndex string, targetPartition i
|
|||
return firstChecksum, nil
|
||||
}
|
||||
|
||||
// These are here to satisfy the linter in CI while the test is being skipped.
|
||||
var _ = getFwdRev
|
||||
var _ = check
|
||||
var _ = getChecksums
|
||||
|
||||
func getChecksums(dirs []string, cfg *FsckConfig, targetPartition int) (chksum []string) {
|
||||
|
|
|
|||
|
|
@ -2957,11 +2957,11 @@ func TestExecutor_Execute_Remote_Row(t *testing.T) {
|
|||
hldr0 := c.GetHolder(0)
|
||||
hldr1 := c.GetHolder(1)
|
||||
|
||||
_, err := c.GetNode(0).API.CreateIndex(context.Background(), "i", pilosa.IndexOptions{})
|
||||
_, err := c.GetCoordinator().API.CreateIndex(context.Background(), "i", 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, pilosa.DefaultCacheSize))
|
||||
_, err = c.GetCoordinator().API.CreateField(context.Background(), "i", "f", pilosa.OptFieldTypeSet(pilosa.DefaultCacheType, pilosa.DefaultCacheSize))
|
||||
if err != nil {
|
||||
t.Fatalf("creating field: %v", err)
|
||||
}
|
||||
|
|
@ -2994,7 +2994,7 @@ func TestExecutor_Execute_Remote_Row(t *testing.T) {
|
|||
})
|
||||
|
||||
t.Run("remote with timestamp", func(t *testing.T) {
|
||||
_, err = c.GetNode(0).API.CreateField(context.Background(), "i", "z", pilosa.OptFieldTypeTime("Y"))
|
||||
_, err = c.GetCoordinator().API.CreateField(context.Background(), "i", "z", pilosa.OptFieldTypeTime("Y"))
|
||||
if err != nil {
|
||||
t.Fatalf("creating field: %v", err)
|
||||
}
|
||||
|
|
@ -3009,7 +3009,7 @@ func TestExecutor_Execute_Remote_Row(t *testing.T) {
|
|||
})
|
||||
|
||||
t.Run("remote topn", func(t *testing.T) {
|
||||
_, err = c.GetNode(0).API.CreateField(context.Background(), "i", "fn", pilosa.OptFieldTypeSet(pilosa.CacheTypeRanked, 100))
|
||||
_, err = c.GetCoordinator().API.CreateField(context.Background(), "i", "fn", pilosa.OptFieldTypeSet(pilosa.CacheTypeRanked, 100))
|
||||
if err != nil {
|
||||
t.Fatalf("creating field: %v", err)
|
||||
}
|
||||
|
|
@ -3056,7 +3056,7 @@ func TestExecutor_Execute_Remote_Row(t *testing.T) {
|
|||
})
|
||||
|
||||
t.Run("remote groupBy", func(t *testing.T) {
|
||||
if res, err := c.GetNode(1).API.Query(context.Background(), &pilosa.QueryRequest{
|
||||
if res, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{
|
||||
Index: "i",
|
||||
Query: `GroupBy(Rows(f))`,
|
||||
}); err != nil {
|
||||
|
|
@ -3072,7 +3072,7 @@ func TestExecutor_Execute_Remote_Row(t *testing.T) {
|
|||
})
|
||||
|
||||
t.Run("remote groupBy on ints", func(t *testing.T) {
|
||||
_, err = c.GetNode(0).API.CreateField(context.Background(), "i", "fint", pilosa.OptFieldTypeInt(-1000, 1000))
|
||||
_, err = c.GetCoordinator().API.CreateField(context.Background(), "i", "fint", pilosa.OptFieldTypeInt(-1000, 1000))
|
||||
if err != nil {
|
||||
t.Fatalf("creating field: %v", err)
|
||||
}
|
||||
|
|
@ -3114,7 +3114,7 @@ func TestExecutor_Execute_Remote_Row(t *testing.T) {
|
|||
})
|
||||
|
||||
t.Run("groupBy on ints with offset regression", func(t *testing.T) {
|
||||
_, err = c.GetNode(0).API.CreateField(context.Background(), "i", "hint", pilosa.OptFieldTypeInt(1, 1000))
|
||||
_, err = c.GetCoordinator().API.CreateField(context.Background(), "i", "hint", pilosa.OptFieldTypeInt(1, 1000))
|
||||
if err != nil {
|
||||
t.Fatalf("creating field: %v", err)
|
||||
}
|
||||
|
|
@ -3145,12 +3145,12 @@ func TestExecutor_Execute_Remote_Row(t *testing.T) {
|
|||
})
|
||||
|
||||
t.Run("Row on ints with ASSIGN condition", func(t *testing.T) {
|
||||
_, err := c.GetNode(0).API.CreateIndex(context.Background(), "intidx", pilosa.IndexOptions{})
|
||||
_, err := c.GetCoordinator().API.CreateIndex(context.Background(), "intidx", pilosa.IndexOptions{})
|
||||
if err != nil {
|
||||
t.Fatalf("creating index: %v", err)
|
||||
}
|
||||
|
||||
_, err = c.GetNode(0).API.CreateField(context.Background(), "intidx", "gint", pilosa.OptFieldTypeInt(-1000, 1000))
|
||||
_, err = c.GetCoordinator().API.CreateField(context.Background(), "intidx", "gint", pilosa.OptFieldTypeInt(-1000, 1000))
|
||||
if err != nil {
|
||||
t.Fatalf("creating field: %v", err)
|
||||
}
|
||||
|
|
@ -3180,12 +3180,12 @@ func TestExecutor_Execute_Remote_Row(t *testing.T) {
|
|||
})
|
||||
|
||||
t.Run("Row on decimals with ASSIGN condition", func(t *testing.T) {
|
||||
_, err := c.GetNode(0).API.CreateIndex(context.Background(), "decidx", pilosa.IndexOptions{})
|
||||
_, err := c.GetCoordinator().API.CreateIndex(context.Background(), "decidx", pilosa.IndexOptions{})
|
||||
if err != nil {
|
||||
t.Fatalf("creating index: %v", err)
|
||||
}
|
||||
|
||||
_, err = c.GetNode(0).API.CreateField(context.Background(), "decidx", "fdec", pilosa.OptFieldTypeDecimal(0))
|
||||
_, err = c.GetCoordinator().API.CreateField(context.Background(), "decidx", "fdec", pilosa.OptFieldTypeDecimal(0))
|
||||
if err != nil {
|
||||
t.Fatalf("creating field: %v", err)
|
||||
}
|
||||
|
|
@ -3214,19 +3214,19 @@ func TestExecutor_Execute_Remote_Row(t *testing.T) {
|
|||
})
|
||||
|
||||
t.Run("Row on foreign key with ASSIGN condition", func(t *testing.T) {
|
||||
_, err := c.GetNode(0).API.CreateIndex(context.Background(), "parent", pilosa.IndexOptions{Keys: true})
|
||||
_, err := c.GetCoordinator().API.CreateIndex(context.Background(), "parent", pilosa.IndexOptions{Keys: true})
|
||||
if err != nil {
|
||||
t.Fatalf("creating index: %v", err)
|
||||
}
|
||||
_, err = c.GetNode(0).API.CreateField(context.Background(), "parent", "general", pilosa.OptFieldTypeSet(pilosa.DefaultCacheType, pilosa.DefaultCacheSize))
|
||||
_, err = c.GetCoordinator().API.CreateField(context.Background(), "parent", "general", pilosa.OptFieldTypeSet(pilosa.DefaultCacheType, pilosa.DefaultCacheSize))
|
||||
if err != nil {
|
||||
t.Fatalf("creating field: %v", err)
|
||||
}
|
||||
_, err = c.GetNode(0).API.CreateIndex(context.Background(), "child", pilosa.IndexOptions{Keys: false})
|
||||
_, err = c.GetCoordinator().API.CreateIndex(context.Background(), "child", pilosa.IndexOptions{Keys: false})
|
||||
if err != nil {
|
||||
t.Fatalf("creating index: %v", err)
|
||||
}
|
||||
_, err = c.GetNode(0).API.CreateField(context.Background(), "child", "parentid",
|
||||
_, err = c.GetCoordinator().API.CreateField(context.Background(), "child", "parentid",
|
||||
pilosa.OptFieldForeignIndex("parent"),
|
||||
pilosa.OptFieldTypeInt(-9223372036854775808, 9223372036854775807),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -49,15 +49,16 @@ func TestClient_MultiNode(t *testing.T) {
|
|||
)
|
||||
defer c.Close()
|
||||
|
||||
hldr := []test.Holder{}
|
||||
for _, command := range c.Nodes {
|
||||
hldr = append(hldr, test.Holder{Holder: command.Server.Holder()})
|
||||
}
|
||||
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.
|
||||
// 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())`
|
||||
// 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},
|
||||
|
|
@ -96,26 +97,26 @@ func TestClient_MultiNode(t *testing.T) {
|
|||
t.Fatalf("creating field: %v", err)
|
||||
}
|
||||
|
||||
hldr[0].MustSetBits("i", "f", 100, baseBit0+10)
|
||||
hldr[0].MustSetBits("i", "f", 4, baseBit0+10, baseBit0+11, baseBit0+12)
|
||||
hldr[0].MustSetBits("i", "f", 4, baseBit0+10, baseBit0+11, baseBit0+12, baseBit0+13, baseBit0+14, baseBit0+15)
|
||||
hldr[0].MustSetBits("i", "f", 2, baseBit0+1, baseBit0+2, baseBit0+3, baseBit0+4)
|
||||
hldr[0].MustSetBits("i", "f", 3, baseBit0+1, baseBit0+2, baseBit0+3, baseBit0+4, baseBit0+5)
|
||||
hldr[0].MustSetBits("i", "f", 22, baseBit0+1, baseBit0+2)
|
||||
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)
|
||||
|
||||
hldr[1].MustSetBits("i", "f", 99, baseBit1+1, baseBit1+2, baseBit1+3, baseBit1+4)
|
||||
hldr[1].MustSetBits("i", "f", 100, baseBit1+1, baseBit1+2, baseBit1+3, baseBit1+4, baseBit1+5, baseBit1+6, baseBit1+7, baseBit1+8, baseBit1+9, baseBit1+10)
|
||||
hldr[1].MustSetBits("i", "f", 98, baseBit1+1, baseBit1+2, baseBit1+3, baseBit1+4, baseBit1+5, baseBit1+6)
|
||||
hldr[1].MustSetBits("i", "f", 1, baseBit1+4)
|
||||
hldr[1].MustSetBits("i", "f", 22, baseBit1+1, baseBit1+2, baseBit1+3, baseBit1+4, baseBit1+5)
|
||||
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)
|
||||
|
||||
hldr[2].MustSetBits("i", "f", 24, baseBit2+10, baseBit2+11, baseBit2+12, baseBit2+13, baseBit2+14)
|
||||
hldr[2].MustSetBits("i", "f", 20, baseBit2+10, baseBit2+11, baseBit2+12, baseBit2+13)
|
||||
hldr[2].MustSetBits("i", "f", 21, baseBit2+10)
|
||||
hldr[2].MustSetBits("i", "f", 100, baseBit2+10)
|
||||
hldr[2].MustSetBits("i", "f", 99, baseBit2+10, baseBit2+11, baseBit2+12)
|
||||
hldr[2].MustSetBits("i", "f", 98, baseBit2+10, baseBit2+11)
|
||||
hldr[2].MustSetBits("i", "f", 22, baseBit2+10, baseBit2+11, baseBit2+12)
|
||||
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)
|
||||
|
||||
// Rebuild the RankCache.
|
||||
// We have to do this to avoid the 10-second cache invalidation delay
|
||||
|
|
|
|||
|
|
@ -695,8 +695,8 @@ func TestCluster_GossipMembership(t *testing.T) {
|
|||
func TestClusterResize_RemoveNode(t *testing.T) {
|
||||
cluster := test.MustRunCluster(t, 3)
|
||||
defer cluster.Close()
|
||||
m0 := cluster.GetNode(0)
|
||||
m1 := cluster.GetNode(1)
|
||||
coord := cluster.GetCoordinator()
|
||||
other := cluster.GetNonCoordinator()
|
||||
|
||||
mustNodeID := func(baseURL string) string {
|
||||
body := test.Do(t, "GET", fmt.Sprintf("%s/status", baseURL), "").Body
|
||||
|
|
@ -712,7 +712,7 @@ func TestClusterResize_RemoveNode(t *testing.T) {
|
|||
}
|
||||
|
||||
t.Run("ErrorRemoveInvalidNode", func(t *testing.T) {
|
||||
resp := test.Do(t, "POST", m0.URL()+"/cluster/resize/remove-node", `{"id": "invalid-node-id"}`)
|
||||
resp := test.Do(t, "POST", coord.URL()+"/cluster/resize/remove-node", `{"id": "invalid-node-id"}`)
|
||||
expBody := "removing node: finding node to remove: node with provided ID does not exist"
|
||||
if resp.StatusCode != http.StatusNotFound {
|
||||
t.Fatalf("expected StatusCode %d but got %d", http.StatusNotFound, resp.StatusCode)
|
||||
|
|
@ -722,8 +722,8 @@ func TestClusterResize_RemoveNode(t *testing.T) {
|
|||
})
|
||||
|
||||
t.Run("ErrorRemoveCoordinator", func(t *testing.T) {
|
||||
nodeID := mustNodeID(m0.URL())
|
||||
resp := test.Do(t, "POST", m0.URL()+"/cluster/resize/remove-node", fmt.Sprintf(`{"id": "%s"}`, nodeID))
|
||||
nodeID := mustNodeID(coord.URL())
|
||||
resp := test.Do(t, "POST", coord.URL()+"/cluster/resize/remove-node", fmt.Sprintf(`{"id": "%s"}`, nodeID))
|
||||
|
||||
expBody := "removing node: calling node leave: coordinator cannot be removed; first, make a different node the new coordinator"
|
||||
if resp.StatusCode != http.StatusInternalServerError {
|
||||
|
|
@ -734,9 +734,9 @@ func TestClusterResize_RemoveNode(t *testing.T) {
|
|||
})
|
||||
|
||||
t.Run("ErrorRemoveOnNonCoordinator", func(t *testing.T) {
|
||||
coordinatorNodeID := mustNodeID(m0.URL())
|
||||
nodeID := mustNodeID(m1.URL())
|
||||
resp := test.Do(t, "POST", m1.URL()+"/cluster/resize/remove-node", fmt.Sprintf(`{"id": "%s"}`, nodeID))
|
||||
coordinatorNodeID := mustNodeID(coord.URL())
|
||||
nodeID := mustNodeID(other.URL())
|
||||
resp := test.Do(t, "POST", other.URL()+"/cluster/resize/remove-node", fmt.Sprintf(`{"id": "%s"}`, nodeID))
|
||||
|
||||
expBody := fmt.Sprintf("removing node: calling node leave: node removal requests are only valid on the coordinator node: %s", coordinatorNodeID)
|
||||
if resp.StatusCode != http.StatusInternalServerError {
|
||||
|
|
@ -747,7 +747,7 @@ func TestClusterResize_RemoveNode(t *testing.T) {
|
|||
})
|
||||
|
||||
t.Run("ErrorRemoveWithoutReplicas", func(t *testing.T) {
|
||||
client0 := m0.Client()
|
||||
client0 := coord.Client()
|
||||
|
||||
// Create indexes and fields on one node.
|
||||
if err := client0.CreateIndex(context.Background(), "i", pilosa.IndexOptions{}); err != nil && err != pilosa.ErrIndexExists {
|
||||
|
|
@ -763,12 +763,12 @@ func TestClusterResize_RemoveNode(t *testing.T) {
|
|||
setColumns += fmt.Sprintf("Set(%d, f=1) ", i*pilosa.ShardWidth)
|
||||
}
|
||||
|
||||
if _, err := m0.Query(t, "i", "", setColumns); err != nil {
|
||||
if _, err := coord.Query(t, "i", "", setColumns); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
nodeID := mustNodeID(m1.URL())
|
||||
resp := test.Do(t, "POST", m0.URL()+"/cluster/resize/remove-node", fmt.Sprintf(`{"id": "%s"}`, nodeID))
|
||||
nodeID := mustNodeID(other.URL())
|
||||
resp := test.Do(t, "POST", coord.URL()+"/cluster/resize/remove-node", fmt.Sprintf(`{"id": "%s"}`, nodeID))
|
||||
expBody := "not enough data to perform resize"
|
||||
if resp.StatusCode != http.StatusInternalServerError {
|
||||
t.Fatalf("expected StatusCode %d but got %d", http.StatusInternalServerError, resp.StatusCode)
|
||||
|
|
|
|||
|
|
@ -387,32 +387,31 @@ func TestTransactionsAPI(t *testing.T) {
|
|||
cluster := test.MustRunCluster(t, 3)
|
||||
defer cluster.Close()
|
||||
|
||||
api0 := cluster.GetNode(0).API
|
||||
api1 := cluster.GetNode(1).API
|
||||
coord := cluster.GetCoordinator().API
|
||||
other := cluster.GetNonCoordinator().API
|
||||
ctx := context.Background()
|
||||
//api2 := cluster.GetNode(2).API
|
||||
|
||||
// can fetch empty transactions
|
||||
if trnsMap, err := api0.Transactions(ctx); err != nil {
|
||||
if trnsMap, err := coord.Transactions(ctx); err != nil {
|
||||
t.Fatalf("getting transactions: %v", err)
|
||||
} else if len(trnsMap) != 0 {
|
||||
t.Fatalf("unexpectedly has transactions: %v", trnsMap)
|
||||
}
|
||||
|
||||
// can't fetch transactions from non-coordinator
|
||||
if _, err := api1.Transactions(ctx); err != pilosa.ErrNodeNotCoordinator {
|
||||
if _, err := other.Transactions(ctx); err != pilosa.ErrNodeNotCoordinator {
|
||||
t.Errorf("api1 should return ErrNodeNotCoordinator when asked for transactions but got: %v", err)
|
||||
}
|
||||
|
||||
// can start transaction
|
||||
if trns, err := api0.StartTransaction(ctx, "a", time.Minute, false, false); err != nil {
|
||||
if trns, err := coord.StartTransaction(ctx, "a", time.Minute, false, false); err != nil {
|
||||
t.Errorf("couldn't start transaction: %v", err)
|
||||
} else {
|
||||
test.CompareTransactions(t, &pilosa.Transaction{ID: "a", Active: true, Timeout: time.Minute, Deadline: time.Now().Add(time.Minute)}, trns)
|
||||
}
|
||||
|
||||
// can retrieve transaction from other nodes with remote=true
|
||||
if trns, err := api1.GetTransaction(ctx, "a", true); err != nil {
|
||||
if trns, err := other.GetTransaction(ctx, "a", true); err != nil {
|
||||
t.Errorf("couldn't fetch transaction from other node with remote=true: %v", err)
|
||||
} else {
|
||||
test.CompareTransactions(t, &pilosa.Transaction{ID: "a", Active: true, Timeout: time.Minute, Deadline: time.Now().Add(time.Minute)}, trns)
|
||||
|
|
@ -420,7 +419,7 @@ func TestTransactionsAPI(t *testing.T) {
|
|||
|
||||
// can start transaction with blank id and get uuid back
|
||||
id := ""
|
||||
if trns, err := api0.StartTransaction(ctx, id, time.Minute, false, false); err != nil {
|
||||
if trns, err := coord.StartTransaction(ctx, id, time.Minute, false, false); err != nil {
|
||||
t.Errorf("couldn't start transaction: %v", err)
|
||||
} else {
|
||||
id = trns.ID
|
||||
|
|
@ -431,54 +430,54 @@ func TestTransactionsAPI(t *testing.T) {
|
|||
}
|
||||
|
||||
// can't finish transaction on non-coordinator
|
||||
if _, err := api1.FinishTransaction(ctx, id, false); err != pilosa.ErrNodeNotCoordinator {
|
||||
if _, err := other.FinishTransaction(ctx, id, false); err != pilosa.ErrNodeNotCoordinator {
|
||||
t.Errorf("unexpected error is not ErrNodeNotCoordinator: %v", err)
|
||||
}
|
||||
|
||||
// can finish transaction
|
||||
if _, err := api0.FinishTransaction(ctx, id, false); err != nil {
|
||||
if _, err := coord.FinishTransaction(ctx, id, false); err != nil {
|
||||
t.Errorf("couldn't finish transaction: %v", err)
|
||||
}
|
||||
|
||||
// can finish previous transaction
|
||||
if _, err := api0.FinishTransaction(ctx, "a", false); err != nil {
|
||||
if _, err := coord.FinishTransaction(ctx, "a", false); err != nil {
|
||||
t.Errorf("couldn't finish transaction a: %v", err)
|
||||
}
|
||||
|
||||
// can start exclusive transaction
|
||||
if te, err := api0.StartTransaction(ctx, "exc", time.Minute, true, false); err != nil {
|
||||
if te, err := coord.StartTransaction(ctx, "exc", time.Minute, true, false); err != nil {
|
||||
t.Errorf("couldn't start exclusive transaction: %v", err)
|
||||
} else if !te.Active {
|
||||
t.Errorf("expected exclusive transaction to be active: %+v", te)
|
||||
}
|
||||
|
||||
// can finish exclusive transaction
|
||||
if _, err := api0.FinishTransaction(ctx, "exc", false); err != nil {
|
||||
if _, err := coord.FinishTransaction(ctx, "exc", false); err != nil {
|
||||
t.Errorf("couldn't finish exclusive transaction: %v", err)
|
||||
}
|
||||
|
||||
// can start transaction (with same name as previous finished transaction)
|
||||
if trns, err := api0.StartTransaction(ctx, "a", time.Minute, false, false); err != nil {
|
||||
if trns, err := coord.StartTransaction(ctx, "a", time.Minute, false, false); err != nil {
|
||||
t.Errorf("couldn't start transaction: %v", err)
|
||||
} else {
|
||||
test.CompareTransactions(t, &pilosa.Transaction{ID: "a", Active: true, Timeout: time.Minute, Deadline: time.Now().Add(time.Minute)}, trns)
|
||||
}
|
||||
|
||||
// can start exclusive transaction and is not immediately active
|
||||
if te, err := api0.StartTransaction(ctx, "exc", time.Minute, true, false); err != nil {
|
||||
if te, err := coord.StartTransaction(ctx, "exc", time.Minute, true, false); err != nil {
|
||||
t.Errorf("couldn't start exclusive transaction: %v", err)
|
||||
} else if te.Active {
|
||||
t.Errorf("expected exclusive transaction to be inactive: %+v", te)
|
||||
}
|
||||
|
||||
// can finish non-exclusive transaction
|
||||
if _, err := api0.FinishTransaction(ctx, "a", false); err != nil {
|
||||
if _, err := coord.FinishTransaction(ctx, "a", false); err != nil {
|
||||
t.Errorf("couldn't finish transaction a: %v", err)
|
||||
}
|
||||
|
||||
// can poll exclusive transaction and is active
|
||||
var excTrns *pilosa.Transaction
|
||||
if trns, err := api0.GetTransaction(ctx, "exc", false); err != nil {
|
||||
if trns, err := coord.GetTransaction(ctx, "exc", false); err != nil {
|
||||
t.Errorf("couldn't poll exclusive transaction: %v", err)
|
||||
} else {
|
||||
excTrns = &pilosa.Transaction{ID: "exc", Active: true, Exclusive: true, Timeout: time.Minute, Deadline: time.Now().Add(time.Minute)}
|
||||
|
|
@ -486,7 +485,7 @@ func TestTransactionsAPI(t *testing.T) {
|
|||
}
|
||||
|
||||
// can't start another exclusive transaction
|
||||
if trns, err := api0.StartTransaction(ctx, "exc2", time.Minute, true, false); errors.Cause(err) != pilosa.ErrTransactionExclusive {
|
||||
if trns, err := coord.StartTransaction(ctx, "exc2", time.Minute, true, false); errors.Cause(err) != pilosa.ErrTransactionExclusive {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
} else {
|
||||
// returned transaction should be the exclusive one which is blocking this one
|
||||
|
|
@ -494,14 +493,14 @@ func TestTransactionsAPI(t *testing.T) {
|
|||
}
|
||||
|
||||
// can't keep the second exclusive name but make it nonexclusive and start a transaction
|
||||
if trns, err := api0.StartTransaction(ctx, "exc2", time.Minute, false, false); errors.Cause(err) != pilosa.ErrTransactionExclusive {
|
||||
if trns, err := coord.StartTransaction(ctx, "exc2", time.Minute, false, false); errors.Cause(err) != pilosa.ErrTransactionExclusive {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
} else {
|
||||
test.CompareTransactions(t, excTrns, trns)
|
||||
}
|
||||
|
||||
// transaction is active on other nodes with remote=true
|
||||
if trns, err := api1.GetTransaction(ctx, "exc", true); err != nil {
|
||||
if trns, err := other.GetTransaction(ctx, "exc", true); err != nil {
|
||||
t.Errorf("couldn't poll exclusive transaction: %v", err)
|
||||
} else {
|
||||
test.CompareTransactions(t, &pilosa.Transaction{ID: "exc", Active: true, Exclusive: true, Timeout: time.Minute, Deadline: time.Now().Add(time.Minute)}, trns)
|
||||
|
|
|
|||
|
|
@ -178,6 +178,17 @@ func (c *Cluster) GetHolder(n int) *Holder {
|
|||
return &Holder{Holder: c.GetNode(n).Server.Holder()}
|
||||
}
|
||||
|
||||
// GetCoordinatorHolder returns the Holder for the coordinator node.
|
||||
func (c *Cluster) GetCoordinatorHolder() *Holder {
|
||||
return &Holder{Holder: c.GetCoordinator().Server.Holder()}
|
||||
}
|
||||
|
||||
// GetNonCoordinatorHolder returns the Holder for the the first non-coordinator
|
||||
// node in the list of nodes.
|
||||
func (c *Cluster) GetNonCoordinatorHolder() *Holder {
|
||||
return &Holder{Holder: c.GetNonCoordinator().Server.Holder()}
|
||||
}
|
||||
|
||||
func (c *Cluster) Len() int {
|
||||
return len(c.Nodes)
|
||||
}
|
||||
|
|
@ -442,6 +453,15 @@ func (c *Cluster) Close() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (c *Cluster) CloseAndRemoveNonCoordinator() error {
|
||||
for i, n := range c.Nodes {
|
||||
if !n.IsCoordinator() {
|
||||
return c.CloseAndRemove(i)
|
||||
}
|
||||
}
|
||||
return errors.New("could not find non-coordinator node")
|
||||
}
|
||||
|
||||
func (c *Cluster) CloseAndRemove(n int) error {
|
||||
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))
|
||||
|
|
|
|||
|
|
@ -514,16 +514,16 @@ func TestTranslation_Replication(t *testing.T) {
|
|||
exp := `{"results":[{"attrs":{},"columns":[],"keys":["x1","x2"]}]}`
|
||||
|
||||
if !test.CheckClusterState(coord, pilosa.ClusterStateNormal, 1000) {
|
||||
t.Fatalf("unexpected node0 cluster state: %s", coord.API.State())
|
||||
t.Fatalf("unexpected coord cluster state: %s", coord.API.State())
|
||||
} else if !test.CheckClusterState(other, pilosa.ClusterStateNormal, 1000) {
|
||||
t.Fatalf("unexpected node1 cluster state: %s", other.API.State())
|
||||
t.Fatalf("unexpected other cluster state: %s", other.API.State())
|
||||
}
|
||||
|
||||
// Verify the data exists
|
||||
coord.QueryExpect(t, idx, "", `Row(f=1)`, exp)
|
||||
|
||||
// Kill one node.
|
||||
if err := c.CloseAndRemove(1); err != nil {
|
||||
// Kill a non-coordinator node.
|
||||
if err := c.CloseAndRemoveNonCoordinator(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue