Skip to content
File

Blob: chord/local_membership_test.go

go66 lines
1package chord
2 
3import (
4 "context"
5 "testing"
6 
7 "go.miragespace.co/specter/spec/chord"
8 
9 "github.com/stretchr/testify/require"
10)
11 
12func TestJoinAfterMissingPredecessor(t *testing.T) {
13 as := require.New(t)
14 ctx := context.Background()
15 key, value := []byte("transferred"), []byte("move")
16 
17 nodeConfig := devConfig(t, as)
18 nodeConfig.Identity.Id = chord.Hash([]byte("owner"))
19 node := NewLocalNode(nodeConfig)
20 joinerConfig := devConfig(t, as)
21 joinerConfig.Identity.Id = chord.Hash(key)
22 joiner := NewLocalNode(joinerConfig)
23 as.NotEqual(node.ID(), joiner.ID())
24 
25 // Keep maintenance tasks stopped so they cannot repair the missing
26 // predecessor before the join request exercises the temporary gap.
27 node.successors = []chord.VNode{node}
28 node.succListHash.Store(node.hash(node.successors))
29 for i := 1; i <= chord.MaxFingerEntries; i++ {
30 node.fingers[i].node = node
31 }
32 node.state.Set(chord.Active)
33 as.NoError(node.kv.Put(ctx, key, value))
34 
35 predecessor, successors, err := node.RequestToJoin(joiner)
36 as.ErrorIs(err, chord.ErrJoinInvalidState)
37 as.True(chord.ErrorIsRetryable(err))
38 as.Nil(predecessor)
39 as.Nil(successors)
40 as.Equal(chord.Active, node.state.Get())
41 as.Nil(node.getPredecessor())
42 as.Nil(node.surrogate)
43 
44 stored, err := node.kv.Get(ctx, key)
45 as.NoError(err)
46 as.Equal(value, stored)
47 keys, err := joiner.kv.RangeKeys(ctx, 0, 0)
48 as.NoError(err)
49 as.Empty(keys)
50 
51 // A subsequent notification establishes the range boundary and allows a
52 // normal join, including transfer and membership-lock release, to finish.
53 as.NoError(node.Notify(node))
54 as.NoError(joiner.Join(node))
55 defer joiner.Leave()
56 as.Equal(chord.Active, node.state.Get())
57 as.Equal(chord.Active, joiner.state.Get())
58 
59 keys, err = node.kv.RangeKeys(ctx, 0, 0)
60 as.NoError(err)
61 as.Empty(keys)
62 stored, err = joiner.kv.Get(ctx, key)
63 as.NoError(err)
64 as.Equal(value, stored)
65}