class CouchbaseClientTest(Base):
    def setUp(self):
        super(CouchbaseClientTest, self).setUp()
        self.client = CouchbaseClient(self.url, self.bucket_name, "", True)

    def tearDown(self):
        self.client.done()

    @nottest
    def setup_memcached_bucket(self):
        self.memcached_bucket = 'testing-memcached'
        self.rest_client = RestConnection({'ip': self.host,
                                           'port': self.port,
                                           'username': self.username,
                                           'password': self.password})
        self.rest_client.create_bucket(self.memcached_bucket,
                                       bucketType='memcached',
                                       authType='sasl', ramQuotaMB=64)
        self.client_for_memcached_bucket = \
            CouchbaseClient(self.url, self.memcached_bucket, verbose=True)

    @nottest
    def teardown_memcached_bucket(self):
        self.rest_client.delete_bucket(self.memcached_bucket)

    @attr(cbv="1.0.0")
    def test_set_integer_value(self):
        self.client.set('int', 0, 0, 10)
        self.assertEqual(self.client.get('int')[2], 10,
                         'value should be the integer 10')
        self.client.incr('int')
        self.assertEqual(self.client.get('int')[2], 11,
                         'value should be the integer 11')
        self.client.delete('int')

    def test_two_client_incr(self):
        """http://www.couchbase.com/issues/browse/PYCBC-16"""
        key = 'test_two_client_incr'
        client_one = self.client
        client_two = CouchbaseClient(self.url, self.bucket_name, "", True)
        # Client one sets a numeric key
        client_one.set(key, 0, 0, 20)
        # Client two tries to increment this numeric key
        (i, cas) = client_two.incr(key)
        self.assertEqual(i, 21)

        # Client two should be able to keep incrementing this key
        (i, cas) = client_two.incr(key)
        self.assertEqual(i, 22)

        (_, cas, i) = client_two.get(key)
        self.assertEqual(i, 22)
        (i, cas) = client_two.incr(key)
        self.assertEqual(i, 23)

    def test_bucket_of_type_memcached(self):
        self.setup_memcached_bucket()
        self.assertIsInstance(self.client_for_memcached_bucket,
                              CouchbaseClient)
        self.teardown_memcached_bucket()
 def setup_rest_connection(self):
     server_info = {
         "ip": self.host,
         "port": self.port,
         "username": self.username,
         "password": self.password
     }
     self.rest = RestConnection(server_info)
 def setup_memcached_bucket(self):
     self.memcached_bucket = 'testing-memcached'
     self.rest_client = RestConnection({
         'ip': self.host,
         'port': self.port,
         'username': self.username,
         'password': self.password
     })
     self.rest_client.create_bucket(self.memcached_bucket,
                                    bucketType='memcached',
                                    authType='sasl',
                                    ramQuotaMB=64)
     self.client_for_memcached_bucket = \
         CouchbaseClient(self.url, self.memcached_bucket, verbose=True)
 def __init__(self, url, bucket, password="", verbose=False,
              dispatcher=CommandDispatcher):
     self.log = logger("CouchbaseClient")
     self.rest_username = bucket
     self.rest_password = password
     self._memcacheds = {}
     self._vBucketMap = {}
     self._vBucketMap_lock = Lock()
     self._vBucketMapFastForward = {}
     self._vBucketMapFastForward_lock = Lock()
     #TODO: use regular expressions to parse the url
     server = {}
     if not bucket:
         raise InvalidArgumentException("bucket can not be an empty string",
                                        parameters="bucket")
     if not url:
         raise InvalidArgumentException("url can not be an empty string",
                                        parameters="url")
     if (url.find("http://") != -1 and url.rfind(":") != -1 and
             url.find("/pools/default") != -1):
         server["ip"] = (url[url.find("http://")
                         + len("http://"):url.rfind(":")])
         server["port"] = url[url.rfind(":") + 1:url.find("/pools/default")]
         server["username"] = self.rest_username
         server["password"] = self.rest_password
     else:
         raise InvalidArgumentException("invalid url string",
                                        parameters=url)
     self.servers = [server]
     self.servers_lock = Lock()
     self.rest = RestConnection(server)
     self.bucket = self.rest.get_bucket(bucket)
     if self.bucket.vbuckets:
         self.reconfig_vbucket_map()
         self.init_vbucket_connections()
         self.streaming_thread = Thread(name="streaming",
                                        target=self._start_streaming,
                                        args=())
         self.streaming_thread.daemon = True
         self.streaming_thread.start()
     self.dispatcher = dispatcher(self, verbose)
     self.dispatcher_thread = Thread(name="dispatcher-thread",
                                     target=self._start_dispatcher)
     self.dispatcher_thread.daemon = True
     self.dispatcher_thread.start()
     self.verbose = verbose
예제 #5
0
 def _rest(self):
     self.servers_lock.acquire()
     server_info = deepcopy(self.servers[0])
     self.servers_lock.release()
     server_info['username'] = self.rest_username
     server_info['password'] = self.rest_password
     server_info['couchApiBase'] = self.couch_api_base
     rest = RestConnection(server_info)
     return rest
    def test_rest_connection_object_creation_with_server_object(self):
        class ServerInfo:
            ip = self.host
            port = self.port
            rest_username = self.username
            rest_password = self.password

        rest = RestConnection(ServerInfo())
        self.assertEqual(rest.base_url,
                         "http://{0}:{1}".format(self.host, self.port))
예제 #7
0
class RestConnectionTest(unittest.TestCase):
    def setUp(self):
        self.host = config['node-1']['host']
        self.port = config['node-1']['port']
        self.username = config['node-1']['username']
        self.password = config['node-1']['password']
        self.bucket_name = config['node-1']['bucket']

    def tearDown(self):
        pass

    @attr(cbv="2.0.0")
    def setup_rest_connection(self):
        server_info = {"ip": self.host,
                       "port": self.port,
                       "username": self.username,
                       "password": self.password}
        self.rest = RestConnection(server_info)

    @attr(cbv="2.0.0")
    def test_rest_connection_object_creation(self):
        self.setup_rest_connection()
        self.assertEqual(self.rest.baseUrl, "http://%s:%s/" %
                         (self.host, self.port))

    @attr(cbv="2.0.0")
    def test_create_design_doc(self):
        self.setup_rest_connection()
        ddoc_name = uuid.uuid4()
        design_doc = json.dumps({"views":
                      {"testing":
                       {"map":
                        "function(doc) { emit(doc._id, null); }"
                        }
                       }
                      })
        resp = self.rest.create_design_doc(self.bucket_name, ddoc_name,
                                           design_doc)
        self.assertTrue(resp["ok"])

        # Cleanup: delete the design doc; just gonna assume this worked
        self.rest.delete_design_doc(self.bucket_name, ddoc_name)
 def setup_memcached_bucket(self):
     self.memcached_bucket = 'testing-memcached'
     self.rest_client = RestConnection({'ip': self.host,
                                        'port': self.port,
                                        'username': self.username,
                                        'password': self.password})
     self.rest_client.create_bucket(self.memcached_bucket,
                                    bucketType='memcached',
                                    authType='sasl', ramQuotaMB=64)
     self.client_for_memcached_bucket = \
         CouchbaseClient(self.url, self.memcached_bucket, verbose=True)
class CouchbaseClientTest(Base):
    def setUp(self):
        super(CouchbaseClientTest, self).setUp()
        self.client = CouchbaseClient(self.url, self.bucket_name, "", True)

    def tearDown(self):
        self.client.flush()
        self.client.done()

    @nottest
    def setup_memcached_bucket(self):
        self.memcached_bucket = 'testing-memcached'
        self.rest_client = RestConnection({'ip': self.host,
                                           'port': self.port,
                                           'username': self.username,
                                           'password': self.password})
        self.rest_client.create_bucket(self.memcached_bucket,
                                       bucketType='memcached',
                                       authType='sasl', ramQuotaMB=64)
        self.client_for_memcached_bucket = \
            CouchbaseClient(self.url, self.memcached_bucket, verbose=True)

    @nottest
    def teardown_memcached_bucket(self):
        self.rest_client.delete_bucket(self.memcached_bucket)

    @attr(cbv="1.0.0")
    def test_set_integer_value(self):
        self.client.set('int', 0, 0, 10)
        self.assertEqual(self.client.get('int')[2], 10,
                         'value should be the integer 10')
        self.client.incr('int')
        self.assertEqual(self.client.get('int')[2], 11,
                         'value should be the integer 11')

    @attr(cbv="1.0.0")
    def test_bucket_of_type_memcached(self):
        self.setup_memcached_bucket()
        self.assertIsInstance(self.client_for_memcached_bucket,
                              CouchbaseClient)
        self.teardown_memcached_bucket()
예제 #10
0
    def test_old_set_get_create_example(self):
        from couchbase.couchbaseclient import CouchbaseClient
        from couchbase.rest_client import RestConnection, RestHelper

        client = CouchbaseClient(self.url, self.bucket_name, "", False)
        client.set("key1", 0, 0, "value1")
        client.get("key1")

        server_info = {
            "ip": self.host,
            "port": self.port,
            "username": self.username,
            "password": self.password
        }
        rest = RestConnection(server_info)
        rest.create_bucket(bucket='newbucket',
                           ramQuotaMB=100,
                           authType='none',
                           saslPassword='',
                           replicaNumber=1,
                           proxyPort=11215,
                           bucketType='membase')

        self.assertTrue(RestHelper(rest).bucket_exists('newbucket'))
        rest.delete_bucket('newbucket')
    def test_old_set_get_create_example(self):
        from couchbase.couchbaseclient import CouchbaseClient
        from couchbase.rest_client import RestConnection, RestHelper

        client = CouchbaseClient(self.url, self.bucket_name, "", False)
        client.set("key1", 0, 0, "value1")
        client.get("key1")

        server_info = {"ip": self.host, "port": self.port, "username": self.username, "password": self.password}
        rest = RestConnection(server_info)
        rest.create_bucket(
            bucket="newbucket",
            ramQuotaMB=100,
            authType="none",
            saslPassword="",
            replicaNumber=1,
            proxyPort=11215,
            bucketType="membase",
        )

        self.assertTrue(RestHelper(rest).bucket_exists("newbucket"))
        rest.delete_bucket("newbucket")
    def setUp(self):
        self.host = config['node-1']['host']
        self.port = config['node-1']['port']
        self.username = config['node-1']['username']
        self.password = config['node-1']['password']
        self.bucket_name = config['node-1']['bucket']

        server_info = {
            "ip": self.host,
            "port": self.port,
            "username": self.username,
            "password": self.password
        }
        self.rest = RestConnection(server_info)
        self.rest_helper = None
예제 #13
0
 def setup_rest_connection(self):
     server_info = {"ip": self.host,
                    "port": self.port,
                    "username": self.username,
                    "password": self.password}
     self.rest = RestConnection(server_info)
class RestConnectionTest(unittest.TestCase):
    def setUp(self):
        self.host = config['node-1']['host']
        self.port = config['node-1']['port']
        self.username = config['node-1']['username']
        self.password = config['node-1']['password']
        self.bucket_name = config['node-1']['bucket']
        # list of design_docs for tearDown to destroy, if they've hung around
        self.design_docs = []

    def tearDown(self):
        for ddoc in self.design_docs:
            self.rest.delete_design_doc(self.bucket_name, ddoc)
        pass

    @nottest
    def setup_rest_connection(self):
        server_info = {"ip": self.host,
                       "port": self.port,
                       "username": self.username,
                       "password": self.password}
        self.rest = RestConnection(server_info)

    @nottest
    def setup_create_design_doc(self):
        self.setup_rest_connection()
        if self.rest.couch_api_base is None:
            raise SkipTest
        ddoc_name = uuid.uuid4()
        design_doc = json.dumps({"views":
                                 {"testing":
                                  {"map":
                                   "function(doc) { emit(doc._id, null); }"
                                   }
                                  }
                                 })
        resp = self.rest.create_design_doc(self.bucket_name, ddoc_name,
                                           design_doc)
        self.design_docs.append(ddoc_name)
        return ddoc_name, resp

    @nottest
    def setup_couchbase_object(self):
        self.cb = Couchbase(self.host + ':' + self.port, self.username,
                            self.password)

    @attr(cbv="1.8.0")
    def test_rest_connection_object_creation(self):
        self.setup_rest_connection()
        self.assertEqual(self.rest.baseUrl, "http://%s:%s/" %
                         (self.host, self.port))

    @attr(cbv="1.8.0")
    def test_rest_connection_object_creation_with_server_object(self):
        class ServerInfo:
            ip = self.host
            port = self.port
            rest_username = self.username
            rest_password = self.password

        rest = RestConnection(ServerInfo())
        self.assertEqual(rest.baseUrl, "http://%s:%s/" % (self.host,
                                                          self.port))

    @attr(cbv="2.0.0")
    def test_create_design_doc(self):
        (ddoc_name, resp) = self.setup_create_design_doc()
        self.assertTrue(resp["ok"])

    @attr(cbv="2.0.0")
    def test_get_design_doc(self):
        ddoc_name, resp = self.setup_create_design_doc()
        ddoc = self.rest.get_design_doc(self.bucket_name, ddoc_name)
        self.assertIn("views", ddoc.keys())
        self.assertRaises(Exception, self.rest.get_design_doc,
                          (self.bucket_name, str(uuid.uuid4())))

    @attr(cbv="2.0.0")
    def test_delete_design_doc(self):
        ddoc_name, resp = self.setup_create_design_doc()
        self.assertTrue(self.rest.delete_design_doc(self.bucket_name,
                                                    ddoc_name))
        self.assertRaises(Exception,
                          self.rest.delete_design_doc,
                          (self.bucket_name, ddoc_name))
        self.design_docs = filter(lambda id: id is not ddoc_name,
                                  self.design_docs)

    @attr(cbv="2.0.0")
    def test_get_view(self):
        (ddoc_name, resp) = self.setup_create_design_doc()
        with warnings.catch_warnings(record=True) as w:
            warnings.simplefilter("always")
            # Trigger a warning.
            view = self.rest.get_view(self.bucket_name, ddoc_name, "testing")
            # Verify some things
            self.assertTrue(len(w) == 1)
            self.assertTrue("deprecated" in str(w[-1].message))

    @attr(cbv="2.0.0")
    def test_view_results(self):
        ddoc_name, resp = self.setup_create_design_doc()
        view = self.rest.view_results(self.bucket_name, ddoc_name, "testing",
                                      {})
        if "error" in view:
            self.fail(view)
        else:
            self.assertIn("rows", view.keys())
        # let's add some sample docs
        self.setup_couchbase_object()
        kvs = [(str(uuid.uuid4()), str(uuid.uuid4())) for i in range(0, 100)]
        for k, v in kvs:
            self.cb[self.bucket_name].set(k, 0, 0, v)
        # rerun the view
        view = self.rest.view_results(self.bucket_name, ddoc_name, "testing",
                                      {})
        if "error" in view:
            self.fail(view)
        else:
            self.assertIn("rows", view.keys())
        # remove sample docs
        for k, v in kvs:
            self.cb[self.bucket_name].delete(k)

    @attr(cbv="1.8.0")
    def test_create_headers(self):
        self.setup_rest_connection()
        headers = self.rest._create_headers()
        self.assertEqual(headers['Authorization'],
                         'Basic ' + base64.encodestring("%s:%s" %
                                                        (self.rest.username,
                                                        self.rest.password)))

    @attr(cbv="1.0.0")
    def test_create_bucket(self):
        self.setup_rest_connection()
        # test membase/couchbase creation defaults
        status = self.rest.create_bucket('newbucket')
        self.assertTrue(status)
        bucket = self.rest.get_bucket('newbucket')
        self.assertEqual(bucket.stats.ram/1024/1024, 100)
        self.assertEqual(bucket.authType, 'sasl')
        self.assertEqual(bucket.type, 'membase')
        self.assertEqual(bucket.numReplicas, 1)
        self.rest.delete_bucket('newbucket')
        # test memcached creation defaults
        status = self.rest.create_bucket(bucket='newbucket',
                                         bucketType='memcached')
        self.assertTrue(status)
        bucket = self.rest.get_bucket('newbucket')
        self.assertEqual(bucket.stats.ram/1024/1024, 100)
        self.assertEqual(bucket.authType, 'sasl')
        self.assertEqual(bucket.type, 'memcached')
        self.assertEqual(bucket.numReplicas, 0)
        # make sure creating an existing bucket fails properly
        self.assertRaises(Exception, self.rest.create_bucket,
                          bucket='newbucket', bucketType='memcached')
        self.rest.delete_bucket('newbucket')
        # test setting ramQuotaMB too low
        self.assertRaises(AssertionError,
                          self.rest.create_bucket,
                          bucket='newbucket', bucketType='memcached',
                          ramQuotaMB=10)
        self.assertRaises(AssertionError,
                          self.rest.create_bucket,
                          bucket='newbucket', ramQuotaMB=90)
class CouchbaseClient(object):
    #poll server every few seconds to see if the vbucket-map
    #has changes
    def __init__(self, url, bucket, password="", verbose=False,
                 dispatcher=CommandDispatcher):
        self.log = logger("CouchbaseClient")
        self.rest_username = bucket
        self.rest_password = password
        self._memcacheds = {}
        self._vBucketMap = {}
        self._vBucketMap_lock = Lock()
        self._vBucketMapFastForward = {}
        self._vBucketMapFastForward_lock = Lock()
        #TODO: use regular expressions to parse the url
        server = {}
        if not bucket:
            raise InvalidArgumentException("bucket can not be an empty string",
                                           parameters="bucket")
        if not url:
            raise InvalidArgumentException("url can not be an empty string",
                                           parameters="url")
        if (url.find("http://") != -1 and url.rfind(":") != -1 and
                url.find("/pools/default") != -1):
            server["ip"] = (url[url.find("http://")
                            + len("http://"):url.rfind(":")])
            server["port"] = url[url.rfind(":") + 1:url.find("/pools/default")]
            server["username"] = self.rest_username
            server["password"] = self.rest_password
        else:
            raise InvalidArgumentException("invalid url string",
                                           parameters=url)
        self.servers = [server]
        self.servers_lock = Lock()
        self.rest = RestConnection(server)
        self.bucket = self.rest.get_bucket(bucket)
        if self.bucket.vbuckets:
            self.reconfig_vbucket_map()
            self.init_vbucket_connections()
            self.streaming_thread = Thread(name="streaming",
                                           target=self._start_streaming,
                                           args=())
            self.streaming_thread.daemon = True
            self.streaming_thread.start()
        self.dispatcher = dispatcher(self, verbose)
        self.dispatcher_thread = Thread(name="dispatcher-thread",
                                        target=self._start_dispatcher)
        self.dispatcher_thread.daemon = True
        self.dispatcher_thread.start()
        self.verbose = verbose

    def _start_dispatcher(self):
        self.dispatcher.dispatch()

    def _start_streaming(self):
        # This will dynamically update vBucketMap, vBucketMapFastForward,
        # and servers

        response = requests.get("http://%s:%s/pools/default/buckets"
                                "Streaming/%s" % (self.servers[0]["ip"],
                                                  self.servers[0]["port"],
                                                  self.bucket.name))
        for line in response.iter_lines():
            if line:
                data = json.loads(line)

                serverlist = data['vBucketServerMap']['serverList']
                vbucketmapfastforward = {}
                index = 0
                if 'vBucketMapForward' in data['vBucketServerMap']:
                    for vbucket in\
                            data['vBucketServerMap']['vBucketMapForward']:
                        vbucketmapfastforward[index] =\
                            serverlist[vbucket[0]]
                        index += 1
                    self._vBucketMapFastForward_lock.acquire()
                    self._vBucketMapFastForward =\
                        deepcopy(vbucketmapfastforward)
                    self._vBucketMapFastForward_lock.release()
                vbucketmap = {}
                index = 0
                for vbucket in data['vBucketServerMap']['vBucketMap']:
                    vbucketmap[index] = serverlist[vbucket[0]]
                    index += 1

                # only update vBucketMap if we don't have a fastforward
                # on a not_mb_vbucket error, we already update the
                # vBucketMap from the fastforward map
                if not vbucketmapfastforward:
                    self._vBucketMap_lock.acquire()
                    self._vBucketMap = deepcopy(vbucketmap)
                    self._vBucketMap_lock.release()

                new_servers = []
                nodes = data["nodes"]
                for node in nodes:
                    if (node["clusterMembership"] == "active" and
                            node["status"] in ["healthy", "warmup"]):
                        ip, port = node["hostname"].split(":")
                        new_servers.append({"ip": ip,
                                            "port": port,
                                            "username": self.rest_username,
                                            "password": self.rest_password
                                            })
                new_servers.sort()
                self.servers_lock.acquire()
                self.servers = deepcopy(new_servers)
                self.servers_lock.release()

    def init_vbucket_connections(self):
        # start up all vbucket connections
        self._vBucketMap_lock.acquire()
        vbucketcount = len(self._vBucketMap)
        self._vBucketMap_lock.release()
        for i in range(vbucketcount):
            self.start_vbucket_connection(i)

    def start_vbucket_connection(self, vbucket):
        self._vBucketMap_lock.acquire()
        server = deepcopy(self._vBucketMap[vbucket])
        self._vBucketMap_lock.release()
        serverIp, serverPort = server.split(":")
        if not server in self._memcacheds:
            self._memcacheds[server] =\
                MemcachedClientHelper.direct_client(self.rest, serverIp,
                                                    serverPort,
                                                    self.bucket.name)

    def start_vbucket_fastforward_connection(self, vbucket):
        self._vBucketMapFastForward_lock.acquire()
        if not vbucket in self._vBucketMapFastForward:
            self._vBucketMapFastForward_lock.release()
            return
        server = deepcopy(self._vBucketMapFastForward[vbucket])
        self._vBucketMapFastForward_lock.release()
        serverIp, serverPort = server.split(":")
        if not server in self._memcacheds:
            self._memcacheds[server] =\
                MemcachedClientHelper.direct_client(self.rest, serverIp,
                                                    serverPort,
                                                    self.bucket.name)

    def restart_vbucket_connection(self, vbucket):
        self._vBucketMap_lock.acquire()
        server = deepcopy(self._vBucketMap[vbucket])
        self._vBucketMap_lock.release()
        serverIp, serverPort = server.split(":")
        if server in self._memcacheds:
            self._memcacheds[server].close()
        self._memcacheds[server] =\
            MemcachedClientHelper.direct_client(self.rest, serverIp,
                                                serverPort,
                                                self.bucket.name)

    def reconfig_vbucket_map(self, vbucket=-1):
        vb_ready = RestHelper(self.rest).vbucket_map_ready(self.bucket.name,
                                                           60)
        if not vb_ready:
            raise Exception("vbucket map is not ready for bucket %s" %
                            (self.bucket.name))
        vBuckets = self.rest.get_vbuckets(self.bucket.name)
        self.vbucket_count = len(vBuckets)

        self._vBucketMap_lock.acquire()
        for vBucket in vBuckets:
            if vBucket.id == vbucket or vbucket == -1:
                self._vBucketMap[vBucket.id] = vBucket.master
        self._vBucketMap_lock.release()

    def memcached(self, key, fastforward=False):
        self._vBucketMap_lock.acquire()
        self._vBucketMapFastForward_lock.acquire()
        vBucketId = (zlib.crc32(key) >> 16) & (len(self._vBucketMap) - 1)

        if fastforward and vBucketId in self._vBucketMapFastForward:
            # only try the fastforward if we have an entry
            # otherwise we just wait for the main map to update
            self.start_vbucket_fastforward_connection(vBucketId)
            self._vBucketMap[vBucketId] =\
                self._vBucketMapFastForward[vBucketId]

        if vBucketId not in self._vBucketMap:
            msg = "vbucket map does not have an entry for vb : %s"
            self._vBucketMapFastForward_lock.release()
            self._vBucketMap_lock.release()
            raise Exception(msg % (vBucketId))
        if self._vBucketMap[vBucketId] not in self._memcacheds:
            msg = "smart client does not have a mc connection for server : %s"
            self._vBucketMapFastForward_lock.release()
            self._vBucketMap_lock.release()
            raise Exception(msg % (self._vBucketMap[vBucketId]))
        r = self._memcacheds[self._vBucketMap[vBucketId]]
        self._vBucketMapFastForward_lock.release()
        self._vBucketMap_lock.release()
        return r

    def vbucketid(self, key):
        self._vBucketMap_lock.acquire()
        r = (zlib.crc32(key) >> 16) & (len(self._vBucketMap) - 1)
        self._vBucketMap_lock.release()
        return r

    def done(self):
        if self.dispatcher:
            self.dispatcher.shutdown()
            if self.verbose:
                self.log.info("dispatcher shutdown invoked")
            [self._memcacheds[ip].close() for ip in self._memcacheds]
            if self.verbose:
                self.log.info("closed all memcached open connections")
            self.dispatcher = None

    def _respond(self, item, event):
        timeout = 30
        event.wait(timeout)
        if not event.is_set() and 'key' in item:
            # if we timeout, then try to reconnect to the server
            # responsible for this vbucket
            self.restart_vbucket_connection(self.vbucketid(item['key']))
            raise MemcachedTimeoutException(item, timeout)
        if "error" in item["response"]:
            raise item["response"]["error"]
        return item["response"]["return"]

    def get(self, key):
        event = Event()
        item = {"operation": "get", "key": key, "event": event, "response": {}}
        self.dispatcher.put(item)
        return self._respond(item, event)

    def gat(self, key, expiry):
        event = Event()
        item = {"operation": "gat", "key": key, "expiry": expiry,
                "event": event, "response": {}}
        self.dispatcher.put(item)
        return self._respond(item, event)

    def touch(self, key, expiry):
        event = Event()
        item = {"operation": "touch", "key": key, "expiry": expiry,
                "event": event,
                "response": {}}
        self.dispatcher.put(item)
        return self._respond(item, event)

    def cas(self, key, expiry, flags, old_value, value):
        event = Event()
        item = {"operation": "cas", "key": key, "expiry": expiry,
                "flags": flags, "old_value": old_value, "value": value,
                "event": event, "response": {}}
        self.dispatcher.put(item)
        return self._respond(item, event)

    def decr(self, key, amount=1, init=0, expiry=0):
        event = Event()
        item = {"operation": "decr", "key": key, "amount": amount,
                "init": init, "expiry": expiry, "event": event, "response": {}}
        self.dispatcher.put(item)
        return self._respond(item, event)

    def set(self, key, expiry, flags, value):
        event = Event()
        item = {"operation": "set", "key": key, "expiry": expiry,
                "flags": flags, "value": value, "event": event, "response": {}}
        self.dispatcher.put(item)
        return self._respond(item, event)

    def add(self, key, expiry, flags, value):
        event = Event()
        item = {"operation": "add", "key": key, "expiry": expiry,
                "flags": flags, "value": value, "event": event, "response": {}}
        self.dispatcher.put(item)
        return self._respond(item, event)

    def append(self, key, value, cas=0):
        event = Event()
        item = {"operation": "append", "key": key, "cas": cas, "value": value,
                "event": event, "response": {}}
        self.dispatcher.put(item)
        return self._respond(item, event)

    def delete(self, key, cas=0):
        event = Event()
        item = {"operation": "delete", "key": key, "cas": cas, "event": event,
                "response": {}}
        self.dispatcher.put(item)
        return self._respond(item, event)

    def prepend(self, key, value, cas=0):
        event = Event()
        item = {"operation": "prepend", "key": key, "cas": cas, "value": value,
                "event": event, "response": {}}
        self.dispatcher.put(item)
        return self._respond(item, event)

    def getl(self, key, expiry=15):
        event = Event()
        item = {"operation": "getl", "key": key, "expiry": expiry,
                "event": event, "response": {}}
        self.dispatcher.put(item)
        return self._respond(item, event)

    def replace(self, key, expiry, flags, value):
        event = Event()
        item = {"operation": "replace", "key": key, "expiry": expiry,
                "flags": flags, "value": value, "event": event, "response": {}}
        self.dispatcher.put(item)
        return self._respond(item, event)

    def incr(self, key, amount=1, init=0, expiry=0):
        event = Event()
        item = {"operation": "incr", "key": key, "amount": amount,
                "init": init, "expiry": expiry, "event": event, "response": {}}
        self.dispatcher.put(item)
        return self._respond(item, event)

    def flush(self, wait_time=0):
        event = Event()
        item = {"operation": "flush", "expiry": wait_time, "event": event,
                "response": {}}
        self.dispatcher.put(item)
        return self._respond(item, event)
class CouchbaseClientTest(Base):
    def setUp(self):
        super(CouchbaseClientTest, self).setUp()
        self.client = CouchbaseClient(self.url, self.bucket_name, "", True)

    def tearDown(self):
        self.client.done()

    @nottest
    def setup_memcached_bucket(self):
        self.memcached_bucket = 'testing-memcached'
        self.rest_client = RestConnection({
            'ip': self.host,
            'port': self.port,
            'username': self.username,
            'password': self.password
        })
        self.rest_client.create_bucket(self.memcached_bucket,
                                       bucketType='memcached',
                                       authType='sasl',
                                       ramQuotaMB=64)
        self.client_for_memcached_bucket = \
            CouchbaseClient(self.url, self.memcached_bucket, verbose=True)

    @nottest
    def teardown_memcached_bucket(self):
        self.rest_client.delete_bucket(self.memcached_bucket)

    @attr(cbv="1.0.0")
    def test_set_integer_value(self):
        self.client.set('int', 0, 0, 10)
        self.assertEqual(
            self.client.get('int')[2], 10, 'value should be the integer 10')
        self.client.incr('int')
        self.assertEqual(
            self.client.get('int')[2], 11, 'value should be the integer 11')
        self.client.delete('int')

    def test_two_client_incr(self):
        """http://www.couchbase.com/issues/browse/PYCBC-16"""
        key = 'test_two_client_incr'
        client_one = self.client
        client_two = CouchbaseClient(self.url, self.bucket_name, "", True)
        # Client one sets a numeric key
        client_one.set(key, 0, 0, 20)
        # Client two tries to increment this numeric key
        (i, cas) = client_two.incr(key)
        self.assertEqual(i, 21)

        # Client two should be able to keep incrementing this key
        (i, cas) = client_two.incr(key)
        self.assertEqual(i, 22)

        (_, cas, i) = client_two.get(key)
        self.assertEqual(i, 22)
        (i, cas) = client_two.incr(key)
        self.assertEqual(i, 23)

    def test_bucket_of_type_memcached(self):
        self.setup_memcached_bucket()
        self.assertIsInstance(self.client_for_memcached_bucket,
                              CouchbaseClient)
        self.teardown_memcached_bucket()
class RestConnectionTest(unittest.TestCase):
    def setUp(self):
        self.host = config['node-1']['host']
        self.port = config['node-1']['port']
        self.username = config['node-1']['username']
        self.password = config['node-1']['password']
        self.bucket_name = config['node-1']['bucket']
        # list of design_docs for tearDown to destroy, if they've hung around
        self.design_docs = []

    def tearDown(self):
        for ddoc in self.design_docs:
            self.rest.delete_design_doc(self.bucket_name, ddoc)
        pass

    @nottest
    def setup_rest_connection(self):
        server_info = {
            "ip": self.host,
            "port": self.port,
            "username": self.username,
            "password": self.password
        }
        self.rest = RestConnection(server_info)

    @nottest
    def setup_create_design_doc(self):
        self.setup_rest_connection()
        if self.rest.couch_api_base is None:
            raise SkipTest
        ddoc_name = uuid.uuid4()
        design_doc = json.dumps({
            "views": {
                "testing": {
                    "map": "function(doc) { emit(doc._id, null); }"
                }
            }
        })
        resp = self.rest.create_design_doc(self.bucket_name, ddoc_name,
                                           design_doc)
        self.design_docs.append(ddoc_name)
        return ddoc_name, resp

    @nottest
    def setup_vbucketawareclient(self):
        self.client = VBucketAwareClient(self.host, 11210)

    @attr(cbv="1.8.0")
    def test_rest_connection_object_creation(self):
        self.setup_rest_connection()
        self.assertEqual(self.rest.base_url,
                         "http://{0}:{1}".format(self.host, self.port))

    @attr(cbv="1.8.0")
    def test_rest_connection_object_creation_with_server_object(self):
        class ServerInfo:
            ip = self.host
            port = self.port
            rest_username = self.username
            rest_password = self.password

        rest = RestConnection(ServerInfo())
        self.assertEqual(rest.base_url,
                         "http://{0}:{1}".format(self.host, self.port))

    @attr(cbv="2.0.0")
    def test_create_design_doc(self):
        (ddoc_name, resp) = self.setup_create_design_doc()
        self.assertTrue(resp["ok"])

    @attr(cbv="2.0.0")
    def test_get_design_doc(self):
        ddoc_name, resp = self.setup_create_design_doc()
        ddoc = self.rest.get_design_doc(self.bucket_name, ddoc_name)
        self.assertIn("views", ddoc.keys())
        self.assertRaises(Exception, self.rest.get_design_doc,
                          (self.bucket_name, str(uuid.uuid4())))

    @attr(cbv="2.0.0")
    def test_delete_design_doc(self):
        ddoc_name, resp = self.setup_create_design_doc()
        self.assertTrue(
            self.rest.delete_design_doc(self.bucket_name, ddoc_name))
        self.assertRaises(Exception, self.rest.delete_design_doc,
                          (self.bucket_name, ddoc_name))
        self.design_docs = filter(lambda id: id is not ddoc_name,
                                  self.design_docs)

    @attr(cbv="2.0.0")
    def test_get_view(self):
        (ddoc_name, resp) = self.setup_create_design_doc()
        with warnings.catch_warnings(record=True) as w:
            warnings.simplefilter("always")
            # Trigger a warning.
            self.rest.get_view(self.bucket_name, ddoc_name, "testing")
            # Verify some things
            self.assertTrue(len(w) == 1)
            self.assertTrue("deprecated" in str(w[-1].message))

    @attr(cbv="2.0.0")
    def test_view_results(self):
        ddoc_name, resp = self.setup_create_design_doc()
        view = self.rest.view_results(self.bucket_name, ddoc_name, "testing",
                                      {})
        if "error" in view:
            self.fail(view)
        else:
            self.assertIn("rows", view.keys())
        # let's add some sample docs
        self.setup_vbucketawareclient()
        kvs = [(str(uuid.uuid4()), str(uuid.uuid4())) for i in range(0, 100)]
        for k, v in kvs:
            self.client.set(k, 0, 0, v)
        # rerun the view
        view = self.rest.view_results(self.bucket_name, ddoc_name, "testing",
                                      {})
        if "error" in view:
            self.fail(view)
        else:
            self.assertIn("rows", view.keys())
        # remove sample docs
        for k, v in kvs:
            self.client.delete(k)

    @attr(cbv="1.8.0")
    def test_create_headers(self):
        self.setup_rest_connection()
        headers = self.rest._create_headers()
        self.assertEqual(headers['Content-Type'],
                         'application/x-www-form-urlencoded')

    @attr(cbv="1.0.0")
    def test_create_bucket(self):
        self.setup_rest_connection()
        # test membase/couchbase creation defaults
        status = self.rest.create_bucket('newbucket')
        self.assertTrue(status)
        bucket = self.rest.get_bucket('newbucket')
        self.assertEqual(bucket.stats.ram / 1024 / 1024, 100)
        self.assertEqual(bucket.authType, 'sasl')
        self.assertEqual(bucket.type, 'membase')
        self.assertEqual(bucket.numReplicas, 1)
        self.rest.delete_bucket('newbucket')
        # test memcached creation defaults
        status = self.rest.create_bucket(bucket='newbucket',
                                         bucketType='memcached')
        self.assertTrue(status)
        bucket = self.rest.get_bucket('newbucket')
        self.assertEqual(bucket.stats.ram / 1024 / 1024, 100)
        self.assertEqual(bucket.authType, 'sasl')
        self.assertEqual(bucket.type, 'memcached')
        self.assertEqual(bucket.numReplicas, 0)
        # make sure creating an existing bucket fails properly
        self.assertRaises(Exception,
                          self.rest.create_bucket,
                          bucket='newbucket',
                          bucketType='memcached')
        self.rest.delete_bucket('newbucket')
        # test setting ramQuotaMB too low
        self.assertRaises(AssertionError,
                          self.rest.create_bucket,
                          bucket='newbucket',
                          bucketType='memcached',
                          ramQuotaMB=10)
        self.assertRaises(AssertionError,
                          self.rest.create_bucket,
                          bucket='newbucket',
                          ramQuotaMB=90)