def info(logger): s = Server() node_hello = s.info() logger.info('== Configuration ==') logger.info('CouchDB: %s ===' % node_hello) logger.info('Target hosts: %s' % NODE_LIST) logger.info('This host''s IP: %s', MY_IP) logger.info('CouchDB expected at port %s' % COUCHDB_PORT) logger.info('Tunnel user for SSH: %s' % TUNNEL_USER) logger.info('Monitoring interval for connections: %s seconds.' % MONITOR_INTERVAL) logger.info('Log path: %s' % LOG_PATH)
class Probe(Process): online = False response_time = 0 logger = None def __init__(self, targets_queue, online_list, offline_list): self.targets_queue = targets_queue # get a reference to the targets holding queue. self.online_list = online_list # get a reference to the online_list for populating it self.offline_list = offline_list # ditto self.logger = configuration.get_logger(logging_instance=connlogging, system_name="connmanager") Thread.__init__(self) def run(self): self.target = self.targets_queue.get() self.dbserver = Server(self.target) try: self.logger.info("Trying: %s" % self.target) start_time = time.time() info = self.dbserver.info() # this is actually the proper request end_time = time.time() except Exception as e: print "CRITICAL: failed connect to %s , %s. Offline!" % (self.target, e) self.logger.info("Failed to connect to [%s]. Out of the online queue!" % self.target) print "Restaring SSH" self.logger.info("Restarting SSH tunnel for %s" % self.target) self.online = False self.offline_list.append(self.target) else: self.logger.info("%s seems online." % self.target) self.online = True self.response_time = end_time - start_time # maintain a list of online nodes, with the response_time as the key # for easy sorting afterwards so we can always re-start replication connections # from fastest reponding node to the rest. self.online_list.append((self.response_time, self.target)) finally: self.logger.info("Probe finsihed.") self.targets_queue.task_done()
class ConflictResolverTestCase(unittest.TestCase): """ Test conflict resolution policy when we're in the state of lag, that is, there's more than 10 minutes time difference between conflicting version of a document: The document with longest rev count wins. If not in a lag, the latest document should win. """ database_name = 'session_store' repdb_name = 'session_store_rep' s = None db = None repdb = None docid = 'testing_doc' doc = None replicated_doc = None source_rev_count = 0 def setUp(self): """ Creating connection to the database according to configuration, and creating docs that act in test. """ self.s = Server('http://localhost:5984') assert len(self.s.info())!=0, 'CouchDB server is down or not working properly.' self.db = self.s.get_or_create_db(self.database_name) self.repdb = self.s.get_or_create_db(self.repdb_name) self.doc = {'_id': self.docid, 'timestamp': str(int(round(time.time()))), 'text' : 'initial text', 'rev_count': str(self.source_rev_count)} # clear previous test residual if self.docid in self.db: self.db.delete_doc(self.docid) if self.docid in self.repdb: self.repdb.delete_doc(self.docid) self.db.save_doc(self.doc) def tearDown(self): pass
class ClientServerTestCase(unittest.TestCase): def setUp(self): self.couchdb = CouchdbResource() self.Server = Server() def tearDown(self): try: del self.Server["couchdbkit_test"] del self.Server["couchdbkit/test"] except: pass def testGetInfo(self): info = self.Server.info() self.assertIn("version", info) def testCreateDb(self): res = self.Server.create_db("couchdbkit_test") self.assertIsInstance(res, Database) all_dbs = self.Server.all_dbs() self.assertIn("couchdbkit_test", all_dbs) del self.Server["couchdbkit_test"] res = self.Server.create_db("couchdbkit/test") self.assertIn("couchdbkit/test", self.Server.all_dbs()) del self.Server["couchdbkit/test"] def testGetOrCreateDb(self): # create the database gocdb = self.Server.get_or_create_db("get_or_create_db") self.assertEqual(gocdb.dbname, "get_or_create_db") self.assertIn("get_or_create_db", self.Server) self.Server.delete_db("get_or_create_db") # get the database (already created) self.assertNotIn("get_or_create_db", self.Server) db = self.Server.create_db("get_or_create_db") self.assertIn("get_or_create_db", self.Server) gocdb = self.Server.get_or_create_db("get_or_create_db") self.assertEqual(db.dbname, gocdb.dbname) self.Server.delete_db("get_or_create_db") def testCreateInvalidDbName(self): def create_invalid(): res = self.Server.create_db("123ab") self.assertRaises(ValueError, create_invalid) def testServerLen(self): res = self.Server.create_db("couchdbkit_test") self.assertGreaterEqual(len(self.Server), 1) self.assertTrue(self.Server) del self.Server["couchdbkit_test"] def testServerContain(self): res = self.Server.create_db("couchdbkit_test") self.assertIn("couchdbkit_test", self.Server) del self.Server["couchdbkit_test"] def testGetUUIDS(self): uuid = self.Server.next_uuid() self.assertIsInstance(uuid, basestring) self.assertEqual(len(self.Server._uuids), 999) uuid2 = self.Server.next_uuid() self.assertNotEqual(uuid, uuid2) self.assertEqual(len(self.Server._uuids), 998)
logger.info('This host''s IP: %s', MY_IP) logger.info('CouchDB expected at port %s' % COUCHDB_PORT) logger.info('Tunnel user for SSH: %s' % TUNNEL_USER) logger.info('Monitoring interval for connections: %s seconds.' % MONITOR_INTERVAL) logger.info('Log path: %s' % LOG_PATH) if __name__ == "__main__": ''' Have a main entry point so configuration.py could be used to upload Relaxession configuration to CouchDB , and CouchDB will be used for the configuration storage and propogation to all nodes. ''' s = Server() node_hello = s.info() logger = get_logger(logging_instance=logging, system_name=SYSTEM_NAME, logging_level=LOGGING_LEVEL, logging_format=LOGGING_FORMAT) info(logger) parser = OptionParser() parser.add_option("--sync", help="Sync the configuration data from configuration.py to CouchDB. " "This starts a propogation process to all nodes in the NODE_LIST " "And the configuration changes handler will pull them and apply " "at each node's end. This will have to either trigger a restart " "of the ConnectionManager or refresh the config vars in memory " "and continue then. Remains to taken care by the implementation.") parser.add_option("--local-sync", help="Like --sync, but sync up against the local CouchDB only. " "Useful when you want to experiment with config values without " "affecting the remote nodes.")