Patrick Kelley 8fd444092b initial
2025-05-07 15:35:15 -04:00

298 lines
9.4 KiB
Python

import time
import unittest
import broker
def create_stores(self):
ep0 = broker.Endpoint()
ep1 = broker.Endpoint()
ep2 = broker.Endpoint()
with (
ep0.make_subscriber("/test") as s0, # noqa: F841
ep1.make_subscriber("/test") as s1,
ep1.make_status_subscriber() as es1, # noqa: F841
ep2.make_subscriber("/test") as s2,
ep2.make_status_subscriber() as es2, # noqa: F841
):
p = ep0.listen("127.0.0.1", 0)
ep1.peer("127.0.0.1", p)
ep2.peer("127.0.0.1", p)
# TODO: This doesn't work. Once it does, remove the event handshake.
# es1.get()
# es2.get()
ep0.publish("/test", "go-ahead")
s1.get()
s2.get()
####
m = ep0.attach_master("test", broker.Backend.Memory)
c1 = ep1.attach_clone("test")
c2 = ep2.attach_clone("test")
return (ep0, ep1, ep2, m, c1, c2)
# Runs a test with one master and two clones
# --tri-setup-start
def run_tri_setup(self, f):
with (
broker.Endpoint() as ep0,
broker.Endpoint() as ep1,
broker.Endpoint() as ep2,
ep0.attach_master("test", broker.Backend.Memory) as m,
ep1.attach_clone("test") as c1,
ep2.attach_clone("test") as c2,
):
# connect the nodes
port = ep0.listen("127.0.0.1", 0)
self.assertTrue(ep1.peer("127.0.0.1", port))
self.assertTrue(ep2.peer("127.0.0.1", port))
# wait until the nodes are fully connected
self.assertTrue(ep0.await_peer(ep1.node_id()))
self.assertTrue(ep0.await_peer(ep2.node_id()))
self.assertTrue(ep1.await_peer(ep0.node_id()))
self.assertTrue(ep2.await_peer(ep0.node_id()))
# wait until the clones have connected to the master
self.assertTrue(c1.await_idle())
self.assertTrue(c2.await_idle())
f(m, c1, c2)
# --tri-setup-end
def await_idle(self, *argv):
for store in argv:
self.assertTrue(store.await_idle())
class TestStore(unittest.TestCase):
def test_basic(self):
# --master-start
with (
broker.Endpoint() as ep1,
ep1.attach_master("test", broker.Backend.Memory) as m,
):
m.put("key", "value")
x = m.get("key")
# x == "value"
# --master-end
self.assertEqual(x, "value")
self.assertEqual(m.name(), "test")
def test_from_master(self):
def impl(m, c1, c2):
v1 = "A"
v2 = {"A", "B", "C"}
v3 = {1: "A", 2: "B", 3: "C"}
v4 = ("A", "B", "C")
m.put("a", v1)
m.put("b", v2)
m.put("c", v3)
m.put("d", v4)
self.assertEqual(c2.put_unique("e", "first"), True)
self.assertEqual(c2.put_unique("e", "second"), False)
self.assertEqual(c2.put_unique("e", "third"), False)
time.sleep(0.5)
def checkAccessors(x):
self.assertEqual(x.get("a"), v1)
self.assertEqual(x.get("b"), v2)
self.assertEqual(x.get("c"), v3)
self.assertEqual(x.get("d"), v4)
self.assertEqual(x.get("e"), "first")
self.assertEqual(x.get("X"), None)
self.assertEqual(x.exists("d"), True)
self.assertEqual(x.exists("X"), False)
self.assertEqual(x.get_index_from_value("b", "A"), True)
self.assertEqual(x.get_index_from_value("b", "X"), False)
self.assertEqual(x.get_index_from_value("c", 1), "A")
self.assertEqual(x.get_index_from_value("c", 10), None)
self.assertEqual(x.get_index_from_value("d", 1), "B")
self.assertEqual(x.get_index_from_value("d", 10), None)
self.assertEqual(x.keys(), {"a", "b", "c", "d", "e"})
checkAccessors(m)
checkAccessors(c1)
checkAccessors(c2)
v5 = 5
m.put("e", v5)
m.put("f", v5)
m.put("g", v5, 0.1)
m.put("h", v5, 2)
m.put("str", "b")
m.put("vec", (1, 2))
m.put("set", {1, 2})
m.put("table", {1: "A", "2": "C"})
# --ops-start
m.increment("e", 1)
m.decrement("f", 1)
m.append("str", "ar")
m.insert_into("set", 3)
m.remove_from("set", 1)
m.insert_into("table", 3, "D")
m.remove_from("table", 1)
m.push("vec", 3)
m.push("vec", 4)
m.pop("vec")
# --ops-end
time.sleep(0.15) # Make sure 'g' expires.
await_idle(self, c2, c1, m)
def checkModifiers(x):
self.assertEqual(x.get("e"), v5 + 1)
self.assertEqual(x.get("f"), v5 - 1)
self.assertEqual(x.get("g"), None) # Expired
self.assertEqual(x.get("h"), v5) # Not Expired
self.assertEqual(x.get("str"), "bar")
self.assertEqual(x.get("set"), {2, 3})
self.assertEqual(x.get("table"), {3: "D", "2": "C"})
self.assertEqual(x.get("vec"), (1, 2, 3))
checkModifiers(m)
checkModifiers(c1)
checkModifiers(c2)
m.clear()
await_idle(self, c2, c1, m)
self.assertEqual(m.keys(), set())
self.assertEqual(c1.keys(), set())
self.assertEqual(c2.keys(), set())
run_tri_setup(self, impl)
def test_from_one_clone(self):
with (
broker.Endpoint() as ep0,
broker.Endpoint() as ep1,
ep0.attach_master("test", broker.Backend.Memory) as m,
ep1.attach_clone("test") as c1,
):
port = ep0.listen("127.0.0.1", 0)
self.assertTrue(ep1.peer("127.0.0.1", port))
ep0.await_peer(ep1.node_id())
ep1.await_peer(ep0.node_id())
v1 = "A"
v2 = {"A", "B", "C"}
# TODO: These are untested, should they be?
# v3 = {1: "A", 2: "B", 3: "C"}
# v4 = ("A", "B", "C")
c1.put("a", v1)
c1.put("b", v2)
await_idle(self, c1, m)
self.assertEqual(c1.put_unique("e", "first"), True)
def test_from_two_clones(self):
def impl(m, c1, c2):
v1 = "A"
v2 = {"A", "B", "C"}
v3 = {1: "A", 2: "B", 3: "C"}
v4 = ("A", "B", "C")
c1.put("a", v1)
c1.put("b", v2)
c2.put("c", v3)
c2.put("d", v4)
self.assertEqual(c2.put_unique("e", "first"), True)
self.assertEqual(c2.put_unique("e", "second"), False)
self.assertEqual(c2.put_unique("e", "third"), False)
await_idle(self, c1, c2)
def checkAccessors(x):
self.assertEqual(x.get("a"), v1)
self.assertEqual(x.get("b"), v2)
self.assertEqual(x.get("c"), v3)
self.assertEqual(x.get("d"), v4)
self.assertEqual(x.get("e"), "first")
self.assertEqual(x.get("X"), None)
self.assertEqual(x.exists("d"), True)
self.assertEqual(x.exists("X"), False)
self.assertEqual(x.get_index_from_value("b", "A"), True)
self.assertEqual(x.get_index_from_value("b", "X"), False)
self.assertEqual(x.get_index_from_value("c", 1), "A")
self.assertEqual(x.get_index_from_value("c", 10), None)
self.assertEqual(x.get_index_from_value("d", 1), "B")
self.assertEqual(x.get_index_from_value("d", 10), None)
self.assertEqual(x.keys(), {"a", "b", "c", "d", "e"})
checkAccessors(m)
checkAccessors(c1)
checkAccessors(c2)
v5 = 5
c1.put("e", v5)
c2.put("f", v5)
c1.put("g", v5, 0.1)
c2.put("h", v5, 20)
m.put("str", "b")
m.put("vec", [1, 2])
m.put("set", {1, 2})
m.put("table", {1: "A", "2": "C"})
await_idle(self, c1, c2, m)
c2.increment("e", 1)
c1.decrement("f", 1)
c2.append("str", "ar")
c1.insert_into("set", 3)
c2.remove_from("set", 1)
c1.insert_into("table", 3, "D")
c2.remove_from("table", 1)
c1.push("vec", 3)
await_idle(self, c1, c2, m)
c2.push("vec", 4)
c2.pop("vec")
await_idle(self, c1, c2, m)
def checkModifiers(x):
self.assertEqual(x.get("e"), v5 + 1)
self.assertEqual(x.get("f"), v5 - 1)
self.assertEqual(x.get("g"), None) # Expired
self.assertEqual(x.get("h"), v5) # Not Expired
self.assertEqual(x.get("str"), "bar")
self.assertEqual(x.get("set"), {2, 3})
self.assertEqual(x.get("table"), {3: "D", "2": "C"})
self.assertEqual(x.get("vec"), (1, 2, 3))
checkModifiers(m)
checkModifiers(c1)
checkModifiers(c2)
m.clear()
await_idle(self, c1, c2, m)
self.assertEqual(m.keys(), set())
self.assertEqual(c1.keys(), set())
self.assertEqual(c2.keys(), set())
run_tri_setup(self, impl)
if __name__ == "__main__":
unittest.main(verbosity=3)