[asterisk-scf-commits] asterisk-scf/integration/testsuite.git branch "review" updated.
Commits to the Asterisk SCF project code repositories
asterisk-scf-commits at lists.digium.com
Tue Jul 5 17:18:53 CDT 2011
branch "review" has been updated
via 17583677312131bee0a3452ff4340c35f328a1cc (commit)
via 3b9d4d8dc2bd4ebedd5e98669598953df061bbd2 (commit)
from ebf408db54bc8a590c5922fd2ad469aa80d8856a (commit)
Summary of changes:
lib/python/TestSuite.py | 18 ++--
lib/python/file.py | 4 +-
lib/python/plugins.py | 27 ++++--
plugins/asteriskscf_configurator.py | 2 +-
plugins/asteriskscf_icebox.py | 2 +-
plugins/build.py | 2 +-
plugins/failover.py | 170 ++++++----------------------------
plugins/protos.py | 2 +-
plugins/sipp.py | 2 +-
plugins/testsuite_remotes.py | 2 +-
plugins/wireshark.py | 2 +-
remote.py | 4 +-
testsuite.py | 6 +-
13 files changed, 70 insertions(+), 173 deletions(-)
- Log -----------------------------------------------------------------
commit 17583677312131bee0a3452ff4340c35f328a1cc
Author: Darren Sessions <dsessions at digium.com>
Date: Tue Jul 5 17:18:50 2011 -0500
Updated the remote test-suite script to provide platform and arch along with the ipv4 and ipv6 addresses in order that plugins, such as failover, can send the proper sequence / syntax.
diff --git a/remote.py b/remote.py
index e0bd0cf..5a16cbf 100755
--- a/remote.py
+++ b/remote.py
@@ -297,8 +297,8 @@ class RemoteManagement(object):
f.close()
return results
- def whatAreMyIps(self):
- return (ipv4addr, ipv6addr)
+ def getHostInfo(self):
+ return (ipv4addr, ipv6addr, plat, arch)
def reset(self):
return 1
commit 3b9d4d8dc2bd4ebedd5e98669598953df061bbd2
Author: Darren Sessions <dsessions at digium.com>
Date: Tue Jul 5 09:49:47 2011 -0500
Added the ability to have config files for plugins. This is particularly useful with the failover plugin as it allows you to specify ip address pools in one file that can then be used throughout the individual test cases while still providing a single yaml file to edit should you need to change anything instead of having to edit individual test cases (which is becoming a lengthly process).
diff --git a/lib/python/TestSuite.py b/lib/python/TestSuite.py
index 54d0f74..b596936 100644
--- a/lib/python/TestSuite.py
+++ b/lib/python/TestSuite.py
@@ -20,16 +20,16 @@ import subprocess
from urlparse import urlparse
class utils():
- def run(self, testData, testPath, globalVars):
+ def run(self, testData, testPath, globalVars, pluginData):
self.RPC.globalVars = globalVars
- return self.baseClass(testData, testPath, globalVars)
+ return self.baseClass(testData, testPath, globalVars, pluginData)
def ping(self, host):
process = subprocess.Popen(
'ping -c1 %s' % host,
- #stdin=subprocess.PIPE,
- #stdout=subprocess.PIPE,
- #stderr=subprocess.PIPE,
+ stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
shell=True)
process.wait()
if process.returncode == 0:
@@ -152,7 +152,7 @@ class utils():
return {'success':True, 'repoName':repoName, 'repoType':'%s' % url[0]}
class BaseClass(utils):
- def baseClass(self, testData, testPath, globalVars):
+ def baseClass(self, testData, testPath, globalVars, pluginData):
if globalVars['testSuccess'] == False:
if 'run_on_test_failure' in testData:
if testData['run_on_test_failure'] == False:
@@ -161,10 +161,10 @@ class BaseClass(utils):
return {'success':False,'msg':'Test has already failed.'}
if not 'cmd' in testData:
return {'success':False,'msg':'No command specified.'}
- return self.main(testData, testPath, globalVars)
+ return self.main(testData, testPath, globalVars, pluginData)
class RemoteBaseClass(utils):
- def baseClass(self, testData, testPath, globalVars):
+ def baseClass(self, testData, testPath, globalVars, pluginData):
if globalVars['testSuccess'] == False:
if 'run_on_test_failure' in testData:
if testData['run_on_test_failure'] == False:
@@ -178,4 +178,4 @@ class RemoteBaseClass(utils):
rpc = self.RPC().connect(testData['testsuite_remote_host'])
if rpc['success'] == False:
return rpc
- return self.main(testData, testPath, globalVars, rpc)
+ return self.main(testData, testPath, globalVars, pluginData, rpc)
diff --git a/lib/python/file.py b/lib/python/file.py
index c51e5f6..30c7e79 100644
--- a/lib/python/file.py
+++ b/lib/python/file.py
@@ -28,9 +28,9 @@ class file:
try:
f = open('%s' % fn, 'r')
except IOError:
- return {'success':False, 'msg':'Failed to open file for reading: %s' % cwd}
+ return {'success':False, 'msg':'Failed to open file for reading: %s' % fn}
except:
- return {'success':False, 'msg':'Unexpected error: %s' % sys.exc_info()[0]}
+ return {'success':False, 'msg':'Unexpected error: %s' % sys.exc_info()[1]}
else:
fc = f.read()
f.close()
diff --git a/lib/python/plugins.py b/lib/python/plugins.py
index 5017c09..8061674 100644
--- a/lib/python/plugins.py
+++ b/lib/python/plugins.py
@@ -14,28 +14,31 @@ import imp
import sys
import inspect
+import file
+
class plugins:
- def execute(self, name, module, testData, testPath, globalVars):
+ def execute(self, name, pluginData, testData, testPath, globalVars):
try:
- func = getattr(module, 'plugin')
+ func = getattr(pluginData['module'], 'plugin')
except AttributeError:
return {'success':False,'msg':"Unable to execute module '%s'. %s" % (name, sys.exc_info()[1])}
else:
- results = func().run(testData, testPath, globalVars)
+ results = func().run(testData, testPath, globalVars, pluginData)
if not type(results) == dict:
return {'success':False,'msg':"The '%s' module return invalid or missing data." % name}
return results
- def init(self, name):
- loadResults = self.load(name)
- if not loadResults['success'] == True:
+ def init(self, name, globalVars):
+ loadResults = self.load(name, globalVars)
+ if loadResults['success'] == False:
return loadResults
checkResults = self.check(name, loadResults['module'])
- if not checkResults['success'] == True:
+ if checkResults['success'] == False:
return checkResults
return loadResults
- def load(self, name):
+ def load(self, name, globalVars):
+ pluginConfig = None
try:
return {'success':True,'module':sys.modules[name]}
except KeyError:
@@ -45,7 +48,11 @@ class plugins:
except ImportError:
return {'success':False,'msg':'%s' % sys.exc_info()[1]}
try:
- return {'success':True,'module':imp.load_module(name, fp, pathName, desc)}
+ pluginConfig = '%s/configs/%s.conf' % (globalVars['cwd'], name)
+ results = file.file().read(pluginConfig)
+ if results['success'] == True:
+ pluginConfig = results['fd']
+ return {'success':True, 'module':imp.load_module(name, fp, pathName, desc), 'pluginConfigFile':pluginConfig}
finally:
if fp:
fp.close()
@@ -58,7 +65,7 @@ class plugins:
except:
return {'success':False,'msg':'The "main" method in the "plugin" class in "%s" is not responding properly. %s.' % (name, sys.exc_info())}
argCheck = inspect.getargspec(module.plugin().main)
- if argCheck[0] != ['self','testData', 'testPath', 'globalVars'] and argCheck[0] != ['self','testData', 'testPath', 'globalVars', 'remote']:
+ if argCheck[0] != ['self','testData', 'testPath', 'globalVars', 'pluginData'] and argCheck[0] != ['self','testData', 'testPath', 'globalVars', 'pluginData', 'remote']:
return {'success':False,'msg':"The 'main' method in the 'plugin' class within '%s' has improperly labeled args! i.e. def main(self, testData, testPath, globalVars)." % name}
return {'success':True}
diff --git a/plugins/asteriskscf_configurator.py b/plugins/asteriskscf_configurator.py
index 51ada43..b3673bb 100644
--- a/plugins/asteriskscf_configurator.py
+++ b/plugins/asteriskscf_configurator.py
@@ -19,7 +19,7 @@ sys.path.append('/opt/Ice-3.4.1/python')
import Ice
class plugin(TestSuite.BaseClass):
- def main(self, testData, testPath, globalVars):
+ def main(self, testData, testPath, globalVars, pluginData):
if globalVars['mode'] == 'docs':
rpc = self.RPC().connect('testsuite-remote-1.digium.internal')
for cmd in testData['cmd']:
diff --git a/plugins/asteriskscf_icebox.py b/plugins/asteriskscf_icebox.py
index beaa13d..3b4b302 100644
--- a/plugins/asteriskscf_icebox.py
+++ b/plugins/asteriskscf_icebox.py
@@ -12,7 +12,7 @@
import TestSuite
class plugin(TestSuite.RemoteBaseClass):
- def main(self, testData, testPath, globalVars, remote):
+ def main(self, testData, testPath, globalVars, pluginData, remote):
iceBoxCmd = ['/opt/Ice-3.4.1/bin/icebox', '--Ice.Config=!!TMP!!/']
''' start and stop individual components. shutdown is implemented in the main testsuite code '''
diff --git a/plugins/build.py b/plugins/build.py
index 12a422b..fcc0ba3 100644
--- a/plugins/build.py
+++ b/plugins/build.py
@@ -12,7 +12,7 @@
import TestSuite
class plugin(TestSuite.RemoteBaseClass):
- def main(self, testData, testPath, globalVars, remote):
+ def main(self, testData, testPath, globalVars, pluginData, remote):
if not 'repo' in testData['cmd']:
return {'success':False,'msg':'No repo specified.'}
diff --git a/plugins/failover.py b/plugins/failover.py
index c65ebd7..4b2e430 100644
--- a/plugins/failover.py
+++ b/plugins/failover.py
@@ -12,83 +12,39 @@
import time
import TestSuite
+import yaml_parser
+
class plugin(TestSuite.BaseClass):
- def main(self, testData, testPath, globalVars):
- corosyncExec = ['corosync','-f']
- pacemakerExec = ['pacemaker']
+ def main(self, testData, testPath, globalVars, pluginData):
- shutdownList = [testData['cmd']['testsuite_remote_active'], testData['cmd']['testsuite_remote_standby']]
+ for cmd in testData['cmd']:
+ if cmd == 'assign':
+ if not 'active_testsuite_remote_host' in testData['cmd'] or not 'standby_testsuite_remote_host' in testData['cmd']:
+ return {'success':False,'msg':'Both active and standby remote hosts must be specified.','shutdownExempt':True}
- activeNode = {}
- standbyNode = {}
+ if not 'shared_ip_label' in testData['cmd']:
+ return {'success':False,'msg':'A label must be specified to assign a shared ip.','shutdownExempt':True}
- if not 'testsuite_remote_active' in testData['cmd']:
- return {'success':False,'msg':'No testsuite-remote specified for the active failover configuration.','shutdownExempt':True}
+ sharedIP = testData['cmd']['shared_ip']
+ if self.ping(sharedIP):
+ return {'success':False, 'msg':'The %s shared ip address is responding before cluster services have been started.' % sharedIP, 'shutdownList':shutdownList}
- if not 'testsuite_remote_standby' in testData['cmd']:
- return {'success':False,'msg':'No testsuite-remote specified for the standby failover configuration.','shutdownExempt':True}
+ continue
- if not 'ipv4oripv6' in testData['cmd']:
- return {'success':False,'msg':'No ip version specified.','shutdownExempt':True}
- else:
- if not testData['cmd']['ipv4oripv6'] == 'ipv4' and not testData['cmd']['ipv4oripv6'] == 'ipv6':
- return {'success':False,'msg':'IP version must be ipv4 or ipv6.','shutdownExempt':True}
- else:
- ipv = testData['cmd']['ipv4oripv6']
-
- if not 'shared_ip' in testData['cmd']:
- return {'success':False,'msg':'No shared IP address specified.','shutdownExempt':True}
- else:
- sharedIP = testData['cmd']['shared_ip']
- if self.ping(sharedIP):
- return {'success':False, 'msg':'The %s shared ip address is responding before cluster services have been started.' % sharedIP, 'shutdownList':shutdownList}
- if ipv and not 'ipv4_network_addr' in testData['cmd']:
- return {'success':False,'msg':'The ipv4_network_addr must be specified on IPv4 networks.','shutdownExempt':True}
- else:
- if ipv == 'ipv4':
- activeNode['nAddr'] = testData['cmd']['ipv4_network_addr']
- standbyNode['nAddr'] = testData['cmd']['ipv4_network_addr']
- elif ipv == 'ipv6':
- activeNode['nAddr'] = 'fc00:1::1'
- standbyNode['nAddr'] = 'fc00:1::2'
-
- results = self.rpc(testData['cmd']['testsuite_remote_active'])
- if not results['success'] == True:
- return self._addShutdownList(results, shutdownList)
- else:
- activeNode['rpc'] = results['rpc']
- activeNode['nodeID'] = '0'
- (activeNode['ipv4'], activeNode['ipv6']) = activeNode['rpc'].whatAreMyIps()
+ results = self.RPC().connect(testData['cmd']['testsuite_remote_active'])
+ if not results['success'] == True:
+ return self._addShutdownList(results, shutdownList)
+ else:
+ activeNode = results
+ activeNode['nodeID'] = '0'
- results = self.rpc(testData['cmd']['testsuite_remote_standby'])
- if not results['success'] == True:
- return self._addShutdownList(results, shutdownList)
- else:
- standbyNode['rpc'] = results['rpc']
- standbyNode['nodeID'] = '1'
- (standbyNode['ipv4'], standbyNode['ipv6']) = standbyNode['rpc'].whatAreMyIps()
-
- results = activeNode['rpc'].wFile('/etc/corosync/corosync.conf', '\n'.join(self._corosyncConfig(activeNode[ipv], standbyNode[ipv], activeNode['nodeID'], activeNode['nAddr'])))
- if not results['success'] == True:
- return self._addShutdownList(results, shutdownList)
- results = activeNode['rpc'].run(globalVars, 'failover', 'corosync', ['service', 'corosync', 'start'], True)
- if not results['success'] == True:
- return self._addShutdownList(results, shutdownList)
-
- standbyNode['rpc'].wFile('/etc/corosync/corosync.conf', '\n'.join(self._corosyncConfig(activeNode[ipv], standbyNode[ipv], standbyNode['nodeID'], standbyNode['nAddr'])))
- if not results['success'] == True:
- return self._addShutdownList(results, shutdownList)
- results = standbyNode['rpc'].run(globalVars, 'failover', 'corosync', ['service', 'corosync', 'start'], True)
- if not results['success'] == True:
- return self._addShutdownList(results, shutdownList)
-
- time.sleep(100)
-
- activeNode['rpc'].writeFile('pacemaker.cli', '\n'.join(self._pacemakerConfig(sharedIP, testData['cmd']['testsuite_remote_active'])))
- if not results['success'] == True:
- return self._addShutdownList(results, shutdownList)
- results = activeNode['rpc'].run(globalVars, 'failover', 'crm', ['crm', '-f', '!!TMP!!/pacemaker.cli'], True)
+ results = self.RPC().connect(testData['cmd']['testsuite_remote_standby'])
+ if not results['success'] == True:
+ return self._addShutdownList(results, shutdownList)
+ else:
+ standbyNode = results
+ standbyNode['nodeID'] = '1'
if not self.ping(sharedIP):
return {'success':False, 'msg':'The %s shared ip address is failing to respond.' % sharedIP, 'shutdownList':shutdownList}
@@ -99,75 +55,9 @@ class plugin(TestSuite.BaseClass):
results['shutdownList'] = shutdownList
return results
- def _corosyncConfig(self, activeIP, standbyIP, nodeID, networkAddr):
- config = [
- 'compatibility: whitetank',
- 'totem {',
- ' version: 2',
- ' token: 160',
- ' token_retransmits_before_loss_const: 3',
- ' join: 30',
- ' consensus: 300',
- ' max_messages: 20',
- ' threads: 0',
- ' secauth: off',
- ' nodeid: %s' % nodeID,
- ' interface {',
- ' member {',
- ' memberaddr: %s' % activeIP,
- ' }',
- ' member {',
- ' memberaddr: %s' % standbyIP,
- ' }',
- ' ringnumber: 0',
- ' bindnetaddr: %s' % networkAddr,
- ' mcastaddr: 226.94.1.1',
- ' mcastport: 5405',
- ' ttl: 1',
- ' }',
- ' transport: udpu',
- '}',
- 'amf {',
- ' mode: disabled',
- '}',
- 'service {',
- ' ver: 0',
- ' name: pacemaker',
- '}',
- 'aisexec {',
- ' user: root',
- ' group: root',
- '}',
- 'logging {',
- ' fileline: off',
- ' to_stderr: yes',
- ' to_logfile: no',
- ' to_syslog: yes',
- ' syslog_facility: daemon',
- ' debug: off',
- ' timestamp: on',
- ' logger_subsys {',
- ' subsys: AMF',
- ' debug: off',
- ' tags: enter|leave|trace1|trace2|trace3|trace4|trace6',
- ' }',
- '}']
- return config
-
- def _pacemakerConfig(self, sharedIP, activeHost):
- config = [
- 'resource stop failover-ip',
- 'configure',
- 'erase',
- 'commit',
- 'property cluster-infrastructure="openais"',
- 'property expected-quorum-votes="2"',
- 'property stonith-enabled=false',
- 'property no-quorum-policy="ignore"',
- 'property default-resource-stickiness="infinity"',
- 'commit',
- 'primitive failover-ip ocf:heartbeat:IPaddr params ip="%s" op monitor interval=1s meta is-managed="true" target-role="Started"' % sharedIP,
- 'location cli-prefer-failover-ip failover-ip rule $id="cli-prefer-rule-failover-ip" inf: #uname eq %s' % activeHost,
- 'commit']
- return config
+ def platformAssignCmd(self, platform):
+ if platform == 'Linux':
+ pass
+ else:
+ return {'success':False, 'msg':'The %s platform is currently not supported within the failover plugin.'}
diff --git a/plugins/protos.py b/plugins/protos.py
index 9302324..7a641d3 100644
--- a/plugins/protos.py
+++ b/plugins/protos.py
@@ -13,7 +13,7 @@ import time
import TestSuite
class plugin(TestSuite.RemoteBaseClass):
- def main(self, testData, testPath, globalVars, remote):
+ def main(self, testData, testPath, globalVars, pluginData, remote):
if not 'cmd' in testData:
return {'success':False,'msg':'No command specified.'}
diff --git a/plugins/sipp.py b/plugins/sipp.py
index b497d10..d86626d 100644
--- a/plugins/sipp.py
+++ b/plugins/sipp.py
@@ -12,7 +12,7 @@
import TestSuite
class plugin(TestSuite.BaseClass):
- def main(self, testData, testPath, globalVars):
+ def main(self, testData, testPath, globalVars, pluginData):
self.hosts = {}
config = {}
diff --git a/plugins/testsuite_remotes.py b/plugins/testsuite_remotes.py
index 23da04a..b680e3b 100644
--- a/plugins/testsuite_remotes.py
+++ b/plugins/testsuite_remotes.py
@@ -14,7 +14,7 @@ import time
import TestSuite
class plugin(TestSuite.BaseClass):
- def main(self, testData, testPath, globalVars):
+ def main(self, testData, testPath, globalVars, pluginData):
rpc = {}
''' start and stop individual components. shutdown is implemented in the main testsuite code '''
for cmd in testData['cmd']:
diff --git a/plugins/wireshark.py b/plugins/wireshark.py
index 6d61bf3..cace55f 100644
--- a/plugins/wireshark.py
+++ b/plugins/wireshark.py
@@ -13,7 +13,7 @@
import TestSuite
class plugin(TestSuite.RemoteBaseClass):
- def main(self, testData, testPath, globalVars, remote):
+ def main(self, testData, testPath, globalVars, pluginData, remote):
rpc = {}
protos = []
hostFilter = []
diff --git a/testsuite.py b/testsuite.py
index c271569..957be00 100755
--- a/testsuite.py
+++ b/testsuite.py
@@ -135,8 +135,8 @@ class __main__:
''' import plugins '''
for plugin in [plugin for timeLine in subTestCase[testName]['timeline'] for plugin in timeLine]:
- pluginData[plugin] = plugins.plugins().init(plugin)
- if not pluginData[plugin]['success'] == True:
+ pluginData[plugin] = plugins.plugins().init(plugin, self.globalVars)
+ if pluginData[plugin]['success'] == False:
errorMsgs.append(pluginData[plugin]['msg'])
success = False
@@ -149,7 +149,7 @@ class __main__:
for timeLine in subTestCase[testName]['timeline']:
for plugin in timeLine:
self.globalVars['testInfo']['testPlugin'] = plugin
- runResults = plugins.plugins().execute(plugin, pluginData[plugin]['module'], timeLine[plugin], testData['path'], self.globalVars)
+ runResults = plugins.plugins().execute(plugin, pluginData[plugin], timeLine[plugin], testData['path'], self.globalVars)
if self.globalVars['mode'] == 'testing':
if not 'shutdownList' in runResults:
if not 'shutdownExempt' in runResults:
-----------------------------------------------------------------------
--
asterisk-scf/integration/testsuite.git
More information about the asterisk-scf-commits
mailing list