<commit_before>#!/usr/bin/env python

import os, re, sys, time, traceback

# doctest is included in the same package as this module, because this testing
# framework uses features only available in the Python 2.4 version of doctest,
# and Django aims to work with Python 2.3+.
import doctest

MODEL_TESTS_DIR_NAME = 'modeltests'
OTHER_TESTS_DIR = "othertests"
TEST_DATABASE_NAME = 'django_test_db'

error_list = []
def log_error(model_name, title, description):
    error_list.append({
        'title': "%r module: %s" % (model_name, title),
        'description': description,
    })

MODEL_TEST_DIR = os.path.join(os.path.dirname(__file__), MODEL_TESTS_DIR_NAME)

def get_test_models():
    return [f for f in os.listdir(MODEL_TEST_DIR) if not f.startswith('__init__') and not f.startswith('.')]

class DjangoDoctestRunner(doctest.DocTestRunner):
    def __init__(self, verbosity_level, *args, **kwargs):
        self.verbosity_level = verbosity_level
        doctest.DocTestRunner.__init__(self, *args, **kwargs)
        self._checker = DjangoDoctestOutputChecker()
        self.optionflags = doctest.ELLIPSIS

    def report_start(self, out, test, example):
        if self.verbosity_level > 1:
            out("  >>> %s\n" % example.source.strip())

    def report_failure(self, out, test, example, got):
        log_error(test.name, "API test failed",
            "Code: %r\nLine: %s\nExpected: %r\nGot: %r" % (example.source.strip(), example.lineno, example.want, got))

    def report_unexpected_exception(self, out, test, example, exc_info):
        from django.db import transaction
        tb = ''.join(traceback.format_exception(*exc_info)[1:])
        log_error(test.name, "API test raised an exception",
            "Code: %r\nLine: %s\nException: %s" % (example.source.strip(), example.lineno, tb))
        # Rollback, in case of database errors. Otherwise they'd have
        # side effects on other tests.
        transaction.rollback_unless_managed()

normalize_long_ints = lambda s: re.sub(r'(?<![\w])(\d+)L(?![\w])', '\\1', s)

class DjangoDoctestOutputChecker(doctest.OutputChecker):
    def check_output(self, want, got, optionflags):
        ok = doctest.OutputChecker.check_output(self, want, got, optionflags)

        # Doctest does an exact string comparison of output, which means long
        # integers aren't equal to normal integers ("22L" vs. "22"). The
        # following code normalizes long integers so that they equal normal
        # integers.
        if not ok:
            return normalize_long_ints(want) == normalize_long_ints(got)
        return ok

class TestRunner:
    def __init__(self, verbosity_level=0, which_tests=None):
        self.verbosity_level = verbosity_level
        self.which_tests = which_tests

    def output(self, required_level, message):
        if self.verbosity_level > required_level - 1:
            print message

    def run_tests(self):
        from django.conf import settings

	# An empty access of the settings to force the default options to be
	# installed prior to assigning to them.
	settings.INSTALLED_APPS

        # Manually set INSTALLED_APPS to point to the test models.
        settings.INSTALLED_APPS = [MODEL_TESTS_DIR_NAME + '.' + a for a in get_test_models()]

        # Manually set DEBUG = False.
        settings.DEBUG = False

        from django.db import connection
        from django.core import management
        import django.db.models

        # Determine which models we're going to test.
        test_models = get_test_models()
        if 'othertests' in self.which_tests:
            self.which_tests.remove('othertests')
            run_othertests = True
            if not self.which_tests:
                test_models = []
        else:
            run_othertests = not self.which_tests

        if self.which_tests:
            # Only run the specified tests.
            bad_models = [m for m in self.which_tests if m not in test_models]
            if bad_models:
                sys.stderr.write("Models not found: %s\n" % bad_models)
                sys.exit(1)
            else:
                test_models = self.which_tests

        self.output(0, "Running tests with database %r" % settings.DATABASE_ENGINE)

        # If we're using SQLite, it's more convenient to test against an
        # in-memory database.
        if settings.DATABASE_ENGINE == "sqlite3":
            global TEST_DATABASE_NAME
            TEST_DATABASE_NAME = ":memory:"
        else:
            # Create the test database and connect to it. We need autocommit()
            # because PostgreSQL doesn't allow CREATE DATABASE statements
            # within transactions.
            cursor = connection.cursor()
            try:
                connection.connection.autocommit(1)
            except AttributeError:
                pass
            self.output(1, "Creating test database")
            try:
                cursor.execute("CREATE DATABASE %s" % TEST_DATABASE_NAME)
            except Exception, e:
                sys.stderr.write("Got an error creating the test database: %s\n" % e)
                confirm = raw_input("It appears the test database, %s, already exists. Type 'yes' to delete it, or 'no' to cancel: " % TEST_DATABASE_NAME)
                if confirm == 'yes':
                    cursor.execute("DROP DATABASE %s" % TEST_DATABASE_NAME)
                    cursor.execute("CREATE DATABASE %s" % TEST_DATABASE_NAME)
                else:
                    print "Tests cancelled."
                    return
        connection.close()
        old_database_name = settings.DATABASE_NAME
        settings.DATABASE_NAME = TEST_DATABASE_NAME

        # Initialize the test database.
        cursor = connection.cursor()

        # Run the tests for each test model.
        self.output(1, "Running app tests")
        for model_name in test_models:
            self.output(1, "%s model: Importing" % model_name)
            try:
                # TODO: Abstract this into a meta.get_app() replacement?
                mod = __import__(MODEL_TESTS_DIR_NAME + '.' + model_name + '.models', '', '', [''])
            except Exception, e:
                log_error(model_name, "Error while importing", ''.join(traceback.format_exception(*sys.exc_info())[1:]))
                continue

            if not getattr(mod, 'error_log', None):
                # Model is not marked as an invalid model
                self.output(1, "%s model: Installing" % model_name)
                management.install(mod)

                # Run the API tests.
                p = doctest.DocTestParser()
                test_namespace = dict([(m._meta.object_name, m) \
                                        for m in django.db.models.get_models(mod)])
                dtest = p.get_doctest(mod.API_TESTS, test_namespace, model_name, None, None)
                # Manually set verbose=False, because "-v" command-line parameter
                # has side effects on doctest TestRunner class.
                runner = DjangoDoctestRunner(verbosity_level=verbosity_level, verbose=False)
                self.output(1, "%s model: Running tests" % model_name)
                runner.run(dtest, clear_globs=True, out=sys.stdout.write)
            else:
                # Check that model known to be invalid is invalid for the right reasons.
                self.output(1, "%s model: Validating" % model_name)

                from cStringIO import StringIO
                s = StringIO()
                count = management.get_validation_errors(s, mod)
                s.seek(0)
                error_log = s.read()
                actual = error_log.split('\n')
                expected = mod.error_log.split('\n')

                unexpected = [err for err in actual if err not in expected]
                missing = [err for err in expected if err not in actual]

                if unexpected or missing:
                    unexpected_log = '\n'.join(unexpected)
                    missing_log = '\n'.join(missing)
                    log_error(model_name,
                        "Validator found %d validation errors, %d expected" % (count, len(expected) - 1),
                        "Missing errors:\n%s\n\nUnexpected errors:\n%s" % (missing_log, unexpected_log))

        if run_othertests:
            # Run the non-model tests in the other tests dir
            self.output(1, "Running other tests")
            other_tests_dir = os.path.join(os.path.dirname(__file__), OTHER_TESTS_DIR)
            test_modules = [f[:-3] for f in os.listdir(other_tests_dir) if f.endswith('.py') and not f.startswith('__init__')]
            for module in test_modules:
                self.output(1, "%s module: Importing" % module)
                try:
                    mod = __import__("othertests." + module, '', '', [''])
                except Exception, e:
                    log_error(module, "Error while importing", ''.join(traceback.format_exception(*sys.exc_info())[1:]))
                    continue
                if mod.__doc__:
                    p = doctest.DocTestParser()
                    dtest = p.get_doctest(mod.__doc__, mod.__dict__, module, None, None)
                    runner = DjangoDoctestRunner(verbosity_level=verbosity_level, verbose=False)
                    self.output(1, "%s module: running tests" % module)
                    runner.run(dtest, clear_globs=True, out=sys.stdout.write)
                if hasattr(mod, "run_tests") and callable(mod.run_tests):
                    self.output(1, "%s module: running tests" % module)
                    try:
                        mod.run_tests(verbosity_level)
                    except Exception, e:
                        log_error(module, "Exception running tests", ''.join(traceback.format_exception(*sys.exc_info())[1:]))
                        continue

        # Unless we're using SQLite, remove the test database to clean up after
        # ourselves. Connect to the previous database (not the test database)
        # to do so, because it's not allowed to delete a database while being
        # connected to it.
        if settings.DATABASE_ENGINE != "sqlite3":
            connection.close()
            settings.DATABASE_NAME = old_database_name
            cursor = connection.cursor()
            self.output(1, "Deleting test database")
            try:
                connection.connection.autocommit(1)
            except AttributeError:
                pass
            else:
                time.sleep(1) # To avoid "database is being accessed by other users" errors.
            cursor.execute("DROP DATABASE %s" % TEST_DATABASE_NAME)

        # Display output.
        if error_list:
            for d in error_list:
                print
                print d['title']
                print "=" * len(d['title'])
                print d['description']
            print "%s error%s:" % (len(error_list), len(error_list) != 1 and 's' or '')
        else:
            print "All tests passed."

if __name__ == "__main__":
    from optparse import OptionParser
    usage = "%prog [options] [model model model ...]"
    parser = OptionParser(usage=usage)
    parser.add_option('-v', help='How verbose should the output be? Choices are 0, 1 and 2, where 2 is most verbose. Default is 0.',
        type='choice', choices=['0', '1', '2'])
    parser.add_option('--settings',
        help='Python path to settings module, e.g. "myproject.settings". If this isn\'t provided, the DJANGO_SETTINGS_MODULE environment variable will be used.')
    options, args = parser.parse_args()
    verbosity_level = 0
    if options.v:
        verbosity_level = int(options.v)
    if options.settings:
        os.environ['DJANGO_SETTINGS_MODULE'] = options.settings
    t = TestRunner(verbosity_level, args)
    t.run_tests()
<commit_msg>Fixed whitespace in tests/runtests.py<commit_after>#!/usr/bin/env python

import os, re, sys, time, traceback

# doctest is included in the same package as this module, because this testing
# framework uses features only available in the Python 2.4 version of doctest,
# and Django aims to work with Python 2.3+.
import doctest

MODEL_TESTS_DIR_NAME = 'modeltests'
OTHER_TESTS_DIR = "othertests"
TEST_DATABASE_NAME = 'django_test_db'

error_list = []
def log_error(model_name, title, description):
    error_list.append({
        'title': "%r module: %s" % (model_name, title),
        'description': description,
    })

MODEL_TEST_DIR = os.path.join(os.path.dirname(__file__), MODEL_TESTS_DIR_NAME)

def get_test_models():
    return [f for f in os.listdir(MODEL_TEST_DIR) if not f.startswith('__init__') and not f.startswith('.')]

class DjangoDoctestRunner(doctest.DocTestRunner):
    def __init__(self, verbosity_level, *args, **kwargs):
        self.verbosity_level = verbosity_level
        doctest.DocTestRunner.__init__(self, *args, **kwargs)
        self._checker = DjangoDoctestOutputChecker()
        self.optionflags = doctest.ELLIPSIS

    def report_start(self, out, test, example):
        if self.verbosity_level > 1:
            out("  >>> %s\n" % example.source.strip())

    def report_failure(self, out, test, example, got):
        log_error(test.name, "API test failed",
            "Code: %r\nLine: %s\nExpected: %r\nGot: %r" % (example.source.strip(), example.lineno, example.want, got))

    def report_unexpected_exception(self, out, test, example, exc_info):
        from django.db import transaction
        tb = ''.join(traceback.format_exception(*exc_info)[1:])
        log_error(test.name, "API test raised an exception",
            "Code: %r\nLine: %s\nException: %s" % (example.source.strip(), example.lineno, tb))
        # Rollback, in case of database errors. Otherwise they'd have
        # side effects on other tests.
        transaction.rollback_unless_managed()

normalize_long_ints = lambda s: re.sub(r'(?<![\w])(\d+)L(?![\w])', '\\1', s)

class DjangoDoctestOutputChecker(doctest.OutputChecker):
    def check_output(self, want, got, optionflags):
        ok = doctest.OutputChecker.check_output(self, want, got, optionflags)

        # Doctest does an exact string comparison of output, which means long
        # integers aren't equal to normal integers ("22L" vs. "22"). The
        # following code normalizes long integers so that they equal normal
        # integers.
        if not ok:
            return normalize_long_ints(want) == normalize_long_ints(got)
        return ok

class TestRunner:
    def __init__(self, verbosity_level=0, which_tests=None):
        self.verbosity_level = verbosity_level
        self.which_tests = which_tests

    def output(self, required_level, message):
        if self.verbosity_level > required_level - 1:
            print message

    def run_tests(self):
        from django.conf import settings

        # An empty access of the settings to force the default options to be
        # installed prior to assigning to them.
        settings.INSTALLED_APPS

        # Manually set INSTALLED_APPS to point to the test models.
        settings.INSTALLED_APPS = [MODEL_TESTS_DIR_NAME + '.' + a for a in get_test_models()]

        # Manually set DEBUG = False.
        settings.DEBUG = False

        from django.db import connection
        from django.core import management
        import django.db.models

        # Determine which models we're going to test.
        test_models = get_test_models()
        if 'othertests' in self.which_tests:
            self.which_tests.remove('othertests')
            run_othertests = True
            if not self.which_tests:
                test_models = []
        else:
            run_othertests = not self.which_tests

        if self.which_tests:
            # Only run the specified tests.
            bad_models = [m for m in self.which_tests if m not in test_models]
            if bad_models:
                sys.stderr.write("Models not found: %s\n" % bad_models)
                sys.exit(1)
            else:
                test_models = self.which_tests

        self.output(0, "Running tests with database %r" % settings.DATABASE_ENGINE)

        # If we're using SQLite, it's more convenient to test against an
        # in-memory database.
        if settings.DATABASE_ENGINE == "sqlite3":
            global TEST_DATABASE_NAME
            TEST_DATABASE_NAME = ":memory:"
        else:
            # Create the test database and connect to it. We need autocommit()
            # because PostgreSQL doesn't allow CREATE DATABASE statements
            # within transactions.
            cursor = connection.cursor()
            try:
                connection.connection.autocommit(1)
            except AttributeError:
                pass
            self.output(1, "Creating test database")
            try:
                cursor.execute("CREATE DATABASE %s" % TEST_DATABASE_NAME)
            except Exception, e:
                sys.stderr.write("Got an error creating the test database: %s\n" % e)
                confirm = raw_input("It appears the test database, %s, already exists. Type 'yes' to delete it, or 'no' to cancel: " % TEST_DATABASE_NAME)
                if confirm == 'yes':
                    cursor.execute("DROP DATABASE %s" % TEST_DATABASE_NAME)
                    cursor.execute("CREATE DATABASE %s" % TEST_DATABASE_NAME)
                else:
                    print "Tests cancelled."
                    return
        connection.close()
        old_database_name = settings.DATABASE_NAME
        settings.DATABASE_NAME = TEST_DATABASE_NAME

        # Initialize the test database.
        cursor = connection.cursor()

        # Run the tests for each test model.
        self.output(1, "Running app tests")
        for model_name in test_models:
            self.output(1, "%s model: Importing" % model_name)
            try:
                # TODO: Abstract this into a meta.get_app() replacement?
                mod = __import__(MODEL_TESTS_DIR_NAME + '.' + model_name + '.models', '', '', [''])
            except Exception, e:
                log_error(model_name, "Error while importing", ''.join(traceback.format_exception(*sys.exc_info())[1:]))
                continue

            if not getattr(mod, 'error_log', None):
                # Model is not marked as an invalid model
                self.output(1, "%s model: Installing" % model_name)
                management.install(mod)

                # Run the API tests.
                p = doctest.DocTestParser()
                test_namespace = dict([(m._meta.object_name, m) \
                                        for m in django.db.models.get_models(mod)])
                dtest = p.get_doctest(mod.API_TESTS, test_namespace, model_name, None, None)
                # Manually set verbose=False, because "-v" command-line parameter
                # has side effects on doctest TestRunner class.
                runner = DjangoDoctestRunner(verbosity_level=verbosity_level, verbose=False)
                self.output(1, "%s model: Running tests" % model_name)
                runner.run(dtest, clear_globs=True, out=sys.stdout.write)
            else:
                # Check that model known to be invalid is invalid for the right reasons.
                self.output(1, "%s model: Validating" % model_name)

                from cStringIO import StringIO
                s = StringIO()
                count = management.get_validation_errors(s, mod)
                s.seek(0)
                error_log = s.read()
                actual = error_log.split('\n')
                expected = mod.error_log.split('\n')

                unexpected = [err for err in actual if err not in expected]
                missing = [err for err in expected if err not in actual]

                if unexpected or missing:
                    unexpected_log = '\n'.join(unexpected)
                    missing_log = '\n'.join(missing)
                    log_error(model_name,
                        "Validator found %d validation errors, %d expected" % (count, len(expected) - 1),
                        "Missing errors:\n%s\n\nUnexpected errors:\n%s" % (missing_log, unexpected_log))

        if run_othertests:
            # Run the non-model tests in the other tests dir
            self.output(1, "Running other tests")
            other_tests_dir = os.path.join(os.path.dirname(__file__), OTHER_TESTS_DIR)
            test_modules = [f[:-3] for f in os.listdir(other_tests_dir) if f.endswith('.py') and not f.startswith('__init__')]
            for module in test_modules:
                self.output(1, "%s module: Importing" % module)
                try:
                    mod = __import__("othertests." + module, '', '', [''])
                except Exception, e:
                    log_error(module, "Error while importing", ''.join(traceback.format_exception(*sys.exc_info())[1:]))
                    continue
                if mod.__doc__:
                    p = doctest.DocTestParser()
                    dtest = p.get_doctest(mod.__doc__, mod.__dict__, module, None, None)
                    runner = DjangoDoctestRunner(verbosity_level=verbosity_level, verbose=False)
                    self.output(1, "%s module: running tests" % module)
                    runner.run(dtest, clear_globs=True, out=sys.stdout.write)
                if hasattr(mod, "run_tests") and callable(mod.run_tests):
                    self.output(1, "%s module: running tests" % module)
                    try:
                        mod.run_tests(verbosity_level)
                    except Exception, e:
                        log_error(module, "Exception running tests", ''.join(traceback.format_exception(*sys.exc_info())[1:]))
                        continue

        # Unless we're using SQLite, remove the test database to clean up after
        # ourselves. Connect to the previous database (not the test database)
        # to do so, because it's not allowed to delete a database while being
        # connected to it.
        if settings.DATABASE_ENGINE != "sqlite3":
            connection.close()
            settings.DATABASE_NAME = old_database_name
            cursor = connection.cursor()
            self.output(1, "Deleting test database")
            try:
                connection.connection.autocommit(1)
            except AttributeError:
                pass
            else:
                time.sleep(1) # To avoid "database is being accessed by other users" errors.
            cursor.execute("DROP DATABASE %s" % TEST_DATABASE_NAME)

        # Display output.
        if error_list:
            for d in error_list:
                print
                print d['title']
                print "=" * len(d['title'])
                print d['description']
            print "%s error%s:" % (len(error_list), len(error_list) != 1 and 's' or '')
        else:
            print "All tests passed."

if __name__ == "__main__":
    from optparse import OptionParser
    usage = "%prog [options] [model model model ...]"
    parser = OptionParser(usage=usage)
    parser.add_option('-v', help='How verbose should the output be? Choices are 0, 1 and 2, where 2 is most verbose. Default is 0.',
        type='choice', choices=['0', '1', '2'])
    parser.add_option('--settings',
        help='Python path to settings module, e.g. "myproject.settings". If this isn\'t provided, the DJANGO_SETTINGS_MODULE environment variable will be used.')
    options, args = parser.parse_args()
    verbosity_level = 0
    if options.v:
        verbosity_level = int(options.v)
    if options.settings:
        os.environ['DJANGO_SETTINGS_MODULE'] = options.settings
    t = TestRunner(verbosity_level, args)
    t.run_tests()
<|endoftext|>


<commit_before>#!/usr/bin/env python

import os
import re
import sys
import glob
import subprocess
from ctypes import c_int
from multiprocessing import Process, Lock, Value, BoundedSemaphore, cpu_count

#---------------------------------------------------------------------
# Extract scenarios from the specified test
def runTest(test):
    global dirname
    global results
    # test has the format of '.*/suites/<suite_name>/src/<test_name>(.erl)?'
    # Split the test in suite and name components using pattern matching
    rest1, name = os.path.split(test)
    rest2 = os.path.split(rest1)[0]
    suite = os.path.split(rest2)[1]
    name = os.path.splitext(name)[0]
    if os.path.isdir(test):
        # Our test is a multi module directory
        dirn = test     # directory
        modn = "test"   # module name
        files = glob.glob(dirn + "/*.erl")
    else:
        dirn = rest1
        modn = name
        files = [test]
    # Create a dir to save the results
    try:
        os.makedirs(results + "/" + suite + "/results")
    except OSError:
        pass
    sema.acquire()
    # Compile it
    os.system("erlc -W0 -o %s %s/%s.erl" % (dirn, dirn, modn))
    # And extract scenarios from it
    pout = subprocess.check_output(
        ["erl -boot start_clean -noinput -pa %s -pa %s -s scenarios extract %s -s init stop"
         % (dirname, dirn, modn)], shell=True).splitlines()
    sema.release()
    procS = []
    for scenario in pout:
        # scenario has the format of {<mod_name>,<func_name>,<preb>}\n
        scen = scenario.strip("{}").split(",")
        # And run the test
        p = Process(
            target=runScenario,
            args=(suite, name, modn, scen[1], scen[2], scen[3:], files))
        p.start()
        procS.append(p)
    # Wait
    for p in procS:
        p.join()
    # Must happen late, in case the test has/needs exceptional
    os.remove("%s/%s.beam" % (dirn,modn))

#---------------------------------------------------------------------
# Run the specified scenario and print the results
def runScenario(suite, name, modn, funn, preb, flags, files):
    global concuerror
    global results
    global dirname
    global sema
    global lock
    global total_tests
    global total_failed
    if "dpor" in flags:
        dpor_flag = "--dpor=optimal"
        file_ext = "-dpor"
        dpor_output = "optimal"
    elif "optimal" in flags:
        dpor_flag = "--dpor=optimal"
        file_ext = "-optimal"
        dpor_output = "optimal"
    elif "source" in flags:
        dpor_flag = "--dpor=source"
        file_ext = "-source"
        dpor_output = "source"
    elif "persistent" in flags:
        dpor_flag = "--dpor=persistent"
        file_ext = "-persistent"
        dpor_output = "persistent"
    else:
        dpor_flag = "--dpor=none"
        file_ext = "-nodpor"
        dpor_output = "disabled"
    if preb == "inf":
        bound = ""
        bound_type = ""
        preb_output = "none"
    else:
        bound = ("-b %s") % (preb)
        if "bpor" in flags:
            bound_type = "-c bpor"
            preb_output=("%s/bpor") % (preb)
            preb=("%s-bpor") % (preb)
        else:
            bound_type = "-c delay"
            preb_output=("%s/delay") % (preb)
    sema.acquire()
    txtname = "%s-%s-%s%s.txt" % (name, funn, preb, file_ext)
    rslt = "%s/%s/results/%s" % (results, suite, txtname)
    try:
        os.remove(rslt)
    except OSError:
        pass
    # Run concuerror
    status = os.system(
        ("%s -kq --assume_racing false --show_races false"
         " %s -f %s"
         " --output %s"
         " -m %s -t %s %s %s"
         )
        % (concuerror, dpor_flag, " ".join(files),
           rslt, modn, funn, bound, bound_type))
    # Compare the results
    has_crash = "crash" in flags
    orig = "%s/suites/%s/results/%s" % (dirname, suite, txtname)
    equalRes = equalResults(suite, name, orig, rslt)
    if status != 512 and not has_crash:
        finished = True
    elif status == 512 and has_crash:
        finished = True
    else:
        finished = False
    sema.release()
    # Print the results
    lock.acquire()
    total_tests.value += 1
    suitename = re.sub('\_tests$', '', suite)
    logline = ("%-10s %-20s %-50s"
               % (suitename, name,
                  "("+funn+",  "+preb_output+",  "+dpor_output+")"))
    if equalRes and finished:
        # We don't need to keep the results file
        try:
            os.remove(rslt)
        except:
            pass
        print "%s  \033[01;32m    ok\033[00m" % (logline)

    else:
        total_failed.value += 1
        print "%s  \033[01;31mfailed\033[00m" % (logline)
    lock.release()

def equalResults(suite, name, orig, rslt):
    global dirname
    if 0 == subprocess.call("bash differ %s %s" % (orig, rslt), shell=True):
        return True
    else:
        beamdir = "%s/suites/%s/src" % (dirname, suite)
        cmd = ("erl -boot start_clean -noinput -pa %s/%s -pa %s"
               " -run scenarios exceptional \"%s\" \"%s\" \"%s\""
               % (beamdir, name, beamdir, name, orig, rslt))
        return 0 == subprocess.call(cmd, shell=True)

#---------------------------------------------------------------------
# Main program

# Get the directory of Concuerror's testsuite
dirname = os.path.abspath(os.path.dirname(sys.argv[0]))
concuerror = os.path.abspath(dirname + "/../bin/concuerror")
results = os.path.abspath(dirname + "/results")

# Ensure made
assert 0 == os.system("make -j -C %s/.. default tests/scenarios.beam" % dirname)

# If we have arguments we should use them as tests,
# otherwise check them all
if len(sys.argv) > 1:
    tests = sys.argv[1:]
    tests = [os.path.abspath(item) for item in tests]
else:
    tests = glob.glob(dirname + "/suites/*/src/*")

# How many threads we want (default, number of CPUs in the system)
threads = os.getenv("THREADS", "")
if threads == "":
    try:
        threads = str(cpu_count())
    except:
        threads = "1"

# Print header
print "Concuerror's Testsuite (%d threads)\n" % int(threads)
print "%-10s %-20s %-50s  %s" % \
      ("Suite", "Module", "(Test,  Bound,  DPOR)", "Result")
print "---------------------------------------------" + \
      "---------------------------------------------"

# Create share integers to count tests and
# a lock to protect printings
lock = Lock()
total_tests = Value(c_int, 0, lock=False)
total_failed = Value(c_int, 0, lock=False)

sema = BoundedSemaphore(int(threads))

# For every test do
procT = []
for test in tests:
    p = Process(target=runTest, args=(test,))
    procT.append(p)
    p.start()
# Wait
for p in procT:
    p.join()

# Print overview
print "\nOVERALL SUMMARY for test run"
print "  %d total tests, which contained" % len(tests)
print "  %d scenarios, of which" % total_tests.value
print "  %d caused unexpected failures!" % total_failed.value

if total_failed.value != 0:
    exit(1)
<commit_msg>Remove hardcoded --show_races false option from runtests.py<commit_after>#!/usr/bin/env python

import os
import re
import sys
import glob
import subprocess
from ctypes import c_int
from multiprocessing import Process, Lock, Value, BoundedSemaphore, cpu_count

#---------------------------------------------------------------------
# Extract scenarios from the specified test
def runTest(test):
    global dirname
    global results
    # test has the format of '.*/suites/<suite_name>/src/<test_name>(.erl)?'
    # Split the test in suite and name components using pattern matching
    rest1, name = os.path.split(test)
    rest2 = os.path.split(rest1)[0]
    suite = os.path.split(rest2)[1]
    name = os.path.splitext(name)[0]
    if os.path.isdir(test):
        # Our test is a multi module directory
        dirn = test     # directory
        modn = "test"   # module name
        files = glob.glob(dirn + "/*.erl")
    else:
        dirn = rest1
        modn = name
        files = [test]
    # Create a dir to save the results
    try:
        os.makedirs(results + "/" + suite + "/results")
    except OSError:
        pass
    sema.acquire()
    # Compile it
    os.system("erlc -W0 -o %s %s/%s.erl" % (dirn, dirn, modn))
    # And extract scenarios from it
    pout = subprocess.check_output(
        ["erl -boot start_clean -noinput -pa %s -pa %s -s scenarios extract %s -s init stop"
         % (dirname, dirn, modn)], shell=True).splitlines()
    sema.release()
    procS = []
    for scenario in pout:
        # scenario has the format of {<mod_name>,<func_name>,<preb>}\n
        scen = scenario.strip("{}").split(",")
        # And run the test
        p = Process(
            target=runScenario,
            args=(suite, name, modn, scen[1], scen[2], scen[3:], files))
        p.start()
        procS.append(p)
    # Wait
    for p in procS:
        p.join()
    # Must happen late, in case the test has/needs exceptional
    os.remove("%s/%s.beam" % (dirn,modn))

#---------------------------------------------------------------------
# Run the specified scenario and print the results
def runScenario(suite, name, modn, funn, preb, flags, files):
    global concuerror
    global results
    global dirname
    global sema
    global lock
    global total_tests
    global total_failed
    if "dpor" in flags:
        dpor_flag = "--dpor=optimal"
        file_ext = "-dpor"
        dpor_output = "optimal"
    elif "optimal" in flags:
        dpor_flag = "--dpor=optimal"
        file_ext = "-optimal"
        dpor_output = "optimal"
    elif "source" in flags:
        dpor_flag = "--dpor=source"
        file_ext = "-source"
        dpor_output = "source"
    elif "persistent" in flags:
        dpor_flag = "--dpor=persistent"
        file_ext = "-persistent"
        dpor_output = "persistent"
    else:
        dpor_flag = "--dpor=none"
        file_ext = "-nodpor"
        dpor_output = "disabled"
    if preb == "inf":
        bound = ""
        bound_type = ""
        preb_output = "none"
    else:
        bound = ("-b %s") % (preb)
        if "bpor" in flags:
            bound_type = "-c bpor"
            preb_output=("%s/bpor") % (preb)
            preb=("%s-bpor") % (preb)
        else:
            bound_type = "-c delay"
            preb_output=("%s/delay") % (preb)
    sema.acquire()
    txtname = "%s-%s-%s%s.txt" % (name, funn, preb, file_ext)
    rslt = "%s/%s/results/%s" % (results, suite, txtname)
    try:
        os.remove(rslt)
    except OSError:
        pass
    # Run concuerror
    status = os.system(
        ("%s -kq --assume_racing false"
         " %s -f %s"
         " --output %s"
         " -m %s -t %s %s %s"
         )
        % (concuerror, dpor_flag, " ".join(files),
           rslt, modn, funn, bound, bound_type))
    # Compare the results
    has_crash = "crash" in flags
    orig = "%s/suites/%s/results/%s" % (dirname, suite, txtname)
    equalRes = equalResults(suite, name, orig, rslt)
    if status != 512 and not has_crash:
        finished = True
    elif status == 512 and has_crash:
        finished = True
    else:
        finished = False
    sema.release()
    # Print the results
    lock.acquire()
    total_tests.value += 1
    suitename = re.sub('\_tests$', '', suite)
    logline = ("%-10s %-20s %-50s"
               % (suitename, name,
                  "("+funn+",  "+preb_output+",  "+dpor_output+")"))
    if equalRes and finished:
        # We don't need to keep the results file
        try:
            os.remove(rslt)
        except:
            pass
        print "%s  \033[01;32m    ok\033[00m" % (logline)

    else:
        total_failed.value += 1
        print "%s  \033[01;31mfailed\033[00m" % (logline)
    lock.release()

def equalResults(suite, name, orig, rslt):
    global dirname
    if 0 == subprocess.call("bash differ %s %s" % (orig, rslt), shell=True):
        return True
    else:
        beamdir = "%s/suites/%s/src" % (dirname, suite)
        cmd = ("erl -boot start_clean -noinput -pa %s/%s -pa %s"
               " -run scenarios exceptional \"%s\" \"%s\" \"%s\""
               % (beamdir, name, beamdir, name, orig, rslt))
        return 0 == subprocess.call(cmd, shell=True)

#---------------------------------------------------------------------
# Main program

# Get the directory of Concuerror's testsuite
dirname = os.path.abspath(os.path.dirname(sys.argv[0]))
concuerror = os.path.abspath(dirname + "/../bin/concuerror")
results = os.path.abspath(dirname + "/results")

# Ensure made
assert 0 == os.system("make -j -C %s/.. default tests/scenarios.beam" % dirname)

# If we have arguments we should use them as tests,
# otherwise check them all
if len(sys.argv) > 1:
    tests = sys.argv[1:]
    tests = [os.path.abspath(item) for item in tests]
else:
    tests = glob.glob(dirname + "/suites/*/src/*")

# How many threads we want (default, number of CPUs in the system)
threads = os.getenv("THREADS", "")
if threads == "":
    try:
        threads = str(cpu_count())
    except:
        threads = "1"

# Print header
print "Concuerror's Testsuite (%d threads)\n" % int(threads)
print "%-10s %-20s %-50s  %s" % \
      ("Suite", "Module", "(Test,  Bound,  DPOR)", "Result")
print "---------------------------------------------" + \
      "---------------------------------------------"

# Create share integers to count tests and
# a lock to protect printings
lock = Lock()
total_tests = Value(c_int, 0, lock=False)
total_failed = Value(c_int, 0, lock=False)

sema = BoundedSemaphore(int(threads))

# For every test do
procT = []
for test in tests:
    p = Process(target=runTest, args=(test,))
    procT.append(p)
    p.start()
# Wait
for p in procT:
    p.join()

# Print overview
print "\nOVERALL SUMMARY for test run"
print "  %d total tests, which contained" % len(tests)
print "  %d scenarios, of which" % total_tests.value
print "  %d caused unexpected failures!" % total_failed.value

if total_failed.value != 0:
    exit(1)
<|endoftext|>


<commit_before>import os
import sys

def main(args):

    if '--dev' in args:
        use_devel_version = True
        ape_devel_arg = '--dev'
        args.remove('--dev')
        djpl_install = 'pip3 install -e git+https://github.com/henzk/django-productline#egg=django-productline'
    else:
        use_devel_version = False
        ape_devel_arg = ''
        djpl_install = 'pip3 install django-productline'

    if len(args) != 2:
        print 'Usage:'
        print
        print 'install.py [--dev] <APE_ROOT_DIR>'
        print
        print 'Creates an ape-root at APE_ROOT_DIR for your django product lines.'
        print 'The given directory must not exist already.'
        print
        print 'If --dev is given, this installs the latest development versions from git.'
        print 'Otherwise, the latest stable version of ape and django-productline are used from PYPI.'
        sys.exit(1)

    webapps = args[1]
    webapps_dir = '%s/%s' % (os.getcwd(), webapps)

    cmds = (
        'wget -O - https://raw.github.com/henzk/ape/master/bin/bootstrape | python3 - %s %s; ' % (webapps, ape_devel_arg) +
        'cd %s ; ' % webapps_dir +
        '. _ape/activape ; ' +
        djpl_install + '; '
    )

    os.system('bash -c "%s deactivape"; ' % cmds)
    # add initenv on ape container level
    with open('%s/initenv' % webapps_dir, 'w+') as initenv:
        initenv.write('export APE_PREPEND_FEATURES="ape.container_mode django_productline"')

if __name__ == '__main__':
    main(sys.argv)
<commit_msg>python 3 install script fixed old style print<commit_after>import os
import sys

def main(args):

    if '--dev' in args:
        use_devel_version = True
        ape_devel_arg = '--dev'
        args.remove('--dev')
        djpl_install = 'pip3 install -e git+https://github.com/henzk/django-productline#egg=django-productline'
    else:
        use_devel_version = False
        ape_devel_arg = ''
        djpl_install = 'pip3 install django-productline'

    if len(args) != 2:
        print('Usage:\n')
        print('install.py [--dev] <APE_ROOT_DIR>\n')
        print('Creates an ape-root at APE_ROOT_DIR for your django product lines.')
        print('The given directory must not exist already.\n')
        print('If --dev is given, this installs the latest development versions from git.')
        print('Otherwise, the latest stable version of ape and django-productline are used from PYPI.')
        sys.exit(1)

    webapps = args[1]
    webapps_dir = '%s/%s' % (os.getcwd(), webapps)

    cmds = (
        'wget -O - https://raw.github.com/henzk/ape/master/bin/bootstrape | python3 - %s %s; ' % (webapps, ape_devel_arg) +
        'cd %s ; ' % webapps_dir +
        '. _ape/activape ; ' +
        djpl_install + '; '
    )

    os.system('bash -c "%s deactivape"; ' % cmds)
    # add initenv on ape container level
    with open('%s/initenv' % webapps_dir, 'w+') as initenv:
        initenv.write('export APE_PREPEND_FEATURES="ape.container_mode django_productline"')

if __name__ == '__main__':
    main(sys.argv)
<|endoftext|>


<commit_before>__version__ = "0.15.0"
<commit_msg>Bump version number to 0.15.1<commit_after>__version__ = "0.15.1"
<|endoftext|>


<commit_before>#!/usr/bin/env python

DESC = """EPP script to copy 'concentration' and 'concentration unit' for each
sample sample in the 'Qubit Result File' to the 'Concentration' and 'Conc. Units'
fields of the output analytes of the process.

Warnings are generated to the user and stored in regular log file wich allso
contains regular execution information in the folowing cases:

1) missing row names (samples) in file
2) duplicated row names (samples)
3) missing value (concentrations)
4) values found but for some reason are not successfully copied:

Can be executed in the background or triggered by a user pressing a "blue button".

Written by Maya Brandi
"""

import os
import sys
import logging
import numpy as np

from argparse import ArgumentParser
from requests import HTTPError
from genologics.lims import Lims
from genologics.config import BASEURI,USERNAME,PASSWORD
from genologics.entities import Process
from genologics.epp import EppLogger
from genologics.epp import ReadResultFiles
from genologics.epp import set_field
lims = Lims(BASEURI,USERNAME,PASSWORD)

def main(lims, pid, epp_logger):
    process = Process(lims,id = pid)
    sample_names = map(lambda a: a.name, process.analytes()[0])
    target_files = process.result_files()
    file_handler = ReadResultFiles(process)
    files = file_handler.shared_files['Qubit Result File']
    qubit_result_file = file_handler.format_file(files,
                                                 name = 'Qubit Result File',
                                                 first_header = 'Sample',
                                                 find_keys = sample_names)
    missing_samples = 0
    bad_formated = 0
    abstract = []
    udfs = dict(process.udf.items())
    if udfs.has_key("Minimum required concentration (ng/ul)"):
        min_conc = udfs["Minimum required concentration (ng/ul)"]
    else:
        min_conc = None
        abstract.append("Set 'Minimum required concentration (ng/ul)' to get qc-flaggs based on this treshold!")
    for target_file in target_files:
        sample = target_file.samples[0].name
        if qubit_result_file.has_key(sample):
            sample_mesurements = qubit_result_file[sample]
            if "Sample Concentration" in sample_mesurements.keys():
                conc, unit = sample_mesurements["Sample Concentration"]
                if conc == 'Out Of Range':
                    target_file.qc_flag = "FAILED"
                else:
                    try:
                        conc = float(conc)
                        if min_conc:
                            if conc < min_conc:
                                target_file.qc_flag = "FAILED"
                                self.low_conc +=1
                            else:
                                target_file.qc_flag = "PASSED"
                        if unit == 'ng/mL':
                            conc = np.true_divide(conc, 1000)
                        target_file.udf['Concentration'] = conc
                        target_file.udf['Conc. Units'] = 'ng/ul'
                    except:
                        bad_formated += 1
                set_field(target_file)
        else:
            missing_samples += 1

    if missing_samples:
        abstract.append('There are {0} out of {1} samples missing in Qubit Result File!'.format(missing_samples, len(target_files)))
    if bad_formated:
        abstract.append('There are {0} badly formated samples in Qubit Result File. Please fix these to get proper results.'.format(bad_formated))

    print >> sys.stderr, ' '.join(abstract)

if __name__ == "__main__":
    parser = ArgumentParser(description=DESC)
    parser.add_argument('--pid', default = '24-38458', dest = 'pid',
                        help='Lims id for current Process')
    parser.add_argument('--log', dest = 'log',
                        help=('File name for standard log file, '
                              'for runtime information and problems.'))

    args = parser.parse_args()

    lims = Lims(BASEURI,USERNAME,PASSWORD)
    lims.check_version()

    with EppLogger(log_file=args.log, lims=lims, prepend=True) as epp_logger:
        main(lims, args.pid, epp_logger)

<commit_msg>adding find_keys to file_handler.format_file<commit_after>#!/usr/bin/env python

DESC = """EPP script to copy 'concentration' and 'concentration unit' for each
sample sample in the 'Qubit Result File' to the 'Concentration' and 'Conc. Units'
fields of the output analytes of the process.

Warnings are generated to the user and stored in regular log file wich allso
contains regular execution information in the folowing cases:

1) missing row names (samples) in file
2) duplicated row names (samples)
3) missing value (concentrations)
4) values found but for some reason are not successfully copied:

Can be executed in the background or triggered by a user pressing a "blue button".

Written by Maya Brandi
"""

import os
import sys
import logging
import numpy as np

from argparse import ArgumentParser
from requests import HTTPError
from genologics.lims import Lims
from genologics.config import BASEURI,USERNAME,PASSWORD
from genologics.entities import Process
from genologics.epp import EppLogger
from genologics.epp import ReadResultFiles
from genologics.epp import set_field
lims = Lims(BASEURI,USERNAME,PASSWORD)

def main(lims, pid, epp_logger):
    process = Process(lims,id = pid)
    sample_names = map(lambda a: a.name, process.analytes()[0])
    target_files = process.result_files()
    file_handler = ReadResultFiles(process)
    files = file_handler.shared_files['Qubit Result File']
    qubit_result_file = file_handler.format_file(files,
                                                 name = 'Qubit Result File',
                                                 first_header = 'Sample',
                                                 find_keys = sample_names)
    missing_samples = 0
    bad_formated = 0
    abstract = []
    udfs = dict(process.udf.items())
    if udfs.has_key("Minimum required concentration (ng/ul)"):
        min_conc = udfs["Minimum required concentration (ng/ul)"]
    else:
        min_conc = None
        abstract.append("Set 'Minimum required concentration (ng/ul)' to get qc-flaggs based on this treshold!")
    for target_file in target_files:
        sample = target_file.samples[0].name
        if qubit_result_file.has_key(sample):
            sample_mesurements = qubit_result_file[sample]
            if "Sample Concentration" in sample_mesurements.keys():
                conc, unit = sample_mesurements["Sample Concentration"]
                if conc == 'Out Of Range':
                    target_file.qc_flag = "FAILED"
                else:
                    try:
                        print sample_mesurements
                        conc = float(conc)
                        if min_conc:
                            if conc < min_conc:
                                target_file.qc_flag = "FAILED"
                                self.low_conc +=1
                            else:
                                target_file.qc_flag = "PASSED"
                        if unit == 'ng/mL':
                            conc = np.true_divide(conc, 1000)
                        target_file.udf['Concentration'] = conc
                        target_file.udf['Conc. Units'] = 'ng/ul'
                    except:
                        print 'bad'
                        bad_formated += 1
                set_field(target_file)
        else:
            missing_samples += 1

    if missing_samples:
        abstract.append('There are {0} out of {1} samples missing in Qubit Result File.'.format(missing_samples, len(target_files)))
    if bad_formated:
        abstract.append('There are {0} badly formated samples in Qubit Result File. Please fix these to get proper results.'.format(bad_formated))

    print >> sys.stderr, ' '.join(abstract)

if __name__ == "__main__":
    parser = ArgumentParser(description=DESC)
    parser.add_argument('--pid', default = '24-38458', dest = 'pid',
                        help='Lims id for current Process')
    parser.add_argument('--log', dest = 'log',
                        help=('File name for standard log file, '
                              'for runtime information and problems.'))

    args = parser.parse_args()

    lims = Lims(BASEURI,USERNAME,PASSWORD)
    lims.check_version()

    with EppLogger(log_file=args.log, lims=lims, prepend=True) as epp_logger:
        main(lims, args.pid, epp_logger)

<|endoftext|>


<commit_before>import plugintypes
import json
import subprocess
import os

"""
Installable plugins are currently hardcoded here for early
development of the installation process. They will be centralized
online at a later date.

Plugin data will be downloaded in JSON format and inserted to a sqlite
database for local cache.
"""

PLUGIN_LINKS={ "Whiskey": "https://github.com/xlopo/tg-pybot-whiskey" }
REPO_DIR="plugins.repos"

class PluginsPlugin(plugintypes.TelegramPlugin):
    """
    Plugin to manage other plugins. Enable, disable or reload.
    """
    patterns = [
        "^!plugins$",
        "^!plugins? (enable) ([\w_.-]+)$",
        "^!plugins? (disable) ([\w_.-]+)$",
        "^!plugins? (install) ([\w_.-]+)$",
        # "^!plugins? (enable) ([\w_.-]+) (chat)",
        # "^!plugins? (disable) ([\w_.-]+) (chat)",
        "^!plugins? (reload)$"
    ]

    usage = [
        "!plugins: list all plugins.",
        "!plugins enable [plugin]: enable plugin.",
        "!plugins disable [plugin]: disable plugin.",
        # "!plugins disable [plugin] chat: disable plugin only this chat.",
        "!plugins reload: reloads all plugins."
    ]

    def activate_plugin(self):
        if not os.path.exists(REPO_DIR):
            os.makedirs(REPO_DIR)

    def run(self, msg, matches):
        if matches.group(0) == "!plugins":
            return self.list_plugins()

        if matches.group(1) == "enable":
            return self.enable_plugin(matches)

        if matches.group(1) == "disable":
            return self.disable_plugin(matches)

        if matches.group(1) == "install":
            return self.install_plugin(matches)

        if matches.group(1) == "reload":
            return self.reload_plugins()

    def enable_plugin(self, matches):
        if self.plugin_manager.activatePluginByName(matches.group(2)):
            return "Plugin {} enabled".format(matches.group(2))
        else:
            return "Error loading plugin {}".format(matches.group(2))

    def disable_plugin(self, matches):
        if self.plugin_manager.activatePluginByName(matches.group(2)):
            return "Plugin {} disabled".format(matches.group(2))
        else:
            return "Error disabling plugin {}".format(matches.group(2))

    def install_plugin(self, matches):
        plugin_name = matches.group(2)
        if plugin_name in PLUGIN_LINKS.keys():
            args = [GIT, "clone", PLUGIN_DIRECTORY[plugin_name]]
            p = subprocess.Popen(args, cwd=REPO_DIR)
        return ""

    def reload_plugins(self):
        self.plugin_manager.collectPlugins()
        return "Plugins reloaded"

    def list_plugins(self):
        text = ""
        for plugin in self.plugin_manager.getAllPlugins():
            text += "{0}: ({1})\n".format(plugin.name,
                                          "(Enabled)" if plugin.plugin_object.is_activated else "(Disabled)")

        return text
<commit_msg>Adding GIT_BIN variable<commit_after>import plugintypes
import json
import subprocess
import os

"""
Installable plugins are currently hardcoded here for early
development of the installation process. They will be centralized
online at a later date.

Plugin data will be downloaded in JSON format and inserted to a sqlite
database for local cache.
"""

PLUGIN_LINKS={ "Whiskey": "https://github.com/xlopo/tg-pybot-whiskey" }
REPO_DIR="plugins.repos"
GIT_BIN="/usr/bin/git"

class PluginsPlugin(plugintypes.TelegramPlugin):
    """
    Plugin to manage other plugins. Enable, disable or reload.
    """
    patterns = [
        "^!plugins$",
        "^!plugins? (enable) ([\w_.-]+)$",
        "^!plugins? (disable) ([\w_.-]+)$",
        "^!plugins? (install) ([\w_.-]+)$",
        # "^!plugins? (enable) ([\w_.-]+) (chat)",
        # "^!plugins? (disable) ([\w_.-]+) (chat)",
        "^!plugins? (reload)$"
    ]

    usage = [
        "!plugins: list all plugins.",
        "!plugins enable [plugin]: enable plugin.",
        "!plugins disable [plugin]: disable plugin.",
        # "!plugins disable [plugin] chat: disable plugin only this chat.",
        "!plugins reload: reloads all plugins."
    ]

    def activate_plugin(self):
        if not os.path.exists(REPO_DIR):
            os.makedirs(REPO_DIR)

    def run(self, msg, matches):
        if matches.group(0) == "!plugins":
            return self.list_plugins()

        if matches.group(1) == "enable":
            return self.enable_plugin(matches)

        if matches.group(1) == "disable":
            return self.disable_plugin(matches)

        if matches.group(1) == "install":
            return self.install_plugin(matches)

        if matches.group(1) == "reload":
            return self.reload_plugins()

    def enable_plugin(self, matches):
        if self.plugin_manager.activatePluginByName(matches.group(2)):
            return "Plugin {} enabled".format(matches.group(2))
        else:
            return "Error loading plugin {}".format(matches.group(2))

    def disable_plugin(self, matches):
        if self.plugin_manager.activatePluginByName(matches.group(2)):
            return "Plugin {} disabled".format(matches.group(2))
        else:
            return "Error disabling plugin {}".format(matches.group(2))

    def install_plugin(self, matches):
        plugin_name = matches.group(2)
        if plugin_name in PLUGIN_LINKS.keys():
            args = [GIT_BIN, "clone", PLUGIN_DIRECTORY[plugin_name]]
            p = subprocess.Popen(args, cwd=REPO_DIR)
        return ""

    def reload_plugins(self):
        self.plugin_manager.collectPlugins()
        return "Plugins reloaded"

    def list_plugins(self):
        text = ""
        for plugin in self.plugin_manager.getAllPlugins():
            text += "{0}: ({1})\n".format(plugin.name,
                                          "(Enabled)" if plugin.plugin_object.is_activated else "(Disabled)")

        return text
<|endoftext|>


<commit_before>"""EntityTypes module: contains classes that describe Entity types"""

from SpecImports import *

class Entity:
    attribs = (
        ('type', None),
        ('name', 'unnamed'),
        ('comment', ''),
        )

class LevelMgr(Entity):
    type = 'levelMgr'
    attribs = (
        ('cogLevel', 0),
        ('cogTrack', 'c'),
        ('modelFilename', None),
        )

class LogicGate(Entity):
    type = 'logicGate'
    attribs = (
        ('input_input1_bool', 0),
        ('input_input2_bool', 0),
        ('isInput1', 0),
        ('isInput2', 0),
        ('logicType', 'or'),
        ('output', 'bool'),
        )

class NodepathImpl:
    attribs = (
        ('parent', 0),
        ('pos', Point3(0,0,0)),
        ('hpr', Vec3(0,0,0)),
        )

# Note: this covers Nodepath and DistributedNodepath
class Nodepath(Entity, NodepathImpl):
    type = 'nodepath'

class NodepathAttribs:
    attribs = (
        ('parent', 0),
        ('pos', Point3(0,0,0)),
        ('hpr', Vec3(0,0,0)),
        )

class Zone(Entity, NodepathAttribs):
    type = 'zone'
    delAttribs = (
        'parent',
        'pos',
        'hpr',
        )
    attribs = (
        ('description', ''),
        ('modelZoneNum', None),
        ('visibility', []),
        )

class BarrelBase(Nodepath):
    delAttribs = (
        'hpr',
        )
    attribs = (
        ('h', 0),
        )

class BeanBarrel(BarrelBase):
    type = 'beanBarrel'

class GagBarrel(BarrelBase):
    type = 'gagBarrel'
    attribs = (
        ('gagLevel', 0),
        ('gagTrack', 0),
        )

class Switch(Entity, NodepathImpl):
    attribs = (
        ('scale', 1),
        ('color', Vec4(1,1,1,1)),
        ('model', None),
        ('input_isOn_bool', 0),
        ('isOn', 0),
        ('output', 'bool'),
        ('secondsOn', 1),
        )

class Button(Switch):
    type = 'button'

class Trigger(Switch):
    type = 'trigger'

class Crate(Nodepath):
    type = 'crate'
    delAttribs = (
        'hpr',
        )
    attribs = (
        ('scale', 1),
        ('gridId', None),
        ('pushable', 1),
        )

class Door(Entity):
    type = 'door'
    attribs = (
        ('parent', 0),
        ('pos', Point3(0,0,0)),
        ('hpr', Vec3(0,0,0)),
        ('scale', 1),
        ('color', Vec4(1,1,1,1)),
        ('model', None),
        ('doorwayNum', 0),
        ('input_Lock0_bool', 0),
        ('input_Lock1_bool', 0),
        ('input_Lock2_bool', 0),
        ('input_Lock3_bool', 0),
        ('input_isOpen_bool', 0),
        ('isLock0Unlocked', 0),
        ('isLock1Unlocked', 0),
        ('isLock2Unlocked', 0),
        ('isLock3Unlocked', 0),
        ('isOpen', 0),
        ('output', 'bool'),
        ('secondsOpen', 1),
        )

class Grid(Nodepath):
    type = 'grid'
    delAttribs = (
        'hpr',
        )
    attribs = (
        ('cellSize', 3),
        ('numCol', 3),
        ('numRow', 3),
        )

class Lift(Nodepath):
    type = 'lift'
    attribs = (
        ('duration', 1),
        ('startPos', Point3(0,0,0)),
        ('endPos', Point3(0,0,0)),
        ('modelPath', ''),
        ('floorName', ''),
        ('modelScale', 1),
        )

class Platform(Nodepath):
    type = 'platform'
    delAttribs = (
        'pos',
        )
    attribs = (
        ('startPos', Point3(0,0,0)),
        ('endPos', Point3(0,0,0)),
        ('speed', 1),
        ('waitDur', 1),
        ('phaseShift', 0.),
        )

class SinkingPlatform(Nodepath):
    type = 'sinkingPlatform'
    delAttribs = (
        'pos',
        )
    attribs = (
        ('endPos', Point3(0,0,0)),
        ('phaseShift', 0.),
        ('startPos', Point3(0,0,0)),
        ('verticalRange', 1),
        ('sinkRate', 1),
        ('riseRate', 1),
        ('speed', 1),
        ('waitDur', 1),
        )

class Stomper(Nodepath):
    type = 'stomper'
    attribs = (
        ('headScale', Vec3(1,1,1)),
        ('motion', 3),
        ('period', 2.),
        ('phaseShift', 0.),
        ('range', 6),
        ('shaftScale', Vec3(1,1,1)),
        ('soundLen', 0),
        ('soundOn', 0),
        ('style', 'horizontal'),
        ('zOffset', 0),
        )

class StomperPair(Nodepath):
    type = 'stomperPair'
    attribs = (
        ('headScale', Vec3(1,1,1)),
        ('motion', 3),
        ('period', 2.),
        ('phaseShift', 0.),
        ('range', 6),
        ('shaftScale', Vec3(1,1,1)),
        ('soundLen', 0),
        ('soundOn', 0),
        ('stomperIds', []),
        ('style', 'horizontal'),
        )
<commit_msg>added ActiveCellEntity<commit_after>"""EntityTypes module: contains classes that describe Entity types"""

from SpecImports import *

class Entity:
    attribs = (
        ('type', None),
        ('name', 'unnamed'),
        ('comment', ''),
        )

class ActiveCell(Entity):
    type = 'activeCell'
    attribs = (
        ('row', 0),
        ('col', 0),
        ('gridId', None)
        )

class LevelMgr(Entity):
    type = 'levelMgr'
    attribs = (
        ('cogLevel', 0),
        ('cogTrack', 'c'),
        ('modelFilename', None),
        )

class LogicGate(Entity):
    type = 'logicGate'
    attribs = (
        ('input_input1_bool', 0),
        ('input_input2_bool', 0),
        ('isInput1', 0),
        ('isInput2', 0),
        ('logicType', 'or'),
        ('output', 'bool'),
        )

class NodepathImpl:
    attribs = (
        ('parent', 0),
        ('pos', Point3(0,0,0)),
        ('hpr', Vec3(0,0,0)),
        )

# Note: this covers Nodepath and DistributedNodepath
class Nodepath(Entity, NodepathImpl):
    type = 'nodepath'

class NodepathAttribs:
    attribs = (
        ('parent', 0),
        ('pos', Point3(0,0,0)),
        ('hpr', Vec3(0,0,0)),
        )

class Zone(Entity, NodepathAttribs):
    type = 'zone'
    delAttribs = (
        'parent',
        'pos',
        'hpr',
        )
    attribs = (
        ('description', ''),
        ('modelZoneNum', None),
        ('visibility', []),
        )

class BarrelBase(Nodepath):
    delAttribs = (
        'hpr',
        )
    attribs = (
        ('h', 0),
        )

class BeanBarrel(BarrelBase):
    type = 'beanBarrel'

class GagBarrel(BarrelBase):
    type = 'gagBarrel'
    attribs = (
        ('gagLevel', 0),
        ('gagTrack', 0),
        )

class Switch(Entity, NodepathImpl):
    attribs = (
        ('scale', 1),
        ('color', Vec4(1,1,1,1)),
        ('model', None),
        ('input_isOn_bool', 0),
        ('isOn', 0),
        ('output', 'bool'),
        ('secondsOn', 1),
        )

class Button(Switch):
    type = 'button'

class Trigger(Switch):
    type = 'trigger'

class Crate(Nodepath):
    type = 'crate'
    delAttribs = (
        'hpr',
        )
    attribs = (
        ('scale', 1),
        ('gridId', None),
        ('pushable', 1),
        )

class Door(Entity):
    type = 'door'
    attribs = (
        ('parent', 0),
        ('pos', Point3(0,0,0)),
        ('hpr', Vec3(0,0,0)),
        ('scale', 1),
        ('color', Vec4(1,1,1,1)),
        ('model', None),
        ('doorwayNum', 0),
        ('input_Lock0_bool', 0),
        ('input_Lock1_bool', 0),
        ('input_Lock2_bool', 0),
        ('input_Lock3_bool', 0),
        ('input_isOpen_bool', 0),
        ('isLock0Unlocked', 0),
        ('isLock1Unlocked', 0),
        ('isLock2Unlocked', 0),
        ('isLock3Unlocked', 0),
        ('isOpen', 0),
        ('output', 'bool'),
        ('secondsOpen', 1),
        )

class Grid(Nodepath):
    type = 'grid'
    delAttribs = (
        'hpr',
        )
    attribs = (
        ('cellSize', 3),
        ('numCol', 3),
        ('numRow', 3),
        )

class Lift(Nodepath):
    type = 'lift'
    attribs = (
        ('duration', 1),
        ('startPos', Point3(0,0,0)),
        ('endPos', Point3(0,0,0)),
        ('modelPath', ''),
        ('floorName', ''),
        ('modelScale', 1),
        )

class Platform(Nodepath):
    type = 'platform'
    delAttribs = (
        'pos',
        )
    attribs = (
        ('startPos', Point3(0,0,0)),
        ('endPos', Point3(0,0,0)),
        ('speed', 1),
        ('waitDur', 1),
        ('phaseShift', 0.),
        )

class SinkingPlatform(Nodepath):
    type = 'sinkingPlatform'
    delAttribs = (
        'pos',
        )
    attribs = (
        ('endPos', Point3(0,0,0)),
        ('phaseShift', 0.),
        ('startPos', Point3(0,0,0)),
        ('verticalRange', 1),
        ('sinkRate', 1),
        ('riseRate', 1),
        ('speed', 1),
        ('waitDur', 1),
        )

class Stomper(Nodepath):
    type = 'stomper'
    attribs = (
        ('headScale', Vec3(1,1,1)),
        ('motion', 3),
        ('period', 2.),
        ('phaseShift', 0.),
        ('range', 6),
        ('shaftScale', Vec3(1,1,1)),
        ('soundLen', 0),
        ('soundOn', 0),
        ('style', 'horizontal'),
        ('zOffset', 0),
        )

class StomperPair(Nodepath):
    type = 'stomperPair'
    attribs = (
        ('headScale', Vec3(1,1,1)),
        ('motion', 3),
        ('period', 2.),
        ('phaseShift', 0.),
        ('range', 6),
        ('shaftScale', Vec3(1,1,1)),
        ('soundLen', 0),
        ('soundOn', 0),
        ('stomperIds', []),
        ('style', 'horizontal'),
        )
<|endoftext|>


<commit_before>#!/usr/bin/env python
# -*- coding: utf-8-*-

# go to the root for access to the module
import sys
import os.path
sys.path.insert(0, os.path.abspath(
    os.path.join(os.path.dirname(__file__), '../') ))

import unittest
from potara import document
from potara import similaritymeasures as sm
from potara import summarizer
import gensim

class SummarizerTest(unittest.TestCase):

    def test_init(self):
        s = summarizer.Summarizer()
        testdir = os.path.dirname(os.path.realpath(__file__))
        doc = document.Document(os.path.join(testdir, 'testdata/smalldoc.txt'))
        s.addDocument(doc)
        self.assertEqual(len(s.documents), 1)

    def test_doclogic(self):
        s = summarizer.Summarizer()
        testdir = os.path.dirname(os.path.realpath(__file__))
        doc = document.Document(os.path.join(testdir, 'testdata/smalldoc.txt'))
        s.addDocument(doc)
        s.addDocument(doc)
        self.assertEqual(len(s.documents), 2)
        s.clearDocuments()
        self.assertEqual(s.documents, None)
        s.addDocument(doc)
        self.assertEqual(len(s.documents), 1)

    def test_clustering(self):
        s = summarizer.Summarizer()
        testdir = os.path.dirname(os.path.realpath(__file__))
        doc = document.Document(os.path.join(testdir, 'testdata/smalldoc.txt'))
        s.addDocument(doc)
        s.addDocument(doc)
        s._clusterSentences()
        self.assertEqual(len(s.clusters), 2)

    def test_fusion(self):
        s1 = "This/DT fake/JJ sentence/NN will/MD create/VB fusions/NNS ./PUNCT"
        s2 = "This/DT awesome/JJ sentence/NN may/MD create/VB fusions/NNS ./PUNCT"

        fusions = summarizer._fuseCluster([s1, s2])
        self.assertTrue(len(fusions) <= 10)
        self.assertTrue("this/DT awesome/JJ sentence/NN "+
                        "will/MD create/VB fusions/NNS ./PUNCT" in fusions)

class DocumentTest(unittest.TestCase):

    def test_normalize(self):

        t1 = """ This is   a .strange
        sentence that has \t\tlots\n
        of spaces\t\n """
        et1 = "This is a .strange sentence that has lots of spaces"
        pt1 = document.normalize(t1)

        self.assertEqual(pt1,et1)

    def test_stem(self):
        words = ["these", "sentences", "are", "awesome"]
        estems = ["these", "sentenc", "are", "awesom"]

        pstems = [document.stem(word) for word in words]
        self.assertEqual(estems, pstems)

    def test_sentTokenize(self):

        t1 = "This test is composed of several sentences. Some of " + \
        "them contain abbreviations like POS. POS means Part Of " + \
        "Speech by the way."

        esent1 = ["This test is composed of several sentences.",
                  "Some of them contain abbreviations like POS.",
                  "POS means Part Of Speech by the way."]
        psent1 = document.sentTokenize(t1)
        self.assertEqual(esent1, psent1)

    def test_postag(self):

        s1 = "I wonder how this sentence will be postagged .".split()

        es1 = [(u'I', u'PRP'), (u'wonder', u'VBP'), (u'how', u'WRB'),
               (u'this', u'DT'), (u'sentence', u'NN'), (u'will', u'MD'),
               (u'be', u'VB'), (u'postagged', u'VBN'), (u'.', 'PUNCT')]
        ps1 = document.postag(s1)
        self.assertEqual(es1, ps1)

    def test_docinit(self):
        testdir = os.path.dirname(os.path.realpath(__file__))
        docfile1 = testdir + "/testdata/smalldoc.txt"
        doc1 = document.Document(docfile1)

        edoc1stem = [[(u'clean', u'JJ'), (u'document', u'NN')],
                     [(u'short', u'JJ'), (u'illform', u'JJ')]]
        pdoc1stem = doc1.stemTokens
        self.assertEqual(edoc1stem, pdoc1stem)

class SimilarityTest(unittest.TestCase):

    def test_cosine(self):
        s1 = "This sentence is not right."
        s2 = "This sentence is wrong."

        ecos = 0.671
        pcos = sm.cosine(s1, s2)

        self.assertAlmostEqual(ecos, pcos, places=3)

    def test_cosine_empty(self):
        s1 = "This sentence is OK ."
        s2 = ""

        ecos = 0
        pcos = sm.cosine(s1, s2)
        self.assertEqual(ecos, pcos)

    # w2v needs a model. Without it, I'll just pass the tests (useful for travis)
    def test_w2v(self):
        testdir = os.path.dirname(os.path.realpath(__file__))
        modelfile = testdir + '/../potara/data/enwiki9stempos.model'
        try:
            model = gensim.models.word2vec.Word2Vec.load(modelfile)
        except:
            return

        s1 = "This/T beautiful/JJ sentence/NN is/V not/N right/JJ ./PUNCT"
        s2 = "This/T beautiful/JJ sentence/NN is/V wrong/JJ ./PUNCT"

        esim = 0.88749
        psim = sm.w2v(s1, s2, model)
        self.assertAlmostEqual(esim, psim, places=3)

        # order doesn't matter
        psim2 = sm.w2v(s2, s1, model)
        self.assertEqual(psim, psim2)

    def test_w2v_notinvocab(self):
        testdir = os.path.dirname(os.path.realpath(__file__))
        modelfile = testdir + '/../potara/data/enwiki9stempos.model'
        try:
            model = gensim.models.word2vec.Word2Vec.load(modelfile)
        except:
            return

        s1 = "This/T beauful/JJ sentence/NN is/V not/N right/JJ ./PUNCT"
        s2 = "This/T beautiful/JJ sentence/NN is/V wrong/JJ ./PUNCT"

        esim = 0.7208
        psim = sm.w2v(s1, s2, model)
        self.assertAlmostEqual(esim, psim, places=3)

    def test_w2v_singleword(self):
        testdir = os.path.dirname(os.path.realpath(__file__))
        modelfile = testdir + '/../potara/data/enwiki9stempos.model'
        try:
            model = gensim.models.word2vec.Word2Vec.load(modelfile)
        except:
            return

        s1 = "right/JJ"
        s2 = "wrong/JJ"

        # a single different word means 0 sim
        esim = 0
        psim = sm.w2v(s1, s2, model)
        self.assertEqual(esim, psim)

        s3 = "right/JJ"
        esim2 = 1
        psim2 = sm.w2v(s1, s3, model)
        self.assertEqual(esim2, psim2)

    def test_w2v_untag(self):
        testdir = os.path.dirname(os.path.realpath(__file__))
        modelfile = testdir + '/../potara/data/enwiki9stempos.model'
        try:
            model = gensim.models.word2vec.Word2Vec.load(modelfile)
        except:
            return

        s1 = "This sentence is not right ."
        s2 = "This sentence is wrong ."

        # without tags we consider the intersection over min length
        esim = 4.0/5
        psim = sm.w2v(s1, s2, model)
        self.assertEqual(esim, psim)

if __name__ == '__main__':
    unittest.main()
        <commit_msg>pep8 and string representation<commit_after>#!/usr/bin/env python
# -*- coding: utf-8-*-

# go to the root for access to the module
import sys
import os.path
sys.path.insert(0, os.path.abspath(
    os.path.join(os.path.dirname(__file__), '../')))

import unittest
from potara import document
from potara import similaritymeasures as sm
from potara import summarizer
import gensim

class SummarizerTest(unittest.TestCase):

    def test_init(self):
        s = summarizer.Summarizer()
        testdir = os.path.dirname(os.path.realpath(__file__))
        doc = document.Document(os.path.join(testdir, 'testdata/smalldoc.txt'))
        s.addDocument(doc)
        self.assertEqual(len(s.documents), 1)

    def test_doclogic(self):
        s = summarizer.Summarizer()
        testdir = os.path.dirname(os.path.realpath(__file__))
        doc = document.Document(os.path.join(testdir, 'testdata/smalldoc.txt'))
        s.addDocument(doc)
        s.addDocument(doc)
        self.assertEqual(len(s.documents), 2)
        s.clearDocuments()
        self.assertEqual(s.documents, None)
        s.addDocument(doc)
        self.assertEqual(len(s.documents), 1)

    def test_clustering(self):
        s = summarizer.Summarizer()
        testdir = os.path.dirname(os.path.realpath(__file__))
        doc = document.Document(os.path.join(testdir, 'testdata/smalldoc.txt'))
        s.addDocument(doc)
        s.addDocument(doc)
        s._clusterSentences()
        self.assertEqual(len(s.clusters), 2)

    def test_fusion(self):
        s1 = "This/DT fake/JJ sentence/NN will/MD " + \
             "create/VB fusions/NNS ./PUNCT"
        s2 = "This/DT awesome/JJ sentence/NN may/MD " + \
             "create/VB fusions/NNS ./PUNCT"

        fusions = summarizer._fuseCluster([s1, s2])
        self.assertTrue(len(fusions) <= 10)
        self.assertTrue(("this/DT awesome/JJ sentence/NN "
                        "will/MD create/VB fusions/NNS ./PUNCT") in fusions)

class DocumentTest(unittest.TestCase):

    def test_normalize(self):

        t1 = """ This is   a .strange
        sentence that has \t\tlots\n
        of spaces\t\n """
        et1 = "This is a .strange sentence that has lots of spaces"
        pt1 = document.normalize(t1)

        self.assertEqual(pt1, et1)

    def test_stem(self):
        words = ["these", "sentences", "are", "awesome"]
        estems = ["these", "sentenc", "are", "awesom"]

        pstems = [document.stem(word) for word in words]
        self.assertEqual(estems, pstems)

    def test_sentTokenize(self):

        t1 = "This test is composed of several sentences. Some of " + \
             "them contain abbreviations like POS. POS means Part Of " + \
             "Speech by the way."

        esent1 = ["This test is composed of several sentences.",
                  "Some of them contain abbreviations like POS.",
                  "POS means Part Of Speech by the way."]
        psent1 = document.sentTokenize(t1)
        self.assertEqual(esent1, psent1)

    def test_postag(self):

        s1 = "I wonder how this sentence will be postagged .".split()

        es1 = [(u'I', u'PRP'), (u'wonder', u'VBP'), (u'how', u'WRB'),
               (u'this', u'DT'), (u'sentence', u'NN'), (u'will', u'MD'),
               (u'be', u'VB'), (u'postagged', u'VBN'), (u'.', 'PUNCT')]
        ps1 = document.postag(s1)
        self.assertEqual(es1, ps1)

    def test_docinit(self):
        testdir = os.path.dirname(os.path.realpath(__file__))
        docfile1 = testdir + "/testdata/smalldoc.txt"
        doc1 = document.Document(docfile1)

        edoc1stem = [[(u'clean', u'JJ'), (u'document', u'NN')],
                     [(u'short', u'JJ'), (u'illform', u'JJ')]]
        pdoc1stem = doc1.stemTokens
        self.assertEqual(edoc1stem, pdoc1stem)

class SimilarityTest(unittest.TestCase):

    def test_cosine(self):
        s1 = "This sentence is not right."
        s2 = "This sentence is wrong."

        ecos = 0.671
        pcos = sm.cosine(s1, s2)

        self.assertAlmostEqual(ecos, pcos, places=3)

    def test_cosine_empty(self):
        s1 = "This sentence is OK ."
        s2 = ""

        ecos = 0
        pcos = sm.cosine(s1, s2)
        self.assertEqual(ecos, pcos)

    # w2v needs a model.
    # Without it, I'll just pass the tests (useful for travis)
    def test_w2v(self):
        testdir = os.path.dirname(os.path.realpath(__file__))
        modelfile = testdir + '/../potara/data/enwiki9stempos.model'
        try:
            model = gensim.models.word2vec.Word2Vec.load(modelfile)
        except:
            return

        s1 = "This/T beautiful/JJ sentence/NN is/V not/N right/JJ ./PUNCT"
        s2 = "This/T beautiful/JJ sentence/NN is/V wrong/JJ ./PUNCT"

        esim = 0.88749
        psim = sm.w2v(s1, s2, model)
        self.assertAlmostEqual(esim, psim, places=3)

        # order doesn't matter
        psim2 = sm.w2v(s2, s1, model)
        self.assertEqual(psim, psim2)

    def test_w2v_notinvocab(self):
        testdir = os.path.dirname(os.path.realpath(__file__))
        modelfile = testdir + '/../potara/data/enwiki9stempos.model'
        try:
            model = gensim.models.word2vec.Word2Vec.load(modelfile)
        except:
            return

        s1 = "This/T beauful/JJ sentence/NN is/V not/N right/JJ ./PUNCT"
        s2 = "This/T beautiful/JJ sentence/NN is/V wrong/JJ ./PUNCT"

        esim = 0.7208
        psim = sm.w2v(s1, s2, model)
        self.assertAlmostEqual(esim, psim, places=3)

    def test_w2v_singleword(self):
        testdir = os.path.dirname(os.path.realpath(__file__))
        modelfile = testdir + '/../potara/data/enwiki9stempos.model'
        try:
            model = gensim.models.word2vec.Word2Vec.load(modelfile)
        except:
            return

        s1 = "right/JJ"
        s2 = "wrong/JJ"

        # a single different word means 0 sim
        esim = 0
        psim = sm.w2v(s1, s2, model)
        self.assertEqual(esim, psim)

        s3 = "right/JJ"
        esim2 = 1
        psim2 = sm.w2v(s1, s3, model)
        self.assertEqual(esim2, psim2)

    def test_w2v_untag(self):
        testdir = os.path.dirname(os.path.realpath(__file__))
        modelfile = testdir + '/../potara/data/enwiki9stempos.model'
        try:
            model = gensim.models.word2vec.Word2Vec.load(modelfile)
        except:
            return

        s1 = "This sentence is not right ."
        s2 = "This sentence is wrong ."

        # without tags we consider the intersection over min length
        esim = 4.0/5
        psim = sm.w2v(s1, s2, model)
        self.assertEqual(esim, psim)

if __name__ == '__main__':
    unittest.main()
        <|endoftext|>


<commit_before># MANSEDS Lunar Rover -- Arm Controller
# Author: Ethan Ramsay

# Import dependencies
import argparse
import RPi.GPIO as GPIO
import Adafruit_PCA9685
# import ikpy
import numpy as np
# from ikpy import plot_utils
import logging

# Logging config
logging.basicConfig(filename='arm.log', level=logging.DEBUG)

# System variables
channel_arm = [0, 1, 2, 3, 4] # Arm servo PWM channels
channel_grip = [5, 6] # Gripper servo PWM channels
pl_limits_arm = [[160, 600], [160, 600], [160, 600], [160, 600], [160, 600], [160, 600]] # Arm servo pl limits
pl_limits_grip = [[160, 600], [160, 600]] # Gripper servo pulse length limits
full_grip_pl = 300
full_release_pl = 580
deposit_pl = [400, 400, 400, 400, 400, 400, 300]
pwm_arm = [0, 0, 0, 0, 0] # Arm servo PWM pins
pwm_grip = [0, 0] # Gripper servo PWM pins
dc_limits_arm = [[0, 13], [0, 13], [0, 13], [0, 13], [0, 13], [0, 13]] # Arm servo pl limits
dc_limits_grip = [[0, 13], [0, 13]] # Gripper servo pulse length limits
full_grip_dc = 7 # Gripper dc at fully closed position
full_release_dc = 13 # Gripper dc at fully open position
arm_angle = 0 # Arm angle relative to chassis

# Create kinematic chain from URDF file
# lunar_chain = ikpy.chain.Chain.from_urdf_file("arm.urdf")

# GPIO setup
GPIO.setmode(GPIO.BCM)

def GPIO_arm(pwm_arm):
    for pin in pwm_arm:
        GPIO.setup(pin, GPIO.OUT)
        GPIO.PWM(pin, 60)

def GPIO_grip(pwm_grip):
    for pin in pwm_grip:
        GPIO.setup(pin, GPIO.OUT)
        GPIO.PWM(pin, 60)

# Setup Adafruit PWM Hat
pwm = Adafruit_PCA9685.PCA9685()
pwm.set_pwm_freq(60)
logging.debug("Adafruit PWM freq set to 60")

# Positioning functions
def calc_servo_angles(target_vector):
    logging.debug("Desired gripper position vector: %s", target_vector)
    target_radius = (target_vector[0]**2 + target_vector[1]**2)**(0.5)
    if target_radius < max_radius:
        raise ValueError('Desired position exceeds reach!')

    servo_angles = []
    logging.debug("Calculated servo angles: %s", servo_angles)
    return servo_angles

def calc_dc(dc_min, dc_max, angle):
    dc_range = dc_max - dc_min
    inter = dc_range * angle / 180
    dc = dc_min + inter
    logging.debug("Calculated required duty cycle for desired servo angle: %s", dc)
    return dc

def calc_pl(pl_min, pl_max, angle):
    if angle > 180:
        raise ValueError("Desired angle exceeds servo range of 180 deg")
    pl_range = servo_max - servo_min
    inter = pl_range * angle / 180
    pl = pl_min + inter
    logging.debug("Calculated required pulse length for desired servo angle: %s", pl)
    pl = int(pl)
    return pl

# Control functions
def extend():
    val = 1
    while True:
        pwm.set_pwm(0, 0, pl_limits_arm[0][1])
        pwm.set_pwm(1, 0, pl_limits_arm[1][1])
        pwm.set_pwm(2, 0, pl_limits_arm[2][1])
        pwm.set_pwm(3, 0, pl_limits_arm[3][1]/2)
        pwm.set_pwm(4, 0, pl_limits_arm[4][1]/2)
        pwm.set_pwm(5, 0, pl_limits_grip[0][1]/2)
        pwm.set_pwm(6, 0, pl_limits_grip[1][1]/2)
        if val > 0:
            logging.debug("Arm extended")
            val -= 1

def stow():
    val = 1
    while True:
        pwm.set_pwm(0, 0, pl_limits_arm[0][0])
        pwm.set_pwm(1, 0, 300) # pl_limits_arm[1][0])
        pwm.set_pwm(2, 0, 300) # pl_limits_arm[2][0])
        pwm.set_pwm(3, 0, 270) # pl_limits_arm[3][0])
        pwm.set_pwm(4, 0, pl_limits_arm[4][0])
        pwm.set_pwm(5, 0, 240) # pl_limits_grip[0][0])
        pwm.set_pwm(6, 0, pl_limits_grip[1][0])
        if val == 1:
            logging.debug("Arm stowed")
            val -= 1

def deposit_pos():
    val = 1
    deposit_pl[0] = 410
    deposit_pl[1] = calc_pl(pl_limits_arm[1][0], pl_limits_arm[1][0], 45)
    deposit_pl[2] = deposit_pl[1]
    deposit_pl[3] = calc_pl(pl_limits_arm[3][0], pl_limits_arm[3][0], 135)
    # need to set base rotation to 0
    rotate_arm(0, 0)
    while True:
        pwm.set_pwm(0, 0, deposit_pl[0])
        pwm.set_pwm(1, 0, deposit_pl[1])
        pwm.set_pwm(2, 0, deposit_pl[2])
        pwm.set_pwm(3, 0, deposit_pl[3])
        pwm.set_pwm(4, 0, deposit_pl[4])
        pwm.set_pwm(5, 0, deposit_pl[5])
        pwm.set_pwm(6, 0, deposit_pl[6])
        if val == 1:
            logging.debug("Gripper positioned above ice box")
            val -= 1

def position_gripper(target_vector):
    a = calc_servo_angles(target_vector)
    pl = [0, 0, 0, 0, 0]
    val = 1
    for i in range(1, 5, 1):
        pl[i] = calc_pl(pl_limits_arm[i][0], pl_limits_arm[i][1], a[i])
    while True:
        pwm.set_pwm(1, 0, pl[1])
        pwm.set_pwm(2, 0, pl[2])
        pwm.set_pwm(3, 0, pl[3])
        pwm.set_pwm(4, 0, pl[4])
        pwm.set_pwm(5, 0, pl[5])
        if val == 1:
            logging.debug("Arm position command called for target vector: {}".format(target_vector))
            logging.debug("Calculated pulse lengths to achieve target vector: {}".format(pl))
            val -= 1

def rotate_arm(desired_angle, channel):
    if desired_angle > 40 or desired_angle < -40:
        raise ValueError("Desired angle exceeds current configuration range: min = -40 deg; max  \
        = 40 deg")
    current_angle = 0
    with open(base_angle_data_filename, 'r') as f:
        current_angle = f.read()
    print(current_angle)
    perc_full_rot = 100 * (desired_angle - current_angle) / 360
    print(perc_full_rot)
    if desired_angle < current_angle:
        rot_time = ccw_full_rot_time * perc_full_rot / 100
        print(rot_time)
        pwm.set_pwm(channel, 0, 440)
        time.sleep(rot_time)
        pwm.set_pwm(channel, 0, 410)
        with open(base_angle_data_filename, 'w') as f:
            f.write(desired_angle)
    elif desired_angle > current_angle:
        rot_time = ccw_full_rot_time * compensation_factor * perc_full_rot / 100
        pwm.set_pwm(channel, 0, 220)
        time.sleep(rot.time)
        pwm.set_pwm(channel, 0, 410)
        with open(base_angle_data_filename, 'w') as f:
            f.write(desired_angle)
    else:
        pwm.set_pwm(channel, 0, 410)
        # cuurent angle must be equal to desired angle

def grip():
    val = 1
    while True:
        pwm.set_pwm(6, 0, full_grip_pl)
        if val == 1:
            logging.debug("Gripper clamped")
            val -= 1

def drop():
    val = 1
    while True:
        pwm.set_pwm(6, 0, full_release_pl)
        if val == 1:
            logging.debug("Gripper released")
            val -= 1

def worm():
    while True:
        for i in range(0, 400, 1):
            if i < 100:
                pl_1 = 400 - i
            if i > 20 and i < 200:
                pl_1 = 300
                pl_3 = 60 + i
            if i > 200:
                pl_1 = 250
                pl_3 = 400 -i
            if i > 240:
                pl_1 = 250
                pl_3 = 400 - 1
                pl_4 = i
            if i > 320:
                pl_1 = 160 + i
                pl_3 = 160 + 400 - i
                pl_4 = 160 + 400 - i
            pwm.set_pwm(1, 0, pl_1)
            pwm.set_pwm(2, 0, pl_1)

# Main
if __name__ == "__main__":
    # Arguments
    parser = argparse.ArgumentParser()
    g = parser.add_mutually_exclusive_group(required=True)
    ge = g.add_mutually_exclusive_group()
    ge.add_argument("-e", "--extend", help="Extend arm", action="store_true")
    ge.add_argument("-s", "--stow", help="Stow arm", action="store_true")
    ge.add_argument("-w", "--wave", help="Do the worm", action="store_true")
    gp = g.add_mutually_exclusive_group()
    gp.add_argument("-r", "--rotate", help="Rotate arm at base (Angle)")
    gp.add_argument("-p", "--position", help="Gripper Position Vector [radius, height]")
    gp.add_argument("-i", "--icebox", help="Position gripper above ice box to deposit sample", action="store_true")
    gg = g.add_mutually_exclusive_group()
    gg.add_argument("-g", "--grip", help="Grip", action="store_true")
    gg.add_argument("-d", "--drop", help="Release grip", action="store_true")
    args = parser.parse_args()
    e = args.extend
    s = args.stow
    w = args.wave
    if args.rotate:
        r = int(args.rotate)
    r = False
    p = args.position # <-- convert from string into ??? format???
    i = args.icebox
    g = args.grip
    d = args.drop
    logging.debug("Arguments parsed: e=%s, s=%s, r=%s, p=%s, i=%s, g=%s, d=%s, w=%s", + \
                        e, s, r, p, i, g, d, w)

    if (e or s):
        # GPIO_arm()
        if e:
            extend()
        elif s:
            stow()
    elif ((p or r) or i):
        if p:
            # GPIO_arm()
            position_gripper(p)
        elif r:
            rotate_arm(r, 0)
        elif i:
            deposit_pos()
    elif (g or d):
        # GPIO_grip()
        if g:
            grip()
        elif d:
            drop()
    elif w:
        worm()

# GPIO cleanup
GPIO.cleanup()
<commit_msg>Fixed a bug Arm_controller.py<commit_after># MANSEDS Lunar Rover -- Arm Controller
# Author: Ethan Ramsay

# Import dependencies
import argparse
import RPi.GPIO as GPIO
import Adafruit_PCA9685
# import ikpy
import numpy as np
# from ikpy import plot_utils
import logging

# Logging config
logging.basicConfig(filename='arm.log', level=logging.DEBUG)

# System variables
channel_arm = [0, 1, 2, 3, 4] # Arm servo PWM channels
channel_grip = [5, 6] # Gripper servo PWM channels
pl_limits_arm = [[160, 600], [160, 600], [160, 600], [160, 600], [160, 600], [160, 600]] # Arm servo pl limits
pl_limits_grip = [[160, 600], [160, 600]] # Gripper servo pulse length limits
full_grip_pl = 300
full_release_pl = 580
deposit_pl = [400, 400, 400, 400, 400, 400, 300]
pwm_arm = [0, 0, 0, 0, 0] # Arm servo PWM pins
pwm_grip = [0, 0] # Gripper servo PWM pins
dc_limits_arm = [[0, 13], [0, 13], [0, 13], [0, 13], [0, 13], [0, 13]] # Arm servo pl limits
dc_limits_grip = [[0, 13], [0, 13]] # Gripper servo pulse length limits
full_grip_dc = 7 # Gripper dc at fully closed position
full_release_dc = 13 # Gripper dc at fully open position
arm_angle = 0 # Arm angle relative to chassis

# Create kinematic chain from URDF file
# lunar_chain = ikpy.chain.Chain.from_urdf_file("arm.urdf")

# GPIO setup
GPIO.setmode(GPIO.BCM)

def GPIO_arm(pwm_arm):
    for pin in pwm_arm:
        GPIO.setup(pin, GPIO.OUT)
        GPIO.PWM(pin, 60)

def GPIO_grip(pwm_grip):
    for pin in pwm_grip:
        GPIO.setup(pin, GPIO.OUT)
        GPIO.PWM(pin, 60)

# Setup Adafruit PWM Hat
pwm = Adafruit_PCA9685.PCA9685()
pwm.set_pwm_freq(60)
logging.debug("Adafruit PWM freq set to 60")

# Positioning functions
def calc_servo_angles(target_vector):
    logging.debug("Desired gripper position vector: %s", target_vector)
    target_radius = (target_vector[0]**2 + target_vector[1]**2)**(0.5)
    if target_radius < max_radius:
        raise ValueError('Desired position exceeds reach!')

    servo_angles = []
    logging.debug("Calculated servo angles: %s", servo_angles)
    return servo_angles

def calc_dc(dc_min, dc_max, angle):
    dc_range = dc_max - dc_min
    inter = dc_range * angle / 180
    dc = dc_min + inter
    logging.debug("Calculated required duty cycle for desired servo angle: %s", dc)
    return dc

def calc_pl(pl_min, pl_max, angle):
    if angle > 180:
        raise ValueError("Desired angle exceeds servo range of 180 deg")
    pl_range = pl_max - pl_min
    inter = pl_range * angle / 180
    pl = pl_min + inter
    logging.debug("Calculated required pulse length for desired servo angle: %s", pl)
    pl = int(pl)
    return pl

# Control functions
def extend():
    val = 1
    while True:
        pwm.set_pwm(0, 0, pl_limits_arm[0][1])
        pwm.set_pwm(1, 0, pl_limits_arm[1][1])
        pwm.set_pwm(2, 0, pl_limits_arm[2][1])
        pwm.set_pwm(3, 0, pl_limits_arm[3][1]/2)
        pwm.set_pwm(4, 0, pl_limits_arm[4][1]/2)
        pwm.set_pwm(5, 0, pl_limits_grip[0][1]/2)
        pwm.set_pwm(6, 0, pl_limits_grip[1][1]/2)
        if val > 0:
            logging.debug("Arm extended")
            val -= 1

def stow():
    val = 1
    while True:
        pwm.set_pwm(0, 0, pl_limits_arm[0][0])
        pwm.set_pwm(1, 0, 300) # pl_limits_arm[1][0])
        pwm.set_pwm(2, 0, 300) # pl_limits_arm[2][0])
        pwm.set_pwm(3, 0, 270) # pl_limits_arm[3][0])
        pwm.set_pwm(4, 0, pl_limits_arm[4][0])
        pwm.set_pwm(5, 0, 240) # pl_limits_grip[0][0])
        pwm.set_pwm(6, 0, pl_limits_grip[1][0])
        if val == 1:
            logging.debug("Arm stowed")
            val -= 1

def deposit_pos():
    val = 1
    deposit_pl[0] = 410
    deposit_pl[1] = calc_pl(pl_limits_arm[1][0], pl_limits_arm[1][0], 45)
    deposit_pl[2] = deposit_pl[1]
    deposit_pl[3] = calc_pl(pl_limits_arm[3][0], pl_limits_arm[3][0], 135)
    # need to set base rotation to 0
    rotate_arm(0, 0)
    while True:
        pwm.set_pwm(0, 0, deposit_pl[0])
        pwm.set_pwm(1, 0, deposit_pl[1])
        pwm.set_pwm(2, 0, deposit_pl[2])
        pwm.set_pwm(3, 0, deposit_pl[3])
        pwm.set_pwm(4, 0, deposit_pl[4])
        pwm.set_pwm(5, 0, deposit_pl[5])
        pwm.set_pwm(6, 0, deposit_pl[6])
        if val == 1:
            logging.debug("Gripper positioned above ice box")
            val -= 1

def position_gripper(target_vector):
    a = calc_servo_angles(target_vector)
    pl = [0, 0, 0, 0, 0]
    val = 1
    for i in range(1, 5, 1):
        pl[i] = calc_pl(pl_limits_arm[i][0], pl_limits_arm[i][1], a[i])
    while True:
        pwm.set_pwm(1, 0, pl[1])
        pwm.set_pwm(2, 0, pl[2])
        pwm.set_pwm(3, 0, pl[3])
        pwm.set_pwm(4, 0, pl[4])
        pwm.set_pwm(5, 0, pl[5])
        if val == 1:
            logging.debug("Arm position command called for target vector: {}".format(target_vector))
            logging.debug("Calculated pulse lengths to achieve target vector: {}".format(pl))
            val -= 1

def rotate_arm(desired_angle, channel):
    if desired_angle > 40 or desired_angle < -40:
        raise ValueError("Desired angle exceeds current configuration range: min = -40 deg; max  \
        = 40 deg")
    current_angle = 0
    with open(base_angle_data_filename, 'r') as f:
        current_angle = f.read()
    print(current_angle)
    perc_full_rot = 100 * (desired_angle - current_angle) / 360
    print(perc_full_rot)
    if desired_angle < current_angle:
        rot_time = ccw_full_rot_time * perc_full_rot / 100
        print(rot_time)
        pwm.set_pwm(channel, 0, 440)
        time.sleep(rot_time)
        pwm.set_pwm(channel, 0, 410)
        with open(base_angle_data_filename, 'w') as f:
            f.write(desired_angle)
    elif desired_angle > current_angle:
        rot_time = ccw_full_rot_time * compensation_factor * perc_full_rot / 100
        pwm.set_pwm(channel, 0, 220)
        time.sleep(rot.time)
        pwm.set_pwm(channel, 0, 410)
        with open(base_angle_data_filename, 'w') as f:
            f.write(desired_angle)
    else:
        pwm.set_pwm(channel, 0, 410)
        # cuurent angle must be equal to desired angle

def grip():
    val = 1
    while True:
        pwm.set_pwm(6, 0, full_grip_pl)
        if val == 1:
            logging.debug("Gripper clamped")
            val -= 1

def drop():
    val = 1
    while True:
        pwm.set_pwm(6, 0, full_release_pl)
        if val == 1:
            logging.debug("Gripper released")
            val -= 1

def worm():
    while True:
        for i in range(0, 400, 1):
            if i < 100:
                pl_1 = 400 - i
            if i > 20 and i < 200:
                pl_1 = 300
                pl_3 = 60 + i
            if i > 200:
                pl_1 = 250
                pl_3 = 400 -i
            if i > 240:
                pl_1 = 250
                pl_3 = 400 - 1
                pl_4 = i
            if i > 320:
                pl_1 = 160 + i
                pl_3 = 160 + 400 - i
                pl_4 = 160 + 400 - i
            pwm.set_pwm(1, 0, pl_1)
            pwm.set_pwm(2, 0, pl_1)

# Main
if __name__ == "__main__":
    # Arguments
    parser = argparse.ArgumentParser()
    g = parser.add_mutually_exclusive_group(required=True)
    ge = g.add_mutually_exclusive_group()
    ge.add_argument("-e", "--extend", help="Extend arm", action="store_true")
    ge.add_argument("-s", "--stow", help="Stow arm", action="store_true")
    ge.add_argument("-w", "--wave", help="Do the worm", action="store_true")
    gp = g.add_mutually_exclusive_group()
    gp.add_argument("-r", "--rotate", help="Rotate arm at base (Angle)")
    gp.add_argument("-p", "--position", help="Gripper Position Vector [radius, height]")
    gp.add_argument("-i", "--icebox", help="Position gripper above ice box to deposit sample", action="store_true")
    gg = g.add_mutually_exclusive_group()
    gg.add_argument("-g", "--grip", help="Grip", action="store_true")
    gg.add_argument("-d", "--drop", help="Release grip", action="store_true")
    args = parser.parse_args()
    e = args.extend
    s = args.stow
    w = args.wave
    if args.rotate:
        r = int(args.rotate)
    r = False
    p = args.position # <-- convert from string into ??? format???
    i = args.icebox
    g = args.grip
    d = args.drop
    logging.debug("Arguments parsed: e=%s, s=%s, r=%s, p=%s, i=%s, g=%s, d=%s, w=%s", + \
                        e, s, r, p, i, g, d, w)

    if (e or s):
        # GPIO_arm()
        if e:
            extend()
        elif s:
            stow()
    elif ((p or r) or i):
        if p:
            # GPIO_arm()
            position_gripper(p)
        elif r:
            rotate_arm(r, 0)
        elif i:
            deposit_pos()
    elif (g or d):
        # GPIO_grip()
        if g:
            grip()
        elif d:
            drop()
    elif w:
        worm()

# GPIO cleanup
GPIO.cleanup()
<|endoftext|>