def test_network_select_check_if_authorized_client(): from coopy.base import logging_config logging_config(basedir="./") system = "a string represented system state" copynet = CopyNet(system, host="127.0.0.1", port=7777) copynet.start() actor1 = tcp_actor("127.0.0.1", 7777, "inet") actor1.send(_str_to_bytes('copynet')) #guarantee that the client is already connected import time time.sleep(0.2) copynet_client1 = list(copynet.clientmap.values())[0] actor1.send(_str_to_bytes('copynet')) assert True == copynet.check_if_authorized_client(copynet_client1.client) actor1.close() actor2 = tcp_actor("127.0.0.1", 7777, "inet") actor2.send(_str_to_bytes('copynet')) time.sleep(0.2) copynet_client2 = list(copynet.clientmap.values())[0] actor2.send(_str_to_bytes('_copynet')) assert False == copynet.check_if_authorized_client(copynet_client2.client) actor2.close() copynet.close()
def test_network_select_send_direct(): received_msgs = [] from coopy.base import logging_config logging_config(basedir="./") system = "a string represented system state" copynet = CopyNet(system, host="127.0.0.1", port=7777) copynet.start() actor1 = tcp_actor("127.0.0.1", 7777, "inet") actor1.send(_str_to_bytes('copynet')) actor2 = tcp_actor("127.0.0.1", 7777, "inet") actor2.send(_str_to_bytes('copynet')) actors = [actor1, actor2] #guarantee that the client is already connected import time time.sleep(0.2) copynet_client1 = list(copynet.clientmap.values())[0] copynet.send_direct(copynet_client1.client, _str_to_bytes("message")) time.sleep(0.2) if six.PY3: import pickle else: import cPickle as pickle import struct, zlib, pickle size = struct.calcsize(COPYNET_HEADER) #one of the 2 reads will raise an error and the other will work error_count = 0 for actor in actors: try: header = actor.recv(size) (psize, stype) = struct.unpack(COPYNET_HEADER, header) data = pickle.loads(zlib.decompress(actor.recv(psize))) received_msgs.append(data) except Exception: error_count += 1 assert len(received_msgs) == 1 assert error_count == 1 copynet.close() actor1.close() actor2.close()
def test_network_select_broadcast(): received_msgs = [] from coopy.base import logging_config logging_config(basedir="./") system = "a string represented system state" copynet = CopyNet(system, host="127.0.0.1", port=7777) copynet.start() actor1 = tcp_actor("127.0.0.1", 7777, "inet") actor1.send(_str_to_bytes('copynet')) actor2 = tcp_actor("127.0.0.1", 7777, "inet") actor2.send(_str_to_bytes('copynet')) clients = [actor1, actor2] #guarantee that the client is already connected import time time.sleep(0.2) copynet.receive(b"message") if six.PY3: import pickle else: import cPickle as pickle #both clients should receive the same message for cli in clients: import struct, zlib, pickle size = struct.calcsize(COPYNET_HEADER) header = cli.recv(size) (psize, stype) = struct.unpack(COPYNET_HEADER, header) data = pickle.loads(zlib.decompress(cli.recv(psize))) received_msgs.append(data) assert stype == b's' assert data == b"message" assert len(received_msgs) == 2 assert received_msgs == [b"message", b"message"] copynet.close() actor1.close() actor2.close()
def test_network_select_receive(): from coopy.base import logging_config logging_config(basedir="./") system = "a string represented system state" copynet = CopyNet(system, host="127.0.0.1", port=7777) copynet.start() actor = tcp_actor("127.0.0.1", 7777, "inet") actor.send(b'copynet') #guarantee that the client is already connected import time time.sleep(0.2) copynet.receive(b"message") #if no error, socket is open import select select.select([], [], [actor], 0) import struct, zlib if six.PY3: import pickle else: import cPickle as pickle size = struct.calcsize(COPYNET_HEADER) header = actor.recv(size) (psize, stype) = struct.unpack(COPYNET_HEADER, header) data = pickle.loads(zlib.decompress(actor.recv(psize))) assert stype == b's' assert data == b"message" copynet.close() actor.close()
def test_network_select_disconnect_senders(): from coopy.base import logging_config logging_config(basedir="./") system = "a string represented system state" copynet = CopyNet(system, host="127.0.0.1", port=7777) copynet.start() actor = tcp_actor("127.0.0.1", 7777, "inet") actor.send(_str_to_bytes('copynet')) #guarantee that the client is already connected import time time.sleep(0.2) actor.send(_str_to_bytes('actor should be disconnected')) time.sleep(0.2) assert 0 == len(copynet.clientmap) copynet.close() actor.close()
class CoopyProxy(): def __init__(self, obj, subscribers, snapshot_manager=None): self.obj = obj self.publisher = Publisher(subscribers) self.lock = threading.RLock() self.master = None self.slave = None self.snapshot_manager = snapshot_manager self.snapshot_timer = None def start_snapshot_manager(self, snapshot_time): import time self.snapshot_timer = SnapshotTimer(snapshot_time, self) time.sleep(snapshot_time) self.snapshot_timer.start() def start_master(self, port=8012, password=None, ipc=False): self.server = CopyNet(self.obj, port=port, password=password, ipc=ipc) self.server.start() self.publisher.register(self.server) self.slave = None def start_slave(self, host, port, password=None, ipc=None): self.server = None self.slave = CopyNetSlave(self.obj, self, host=host, password=password, port=port, ipc=ipc) self.slave.start() def __getattr__(self, name): method = method_or_none(self.obj, name) if not method: return getattr(self.obj, name) (readonly,unlocked,abort_exception) = action_check(method) #TODO: re-write if not readonly and hasattr(self, 'slave') and self.slave: raise Exception('This is a slave/read-only instance.') def method(*args, **kwargs): exception = None try: if not unlocked: self.lock.acquire(1) #record all calls to clock.now() self.obj._clock = RecordClock() thread_ident = thread.get_ident() action = Action(thread_ident, name, datetime.now(), args, kwargs) system = None if not readonly: self.publisher.publish_before(action) try: system = action.execute_action(self.obj) except Exception as e: logger.debug(CORE_LOG_PREFIX + 'Error: ' + str(e)) if abort_exception: logger.debug(CORE_LOG_PREFIX + 'Aborting action' + str(action)) if not abort_exception: self.publisher.publish_exception(action) exception = e #restore clock action.results = self.obj._clock.results if not readonly and not abort_exception: self.publisher.publish(action) finally: if not unlocked: self.lock.release() if exception: raise exception return system return method def basedir_abspath(self): disk_journals = (journal for journal in self.publisher.subscribers if hasattr(journal, 'basedir')) return [os.path.join(os.path.abspath(os.getcwd()), journal.basedir) for journal in disk_journals] def take_snapshot(self): if self.slave: self.slave.acquire() self.lock.acquire() if self.snapshot_manager: self.snapshot_manager.take_snapshot(self.obj) self.lock.release() if self.slave: self.slave.release() def close(self): self.publisher.close() logging.shutdown() if self.snapshot_timer: self.snapshot_timer.stop() def shutdown(self): if self.master: self.server.close() if self.slave: self.slave.close()