217 lines
7.6 KiB
Python
217 lines
7.6 KiB
Python
# /****************************************************************************
|
|
# * <Novell-copyright>
|
|
# * Copyright (c) 2001 Novell, Inc. All Rights Reserved.
|
|
# *
|
|
# * This program is free software; you can redistribute it and/or
|
|
# * modify it under the terms of version 2 of the GNU General Public License
|
|
# * as published by the Free Software Foundation.
|
|
# *
|
|
# * This program is distributed in the hope that it will be useful,
|
|
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# * GNU General Public License for more details.
|
|
# *
|
|
# * You should have received a copy of the GNU General Public License
|
|
# * along with this program; if not, contact Novell, Inc.
|
|
# *
|
|
# * To contact Novell about this file by physical or electronic mail, you
|
|
# * may find current contact information at www.novell.com.
|
|
# * </Novell-copyright>
|
|
# ****************************************************************************/
|
|
|
|
import unittest
|
|
|
|
from bongo.store.QueueClient import QueueClient
|
|
|
|
|
|
class Response:
|
|
def __init__(self, code, message):
|
|
self.code = code
|
|
self.message = message
|
|
|
|
|
|
class Stream:
|
|
def __init__(self, responses, data):
|
|
self.responses = iter(responses)
|
|
self.data = data
|
|
self.commands = []
|
|
self.lengths = []
|
|
|
|
def Write(self, command):
|
|
self.commands.append(command)
|
|
|
|
def GetResponse(self):
|
|
return next(self.responses)
|
|
|
|
def Read(self, length):
|
|
self.lengths.append(length)
|
|
return self.data
|
|
|
|
|
|
class QueueClientTests(unittest.TestCase):
|
|
def test_diskspace_preserves_64_bit_value(self):
|
|
client = QueueClient.__new__(QueueClient)
|
|
client.stream = Stream(
|
|
[Response(1000, "17174626304 bytes free")], b"")
|
|
|
|
self.assertEqual(client.Diskspace(), 17174626304)
|
|
self.assertEqual(client.stream.commands, ["QDSPC"])
|
|
|
|
def test_create_with_isolated_target(self):
|
|
client = QueueClient.__new__(QueueClient)
|
|
client.stream = Stream([Response(1000, "Entry made")], b"")
|
|
|
|
client.Create(999)
|
|
|
|
self.assertEqual(client.stream.commands, ["QCREA 999"])
|
|
|
|
def test_create_rejects_invalid_target(self):
|
|
client = QueueClient.__new__(QueueClient)
|
|
client.stream = Stream([], b"")
|
|
|
|
with self.assertRaisesRegex(ValueError, "between 0 and 999"):
|
|
client.Create(1000)
|
|
|
|
def test_count_collected_returns_global_and_user_counts(self):
|
|
client = QueueClient.__new__(QueueClient)
|
|
client.stream = Stream(
|
|
[Response(1000, "47 12 Collected queue counts")], b"")
|
|
|
|
self.assertEqual(client.CountCollected("test1"), (47, 12))
|
|
self.assertEqual(
|
|
client.stream.commands, ["QCOUNT COLLECTED test1"])
|
|
|
|
def test_count_collected_rejects_user_injection(self):
|
|
client = QueueClient.__new__(QueueClient)
|
|
client.stream = Stream([], b"")
|
|
|
|
with self.assertRaisesRegex(ValueError, "invalid queue user"):
|
|
client.CountCollected("test1\r\nQDELE 007-deadbee")
|
|
|
|
def test_retrieve_message_reads_declared_payload(self):
|
|
client = QueueClient.__new__(QueueClient)
|
|
client.stream = Stream(
|
|
[Response(2023, "7 Message follows"), Response(1000, "OK")],
|
|
b"a\0b\r\n\xff",
|
|
)
|
|
|
|
self.assertEqual(client.RetrieveMessage("999-deadbee"), b"a\0b\r\n\xff")
|
|
self.assertEqual(client.stream.commands, ["QRETR 999-deadbee MESSAGE"])
|
|
self.assertEqual(client.stream.lengths, [7])
|
|
|
|
def test_retrieve_message_rejects_malformed_size(self):
|
|
client = QueueClient.__new__(QueueClient)
|
|
client.stream = Stream([Response(2023, "bad Message follows")], b"")
|
|
|
|
with self.assertRaisesRegex(Exception, "Malformed queue message"):
|
|
client.RetrieveMessage("999-deadbee")
|
|
|
|
def test_deliver_to_mailbox_uses_qaddm(self):
|
|
client = QueueClient.__new__(QueueClient)
|
|
client.stream = Stream([Response(1000, "OK")], b"")
|
|
|
|
client.DeliverToMailbox(
|
|
"999-deadbee", "sender@example.test", "-",
|
|
"recipient", "mail/INBOX", 3)
|
|
|
|
self.assertEqual(
|
|
client.stream.commands,
|
|
["QADDM 999-deadbee sender@example.test - recipient mail/INBOX 3"],
|
|
)
|
|
|
|
def test_store_flags_uses_qstor_flags(self):
|
|
client = QueueClient.__new__(QueueClient)
|
|
client.stream = Stream([Response(1000, "OK")], b"")
|
|
|
|
client.StoreFlags(32932)
|
|
|
|
self.assertEqual(client.stream.commands, ["QSTOR FLAGS 32932"])
|
|
|
|
def test_store_mailbox_uses_validated_raw_envelope(self):
|
|
client = QueueClient.__new__(QueueClient)
|
|
client.stream = Stream([Response(1000, "OK")], b"")
|
|
|
|
client.StoreMailbox("test1", "test1", 32, "Collected Mail", 0)
|
|
|
|
self.assertEqual(
|
|
client.stream.commands,
|
|
["QSTOR RAW Mtest1 test1 32 Collected Mail 0"],
|
|
)
|
|
|
|
def test_store_mailbox_rejects_line_injection(self):
|
|
client = QueueClient.__new__(QueueClient)
|
|
client.stream = Stream([], b"")
|
|
|
|
with self.assertRaisesRegex(ValueError, "invalid queue mailbox"):
|
|
client.StoreMailbox("test1", "test1", 32, "INBOX\r\nQSTOR TO x")
|
|
|
|
def test_delete_uses_qdele(self):
|
|
client = QueueClient.__new__(QueueClient)
|
|
client.stream = Stream([Response(1000, "OK")], b"")
|
|
|
|
client.Delete("999-deadbee")
|
|
|
|
self.assertEqual(client.stream.commands, ["QDELE 999-deadbee"])
|
|
|
|
def test_list_reads_declared_payload(self):
|
|
data = b"007-deadbee 42\r\n999-cafebad 81\r\n"
|
|
client = QueueClient.__new__(QueueClient)
|
|
client.stream = Stream(
|
|
[Response(2024, f"{len(data)} Queue list follows"),
|
|
Response(1000, "OK")],
|
|
data,
|
|
)
|
|
|
|
self.assertEqual(
|
|
client.List(),
|
|
[("007-deadbee", 42), ("999-cafebad", 81)],
|
|
)
|
|
self.assertEqual(client.stream.commands, ["QLIST"])
|
|
self.assertEqual(client.stream.lengths, [len(data)])
|
|
|
|
def test_move_uses_qmove(self):
|
|
client = QueueClient.__new__(QueueClient)
|
|
client.stream = Stream([Response(1000, "999-deadbee OK")], b"")
|
|
|
|
client.Move("007-deadbee", 999)
|
|
|
|
self.assertEqual(client.stream.commands, ["QMOVE 007-deadbee 999"])
|
|
|
|
def test_expire_uses_qexpire(self):
|
|
client = QueueClient.__new__(QueueClient)
|
|
client.stream = Stream([Response(1000, "008-deadbee OK")], b"")
|
|
|
|
client.Expire("007-deadbee")
|
|
|
|
self.assertEqual(client.stream.commands, ["QEXPIRE 007-deadbee"])
|
|
|
|
def test_run_accepts_existing_queue_id(self):
|
|
client = QueueClient.__new__(QueueClient)
|
|
client.stream = Stream([Response(1000, "000-deadbee OK")], b"")
|
|
|
|
client.Run("000-deadbee")
|
|
|
|
self.assertEqual(client.stream.commands, ["QRUN 000-deadbee"])
|
|
|
|
def test_retrieve_info_reads_declared_payload(self):
|
|
client = QueueClient.__new__(QueueClient)
|
|
client.stream = Stream(
|
|
[Response(2022, "14 Info follows"), Response(1000, "OK")],
|
|
b"Mtest test 0\r\n",
|
|
)
|
|
|
|
self.assertEqual(client.RetrieveInfo("007-deadbee"), b"Mtest test 0\r\n")
|
|
self.assertEqual(client.stream.commands, ["QRETR 007-deadbee INFO"])
|
|
self.assertEqual(client.stream.lengths, [14])
|
|
|
|
def test_retrieve_info_rejects_malformed_size(self):
|
|
client = QueueClient.__new__(QueueClient)
|
|
client.stream = Stream([Response(2022, "bad Info follows")], b"")
|
|
|
|
with self.assertRaisesRegex(Exception, "Malformed queue information"):
|
|
client.RetrieveInfo("007-deadbee")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|