"Fossies" - the Fresh Open Source Software Archive

Member "redis-7.0.5/tests/cluster/tests/24-links.tcl" (21 Sep 2022, 4556 Bytes) of package /linux/misc/redis-7.0.5.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. Alternatively you can here view or download the uninterpreted source code file.

    1 source "../tests/includes/init-tests.tcl"
    2 
    3 test "Create a cluster with two single-node shards" {
    4     create_cluster 2 0
    5 }
    6 
    7 test "Cluster should start ok" {
    8     assert_cluster_state ok
    9 }
   10 
   11 proc number_of_peers {id} {
   12     expr [llength [get_cluster_nodes $id]] - 1
   13 }
   14 
   15 proc number_of_links {id} {
   16     llength [get_cluster_links $id]
   17 }
   18 
   19 test "Each node has two links with each peer" {
   20     foreach_redis_id id {
   21         # Assert that from point of view of each node, there are two links for
   22         # each peer. It might take a while for cluster to stabilize so wait up
   23         # to 5 seconds.
   24         wait_for_condition 50 100 {
   25             [number_of_peers $id]*2 == [number_of_links $id]
   26         } else {
   27             assert_equal [expr [number_of_peers $id]*2] [number_of_links $id]
   28         }
   29 
   30         set nodes [get_cluster_nodes $id]
   31         set links [get_cluster_links $id]
   32 
   33         # For each peer there should be exactly one
   34         # link "to" it and one link "from" it.
   35         foreach n $nodes {
   36             if {[has_flag $n myself]} continue
   37             set peer [dict get $n id]
   38             set to 0
   39             set from 0
   40             foreach l $links {
   41                 if {[dict get $l node] eq $peer} {
   42                     if {[dict get $l dir] eq "to"} {
   43                         incr to
   44                     } elseif {[dict get $l dir] eq "from"} {
   45                         incr from
   46                     }
   47                 }
   48             }
   49             assert {$to eq 1}
   50             assert {$from eq 1}
   51         }
   52     }
   53 }
   54 
   55 set primary1_id 0
   56 set primary2_id 1
   57 
   58 set primary1 [Rn $primary1_id]
   59 set primary2 [Rn $primary2_id]
   60 
   61 test "Disconnect link when send buffer limit reached" {
   62     # On primary1, set timeout to 1 hour so links won't get disconnected due to timeouts
   63     set oldtimeout [lindex [$primary1 CONFIG get cluster-node-timeout] 1]
   64     $primary1 CONFIG set cluster-node-timeout [expr 60*60*1000]
   65 
   66     # Get primary1's links with primary2
   67     set primary2_name [dict get [get_myself $primary2_id] id]
   68     set orig_link_p1_to_p2 [get_link_to_peer $primary1_id $primary2_name]
   69     set orig_link_p1_from_p2 [get_link_from_peer $primary1_id $primary2_name]
   70 
   71     # On primary1, set cluster link send buffer limit to 256KB, which is large enough to not be
   72     # overflowed by regular gossip messages but also small enough that it doesn't take too much
   73     # memory to overflow it. If it is set too high, Redis may get OOM killed by kernel before this
   74     # limit is overflowed in some RAM-limited test environments.
   75     set oldlimit [lindex [$primary1 CONFIG get cluster-link-sendbuf-limit] 1]
   76     $primary1 CONFIG set cluster-link-sendbuf-limit [expr 256*1024]
   77     assert {[get_info_field [$primary1 cluster info] total_cluster_links_buffer_limit_exceeded] eq 0}
   78 
   79     # To manufacture an ever-growing send buffer from primary1 to primary2,
   80     # make primary2 unresponsive.
   81     set primary2_pid [get_instance_attrib redis $primary2_id pid]
   82     exec kill -SIGSTOP $primary2_pid
   83 
   84     # On primary1, send 128KB Pubsub messages in a loop until the send buffer of the link from
   85     # primary1 to primary2 exceeds buffer limit therefore be dropped.
   86     # For the send buffer to grow, we need to first exhaust TCP send buffer of primary1 and TCP
   87     # receive buffer of primary2 first. The sizes of these two buffers vary by OS, but 100 128KB
   88     # messages should be sufficient.
   89     set i 0
   90     wait_for_condition 100 0 {
   91         [catch {incr i} e] == 0 &&
   92         [catch {$primary1 publish channel [prepare_value [expr 128*1024]]} e] == 0 &&
   93         [catch {after 500} e] == 0 &&
   94         [get_info_field [$primary1 cluster info] total_cluster_links_buffer_limit_exceeded] >= 1
   95     } else {
   96         fail "Cluster link not freed as expected"
   97     }
   98     puts -nonewline "$i 128KB messages needed to overflow 256KB buffer limit. "
   99 
  100     # A new link to primary2 should have been recreated
  101     set new_link_p1_to_p2 [get_link_to_peer $primary1_id $primary2_name]
  102     assert {[dict get $new_link_p1_to_p2 create_time] > [dict get $orig_link_p1_to_p2 create_time]}
  103 
  104     # Link from primary2 should not be affected
  105     set same_link_p1_from_p2 [get_link_from_peer $primary1_id $primary2_name]
  106     assert {[dict get $same_link_p1_from_p2 create_time] eq [dict get $orig_link_p1_from_p2 create_time]}
  107 
  108     # Revive primary2
  109     exec kill -SIGCONT $primary2_pid
  110 
  111     # Reset configs on primary1 so config changes don't leak out to other tests
  112     $primary1 CONFIG set cluster-node-timeout $oldtimeout
  113     $primary1 CONFIG set cluster-link-sendbuf-limit $oldlimit
  114 }