Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 189 lines (171 sloc) 8.599 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
07050bc @ahyatt Get opening handshake to work correctly. Framing does not yet work,
authored
44 do (should (= (string-bytes (websocket-genbytes)) 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="
50 (websocket-calculate-accept "dGhlIHNhbXBsZSBub25jZQ=="))))
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.")
4c8dbe2 @ahyatt Implement masking and unmasking.
authored
54 (defconst websocket-test-masked-hello
55 "\x81\x85\x37\xfa\x21\x3d\x7f\x9f\x4d\x51\x58"
56 "'Hello' masked string example, taken from the RFC.")
f4e1aa8 @ahyatt Add helper functions for websocket-get-opcode and
authored
57
b948e95 @ahyatt Fixed payload len logic, and rewrote the bit-grabbing bits to just
authored
58 (ert-deftest websocket-get-bytes ()
59 (should (equal #x5 (websocket-get-bytes "\x5" 1)))
60 (should (equal #x101 (websocket-get-bytes "\x1\x1" 2)))
61 (should (equal #x100000001
62 (websocket-get-bytes "\x0\x0\x0\x1\x0\x0\x0\x1" 8)))
63 (should-error (websocket-get-bytes "\x0\x0\x0" 3))
64 (should-error (websocket-get-bytes "\x0" 2)))
65
f4e1aa8 @ahyatt Add helper functions for websocket-get-opcode and
authored
66 (ert-deftest websocket-get-opcode ()
67 (should (equal 'text (websocket-get-opcode websocket-test-hello))))
68
69 (ert-deftest websocket-get-payload-len ()
b948e95 @ahyatt Fixed payload len logic, and rewrote the bit-grabbing bits to just
authored
70 (should (equal '(5 . 1)
71 (websocket-get-payload-len
72 (substring websocket-test-hello 1))))
f4e1aa8 @ahyatt Add helper functions for websocket-get-opcode and
authored
73 (should (equal '(200 . 3)
74 (websocket-get-payload-len
b948e95 @ahyatt Fixed payload len logic, and rewrote the bit-grabbing bits to just
authored
75 (bindat-pack '((:len u8) (:val u16))
76 `((:len . 126)
f4e1aa8 @ahyatt Add helper functions for websocket-get-opcode and
authored
77 (:val . 200))))))
78 ;; we don't want to hit up any limits even on strange emacs builds,
79 ;; so this test has a pretty small test value
80 (should (equal '(70000 . 9)
81 (websocket-get-payload-len
b948e95 @ahyatt Fixed payload len logic, and rewrote the bit-grabbing bits to just
authored
82 (bindat-pack '((:len u8) (:val vec 2 u32))
83 `((:len . 127)
f4e1aa8 @ahyatt Add helper functions for websocket-get-opcode and
authored
84 (:val . [0 70000])))))))
ae51a78 @ahyatt Code to read a frame. Does not yet support masking.
authored
85
86 (ert-deftest websocket-read-frame ()
7900cda @ahyatt Return the length of the websocket frame from websocket-read-frame.
authored
87 (should (equal (make-websocket-frame :opcode 'text :payload "Hello"
b0a2970 @ahyatt Add completep in frame
authored
88 :length (length websocket-test-hello)
89 :completep t)
4c8dbe2 @ahyatt Implement masking and unmasking.
authored
90 (websocket-read-frame websocket-test-hello)))
7900cda @ahyatt Return the length of the websocket frame from websocket-read-frame.
authored
91 (should (equal (make-websocket-frame :opcode 'text :payload "Hello"
b0a2970 @ahyatt Add completep in frame
authored
92 :length (length websocket-test-hello)
93 :completep t)
7900cda @ahyatt Return the length of the websocket frame from websocket-read-frame.
authored
94 (websocket-read-frame (concat websocket-test-hello
95 "should-not-be-read"))))
96 (should (equal (make-websocket-frame :opcode 'text :payload "Hello"
b0a2970 @ahyatt Add completep in frame
authored
97 :length (length websocket-test-masked-hello)
98 :completep t)
51b5764 @ahyatt Ensure the websocket frame is complete, and return NIL if not.
authored
99 (websocket-read-frame websocket-test-masked-hello)))
b0a2970 @ahyatt Add completep in frame
authored
100 (should (equal (make-websocket-frame :opcode 'text :payload "Hello"
101 :length (length websocket-test-hello)
102 :completep nil)
103 (websocket-read-frame (concat (unibyte-string
104 (logand (string-to-char
105 (substring websocket-test-hello 0 1))
106 127))
107 (substring websocket-test-hello 1)))))
51b5764 @ahyatt Ensure the websocket frame is complete, and return NIL if not.
authored
108 (dotimes (i (- (length websocket-test-hello) 1))
109 (should-not (websocket-read-frame
110 (substring websocket-test-hello 0
111 (- (length websocket-test-hello) (+ i 1))))))
112 (dotimes (i (- (length websocket-test-masked-hello) 1))
113 (should-not (websocket-read-frame
114 (substring websocket-test-masked-hello 0
115 (- (length websocket-test-masked-hello) (+ i 1)))))))
8da9119 @ahyatt Separate out the handshake verification logic, and test it. Look for
authored
116
117 (defun websocket-test-make-websocket-with-accept-string (s)
3a7798f @ahyatt Added frame processing, and more of the structure to use it.
authored
118 (make-websocket :conn "fake-conn" :url "ws://foo/bar" :filter t :close-callback t
8da9119 @ahyatt Separate out the handshake verification logic, and test it. Look for
authored
119 :accept-string s))
120
121 (ert-deftest websocket-verify-handshake ()
122 ;; This examples comes from the RFC
123 (should (websocket-verify-handshake
124 (websocket-test-make-websocket-with-accept-string "s3pPLMBiTxaQ9kYGzzhZRbK+xOo=")
125 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"))
126 (should-error (websocket-verify-handshake
127 (websocket-test-make-websocket-with-accept-string "s3pPLMBiTxaQ9kYGzzhZRbK+xOo=")
128 "Sec-WebSocket-Accept: foo\r\n")))
3a7798f @ahyatt Added frame processing, and more of the structure to use it.
authored
129
130 (ert-deftest websocket-process-frame ()
131 (let* ((sent)
132 (processed)
133 (deleted)
134 (websocket (make-websocket :conn "fake-conn"
135 :url "ws://foo/bar"
136 :filter (lambda (frame) (setq processed
137 (websocket-frame-payload frame)))
138 :close-callback t
139 :accept-string "accept-string")))
140 (dolist (opcode '(text binary continuation))
141 (setq processed nil)
142 (should (equal
143 "hello"
144 (progn
145 (websocket-process-frame websocket
146 (make-websocket-frame :opcode opcode :payload "hello"))
147 processed))))
148 (setq sent nil)
149 (flet ((websocket-send (websocket content) (setq sent content)))
150 (should (equal
7bc2aae @ahyatt Make websocket-send work on frames, and use it to send pongs.
authored
151 (make-websocket-frame :opcode 'pong :completep t)
3a7798f @ahyatt Added frame processing, and more of the structure to use it.
authored
152 (progn
153 (websocket-process-frame websocket
154 (make-websocket-frame :opcode 'ping))
155 sent))))
156 (flet ((delete-process (conn) (setq deleted t)))
157 (should (progn
158 (websocket-process-frame websocket
159 (make-websocket-frame :opcode 'close))
160 deleted)))))
2148c5a @ahyatt Create the websocket-to-bytes function, to encode a number in a
authored
161
162 (ert-deftest websocket-to-bytes ()
163 ;; We've tested websocket-get-bytes by itself, now we can use it to
164 ;; help test websocket-to-bytes.
165 (should (equal 30 (websocket-get-bytes (websocket-to-bytes 30 1) 1)))
166 (should (equal 300 (websocket-get-bytes (websocket-to-bytes 300 2) 2)))
167 (should (equal 70000 (websocket-get-bytes (websocket-to-bytes 70000 8) 8)))
168 (should-error (websocket-to-bytes 30 3))
169 (should-error (websocket-to-bytes 300 1)))
170
3596d84 @ahyatt Write and test websocket-encode-frame.
authored
171 (ert-deftest websocket-encode-frame ()
172 ;; We've tested websocket-read-frame, now we can use that to help
173 ;; test websocket-encode-frame.
174 (should (equal
175 websocket-test-hello
176 (websocket-encode-frame
177 (make-websocket-frame :opcode 'text :payload "Hello" :completep t))))
178 (should-not
179 (websocket-frame-completep
180 (websocket-read-frame
181 (websocket-encode-frame (make-websocket-frame :opcode 'text :payload "Hello" :completep nil)))))
182 (dolist ((opcode '(close ping pong)))
183 (should (equal
184 opcode
185 (websocket-frame-opcode
186 (websocket-read-frame
187 (websocket-encode-frame (make-websocket-frame :opcode opcode))))))))
188
Something went wrong with that request. Please try again.