示例#1
0
    def test_default_state():

        fake_request(10.0)

        assert pmnc.state.get("") is None
        assert pmnc.state.get("", "default") == "default"

        pmnc.state.set("", None)
        assert pmnc.state.get("") is None
        assert pmnc.state.get("", "default") is None

        pmnc.state.delete("")
        assert pmnc.state.get("", "default") == "default"

        # and now for str/bytes support

        pmnc.state.set(rus, rus + rus)
        assert pmnc.state.get(rus) == rus + rus
        pmnc.state.delete(rus)

        with expected(InputParameterError):
            pmnc.state.set(rus_b, rus)

        with expected(InputParameterError):
            pmnc.state.get(rus_b)

        with expected(InputParameterError):
            pmnc.state.delete(rus_b)

        pmnc.state.set(rus, rus_b)
        assert pmnc.state.get(rus) == rus_b
        pmnc.state.delete(rus)
示例#2
0
 def caller(*args, **kwargs):
     fake_request(6.0)
     nonlocal request_id, response
     request_id = pmnc.request.unique_id
     pmnc.request.parameters["AAA"] = "BBB"
     pmnc.request.describe("my request")
     response = pmnc.__getattr__(__name__).execute_reverse("good_cage", "module", "method", args, kwargs)
示例#3
0
    def test_module_state():

        fake_request(10.0)

        module_state_dir = _module_state_dir("foo")

        module_state = ModuleState(module_state_dir)
        try:

            # note that the first access to a queue or a database creates it,
            # therefore options such as re_len are required, but subsequent
            # accesses just open it and the options can be omitted

            assert not os_path.exists(os_path.join(module_state_dir, "state.queue"))
            queue = module_state.get_queue_db("state", re_len=100)
            assert os_path.exists(os_path.join(module_state_dir, "state.queue"))
            stat = queue.stat()
            assert "buckets" not in stat
            queue.append("foo")
            assert module_state.get_queue_db("state") is queue
            assert module_state.get_queue_db("state2") is not queue

            assert not os_path.exists(os_path.join(module_state_dir, "state.btree"))
            btree = module_state.get_btree_db("state")
            assert os_path.exists(os_path.join(module_state_dir, "state.btree"))
            stat = btree.stat()
            assert "buckets" not in stat
            with expected(bsddb.DBInvalidArgError):
                btree.append("foo")
            assert module_state.get_btree_db("state") is btree
            assert module_state.get_btree_db("state2") is not btree

        finally:
            module_state.close()
示例#4
0
    def test_connect_fails():

        # connect fails

        fake_request(1.0)

        xa = pmnc.transaction.create()
        xa.callable_2(**hooks_).execute()
        try:
            xa.execute()
        except ResourceError as e:
            assert by_regex("^(?:int )?division (?:or modulo )?by zero$")(str(e))
            assert e.participant_index == 0 and e.terminal and e.recoverable
        else:
            assert False

        # connect hangs

        fake_request(1.0)

        xa = pmnc.transaction.create()
        xa.callable_3(**hooks_).execute()
        try:
            xa.execute()
        except TransactionExecutionError as e:
            assert str(e) == "request deadline waiting for intermediate result from " \
                             "resource callable_3 in transaction {0:s}".format(xa)
            assert e.participant_index == 0
        else:
            assert False
示例#5
0
    def test_execute_success():

        fake_request(10.0)

        request_id = None
        response = None

        def caller(*args, **kwargs):
            fake_request(6.0)
            nonlocal request_id, response
            request_id = pmnc.request.unique_id
            pmnc.request.parameters["AAA"] = "BBB"
            pmnc.request.describe("my request")
            response = pmnc.__getattr__(__name__).execute_reverse("good_cage", "module", "method", args, kwargs)

        assert "good_cage" not in _rq_queues

        th = HeavyThread(target = caller, args = (1, "foo"), kwargs = { "biz": "baz" })
        th.start()
        try:

            sleep(2.0)

            assert "good_cage" in _rq_queues
            assert request_id in _rs_queues

            req_id, req = _rq_queues["good_cage"].pop()

            assert req_id == request_id
            assert abs(req["request"].pop("deadline") - time() - 4.0) < 1.0

            assert req == dict \
            (
                source_cage = __cage__,
                target_cage = "good_cage",
                module = "module",
                method = "method",
                args = (1, "foo"),
                kwargs = { "biz": "baz" },
                request = dict(protocol = pmnc.request.protocol,
                               interface = pmnc.request.interface,
                               unique_id = request_id,
                               description = "my request",
                               parameters = dict(auth_tokens = {}, AAA = "BBB")),
            )

            _rs_queues[request_id].push({ "result": "RESULT" })

            sleep(2.0)

            assert "good_cage" in _rq_queues
            assert request_id not in _rs_queues

        finally:
            th.stop()

        assert response == "RESULT"

        assert "good_cage" in _rq_queues
        assert request_id not in _rs_queues
示例#6
0
    def test_failure():

        def process_revrpc_request(module, method, args, kwargs):
            1 / 0

        with active_interface("revrpc", **interface_config(process_revrpc_request = process_revrpc_request)):

            fake_request(3.0)

            request_dict = pmnc.request.to_dict()

            request = dict(source_cage = "source_cage",
                           target_cage = __cage__,
                           module = "module",
                           method = "method",
                           args = (),
                           kwargs = {},
                           request = request_dict)

            poll_queue.push(request)
            request_id, response = post_queue.pop(3.0)
            assert request_id == pmnc.request.unique_id

            error = response.pop("exception")
            assert not response
            assert error.startswith("ZeroDivisionError(")
示例#7
0
    def test_success():

        fake_request(10.0)

        def execute(resource, *args, **kwargs):
            resource._count += 1
            resource._q.push(("execute", resource._count, args, kwargs))
            return "ok"

        # success sequence: connect, begin_transaction, execute, commit (then the instance is put back to the pool)

        xa = pmnc.transaction.create(biz = "baz")
        xa.callable_1("abc", begin_transaction = begin_transaction, execute = execute,
                      commit = commit, rollback = rollback, foo = "bar").execute(1, 2, eee = "fff")
        assert xa.execute() == ("ok", )

        # now check the trace

        assert q.pop(0.0) == ("connect", 0, { "param1": "value1", "param2": "value2" })
        m, c, args, kwargs = q.pop(0.0)
        assert m == "begin_transaction" and c == 1
        assert args == (xa._xid, )
        assert kwargs == dict(transaction_options = { "biz": "baz" }, source_module_name = __name__,
                              resource_args = ("abc", ), resource_kwargs = { "foo": "bar" })
        assert q.pop(0.0) == ("execute", 2, (1, 2), { "eee": "fff" })
        assert q.pop(0.0) == ("commit", 3) # commit is waited upon, therefore "commit" is in the queue
        assert q.pop(1.0) is None
示例#8
0
    def _poller_proc(self, source_cage):

        while not current_thread().stopped():
            try:

                # attach a new fake request to this thread so that
                # network access in RPC call times out properly

                fake_request(timeout = self._request_timeout, interface = self._name)
                pmnc.request.describe("polling cage {0:s}".format(source_cage))

                # fetch a request from the remote cage
                # and extract the call information from it

                try:
                    revrpc_request = self._poll(source_cage)
                except:
                    pmnc.log.error(exc_string())                    # failure to fetch a request
                    current_thread().stopped(self._request_timeout) # results in idle delay
                    continue

                if revrpc_request is None:
                    continue
                elif current_thread().stopped():
                    break

                assert revrpc_request.pop("target_cage") == __cage__, "expected call to this cage"
                assert revrpc_request.pop("source_cage") == source_cage, "expected call from {0:s}".format(source_cage)

                self._process_request(source_cage, revrpc_request)

            except:
                pmnc.log.error(exc_string())
示例#9
0
    def test_failure():

        fake_request(10.0)

        def execute(resource, *args, **kwargs):
            1 / 0

        # failure sequence (the instance is reused): begin_transaction, execute, rollback, disconnect

        xa = pmnc.transaction.create(biz = "baz")
        xa.callable_1("abc", begin_transaction = begin_transaction, execute = execute,
                      commit = commit, rollback = rollback, foo = "bar").execute(1, 2, eee = "fff")
        try:
            xa.execute()
        except ResourceError as e:
            assert by_regex("^(?:int )?division (?:or modulo )?by zero$")(str(e))
            assert not e.recoverable and e.terminal
        else:
            assert False

        # now check the trace

        m, c, args, kwargs = q.pop(0.0)
        assert m == "begin_transaction" and c == 4
        assert args == (xa._xid, )
        assert kwargs == dict(transaction_options = { "biz": "baz" }, source_module_name = __name__,
                              resource_args = ("abc", ), resource_kwargs = { "foo": "bar" })
        assert q.pop(1.0) == ("rollback", 5) # rollback is not waited upon, therefore "rollback" may not appear in the queue immediately
        assert q.pop(1.0) == ("disconnect", 6)
        assert q.pop(1.0) is None
示例#10
0
    def test_get_set_delete():

        fake_request(10.0)

        xa = pmnc.transaction.create()
        xa.state.get("key")
        assert xa.execute() == (None,)

        xa = pmnc.transaction.create()
        xa.state.get("key", "default")
        assert xa.execute() == ("default",)

        xa = pmnc.transaction.create()
        xa.state.set("key", "value")
        assert xa.execute() == (None,)

        xa = pmnc.transaction.create()
        xa.state.get("key")
        assert xa.execute() == ("value",)

        xa = pmnc.transaction.create()
        xa.state.get("key", "default")
        assert xa.execute() == ("value",)

        xa = pmnc.transaction.create()
        xa.state.delete("key")
        assert xa.execute() == (None,)

        xa = pmnc.transaction.create()
        xa.state.get("key")
        assert xa.execute() == (None,)

        xa = pmnc.transaction.create()
        xa.state.get("key", "default")
        assert xa.execute() == ("default",)
示例#11
0
    def test_bytes_str():

        fake_request(5.0)

        xa = pmnc.transaction.create()
        xa.state.set(rus, rus + rus)
        assert xa.execute() == (None,)

        xa = pmnc.transaction.create()
        xa.state.get(rus)
        assert xa.execute() == (rus + rus,)

        xa = pmnc.transaction.create()
        xa.state.delete(rus)
        assert xa.execute() == (None,)

        xa = pmnc.transaction.create()
        xa.state.get(rus_b)
        with expected(ResourceInputParameterError):
            xa.execute()

        xa = pmnc.transaction.create()
        xa.state.set(rus_b, "value")
        with expected(ResourceInputParameterError):
            xa.execute()

        xa = pmnc.transaction.create()
        xa.state.delete(rus_b)
        with expected(ResourceInputParameterError):
            xa.execute()
示例#12
0
    def test_queue_extent_reuse():

        fake_request(10.0)

        def current_extents():
            return sorted(
                [
                    int(s.split(".")[-1])
                    for s in listdir(_module_state_dir(__name__))
                    if by_regex("^.*\\.ext_queue\\.queue\\.[0-9]+$")(s)
                ]
            )

        q = pmnc.state.get_queue("ext_queue", pagesize=8192, re_len=1024, q_extentsize=2)

        v = 0
        for i in range(64):  # fill up more than one extent
            push(q, v)
            v += 1

        extents_before = current_extents()
        assert len(extents_before) > 1

        w = 0
        t = Timeout(5.0)
        while not t.expired:  # keep popping and pushing to have the extents reused
            push(q, v)
            v += 1
            assert pop(q) == w
            w += 1

        extents_after = current_extents()
        assert extents_before[0] < extents_after[0]
示例#13
0
    def test_partial_commit():

        def accept_anything(xa, results):
            for value in results:
                if value is not xa.NoValue:
                    return value

        fake_request(2.0)

        xa = pmnc.transaction.create(accept = accept_anything)
        xa.callable_1(execute = lambda self: 1).execute()
        xa.callable_1(execute = lambda self: 1 / 0).execute()
        try:
            xa.execute()
        except TransactionCommitError as e:
            assert str(e) == "transaction {0:s} got unexpected commit outcome " \
                             "from resource callable_1: rollback".format(xa)
            assert e.participant_index == 1
        else:
            assert False

        fake_request(2.0)

        xa = pmnc.transaction.create(accept = accept_anything, sync_commit = False)
        xa.callable_1(execute = lambda self: 1).execute()
        xa.callable_1(execute = lambda self: 1 / 0).execute()
        xa.execute()
示例#14
0
def self_test():

    from pmnc.request import fake_request

    fake_request(10.0)

    xa = pmnc.transaction.create()
    xa.void.do_stuff()
    assert xa.execute() == (None,)
示例#15
0
 def test_transaction_rate():
     fake_request(4.0)
     t = Timeout(2.0)
     while not t.expired:
         xa = pmnc.transaction.create()
         xa.execute()
     xa = pmnc.transaction.create()
     xa.execute()
     assert xa.get_transaction_rate() > 1.0
示例#16
0
    def test_request_processing():

        fake_request(1.0)

        with pmnc.performance.request_processing():
            pass

        with expected(ZeroDivisionError):
            with pmnc.performance.request_processing():
                1 / 0
示例#17
0
    def test_secondary_index():

        fake_request(30.0)

        def _insert(txn, db, idx, primary_key, secondary_key, value):
            db.put(primary_key.encode("unicode-escape"), pickle(value), txn)
            idx.put(secondary_key.encode("unicode-escape"), pickle(primary_key), txn)

        def _lookup_primary_key(txn, db, primary_key):
            value = db.get(primary_key.encode("unicode-escape"), None, txn)
            if value is not None:
                return unpickle(value)

        def _lookup_secondary_key(txn, db, idx, secondary_key):
            primary_key = idx.get(secondary_key.encode("unicode-escape"), None, txn)
            if primary_key is not None:
                return _lookup_primary_key(txn, db, unpickle(primary_key))

        N = 100
        pks = [str(i) for i in range(N)]
        sks = [str(urandom(8)) for i in range(N)]
        values = [urandom(randint(1, 2048)) for i in range(N)]

        # populate the database

        db = pmnc.state.get_database("indexed_database")
        idx = pmnc.state.get_database("indexed_database")

        start = time()
        for i in range(N):
            pmnc.state.implicit_transaction(_insert, db, idx, pks[i], sks[i], values[i])
        pmnc.log.info("indexed state: {0:d} insert(s)/sec.".format(int(N / ((time() - start) or 0.01))))

        # lookup by the primary index

        db = pmnc.state.get_database("indexed_database")

        start = time()
        for i in range(N):
            assert pmnc.state.implicit_transaction(_lookup_primary_key, db, pks[i]) == values[i]
        pmnc.log.info("indexed state: {0:d} primary lookup(s)/sec.".format(int(N / ((time() - start) or 0.01))))

        assert pmnc.state.implicit_transaction(_lookup_primary_key, db, "") is None

        # lookup by the primary index

        db = pmnc.state.get_database("indexed_database")
        idx = pmnc.state.get_database("indexed_database")

        start = time()
        for i in range(N):
            assert pmnc.state.implicit_transaction(_lookup_secondary_key, db, idx, sks[i]) == values[i]
        pmnc.log.info("indexed state: {0:d} secondary lookup(s)/sec.".format(int(N / ((time() - start) or 0.01))))

        assert pmnc.state.implicit_transaction(_lookup_secondary_key, db, idx, "") is None
示例#18
0
    def test_large_values():

        fake_request(10.0)

        for i in range(20):
            value = "*" * (1 << i)
            pmnc.state.set(str(i), value)

        for i in range(20):
            value = "*" * (1 << i)
            assert pmnc.state.get(str(i)) == value
示例#19
0
    def test_running():

        fake_request(90.0)

        start = time()
        for i in range(901):
            pmnc.performance.event("resource.baz.response_rate.success")
            pmnc.performance.sample("resource.baz.response_time.success", 1)
            sleep(0.1)
            if i % 10 == 0:
                pmnc.log("wait {0:d}/90".format(i // 10))

        pmnc.performance.extract()
示例#20
0
    def test_resource_decline():

        fake_request(0.4) # less than pool__min_time

        xa = pmnc.transaction.create()
        xa.void.do_stuff()
        try:
            xa.execute()
        except ResourceError as e:
            assert str(e).startswith("transaction {0:s} is declined by resource instance void/".format(xa))
            assert e.participant_index == 0 and e.recoverable and not e.terminal
        else:
            assert False
示例#21
0
    def test_performance():

        N = 256

        def threads(n, f):
            ths = [ Thread(target = f, args = (N // n, )) for i in range(n) ]
            start = time()
            for th in ths: th.start()
            for th in ths: th.join()
            return int(N  / (time() - start))

        def test_transaction(n):
            for i in range(n):
                fake_request(10.0)
                xa = pmnc.transaction.create()
                xa.void.do_stuff()
                xa.execute()

        def state_transaction(n):
            for i in range(n):
                fake_request(30.0)
                xa = pmnc.transaction.create()
                xa.state.set(str(randint(0, 1000000)), i)
                xa.execute()

        fake_request(60.0)

        pmnc.log("begin performance test (may take a few minutes)")
        pmnc._loader.set_log_priority(4)
        try:

            test_1 = threads(1, test_transaction)
            test_4 = threads(4, test_transaction)
            test_16 = threads(16, test_transaction)
            test_64 = threads(64, test_transaction)

            pmnc.log("{0:d}/{1:d}/{2:d}/{3:d} empty transaction(s) per second".\
                     format(test_1, test_4, test_16, test_64))

            state_1 = threads(1, state_transaction)
            state_4 = threads(4, state_transaction)
            state_16 = threads(16, state_transaction)
            state_64 = threads(64, state_transaction)

            pmnc.log("{0:d}/{1:d}/{2:d}/{3:d} state transaction(s) per second".\
                     format(state_1, state_4, state_16, state_64))

        finally:
            pmnc._loader.set_log_priority(6)

        pmnc.log("end performance test")
示例#22
0
    def test_execute_fails():

        # execute hangs

        fake_request(1.0)

        def execute(res, *args, **kwargs):
            sleep(2.0)
        hooks = hooks_.copy(); hooks["execute"] = execute

        xa = pmnc.transaction.create()
        xa.callable_1(**hooks).execute()
        try:
            xa.execute()
        except TransactionExecutionError as e:
            assert str(e) == "request deadline waiting for intermediate result from " \
                             "resource callable_1 in transaction {0:s}".format(xa)
            assert e.participant_index == 0
        else:
            assert False

        assert q.pop(0.0)[:2] == ("connect", 0)
        assert q.pop(0.0)[:2] == ("begin_transaction", 1)
        assert q.pop(0.5) is None # this is where execute is called
        assert q.pop(1.0)[:2] == ("rollback", 2)
        assert q.pop(1.0) is None

        # note that the resource instance had not failed and is reused

        # execute throws

        fake_request(1.0)

        def execute(res, *args, **kwargs):
            1 / 0
        hooks = hooks_.copy(); hooks["execute"] = execute

        xa = pmnc.transaction.create()
        xa.callable_1(**hooks).execute()
        try:
            xa.execute()
        except ResourceError as e:
            assert by_regex("^(?:int )?division (?:or modulo )?by zero$")(str(e))
            assert e.participant_index == 0 and e.terminal and not e.recoverable
        else:
            assert False

        assert q.pop(0.0)[:2] == ("begin_transaction", 3)
        assert q.pop(1.0)[:2] == ("rollback", 4)
        assert q.pop(1.0)[:2] == ("disconnect", 5)
        assert q.pop(1.0) is None
示例#23
0
    def test_commit_fails():

        # commit hangs

        fake_request(1.0)

        def commit(res, *args, **kwargs):
            sleep(2.0)
        hooks = hooks_.copy(); hooks["commit"] = commit

        xa = pmnc.transaction.create()
        xa.callable_1(**hooks).execute()
        try:
            xa.execute()
        except TransactionCommitError as e:
            assert str(e) == "request deadline waiting for commit from resource " \
                             "callable_1 in transaction {0:s}".format(xa)
            assert e.participant_index == 0
        else:
            assert False

        assert q.pop(0.0)[:2] == ("connect", 0)
        assert q.pop(0.0)[:2] == ("begin_transaction", 1)
        assert q.pop(0.0)[:2] == ("execute", 2)
        assert q.pop(1.5) is None # this is where commit is called

        # note that the resource instance had not failed and is reused

        # commit throws

        fake_request(1.0)

        def commit(res, *args, **kwargs):
            1 / 0
        hooks = hooks_.copy(); hooks["commit"] = commit

        xa = pmnc.transaction.create()
        xa.callable_1(**hooks).execute()
        try:
            xa.execute()
        except TransactionCommitError as e:
            assert str(e) == "transaction {0:s} got unexpected commit outcome " \
                             "from resource callable_1: failure".format(xa)
            assert e.participant_index == 0
        else:
            assert False

        assert q.pop(0.0)[:2] == ("begin_transaction", 3), x
        assert q.pop(0.0)[:2] == ("execute", 4)
        assert q.pop(1.0)[:2] == ("disconnect", 5)
        assert q.pop(1.0) is None
示例#24
0
    def test_queue_many_items():

        fake_request(60.0)

        q = pmnc.state.get_queue("queue_many_items", re_len=64)

        counter = InterlockedCounter()

        def _push_n(txn, n):
            for i in range(n):
                c = counter.next()
                _push(txn, q, "test-{0:d}".format(c), pickle)

        def push_n(n):
            pmnc.state.implicit_transaction(_push_n, n)

        # push as much as we can per single transaction

        for i in range(8):
            push_n(1024)
            push_n(2048)
            push_n(4096)
            push_n(8100)

        # until we hit the limit of max_objects (8192) for one transaction

        with expected(MemoryError):
            push_n(8192)

        Timeout(4.0).wait()  # wait for checkpoint

        # now pop everything off the queue

        def _pop_n(txn, n):
            for i in range(n):
                assert _pop(txn, q, None, unpickle) is not None

        def pop_n(n):
            pmnc.state.implicit_transaction(_pop_n, n)

        assert peek(q) == "test-0"

        for i in range(8):
            pop_n(8100)
            pop_n(4096)
            pop_n(2048)
            pop_n(1024)

        # the attempt to push 8192 records should have left no trace

        assert peek(q) is None
示例#25
0
    def test_rollback_fails():

        # rollback hangs

        fake_request(1.0)

        def execute(res, *args, **kwargs):
            1 / 0
        def rollback(res, *args, **kwargs):
            sleep(2.0)
        hooks = hooks_.copy(); hooks["execute"] = execute; hooks["rollback"] = rollback

        xa = pmnc.transaction.create()
        xa.callable_1(**hooks).execute()
        try:
            xa.execute()
        except ResourceError as e:
            assert by_regex("^(?:int )?division (?:or modulo )?by zero$")(str(e))
            assert e.participant_index == 0 and e.terminal and not e.recoverable
        else:
            assert False

        assert q.pop(0.0)[:2] == ("connect", 0)
        assert q.pop(0.0)[:2] == ("begin_transaction", 1)
        assert q.pop(1.0) is None # this is where rollback is called
        assert q.pop(2.0)[:2] == ("disconnect", 2)

        # rollback throws

        fake_request(1.0)

        def execute(res, *args, **kwargs):
            1 / 0
        def rollback(res, *args, **kwargs):
            {}["not there"]
        hooks = hooks_.copy(); hooks["execute"] = execute; hooks["rollback"] = rollback

        xa = pmnc.transaction.create()
        xa.callable_1(**hooks).execute()
        try:
            xa.execute()
        except ResourceError as e:
            assert by_regex("^(?:int )?division (?:or modulo )?by zero$")(str(e))
            assert e.participant_index == 0 and e.terminal and not e.recoverable
        else:
            assert False

        assert q.pop(0.0)[:2] == ("connect", 0)
        assert q.pop(0.0)[:2] == ("begin_transaction", 1)
        assert q.pop(1.0)[:2] == ("disconnect", 2)
示例#26
0
def _start_pmnc(test_cages_dir):

    test_cage_dir = os_path.join(test_cages_dir, cage_name)

    Request._self_test = main_module_name
    fake_request()

    pmnc = ModuleLoader(node_name, cage_name, test_cage_dir, _log, 6)
    try:
        pmnc.startup.start()
    except:
        pmnc.startup.stop()
        raise
    else:
        return pmnc
示例#27
0
    def test_no_accept():

        fake_request(1.0)

        def no_accept(xa, results):
            return None

        xa = pmnc.transaction.create(accept = no_accept)
        xa.void.do_stuff()
        try:
            xa.execute()
        except TransactionExecutionError as e:
            assert str(e) == "intermediate results of transaction {0:s} have not been accepted".format(xa)
            assert e.participant_index is None
        else:
            assert False
示例#28
0
    def test_errors():

        fake_request(1.0)

        def execute(res, *args, **kwargs):
            raise ResourceError(code = 1, description = "foo", recoverable = True) # but terminal by default

        hooks = hooks_.copy(); hooks["execute"] = execute

        xa = pmnc.transaction.create()
        xa.callable_1(**hooks).execute()
        try:
            xa.execute()
        except ResourceError as e:
            assert str(e) == "1: foo" and e.code == 1 and e.description == "foo"
            assert e.participant_index == 0 and e.terminal and e.recoverable
        else:
            assert False

        assert q.pop(0.0)[:2] == ("connect", 0)
        assert q.pop(0.0)[:2] == ("begin_transaction", 1)
        assert q.pop(1.0)[:2] == ("rollback", 2)
        assert q.pop(1.0)[:2] == ("disconnect", 3)
        assert q.pop(1.0) is None

        fake_request(1.0)

        def execute(res, *args, **kwargs):
            raise SQLResourceError(description = "bar", state = "P0001", recoverable = False) # and terminal by default

        hooks = hooks_.copy(); hooks["execute"] = execute

        xa = pmnc.transaction.create()
        xa.callable_1(**hooks).execute()
        try:
            xa.execute()
        except SQLResourceError as e:
            assert str(e) == "[P0001] bar" and e.state == "P0001" and e.description == "bar"
            assert e.participant_index == 0 and e.terminal and not e.recoverable
        else:
            assert False

        assert q.pop(0.0)[:2] == ("connect", 0)
        assert q.pop(0.0)[:2] == ("begin_transaction", 1)
        assert q.pop(1.0)[:2] == ("rollback", 2)
        assert q.pop(1.0)[:2] == ("disconnect", 3)
        assert q.pop(1.0) is None
示例#29
0
    def test_pool_exhaust():

        fake_request(1.0)

        xa = pmnc.transaction.create()
        xa.void.do_stuff()
        xa.void.do_stuff()
        xa.void.do_stuff()
        xa.void.do_stuff() # one too many, pool__size = 3, results in deadlock
        try:
            xa.execute()
        except TransactionExecutionError as e:
            assert str(e) == "request deadline waiting for intermediate result " \
                             "from resource void in transaction {0:s}".format(xa)
            assert 0 <= e.participant_index <= 3
        else:
            assert False
示例#30
0
    def test_queue():

        fake_request(10.0)

        q = pmnc.state.get_queue("some_queue", re_len=1024)

        assert pop(q, "default") == "default"
        push(q, None)
        assert pop(q, "default") is None
        assert pop(q, "default") == "default"

        # and now for str/bytes support

        push(q, rus)
        assert pop(q) == rus

        push(q, rus_b)
        assert pop(q) == rus_b
示例#31
0
    def test_send_many():

        def process_request(request, response):
            pass

        with active_interface("smpp_1", **interface_config(process_request = process_request)):

            sleep(3.0) # to allow connection to spin up

            fake_request(30.0)

            xa = pmnc.transaction.create()
            xa.smpp_1.submit_sm(dest_addr_ton = DEST_TON, dest_addr_npi = DEST_NPI, destination_addr = DEST_ADDR, short_message = "test1")
            xa.smpp_1.submit_sm(dest_addr_ton = DEST_TON, dest_addr_npi = DEST_NPI, destination_addr = DEST_ADDR, short_message = "test2")
            xa.smpp_1.submit_sm(dest_addr_ton = DEST_TON, dest_addr_npi = DEST_NPI, destination_addr = DEST_ADDR, short_message = "test3")
            xa.execute()

            sleep(10.0)
示例#32
0
    def test_large_queue_items():

        fake_request(10.0)

        q = pmnc.state.get_queue("large_items", re_len=1024, re_pad=0x5A)

        for i in (16, 64, 256, 1024):
            value = b"*" * i
            push(q, value, lambda x: x)

        with expected(bsddb.DBInvalidArgError):
            push(q, b"*" * 1025, lambda x: x)

        for i in (16, 64, 256, 1024):
            value = b"*" * i + b"\x5a" * (1024 - i)
            assert pop(q, None, lambda x: x) == value

        assert pop(q, None, lambda x: x) is None
示例#33
0
def _start_pmnc(test_cages_dir):

    test_cage_dir = os_path.join(test_cages_dir, cage_name)

    Request._self_test = main_module_name
    fake_request()

    loader = ModuleLoader(node_name, cage_name, test_cage_dir, _log, "NOISE",
                          0.0, 0.0)
    pmnc = ModuleLoaderProxy(loader, __name__)

    try:
        pmnc.startup.start()
    except:
        pmnc.startup.stop()
        raise
    else:
        return pmnc
示例#34
0
    def test_queue_rollback_disorder():

        fake_request(10.0)

        q = pmnc.state.get_queue("queue_abort_reverse", re_len=128)

        push(q, 1)
        push(q, 2)

        # first reader rolls back

        evt1 = Event()

        def txn1(txn):
            assert _pop(txn, q, None, unpickle) == 1
            evt1.set()
            evt2.wait()
            1 / 0  # this causes rollback of the first transaction

        # second reader commits

        evt2 = Event()

        def txn2(txn):
            evt1.wait()
            result = _pop(txn, q, None, unpickle)
            evt2.set()
            return result

        def th_proc():
            fake_request(10.0)
            with expected(ZeroDivisionError):
                pmnc.state.implicit_transaction(txn1)

        # in presence of multiple failing readers the order is not preserved

        th = Thread(target=th_proc)
        th.start()
        try:
            assert pmnc.state.implicit_transaction(txn2) == 2
        finally:
            th.join()

        assert pmnc.state.implicit_transaction(txn2) == 1
示例#35
0
        def test_data_type(t, vs):

            tn = "table_{0:s}".format(random_string(8))

            sqls = [ "CREATE TABLE {0:s} (i number(8), v {1:s})".format(tn, t) ]
            params = {}
            for i, v in enumerate(vs):
                sqls.append("INSERT INTO {0:s} (i, v) VALUES ({1:d}, {{v{1:d}}})".format(tn, i))
                params["v{0:d}".format(i)] = v
            sqls.append("SELECT v FROM {0:s} ORDER BY i".format(tn))
            sqls.append("DROP TABLE {0:s}".format(tn))

            fake_request(30.0)

            xa = pmnc.transaction.create()
            xa.oracle_1.execute(*sqls, **params)
            records = xa.execute()[0][-2]
            result = [ r["V"] for r in records ] # note that field name is capitalized
            return result
示例#36
0
    def test_query_cursor():

        fake_request(10.0)

        rs = pmnc.transaction.mongodb_1.test.find()
        assert len(rs.documents) == 1 and rs.cursor_id == 0

        rs = pmnc.transaction.mongodb_1.test.find(docs_to_return=50)
        assert len(rs.documents) == 50 and rs.cursor_id != 0

        xa = pmnc.transaction.create()
        xa.mongodb_1.test.get_more(rs.cursor_id, docs_to_return=25)
        xa.mongodb_1.test.get_more(rs.cursor_id, docs_to_return=25)
        rs1, rs2 = xa.execute()
        assert len(rs1.documents) == 25 and len(rs2.documents) == 25

        ds = [d["k"] for d in (rs.documents + rs1.documents + rs2.documents)]
        ds.sort()
        assert ds == list(range(100))
    def test_performance():

        fake_request(120.0)

        for i in range(90):
            pmnc.performance.event("interface.foo.response_rate.success")
            pmnc.performance.sample("interface.foo.response_time.success", 10)
            pmnc.performance.event("resource.bar.transaction_rate.success")
            pmnc.performance.sample("resource.bar.processing_time.success", 10)
            sleep(1.0)
            pmnc.log("wait {0:d}/90".format(i + 1))

        request = dict(url="/?"
                       "interface.foo.request_rate=expanded&"
                       "interface.foo.response_rate.success=collapsed&"
                       "interface.foo.response_time=expanded&"
                       "interface.foo.response_time.success=collapsed&"
                       "resource.bar.transaction_rate=expanded&"
                       "resource.bar.transaction_rate.success=collapsed&"
                       "resource.bar.processing_time=expanded&"
                       "resource.bar.processing_time.success=collapsed",
                       method="GET",
                       headers={},
                       body=b"")
        response = dict(status_code=200, headers={}, body=b"")

        pmnc.__getattr__(__name__).process_request(request, response)
        assert response["status_code"] == 200
        content = response["content"]

        # difficult to assert anything reasonable about the response content here

        assert "10.0" in content and "100" in content
        assert "interface foo (successful response rate)" in content
        assert "interface foo (successful response time)" in content
        assert "resource bar (successful transaction rate)" in content
        assert "resource bar (successful processing time)" in content
        assert "request rate</a>" in content
        assert "response time</a>" in content
        assert "transaction rate</a>" in content
        assert "processing time</a>" in content
        assert "RAM" in content
        assert "CPU" in content
示例#38
0
    def test_resource_echo():

        fake_request(1.0)

        echo = Resource("echo/1",
                        executable="echo",
                        arguments=(),
                        environment={})
        echo.connect()
        try:
            assert echo.expired
            echo.set_pool_info("echo", 1)
            retcode, stdout, stderr = \
                echo.execute("foo", 123, Decimal("1.00"))
            assert retcode == 0
            assert stdout.rstrip() == b"foo 123 1.00"
            assert stderr == b""
        finally:
            echo.disconnect()
示例#39
0
    def test_resource():
        def process_xmlrpc_request(request, response):
            if request["method"] == "ShouldBe.Failing":
                raise Exception(request["args"][0])
            else:
                response["result"] = request, pmnc.request.parameters[
                    "auth_tokens"]

        with active_interface(
                "xmlrpc_1",
                **interface_config(
                    process_xmlrpc_request=process_xmlrpc_request)):

            fake_request(10.0)

            for i in range(16):
                s = "*" * 2**i
                n = "n" + str(i)
                result = pmnc.transaction.xmlrpc_1.Module.Method(
                    i, s, [s], {
                        s: i,
                        n: None
                    })
                assert result == [{
                    "method": "Module.Method",
                    "args": [i, s, [s], {
                        s: i,
                        n: None
                    }]
                }, {
                    "username": "******",
                    "peer_ip": "127.0.0.1",
                    "password": "******",
                    "encrypted": False
                }]

            try:
                pmnc.transaction.xmlrpc_1.ShouldBe.Failing("some error")
            except ResourceError as e:
                assert e.code == 500 and e.description.startswith(
                    "Exception(\"some error\")")
                assert not e.recoverable and not e.terminal
示例#40
0
    def test_international():

        fake_request(10.0)

        russian = "������¨�������������������������‗אבגדהו¸זחטיךכלםמןנסעףפץצקרש��ת‎‏�"
        assert pmnc.transaction.mysql_1.execute("SELECT {s} AS s", s = russian) == \
               ([{ "s": russian }],)

        # assuming CIS collation in WHERE clause

        tn = random_name()

        rs = pmnc.transaction.mysql_1.execute(
                "CREATE TABLE {0:s} (s VARCHAR(66))".format(tn),
                "INSERT INTO {0:s} (s) VALUES ({{s}})".format(tn),
                "SELECT s FROM {0:s} WHERE s = {{s}}".format(tn),
                "SELECT LOWER(s) AS sl FROM {0:s} WHERE s = {{sl}}".format(tn),
                "DROP TABLE {0:s}".format(tn), s = russian, sl = russian.lower())

        assert rs == ([], [], [{ "s": russian }], [{ "sl": russian.lower() }], [])
示例#41
0
    def test_sp():

        fake_request(10.0)

        tn = random_name()

        rs = pmnc.transaction.mysql_1.execute("""\
CREATE PROCEDURE {0:s}(x int)
BEGIN
SELECT x AS x;
END
""".format(tn),
"CALL {0:s}({{one}})".format(tn),
"CALL {0:s}({{null}})".format(tn),
"DROP PROCEDURE {0:s}".format(tn),
one = 1, null = None)

        # this is awkward but SELECT NULL returns nothing

        assert rs == ([], [{ "x": 1 }], [], [])
示例#42
0
    def test_resource_read():

        fn = random_filename()

        fake_request(3.0)

        pmnc.transaction.file_1.write(fn, b"foobar")

        assert pmnc.transaction.file_1.read(fn) == b"foobar"
        assert os_path.isfile(target_filename(fn))

        assert pmnc.transaction.file_1.read(fn, remove = True, frag_size = 4) == b"foobar"
        assert not os_path.isfile(target_filename(fn))

        with expected(ResourceError, "^.*never_existed.*$"):
            pmnc.transaction.file_1.read("never_existed")

        pmnc.transaction.file_1.write(fn, b"\x00" * 33554432)
        fake_request(0.1)
        with expected(Exception, "^request deadline.*$"):
            pmnc.transaction.file_1.read(fn, frag_size = 1)
示例#43
0
    def test_notify():

        fake_request(10.0)

        pmnc.notify.info("info")
        pmnc.notify.warning("warning")
        pmnc.notify.error("error")
        pmnc.notify.alert("alert")

        assert len(notifications) == 4
        extracted_notifications = pmnc.notify.extract()
        assert extracted_notifications is not notifications
        assert [ (type(d["timestamp"]), d["level"], d["message"]) for d in extracted_notifications ] == \
               [ (int, "INFO", "info"), (int, "WARNING", "warning"), (int, "ERROR", "error"), (int, "ALERT", "alert") ]

        pmnc.notify.alert("again")

        assert len(notifications) == 4
        extracted_notifications = pmnc.notify.extract()
        assert [ (type(d["timestamp"]), d["level"], d["message"]) for d in extracted_notifications ] == \
               [ (int, "WARNING", "warning"), (int, "ERROR", "error"), (int, "ALERT", "alert"), (int, "ALERT", "again") ]
示例#44
0
    def test_process_one():

        loopback_queue = InterlockedQueue()

        def process_request(request, response):
            loopback_queue.push(request)

        with active_interface("jms_1", **interface_config(process_request = process_request)):

            fake_request(10.0)

            xa = pmnc.transaction.create()
            xa.jms_1.send(russian, JMSCorrelationID = russian, FOOBAR = "123")
            message_id = xa.execute()[0]

            request = loopback_queue.pop(10.0)

        assert request["message_id"] == message_id
        assert request["message_text"] == russian
        headers = request["headers"]
        assert headers["JMSCorrelationID"] == russian and headers["FOOBAR"] == "123"
示例#45
0
    def test_getlasterror():

        fake_request(10.0)

        try:
            pmnc.transaction.mongodb_1.capped.drop()
        except ResourceError as e:
            if e.description == "ns not found":
                pass
            else:
                raise

        pmnc.transaction.mongodb_1.command("create", {
            "capped": True,
            "size": 10
        },
                                           create="capped")

        with expected(ResourceError,
                      "10101.*remove from a capped collection.*"):
            pmnc.transaction.mongodb_1.capped.remove({"foo": "bar"})
示例#46
0
    def test_complex_search():

        fake_request(10.0)

        rs = pmnc.transaction.mongodb_1.test.find(
            {"$query": {
                "k": {
                    "$gt": 90
                }
            }}, docs_to_return=-10)
        assert len(rs.documents) == 9 and rs.cursor_id == 0

        rs = pmnc.transaction.mongodb_1.test.find(
            {
                "$where":
                BSON_JavaScript("function() { return this.k % 3 == 0; }")
            },
            docs_to_return=-100)
        ds = [d["k"] for d in rs.documents]
        ds.sort()
        assert ds == list(range(0, 100, 3))
示例#47
0
    def test_mixed_access():

        fake_request(10.0)

        pmnc.state.set("MIX-KEY", "VALUE")

        xa = pmnc.transaction.create()
        xa.state.get("MIX-KEY")
        assert xa.execute() == ("VALUE", )

        xa = pmnc.transaction.create()
        xa.state.delete("MIX-KEY")
        assert xa.execute() == (None, )

        assert pmnc.state.get("MIX-KEY") is None

        xa = pmnc.transaction.create()
        xa.state.set("MIX-KEY", "VALUE")
        assert xa.execute() == (None, )

        assert pmnc.state.get("MIX-KEY") == "VALUE"
示例#48
0
    def test_log_truncation():
        def current_logs():
            return sorted([
                int(s[4:]) for s in listdir(_module_state_dir(__name__))
                if s.startswith("log.")
            ])

        def grow_log():
            for i in range(32):
                pmnc.state.set(str(randint(0, 127)), urandom(65536))
            return current_logs()

        fake_request(60.0)

        logs_before = grow_log()
        logs_after = grow_log()
        while logs_before[0] == logs_after[0]:
            Timeout(1.0).wait()
            logs_after = grow_log()

        assert logs_before[0] < logs_after[0]
示例#49
0
    def test_transaction_isolation():

        fake_request(10.0)

        tn = "table_{0:s}".format(random_string(8))

        xa = pmnc.transaction.create()
        xa.oracle_1.execute("CREATE TABLE {0:s} (ID NUMBER(8) NOT NULL PRIMARY KEY)".format(tn))
        xa.execute()

        xa = pmnc.transaction.create()
        xa.oracle_1.execute("INSERT INTO {0:s} (ID) VALUES ({{id}})".format(tn),
                            "SELECT ID FROM {0:s}".format(tn), id = 1)
        xa.oracle_1.execute("INSERT INTO {0:s} (ID) VALUES ({{id}})".format(tn),
                            "SELECT ID FROM {0:s}".format(tn), id = 2)
        assert xa.execute() == (([], [{ "ID": 1 }]), ([], [{ "ID": 2 }]))

        fake_request(5.0)

        xa = pmnc.transaction.create()
        xa.oracle_1.execute("INSERT INTO {0:s} (ID) VALUES ({{id}})".format(tn), id = 3) # causes a deadlock
        xa.oracle_1.execute("INSERT INTO {0:s} (ID) VALUES ({{id}})".format(tn), id = 3)
        with expected(Exception("request deadline")):
            xa.execute()

        fake_request(10.0)

        xa = pmnc.transaction.create()
        xa.oracle_1.execute("SELECT id FROM {0:s} ORDER BY id".format(tn),
                            "DROP TABLE {0:s}".format(tn))
        assert xa.execute()[0] == ([{ "ID": 1 }, { "ID": 2 }], [])
示例#50
0
    def test_errors():

        fake_request(10.0)
        try:
            pmnc.transaction.postgresql_2.execute("SELECT 1/0")
        except SQLResourceError as e:
            assert e.code is None and e.state == "22012"
            assert e.recoverable and not e.terminal
        else:
            assert False

        t = "table_{0:s}".format(random_string(8))

        fake_request(10.0)
        try:
            pmnc.transaction.postgresql_2.execute(
                "CREATE TABLE {t} (id int PRIMARY KEY)".format(t = t),
                "INSERT INTO {t} VALUES ({{id}})".format(t = t),
                "INSERT INTO {t} VALUES ({{id}})".format(t = t),
                id = 123)
        except SQLResourceError as e:
            assert e.code is None and e.state == "23505"
            assert e.recoverable and not e.terminal
        else:
            assert False

        fake_request(10.0)
        try:
            pmnc.transaction.postgresql_2.execute("DROP TABLE {t}".format(t = t))
        except SQLResourceError as e:
            assert e.code is None and e.state == "42P01"
            assert e.recoverable and not e.terminal
        else:
            assert False
示例#51
0
    def test_failure():

        fake_request(10.0)

        def execute(resource, *args, **kwargs):
            1 / 0

        # failure sequence (the instance is reused): begin_transaction, execute, rollback, disconnect

        xa = pmnc.transaction.create(biz="baz")
        xa.callable_1("abc",
                      begin_transaction=begin_transaction,
                      execute=execute,
                      commit=commit,
                      rollback=rollback,
                      foo="bar").execute(1, 2, eee="fff")
        try:
            xa.execute()
        except ResourceError as e:
            assert by_regex("^(?:int )?division (?:or modulo )?by zero$")(
                str(e))
            assert not e.recoverable and e.terminal
        else:
            assert False

        # now check the trace

        m, c, args, kwargs = q.pop(0.0)
        assert m == "begin_transaction" and c == 4
        assert args == (xa._xid, )
        assert kwargs == dict(transaction_options={"biz": "baz"},
                              source_module_name=__name__,
                              resource_args=("abc", ),
                              resource_kwargs={"foo": "bar"})
        assert q.pop(1.0) == (
            "rollback", 5
        )  # rollback is not waited upon, therefore "rollback" may not appear in the queue immediately
        assert q.pop(1.0) == ("disconnect", 6)
        assert q.pop(1.0) is None
示例#52
0
    def _poller_proc(self, source_cage):

        while not current_thread().stopped():
            try:

                # attach a new fake request to this thread so that
                # network access in RPC call times out properly

                fake_request(timeout=self._request_timeout,
                             interface=self._name)
                pmnc.request.describe("polling cage {0:s}".format(source_cage))

                # fetch a request from the remote cage
                # and extract the call information from it

                try:
                    revrpc_request = self._poll(source_cage)
                except:
                    pmnc.log.error(exc_string())  # failure to fetch a request
                    current_thread().stopped(
                        self._request_timeout)  # results in idle delay
                    continue

                if revrpc_request is None:
                    continue
                elif current_thread().stopped():
                    break

                assert revrpc_request.pop(
                    "target_cage") == __cage__, "expected call to this cage"
                assert revrpc_request.pop(
                    "source_cage"
                ) == source_cage, "expected call from {0:s}".format(
                    source_cage)

                self._process_request(source_cage, revrpc_request)

            except:
                pmnc.log.error(exc_string())
示例#53
0
    def test_success():

        fake_request(10.0)

        def execute(resource, *args, **kwargs):
            resource._count += 1
            resource._q.push(("execute", resource._count, args, kwargs))
            return "ok"

        # success sequence: connect, begin_transaction, execute, commit (then the instance is put back to the pool)

        xa = pmnc.transaction.create(biz="baz")
        xa.callable_1("abc",
                      begin_transaction=begin_transaction,
                      execute=execute,
                      commit=commit,
                      rollback=rollback,
                      foo="bar").execute(1, 2, eee="fff")
        assert xa.execute() == ("ok", )

        # now check the trace

        assert q.pop(0.0) == ("connect", 0, {
            "param1": "value1",
            "param2": "value2"
        })
        m, c, args, kwargs = q.pop(0.0)
        assert m == "begin_transaction" and c == 1
        assert args == (xa._xid, )
        assert kwargs == dict(transaction_options={"biz": "baz"},
                              source_module_name=__name__,
                              resource_args=("abc", ),
                              resource_kwargs={"foo": "bar"})
        assert q.pop(0.0) == ("execute", 2, (1, 2), {"eee": "fff"})
        assert q.pop(0.0) == (
            "commit", 3
        )  # commit is waited upon, therefore "commit" is in the queue
        assert q.pop(1.0) is None
示例#54
0
    def test_module_state():

        fake_request(10.0)

        module_state_dir = _module_state_dir("foo")

        module_state = ModuleState(module_state_dir)
        try:

            # note that the first access to a queue or a database creates it,
            # therefore options such as re_len are required, but subsequent
            # accesses just open it and the options can be omitted

            assert not os_path.exists(
                os_path.join(module_state_dir, "state.queue"))
            queue = module_state.get_queue_db("state", re_len=100)
            assert os_path.exists(os_path.join(module_state_dir,
                                               "state.queue"))
            stat = queue.stat()
            assert "buckets" not in stat
            queue.append("foo")
            assert module_state.get_queue_db("state") is queue
            assert module_state.get_queue_db("state2") is not queue

            assert not os_path.exists(
                os_path.join(module_state_dir, "state.btree"))
            btree = module_state.get_btree_db("state")
            assert os_path.exists(os_path.join(module_state_dir,
                                               "state.btree"))
            stat = btree.stat()
            assert "buckets" not in stat
            with expected(bsddb.DBInvalidArgError):
                btree.append("foo")
            assert module_state.get_btree_db("state") is btree
            assert module_state.get_btree_db("state2") is not btree

        finally:
            module_state.close()
    def test_performance():

        fake_request(30.0)

        N = 250

        table_name = random_name("t")
        qs = [ "CREATE TABLE {0:s} (id integer PRIMARY KEY)".format(table_name) ]
        ids = list(range(N)); shuffle(ids); ii = {}
        for i, id in enumerate(ids):
            n = format("id_{0:d}".format(i))
            ii[n] = id
            qs.append("INSERT INTO {0:s} (id) VALUES ({{{1:s}}})".format(table_name, n))
        qs.append("SELECT id FROM {0:s} ORDER BY newid()".format(table_name))
        qs.append("DROP TABLE {0:s}".format(table_name))

        start = time()
        rs = pmnc.transaction.sqlserver_1.execute(*qs, **ii)[-2]
        ids = list(map(lambda r: r["id"], rs))
        stop = time()

        assert sorted(ids) == list(range(N))
        pmnc.log("performance: {0:d} insert(s)/sec".format(int(N / (stop - start))))
示例#56
0
    def test_cross_db_deadlock():

        fake_request(30.0)

        db1 = pmnc.state.get_database("db1")
        db2 = pmnc.state.get_queue("db2", re_len=6144)

        def f(txn):
            db1.put(b"key", b"value_1", txn)
            Timeout(3.0).wait()
            db2.append(pickle("item_1"), txn)

        def g(txn):
            db2.append(pickle("item_2"), txn)
            Timeout(3.0).wait()
            db1.put(b"key", b"value_2", txn)

        th_f = HeavyThread(target=lambda: pmnc.state.implicit_transaction(f))
        th_g = HeavyThread(target=lambda: pmnc.state.implicit_transaction(g))

        th_f.start()
        th_g.start()

        th_f.join()
        th_g.join()

        # now see what went through

        def fetch_result(txn):
            value = db1.get(b"key", None, txn)
            item1 = _pop(txn, db2, None, unpickle)
            item2 = _pop(txn, db2, None, unpickle)
            return value, item1, item2

        value, item1, item2 = pmnc.state.implicit_transaction(fetch_result)
        assert value in (b"value_1", b"value_2")
        assert (item1, item2) in (("item_1", "item_2"), ("item_2", "item_1"))
示例#57
0
    def test_performance():

        pmnc.log("begin performance test")

        # create table

        t = "table_{0:s}".format(random_string(8))

        fake_request(10.0)
        pmnc.transaction.postgresql_1.execute(
            "CREATE TABLE {t} (id int PRIMARY KEY, key char(8) UNIQUE NOT NULL, "
                              "pad varchar(200) NOT NULL)".format(t = t))

        # populate table

        start = time()

        for i in range(10):
            fake_request(10.0)
            sqls, params = [], {}
            for j in range(100):
                id = i * 100 + j
                params["id{0:d}".format(id)] = id
                params["key{0:d}".format(id)] = str(id)
                params["pad{0:d}".format(id)] = random_string(200)
                sql = "INSERT INTO {t} VALUES ({{id{id}}}, {{key{id}}}, {{pad{id}}})".format(t = t, id = id)
                sqls.append(sql)
            pmnc.transaction.postgresql_1.execute(*sqls, **params)

        pmnc.log("{0:.01f} insert(s)/sec".format(1000 / (time() - start)))

        # query table

        stop = Timeout(10.0)
        count = InterlockedCounter()

        def th_proc():
            while not stop.expired:
                fake_request(10.0)
                key = randint(0, 999)
                rs = pmnc.transaction.postgresql_1.execute(
                    "SELECT id FROM {t} WHERE key = {{key}}".format(t = t), key = str(key))
                assert rs[0][0]["id"] == key
                count.next()

        ths = [ Thread(target = th_proc) for i in range(5) ]
        for th in ths: th.start()
        for th in ths: th.join()

        pmnc.log("{0:.01f} select(s)/sec".format(count.next() / 10.0))

        # drop table

        fake_request(10.0)
        pmnc.transaction.postgresql_1.execute("DROP TABLE {t}".format(t = t))

        pmnc.log("end performance test")
示例#58
0
    def test_send_one():

        def process_request(request, response):
            pass

        with active_interface("smpp_1", **interface_config(process_request = process_request)):

            sleep(3.0) # to allow connection to spin up

            fake_request(30.0)

            with expected(ResourceError, "^data_coding is not specified, provide short_message of type str$"):
                pmnc.transaction.smpp_1.submit_sm(
                        dest_addr_ton = DEST_TON, dest_addr_npi = DEST_NPI,
                        destination_addr = DEST_ADDR, short_message = b"test")

            with expected(ResourceError, "^data_coding is specified, provide short_message of type bytes$"):
                pmnc.transaction.smpp_1.submit_sm(
                        dest_addr_ton = DEST_TON, dest_addr_npi = DEST_NPI,
                        destination_addr = DEST_ADDR, short_message = "test", data_coding = 0x00)

            pmnc.transaction.smpp_1.submit_sm(
                        dest_addr_ton = DEST_TON, dest_addr_npi = DEST_NPI,
                        destination_addr = DEST_ADDR, short_message = b"test1", data_coding = 0x00)

            pmnc.transaction.smpp_1.submit_sm(
                        dest_addr_ton = DEST_TON, dest_addr_npi = DEST_NPI,
                        destination_addr = DEST_ADDR, short_message = "test2") # encoded to GSM7

            pmnc.transaction.smpp_1.submit_sm(
                        dest_addr_ton = DEST_TON, dest_addr_npi = DEST_NPI,
                        destination_addr = DEST_ADDR, short_message = "@$\\") # encoded to GSM7

            pmnc.transaction.smpp_1.submit_sm(
                        dest_addr_ton = DEST_TON, dest_addr_npi = DEST_NPI,
                        destination_addr = DEST_ADDR, short_message = russian) # encoded to UCS2
示例#59
0
        def th_proc(n):

            count = 0

            def next_key():
                nonlocal count
                count += 1
                return "{0:d}_{1:d}".format(n, count)

            def next_value():
                return urandom(randint(1, 2048))

            while count < 10:

                fake_request(10.0)

                left_value = pop(lq)
                if left_value is not None:
                    key, value = next_key(), left_value
                    pmnc.state.implicit_transaction(_set, ldb, key, value)
                    register(left_data, key, value)
                    push(rq, left_value)
                push(rq, next_value())

                right_value = pop(rq)
                if right_value is not None:
                    key, value = next_key(), right_value
                    pmnc.state.implicit_transaction(_set, rdb, key, value)
                    register(right_data, key, value)
                    push(lq, right_value)
                push(lq, next_value())

            while True:

                fake_request(10.0)

                left_value = pop(lq)
                if left_value is not None:
                    key, value = next_key(), left_value
                    pmnc.state.implicit_transaction(_set, ldb, key, value)
                    register(left_data, key, value)
                else:
                    break

            while True:

                fake_request(10.0)

                right_value = pop(rq)
                if right_value is not None:
                    key, value = next_key(), right_value
                    pmnc.state.implicit_transaction(_set, rdb, key, value)
                    register(right_data, key, value)
                else:
                    break
示例#60
0
    def test_get_set_delete_deadlock():

        fake_request(5.0)

        xa = pmnc.transaction.create()
        xa.state.set("key", "value1")
        xa.state.set("key", "value2")
        try:
            xa.execute()
        except (ResourceError, TransactionExecutionError): # depends on who times out first
            pass
        else:
            assert False

        fake_request(5.0)

        xa = pmnc.transaction.create()
        xa.state.set("key", "value")
        xa.execute()

        xa = pmnc.transaction.create()
        xa.state.delete("key")
        xa.state.get("key")
        try:
            xa.execute()
        except (ResourceError, TransactionExecutionError): # depends on who times out first
            pass
        else:
            assert False

        fake_request(5.0)

        xa = pmnc.transaction.create()
        xa.state.get("key")
        xa.state.get("key")
        assert xa.execute() == ("value", "value")

        xa = pmnc.transaction.create()
        xa.state.get("key")
        xa.state.set("key", "value2")
        try:
            xa.execute()
        except (ResourceError, TransactionExecutionError): # depends on who times out first
            pass
        else:
            assert False