File: fake_redis_node.tcl

package info (click to toggle)
redis 5%3A8.0.2-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 22,304 kB
  • sloc: ansic: 216,903; tcl: 51,562; sh: 4,625; perl: 4,214; cpp: 3,568; python: 2,954; makefile: 2,055; ruby: 639; javascript: 30; csh: 7
file content (60 lines) | stat: -rw-r--r-- 1,673 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# A fake Redis node for replaying predefined/expected traffic with a client.
#
# Usage: tclsh fake_redis_node.tcl PORT COMMAND REPLY [ COMMAND REPLY [ ... ] ]
#
# Commands are given as space-separated strings, e.g. "GET foo", and replies as
# RESP-encoded replies minus the trailing \r\n, e.g. "+OK".

set port [lindex $argv 0];
set expected_traffic [lrange $argv 1 end];

# Reads and parses a command from a socket and returns it as a space-separated
# string, e.g. "set foo bar".
proc read_command {sock} {
    set char [read $sock 1]
    switch $char {
        * {
            set numargs [gets $sock]
            set result {}
            for {set i 0} {$i<$numargs} {incr i} {
                read $sock 1;       # dollar sign
                set len [gets $sock]
                set str [read $sock $len]
                gets $sock;         # trailing \r\n
                lappend result $str
            }
            return $result
        }
        {} {
            # EOF
            return {}
        }
        default {
            # Non-RESP command
            set rest [gets $sock]
            return "$char$rest"
        }
    }
}

proc accept {sock host port} {
    global expected_traffic
    foreach {expect_cmd reply} $expected_traffic {
        if {[eof $sock]} {break}
        set cmd [read_command $sock]
        if {[string equal -nocase $cmd $expect_cmd]} {
            puts $sock $reply
            flush $sock
        } else {
            puts $sock "-ERR unexpected command $cmd"
            break
        }
    }
    close $sock
}

set sockfd [socket -server accept -myaddr 127.0.0.1 $port]
after 5000 set done timeout
vwait done
close $sockfd