Exemple #1
0
class TestGeospatial(TestBaseClass):

    pytestmark = pytest.mark.skipif(
        TestBaseClass.has_geo_support() == False,
        reason="Server does not support geospatial data.")

    def setup_class(cls):
        """
        Setup method.
        """
        hostlist, user, password = TestBaseClass.get_hosts()
        config = {'hosts': hostlist}
        if user == None and password == None:
            TestGeospatial.client = aerospike.client(config).connect()
        else:
            TestGeospatial.client = aerospike.client(config).connect(
                user, password)
        TestGeospatial.client.index_geo2dsphere_create("test", "demo", "loc",
                                                       "loc_index")

    def teardown_class(cls):
        TestGeospatial.client.index_remove('test', 'loc_index')
        TestGeospatial.client.close()

    def setup_method(self, method):

        self.keys = []
        for i in xrange(10):
            key = ('test', 'demo', i)
            lng = -122 + (0.2 * i)
            lat = 37.5 + (0.2 * i)
            self.geo_object = aerospike.GeoJSON({
                "type": "Point",
                "coordinates": [lng, lat]
            })

            TestGeospatial.client.put(key, {"loc": self.geo_object})
            self.keys.append(key)

    def teardown_method(self, method):
        """
        Teardown method.
        """
        for key in self.keys:
            TestGeospatial.client.remove(key)

    def test_geospatial_put_get_positive(self):
        """
            Perform a get and put with multiple bins including geospatial bin
        """

        key = ('test', 'demo', 'single_geo_put')
        geo_object_single = aerospike.GeoJSON({
            "type": "Point",
            "coordinates": [42.34, 58.62]
        })
        geo_object_dict = aerospike.GeoJSON({
            "type": "Point",
            "coordinates": [56.34, 69.62]
        })

        TestGeospatial.client.put(
            key, {
                "loc": geo_object_single,
                "int_bin": 2,
                "string_bin": "str",
                "dict_bin": {
                    "a": 1,
                    "b": 2,
                    "geo": geo_object_dict
                }
            })

        key, meta, bins = TestGeospatial.client.get(key)

        assert bins == {
            'loc': {
                'coordinates': [42.34, 58.62],
                'type': 'Point'
            },
            "int_bin": 2,
            "string_bin": "str",
            "dict_bin": {
                "a": 1,
                "b": 2,
                "geo": {
                    'coordinates': [56.34, 69.62],
                    'type': 'Point'
                }
            }
        }

        TestGeospatial.client.remove(key)

    def test_geospatial_positive_query(self):
        """
            Perform a positive geospatial query for a polygon
        """
        records = []
        query = TestGeospatial.client.query("test", "demo")

        geo_object2 = aerospike.GeoJSON({
            "type":
            "Polygon",
            "coordinates":
            [[[-122.500000, 37.000000], [-121.000000, 37.000000],
              [-121.000000, 38.080000], [-122.500000, 38.080000],
              [-122.500000, 37.000000]]]
        })

        query.where(p.geo_within("loc", geo_object2.dumps()))

        def callback((key, metadata, record)):
            records.append(record)

        query.foreach(callback)

        assert len(records) == 3
        assert records == [{
            'loc': {
                'coordinates': [-122.0, 37.5],
                'type': 'Point'
            }
        }, {
            'loc': {
                'coordinates': [-121.8, 37.7],
                'type': 'Point'
            }
        }, {
            'loc': {
                'coordinates': [-121.6, 37.9],
                'type': 'Point'
            }
        }]

    def test_geospatial_positive_query_outside_shape(self):
        """
            Perform a positive geospatial query for polygon where all points are
            outside polygon
        """
        records = []
        query = TestGeospatial.client.query("test", "demo")

        geo_object2 = aerospike.GeoJSON({
            "type":
            "Polygon",
            "coordinates":
            [[[-126.500000, 37.000000], [-124.000000, 37.000000],
              [-124.000000, 38.080000], [-126.500000, 38.080000],
              [-126.500000, 37.000000]]]
        })

        query.where(p.geo_within("loc", geo_object2.dumps()))

        def callback((key, metadata, record)):
            records.append(record)

        query.foreach(callback)

        assert len(records) == 0

    def test_geospatial_positive_query_without_set(self):
        """
            Perform a positive geospatial query for a polygon without a set
        """
        keys = []
        for i in xrange(1, 10):
            key = ('test', None, i)
            lng = -122 + (0.2 * i)
            lat = 37.5 + (0.2 * i)
            geo_object = aerospike.GeoJSON({
                "type": "Point",
                "coordinates": [lng, lat]
            })

            TestGeospatial.client.put(key, {"loc": geo_object})
            keys.append(key)

        TestGeospatial.client.index_geo2dsphere_create("test", None, "loc",
                                                       "loc_index_no_set")
        records = []
        query = TestGeospatial.client.query("test", None)

        geo_object2 = aerospike.GeoJSON({
            "type":
            "Polygon",
            "coordinates":
            [[[-122.500000, 37.000000], [-121.000000, 37.000000],
              [-121.000000, 38.080000], [-122.500000, 38.080000],
              [-122.500000, 37.000000]]]
        })

        query.where(p.geo_within("loc", geo_object2.dumps()))

        def callback((key, metadata, record)):
            records.append(record)

        query.foreach(callback)

        TestGeospatial.client.index_remove('test', 'loc_index_no_set')
        for key in keys:
            TestGeospatial.client.remove(key)

        assert len(records) == 2
        assert records == [{
            'loc': {
                'coordinates': [-121.8, 37.7],
                'type': 'Point'
            }
        }, {
            'loc': {
                'coordinates': [-121.6, 37.9],
                'type': 'Point'
            }
        }]

    def test_geospatial_positive_query_for_circle(self):
        """
            Perform a positive geospatial query for a circle
        """
        records = []
        query = TestGeospatial.client.query("test", "demo")

        geo_object2 = aerospike.GeoJSON({
            "type": "AeroCircle",
            "coordinates": [[-122.0, 37.5], 250.2]
        })

        query.where(p.geo_within("loc", geo_object2.dumps()))

        def callback((key, metadata, record)):
            records.append(record)

        query.foreach(callback)

        assert len(records) == 1
        assert records == [{
            'loc': {
                'coordinates': [-122.0, 37.5],
                'type': 'Point'
            }
        }]

    def test_geospatial_operate_positive(self):
        """
            Perform an operate operation with geospatial bin
        """

        geo_object_operate = aerospike.GeoJSON({
            "type": "Point",
            "coordinates": [43.45, 56.75]
        })
        key = ('test', 'demo', 'single_geo_operate')
        list = [{
            "op": aerospike.OPERATOR_WRITE,
            "bin": "write_bin",
            "val": {
                "no": geo_object_operate
            }
        }, {
            "op": aerospike.OPERATOR_READ,
            "bin": "write_bin"
        }]

        key, meta, bins = TestGeospatial.client.operate(key, list)

        assert bins == {
            'write_bin': {
                'no': {
                    'coordinates': [43.45, 56.75],
                    'type': 'Point'
                }
            }
        }

        TestGeospatial.client.remove(key)

    def test_geospatial_object_not_dict_or_string(self):
        """
            The geospatial object is not a dictionary or string
        """
        try:
            geo_object_wrong = aerospike.GeoJSON(1)

        except ParamError as exception:
            assert exception.code == -2
            assert exception.msg == 'Geospatial data should be a dictionary or raw GeoJSON string'

    def test_geospatial_object_non_json_serialziable_string(self):
        """
            The geospatial object is not a json serializable string
        """
        try:
            geo_object_wrong = aerospike.GeoJSON("abc")

        except ClientError as exception:
            assert exception.code == -1
            assert exception.msg == 'String is not GeoJSON serializable'

    def test_geospatial_wrap_positive(self):
        """
            Perform a positive wrap on geospatial data
        """
        self.geo_object.wrap({
            "type":
            "Polygon",
            "coordinates":
            [[[-122.500000, 37.000000], [-121.000000, 37.000000],
              [-121.000000, 38.080000], [-122.500000, 38.080000],
              [-122.500000, 37.000000]]]
        })
        assert self.geo_object.unwrap() == {
            'coordinates': [[[-122.5, 37.0], [-121.0, 37.0], [-121.0, 38.08],
                             [-122.5, 38.08], [-122.5, 37.0]]],
            'type':
            'Polygon'
        }

    def test_geospatial_object_wrap_non_dict(self):
        """
            The geospatial object provided to wrap() is not a dictionary
        """
        try:
            self.geo_object.wrap("abc")
        except ParamError as exception:
            assert exception.code == -2
            assert exception.msg == 'Geospatial data should be a dictionary or raw GeoJSON string'

    def test_geospatial_wrap_positive_with_query(self):
        """
            Perform a positive wrap on geospatial data followed by a query
        """
        geo_object_wrap = aerospike.GeoJSON({
            "type":
            "Polygon",
            "coordinates":
            [[[-124.500000, 37.000000], [-125.000000, 37.000000],
              [-121.000000, 38.080000], [-122.500000, 38.080000],
              [-124.500000, 37.000000]]]
        })

        geo_object_wrap.wrap({
            "type":
            "Polygon",
            "coordinates":
            [[[-122.500000, 37.000000], [-121.000000, 37.000000],
              [-121.000000, 38.080000], [-122.500000, 38.080000],
              [-122.500000, 37.000000]]]
        })
        assert geo_object_wrap.unwrap() == {
            'coordinates': [[[-122.5, 37.0], [-121.0, 37.0], [-121.0, 38.08],
                             [-122.5, 38.08], [-122.5, 37.0]]],
            'type':
            'Polygon'
        }

        records = []
        query = TestGeospatial.client.query("test", "demo")
        query.where(p.geo_within("loc", geo_object_wrap.dumps()))

        def callback((key, metadata, record)):
            records.append(record)

        query.foreach(callback)

        assert len(records) == 3
        assert records == [{
            'loc': {
                'coordinates': [-122.0, 37.5],
                'type': 'Point'
            }
        }, {
            'loc': {
                'coordinates': [-121.8, 37.7],
                'type': 'Point'
            }
        }, {
            'loc': {
                'coordinates': [-121.6, 37.9],
                'type': 'Point'
            }
        }]

    def test_geospatial_loads_positive(self):
        """
            Perform a positive loads on geoJSON raw string
        """
        self.geo_object.loads(
            '{"type": "Polygon", "coordinates": [[[-122.500000, 37.000000], [-121.000000, 37.000000], [-121.000000, 38.080000],[-122.500000, 38.080000], [-122.500000, 37.000000]]]}'
        )

        assert self.geo_object.unwrap() == {
            'coordinates': [[[-122.5, 37.0], [-121.0, 37.0], [-121.0, 38.08],
                             [-122.5, 38.08], [-122.5, 37.0]]],
            'type':
            'Polygon'
        }

    def test_geospatial_object_loads_non_dict(self):
        """
            The geospatial object provided to loads() is not a dictionary
        """
        try:
            self.geo_object.loads('{"abc"}')
        except ClientError as exception:
            assert exception.code == -1
            assert exception.msg == 'String is not GeoJSON serializable'

    def test_geospatial_loads_positive_with_query(self):
        """
            Perform a positive loads on geoJSON raw string followed by a query
        """
        geo_object_loads = aerospike.GeoJSON({
            "type":
            "Polygon",
            "coordinates":
            [[[-124.500000, 37.000000], [-125.000000, 37.000000],
              [-121.000000, 38.080000], [-122.500000, 38.080000],
              [-124.500000, 37.000000]]]
        })

        geo_object_loads.loads(
            '{"type": "Polygon", "coordinates": [[[-122.500000, 37.000000], [-121.000000, 37.000000], [-121.000000, 38.080000],[-122.500000, 38.080000], [-122.500000, 37.000000]]]}'
        )

        assert geo_object_loads.unwrap() == {
            'coordinates': [[[-122.5, 37.0], [-121.0, 37.0], [-121.0, 38.08],
                             [-122.5, 38.08], [-122.5, 37.0]]],
            'type':
            'Polygon'
        }

        records = []
        query = TestGeospatial.client.query("test", "demo")
        query.where(p.geo_within("loc", geo_object_loads.dumps()))

        def callback((key, metadata, record)):
            records.append(record)

        query.foreach(callback)

        assert len(records) == 3
        assert records == [{
            'loc': {
                'coordinates': [-122.0, 37.5],
                'type': 'Point'
            }
        }, {
            'loc': {
                'coordinates': [-121.8, 37.7],
                'type': 'Point'
            }
        }, {
            'loc': {
                'coordinates': [-121.6, 37.9],
                'type': 'Point'
            }
        }]

    def test_geospatial_dumps_positive(self):
        """
            Perform a positive dumps. Verify using str
        """
        assert self.geo_object.dumps(
        ) == '{"type": "Point", "coordinates": [-120.2, 39.3]}'

        assert str(self.geo_object
                   ) == '{"type": "Point", "coordinates": [-120.2, 39.3]}'

    def test_geospatial_repr_positive(self):
        """
            Perform a positive repr. Verify using eval()
        """
        assert repr(self.geo_object
                    ) == '\'{"type": "Point", "coordinates": [-120.2, 39.3]}\''
        assert eval(repr(self.geo_object)
                    ) == '{"type": "Point", "coordinates": [-120.2, 39.3]}'

    def test_geospatial_put_get_positive_with_geodata(self):
        """
            Perform a get and put with multiple bins including geospatial bin
            using geodata method
        """

        key = ('test', 'demo', 'single_geo_put')
        geo_object_single = aerospike.geodata({
            "type": "Point",
            "coordinates": [42.34, 58.62]
        })
        geo_object_dict = aerospike.geodata({
            "type": "Point",
            "coordinates": [56.34, 69.62]
        })

        TestGeospatial.client.put(
            key, {
                "loc": geo_object_single,
                "int_bin": 2,
                "string_bin": "str",
                "dict_bin": {
                    "a": 1,
                    "b": 2,
                    "geo": geo_object_dict
                }
            })

        key, meta, bins = TestGeospatial.client.get(key)

        assert bins == {
            'loc': {
                'coordinates': [42.34, 58.62],
                'type': 'Point'
            },
            "int_bin": 2,
            "string_bin": "str",
            "dict_bin": {
                "a": 1,
                "b": 2,
                "geo": {
                    'coordinates': [56.34, 69.62],
                    'type': 'Point'
                }
            }
        }

        TestGeospatial.client.remove(key)

    def test_geospatial_put_get_positive_with_geojson(self):
        """
            Perform a get and put with multiple bins including geospatial bin
            using geodata method
        """

        key = ('test', 'demo', 'single_geo_put')
        geo_object_single = aerospike.geojson(
            '{"type": "Point", "coordinates": [42.34, 58.62] }')
        geo_object_dict = aerospike.geojson(
            '{"type": "Point", "coordinates": [56.34, 69.62] }')

        TestGeospatial.client.put(
            key, {
                "loc": geo_object_single,
                "int_bin": 2,
                "string_bin": "str",
                "dict_bin": {
                    "a": 1,
                    "b": 2,
                    "geo": geo_object_dict
                }
            })

        key, meta, bins = TestGeospatial.client.get(key)

        assert bins == {
            'loc': {
                'coordinates': [42.34, 58.62],
                'type': 'Point'
            },
            "int_bin": 2,
            "string_bin": "str",
            "dict_bin": {
                "a": 1,
                "b": 2,
                "geo": {
                    'coordinates': [56.34, 69.62],
                    'type': 'Point'
                }
            }
        }

        TestGeospatial.client.remove(key)

    def test_geospatial_positive_query_with_geodata(self):
        """
            Perform a positive geospatial query for a polygon with geodata
        """
        records = []
        query = TestGeospatial.client.query("test", "demo")

        geo_object2 = aerospike.geodata({
            "type":
            "Polygon",
            "coordinates":
            [[[-122.500000, 37.000000], [-121.000000, 37.000000],
              [-121.000000, 38.080000], [-122.500000, 38.080000],
              [-122.500000, 37.000000]]]
        })

        query.where(p.geo_within("loc", geo_object2.dumps()))

        def callback((key, metadata, record)):
            records.append(record)

        query.foreach(callback)

        assert len(records) == 3
        assert records == [{
            'loc': {
                'coordinates': [-122.0, 37.5],
                'type': 'Point'
            }
        }, {
            'loc': {
                'coordinates': [-121.8, 37.7],
                'type': 'Point'
            }
        }, {
            'loc': {
                'coordinates': [-121.6, 37.9],
                'type': 'Point'
            }
        }]

    def test_geospatial_positive_query_with_geojson(self):
        """
            Perform a positive geospatial query for a polygon with geojson
        """
        records = []
        query = TestGeospatial.client.query("test", "demo")

        geo_object2 = aerospike.geojson(
            '{"type": "Polygon", "coordinates": [[[-122.500000, 37.000000], [-121.000000, 37.000000], [-121.000000, 38.080000],[-122.500000, 38.080000], [-122.500000, 37.000000]]]}'
        )

        query.where(p.geo_within("loc", geo_object2.dumps()))

        def callback((key, metadata, record)):
            records.append(record)

        query.foreach(callback)

        assert len(records) == 3
        assert records == [{
            'loc': {
                'coordinates': [-122.0, 37.5],
                'type': 'Point'
            }
        }, {
            'loc': {
                'coordinates': [-121.8, 37.7],
                'type': 'Point'
            }
        }, {
            'loc': {
                'coordinates': [-121.6, 37.9],
                'type': 'Point'
            }
        }]

    def test_geospatial_2dindex_positive(self):
        """
            Perform a positive 2d index creation
        """
        status = TestGeospatial.client.index_remove('test', 'loc_index')

        assert status == 0

        status = TestGeospatial.client.index_geo2dsphere_create(
            "test", "demo", "loc", "loc_index")

        assert status == 0

    def test_geospatial_2dindex_positive_with_policy(self):
        """
            Perform a positive 2d index creation with policy
        """
        status = TestGeospatial.client.index_remove('test', 'loc_index')

        assert status == 0

        status = TestGeospatial.client.index_geo2dsphere_create(
            "test", "demo", "loc", "loc_index", {"timeout": 2000})

        assert status == 0

    def test_geospatial_2dindex_set_length_extra(self):
        """
            Perform a 2d creation with set length exceeding limit
        """
        set_name = 'a'
        for i in xrange(100):
            set_name = set_name + 'a'
        status = TestGeospatial.client.index_remove('test', 'loc_index')

        assert status == 0
        try:
            status = TestGeospatial.client.index_geo2dsphere_create(
                "test", set_name, "loc", "loc_index")

        except InvalidRequest as exception:
            assert exception.code == 4
            assert exception.msg == "Invalid Set Name"
class TestGeospatial(TestBaseClass):

    pytestmark = pytest.mark.skipif(
        TestBaseClass.has_geo_support() == False,
        reason="Server does not support geospatial data.")

    def setup_class(cls):
        """
        Setup method.
        """
        hostlist, user, password = TestBaseClass.get_hosts()
        config = {'hosts': hostlist}
        if user == None and password == None:
            TestGeospatial.client = aerospike.client(config).connect()
        else:
            TestGeospatial.client = aerospike.client(config).connect(user, password)
        TestGeospatial.client.index_geo2dsphere_create("test", "demo", "loc", "loc_index")
        TestGeospatial.client.index_geo2dsphere_create("test", "demo", "loc_polygon", "loc_polygon_index")
        TestGeospatial.client.index_geo2dsphere_create("test", "demo",
                "loc_circle", "loc_circle_index")

        TestGeospatial.skip_old_server = True
        versioninfo = TestGeospatial.client.info('version')
        for keys in versioninfo:
            for value in versioninfo[keys]:
                if value != None:
                    versionlist = value[value.find("build") + 6:value.find("\n")].split(".")
                    if int(versionlist[0]) >= 3 and int(versionlist[1]) >= 7:
                        TestGeospatial.skip_old_server = False

    def teardown_class(cls):
        TestGeospatial.client.index_remove('test', 'loc_index')
        TestGeospatial.client.index_remove('test', 'loc_polygon_index')
        TestGeospatial.client.index_remove('test', 'loc_circle_index')
        TestGeospatial.client.close()

    def setup_method(self, method):

        self.keys = []
        pre = '{"type": "Point", "coordinates"'
        suf = ']}'
        for i in xrange(10):
            lng =  1220 - (2 * i)
            lat = 375 + (2 * i)
            key = ('test', 'demo', i)
            s = "{0}: [-{1}.{2}, {3}.{4}{5}".format(pre, (lng/10), (lng%10), (lat/10), (lat%10), suf)
            self.geo_object = aerospike.geojson(s)
            TestGeospatial.client.put(key, {"loc": self.geo_object})
            self.keys.append(key)

        key = ('test', 'demo', 'polygon')
        self.geo_object_polygon = aerospike.GeoJSON({"type": "Polygon",
            "coordinates": [[[-122.500000, 37.000000],[-121.000000, 37.000000], [-121.000000, 
                38.080000],[-122.500000, 38.080000], [-122.500000, 37.000000]]]})
        TestGeospatial.client.put(key, {"loc_polygon": self.geo_object_polygon})
        self.keys.append(key)

        if not TestGeospatial.skip_old_server:
            key = ('test', 'demo', 'circle')
            geo_circle = aerospike.GeoJSON({"type": "AeroCircle", "coordinates": [[-122.0, 37.5], 250.2]})
            TestGeospatial.client.put(key, {"loc_circle": geo_circle})
            self.keys.append(key)

    def teardown_method(self, method):
        """
        Teardown method.
        """
        for key in self.keys:
            TestGeospatial.client.remove(key)

    def test_geospatial_put_get_positive(self):
        """
            Perform a get and put with multiple bins including geospatial bin
        """
        key = ('test', 'demo', 'single_geo_put')
        geo_object_single = aerospike.GeoJSON({"type": "Point", "coordinates": [42.34, 58.62] })
        geo_object_dict = aerospike.GeoJSON({"type": "Point", "coordinates": [56.34, 69.62] })
        
        TestGeospatial.client.put(key, {"loc": geo_object_single, "int_bin": 2,
            "string_bin": "str", "dict_bin": {"a": 1, "b":2, "geo":
                geo_object_dict}})
        
        key, meta, bins = TestGeospatial.client.get(key)

        expected = {'loc': {'coordinates': [42.34, 58.62], 'type': 'Point'},
                "int_bin": 2, "string_bin": "str", "dict_bin": {"a": 1, "b": 2,
                  "geo": {'coordinates': [56.34, 69.62], 'type':
                        'Point'}}}
        for b in bins:
            assert b in expected

        TestGeospatial.client.remove(key)

    def test_geospatial_positive_query(self):
        """
            Perform a positive geospatial query for a polygon
        """
        records = []
        query = TestGeospatial.client.query("test", "demo")

        geo_object2 = aerospike.GeoJSON({"type": "Polygon", "coordinates": [[[-122.500000,
    37.000000],[-121.000000, 37.000000], [-121.000000, 38.080000],[-122.500000,
        38.080000], [-122.500000, 37.000000]]]})

        query.where(p.geo_within_geojson_region("loc", geo_object2.dumps()))

        def callback((key, metadata, record)):
            records.append(record)

        query.foreach(callback)

        assert len(records) == 3
        expected = [{"coordinates": [-122.0, 37.5], "type": "Point"}, {"coordinates": [-121.8, 37.7], "type": "Point"}, {"coordinates": [-121.6, 37.9], "type": "Point"}]
        for r in records:
            assert r['loc'].unwrap() in expected

    def test_geospatial_positive_query_outside_shape(self):
        """
            Perform a positive geospatial query for polygon where all points are
            outside polygon
        """
        records = []
        query = TestGeospatial.client.query("test", "demo")

        geo_object2 = aerospike.GeoJSON({"type": "Polygon", "coordinates": [[[-126.500000,
    37.000000],[-124.000000, 37.000000], [-124.000000, 38.080000],[-126.500000,
        38.080000], [-126.500000, 37.000000]]]})

        query.where(p.geo_within_geojson_region("loc", geo_object2.dumps()))

        def callback((key, metadata, record)):
            records.append(record)

        query.foreach(callback)

        assert len(records) == 0

    def test_geospatial_positive_query_without_set(self):
        """
            Perform a positive geospatial query for a polygon without a set
        """
        keys = []
        pre = '{"type": "Point", "coordinates"'
        suf = ']}'
        for i in xrange(1, 10):
            lng =  1220 - (2 * i)
            lat = 375 + (2 * i)
            key = ('test', None, i)
            s = "{0}: [-{1}.{2}, {3}.{4}{5}".format(pre, (lng/10), (lng%10), (lat/10), (lat%10), suf)
            geo_object = aerospike.geojson(s)
            TestGeospatial.client.put(key, {"loc": geo_object})
            keys.append(key)

        TestGeospatial.client.index_geo2dsphere_create("test", None, "loc", "loc_index_no_set")
        records = []
        query = TestGeospatial.client.query("test", None)

        geo_object2 = aerospike.GeoJSON({"type": "Polygon", "coordinates": [[[-122.500000,
    37.000000],[-121.000000, 37.000000], [-121.000000, 38.080000],[-122.500000,
        38.080000], [-122.500000, 37.000000]]]})

        query.where(p.geo_within_geojson_region("loc", geo_object2.dumps()))

        def callback((key, metadata, record)):
            records.append(record)

        query.foreach(callback)

        TestGeospatial.client.index_remove('test', 'loc_index_no_set')
        for key in keys:
            TestGeospatial.client.remove(key)

        assert len(records) == 2
        expected = [{'coordinates': [-121.8, 37.7], 'type': 'Point'}, {'coordinates': [-121.6, 37.9], 'type': 'Point'}]
        
        for r in records:
            assert r['loc'].unwrap() in expected

    def test_geospatial_positive_query_for_circle(self):
        """
            Perform a positive geospatial query for a circle
        """
        if TestGeospatial.skip_old_server == True:
            pytest.skip("Server does not support apply on AeroCircle for GeoJSON")

        records = []
        query = TestGeospatial.client.query("test", "demo")

        geo_object2 = aerospike.GeoJSON({"type": "AeroCircle", "coordinates": [[-122.0, 37.5], 250.2]})

        query.where(p.geo_within_geojson_region("loc", geo_object2.dumps()))

        def callback((key, metadata, record)):
            records.append(record)

        query.foreach(callback)

        assert len(records) == 1
        expected = [{'coordinates': [-122.0, 37.5], 'type': 'Point'}]
        for r in records:
            assert r['loc'].unwrap() in expected

    def test_geospatial_positive_query_for_circle_with_within_radius_helper(self):
        """
            Perform a positive geospatial query for a circle with helper
        """
        if TestGeospatial.skip_old_server == True:
            pytest.skip("Server does not support apply on AeroCircle for GeoJSON")

        records = []
        query = TestGeospatial.client.query("test", "demo")

        query.where(p.geo_within_radius("loc", -122.0, 37.5, 250.2))

        def callback((key, metadata, record)):
            records.append(record)

        query.foreach(callback)

        assert len(records) == 1
        expected = [{'coordinates': [-122.0, 37.5], 'type': 'Point'}]
        for r in records:
            assert r['loc'].unwrap() in expected

    def test_geospatial_operate_positive(self):
        """
            Perform an operate operation with geospatial bin
        """

        geo_object_operate = aerospike.GeoJSON({"type": "Point", "coordinates": [43.45, 56.75] })
        key = ('test', 'demo', 'single_geo_operate')
        list = [{
            "op": aerospike.OPERATOR_WRITE,
            "bin": "write_bin",
            "val": {"no": geo_object_operate}
            }, {"op": aerospike.OPERATOR_READ,
                "bin": "write_bin"}]

        key, meta, bins = TestGeospatial.client.operate(key, list)
        assert bins['write_bin']['no'].unwrap() == {'coordinates': [43.45, 56.75], 'type': 'Point'}

        TestGeospatial.client.remove(key)

    def test_geospatial_wrap_positive(self):
        """
            Perform a positive wrap on geospatial data
        """
        self.geo_object.wrap({"type": "Polygon", "coordinates": [[[-122.500000, 
            37.000000],[-121.000000, 37.000000], [-121.000000, 38.080000],[-122.500000,
            38.080000], [-122.500000, 37.000000]]]})
        assert self.geo_object.unwrap() == {'coordinates': [[[-122.5, 37.0], [-121.0, 37.0], [-121.0, 38.08],
            [-122.5, 38.08], [-122.5, 37.0]]], 'type': 'Polygon'}

    def test_geospatial_wrap_positive_with_query(self):
        """
            Perform a positive wrap on geospatial data followed by a query
        """
        geo_object_wrap = aerospike.GeoJSON({"type": "Polygon", "coordinates": [[[-124.500000, 
            37.000000],[-125.000000, 37.000000], [-121.000000, 38.080000],[-122.500000, 
                38.080000], [-124.500000, 37.000000]]]})

        geo_object_wrap.wrap({"type": "Polygon", "coordinates": [[[-122.500000, 
            37.000000],[-121.000000, 37.000000], [-121.000000, 38.080000],[-122.500000,
            38.080000], [-122.500000, 37.000000]]]})
        assert geo_object_wrap.unwrap() == {'coordinates': [[[-122.5, 37.0], [-121.0, 37.0], [-121.0, 38.08],
            [-122.5, 38.08], [-122.5, 37.0]]], 'type': 'Polygon'}
        
        records = []
        query = TestGeospatial.client.query("test", "demo")
        query.where(p.geo_within_geojson_region("loc", geo_object_wrap.dumps()))

        def callback((key, metadata, record)):
            records.append(record)

        query.foreach(callback)

        assert len(records) == 3
        expected = [{'coordinates': [-122.0, 37.5], 'type': 'Point'}, {'coordinates': [-121.8, 37.7], 'type':
                'Point'}, {'coordinates': [-121.6, 37.9], 'type': 'Point'}]
        for r in records:
            assert r['loc'].unwrap() in expected

    def test_geospatial_loads_positive(self):
        """
            Perform a positive loads on geoJSON raw string
        """
        self.geo_object.loads('{"type": "Polygon", "coordinates": [[[-122.500000, 37.000000], [-121.000000, 37.000000], [-121.000000, 38.080000],[-122.500000, 38.080000], [-122.500000, 37.000000]]]}')

        assert self.geo_object.unwrap() == {'coordinates': [[[-122.5, 37.0], [-121.0, 37.0], [-121.0, 38.08],
            [-122.5, 38.08], [-122.5, 37.0]]], 'type': 'Polygon'}


    def test_geospatial_loads_positive_with_query(self):
        """
            Perform a positive loads on geoJSON raw string followed by a query
        """
        geo_object_loads = aerospike.GeoJSON({"type": "Polygon", "coordinates": [[[-124.500000, 
            37.000000],[-125.000000, 37.000000], [-121.000000, 38.080000],[-122.500000, 
                38.080000], [-124.500000, 37.000000]]]})

        geo_object_loads.loads('{"type": "Polygon", "coordinates": [[[-122.500000, 37.000000], [-121.000000, 37.000000], [-121.000000, 38.080000],[-122.500000, 38.080000], [-122.500000, 37.000000]]]}')

        assert geo_object_loads.unwrap() == {'coordinates': [[[-122.5, 37.0], [-121.0, 37.0], [-121.0, 38.08],
            [-122.5, 38.08], [-122.5, 37.0]]], 'type': 'Polygon'}

        records = []
        query = TestGeospatial.client.query("test", "demo")
        query.where(p.geo_within_geojson_region("loc", geo_object_loads.dumps()))

        def callback((key, metadata, record)):
            records.append(record)

        query.foreach(callback)

        assert len(records) == 3
        expected = [{'coordinates': [-122.0, 37.5], 'type': 'Point'}, {'coordinates': [-121.8, 37.7], 'type':
                'Point'}, {'coordinates': [-121.6, 37.9], 'type': 'Point'}]
        for r in records:
            assert r['loc'].unwrap() in expected

    def test_geospatial_dumps_positive(self):
        """
            Perform a positive dumps. Verify using str
        """
        geojson_str = self.geo_object.dumps()
        assert type(geojson_str) == str
        obj = aerospike.geojson(geojson_str)
        assert obj.unwrap() == self.geo_object.unwrap()

        geojson_str = str(self.geo_object)
        assert type(geojson_str) == str
        obj = aerospike.geojson(geojson_str)
        assert obj.unwrap() == self.geo_object.unwrap()

    def test_geospatial_repr_positive(self):
        """
            Perform a positive repr. Verify using eval()
        """
        geojson_str = eval(repr(self.geo_object))
        assert type(geojson_str) == str
        obj = aerospike.geojson(geojson_str)
        assert obj.unwrap() == self.geo_object.unwrap()

    def test_geospatial_put_get_positive_with_geodata(self):
        """
            Perform a get and put with multiple bins including geospatial bin
            using geodata method
        """

        key = ('test', 'demo', 'single_geo_put')
        geo_object_single = aerospike.geodata({"type": "Point", "coordinates": [42.34, 58.62] })
        geo_object_dict = aerospike.geodata({"type": "Point", "coordinates": [56.34, 69.62] })
        
        TestGeospatial.client.put(key, {"loc": geo_object_single, "int_bin": 2,
            "string_bin": "str", "dict_bin": {"a": 1, "b":2, "geo":
                geo_object_dict}})
        
        key, meta, bins = TestGeospatial.client.get(key)

        expected = {'loc': {'coordinates': [42.34, 58.62], 'type': 'Point'},
                "int_bin": 2, "string_bin": "str", "dict_bin": {"a": 1, "b": 2,
                  "geo": {'coordinates': [56.34, 69.62], 'type':
                        'Point'}}}
        for b in bins:
            assert b in expected

        TestGeospatial.client.remove(key)

    def test_geospatial_put_get_positive_with_geojson(self):
        """
            Perform a get and put with multiple bins including geospatial bin
            using geodata method
        """

        key = ('test', 'demo', 'single_geo_put')
        geo_object_single = aerospike.geojson('{"type": "Point", "coordinates": [42.34, 58.62] }')
        geo_object_dict = aerospike.geojson('{"type": "Point", "coordinates": [56.34, 69.62] }')
        
        TestGeospatial.client.put(key, {"loc": geo_object_single, "int_bin": 2,
            "string_bin": "str", "dict_bin": {"a": 1, "b":2, "geo":
                geo_object_dict}})
        
        key, meta, bins = TestGeospatial.client.get(key)

        expected = {'loc': {'coordinates': [42.34, 58.62], 'type': 'Point'},
                "int_bin": 2, "string_bin": "str", "dict_bin": {"a": 1, "b": 2,
                  "geo": {'coordinates': [56.34, 69.62], 'type':
                        'Point'}}}
        for b in bins:
            assert b in expected

        TestGeospatial.client.remove(key)

    def test_geospatial_positive_query_with_geodata(self):
        """
            Perform a positive geospatial query for a polygon with geodata
        """
        records = []
        query = TestGeospatial.client.query("test", "demo")

        geo_object2 = aerospike.geodata({"type": "Polygon", "coordinates": [[[-122.500000, 
            37.000000],[-121.000000, 37.000000], [-121.000000, 38.080000],[-122.500000, 
                38.080000], [-122.500000, 37.000000]]]})

        query.where(p.geo_within_geojson_region("loc", geo_object2.dumps()))

        def callback((key, metadata, record)):
            records.append(record)

        query.foreach(callback)

        assert len(records) == 3
        expected = [{'coordinates': [-122.0, 37.5], 'type': 'Point'}, {'coordinates': [-121.8, 37.7], 'type':
                'Point'}, {'coordinates': [-121.6, 37.9], 'type': 'Point'}]
        for r in records:
            assert r['loc'].unwrap() in expected

    def test_geospatial_positive_query_with_geojson(self):
        """
            Perform a positive geospatial query for a polygon with geojson
        """
        records = []
        query = TestGeospatial.client.query("test", "demo")

        geo_object2 = aerospike.geojson('{"type": "Polygon", "coordinates": [[[-122.500000, 37.000000], [-121.000000, 37.000000], [-121.000000, 38.080000],[-122.500000, 38.080000], [-122.500000, 37.000000]]]}')

        query.where(p.geo_within_geojson_region("loc", geo_object2.dumps()))

        def callback((key, metadata, record)):
            records.append(record)

        query.foreach(callback)

        assert len(records) == 3
        expected = [{'coordinates': [-122.0, 37.5], 'type': 'Point'}, {'coordinates': [-121.8, 37.7], 'type':
                'Point'},{'coordinates': [-121.6, 37.9], 'type': 'Point'}]
        for r in records:
            assert r['loc'].unwrap() in expected

    def test_geospatial_2dindex_positive(self):
        """
            Perform a positive 2d index creation
        """
        status = TestGeospatial.client.index_remove('test', 'loc_index')

        assert status == 0

        status = TestGeospatial.client.index_geo2dsphere_create("test", "demo", "loc", "loc_index")

        assert status == 0

    def test_geospatial_2dindex_positive_with_policy(self):
        """
            Perform a positive 2d index creation with policy
        """
        status = TestGeospatial.client.index_remove('test', 'loc_index')

        assert status == 0

        status = TestGeospatial.client.index_geo2dsphere_create("test", "demo", "loc", "loc_index", {"timeout": 2000})

        assert status == 0

    def test_geospatial_positive_query_with_point(self):
        """
            Perform a positive geospatial query for a point
        """
        records = []
        query = TestGeospatial.client.query("test", "demo")

        geo_object2 = aerospike.GeoJSON({"type": "Point", "coordinates":
            [-121.700000, 37.200000]})

        query.where(p.geo_contains_geojson_point("loc_polygon", geo_object2.dumps()))

        def callback((key, metadata, record)):
            records.append(record)

        query.foreach(callback)

        assert len(records) == 1
        expected = [{'coordinates': [[[-122.500000,
            37.000000],[-121.000000, 37.000000], [-121.000000, 38.080000],[-122.500000, 38.080000],
            [-122.500000, 37.000000]]], 'type': 'Polygon'}]
        for r in records:
            assert r['loc_polygon'].unwrap() in expected

    def test_geospatial_positive_query_with_point_outside_polygon(self):
        """
            Perform a positive geospatial query for a point outside polygon
        """
        records = []
        query = TestGeospatial.client.query("test", "demo")

        geo_object2 = aerospike.GeoJSON({"type": "Point", "coordinates":
            [-123.700000, 37.200000]})

        query.where(p.geo_contains_geojson_point("loc_polygon", geo_object2.dumps()))

        def callback((key, metadata, record)):
            records.append(record)

        query.foreach(callback)

        assert len(records) == 0

    def test_geospatial_positive_query_with_point_in_aerocircle(self):
        """
            Perform a positive geospatial query for a point in aerocircle
        """
        if TestGeospatial.skip_old_server == True:
            pytest.skip("Server does not support apply on AeroCircle for GeoJSON")

        records = []
        query = TestGeospatial.client.query("test", "demo")

        geo_object2 = aerospike.GeoJSON({"type": "Point", "coordinates":
            [-122.000000, 37.500000]})

        query.where(p.geo_contains_geojson_point("loc_circle", geo_object2.dumps()))

        def callback((key, metadata, record)):
            records.append(record)

        query.foreach(callback)

        assert len(records) == 1
        expected = [{'coordinates': [[-122.0, 37.5], 250.2], 'type': 'AeroCircle'}]
        for r in records:
            assert r['loc_circle'].unwrap() in expected

    def test_geospatial_positive_query_with_point_outside_aerocircle(self):
        """
            Perform a positive geospatial query for a point in aerocircle
        """
        if TestGeospatial.skip_old_server == True:
            pytest.skip("Server does not support apply on AeroCircle for GeoJSON")

        records = []
        query = TestGeospatial.client.query("test", "demo")

        geo_object2 = aerospike.GeoJSON({"type": "Point", "coordinates":
            [-122.000000, 450.200]})

        query.where(p.geo_contains_geojson_point("loc_circle", geo_object2.dumps()))

        def callback((key, metadata, record)):
            records.append(record)

        query.foreach(callback)

        assert len(records) == 0

    def test_geospatial_positive_query_with_point_helper_method(self):
        """
            Perform a positive geospatial query for a point with helper method
        """
        records = []
        query = TestGeospatial.client.query("test", "demo")

        query.where(p.geo_contains_point("loc_polygon", -121.7, 37.2))

        def callback((key, metadata, record)):
            records.append(record)

        query.foreach(callback)

        assert len(records) == 1
        expected = [{'coordinates': [[[-122.500000,
            37.000000],[-121.000000, 37.000000], [-121.000000, 38.080000],[-122.500000, 38.080000],
            [-122.500000, 37.000000]]], 'type': 'Polygon'}]
        for r in records:
            assert r['loc_polygon'].unwrap() in expected

    def test_geospatial_object_not_dict_or_string(self):
        """
            The geospatial object is not a dictionary or string
        """
        try:
            geo_object_wrong = aerospike.GeoJSON(1)

        except ParamError as exception:
            assert exception.code == -2
            assert exception.msg == 'Geospatial data should be a dictionary or raw GeoJSON string'

    def test_geospatial_object_non_json_serializable_string(self):
        """
            The geospatial object is not a json serializable string
        """
        try:
            geo_object_wrong = aerospike.GeoJSON("abc")

        except ClientError as exception:
            assert exception.code == -1
            assert exception.msg == 'String is not GeoJSON serializable'

    def test_geospatial_object_wrap_non_dict(self):
        """
            The geospatial object provided to wrap() is not a dictionary
        """
        try:
            self.geo_object.wrap("abc")
        except ParamError as exception:
            assert exception.code == -2
            assert exception.msg == 'Geospatial data should be a dictionary or raw GeoJSON string'

    def test_geospatial_object_loads_non_dict(self):
        """
            The geospatial object provided to loads() is not a dictionary
        """
        try:
            self.geo_object.loads('{"abc"}')
        except ClientError as exception:
            assert exception.code == -1
            assert exception.msg == 'String is not GeoJSON serializable'

    def test_geospatial_2dindex_set_length_extra(self):
        """
            Perform a 2d creation with set length exceeding limit
        """
        set_name = 'a'
        for i in xrange(100):
            set_name = set_name + 'a'
        status = TestGeospatial.client.index_remove('test', 'loc_index')

        assert status == 0
        try:
        	status = TestGeospatial.client.index_geo2dsphere_create("test", set_name, "loc", "loc_index")

        except InvalidRequest as exception:
        	assert exception.code == 4

    def test_geospatial_query_circle_incorrect_param_within_radius_helper_method(self):
        """
            Perform a positive geospatial query for a circle with incorrect
            params for helper method
        """
        records = []
        query = TestGeospatial.client.query("test", "demo")

        try:
            query.where(p.geo_contains_point("loc_polygon", -122.0, 37.5, 250))
        except ParamError as exception:
            assert exception.code == -2L
            assert exception.msg == "predicate is invalid."

    def test_geospatial_query_point_incorrect_param_helper_method(self):
        """
            Perform a positive geospatial query for a point with incorrect
            params for helper method
        """
        records = []
        query = TestGeospatial.client.query("test", "demo")

        try:
            query.where(p.geo_contains_point("loc_polygon", -121.7, 37))
        except ParamError as exception:
            assert exception.code == -2L