1source "../tests/includes/init-tests.tcl"
2
3test "Create a 1 node cluster" {
4    create_cluster 1 0
5}
6
7test "Cluster is up" {
8    assert_cluster_state ok
9}
10
11test "Cluster is writable" {
12    cluster_write_test 0
13}
14
15proc is_in_slots {master_id replica} {
16    set slots [R $master_id cluster slots]
17    set found_position [string first $replica $slots]
18    set result [expr {$found_position != -1}]
19    return $result
20}
21
22proc is_replica_online {info_repl} {
23    set found_position [string first "state=online" $info_repl]
24    set result [expr {$found_position != -1}]
25    return $result
26}
27
28proc get_last_pong_time {node_id target_cid} {
29    foreach item [split [R $node_id cluster nodes] \n] {
30        set args [split $item " "]
31        if {[lindex $args 0] eq $target_cid} {
32            return [lindex $args 5]
33        }
34    }
35    fail "Target node ID was not present"
36}
37
38set master_id 0
39
40test "Fill up primary with data" {
41    # Set 1 MB of data
42    R $master_id debug populate 1000 key 1000
43}
44
45test "Add new node as replica" {
46    set replica_id 1
47    set replica [R $replica_id CLUSTER MYID]
48    R $replica_id cluster replicate [R $master_id CLUSTER MYID]
49}
50
51test "Check digest and replica state" {
52    wait_for_condition 1000 50 {
53        [is_in_slots $master_id $replica]
54    } else {
55        fail "New replica didn't appear in the slots"
56    }
57
58    wait_for_condition 100 50 {
59        [is_replica_online [R $master_id info replication]]
60    } else {
61        fail "Replica is down for too long"
62    }
63    set replica_digest [R $replica_id debug digest]
64    assert {$replica_digest ne 0}
65}
66
67test "Replica in loading state is hidden" {
68    # Kill replica client for master and load new data to the primary
69    R $master_id config set repl-backlog-size 100
70
71    # Set the key load delay so that it will take at least
72    # 2 seconds to fully load the data.
73    R $replica_id config set key-load-delay 4000
74
75    # Trigger event loop processing every 1024 bytes, this trigger
76    # allows us to send and receive cluster messages, so we are setting
77    # it low so that the cluster messages are sent more frequently.
78    R $replica_id config set loading-process-events-interval-bytes 1024
79
80    R $master_id multi
81    R $master_id client kill type replica
82    set num 100
83    set value [string repeat A 1024]
84    for {set j 0} {$j < $num} {incr j} {
85        set key "{0}"
86        append key $j
87        R $master_id set $key $value
88    }
89    R $master_id exec
90
91    # The master will be the last to know the replica
92    # is loading, so we will wait on that and assert
93    # the replica is loading afterwards.
94    wait_for_condition 100 50 {
95        ![is_in_slots $master_id $replica]
96    } else {
97        fail "Replica was always present in cluster slots"
98    }
99    assert_equal 1 [s $replica_id loading]
100
101    # Wait for the replica to finish full-sync and become online
102    wait_for_condition 200 50 {
103        [s $replica_id master_link_status] eq "up"
104    } else {
105        fail "Replica didn't finish loading"
106    }
107
108    # Return configs to default values
109    R $replica_id config set loading-process-events-interval-bytes 2097152
110    R $replica_id config set key-load-delay 0
111
112    # Check replica is back in cluster slots
113    wait_for_condition 100 50 {
114        [is_in_slots $master_id $replica]
115    } else {
116        fail "Replica is not back to slots"
117    }
118    assert_equal 1 [is_in_slots $replica_id $replica]
119}
120
121test "Check disconnected replica not hidden from slots" {
122    # We want to disconnect the replica, but keep it alive so it can still gossip
123
124    # Make sure that the replica will not be able to re-connect to the master
125    R $master_id config set requirepass asdf
126
127    # Disconnect replica from primary
128    R $master_id client kill type replica
129
130    # Check master to have no replicas
131    assert {[s $master_id connected_slaves] == 0}
132
133    set replica_cid [R $replica_id cluster myid]
134    set initial_pong [get_last_pong_time $master_id $replica_cid]
135    wait_for_condition 50 100 {
136        $initial_pong != [get_last_pong_time $master_id $replica_cid]
137    } else {
138        fail "Primary never received gossip from replica"
139    }
140
141    # Check that replica is still in the cluster slots
142    assert {[is_in_slots $master_id $replica]}
143
144    # undo config
145    R $master_id config set requirepass ""
146}
147