Add zookeeper test infrastructure
This adds a per-test zookeeper server fixture and demonstrates its use in preparation for actual zookeeper use. Change-Id: I99ac519057cdd9d9c829928e0e12ece65b0a5c43 Depends-On: I66d2bc90eb350424c051f480b4102209054ce2eb
This commit is contained in:
parent
eed395d637
commit
18f3f4c7bc
@ -109,6 +109,102 @@ class GearmanServerFixture(fixtures.Fixture):
|
||||
raise
|
||||
|
||||
|
||||
class ZookeeperServerFixture(fixtures.Fixture):
|
||||
def __init__(self, port=0):
|
||||
self._port = port
|
||||
|
||||
def setUp(self):
|
||||
super(ZookeeperServerFixture, self).setUp()
|
||||
|
||||
# Get the local port range, we're going to pick one at a time
|
||||
# at random to try.
|
||||
with open('/proc/sys/net/ipv4/ip_local_port_range') as f:
|
||||
line = f.readline()
|
||||
begin, end = map(int, line.split())
|
||||
|
||||
zookeeper_fixtures = os.path.join(os.path.dirname(__file__),
|
||||
'fixtures', 'zookeeper')
|
||||
|
||||
# Make a tmpdir to hold the config file, zookeeper data dir,
|
||||
# and log file.
|
||||
tmp_root = self.useFixture(fixtures.TempDir()).path
|
||||
with open(os.path.join(zookeeper_fixtures, 'log4j.properties')) as i:
|
||||
with open(os.path.join(tmp_root, 'log4j.properties'), 'w') as o:
|
||||
o.write(i.read())
|
||||
|
||||
config_path = os.path.join(tmp_root, 'zoo.cfg')
|
||||
log_path = os.path.join(tmp_root, 'zookeeper.log')
|
||||
|
||||
classpath = [
|
||||
tmp_root,
|
||||
'/usr/share/java/jline.jar',
|
||||
'/usr/share/java/log4j-1.2.jar',
|
||||
'/usr/share/java/xercesImpl.jar',
|
||||
'/usr/share/java/xmlParserAPIs.jar',
|
||||
'/usr/share/java/netty.jar',
|
||||
'/usr/share/java/slf4j-api.jar',
|
||||
'/usr/share/java/slf4j-log4j12.jar',
|
||||
'/usr/share/java/zookeeper.jar',
|
||||
]
|
||||
classpath = ':'.join(classpath)
|
||||
|
||||
args = ['/usr/bin/java', '-cp', classpath,
|
||||
'-Dzookeeper.log.dir=%s' % (tmp_root,),
|
||||
'-Dzookeeper.root.logger=INFO,ROLLINGFILE',
|
||||
'org.apache.zookeeper.server.quorum.QuorumPeerMain',
|
||||
config_path]
|
||||
|
||||
found_port = False
|
||||
|
||||
# Try a random port in the local port range one at a time
|
||||
# until we find one that's available.
|
||||
while not found_port:
|
||||
port = random.randrange(begin, end)
|
||||
|
||||
# Write a config file with this port.
|
||||
with open(os.path.join(zookeeper_fixtures, 'zoo.cfg')) as i:
|
||||
with open(config_path, 'w') as o:
|
||||
o.write(i.read().format(datadir=os.path.join(tmp_root, 'data'),
|
||||
port=port))
|
||||
|
||||
# Run zookeeper.
|
||||
p = subprocess.Popen(args)
|
||||
|
||||
# Wait up to 30 seconds to figure out if it has started.
|
||||
for x in range(30):
|
||||
r = self._checkZKLog(log_path)
|
||||
if r is True:
|
||||
found_port = True
|
||||
break
|
||||
elif r is False:
|
||||
break
|
||||
time.sleep(1)
|
||||
|
||||
if not found_port:
|
||||
p.kill()
|
||||
p.wait()
|
||||
|
||||
if found_port:
|
||||
self.zookeeper_port = port
|
||||
self.zookeeper_process = p
|
||||
self.addCleanup(self.shutdownZookeeper)
|
||||
|
||||
def _checkZKLog(self, path):
|
||||
if not os.path.exists(path):
|
||||
return None
|
||||
with open(path) as f:
|
||||
for line in f:
|
||||
if 'Snapshotting:' in line:
|
||||
return True
|
||||
if 'Address already in use' in line:
|
||||
return False
|
||||
return None
|
||||
|
||||
def shutdownZookeeper(self):
|
||||
self.zookeeper_process.kill()
|
||||
self.zookeeper_process.wait()
|
||||
|
||||
|
||||
class GearmanClient(gear.Client):
|
||||
def __init__(self):
|
||||
super(GearmanClient, self).__init__(client_id='test_client')
|
||||
@ -397,3 +493,11 @@ class DBTestCase(BaseTestCase):
|
||||
class IntegrationTestCase(DBTestCase):
|
||||
def setUpFakes(self):
|
||||
pass
|
||||
|
||||
|
||||
class ZKTestCase(BaseTestCase):
|
||||
def setUp(self):
|
||||
super(ZKTestCase, self).setUp()
|
||||
f = ZookeeperServerFixture()
|
||||
self.useFixture(f)
|
||||
self.zookeeper_port = f.zookeeper_port
|
||||
|
51
nodepool/tests/fixtures/zookeeper/log4j.properties
vendored
Normal file
51
nodepool/tests/fixtures/zookeeper/log4j.properties
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
#
|
||||
# ZooKeeper Logging Configuration
|
||||
#
|
||||
|
||||
# Format is "<default threshold> (, <appender>)+
|
||||
|
||||
log4j.rootLogger=${zookeeper.root.logger}
|
||||
|
||||
# Example: console appender only
|
||||
# log4j.rootLogger=INFO, CONSOLE
|
||||
|
||||
# Example with rolling log file
|
||||
#log4j.rootLogger=DEBUG, CONSOLE, ROLLINGFILE
|
||||
|
||||
# Example with rolling log file and tracing
|
||||
#log4j.rootLogger=TRACE, CONSOLE, ROLLINGFILE, TRACEFILE
|
||||
|
||||
#
|
||||
# Log INFO level and above messages to the console
|
||||
#
|
||||
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
|
||||
log4j.appender.CONSOLE.Threshold=INFO
|
||||
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} - %-5p [%t:%C{1}@%L] - %m%n
|
||||
|
||||
#
|
||||
# Add ROLLINGFILE to rootLogger to get log file output
|
||||
# Log DEBUG level and above messages to a log file
|
||||
log4j.appender.ROLLINGFILE=org.apache.log4j.RollingFileAppender
|
||||
log4j.appender.ROLLINGFILE.Threshold=DEBUG
|
||||
log4j.appender.ROLLINGFILE.File=${zookeeper.log.dir}/zookeeper.log
|
||||
|
||||
# Max log file size of 10MB
|
||||
log4j.appender.ROLLINGFILE.MaxFileSize=10MB
|
||||
# uncomment the next line to limit number of backup files
|
||||
#log4j.appender.ROLLINGFILE.MaxBackupIndex=10
|
||||
|
||||
log4j.appender.ROLLINGFILE.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.ROLLINGFILE.layout.ConversionPattern=%d{ISO8601} - %-5p [%t:%C{1}@%L] - %m%n
|
||||
|
||||
|
||||
#
|
||||
# Add TRACEFILE to rootLogger to get log file output
|
||||
# Log DEBUG level and above messages to a log file
|
||||
log4j.appender.TRACEFILE=org.apache.log4j.FileAppender
|
||||
log4j.appender.TRACEFILE.Threshold=TRACE
|
||||
log4j.appender.TRACEFILE.File=${zookeeper.log.dir}/zookeeper_trace.log
|
||||
|
||||
log4j.appender.TRACEFILE.layout=org.apache.log4j.PatternLayout
|
||||
### Notice we are including log4j's NDC here (%x)
|
||||
log4j.appender.TRACEFILE.layout.ConversionPattern=%d{ISO8601} - %-5p [%t:%C{1}@%L][%x] - %m%n
|
5
nodepool/tests/fixtures/zookeeper/zoo.cfg
vendored
Normal file
5
nodepool/tests/fixtures/zookeeper/zoo.cfg
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
tickTime=2000
|
||||
initLimit=10
|
||||
syncLimit=5
|
||||
dataDir={datadir}
|
||||
clientPort={port}
|
@ -18,6 +18,7 @@ import time
|
||||
import threading
|
||||
|
||||
import fixtures
|
||||
import kazoo.client
|
||||
|
||||
from nodepool import builder, exceptions, fakeprovider, tests
|
||||
|
||||
@ -147,3 +148,9 @@ class TestNodepoolBuilder(tests.DBTestCase):
|
||||
# We failed to upload first_fail_id and have
|
||||
# moved onto another upload that will fail.
|
||||
break
|
||||
|
||||
class TestZookeeper(tests.ZKTestCase):
|
||||
def test_zk(self):
|
||||
zk = kazoo.client.KazooClient(hosts='127.0.0.1:%s' % self.zookeeper_port)
|
||||
zk.start()
|
||||
zk.get('/')
|
||||
|
@ -19,3 +19,4 @@ os-client-config>=1.2.0
|
||||
shade>=0.12.0
|
||||
diskimage-builder
|
||||
voluptuous
|
||||
kazoo
|
||||
|
Loading…
x
Reference in New Issue
Block a user