File: websocket.test

package info (click to toggle)
tcllib 2.0%2Bdfsg-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 83,560 kB
  • sloc: tcl: 306,798; ansic: 14,272; sh: 3,035; xml: 1,766; yacc: 1,157; pascal: 881; makefile: 124; perl: 84; f90: 84; python: 33; ruby: 13; php: 11
file content (207 lines) | stat: -rw-r--r-- 5,195 bytes parent folder | download | duplicates (2)
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
# websocket.test - Copyright (c) 2022 Keith Nash
#
# The tests use the WebSocket Echo Server hosted at ws.ifelse.io.
# ------------------------------------------------------------------------------

source [file join \
	[file dirname [file dirname [file join [pwd] [info script]]]] \
	devtools testutilities.tcl]

testsNeedTcl     8.6
testsNeedTcltest 2

testing {
    useLocal websocket.tcl websocket
}

# The commands ws*Handler* process responses from the server.

proc wsResetHandler {} {
    set ::wsMsgCounter 0
    set ::wsOutput     {}
    return
}

proc wsExpectHandler {lines} {
    set ::wsMsgMax $lines
    return
}

proc wsOutputHandler {args} {
    append ::wsOutput $args \n

    # Stop sleeping if we've had $wsMsgMax messages.
    incr ::wsMsgCounter
    if {$::wsMsgCounter == $::wsMsgMax} {
        wsStopSleep 1
    }
    return
}

# - The commands ws*Sleep allow time for the server to responses to arrive and
#   be processed by the output handler.
# - The default value of delay is a worst case for a slow server: the test will
#   time out if this value is reached.  The output handler counts the messages
#   and interrupts the sleep when the expected number of messages has arrived.
# - In the body of test, a second call to wsSleep gives the server the
#   opportunity to send excess messages.

proc wsSleep {{delay 10000}} {
    if {$::wsWAITER != 0} {
        # The wake-up call has arrived already.
        return
    }
    set ev [after $delay set ::wsWAITER -1]
    vwait ::wsWAITER
    after cancel $ev
    return
}

proc wsResetSleep {} {
    set ::wsWAITER 0
    return
}

proc wsStopSleep {val} {
    set ::wsWAITER $val
    return
}

set wsNum 0

# Set the test URL.
# The value of expectNum, and some of the result strings, depend on the
# server configuration and therefore on the URL.
set wsUrl ws://ws.ifelse.io
set expectNum 2

test example-1.1 "Open a websocket" -constraints {} -setup {
    wsResetSleep
    wsResetHandler
} -body {
    wsExpectHandler $expectNum
    set ws1 [::websocket::open $wsUrl wsOutputHandler]
    wsSleep
    wsResetSleep
    wsSleep 1000
    string map [list $ws1 SOCKET] $wsOutput
} -cleanup {
    ::websocket::close $ws1
    wsSleep
    wsResetSleep
    wsResetHandler
} -match glob -result {SOCKET connect {}
SOCKET text {Request served by *}
}

test example-1.2 "Close a websocket" -constraints {} -setup {
    wsResetHandler
    wsResetSleep
    wsExpectHandler $expectNum
    set ws1 [::websocket::open $wsUrl wsOutputHandler]
    wsSleep
    wsResetHandler
    wsResetSleep
} -body {
    ::websocket::close $ws1
    wsSleep
    wsResetSleep
    wsSleep 1000
    string map [list $ws1 SOCKET] $wsOutput
} -cleanup {
    wsResetSleep
    wsResetHandler
} -match exact -result {SOCKET close {1000 {Normal closure}}
SOCKET disconnect {Disconnected from remote end}
}

test example-1.3 "Open second websocket - require different socket" -constraints {} -setup {
    wsResetSleep
    wsResetHandler
    wsExpectHandler $expectNum
    set ws1 [::websocket::open $wsUrl wsOutputHandler]
    wsSleep
    wsResetSleep
    wsResetHandler
} -body {
    wsExpectHandler $expectNum
    set ws2 [::websocket::open $wsUrl wsOutputHandler]
    if {$ws1 eq $ws2} {
        set res "Both sockets are $ws1"
    } else {
        set res "Sockets differ: $ws1 and $ws2"
    }
} -cleanup {
    catch {::websocket::close $ws1}
    catch {::websocket::close $ws2}
    wsResetSleep
    wsResetHandler
} -match glob -result {Sockets differ: *}

test example-1.4 "Open second websocket - usual server return" -constraints {} -setup {
    wsResetSleep
    wsResetHandler
    wsExpectHandler $expectNum
    set ws1 [::websocket::open $wsUrl wsOutputHandler]
    wsSleep
    wsResetSleep
    wsResetHandler
} -body {
    wsExpectHandler $expectNum
    set ws2 [::websocket::open $wsUrl wsOutputHandler]
    if {$ws1 eq $ws2} {
        return -code error "Both sockets are $ws1"
    }
    wsSleep
    wsResetSleep
    wsSleep 1000
    string map [list $ws2 SOCKET] $wsOutput
} -cleanup {
    catch {::websocket::close $ws1}
    catch {::websocket::close $ws2}
    wsResetSleep
    wsResetHandler
} -match glob -result {SOCKET connect {}
SOCKET text {Request served by *}
}

test example-2.1 "Send a message" -constraints {} -setup {
    wsResetHandler
    wsResetSleep
    wsExpectHandler $expectNum
    set ws1 [::websocket::open $wsUrl wsOutputHandler]
    wsSleep
    wsResetHandler
    wsResetSleep
} -body {
    wsExpectHandler 1
    set ::newMessage "Hello this is message <[incr wsNum]>"
    ::websocket::send $ws1 text $::newMessage
    wsSleep
    wsResetSleep
    wsSleep 1000
    string map [list $ws1 SOCKET <${wsNum}> NUMBER] $wsOutput
} -cleanup {
    wsExpectHandler $expectNum
    ::websocket::close $ws1
    wsSleep
    wsResetSleep
    wsResetHandler
} -match exact -result {SOCKET text {Hello this is message NUMBER}
}

testsuiteCleanup
unset -nocomplain wsNum wsMsgCounter wsOutput wsMsgMax wsWAITER wsUrl expectNum ws1 ws2 newMessage
foreach pr {
    wsResetHandler wsExpectHandler wsOutputHandler
    wsSleep wsResetSleep wsStopSleep
} {
    rename $pr {}
}


# Local variables:
#   mode: tcl
#   indent-tabs-mode: nil
# End: