Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 252 lines (232 sloc) 11.551 kb
59697b4 @ahyatt Initial checkin of files. These files were initially part of the
authored
1 ;;; websocket-test.el --- Unit tests for the websocket layer
2
3 ;; Copyright (c) 2010 Andrew Hyatt
4 ;;
5 ;; Author: Andrew Hyatt <ahyatt at gmail dot com>
6 ;; Maintainer: Andrew Hyatt <ahyatt at gmail dot com>
7 ;;
8 ;; This program is free software; you can redistribute it and/or
9 ;; modify it under the terms of the GNU General Public License as
10 ;; published by the Free Software Foundation; either version 2 of the
11 ;; License, or (at your option) any later version.
12 ;;
13 ;; This program is distributed in the hope that it will be useful, but
14 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 ;; General Public License for more details.
17 ;;
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with this program; if not, write to the Free Software
20 ;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 ;; 02110-1301, USA.
22
23 ;;; Commentary:
24 ;; This defines and runs ert unit tests. You can download ert from:
25 ;; http://github.com/ohler/ert, it also comes with Emacs 24 and above.
26
27 (require 'ert)
9d8794a @tkf Suppress compilation warning in websocket-test.el
tkf authored
28 (require 'websocket)
29 (eval-when-compile (require 'cl))
59697b4 @ahyatt Initial checkin of files. These files were initially part of the
authored
30
31 (defun websocket-test-get-filtered-response (outputs)
9d8794a @tkf Suppress compilation warning in websocket-test.el
tkf authored
32 (let* ((packet-data nil)
33 (websocket
34 (make-websocket :conn "fake-conn"
35 :filter (lambda (packet) (push packet packet-data))
36 :close-callback (lambda (not-called) (assert nil))
763cb60 @ahyatt Get rid of all mentions of version 75.
authored
37 :url "ws://foo/bar")))
59697b4 @ahyatt Initial checkin of files. These files were initially part of the
authored
38 (dolist (output outputs)
39 (websocket-outer-filter websocket output))
40 (nreverse packet-data)))
41
45245a4 @tkf Add test websocket-genbytes-length
tkf authored
42 (ert-deftest websocket-genbytes-length ()
43 (loop repeat 100
82e85aa @ahyatt Fix test for websocket-genbytes
authored
44 do (should (= (string-bytes (websocket-genbytes 16)) 16))))
45245a4 @tkf Add test websocket-genbytes-length
tkf authored
45
b5bbce1 @ahyatt Add a function to calculate the accept header expected.
authored
46 (ert-deftest websocket-calculate-accept ()
47 ;; This example comes straight from RFC 6455
48 (should
49 (equal "s3pPLMBiTxaQ9kYGzzhZRbK+xOo="
237b190 @ahyatt Various whitespace changes
authored
50 (websocket-calculate-accept "dGhlIHNhbXBsZSBub25jZQ=="))))
b5bbce1 @ahyatt Add a function to calculate the accept header expected.
authored
51
f4e1aa8 @ahyatt Add helper functions for websocket-get-opcode and
authored
52 (defconst websocket-test-hello "\x81\x05\x48\x65\x6c\x6c\x6f"
53 "'Hello' string example, taken from the RFC.")
237b190 @ahyatt Various whitespace changes
authored
54
4c8dbe2 @ahyatt Implement masking and unmasking.
authored
55 (defconst websocket-test-masked-hello
56 "\x81\x85\x37\xfa\x21\x3d\x7f\x9f\x4d\x51\x58"
57 "'Hello' masked string example, taken from the RFC.")
f4e1aa8 @ahyatt Add helper functions for websocket-get-opcode and
authored
58
b948e95 @ahyatt Fixed payload len logic, and rewrote the bit-grabbing bits to just
authored
59 (ert-deftest websocket-get-bytes ()
60 (should (equal #x5 (websocket-get-bytes "\x5" 1)))
61 (should (equal #x101 (websocket-get-bytes "\x1\x1" 2)))
62 (should (equal #x100000001
63 (websocket-get-bytes "\x0\x0\x0\x1\x0\x0\x0\x1" 8)))
64 (should-error (websocket-get-bytes "\x0\x0\x0" 3))
65 (should-error (websocket-get-bytes "\x0" 2)))
66
f4e1aa8 @ahyatt Add helper functions for websocket-get-opcode and
authored
67 (ert-deftest websocket-get-opcode ()
68 (should (equal 'text (websocket-get-opcode websocket-test-hello))))
69
70 (ert-deftest websocket-get-payload-len ()
b948e95 @ahyatt Fixed payload len logic, and rewrote the bit-grabbing bits to just
authored
71 (should (equal '(5 . 1)
72 (websocket-get-payload-len
73 (substring websocket-test-hello 1))))
f4e1aa8 @ahyatt Add helper functions for websocket-get-opcode and
authored
74 (should (equal '(200 . 3)
75 (websocket-get-payload-len
b948e95 @ahyatt Fixed payload len logic, and rewrote the bit-grabbing bits to just
authored
76 (bindat-pack '((:len u8) (:val u16))
77 `((:len . 126)
f4e1aa8 @ahyatt Add helper functions for websocket-get-opcode and
authored
78 (:val . 200))))))
79 ;; we don't want to hit up any limits even on strange emacs builds,
80 ;; so this test has a pretty small test value
81 (should (equal '(70000 . 9)
82 (websocket-get-payload-len
b948e95 @ahyatt Fixed payload len logic, and rewrote the bit-grabbing bits to just
authored
83 (bindat-pack '((:len u8) (:val vec 2 u32))
84 `((:len . 127)
f4e1aa8 @ahyatt Add helper functions for websocket-get-opcode and
authored
85 (:val . [0 70000])))))))
ae51a78 @ahyatt Code to read a frame. Does not yet support masking.
authored
86
87 (ert-deftest websocket-read-frame ()
7900cda @ahyatt Return the length of the websocket frame from websocket-read-frame.
authored
88 (should (equal (make-websocket-frame :opcode 'text :payload "Hello"
b0a2970 @ahyatt Add completep in frame
authored
89 :length (length websocket-test-hello)
90 :completep t)
4c8dbe2 @ahyatt Implement masking and unmasking.
authored
91 (websocket-read-frame websocket-test-hello)))
7900cda @ahyatt Return the length of the websocket frame from websocket-read-frame.
authored
92 (should (equal (make-websocket-frame :opcode 'text :payload "Hello"
b0a2970 @ahyatt Add completep in frame
authored
93 :length (length websocket-test-hello)
94 :completep t)
7900cda @ahyatt Return the length of the websocket frame from websocket-read-frame.
authored
95 (websocket-read-frame (concat websocket-test-hello
96 "should-not-be-read"))))
97 (should (equal (make-websocket-frame :opcode 'text :payload "Hello"
b0a2970 @ahyatt Add completep in frame
authored
98 :length (length websocket-test-masked-hello)
99 :completep t)
51b5764 @ahyatt Ensure the websocket frame is complete, and return NIL if not.
authored
100 (websocket-read-frame websocket-test-masked-hello)))
b0a2970 @ahyatt Add completep in frame
authored
101 (should (equal (make-websocket-frame :opcode 'text :payload "Hello"
102 :length (length websocket-test-hello)
103 :completep nil)
1081075 @ahyatt More whitespace changes
authored
104 (websocket-read-frame
105 (concat (unibyte-string
106 (logand (string-to-char
107 (substring websocket-test-hello 0 1))
108 127))
109 (substring websocket-test-hello 1)))))
51b5764 @ahyatt Ensure the websocket frame is complete, and return NIL if not.
authored
110 (dotimes (i (- (length websocket-test-hello) 1))
111 (should-not (websocket-read-frame
112 (substring websocket-test-hello 0
113 (- (length websocket-test-hello) (+ i 1))))))
114 (dotimes (i (- (length websocket-test-masked-hello) 1))
115 (should-not (websocket-read-frame
116 (substring websocket-test-masked-hello 0
117 (- (length websocket-test-masked-hello) (+ i 1)))))))
8da9119 @ahyatt Separate out the handshake verification logic, and test it. Look for
authored
118
119 (defun websocket-test-make-websocket-with-accept-string (s)
237b190 @ahyatt Various whitespace changes
authored
120 (make-websocket :conn "fake-conn" :url "ws://foo/bar" :filter t
121 :close-callback t :accept-string s))
8da9119 @ahyatt Separate out the handshake verification logic, and test it. Look for
authored
122
123 (ert-deftest websocket-verify-handshake ()
124 ;; This examples comes from the RFC
125 (should (websocket-verify-handshake
237b190 @ahyatt Various whitespace changes
authored
126 (websocket-test-make-websocket-with-accept-string
127 "s3pPLMBiTxaQ9kYGzzhZRbK+xOo=")
8da9119 @ahyatt Separate out the handshake verification logic, and test it. Look for
authored
128 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"))
129 (should-error (websocket-verify-handshake
237b190 @ahyatt Various whitespace changes
authored
130 (websocket-test-make-websocket-with-accept-string
131 "s3pPLMBiTxaQ9kYGzzhZRbK+xOo=")
8da9119 @ahyatt Separate out the handshake verification logic, and test it. Look for
authored
132 "Sec-WebSocket-Accept: foo\r\n")))
3a7798f @ahyatt Added frame processing, and more of the structure to use it.
authored
133
134 (ert-deftest websocket-process-frame ()
135 (let* ((sent)
136 (processed)
137 (deleted)
138 (websocket (make-websocket :conn "fake-conn"
139 :url "ws://foo/bar"
237b190 @ahyatt Various whitespace changes
authored
140 :filter (lambda (frame)
141 (setq
142 processed
143 (websocket-frame-payload frame)))
3a7798f @ahyatt Added frame processing, and more of the structure to use it.
authored
144 :close-callback t
145 :accept-string "accept-string")))
146 (dolist (opcode '(text binary continuation))
147 (setq processed nil)
148 (should (equal
149 "hello"
150 (progn
237b190 @ahyatt Various whitespace changes
authored
151 (websocket-process-frame
152 websocket
153 (make-websocket-frame :opcode opcode :payload "hello"))
3a7798f @ahyatt Added frame processing, and more of the structure to use it.
authored
154 processed))))
155 (setq sent nil)
156 (flet ((websocket-send (websocket content) (setq sent content)))
157 (should (equal
7bc2aae @ahyatt Make websocket-send work on frames, and use it to send pongs.
authored
158 (make-websocket-frame :opcode 'pong :completep t)
3a7798f @ahyatt Added frame processing, and more of the structure to use it.
authored
159 (progn
160 (websocket-process-frame websocket
161 (make-websocket-frame :opcode 'ping))
162 sent))))
163 (flet ((delete-process (conn) (setq deleted t)))
164 (should (progn
165 (websocket-process-frame websocket
166 (make-websocket-frame :opcode 'close))
167 deleted)))))
2148c5a @ahyatt Create the websocket-to-bytes function, to encode a number in a
authored
168
169 (ert-deftest websocket-to-bytes ()
170 ;; We've tested websocket-get-bytes by itself, now we can use it to
171 ;; help test websocket-to-bytes.
172 (should (equal 30 (websocket-get-bytes (websocket-to-bytes 30 1) 1)))
173 (should (equal 300 (websocket-get-bytes (websocket-to-bytes 300 2) 2)))
174 (should (equal 70000 (websocket-get-bytes (websocket-to-bytes 70000 8) 8)))
175 (should-error (websocket-to-bytes 30 3))
176 (should-error (websocket-to-bytes 300 1)))
177
3596d84 @ahyatt Write and test websocket-encode-frame.
authored
178 (ert-deftest websocket-encode-frame ()
179 ;; We've tested websocket-read-frame, now we can use that to help
180 ;; test websocket-encode-frame.
655cf1e @ahyatt Support outbound masking
authored
181 (let ((websocket-mask-frames nil))
182 (should (equal
183 websocket-test-hello
184 (websocket-encode-frame
185 (make-websocket-frame :opcode 'text :payload "Hello" :completep t))))
237b190 @ahyatt Various whitespace changes
authored
186 (dolist (len '(200 70000))
187 (let ((long-string (make-string len ?x)))
188 (should (equal long-string
189 (websocket-frame-payload
190 (websocket-read-frame
191 (websocket-encode-frame
1081075 @ahyatt More whitespace changes
authored
192 (make-websocket-frame :opcode 'text
193 :payload long-string)))))))))
655cf1e @ahyatt Support outbound masking
authored
194 (let ((websocket-mask-frames t))
195 (flet ((websocket-genbytes (n) (substring websocket-test-masked-hello 2 6)))
237b190 @ahyatt Various whitespace changes
authored
196 (should (equal websocket-test-masked-hello
197 (websocket-encode-frame
1081075 @ahyatt More whitespace changes
authored
198 (make-websocket-frame :opcode 'text :payload "Hello"
199 :completep t))))))
3596d84 @ahyatt Write and test websocket-encode-frame.
authored
200 (should-not
201 (websocket-frame-completep
202 (websocket-read-frame
1081075 @ahyatt More whitespace changes
authored
203 (websocket-encode-frame (make-websocket-frame :opcode 'text
204 :payload "Hello"
205 :completep nil)))))
0e04e15 @ahyatt Fix issue with encoding & decoding non-payload frames, and fix the
authored
206 (dolist (opcode '(close ping pong))
3596d84 @ahyatt Write and test websocket-encode-frame.
authored
207 (should (equal
208 opcode
209 (websocket-frame-opcode
210 (websocket-read-frame
0e04e15 @ahyatt Fix issue with encoding & decoding non-payload frames, and fix the
authored
211 (websocket-encode-frame (make-websocket-frame :opcode opcode
212 :completep t))))))))
3596d84 @ahyatt Write and test websocket-encode-frame.
authored
213
33ff92c @ahyatt Update websocket-close and test
authored
214 (ert-deftest websocket-close ()
215 (let ((sent-frames))
216 (flet ((websocket-send (websocket frame) (push frame sent-frames))
217 (websocket-openp (websocket) t)
218 (kill-buffer (buffer))
219 (process-buffer (conn)))
220 (websocket-close (make-websocket :conn "fake-conn"
221 :filter t
222 :url t
223 :accept-string t
224 :close-callback t))
225 (should (equal sent-frames (list
226 (make-websocket-frame :opcode 'close
227 :completep t)))))))
b89e002 @ahyatt Test for websocket-outer-filter, plus removing some useless code from th...
authored
228
229 (ert-deftest websocket-outer-filter ()
230 (let* ((fake-ws (make-websocket :conn t :filter t :url t
231 :accept-string t :close-callback t))
232 (processed-frames)
233 (frame1 (make-websocket-frame :opcode 'text :payload "foo" :completep t
234 :length 9))
235 (frame2 (make-websocket-frame :opcode 'text :payload "bar" :completep t
236 :length 9))
237 (websocket-frames
238 (concat
239 (websocket-encode-frame frame1)
240 (websocket-encode-frame frame2))))
241 (flet ((websocket-process-frame (websocket frame)
242 (push frame processed-frames))
243 (websocket-verify-handshake (websocket output) t))
244 (websocket-outer-filter fake-ws "Sec-")
245 (websocket-outer-filter fake-ws "WebSocket-Accept: acceptstring")
246 (websocket-outer-filter fake-ws (concat
247 "\r\n\r\n"
248 (substring websocket-frames 0 2)))
249 (should (websocket-header-read-p fake-ws))
250 (websocket-outer-filter fake-ws (substring websocket-frames 2))
251 (should (equal (list frame2 frame1) processed-frames)))))
Something went wrong with that request. Please try again.