~azzar1/unity/add-show-desktop-key

1637 by William Grant
Add ivle.tests, move ivle.test_chat into there, and be slightly more idiomatic.
1
# IVLE - Informatics Virtual Learning Environment
2
# Copyright (C) 2007-2010 The University of Melbourne
3
#
4
# This program is free software; you can redistribute it and/or modify
5
# it under the terms of the GNU General Public License as published by
6
# the Free Software Foundation; either version 2 of the License, or
7
# (at your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
#
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17
18
import socket
1651 by David Coles
A few more tests for chat. Testing the chat and start_server functions will likey require a little bit of refactoring.
19
import os
20
import random
1637 by William Grant
Add ivle.tests, move ivle.test_chat into there, and be slightly more idiomatic.
21
1697 by David Coles
chat: Factor out the encoding and decoding functions so we can test them and possibly reuse elsewhere
22
import cjson
1636 by David Coles
Testcase for chat protocol
23
from nose.tools import assert_equal, raises
24
1637 by William Grant
Add ivle.tests, move ivle.test_chat into there, and be slightly more idiomatic.
25
import ivle.chat
26
1636 by David Coles
Testcase for chat protocol
27
28
TIMEOUT = 0.1
29
NULLNETSTRING = "0:,"
30
SIMPLESTRING = "Hello world!"
31
SIMPLENETSTRING = "12:Hello world!,"
32
1637 by William Grant
Add ivle.tests, move ivle.test_chat into there, and be slightly more idiomatic.
33
34
class TestChat(object):
35
    def setUp(self):
1636 by David Coles
Testcase for chat protocol
36
        """Creates a socket pair for testing"""
37
        self.s1, self.s2 = socket.socketpair()
38
        self.s1.settimeout(TIMEOUT)
39
        self.s2.settimeout(TIMEOUT)
40
1637 by William Grant
Add ivle.tests, move ivle.test_chat into there, and be slightly more idiomatic.
41
    def tearDown(self):
1636 by David Coles
Testcase for chat protocol
42
        """Closes the socket pair"""
43
        self.s1.close()
44
        self.s2.close()
45
46
    def test_send_null_netstring(self):
47
        """Check that we construct a empty Netstring correctly"""
1637 by William Grant
Add ivle.tests, move ivle.test_chat into there, and be slightly more idiomatic.
48
        ivle.chat.send_netstring(self.s1, "")
1636 by David Coles
Testcase for chat protocol
49
        assert_equal(self.s2.recv(1024), NULLNETSTRING)
50
51
    def test_send_simple_netstring(self):
52
        """Check that we construct a simple Netstring correctly"""
1637 by William Grant
Add ivle.tests, move ivle.test_chat into there, and be slightly more idiomatic.
53
        ivle.chat.send_netstring(self.s1, SIMPLESTRING)
1636 by David Coles
Testcase for chat protocol
54
        assert_equal(self.s2.recv(1024), SIMPLENETSTRING)
55
56
    def test_recv_null_netstring(self):
57
        """Check that we can decode a null Netstring"""
58
        self.s1.sendall(NULLNETSTRING)
1637 by William Grant
Add ivle.tests, move ivle.test_chat into there, and be slightly more idiomatic.
59
        assert_equal(ivle.chat.recv_netstring(self.s2), "")
1636 by David Coles
Testcase for chat protocol
60
61
    def test_recv_null_netstring(self):
62
        """Check that we can decode a simple Netstring"""
63
        self.s1.sendall(SIMPLENETSTRING)
1637 by William Grant
Add ivle.tests, move ivle.test_chat into there, and be slightly more idiomatic.
64
        assert_equal(ivle.chat.recv_netstring(self.s2), SIMPLESTRING)
1636 by David Coles
Testcase for chat protocol
65
66
    @raises(socket.timeout)
1651 by David Coles
A few more tests for chat. Testing the chat and start_server functions will likey require a little bit of refactoring.
67
    def test_invalid_short_netstring(self):
1636 by David Coles
Testcase for chat protocol
68
        self.s1.sendall("1234:not that long!,")
1637 by William Grant
Add ivle.tests, move ivle.test_chat into there, and be slightly more idiomatic.
69
        assert ivle.chat.recv_netstring(self.s2) is None
1636 by David Coles
Testcase for chat protocol
70
1637 by William Grant
Add ivle.tests, move ivle.test_chat into there, and be slightly more idiomatic.
71
    @raises(ivle.chat.ProtocolError)
1651 by David Coles
A few more tests for chat. Testing the chat and start_server functions will likey require a little bit of refactoring.
72
    def test_invalid_long_netstring(self):
73
        self.s1.sendall("5:not that short!,")
74
        assert ivle.chat.recv_netstring(self.s2) is None
75
1636 by David Coles
Testcase for chat protocol
76
    def test_long_netstring(self):
1651 by David Coles
A few more tests for chat. Testing the chat and start_server functions will likey require a little bit of refactoring.
77
        # XXX: send() may block if this is too big
78
        msg = os.urandom(50000)
79
        ivle.chat.send_netstring(self.s1, msg)
80
        assert ivle.chat.recv_netstring(self.s2) == msg
81
82
    def test_multiple_netstrings(self):
83
        messages = []
84
        for i in range(10):
85
            message = os.urandom(random.randint(0,20))
86
            messages.append(message)
87
            ivle.chat.send_netstring(self.s1, message)
88
        for i in range(10):
89
            assert_equal(ivle.chat.recv_netstring(self.s2), messages[i])
1636 by David Coles
Testcase for chat protocol
90
1697 by David Coles
chat: Factor out the encoding and decoding functions so we can test them and possibly reuse elsewhere
91
    def test_encode(self):
92
        """Check that we correctly encode a basic object
93
        """
94
        MESSAGE = {}
95
        MAGIC = "3EE"
96
        content = cjson.encode(MESSAGE)
97
        # Digest can be formed with `echo -n "${content}${MAGIC}" | md5sum`
98
        DIGEST = '2b59b68e1ac0852b87fb7e64946f2658'
99
        expected = {'digest': DIGEST,
100
                'content': content}
101
        encoded = ivle.chat.encode(MESSAGE, MAGIC)
102
        assert_equal(cjson.decode(encoded), expected)
103
104
    def test_encode_decode(self):
105
        """Check that a round trip encoding and decoding works
106
        """
107
        MESSAGE = {'message': 'Hello, world'}
108
        MAGIC = "MagicString"
109
        encoded = ivle.chat.encode(MESSAGE, MAGIC)
110
        decoded = ivle.chat.decode(encoded, MAGIC)
111
        assert_equal(decoded, MESSAGE)
112
113
    @raises(ivle.chat.ProtocolError)
114
    def test_decode_bad_magic(self):
115
        """Check that a bad digest causes a ProtocolError to be raised
116
        """
117
        CHATMESSAGE = ('{"content": "{\\"a\\": \\"b\\"}", "digest": ' +
118
                '"eb860a5fe8fdbef19ffb79e3a5c47113"}')
119
        CORRECTMAGIC = "AEIOU"
120
        INCORRECTMAGIC = "ABCDE"
121
122
        # Check our "correct" string decodes without a ProtocolError
123
        try:
124
            ivle.chat.decode(CHATMESSAGE, CORRECTMAGIC)
125
        except ivle.chat.ProtocolError:
126
            raise AssertionError("ProtocolError with 'correct' magic")
127
128
        # This should raise the ProtocolError
129
        ivle.chat.decode(CHATMESSAGE, INCORRECTMAGIC)