def test_pos_operate_prepend_set_to_aerospike_null(self):
        """
        Invoke operate() with prepend command with bin set to aerospike_null
        """
        key = ('test', 'demo', 'null_record')

        bins = {"name": "John", "no": 3}

        assert 0 == self.as_connection.put(key, bins)

        (key, _, bins) = self.as_connection.get(key)

        assert {"name": "John", "no": 3} == bins

        llist = [
            operations.prepend("no", aerospike.null()),
            operations.read("no")
        ]

        try:
            (key, _, bins) = self.as_connection.operate(key, llist)

        except e.InvalidRequest as exception:
            assert exception.code == 4
        self.as_connection.remove(key)
    def test_pos_operate_prepend_set_to_aerospike_null(self):
        """
        Invoke operate() with prepend command with bin set to aerospike_null
        """
        key = ('test', 'demo', 'null_record')

        bins = {"name": "John", "no": 3}

        assert 0 == self.as_connection.put(key, bins)

        (key, _, bins) = self.as_connection.get(key)

        assert {"name": "John", "no": 3} == bins

        llist = [
            operations.prepend("no", aerospike.null()),
            operations.read("no")
        ]

        try:
            (key, _, bins) = self.as_connection.operate(key, llist)

        except e.InvalidRequest as exception:
            assert exception.code == 4
        self.as_connection.remove(key)
    def test_predexp_key_operate_record_digest_modulo(self):
        """
        Invoke the C client aerospike_key_operate with a rec_digest_modulo predexp.
        """

        less_than_128 = 0
        for i in range(100):
            key = 'test', 'demo', i
            if aerospike.calc_digest(*key)[-1] < 128:
                less_than_128 += 1
            self.as_connection.put(key, {'dig_id': i})

        results = []

        predexp = [
            as_predexp.rec_digest_modulo(256),
            as_predexp.integer_value(128),
            as_predexp.integer_less()
        ]

        ops = [operations.read('dig_id')]

        for i in range(100):
            try:
                key = 'test', 'demo', i
                _, _, res = self.as_connection.operate(
                    key, ops, policy={'predexp': predexp})
                results.append(res)
            except:
                pass
            self.as_connection.remove(key)

        assert len(results) == less_than_128
    def test_expressions_key_operate_record_digest_modulo(self):
        """
        Invoke the C client aerospike_key_operate with a rec_digest_modulo expressions.
        """

        less_than_128 = 0
        for i in range(100):
            key = 'test', 'demo', i
            if aerospike.calc_digest(*key)[-1] < 128:
                less_than_128 += 1
            self.as_connection.put(key, {'dig_id': i})

        results = []

        expr = exp.LT(exp.DigestMod(256), 128).compile()

        ops = [operations.read('dig_id')]

        for i in range(100):
            try:
                key = 'test', 'demo', i
                _, _, res = self.as_connection.operate(
                    key, ops, policy={'expressions': expr})
                results.append(res)
            except:
                pass
            self.as_connection.remove(key)

        assert len(results) == less_than_128
    def test_expressions_key_operate_record_last_updated(self):
        """
        Invoke the C client aerospike_key_operate with a record_last_updated expressions.
        """

        for i in range(5):
            key = 'test', 'pred_lut', i
            self.as_connection.put(key, {'time': 'earlier'})

        cutoff_nanos = (10**9) * int(time.time() + 2)
        time.sleep(5)

        for i in range(5, 10):
            key = 'test', 'pred_lut', i
            self.as_connection.put(key, {'time': 'later'})

        results = []

        expr = exp.LT(exp.LastUpdateTime(), cutoff_nanos)
        ops = [operations.read('time')]

        for i in range(10):
            try:
                key = 'test', 'pred_lut', i
                _, _, res = self.as_connection.operate(
                    key, ops, policy={'expressions': expr.compile()})
                results.append(res)
            except:
                pass
            self.as_connection.remove(key)

        assert len(results) == 5
        for res in results:
            assert res['time'] == 'earlier'
def verify_multiple_expression_avenues(client, test_ns, test_set, expr, op_bin, expected):
    keys = [(test_ns, test_set, i) for i in range(_NUM_RECORDS + 1)]

    # operate
    ops = [
        operations.read(op_bin)
    ]
    res = []
    for key in keys:
        try:
            res.append(client.operate(key, ops, policy={'expressions': expr})[2])
        except e.FilteredOut:
            pass

    assert len(res) == expected

    # operate ordered
    ops = [
        operations.read(op_bin)
    ]
    res = []
    for key in keys:
        try:
            res.append(client.operate_ordered(key, ops, policy={'expressions': expr})[2])
        except e.FilteredOut:
            pass
    
    # batch get
    res = [rec for rec in client.get_many(keys, policy={'expressions': expr}) if rec[2]]

    assert len(res) == expected

    # scan results
    scan_obj = client.scan(test_ns, test_set)
    records = scan_obj.results({'expressions': expr})
    assert len(records) == expected


    # other scan methods
    # execute_background tested test_scan_execute_background.py 
    # foreach tested test_scan.py

    # query results
    query_obj = client.query(test_ns, test_set)
    records = query_obj.results({'expressions': expr})
    assert len(records) == expected
    def test_pos_operate_with_nonexistent_bin(self):
        """
        Invoke operate() with non-existent bin
        """
        key = ('test', 'demo', 1)
        llist = [operations.append("addr", "pune"), operations.read("addr")]
        _, _, bins = self.as_connection.operate(key, llist)

        assert bins == {'addr': 'pune'}
    def test_pos_operate_with_nonexistent_key(self):
        """
        Invoke operate() with non-existent key
        """
        new_key = ('test', 'demo', "key11")
        llist = [operations.prepend("loc", "mumbai"), operations.read("loc")]
        _, _, bins = self.as_connection.operate(new_key, llist)

        assert bins == {'loc': 'mumbai'}
        self.as_connection.remove(new_key)
    def test_pos_operate_with_nonexistent_bin(self):
        """
        Invoke operate() with non-existent bin
        """
        key = ('test', 'demo', 1)
        llist = [
            operations.append("addr", "pune"),
            operations.read("addr")
        ]
        _, _, bins = self.as_connection.operate(key, llist)

        assert bins == {'addr': 'pune'}
    def test_pos_operate_with_increment_positive_float_value(self):
        """
        Invoke operate() with correct parameters
        """
        if TestOperate.skip_old_server is True:
            pytest.skip("Server does not support increment on float type")
        key = ('test', 'demo', 6)
        llist = [operations.increment("age", 3.5), operations.read("age")]

        _, _, bins = self.as_connection.operate(key, llist)

        assert bins == {'age': 9.8}
    def test_pos_operate_with_nonexistent_key(self):
        """
        Invoke operate() with non-existent key
        """
        new_key = ('test', 'demo', "key11")
        llist = [
            operations.prepend("loc", "mumbai"),
            operations.read("loc")
        ]
        _, _, bins = self.as_connection.operate(new_key, llist)

        assert bins == {'loc': 'mumbai'}
        self.as_connection.remove(new_key)
    def test_pos_operate_with_increment_positive_float_value(self):
        """
        Invoke operate() with correct parameters
        """
        if TestOperate.skip_old_server is True:
            pytest.skip("Server does not support increment on float type")
        key = ('test', 'demo', 6)
        llist = [
            operations.increment("age", 3.5),
            operations.read("age")
        ]

        _, _, bins = self.as_connection.operate(key, llist)

        assert bins == {'age': 9.8}
Пример #13
0
 def _lock(self, txn_id, op):
     """
     Atomically check if the queue is locked, break an expired lock, lock the queue and
     set the lock-owner and lock-time, and if the operation is enqueue, also increment and
     return the fencing counter.
     Try multiple times if the lock is not available, and wait before subsequent attempt.
     :param txn_id: lock owner id, must be unique among concurrent requests
     :param op: enqueue or dequeue
     :return: dict with head and tail positions on success
         throws ASAborted('Failed to acquire lock') on failure
     """
     metadata_key = (self.namespace, self.name, LargeQueue.META_REC_KEY)
     for _ in range(LargeQueue.LOCK_MAX_RETRIES):
         curr_time_ms = LargeQueue._curr_time_milliseconds()
         predexps = [ predexp.integer_bin("locked"),
                      predexp.integer_value(0),
                      predexp.integer_equal(),
                      predexp.integer_bin("lock-time-ms"),
                      predexp.integer_value(curr_time_ms-LargeQueue.LOCK_EXPIRATION_MS),
                      predexp.integer_less(),
                      predexp.predexp_or(2) ]
         ops = [ op_helpers.read('head-offset'),
                 op_helpers.read('tail-offset'),
                 op_helpers.write('locked', 1),
                 op_helpers.write('lock-owner', txn_id),
                 op_helpers.write('lock-time-ms', curr_time_ms) ]
         if op == LargeQueue.Ops.Enqueue:
             ops.append(op_helpers.increment('fencing-ctr', 1))
             ops.append(op_helpers.read('fencing-ctr'))
         try:
             _, _, record = self.client.operate(metadata_key, ops, policy={'predexp': predexps})
         except exception.FilteredOut as ex:     # predexp failed
             time.sleep(LargeQueue.LOCK_POLL_WAIT_MS/1000.0)
             continue
         return record
     raise ASAborted('Failed to acquire lock')
    def test_pos_operate_incr_with_geospatial_new_record(self):
        """
        Invoke operate() with incr command on a new record
        """
        key = ('test', 'demo', 'geospatial_key')

        llist = [
            operations.increment("geospatial", aerospike.GeoJSON({"type": "Point", "coordinates":
                                          [42.34, 58.62]})),
            operations.read("geospatial")
        ]

        _, _, bins = TestOperate.client_no_typechecks.operate(key, llist)

        assert bins['geospatial'].unwrap() == {
            'coordinates': [42.34, 58.62], 'type': 'Point'}
        TestOperate.client_no_typechecks.remove(key)
    def test_predexp_key_operate_record_void_time(self):
        """
        Invoke the C client aerospike_key_operate with a rec_void_time predexp.
        """

        for i in range(5):
            key = 'test', 'pred_ttl', i
            self.as_connection.put(key, {'time': 'earlier'}, meta={'ttl': 100})

        # 150 second range for record TTLs should be enough, we are storing with
        # Current time + 100s and current time +5000s, so only one of the group should be found
        void_time_range_start = (10**9) * int(time.time() + 50)
        void_time_range_end = (10**9) * int(time.time() + 150)

        for i in range(5, 10):
            key = 'test', 'pred_ttl', i
            self.as_connection.put(key, {'time': 'later'}, meta={'ttl': 1000})

        results = []

        predexp = [
            as_predexp.rec_void_time(),
            as_predexp.integer_value(void_time_range_start),
            as_predexp.integer_greater(),
            as_predexp.rec_void_time(),
            as_predexp.integer_value(void_time_range_end),
            as_predexp.integer_less(),
            as_predexp.predexp_and(2)
        ]

        ops = [operations.read('time')]

        for i in range(10):
            try:
                key = 'test', 'pred_ttl', i
                _, _, res = self.as_connection.operate(
                    key, ops, policy={'predexp': predexp})
                results.append(res)
            except:
                pass
            self.as_connection.remove(key)

        assert len(results) == 5
        for res in results:
            assert res['time'] == 'earlier'
    def test_pos_operate_with_policy_gen_GT(self):
        """
        Invoke operate() with gen GT positive.
        """
        key = ('test', 'demo', 1)
        policy = {'gen': aerospike.POLICY_GEN_GT}
        _, meta = self.as_connection.exists(key)
        gen = meta['gen']
        meta = {'gen': gen + 5}

        llist = [
            operations.append("name", "aa"),
            operations.increment("age", 3),
            operations.read("name")
        ]
        _, _, bins = self.as_connection.operate(key, llist, meta, policy)

        assert bins == {'name': 'name1aa'}
    def test_pos_operate_write_set_to_aerospike_null(self):
        """
        Invoke operate() with write command with bin set to aerospike_null
        """
        key = ('test', 'demo', 'null_record')

        bins = {"name": "John", "no": 3}

        self.as_connection.put(key, bins)

        llist = [
            operations.write("no", aerospike.null()),
            operations.read("no")
        ]

        _, _, bins = self.as_connection.operate(key, llist)
        assert {} == bins

        self.as_connection.remove(key)
    def test_pos_operate_write_set_to_aerospike_null(self):
        """
        Invoke operate() with write command with bin set to aerospike_null
        """
        key = ('test', 'demo', 'null_record')

        bins = {"name": "John", "no": 3}

        self.as_connection.put(key, bins)

        llist = [
            operations.write("no", aerospike.null()),
            operations.read("no")
        ]

        _, _, bins = self.as_connection.operate(key, llist)
        assert {} == bins

        self.as_connection.remove(key)
    def test_pos_operate_with_policy_gen_GT(self):
        """
        Invoke operate() with gen GT positive.
        """
        key = ('test', 'demo', 1)
        policy = {
            'gen': aerospike.POLICY_GEN_GT
        }
        _, meta = self.as_connection.exists(key)
        gen = meta['gen']
        meta = {'gen': gen + 5}

        llist = [
            operations.append("name", "aa"),
            operations.increment("age", 3),
            operations.read("name")
        ]
        _, _, bins = self.as_connection.operate(
            key, llist, meta, policy)

        assert bins == {'name': 'name1aa'}
    def test_pos_operate_with_correct_policy(self):
        """
        Invoke operate() with correct policy
        """
        key = ('test', 'demo', 1)
        policy = {
            'timeout': 1000,
            'key': aerospike.POLICY_KEY_SEND,
            'commit_level': aerospike.POLICY_COMMIT_LEVEL_MASTER
        }

        llist = [
            operations.append("name", "aa"),
            operations.increment("age", 3),
            operations.read("name")
        ]

        _, _, bins = self.as_connection.operate(key, llist, {}, policy)

        assert bins == {'name': 'name1aa'}

        self.as_connection.remove(key)
    def test_pos_operate_with_correct_policy(self):
        """
        Invoke operate() with correct policy
        """
        key = ('test', 'demo', 1)
        policy = {
            'timeout': 1000,
            'key': aerospike.POLICY_KEY_SEND,
            'commit_level': aerospike.POLICY_COMMIT_LEVEL_MASTER
        }

        llist = [
            operations.append("name", "aa"),
            operations.increment("age", 3),
            operations.read("name")
        ]

        _, _, bins = self.as_connection.operate(key, llist, {}, policy)

        assert bins == {'name': 'name1aa'}

        self.as_connection.remove(key)
    def test_predexp_key_operate_record_last_updated(self):
        """
        Invoke the C client aerospike_key_operate with a record_last_updated predexp.
        """

        for i in range(5):
            key = 'test', 'pred_lut', i
            self.as_connection.put(key, {'time': 'earlier'})

        cutoff_nanos = (10**9) * int(time.time() + 2)
        time.sleep(5)

        for i in range(5, 10):
            key = 'test', 'pred_lut', i
            self.as_connection.put(key, {'time': 'later'})

        results = []

        predexp = [
            as_predexp.rec_last_update(),
            as_predexp.integer_value(cutoff_nanos),
            as_predexp.integer_less()
        ]

        ops = [operations.read('time')]

        for i in range(10):
            try:
                key = 'test', 'pred_lut', i
                _, _, res = self.as_connection.operate(
                    key, ops, policy={'predexp': predexp})
                results.append(res)
            except:
                pass
            self.as_connection.remove(key)

        assert len(results) == 5
        for res in results:
            assert res['time'] == 'earlier'
    def test_expressions_key_operate_record_void_time(self):
        """
        Invoke the C client aerospike_key_operate with a rec_void_time expressions.
        """

        for i in range(5):
            key = 'test', 'pred_ttl', i
            self.as_connection.put(key, {'time': 'earlier'}, meta={'ttl': 100})

        # 150 second range for record TTLs should be enough, we are storing with
        # Current time + 100s and current time +5000s, so only one of the group should be found
        void_time_range_start = (10**9) * int(time.time() + 50)
        void_time_range_end = (10**9) * int(time.time() + 150)

        for i in range(5, 10):
            key = 'test', 'pred_ttl', i
            self.as_connection.put(key, {'time': 'later'}, meta={'ttl': 1000})

        results = []

        expr = exp.And(exp.GT(exp.VoidTime(), void_time_range_start),
                       exp.LT(exp.VoidTime(), void_time_range_end)).compile()

        ops = [operations.read('time')]

        for i in range(10):
            try:
                key = 'test', 'pred_ttl', i
                _, _, res = self.as_connection.operate(
                    key, ops, policy={'expressions': expr})
                results.append(res)
            except:
                pass
            self.as_connection.remove(key)

        assert len(results) == 5
        for res in results:
            assert res['time'] == 'earlier'
    def test_pos_operate_incr_with_geospatial_new_record(self):
        """
        Invoke operate() with incr command on a new record
        """
        key = ('test', 'demo', 'geospatial_key')

        llist = [
            operations.increment(
                "geospatial",
                aerospike.GeoJSON({
                    "type": "Point",
                    "coordinates": [42.34, 58.62]
                })),
            operations.read("geospatial")
        ]

        _, _, bins = TestOperate.client_no_typechecks.operate(key, llist)

        assert bins['geospatial'].unwrap() == {
            'coordinates': [42.34, 58.62],
            'type': 'Point'
        }
        TestOperate.client_no_typechecks.remove(key)
class TestOperate(object):
    def setup_class(cls):
        """
        Setup class.
        """
        # hostlist, user, password = TestBaseClass.get_hosts()

        # config_no_typechecks = {'hosts': hostlist, 'strict_types': False}
        # if user is None and password is None:
        #     TestOperate.client_no_typechecks = aerospike.client(
        #         config_no_typechecks).connect()
        # else:
        #     TestOperate.client_no_typechecks = aerospike.client(
        #         config_no_typechecks).connect(user, password)
        cls.client_no_typechecks = TestBaseClass.get_new_connection(
            {'strict_types': False})

    def teardown_class(cls):
        TestOperate.client_no_typechecks.close()

    @pytest.fixture(autouse=True)
    def setup(self, request, as_connection):
        """
        Setup Method
        """
        keys = []

        for i in range(5):
            key = ('test', 'demo', i)
            rec = {'name': 'name%s' % (str(i)), 'age': i}
            as_connection.put(key, rec)

        key = ('test', 'demo', 6)
        rec = {"age": 6.3}
        as_connection.put(key, rec)
        keys.append(key)

        key = ('test', 'demo', 'bytearray_key')
        rec = {"bytearray_bin": bytearray("asd;as[d'as;d", "utf-8")}
        as_connection.put(key, rec)

        keys.append(key)

        key = ('test', 'demo', 'bytes_key')
        rec = {"bytes_bin": b''}
        as_connection.put(key, rec)

        keys.append(key)

        key = ('test', 'demo', 'list_key')
        rec = {"int_bin": [1, 2, 3, 4], "string_bin": ['a', 'b', 'c', 'd']}
        as_connection.put(key, rec)

        keys.append(key)

        key = ('test', 'demo', 'existing_key')
        rec = {
            "dict": {
                "a": 1
            },
            "bytearray": bytearray("abc", "utf-8"),
            "float": 3.4,
            "list": ['a']
        }
        as_connection.put(key, rec)

        keys.append(key)

        def teardown():
            """
            Teardown Method
            """
            for i in range(5):
                key = ('test', 'demo', i)
                try:
                    as_connection.remove(key)
                except e.RecordNotFound:
                    pass
            for key in keys:
                try:
                    as_connection.remove(key)
                except e.RecordNotFound:
                    pass

        request.addfinalizer(teardown)

    @pytest.mark.parametrize(
        "key, llist, expected",
        [
            (('test', 'demo', 1), [
                operations.prepend("name", u"ram"),
                operations.increment("age", 3),
                operations.read("name")
            ], {
                'name': 'ramname1'
            }),
            (
                ('test', 'demo', 1),  # with_write_float_value
                [
                    operations.write("write_bin", {"no": 89.8}),
                    operations.read("write_bin")
                ],
                {
                    'write_bin': {
                        u'no': 89.8
                    }
                }),
            (
                ('test', 'demo', 1),  # write positive
                [
                    operations.write("write_bin", {"no": 89}),
                    operations.read("write_bin")
                ],
                {
                    'write_bin': {
                        u'no': 89
                    }
                }),
            (
                ('test', 'demo', 1),  # write_tuple_positive
                [
                    operations.write("write_bin", ('a', 'b', 'c')),
                    operations.read("write_bin")
                ],
                {
                    'write_bin': ('a', 'b', 'c')
                }),
            (
                ('test', 'demo', 1),  # with_bin_bytearray
                [
                    operations.prepend("asd[;asjk", "ram"),
                    operations.read("asd[;asjk")
                ],
                {
                    'asd[;asjk': 'ram'
                }),
            (
                ('test', 'demo',
                 'bytearray_key'),  # with_operator append_val bytearray
                [
                    operations.append("bytearray_bin", bytearray(
                        "abc", "utf-8")),
                    operations.read("bytearray_bin")
                ],
                {
                    'bytearray_bin': bytearray("asd;as[d'as;dabc", "utf-8")
                }),
            (
                ('test', 'demo', 'bytearray_new'
                 ),  # with_operator append_val bytearray_newrecord
                [
                    operations.append("bytearray_bin",
                                      bytearray("asd;as[d'as;d", "utf-8")),
                    operations.read("bytearray_bin")
                ],
                {
                    'bytearray_bin': bytearray("asd;as[d'as;d", "utf-8")
                }),
            (
                ('test', 'demo',
                 'bytes_key'),  # with_operator append_val bytes
                [
                    operations.append("bytes_bin", b"abc"),
                    operations.read("bytes_bin")
                ],
                {
                    'bytes_bin': b'abc'
                }),
            (
                ('test', 'demo',
                 'bytes_new'),  # with_operator append_val bytes_newrecord
                [
                    operations.append("bytes_bin", b"asd;as[d'as;d"),
                    operations.read("bytes_bin")
                ],
                {
                    'bytes_bin': b"asd;as[d'as;d"
                }),
            (
                ('test', 'demo',
                 'bytearray_key'),  # with_operatorprepend_valbytearray
                [
                    operations.prepend("bytearray_bin",
                                       bytearray("abc", "utf-8")),
                    operations.read("bytearray_bin")
                ],
                {
                    'bytearray_bin': bytearray("abcasd;as[d'as;d", "utf-8")
                }),
            (
                ('test', 'demo', 'bytearray_new'
                 ),  # with_operatorprepend_valbytearray_newrecord
                [
                    operations.prepend("bytearray_bin",
                                       bytearray("asd;as[d'as;d", "utf-8")),
                    operations.read("bytearray_bin")
                ],
                {
                    'bytearray_bin': bytearray("asd;as[d'as;d", "utf-8")
                }),
            (
                ('test', 'demo',
                 'bytes_key'),  # with_operator prepend_val bytes
                [
                    operations.prepend("bytes_bin", b"abc"),
                    operations.read("bytes_bin")
                ],
                {
                    'bytes_bin': b'abc'
                }),
            (
                ('test', 'demo',
                 'bytes_new'),  # with_operator prepend_val bytes_newrecord
                [
                    operations.prepend("bytes_bin", b"asd;as[d'as;d"),
                    operations.read("bytes_bin")
                ],
                {
                    'bytes_bin': b"asd;as[d'as;d"
                })
        ])
    def test_pos_operate_with_correct_paramters(self, key, llist, expected):
        """
        Invoke operate() with correct parameters
        """

        key, _, bins = self.as_connection.operate(key, llist)

        assert bins == expected
        self.as_connection.remove(key)

    @pytest.mark.parametrize("key, llist, expected", [
        (('test', 'demo', 1), [
            operations.write("write_bin", {"no": 89.8}),
            operations.write("write_bin2", {"no": 100}),
            operations.delete(),
        ], {}),
    ])
    def test_pos_operate_delete_with_correct_paramters(self, key, llist,
                                                       expected):
        """
        Invoke operate() with correct parameters
        """

        key, _, bins = self.as_connection.operate(key, llist)

        assert bins == expected

    def test_pos_operate_with_increment_positive_float_value(self):
        """
        Invoke operate() with correct parameters
        """
        if TestOperate.skip_old_server is True:
            pytest.skip("Server does not support increment on float type")
        key = ('test', 'demo', 6)
        llist = [operations.increment("age", 3.5), operations.read("age")]

        _, _, bins = self.as_connection.operate(key, llist)

        assert bins == {'age': 9.8}

    def test_pos_operate_with_correct_policy(self):
        """
        Invoke operate() with correct policy
        """
        key = ('test', 'demo', 1)
        policy = {
            'timeout': 1000,
            'key': aerospike.POLICY_KEY_SEND,
            'commit_level': aerospike.POLICY_COMMIT_LEVEL_MASTER
        }

        llist = [
            operations.append("name", "aa"),
            operations.increment("age", 3),
            operations.read("name")
        ]

        _, _, bins = self.as_connection.operate(key, llist, {}, policy)

        assert bins == {'name': 'name1aa'}

        self.as_connection.remove(key)

    @pytest.mark.parametrize("key, policy, meta, llist", [
        (('test', 'demo', 1), {
            'total_timeout': 1000,
            'key': aerospike.POLICY_KEY_SEND,
            'gen': aerospike.POLICY_GEN_IGNORE,
            'commit_level': aerospike.POLICY_COMMIT_LEVEL_ALL
        }, {
            'gen': 10,
            'ttl': 1200
        }, [
            operations.append("name", "aa"),
            operations.increment("age", 3),
            operations.read("name")
        ]),
    ])
    def test_pos_operate_with_policy_gen_ignore(self, key, policy, meta,
                                                llist):
        """
        Invoke operate() with gen ignore.
        """

        key, meta, bins = self.as_connection.operate(key, llist, meta, policy)

        assert bins == {'name': 'name1aa'}

    def test_pos_operate_with_policy_gen_EQ(self):
        """
        Invoke operate() with gen EQ positive.
        """
        key = ('test', 'demo', 1)
        policy = {'gen': aerospike.POLICY_GEN_EQ}
        (key, meta) = self.as_connection.exists(key)
        gen = meta['gen']
        meta = {'gen': gen}

        llist = [
            operations.append("name", "aa"),
            operations.increment("age", 3),
            operations.read("name")
        ]
        (key, meta, bins) = self.as_connection.operate(key, llist, meta,
                                                       policy)

        assert bins == {'name': 'name1aa'}

    @pytest.mark.parametrize("key, llist",
                             [(('test', 'demo', 1), [operations.touch(4000)]),
                              (('test', 'demo', 1), [operations.touch(4000)])])
    def test_pos_operate_touch_operation_with_bin_and_value_combination(
            self, key, llist):
        """
        Invoke operate() with touch value with bin and value combination.
        """

        self.as_connection.operate(key, llist)

        (key, meta) = self.as_connection.exists(key)

        assert meta['ttl'] is not None

    def test_pos_operate_with_policy_gen_EQ_not_equal(self):
        """
        Invoke operate() with a mismatched generation, and verify
        it does not succeed
        """
        key = ('test', 'demo', 1)
        policy = {'gen': aerospike.POLICY_GEN_EQ}

        (_, meta) = self.as_connection.exists(key)
        gen = meta['gen']
        meta = {
            'gen': gen + 5,
        }
        llist = [
            operations.append("name", "aa"),
            operations.increment("age", 3),
        ]

        with pytest.raises(e.RecordGenerationError):
            self.as_connection.operate(key, llist, meta, policy)

        _, _, bins = self.as_connection.get(key)
        assert bins == {"age": 1, 'name': 'name1'}

    def test_pos_operate_with_policy_gen_GT_mismatch(self):
        """
        Invoke operate() with gen GT policy, with amatching generation
        then verify that the operation was rejected properly
        """
        key = ('test', 'demo', 1)
        policy = {'gen': aerospike.POLICY_GEN_GT}
        _, meta = self.as_connection.exists(key)
        gen = meta['gen']
        meta = {'gen': gen}

        llist = [
            operations.append("name", "aa"),
            operations.increment("age", 3)
        ]

        with pytest.raises(e.RecordGenerationError):
            self.as_connection.operate(key, llist, meta, policy)

        _, _, bins = self.as_connection.get(key)
        assert bins == {'age': 1, 'name': 'name1'}

    def test_pos_operate_touch_with_meta(self):
        """
        Invoke operate() OPERATE_TOUCH using meta to pass in ttl.
        """
        key = ('test', 'demo', 1)
        meta = {'ttl': 1200}

        llist = [operations.touch()]

        self.as_connection.operate(key, llist, meta)

        _, meta = self.as_connection.exists(key)

        assert meta['ttl'] <= 1200 and meta['ttl'] >= 1150

    def test_pos_operate_with_policy_gen_GT(self):
        """
        Invoke operate() with gen GT positive.
        """
        key = ('test', 'demo', 1)
        policy = {'gen': aerospike.POLICY_GEN_GT}
        _, meta = self.as_connection.exists(key)
        gen = meta['gen']
        meta = {'gen': gen + 5}

        llist = [
            operations.append("name", "aa"),
            operations.increment("age", 3),
            operations.read("name")
        ]
        _, _, bins = self.as_connection.operate(key, llist, meta, policy)

        assert bins == {'name': 'name1aa'}

    def test_pos_operate_with_nonexistent_key(self):
        """
        Invoke operate() with non-existent key
        """
        new_key = ('test', 'demo', "key11")
        llist = [operations.prepend("loc", "mumbai"), operations.read("loc")]
        _, _, bins = self.as_connection.operate(new_key, llist)

        assert bins == {'loc': 'mumbai'}
        self.as_connection.remove(new_key)

    def test_pos_operate_with_nonexistent_bin(self):
        """
        Invoke operate() with non-existent bin
        """
        key = ('test', 'demo', 1)
        llist = [operations.append("addr", "pune"), operations.read("addr")]
        _, _, bins = self.as_connection.operate(key, llist)

        assert bins == {'addr': 'pune'}

    def test_pos_operate_increment_nonexistent_key(self):
        """
        Invoke operate() with increment with nonexistent_key
        """
        key = ('test', 'demo', "non_existentkey")
        llist = [operations.increment("age", 5)]

        self.as_connection.operate(key, llist)

        _, _, bins = self.as_connection.get(key)

        assert bins == {"age": 5}

        self.as_connection.remove(key)

    def test_pos_operate_with_correct_paramters_without_connection(self):
        """
        Invoke operate() with correct parameters without connection
        """
        key = ('test', 'demo', 1)
        config = {'hosts': [('127.0.0.1', 3000)]}
        client1 = aerospike.client(config)
        llist = [operations.touch()]

        with pytest.raises(e.ClusterError):
            client1.operate(key, llist)

    def test_pos_operate_write_set_to_aerospike_null(self):
        """
        Invoke operate() with write command with bin set to aerospike_null
        """
        key = ('test', 'demo', 'null_record')

        bins = {"name": "John", "no": 3}

        self.as_connection.put(key, bins)

        llist = [
            operations.write("no", aerospike.null()),
            operations.read("no")
        ]

        _, _, bins = self.as_connection.operate(key, llist)
        assert {} == bins

        self.as_connection.remove(key)

    @pytest.mark.parametrize(
        "key, llist, expected",
        [
            (
                ('test', 'demo', 'prepend_int'),  # prepend_with_int
                [operations.prepend("age", 4),
                 operations.read("age")],
                {
                    'age': 4
                }),
            (
                ('test', 'demo', 'append_dict'),  # append_with_dict
                [
                    operations.append("dict", {
                        "a": 1,
                        "b": 2
                    }),
                    operations.read("dict")
                ],
                {
                    'dict': {
                        "a": 1,
                        "b": 2
                    }
                }),
            (
                ('test', 'demo', 'incr_string'),  # incr_with_string
                [
                    operations.increment("name", "aerospike"),
                    operations.read("name")
                ],
                {
                    'name': 'aerospike'
                }),
        ])
    def test_pos_operate_new_record(self, key, llist, expected):
        """
        Invoke operate() with prepend command on a new record
        """
        _, _, bins = TestOperate.client_no_typechecks.operate(key, llist)
        assert expected == bins
        TestOperate.client_no_typechecks.remove(key)

    @pytest.mark.parametrize(
        "key, llist",
        [
            (('test', 'demo', 1),
             [operations.prepend("age", 4),
              operations.read("age")]),
            (
                ('test', 'demo', 'existing_key'),  # Existing list
                [operations.prepend("list", ['c']),
                 operations.read("list")]),
            (
                ('test', 'demo', 'existing_key'),  # Existing dict
                [operations.append("dict", {"c": 2}),
                 operations.read("dict")]),
            (
                ('test', 'demo', 'existing_key'),  # Exiting float
                [operations.append("float", 3.4),
                 operations.read("float")]),
            (
                ('test', 'demo', 1),  # Existing string
                [
                    operations.increment("name", "aerospike"),
                    operations.read("name")
                ]),
            (
                ('test', 'demo', 'existing_key'),  # Existing Bytearray
                [
                    operations.increment("bytearray", bytearray(
                        "abc", "utf-8")),
                    operations.read("bytearray")
                ]),
        ])
    def test_pos_operate_prepend_with_existing_record(self, key, llist):
        """
        Invoke operate() with prepend command on a existing record
        """

        with pytest.raises(e.BinIncompatibleType):
            TestOperate.client_no_typechecks.operate(key, llist)

        TestOperate.client_no_typechecks.remove(key)

    def test_pos_operate_incr_with_geospatial_new_record(self):
        """
        Invoke operate() with incr command on a new record
        """
        key = ('test', 'demo', 'geospatial_key')

        llist = [
            operations.increment(
                "geospatial",
                aerospike.GeoJSON({
                    "type": "Point",
                    "coordinates": [42.34, 58.62]
                })),
            operations.read("geospatial")
        ]

        _, _, bins = TestOperate.client_no_typechecks.operate(key, llist)

        assert bins['geospatial'].unwrap() == {
            'coordinates': [42.34, 58.62],
            'type': 'Point'
        }
        TestOperate.client_no_typechecks.remove(key)

    def test_pos_operate_with_bin_length_extra_nostricttypes(self):
        """
        Invoke operate() with bin length extra. Strict types disabled
        """
        key = ('test', 'demo', 1)

        max_length = 'a' * 21

        llist = [
            operations.prepend("name", "ram"),
            operations.increment(max_length, 3)
        ]

        TestOperate.client_no_typechecks.operate(key, llist)

        _, _, bins = TestOperate.client_no_typechecks.get(key)

        assert bins == {"name": "ramname1", "age": 1}

    def test_pos_operate_prepend_set_to_aerospike_null(self):
        """
        Invoke operate() with prepend command with bin set to aerospike_null
        """
        key = ('test', 'demo', 'null_record')

        bins = {"name": "John", "no": 3}

        assert 0 == self.as_connection.put(key, bins)

        (key, _, bins) = self.as_connection.get(key)

        assert {"name": "John", "no": 3} == bins

        llist = [
            operations.prepend("no", aerospike.null()),
            operations.read("no")
        ]

        try:
            (key, _, bins) = self.as_connection.operate(key, llist)

        except e.InvalidRequest as exception:
            assert exception.code == 4
        self.as_connection.remove(key)

    @pytest.mark.parametrize(
        "list, result, bin, expected",
        [
            ([
                list_operations.list_append("int_bin", 7),
                list_operations.list_get("int_bin", 4)
            ], {
                "int_bin": 7
            }, "int_bin", [1, 2, 3, 4, 7]),
            ([
                list_operations.list_append_items("int_bin", [7, 9]),
                list_operations.list_get_range("int_bin", 3, 3),
            ], {
                'int_bin': [4, 7, 9]
            }, "int_bin", [1, 2, 3, 4, 7, 9]),
            ([
                list_operations.list_insert("int_bin", 2, 7),
                list_operations.list_pop("int_bin", 2)
            ], {
                'int_bin': 7
            }, "int_bin", [1, 2, 3, 4]),
            ([
                list_operations.list_insert_items("int_bin", 2, [7, 9]),
                list_operations.list_pop_range("int_bin", 2, 2)
            ], {
                'int_bin': [7, 9]
            }, "int_bin", [1, 2, 3, 4]),
            ([
                list_operations.list_set("int_bin", 2, 18),
                list_operations.list_get("int_bin", 2)
            ], {
                'int_bin': 18
            }, "int_bin", [1, 2, 18, 4]),
            (
                [
                    list_operations.list_set("int_bin", 6, 10),
                    list_operations.list_get("int_bin", 6)
                ],
                {
                    'int_bin': 10
                },
                "int_bin",
                [1, 2, 3, 4, None, None, 10
                 ]  # Inserting outside of the range adds nils in between
            )
        ])
    def test_pos_operate_with_list_addition_operations(self, list, result, bin,
                                                       expected):
        """
        Invoke operate() with list addition operations
        """
        key = ('test', 'demo', 'list_key')

        key, _, bins = self.as_connection.operate(key, list)

        assert bins == result

        key, _, bins = self.as_connection.get(key)
        assert bins[bin] == expected

    @pytest.mark.parametrize(
        "list, bin, expected",
        [([list_operations.list_remove("int_bin", 2)], "int_bin", [1, 2, 4]),
         ([list_operations.list_remove_range("int_bin", 2, 2)
           ], "int_bin", [1, 2]),
         ([list_operations.list_trim("int_bin", 2, 2)], "int_bin", [3, 4]),
         ([list_operations.list_clear("int_bin")], "int_bin", [])])
    def test_pos_operate_with_list_remove_operations(self, list, bin,
                                                     expected):
        """
        Invoke operate() with list remove operations
        """
        key = ('test', 'demo', 'list_key')

        self.as_connection.operate(key, list)

        key, _, bins = self.as_connection.get(key)

        assert bins[bin] == expected

    def test_pos_operate_with_list_size(self):
        """
        Invoke operate() with list_size operation
        """
        key = ('test', 'demo', 'list_key')
        list = [list_operations.list_size("int_bin")]

        key, _, bins = self.as_connection.operate(key, list)

        assert bins == {'int_bin': 4}

    def test_list_increment_with_valid_value(self):
        '''
        previous list was [1, 2, 3, 4]
        new should be [1, 2, 23, 4]
        '''
        key = ('test', 'demo', 'list_key')
        list = [list_operations.list_increment("int_bin", 2, 20)]

        _, _, bins = self.as_connection.operate(key, list)

        assert bins == {'int_bin': 23}
        _, _, bins = self.as_connection.get(key)

        assert bins['int_bin'] == [1, 2, 23, 4]

    def test_list_increment_with_incorrect_value_type(self):
        '''
        previous list was [1, 2, 3, 4]
        new should be [1, 2, 23, 4]
        '''
        key = ('test', 'demo', 'list_key')
        list = [list_operations.list_increment("int_bin", 2, "twenty")]

        with pytest.raises(e.AerospikeError):
            self.as_connection.operate(key, list)

    def test_pos_operate_with_list_get_range_val_out_of_bounds(self):
        """
        Invoke operate() with list_get_range operation and value out of bounds
        """
        key = ('test', 'demo', 'list_key')
        list = [list_operations.list_get_range("int_bin", 2, 9)]

        _, _, bins = self.as_connection.operate(key, list)

        assert bins == {'int_bin': [3, 4]}

    def test_pos_operate_with_list_trim_val_with_negative_value(self):
        """
        Invoke operate() with list_trimoperation and value is negative
        """
        key = ('test', 'demo', 'list_key')
        list = [list_operations.list_trim("int_bin", 1, -9)]

        self.as_connection.operate(key, list)

        _, _, bins = self.as_connection.get(key)

        assert bins['int_bin'] == [2, 3, 4]

    def test_pos_operate_with_list_insert_index_negative(self):
        """
        Invoke operate() with list_insert and item index is a negative value
        """
        key = ('test', 'demo', 'list_key')
        list = [list_operations.list_insert("int_bin", -2, 9)]

        self.as_connection.operate(key, list)

        _, _, bins = self.as_connection.get(key)

        assert bins['int_bin'] == [1, 2, 9, 3, 4]

    @pytest.mark.parametrize("list, result, bin, expected", [
        ([
            list_operations.list_append("string_bin", {"new_val": 1}),
            list_operations.list_get("string_bin", 4)
        ], {
            "string_bin": {
                "new_val": 1
            }
        }, "string_bin", ['a', 'b', 'c', 'd', {
            'new_val': 1
        }]),
        ([
            list_operations.list_append_items("string_bin", [['z', 'x'],
                                                             ('y', 'w')]),
            list_operations.list_get_range("string_bin", 3, 3)
        ], {
            "string_bin": ['d', ['z', 'x'], ('y', 'w')]
        }, "string_bin", ['a', 'b', 'c', 'd', ['z', 'x'], ('y', 'w')]),
        ([
            list_operations.list_insert("string_bin", 2, True),
            list_operations.list_pop("string_bin", 2)
        ], {
            'string_bin': True
        }, "string_bin", ['a', 'b', 'c', 'd']),
        ([
            list_operations.list_insert_items(
                "string_bin", 2, [bytearray("abc", "utf-8"), u"xyz"]),
            list_operations.list_pop_range("string_bin", 2, 2)
        ], {
            'string_bin': [bytearray(b'abc'), 'xyz']
        }, "string_bin", ['a', 'b', 'c', 'd']),
    ])
    def test_pos_operate_with_list_operations_different_datatypes(
            self, list, result, bin, expected):
        """
        Invoke operate() with list operations using different datatypes
        """
        key = ('test', 'demo', 'list_key')

        _, _, bins = self.as_connection.operate(key, list)

        assert bins == result

        _, _, bins = self.as_connection.get(key)

        assert bins[bin] == expected

    # Negative Tests
    def test_neg_operate_with_no_parameters(self):
        """
        Invoke operate() without any mandatory parameters.
        """
        with pytest.raises(TypeError) as typeError:
            self.as_connection.operate()
        assert "key" in str(typeError.value)

    @pytest.mark.parametrize("key, llist, expected",
                             [(('test', 'demo', 'bad_key'), [
                                 operations.delete(),
                             ], e.RecordNotFound)])
    def test_pos_operate_delete_with_incorrect_paramters(
            self, key, llist, expected):
        """
        Invoke operate() with correct parameters
        """

        with pytest.raises(expected):
            self.as_connection.operate(key, llist)

    def test_neg_operate_list_operation_bin_notlist(self):
        """
        Invoke operate() with a list operation and bin does not contain list
        """
        key = ('test', 'demo', 1)
        list = [list_operations.list_insert("age", 2, 9)]

        with pytest.raises(e.BinIncompatibleType):
            self.as_connection.operate(key, list)

    def test_neg_operate_append_items_not_a_list(self):
        """
        Invoke operate() with list addition operations negative
        """
        key = ('test', 'demo', 1)
        ops = [list_operations.list_append_items("int_bin", 7)]
        with pytest.raises(e.ParamError):
            self.as_connection.operate(key, ops)

    @pytest.mark.parametrize("list",
                             [([list_operations.list_get("int_bin", 7)]),
                              ([
                                  list_operations.list_clear("int_bin"),
                                  list_operations.list_pop("int_bin", 2)
                              ]),
                              ([
                                  list_operations.list_clear("int_bin"),
                                  list_operations.list_remove("int_bin", 2)
                              ])])
    def test_neg_operate_list_invalid_requests(self, list):
        """
        Invoke operate() with list addition operations negative
        """
        key = ('test', 'demo', 'list_key')
        with pytest.raises(e.OpNotApplicable):
            self.as_connection.operate(key, list)

    def test_neg_operate_with_bin_length_extra(self):
        """
        Invoke operate() with bin length extra. Strict types enabled
        """
        key = ('test', 'demo', 1)

        max_length = 'a' * 21

        llist = [
            operations.prepend("name", "ram"),
            operations.increment(max_length, 3)
        ]

        with pytest.raises(e.BinNameError):
            self.as_connection.operate(key, llist)

    def test_neg_operate_empty_string_key(self):
        """
        Invoke operate() with empty string key
        """
        llist = [operations.prepend("name", "ram")]
        with pytest.raises(e.ParamError):
            self.as_connection.operate("", llist)

    def test_neg_operate_with_extra_parameter(self):
        """
        Invoke operate() with extra parameter.
        """
        key = ('test', 'demo', 1)
        policy = {'timeout': 1000}
        llist = [operations.prepend("name", "ram")]
        with pytest.raises(TypeError) as typeError:
            self.as_connection.operate(key, llist, {}, policy, "")

    def test_neg_operate_policy_is_string(self):
        """
        Invoke operate() with policy is string
        """
        key = ('test', 'demo', 1)
        llist = [operations.prepend("name", "ram")]
        try:
            self.as_connection.operate(key, llist, {}, "")

        except e.ParamError as exception:
            assert exception.code == -2

    def test_neg_operate_key_is_none(self):
        """
        Invoke operate() with key is none
        """
        llist = [operations.prepend("name", "ram")]
        try:
            self.as_connection.operate(None, llist)

        except e.ParamError as exception:
            assert exception.code == -2

    def test_neg_operate_append_value_integer(self):
        """
        Invoke operate() with append value is of type integer
        """
        key = ('test', 'demo', 1)
        llist = [operations.append("name", 12)]

        try:
            self.as_connection.operate(key, llist)
        except e.ParamError as exception:
            assert exception.code == -2

    def test_neg_operate_with_incorrect_polic(self):
        """
        Invoke operate() with incorrect policy
        """
        key = ('test', 'demo', 1)
        policy = {'total_timeout': 0.5}
        llist = [operations.prepend("name", "ram")]

        with pytest.raises(e.ParamError):
            self.as_connection.operate(key, llist, {}, policy)
Пример #26
0
        client.put(record_key, record, meta, policy)

        print("---")
        print("OK, 1 record written.")

        _, _, bins = client.get(record_key)

        print("---")
        print("Before operate operation")
        print(bins)

        operation_list = [
            op_helpers.prepend("example_name", "Mr "),
            op_helpers.increment("example_age", 3),
            op_helpers.read("example_name")
        ]

        _, _, bins = client.operate(record_key, operation_list, meta, policy)
        print("---")
        print("Record returned on operate completion")
        print(bins)

        _, _, bins = client.get(record_key)

        print("---")
        print("After operate operation")
        print(bins)

    except Exception as e:
        print("error: {0}".format(e), file=sys.stderr)
Пример #27
0
    try:
        shard_key = shards[random.randrange(0, 5, 1)]
        k, m, b = client.get(shard_key)
        val = list(b.values())[0]
        print("Shard", shard_key[2], "has value", val)
        if not val:
            val = 0
        if val < options.cap:
            # continue and attempt to serve the ad
            print("The shard is under the cap, incrementing its counter")
            client.increment(shard_key, "c", 1, {},
                             {"ttl": aerospike.TTL_DONT_UPDATE})  # aka ttl -2
    except e.RecordNotFound as err:
        ttl = aerospike.TTL_NAMESPACE_DEFAULT  # AKA ttl 0, inherit the default-ttl
        try:
            ops = [oh.increment("c", 1), oh.read("c")]
            print("The shard", shard_key[2],
                  "does not exist yet, initializing it to 1")
            (shard_key, meta, bins) = client.operate(shard_key, ops,
                                                     {"ttl": ttl})
        except e.AerospikeError as err:
            print("Error: {0} [{1}]".format(err.msg, err.code))

print("\nState of the sharded counters")
for i in range(0, 5, 1):
    shard_key = shards[i]
    try:
        k, m, b = client.get(shard_key)
        print("shard", shard_key[2], "=", list(b.values())[0])
    except e.RecordNotFound as err:
        print("shard", shard_key[2], "was never used")
Пример #28
0
except ex.RecordError as e:
    pass

try:
    print("\nremove_by_index_range(bin, index[, returnType, count, context])\n")
    # create a new record with a put. list policy can't be applied outside of
    # list operations, and a new list is unordered by default
    client.put(key, {"l": [1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 10, 12, 13]})
    key, metadata, bins = client.get(key)
    print("{}".format(bins["l"]))
    # [1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 10, 12, 13]

    # demonstrate the meaning of the different return types
    ops = [
        listops.list_remove_by_index_range("l", 6, aerospike.LIST_RETURN_VALUE, 3),
        operations.read("l"),
        listops.list_remove_by_index_range("l", 3, aerospike.LIST_RETURN_COUNT, 3),
        operations.read("l"),
        listops.list_remove_by_index_range("l", 0, aerospike.LIST_RETURN_NONE, 3),
        operations.read("l"),
    ]
    key, metadata, bins = client.operate_ordered(key, ops)
    # in the python client the operate() command returns the result of the last
    # operation on a specific bin, so using operate_ordered instead, which
    # gives the results as ordered (bin-name, result) tuples
    print(
        "\nremove_by_index_range('l', 6, VALUE, 3): {}\nRemaining: {}".format(
            bins[0][1], bins[1][1]
        )
    )
    # remove_by_index_range('l', 6, VALUE, 3): [7, 8, 9]
Пример #29
0
        client.put(record_key, record, meta, policy)

        print("---")
        print("OK, 1 record written.")

        _, _, bins = client.get(record_key)

        print("---")
        print("Before operate operation")
        print(bins)

        operation_list = [
            op_helpers.prepend("example_name", "Mr "),
            op_helpers.increment("example_age", 3),
            op_helpers.read("example_name")
        ]

        _, _, bins = client.operate(
            record_key, operation_list, meta, policy)
        print("---")
        print("Record returned on operate completion")
        print(bins)

        _, _, bins = client.get(record_key)

        print("---")
        print("After operate operation")
        print(bins)

    except Exception as e: