test_helper.tcl 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856
  1. # Redis test suite. Copyright (C) 2009 Salvatore Sanfilippo antirez@gmail.com
  2. # This software is released under the BSD License. See the COPYING file for
  3. # more information.
  4. package require Tcl 8.5
  5. set tcl_precision 17
  6. source tests/support/redis.tcl
  7. source tests/support/server.tcl
  8. source tests/support/tmpfile.tcl
  9. source tests/support/test.tcl
  10. source tests/support/util.tcl
  11. set ::all_tests {
  12. unit/printver
  13. unit/dump
  14. unit/auth
  15. unit/protocol
  16. unit/keyspace
  17. unit/scan
  18. unit/info
  19. unit/type/string
  20. unit/type/incr
  21. unit/type/list
  22. unit/type/list-2
  23. unit/type/list-3
  24. unit/type/set
  25. unit/type/zset
  26. unit/type/hash
  27. unit/type/stream
  28. unit/type/stream-cgroups
  29. unit/sort
  30. unit/expire
  31. unit/other
  32. unit/multi
  33. unit/quit
  34. unit/aofrw
  35. unit/acl
  36. unit/latency-monitor
  37. integration/block-repl
  38. integration/replication
  39. integration/replication-2
  40. integration/replication-3
  41. integration/replication-4
  42. integration/replication-psync
  43. integration/aof
  44. integration/rdb
  45. integration/corrupt-dump
  46. integration/corrupt-dump-fuzzer
  47. integration/convert-zipmap-hash-on-load
  48. integration/convert-ziplist-hash-on-load
  49. integration/logging
  50. integration/psync2
  51. integration/psync2-reg
  52. integration/psync2-pingoff
  53. integration/failover
  54. integration/redis-cli
  55. integration/redis-benchmark
  56. integration/dismiss-mem
  57. unit/pubsub
  58. unit/slowlog
  59. unit/scripting
  60. unit/maxmemory
  61. unit/introspection
  62. unit/introspection-2
  63. unit/limits
  64. unit/obuf-limits
  65. unit/bitops
  66. unit/bitfield
  67. unit/geo
  68. unit/memefficiency
  69. unit/hyperloglog
  70. unit/lazyfree
  71. unit/wait
  72. unit/pause
  73. unit/querybuf
  74. unit/pendingquerybuf
  75. unit/tls
  76. unit/tracking
  77. unit/oom-score-adj
  78. unit/shutdown
  79. unit/networking
  80. }
  81. # Index to the next test to run in the ::all_tests list.
  82. set ::next_test 0
  83. set ::host 127.0.0.1
  84. set ::port 6379; # port for external server
  85. set ::baseport 21111; # initial port for spawned redis servers
  86. set ::portcount 8000; # we don't wanna use more than 10000 to avoid collision with cluster bus ports
  87. set ::traceleaks 0
  88. set ::valgrind 0
  89. set ::durable 0
  90. set ::tls 0
  91. set ::stack_logging 0
  92. set ::verbose 0
  93. set ::quiet 0
  94. set ::denytags {}
  95. set ::skiptests {}
  96. set ::skipunits {}
  97. set ::no_latency 0
  98. set ::allowtags {}
  99. set ::only_tests {}
  100. set ::single_tests {}
  101. set ::run_solo_tests {}
  102. set ::skip_till ""
  103. set ::external 0; # If "1" this means, we are running against external instance
  104. set ::file ""; # If set, runs only the tests in this comma separated list
  105. set ::curfile ""; # Hold the filename of the current suite
  106. set ::accurate 0; # If true runs fuzz tests with more iterations
  107. set ::force_failure 0
  108. set ::timeout 1200; # 20 minutes without progresses will quit the test.
  109. set ::last_progress [clock seconds]
  110. set ::active_servers {} ; # Pids of active Redis instances.
  111. set ::dont_clean 0
  112. set ::wait_server 0
  113. set ::stop_on_failure 0
  114. set ::dump_logs 0
  115. set ::loop 0
  116. set ::tlsdir "tests/tls"
  117. set ::singledb 0
  118. set ::cluster_mode 0
  119. set ::ignoreencoding 0
  120. set ::ignoredigest 0
  121. # Set to 1 when we are running in client mode. The Redis test uses a
  122. # server-client model to run tests simultaneously. The server instance
  123. # runs the specified number of client instances that will actually run tests.
  124. # The server is responsible of showing the result to the user, and exit with
  125. # the appropriate exit code depending on the test outcome.
  126. set ::client 0
  127. set ::numclients 16
  128. # This function is called by one of the test clients when it receives
  129. # a "run" command from the server, with a filename as data.
  130. # It will run the specified test source file and signal it to the
  131. # test server when finished.
  132. proc execute_test_file __testname {
  133. set path "tests/$__testname.tcl"
  134. set ::curfile $path
  135. source $path
  136. send_data_packet $::test_server_fd done "$__testname"
  137. }
  138. # This function is called by one of the test clients when it receives
  139. # a "run_code" command from the server, with a verbatim test source code
  140. # as argument, and an associated name.
  141. # It will run the specified code and signal it to the test server when
  142. # finished.
  143. proc execute_test_code {__testname filename code} {
  144. set ::curfile $filename
  145. eval $code
  146. send_data_packet $::test_server_fd done "$__testname"
  147. }
  148. # Setup a list to hold a stack of server configs. When calls to start_server
  149. # are nested, use "srv 0 pid" to get the pid of the inner server. To access
  150. # outer servers, use "srv -1 pid" etcetera.
  151. set ::servers {}
  152. proc srv {args} {
  153. set level 0
  154. if {[string is integer [lindex $args 0]]} {
  155. set level [lindex $args 0]
  156. set property [lindex $args 1]
  157. } else {
  158. set property [lindex $args 0]
  159. }
  160. set srv [lindex $::servers end+$level]
  161. dict get $srv $property
  162. }
  163. # Provide easy access to the client for the inner server. It's possible to
  164. # prepend the argument list with a negative level to access clients for
  165. # servers running in outer blocks.
  166. proc r {args} {
  167. set level 0
  168. if {[string is integer [lindex $args 0]]} {
  169. set level [lindex $args 0]
  170. set args [lrange $args 1 end]
  171. }
  172. [srv $level "client"] {*}$args
  173. }
  174. proc reconnect {args} {
  175. set level [lindex $args 0]
  176. if {[string length $level] == 0 || ![string is integer $level]} {
  177. set level 0
  178. }
  179. set srv [lindex $::servers end+$level]
  180. set host [dict get $srv "host"]
  181. set port [dict get $srv "port"]
  182. set config [dict get $srv "config"]
  183. set client [redis $host $port 0 $::tls]
  184. if {[dict exists $srv "client"]} {
  185. set old [dict get $srv "client"]
  186. $old close
  187. }
  188. dict set srv "client" $client
  189. # select the right db when we don't have to authenticate
  190. if {![dict exists $config "requirepass"] && !$::singledb} {
  191. $client select 9
  192. }
  193. # re-set $srv in the servers list
  194. lset ::servers end+$level $srv
  195. }
  196. proc redis_deferring_client {args} {
  197. set level 0
  198. if {[llength $args] > 0 && [string is integer [lindex $args 0]]} {
  199. set level [lindex $args 0]
  200. set args [lrange $args 1 end]
  201. }
  202. # create client that defers reading reply
  203. set client [redis [srv $level "host"] [srv $level "port"] 1 $::tls]
  204. # select the right db and read the response (OK)
  205. if {!$::singledb} {
  206. $client select 9
  207. $client read
  208. } else {
  209. # For timing/symmetry with the above select
  210. $client ping
  211. $client read
  212. }
  213. return $client
  214. }
  215. proc redis_client {args} {
  216. set level 0
  217. if {[llength $args] > 0 && [string is integer [lindex $args 0]]} {
  218. set level [lindex $args 0]
  219. set args [lrange $args 1 end]
  220. }
  221. # create client that defers reading reply
  222. set client [redis [srv $level "host"] [srv $level "port"] 0 $::tls]
  223. # select the right db and read the response (OK), or at least ping
  224. # the server if we're in a singledb mode.
  225. if {$::singledb} {
  226. $client ping
  227. } else {
  228. $client select 9
  229. }
  230. return $client
  231. }
  232. # Provide easy access to INFO properties. Same semantic as "proc r".
  233. proc s {args} {
  234. set level 0
  235. if {[string is integer [lindex $args 0]]} {
  236. set level [lindex $args 0]
  237. set args [lrange $args 1 end]
  238. }
  239. status [srv $level "client"] [lindex $args 0]
  240. }
  241. # Test wrapped into run_solo are sent back from the client to the
  242. # test server, so that the test server will send them again to
  243. # clients once the clients are idle.
  244. proc run_solo {name code} {
  245. if {$::numclients == 1 || $::loop || $::external} {
  246. # run_solo is not supported in these scenarios, just run the code.
  247. eval $code
  248. return
  249. }
  250. send_data_packet $::test_server_fd run_solo [list $name $::curfile $code]
  251. }
  252. proc cleanup {} {
  253. if {!$::quiet} {puts -nonewline "Cleanup: may take some time... "}
  254. flush stdout
  255. catch {exec rm -rf {*}[glob tests/tmp/redis.conf.*]}
  256. catch {exec rm -rf {*}[glob tests/tmp/server.*]}
  257. if {!$::quiet} {puts "OK"}
  258. }
  259. proc test_server_main {} {
  260. cleanup
  261. set tclsh [info nameofexecutable]
  262. # Open a listening socket, trying different ports in order to find a
  263. # non busy one.
  264. set clientport [find_available_port [expr {$::baseport - 32}] 32]
  265. if {!$::quiet} {
  266. puts "Starting test server at port $clientport"
  267. }
  268. socket -server accept_test_clients -myaddr 127.0.0.1 $clientport
  269. # Start the client instances
  270. set ::clients_pids {}
  271. if {$::external} {
  272. set p [exec $tclsh [info script] {*}$::argv \
  273. --client $clientport &]
  274. lappend ::clients_pids $p
  275. } else {
  276. set start_port $::baseport
  277. set port_count [expr {$::portcount / $::numclients}]
  278. for {set j 0} {$j < $::numclients} {incr j} {
  279. set p [exec $tclsh [info script] {*}$::argv \
  280. --client $clientport --baseport $start_port --portcount $port_count &]
  281. lappend ::clients_pids $p
  282. incr start_port $port_count
  283. }
  284. }
  285. # Setup global state for the test server
  286. set ::idle_clients {}
  287. set ::active_clients {}
  288. array set ::active_clients_task {}
  289. array set ::clients_start_time {}
  290. set ::clients_time_history {}
  291. set ::failed_tests {}
  292. # Enter the event loop to handle clients I/O
  293. after 100 test_server_cron
  294. vwait forever
  295. }
  296. # This function gets called 10 times per second.
  297. proc test_server_cron {} {
  298. set elapsed [expr {[clock seconds]-$::last_progress}]
  299. if {$elapsed > $::timeout} {
  300. set err "\[[colorstr red TIMEOUT]\]: clients state report follows."
  301. puts $err
  302. lappend ::failed_tests $err
  303. show_clients_state
  304. kill_clients
  305. force_kill_all_servers
  306. the_end
  307. }
  308. after 100 test_server_cron
  309. }
  310. proc accept_test_clients {fd addr port} {
  311. fconfigure $fd -encoding binary
  312. fileevent $fd readable [list read_from_test_client $fd]
  313. }
  314. # This is the readable handler of our test server. Clients send us messages
  315. # in the form of a status code such and additional data. Supported
  316. # status types are:
  317. #
  318. # ready: the client is ready to execute the command. Only sent at client
  319. # startup. The server will queue the client FD in the list of idle
  320. # clients.
  321. # testing: just used to signal that a given test started.
  322. # ok: a test was executed with success.
  323. # err: a test was executed with an error.
  324. # skip: a test was skipped by skipfile or individual test options.
  325. # ignore: a test was skipped by a group tag.
  326. # exception: there was a runtime exception while executing the test.
  327. # done: all the specified test file was processed, this test client is
  328. # ready to accept a new task.
  329. proc read_from_test_client fd {
  330. set bytes [gets $fd]
  331. set payload [read $fd $bytes]
  332. foreach {status data} $payload break
  333. set ::last_progress [clock seconds]
  334. if {$status eq {ready}} {
  335. if {!$::quiet} {
  336. puts "\[$status\]: $data"
  337. }
  338. signal_idle_client $fd
  339. } elseif {$status eq {done}} {
  340. set elapsed [expr {[clock seconds]-$::clients_start_time($fd)}]
  341. set all_tests_count [llength $::all_tests]
  342. set running_tests_count [expr {[llength $::active_clients]-1}]
  343. set completed_tests_count [expr {$::next_test-$running_tests_count}]
  344. puts "\[$completed_tests_count/$all_tests_count [colorstr yellow $status]\]: $data ($elapsed seconds)"
  345. lappend ::clients_time_history $elapsed $data
  346. signal_idle_client $fd
  347. set ::active_clients_task($fd) "(DONE) $data"
  348. } elseif {$status eq {ok}} {
  349. if {!$::quiet} {
  350. puts "\[[colorstr green $status]\]: $data"
  351. }
  352. set ::active_clients_task($fd) "(OK) $data"
  353. } elseif {$status eq {skip}} {
  354. if {!$::quiet} {
  355. puts "\[[colorstr yellow $status]\]: $data"
  356. }
  357. } elseif {$status eq {ignore}} {
  358. if {!$::quiet} {
  359. puts "\[[colorstr cyan $status]\]: $data"
  360. }
  361. } elseif {$status eq {err}} {
  362. set err "\[[colorstr red $status]\]: $data"
  363. puts $err
  364. lappend ::failed_tests $err
  365. set ::active_clients_task($fd) "(ERR) $data"
  366. if {$::stop_on_failure} {
  367. puts -nonewline "(Test stopped, press enter to resume the tests)"
  368. flush stdout
  369. gets stdin
  370. }
  371. } elseif {$status eq {exception}} {
  372. puts "\[[colorstr red $status]\]: $data"
  373. kill_clients
  374. force_kill_all_servers
  375. exit 1
  376. } elseif {$status eq {testing}} {
  377. set ::active_clients_task($fd) "(IN PROGRESS) $data"
  378. } elseif {$status eq {server-spawning}} {
  379. set ::active_clients_task($fd) "(SPAWNING SERVER) $data"
  380. } elseif {$status eq {server-spawned}} {
  381. lappend ::active_servers $data
  382. set ::active_clients_task($fd) "(SPAWNED SERVER) pid:$data"
  383. } elseif {$status eq {server-killing}} {
  384. set ::active_clients_task($fd) "(KILLING SERVER) pid:$data"
  385. } elseif {$status eq {server-killed}} {
  386. set ::active_servers [lsearch -all -inline -not -exact $::active_servers $data]
  387. set ::active_clients_task($fd) "(KILLED SERVER) pid:$data"
  388. } elseif {$status eq {run_solo}} {
  389. lappend ::run_solo_tests $data
  390. } else {
  391. if {!$::quiet} {
  392. puts "\[$status\]: $data"
  393. }
  394. }
  395. }
  396. proc show_clients_state {} {
  397. # The following loop is only useful for debugging tests that may
  398. # enter an infinite loop.
  399. foreach x $::active_clients {
  400. if {[info exist ::active_clients_task($x)]} {
  401. puts "$x => $::active_clients_task($x)"
  402. } else {
  403. puts "$x => ???"
  404. }
  405. }
  406. }
  407. proc kill_clients {} {
  408. foreach p $::clients_pids {
  409. catch {exec kill $p}
  410. }
  411. }
  412. proc force_kill_all_servers {} {
  413. foreach p $::active_servers {
  414. puts "Killing still running Redis server $p"
  415. catch {exec kill -9 $p}
  416. }
  417. }
  418. proc lpop {listVar {count 1}} {
  419. upvar 1 $listVar l
  420. set ele [lindex $l 0]
  421. set l [lrange $l 1 end]
  422. set ele
  423. }
  424. proc lremove {listVar value} {
  425. upvar 1 $listVar var
  426. set idx [lsearch -exact $var $value]
  427. set var [lreplace $var $idx $idx]
  428. }
  429. # A new client is idle. Remove it from the list of active clients and
  430. # if there are still test units to run, launch them.
  431. proc signal_idle_client fd {
  432. # Remove this fd from the list of active clients.
  433. set ::active_clients \
  434. [lsearch -all -inline -not -exact $::active_clients $fd]
  435. # New unit to process?
  436. if {$::next_test != [llength $::all_tests]} {
  437. if {!$::quiet} {
  438. puts [colorstr bold-white "Testing [lindex $::all_tests $::next_test]"]
  439. set ::active_clients_task($fd) "ASSIGNED: $fd ([lindex $::all_tests $::next_test])"
  440. }
  441. set ::clients_start_time($fd) [clock seconds]
  442. send_data_packet $fd run [lindex $::all_tests $::next_test]
  443. lappend ::active_clients $fd
  444. incr ::next_test
  445. if {$::loop && $::next_test == [llength $::all_tests]} {
  446. set ::next_test 0
  447. }
  448. } elseif {[llength $::run_solo_tests] != 0 && [llength $::active_clients] == 0} {
  449. if {!$::quiet} {
  450. puts [colorstr bold-white "Testing solo test"]
  451. set ::active_clients_task($fd) "ASSIGNED: $fd solo test"
  452. }
  453. set ::clients_start_time($fd) [clock seconds]
  454. send_data_packet $fd run_code [lpop ::run_solo_tests]
  455. lappend ::active_clients $fd
  456. } else {
  457. lappend ::idle_clients $fd
  458. set ::active_clients_task($fd) "SLEEPING, no more units to assign"
  459. if {[llength $::active_clients] == 0} {
  460. the_end
  461. }
  462. }
  463. }
  464. # The the_end function gets called when all the test units were already
  465. # executed, so the test finished.
  466. proc the_end {} {
  467. # TODO: print the status, exit with the right exit code.
  468. puts "\n The End\n"
  469. puts "Execution time of different units:"
  470. foreach {time name} $::clients_time_history {
  471. puts " $time seconds - $name"
  472. }
  473. if {[llength $::failed_tests]} {
  474. puts "\n[colorstr bold-red {!!! WARNING}] The following tests failed:\n"
  475. foreach failed $::failed_tests {
  476. puts "*** $failed"
  477. }
  478. if {!$::dont_clean} cleanup
  479. exit 1
  480. } else {
  481. puts "\n[colorstr bold-white {\o/}] [colorstr bold-green {All tests passed without errors!}]\n"
  482. if {!$::dont_clean} cleanup
  483. exit 0
  484. }
  485. }
  486. # The client is not even driven (the test server is instead) as we just need
  487. # to read the command, execute, reply... all this in a loop.
  488. proc test_client_main server_port {
  489. set ::test_server_fd [socket localhost $server_port]
  490. fconfigure $::test_server_fd -encoding binary
  491. send_data_packet $::test_server_fd ready [pid]
  492. while 1 {
  493. set bytes [gets $::test_server_fd]
  494. set payload [read $::test_server_fd $bytes]
  495. foreach {cmd data} $payload break
  496. if {$cmd eq {run}} {
  497. execute_test_file $data
  498. } elseif {$cmd eq {run_code}} {
  499. foreach {name filename code} $data break
  500. execute_test_code $name $filename $code
  501. } else {
  502. error "Unknown test client command: $cmd"
  503. }
  504. }
  505. }
  506. proc send_data_packet {fd status data} {
  507. set payload [list $status $data]
  508. puts $fd [string length $payload]
  509. puts -nonewline $fd $payload
  510. flush $fd
  511. }
  512. proc print_help_screen {} {
  513. puts [join {
  514. "--valgrind Run the test over valgrind."
  515. "--durable suppress test crashes and keep running"
  516. "--stack-logging Enable OSX leaks/malloc stack logging."
  517. "--accurate Run slow randomized tests for more iterations."
  518. "--quiet Don't show individual tests."
  519. "--single <unit> Just execute the specified unit (see next option). This option can be repeated."
  520. "--verbose Increases verbosity."
  521. "--list-tests List all the available test units."
  522. "--only <test> Just execute tests that match <test> regexp. This option can be repeated."
  523. "--skip-till <unit> Skip all units until (and including) the specified one."
  524. "--skipunit <unit> Skip one unit."
  525. "--clients <num> Number of test clients (default 16)."
  526. "--timeout <sec> Test timeout in seconds (default 10 min)."
  527. "--force-failure Force the execution of a test that always fails."
  528. "--config <k> <v> Extra config file argument."
  529. "--skipfile <file> Name of a file containing test names that should be skipped (one per line)."
  530. "--skiptest <name> Name of a file containing test names that should be skipped (one per line)."
  531. "--tags <tags> Run only tests having specified tags or not having '-' prefixed tags."
  532. "--dont-clean Don't delete redis log files after the run."
  533. "--no-latency Skip latency measurements and validation by some tests."
  534. "--stop Blocks once the first test fails."
  535. "--loop Execute the specified set of tests forever."
  536. "--wait-server Wait after server is started (so that you can attach a debugger)."
  537. "--dump-logs Dump server log on test failure."
  538. "--tls Run tests in TLS mode."
  539. "--host <addr> Run tests against an external host."
  540. "--port <port> TCP port to use against external host."
  541. "--baseport <port> Initial port number for spawned redis servers."
  542. "--portcount <num> Port range for spawned redis servers."
  543. "--singledb Use a single database, avoid SELECT."
  544. "--cluster-mode Run tests in cluster protocol compatible mode."
  545. "--ignore-encoding Don't validate object encoding."
  546. "--ignore-digest Don't use debug digest validations."
  547. "--help Print this help screen."
  548. } "\n"]
  549. }
  550. # parse arguments
  551. for {set j 0} {$j < [llength $argv]} {incr j} {
  552. set opt [lindex $argv $j]
  553. set arg [lindex $argv [expr $j+1]]
  554. if {$opt eq {--tags}} {
  555. foreach tag $arg {
  556. if {[string index $tag 0] eq "-"} {
  557. lappend ::denytags [string range $tag 1 end]
  558. } else {
  559. lappend ::allowtags $tag
  560. }
  561. }
  562. incr j
  563. } elseif {$opt eq {--config}} {
  564. set arg2 [lindex $argv [expr $j+2]]
  565. lappend ::global_overrides $arg
  566. lappend ::global_overrides $arg2
  567. incr j 2
  568. } elseif {$opt eq {--skipfile}} {
  569. incr j
  570. set fp [open $arg r]
  571. set file_data [read $fp]
  572. close $fp
  573. set ::skiptests [split $file_data "\n"]
  574. } elseif {$opt eq {--skiptest}} {
  575. lappend ::skiptests $arg
  576. incr j
  577. } elseif {$opt eq {--valgrind}} {
  578. set ::valgrind 1
  579. } elseif {$opt eq {--stack-logging}} {
  580. if {[string match {*Darwin*} [exec uname -a]]} {
  581. set ::stack_logging 1
  582. }
  583. } elseif {$opt eq {--quiet}} {
  584. set ::quiet 1
  585. } elseif {$opt eq {--tls}} {
  586. package require tls 1.6
  587. set ::tls 1
  588. ::tls::init \
  589. -cafile "$::tlsdir/ca.crt" \
  590. -certfile "$::tlsdir/client.crt" \
  591. -keyfile "$::tlsdir/client.key"
  592. } elseif {$opt eq {--host}} {
  593. set ::external 1
  594. set ::host $arg
  595. incr j
  596. } elseif {$opt eq {--port}} {
  597. set ::port $arg
  598. incr j
  599. } elseif {$opt eq {--baseport}} {
  600. set ::baseport $arg
  601. incr j
  602. } elseif {$opt eq {--portcount}} {
  603. set ::portcount $arg
  604. incr j
  605. } elseif {$opt eq {--accurate}} {
  606. set ::accurate 1
  607. } elseif {$opt eq {--force-failure}} {
  608. set ::force_failure 1
  609. } elseif {$opt eq {--single}} {
  610. lappend ::single_tests $arg
  611. incr j
  612. } elseif {$opt eq {--only}} {
  613. lappend ::only_tests $arg
  614. incr j
  615. } elseif {$opt eq {--skipunit}} {
  616. lappend ::skipunits $arg
  617. incr j
  618. } elseif {$opt eq {--skip-till}} {
  619. set ::skip_till $arg
  620. incr j
  621. } elseif {$opt eq {--list-tests}} {
  622. foreach t $::all_tests {
  623. puts $t
  624. }
  625. exit 0
  626. } elseif {$opt eq {--verbose}} {
  627. set ::verbose 1
  628. } elseif {$opt eq {--client}} {
  629. set ::client 1
  630. set ::test_server_port $arg
  631. incr j
  632. } elseif {$opt eq {--clients}} {
  633. set ::numclients $arg
  634. incr j
  635. } elseif {$opt eq {--durable}} {
  636. set ::durable 1
  637. } elseif {$opt eq {--dont-clean}} {
  638. set ::dont_clean 1
  639. } elseif {$opt eq {--no-latency}} {
  640. set ::no_latency 1
  641. } elseif {$opt eq {--wait-server}} {
  642. set ::wait_server 1
  643. } elseif {$opt eq {--dump-logs}} {
  644. set ::dump_logs 1
  645. } elseif {$opt eq {--stop}} {
  646. set ::stop_on_failure 1
  647. } elseif {$opt eq {--loop}} {
  648. set ::loop 1
  649. } elseif {$opt eq {--timeout}} {
  650. set ::timeout $arg
  651. incr j
  652. } elseif {$opt eq {--singledb}} {
  653. set ::singledb 1
  654. } elseif {$opt eq {--cluster-mode}} {
  655. set ::cluster_mode 1
  656. set ::singledb 1
  657. } elseif {$opt eq {--ignore-encoding}} {
  658. set ::ignoreencoding 1
  659. } elseif {$opt eq {--ignore-digest}} {
  660. set ::ignoredigest 1
  661. } elseif {$opt eq {--help}} {
  662. print_help_screen
  663. exit 0
  664. } else {
  665. puts "Wrong argument: $opt"
  666. exit 1
  667. }
  668. }
  669. set filtered_tests {}
  670. # Set the filtered tests to be the short list (single_tests) if exists.
  671. # Otherwise, we start filtering all_tests
  672. if {[llength $::single_tests] > 0} {
  673. set filtered_tests $::single_tests
  674. } else {
  675. set filtered_tests $::all_tests
  676. }
  677. # If --skip-till option was given, we populate the list of single tests
  678. # to run with everything *after* the specified unit.
  679. if {$::skip_till != ""} {
  680. set skipping 1
  681. foreach t $::all_tests {
  682. if {$skipping == 1} {
  683. lremove filtered_tests $t
  684. }
  685. if {$t == $::skip_till} {
  686. set skipping 0
  687. }
  688. }
  689. if {$skipping} {
  690. puts "test $::skip_till not found"
  691. exit 0
  692. }
  693. }
  694. # If --skipunits option was given, we populate the list of single tests
  695. # to run with everything *not* in the skipunits list.
  696. if {[llength $::skipunits] > 0} {
  697. foreach t $::all_tests {
  698. if {[lsearch $::skipunits $t] != -1} {
  699. lremove filtered_tests $t
  700. }
  701. }
  702. }
  703. # Override the list of tests with the specific tests we want to run
  704. # in case there was some filter, that is --single, -skipunit or --skip-till options.
  705. if {[llength $filtered_tests] < [llength $::all_tests]} {
  706. set ::all_tests $filtered_tests
  707. }
  708. proc attach_to_replication_stream {} {
  709. r config set repl-ping-replica-period 3600
  710. if {$::tls} {
  711. set s [::tls::socket [srv 0 "host"] [srv 0 "port"]]
  712. } else {
  713. set s [socket [srv 0 "host"] [srv 0 "port"]]
  714. }
  715. fconfigure $s -translation binary
  716. puts -nonewline $s "SYNC\r\n"
  717. flush $s
  718. # Get the count
  719. while 1 {
  720. set count [gets $s]
  721. set prefix [string range $count 0 0]
  722. if {$prefix ne {}} break; # Newlines are allowed as PINGs.
  723. }
  724. if {$prefix ne {$}} {
  725. error "attach_to_replication_stream error. Received '$count' as count."
  726. }
  727. set count [string range $count 1 end]
  728. # Consume the bulk payload
  729. while {$count} {
  730. set buf [read $s $count]
  731. set count [expr {$count-[string length $buf]}]
  732. }
  733. return $s
  734. }
  735. proc read_from_replication_stream {s} {
  736. fconfigure $s -blocking 0
  737. set attempt 0
  738. while {[gets $s count] == -1} {
  739. if {[incr attempt] == 10} return ""
  740. after 100
  741. }
  742. fconfigure $s -blocking 1
  743. set count [string range $count 1 end]
  744. # Return a list of arguments for the command.
  745. set res {}
  746. for {set j 0} {$j < $count} {incr j} {
  747. read $s 1
  748. set arg [::redis::redis_bulk_read $s]
  749. if {$j == 0} {set arg [string tolower $arg]}
  750. lappend res $arg
  751. }
  752. return $res
  753. }
  754. proc assert_replication_stream {s patterns} {
  755. for {set j 0} {$j < [llength $patterns]} {incr j} {
  756. assert_match [lindex $patterns $j] [read_from_replication_stream $s]
  757. }
  758. }
  759. proc close_replication_stream {s} {
  760. close $s
  761. r config set repl-ping-replica-period 10
  762. return
  763. }
  764. # With the parallel test running multiple Redis instances at the same time
  765. # we need a fast enough computer, otherwise a lot of tests may generate
  766. # false positives.
  767. # If the computer is too slow we revert the sequential test without any
  768. # parallelism, that is, clients == 1.
  769. proc is_a_slow_computer {} {
  770. set start [clock milliseconds]
  771. for {set j 0} {$j < 1000000} {incr j} {}
  772. set elapsed [expr [clock milliseconds]-$start]
  773. expr {$elapsed > 200}
  774. }
  775. if {$::client} {
  776. if {[catch { test_client_main $::test_server_port } err]} {
  777. set estr "Executing test client: $err.\n$::errorInfo"
  778. if {[catch {send_data_packet $::test_server_fd exception $estr}]} {
  779. puts $estr
  780. }
  781. exit 1
  782. }
  783. } else {
  784. if {[is_a_slow_computer]} {
  785. puts "** SLOW COMPUTER ** Using a single client to avoid false positives."
  786. set ::numclients 1
  787. }
  788. if {[catch { test_server_main } err]} {
  789. if {[string length $err] > 0} {
  790. # only display error when not generated by the test suite
  791. if {$err ne "exception"} {
  792. puts $::errorInfo
  793. }
  794. exit 1
  795. }
  796. }
  797. }