"Fossies" - the Fresh Open Source Software Archive

Member "redis-5.0.7/tests/integration/replication.tcl" (19 Nov 2019, 11539 Bytes) of package /linux/misc/redis-5.0.7.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Tcl/Tk source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the last Fossies "Diffs" side-by-side code changes report for "replication.tcl": 5.0.3_vs_5.0.4.

    1 proc log_file_matches {log pattern} {
    2     set fp [open $log r]
    3     set content [read $fp]
    4     close $fp
    5     string match $pattern $content
    6 }
    7 
    8 start_server {tags {"repl"}} {
    9     set slave [srv 0 client]
   10     set slave_host [srv 0 host]
   11     set slave_port [srv 0 port]
   12     set slave_log [srv 0 stdout]
   13     start_server {} {
   14         set master [srv 0 client]
   15         set master_host [srv 0 host]
   16         set master_port [srv 0 port]
   17 
   18         # Configure the master in order to hang waiting for the BGSAVE
   19         # operation, so that the slave remains in the handshake state.
   20         $master config set repl-diskless-sync yes
   21         $master config set repl-diskless-sync-delay 1000
   22 
   23         # Use a short replication timeout on the slave, so that if there
   24         # are no bugs the timeout is triggered in a reasonable amount
   25         # of time.
   26         $slave config set repl-timeout 5
   27 
   28         # Start the replication process...
   29         $slave slaveof $master_host $master_port
   30 
   31         test {Slave enters handshake} {
   32             wait_for_condition 50 1000 {
   33                 [string match *handshake* [$slave role]]
   34             } else {
   35                 fail "Replica does not enter handshake state"
   36             }
   37         }
   38 
   39         # But make the master unable to send
   40         # the periodic newlines to refresh the connection. The slave
   41         # should detect the timeout.
   42         $master debug sleep 10
   43 
   44         test {Slave is able to detect timeout during handshake} {
   45             wait_for_condition 50 1000 {
   46                 [log_file_matches $slave_log "*Timeout connecting to the MASTER*"]
   47             } else {
   48                 fail "Replica is not able to detect timeout"
   49             }
   50         }
   51     }
   52 }
   53 
   54 start_server {tags {"repl"}} {
   55     set A [srv 0 client]
   56     set A_host [srv 0 host]
   57     set A_port [srv 0 port]
   58     start_server {} {
   59         set B [srv 0 client]
   60         set B_host [srv 0 host]
   61         set B_port [srv 0 port]
   62 
   63         test {Set instance A as slave of B} {
   64             $A slaveof $B_host $B_port
   65             wait_for_condition 50 100 {
   66                 [lindex [$A role] 0] eq {slave} &&
   67                 [string match {*master_link_status:up*} [$A info replication]]
   68             } else {
   69                 fail "Can't turn the instance into a replica"
   70             }
   71         }
   72 
   73         test {BRPOPLPUSH replication, when blocking against empty list} {
   74             set rd [redis_deferring_client]
   75             $rd brpoplpush a b 5
   76             r lpush a foo
   77             wait_for_condition 50 100 {
   78                 [$A debug digest] eq [$B debug digest]
   79             } else {
   80                 fail "Master and replica have different digest: [$A debug digest] VS [$B debug digest]"
   81             }
   82         }
   83 
   84         test {BRPOPLPUSH replication, list exists} {
   85             set rd [redis_deferring_client]
   86             r lpush c 1
   87             r lpush c 2
   88             r lpush c 3
   89             $rd brpoplpush c d 5
   90             after 1000
   91             assert_equal [$A debug digest] [$B debug digest]
   92         }
   93 
   94         test {BLPOP followed by role change, issue #2473} {
   95             set rd [redis_deferring_client]
   96             $rd blpop foo 0 ; # Block while B is a master
   97 
   98             # Turn B into master of A
   99             $A slaveof no one
  100             $B slaveof $A_host $A_port
  101             wait_for_condition 50 100 {
  102                 [lindex [$B role] 0] eq {slave} &&
  103                 [string match {*master_link_status:up*} [$B info replication]]
  104             } else {
  105                 fail "Can't turn the instance into a replica"
  106             }
  107 
  108             # Push elements into the "foo" list of the new replica.
  109             # If the client is still attached to the instance, we'll get
  110             # a desync between the two instances.
  111             $A rpush foo a b c
  112             after 100
  113 
  114             wait_for_condition 50 100 {
  115                 [$A debug digest] eq [$B debug digest] &&
  116                 [$A lrange foo 0 -1] eq {a b c} &&
  117                 [$B lrange foo 0 -1] eq {a b c}
  118             } else {
  119                 fail "Master and replica have different digest: [$A debug digest] VS [$B debug digest]"
  120             }
  121         }
  122     }
  123 }
  124 
  125 start_server {tags {"repl"}} {
  126     r set mykey foo
  127 
  128     start_server {} {
  129         test {Second server should have role master at first} {
  130             s role
  131         } {master}
  132 
  133         test {SLAVEOF should start with link status "down"} {
  134             r slaveof [srv -1 host] [srv -1 port]
  135             s master_link_status
  136         } {down}
  137 
  138         test {The role should immediately be changed to "replica"} {
  139             s role
  140         } {slave}
  141 
  142         wait_for_sync r
  143         test {Sync should have transferred keys from master} {
  144             r get mykey
  145         } {foo}
  146 
  147         test {The link status should be up} {
  148             s master_link_status
  149         } {up}
  150 
  151         test {SET on the master should immediately propagate} {
  152             r -1 set mykey bar
  153 
  154             wait_for_condition 500 100 {
  155                 [r  0 get mykey] eq {bar}
  156             } else {
  157                 fail "SET on master did not propagated on replica"
  158             }
  159         }
  160 
  161         test {FLUSHALL should replicate} {
  162             r -1 flushall
  163             if {$::valgrind} {after 2000}
  164             list [r -1 dbsize] [r 0 dbsize]
  165         } {0 0}
  166 
  167         test {ROLE in master reports master with a slave} {
  168             set res [r -1 role]
  169             lassign $res role offset slaves
  170             assert {$role eq {master}}
  171             assert {$offset > 0}
  172             assert {[llength $slaves] == 1}
  173             lassign [lindex $slaves 0] master_host master_port slave_offset
  174             assert {$slave_offset <= $offset}
  175         }
  176 
  177         test {ROLE in slave reports slave in connected state} {
  178             set res [r role]
  179             lassign $res role master_host master_port slave_state slave_offset
  180             assert {$role eq {slave}}
  181             assert {$slave_state eq {connected}}
  182         }
  183     }
  184 }
  185 
  186 foreach dl {no yes} {
  187     start_server {tags {"repl"}} {
  188         set master [srv 0 client]
  189         $master config set repl-diskless-sync $dl
  190         set master_host [srv 0 host]
  191         set master_port [srv 0 port]
  192         set slaves {}
  193         set load_handle0 [start_write_load $master_host $master_port 3]
  194         set load_handle1 [start_write_load $master_host $master_port 5]
  195         set load_handle2 [start_write_load $master_host $master_port 20]
  196         set load_handle3 [start_write_load $master_host $master_port 8]
  197         set load_handle4 [start_write_load $master_host $master_port 4]
  198         start_server {} {
  199             lappend slaves [srv 0 client]
  200             start_server {} {
  201                 lappend slaves [srv 0 client]
  202                 start_server {} {
  203                     lappend slaves [srv 0 client]
  204                     test "Connect multiple replicas at the same time (issue #141), diskless=$dl" {
  205                         # Send SLAVEOF commands to slaves
  206                         [lindex $slaves 0] slaveof $master_host $master_port
  207                         [lindex $slaves 1] slaveof $master_host $master_port
  208                         [lindex $slaves 2] slaveof $master_host $master_port
  209 
  210                         # Wait for all the three slaves to reach the "online"
  211                         # state from the POV of the master.
  212                         set retry 500
  213                         while {$retry} {
  214                             set info [r -3 info]
  215                             if {[string match {*slave0:*state=online*slave1:*state=online*slave2:*state=online*} $info]} {
  216                                 break
  217                             } else {
  218                                 incr retry -1
  219                                 after 100
  220                             }
  221                         }
  222                         if {$retry == 0} {
  223                             error "assertion:Replicas not correctly synchronized"
  224                         }
  225 
  226                         # Wait that slaves acknowledge they are online so
  227                         # we are sure that DBSIZE and DEBUG DIGEST will not
  228                         # fail because of timing issues.
  229                         wait_for_condition 500 100 {
  230                             [lindex [[lindex $slaves 0] role] 3] eq {connected} &&
  231                             [lindex [[lindex $slaves 1] role] 3] eq {connected} &&
  232                             [lindex [[lindex $slaves 2] role] 3] eq {connected}
  233                         } else {
  234                             fail "Replicas still not connected after some time"
  235                         }
  236 
  237                         # Stop the write load
  238                         stop_write_load $load_handle0
  239                         stop_write_load $load_handle1
  240                         stop_write_load $load_handle2
  241                         stop_write_load $load_handle3
  242                         stop_write_load $load_handle4
  243 
  244                         # Make sure that slaves and master have same
  245                         # number of keys
  246                         wait_for_condition 500 100 {
  247                             [$master dbsize] == [[lindex $slaves 0] dbsize] &&
  248                             [$master dbsize] == [[lindex $slaves 1] dbsize] &&
  249                             [$master dbsize] == [[lindex $slaves 2] dbsize]
  250                         } else {
  251                             fail "Different number of keys between masted and replica after too long time."
  252                         }
  253 
  254                         # Check digests
  255                         set digest [$master debug digest]
  256                         set digest0 [[lindex $slaves 0] debug digest]
  257                         set digest1 [[lindex $slaves 1] debug digest]
  258                         set digest2 [[lindex $slaves 2] debug digest]
  259                         assert {$digest ne 0000000000000000000000000000000000000000}
  260                         assert {$digest eq $digest0}
  261                         assert {$digest eq $digest1}
  262                         assert {$digest eq $digest2}
  263                     }
  264                }
  265             }
  266         }
  267     }
  268 }
  269 
  270 start_server {tags {"repl"}} {
  271     set master [srv 0 client]
  272     set master_host [srv 0 host]
  273     set master_port [srv 0 port]
  274     set load_handle0 [start_write_load $master_host $master_port 3]
  275     start_server {} {
  276         test "Master stream is correctly processed while the replica has a script in -BUSY state" {
  277             set slave [srv 0 client]
  278             $slave config set lua-time-limit 500
  279             $slave slaveof $master_host $master_port
  280 
  281             # Wait for the slave to be online
  282             wait_for_condition 500 100 {
  283                 [lindex [$slave role] 3] eq {connected}
  284             } else {
  285                 fail "Replica still not connected after some time"
  286             }
  287 
  288             # Wait some time to make sure the master is sending data
  289             # to the slave.
  290             after 5000
  291 
  292             # Stop the ability of the slave to process data by sendig
  293             # a script that will put it in BUSY state.
  294             $slave eval {for i=1,3000000000 do end} 0
  295 
  296             # Wait some time again so that more master stream will
  297             # be processed.
  298             after 2000
  299 
  300             # Stop the write load
  301             stop_write_load $load_handle0
  302 
  303             # number of keys
  304             wait_for_condition 500 100 {
  305                 [$master debug digest] eq [$slave debug digest]
  306             } else {
  307                 fail "Different datasets between replica and master"
  308             }
  309         }
  310     }
  311 }