diff --git a/integration-tests/settings.py b/integration-tests/settings.py new file mode 100644 index 0000000000000000000000000000000000000000..acff00acff90893dfe87a67b05f08e30ab2447da --- /dev/null +++ b/integration-tests/settings.py @@ -0,0 +1,29 @@ +""" +Setup infrastructure common for all tests. +""" +import sys +import os.path +import time + +# Base URL of the CI server which hosts the artifacts. +CI_BASE_URL = 'http://bs-ci01.ethz.ch:8090' + +reuseRepository = False +cmd = sys.argv[0] +if len(sys.argv) > 1: + firstArgument = sys.argv[1] + if firstArgument == '-r': + reuseRepository = True + if firstArgument == '-h': + print "Usage: %s [-h|-r]\n-h: prints this help\n-r: reuses artifact repository" % os.path.basename(cmd) + exit(1) + +dirname = os.path.dirname(cmd) +sys.path.append("%s/source" % dirname) +sys.path.append("%s/sourceTest" % dirname) + +from systemtest.artifactrepository import JenkinsArtifactRepository + +REPOSITORY = JenkinsArtifactRepository(CI_BASE_URL, "%s/targets/artifact-repository" % dirname) +if not reuseRepository: + REPOSITORY.clear() diff --git a/integration-tests/source/systemtest/artifactrepository.py b/integration-tests/source/systemtest/artifactrepository.py index 72590b594a7bb7a8bfb4d6a10e0a5c19409bfe2a..1ad924d11d73d9a3c158d5cf98457fc115172032 100644 --- a/integration-tests/source/systemtest/artifactrepository.py +++ b/integration-tests/source/systemtest/artifactrepository.py @@ -17,6 +17,7 @@ class ArtifactRepository(): self.localRepositoryFolder = localRepositoryFolder if not os.path.exists(localRepositoryFolder): os.makedirs(localRepositoryFolder) + print "Artifact repository: %s" % localRepositoryFolder def clear(self): """ @@ -26,6 +27,7 @@ class ArtifactRepository(): path = "%s/%s" % (self.localRepositoryFolder, f) if os.path.isfile(path): os.remove(path) + print "Artifact repository cleared." def getPathToArtifact(self, project, pattern='.*'): """ @@ -37,7 +39,7 @@ class ArtifactRepository(): """ files = [f for f in os.listdir(self.localRepositoryFolder) if re.match(pattern, f)] if len(files) > 1: - raise Exception("More than one artifact in '%s' matches the pattern '%': %s" + raise Exception("More than one artifact in '%s' matches the pattern '%s': %s" % (self.localRepositoryFolder, pattern, files)) if len(files) == 0: f = self.downloadArtifact(project, pattern) diff --git a/integration-tests/source/systemtest/testcase.py b/integration-tests/source/systemtest/testcase.py new file mode 100644 index 0000000000000000000000000000000000000000..19194238552806f1819f510060242359e230efcf --- /dev/null +++ b/integration-tests/source/systemtest/testcase.py @@ -0,0 +1,94 @@ +import os +import os.path +import shutil +import subprocess +import time +import traceback + +import util + +INSTALLER_PROJECT = 'gradle-installation' +OPENBIS_STANDARD_TECHNOLOGIES_PROJECT = 'gradle-openbis-standard-technologies' +PLAYGROUND = 'targets/playground' + +class TestCase(): + def __init__(self, artifactRepository, filePath): + self.artifactRepository = artifactRepository + self.project = None + fileName = os.path.basename(filePath) + self.name = fileName[0:fileName.rfind('.')] + self.playgroundFolder = "%s/%s" % (PLAYGROUND, self.name) + if os.path.exists(self.playgroundFolder): + shutil.rmtree(self.playgroundFolder) + os.makedirs(self.playgroundFolder) + + def runTest(self): + """ + Runs this test case. This is a final method. It should not be overwritten. + """ + startTime = time.time() + print "\n/''''''''''''''''''' %s started at %s ''''''''''" % (self.name, time.strftime('%Y-%m-%d %H:%M:%S')) + try: + self.execute() + success = True + except: + traceback.print_exc() + success = False + raise Exception("%s failed" % self.name) + finally: + duration = time.time() - startTime + if success: + print "\...........SUCCESS: %s executed in %d seconds .........." % (self.name, duration) + else: + print "\............FAILED: %s executed in %d seconds .........." % (self.name, duration) + + def execute(self): + """ + Executes this test case. This is an abstract method which has to be overwritten in subclasses. + """ + pass + + def installOpenbis(self, instanceName = 'openbis', technologies = []): + """ + Installs openBIS from the installer. The instanceName specifies the subfolder in the playground folder + where the instance will be installed. The technologies are an array of enabled technologies. + An instance of OpenbisController is returned. + """ + installerPath = self.artifactRepository.getPathToArtifact(INSTALLER_PROJECT, 'openBIS-installation') + installerFileName = os.path.basename(installerPath).split('.')[0] + exitValue = subprocess.call(['tar', '-zxf', installerPath, '-C', self.playgroundFolder]) + if exitValue > 0: raise Exception("Couldn't untar openBIS installer.") + consolePropertiesFile = "%s/%s/console.properties" % (self.playgroundFolder, installerFileName) + consoleProperties = util.readProperties(consolePropertiesFile) + installPath = os.path.abspath("%s/%s" % (self.playgroundFolder, instanceName)) + consoleProperties['INSTALL_PATH'] = installPath + consoleProperties['DSS_ROOT_DIR'] = "%s/data" % installPath + for technology in technologies: + consoleProperties[technology.upper()] = True + util.writeProperties(consolePropertiesFile, consoleProperties) + p = subprocess.Popen("%s/%s/run-console.sh" % (self.playgroundFolder, installerFileName), stdin = subprocess.PIPE) + p.communicate('admin\nadmin') + exitValue = p.wait() + if exitValue > 0: raise Exception("Couldn't install openBIS.") + return OpenbisController(installPath) + + def _getAndCreateFolder(self, folderPath): + """ + Creates a folder inside the playground. The argument is a relative path to the playground. + The returned path is relative to the working directory. + """ + path = "%s/%s" % (self.playgroundFolder, folderPath) + os.makedirs(path) + return path + +class OpenbisController(): + """ + Class to control AS and DSS of an installed openBIS instance. + """ + def __init__(self, installPath): + self.installPath = installPath + self.asServicePropertiesFile = "%s/servers/openBIS-server/jetty/etc/service.properties" % installPath + self.asProperties = util.readProperties(self.asServicePropertiesFile) + self.dssServicePropertiesFile = "%s/servers/datastore_server/etc/service.properties" % installPath + self.dssProperties = util.readProperties(self.dssServicePropertiesFile) + diff --git a/integration-tests/source/systemtest/util.py b/integration-tests/source/systemtest/util.py new file mode 100644 index 0000000000000000000000000000000000000000..18d1acb012de9c744c6d40f8a092b4465a95ba3e --- /dev/null +++ b/integration-tests/source/systemtest/util.py @@ -0,0 +1,22 @@ +def readProperties(propertiesFile): + """ + Reads a Java properties file and returns the key-value pairs as a dictionary. + """ + with open(propertiesFile, "r") as f: + result = {} + for line in f.readlines(): + trimmedLine = line.lstrip().rstrip() + if len(trimmedLine) > 0 and not trimmedLine.startswith('#'): + splittedLine = line.split('=', 1) + key = splittedLine[0].lstrip().rstrip() + value = splittedLine[1].lstrip().rstrip() + result[key] = value + return result + +def writeProperties(propertiesFile, dictionary): + """ + Saves the specified dictionary as a Java dictionary file. + """ + with open(propertiesFile, "w") as f: + for key, value in dictionary.iteritems(): + f.write("%s=%s\n" % (key, value)) diff --git a/integration-tests/sourceTest/systemtest/__init__.py b/integration-tests/sourceTest/systemtest/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/integration-tests/sourceTest/systemtest/artifactrepository_test.py b/integration-tests/sourceTest/systemtest/artifactrepository_test.py new file mode 100644 index 0000000000000000000000000000000000000000..7ca09aef3adfb43c5a4d638dd990cb94fc9cc978 --- /dev/null +++ b/integration-tests/sourceTest/systemtest/artifactrepository_test.py @@ -0,0 +1,15 @@ +import unittest + +from systemtest.artifactrepository import ArtifactRepository +from testcasewithfiles import TestCaseWithFiles + + +class ArtifactRepositoryTest(TestCaseWithFiles): + def setUp(self): + self.testRepository = ArtifactRepository(self.createPath("test-repository")) + + def test_clear(self): + self.testRepository.clear() + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff --git a/integration-tests/sourceTest/systemtest/testcasewithfiles.py b/integration-tests/sourceTest/systemtest/testcasewithfiles.py new file mode 100644 index 0000000000000000000000000000000000000000..c75a5d5ca061ea30e27cbfb43ab6950181f785ba --- /dev/null +++ b/integration-tests/sourceTest/systemtest/testcasewithfiles.py @@ -0,0 +1,17 @@ +import os +import os.path +import shutil +import unittest + +class TestCaseWithFiles(unittest.TestCase): + workspace = 'targets/python-test-workspace' + + def setUp(self): + shutil.rmtree("%s/%s" % (self.workspace, self.__class__.__name__)) + + def createPath(self, relativePath): + path = "%s/%s/%s" % (self.workspace, self.__class__.__name__, relativePath) + parent = os.path.dirname(path) + if not os.path.exists(parent): + os.makedirs(parent) + return path diff --git a/integration-tests/sourceTest/systemtest/util_test.py b/integration-tests/sourceTest/systemtest/util_test.py new file mode 100644 index 0000000000000000000000000000000000000000..43b9d248ab455168b44d1e9cac9b39cce0bc508c --- /dev/null +++ b/integration-tests/sourceTest/systemtest/util_test.py @@ -0,0 +1,31 @@ +import unittest + +import systemtest.util as util +from testcasewithfiles import TestCaseWithFiles + + +class UtilTest(TestCaseWithFiles): + def test_readProperties(self): + example = self.createPath("my.properties") + with open(example, "w") as out: + out.write("# a comment\n\n") + out.write(" \n") + out.write(" alpha = beta \n") + out.write(" non=\n") + + keyValuePairs = util.readProperties(example) + + self.assertEqual('beta', keyValuePairs['alpha']) + self.assertEqual('', keyValuePairs['non']) + self.assertEqual(2, len(keyValuePairs)) + + def test_writeProperties(self): + example = self.createPath("my.props") + + util.writeProperties(example, {'alpha': 4711, 'beta': 'hello'}) + + with open(example, "r") as f: + self.assertEqual(['alpha=4711\n', 'beta=hello\n'], sorted(f.readlines())) + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff --git a/integration-tests/test.py b/integration-tests/test.py new file mode 100755 index 0000000000000000000000000000000000000000..e16000437bebdb5f5f1ebacbd8d0be977d453944 --- /dev/null +++ b/integration-tests/test.py @@ -0,0 +1,36 @@ +#!/usr/bin/python +""" +Runs all test cases in alphabetical order. A test case is a file of type '.py' and starts with 'test-'. +Exit value will 0 if all test cases succeeded otherwise it will be 1. +""" +import os +import os.path +import sys +import time + +import settings + +startTime = time.time() +numberOfTestCases = 0 +numberOfFailedTestCases = 0 +for f in sorted(os.listdir(os.path.dirname(__file__))): + splittedFileName = f.rsplit('.', 1) + if len(splittedFileName) > 1: + moduleName = splittedFileName[0] + fileType = splittedFileName[1] + if moduleName.startswith('test_') and fileType == 'py': + numberOfTestCases += 1 + try: + __import__(moduleName) + except: + numberOfFailedTestCases += 1 +print '=====================================' +print "%d test cases executed in %d seconds" % (numberOfTestCases, time.time() - startTime) +if numberOfFailedTestCases == 0: + print "no test case failed" + exit(0) +if numberOfFailedTestCases == 1: + print "1 test case failed" +else: + print "%d test cases failed" % numberOfFailedTestCases +exit(1) diff --git a/integration-tests/test_screening.py b/integration-tests/test_screening.py new file mode 100755 index 0000000000000000000000000000000000000000..0640a034f59a3687a6e8bd208f3449ea0be24268 --- /dev/null +++ b/integration-tests/test_screening.py @@ -0,0 +1,11 @@ +#!/usr/bin/python +import settings +import systemtest.testcase + +class TestCase(systemtest.testcase.TestCase): + def execute(self): + openbisController = self.installOpenbis(technologies = ['screening']) + print openbisController.asProperties + +TestCase(settings.REPOSITORY, __file__).runTest() + diff --git a/integration-tests/test_yeastx.py b/integration-tests/test_yeastx.py new file mode 100755 index 0000000000000000000000000000000000000000..592c6c9a2401113bafe38fa5e664da3f78b9d370 --- /dev/null +++ b/integration-tests/test_yeastx.py @@ -0,0 +1,10 @@ +#!/usr/bin/python +import settings +import systemtest.testcase + +class TestCase(systemtest.testcase.TestCase): + def execute(self): + self.installOpenbis() + +TestCase(settings.REPOSITORY, __file__).runTest() +