You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by vi...@apache.org on 2016/03/22 00:01:11 UTC
mesos git commit: Added upgrade testing script.
Repository: mesos
Updated Branches:
refs/heads/master f4bfd4bd6 -> ed7037390
Added upgrade testing script.
Review: https://reviews.apache.org/r/44229/
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/ed703739
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/ed703739
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/ed703739
Branch: refs/heads/master
Commit: ed70373900e5044c19022a47c790b955c45e1426
Parents: f4bfd4b
Author: Greg Mann <gr...@mesosphere.io>
Authored: Mon Mar 21 15:59:07 2016 -0700
Committer: Vinod Kone <vi...@gmail.com>
Committed: Mon Mar 21 16:00:59 2016 -0700
----------------------------------------------------------------------
support/test-upgrade.py | 254 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 254 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/ed703739/support/test-upgrade.py
----------------------------------------------------------------------
diff --git a/support/test-upgrade.py b/support/test-upgrade.py
new file mode 100755
index 0000000..99c8e76
--- /dev/null
+++ b/support/test-upgrade.py
@@ -0,0 +1,254 @@
+#!/usr/bin/env python
+
+import argparse
+import os
+import subprocess
+import sys
+import tempfile
+import time
+
+DEFAULT_PRINCIPAL = 'foo'
+DEFAULT_SECRET = 'bar'
+
+# Helper class to keep track of process lifecycles, i.e., starting processes,
+# capturing output, and checking liveness during delays/sleep.
+class Process:
+
+ def __init__(self, args, environment=None):
+ outfile = tempfile.mktemp()
+ fout = open(outfile, 'w')
+ print 'Run %s, output: %s' % (args, outfile)
+
+ # TODO(nnielsen): Enable glog verbose logging.
+ self.process = subprocess.Popen(args,
+ stdout=fout,
+ stderr=subprocess.STDOUT,
+ env=environment)
+
+ # Polls the process for the specified number of seconds, returning the
+ # process's return value if it ends during that time. Returns `True` if the
+ # process is still running after that time period.
+ def sleep(self, seconds):
+ poll_time = 0.1
+ while seconds > 0:
+ seconds -= poll_time
+ time.sleep(poll_time)
+ poll = self.process.poll()
+ if poll != None:
+ return poll
+ return True
+
+ def __del__(self):
+ if self.process.poll() == None:
+ self.process.kill()
+
+
+# Class representing a agent process.
+class Agent(Process):
+
+ def __init__(self, path, work_dir, credfile):
+ Process.__init__(self, [os.path.join(path, 'bin', 'mesos-slave.sh'),
+ '--master=127.0.0.1:5050',
+ '--credential=' + credfile,
+ '--work_dir=' + work_dir,
+ '--resources=disk:2048;mem:2048;cpus:2'])
+ pass
+
+
+# Class representing a master process.
+class Master(Process):
+
+ def __init__(self, path, work_dir, credfile):
+ Process.__init__(self, [os.path.join(path, 'bin', 'mesos-master.sh'),
+ '--ip=127.0.0.1',
+ '--work_dir=' + work_dir,
+ '--authenticate',
+ '--credentials=' + credfile,
+ '--roles=test'])
+ pass
+
+
+# Class representing a framework instance (the test-framework for now).
+#
+# TODO(greggomann): Add support for multiple frameworks.
+class Framework(Process):
+
+ def __init__(self, path):
+ # The test-framework can take these parameters as environment variables,
+ # but not as command-line parameters.
+ environment = {
+ 'MESOS_BUILD_DIR': path,
+ 'MESOS_AUTHENTICATE': '1',
+ 'DEFAULT_PRINCIPAL': DEFAULT_PRINCIPAL,
+ 'DEFAULT_SECRET': DEFAULT_SECRET
+ }
+
+ Process.__init__(self, [os.path.join(path, 'src', 'test-framework'),
+ '--master=127.0.0.1:5050'], environment)
+ pass
+
+
+# Convenience function to get the Mesos version from the built executables.
+def version(path):
+ p = subprocess.Popen([os.path.join(path, 'bin', 'mesos-master.sh'),
+ '--version'],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ output, err = p.communicate()
+ rc = p.returncode
+ if rc != 0:
+ return False
+
+ return output[:-1]
+
+
+# Script to test the upgrade path between two versions of Mesos.
+#
+# TODO(nnielsen): Add support for zookeeper and failover of master.
+# TODO(nnielsen): Add support for testing scheduler live upgrade/failover.
+if __name__ == '__main__':
+ parser = argparse.ArgumentParser(description='Test upgrade path between two mesos builds')
+ parser.add_argument('--prev',
+ type=str,
+ help='Build path to mesos version to upgrade from',
+ required=True)
+
+ parser.add_argument('--next',
+ type=str,
+ help='Build path to mesos version to upgrade to',
+ required=True)
+ args = parser.parse_args()
+
+ prev_path = args.prev
+ next_path = args.next
+
+ # Get the version strings from the built executables.
+ prev_version = version(prev_path)
+ next_version = version(next_path)
+
+ if prev_version == False or next_version == False:
+ print 'Could not get mesos version numbers'
+ sys.exit(1)
+
+ # Write credentials to temporary file.
+ credfile = tempfile.mktemp()
+ with open(credfile, 'w') as fout:
+ fout.write(DEFAULT_PRINCIPAL + ' ' + DEFAULT_SECRET)
+
+ # Create a work directory for the master.
+ master_work_dir = tempfile.mkdtemp()
+
+ # Create a work directory for the agent.
+ agent_work_dir = tempfile.mkdtemp()
+
+ print 'Running upgrade test from %s to %s' % (prev_version, next_version)
+
+ print """\
++--------------+----------------+----------------+---------------+
+| Test case | Framework | Master | Agent |
++--------------+----------------+----------------+---------------+
+| #1 | %s\t| %s\t | %s\t |
+| #2 | %s\t| %s\t | %s\t |
+| #3 | %s\t| %s\t | %s\t |
+| #4 | %s\t| %s\t | %s\t |
++--------------+----------------+----------------+---------------+
+
+NOTE: live denotes that master process keeps running from previous case.
+ """ % (prev_version, prev_version, prev_version,
+ prev_version, next_version, prev_version,
+ prev_version, next_version, next_version,
+ next_version, next_version, next_version)
+
+ print ''
+ print 'Test case 1 (Run of previous setup)'
+ print '##### Starting %s master #####' % prev_version
+
+ prev_master = Master(prev_path, master_work_dir, credfile)
+ if prev_master.sleep(0.5) != True:
+ print '%s master exited prematurely' % prev_version
+ sys.exit(1)
+
+ print '##### Starting %s agent #####' % prev_version
+
+ prev_agent = Agent(prev_path, agent_work_dir, credfile)
+ if prev_agent.sleep(0.5) != True:
+ print '%s agent exited prematurely' % prev_version
+ sys.exit(1)
+
+ print '##### Starting %s framework #####' % prev_version
+ print 'Waiting for %s framework to complete (10 sec max)...' % prev_version
+ prev_framework = Framework(prev_path)
+ if prev_framework.sleep(10) != 0:
+ print '%s framework failed' % prev_version
+ sys.exit(1)
+
+
+ print ''
+ print 'Test case 2 (Upgrade master)'
+
+ # NOTE: Need to stop and start the agent because standalone detector does
+ # not detect master failover.
+ print '##### Stopping %s agent #####' % prev_version
+ prev_agent.process.kill()
+
+ print '##### Stopping %s master #####' % prev_version
+ prev_master.process.kill()
+
+ print '##### Starting %s master #####' % next_version
+ next_master = Master(next_path, master_work_dir, credfile)
+ if next_master.sleep(0.5) != True:
+ print '%s master exited prematurely' % next_version
+ sys.exit(1)
+
+ print '##### Starting %s agent #####' % prev_version
+ prev_agent = Agent(prev_path, agent_work_dir, credfile)
+ if prev_agent.sleep(0.5) != True:
+ print '%s agent exited prematurely' % prev_version
+ sys.exit(1)
+
+ print '##### Starting %s framework #####' % prev_version
+ print 'Waiting for %s framework to complete (10 sec max)...' % prev_version
+ prev_framework = Framework(prev_path)
+ if prev_framework.sleep(10) != 0:
+ print '%s framework failed with %s master and %s agent' % (prev_version,
+ next_version,
+ prev_version)
+ sys.exit(1)
+
+
+ print ''
+ print 'Test case 3 (Upgrade agent)'
+
+ print '##### Stopping %s agent #####' % prev_version
+ prev_agent.process.kill()
+
+ print '##### Starting %s agent #####' % next_version
+ next_agent = Agent(next_path, agent_work_dir, credfile)
+ if next_agent.sleep(0.5) != True:
+ print '%s agent exited prematurely' % next_version
+ sys.exit(1)
+
+ print '##### Starting %s framework #####' % prev_version
+ print 'Waiting for %s framework to complete (10 sec max)...' % prev_version
+ prev_framework = Framework(prev_path)
+ if prev_framework.sleep(10) != 0:
+ print '%s framework failed with %s master and %s agent' % (prev_version,
+ next_version,
+ next_version)
+ sys.exit(1)
+
+
+ print ''
+ print 'Test case 4 (Run of next setup)'
+
+ print '##### Starting %s framework #####' % next_version
+ print 'Waiting for %s framework to complete (10 sec max)...' % next_version
+ next_framework = Framework(next_path)
+ if next_framework.sleep(10) != 0:
+ print '%s framework failed with %s master and %s agent' % (next_version,
+ next_version,
+ next_version)
+ sys.exit(1)
+
+ # Test passed.
+ sys.exit(0)