Пример #1
0
def test_network_select_init():
    system = "a string represented system state"

    copynet = CopyNet(system)

    assert isinstance(copynet.server, socket.socket)
    assert len(copynet.clientmap) == 0
    assert copynet.queues == {}
    assert copynet.obj == system

    copynet.close()
Пример #2
0
def test_network_select_init_close():
    import select
    system = "a string represented system state"

    copynet = CopyNet(system)

    #no error because socket is open
    select.select([copynet.server], [], [], 0)

    copynet.close()

    assert copynet.running == False

    #must raise error
    with pytest.raises(socket_select_error):
        select.select([copynet.server], [], [], 0)
Пример #3
0
 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
Пример #4
0
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()
Пример #5
0
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()
Пример #6
0
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()
Пример #7
0
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()
Пример #8
0
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()
Пример #9
0
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()