Ejemplo n.º 1
0
    def setUp(self):

        self.LibValidator = LibraryValidator()
        self.ExpValidator = ExperimentValidator()
        self.RuntimeValidator = RuntimeValidator()
        self.experiments_base = "%s/experiments" % (here)
        self.experiments = glob("%s/*" % self.experiments_base)
Ejemplo n.º 2
0
    def setUp(self):

        self.LibValidator = LibraryValidator()
        self.ExpValidator = ExperimentValidator()
        self.RuntimeValidator = RuntimeValidator()
        self.experiments_base = "/scif/data"
        self.experiments = glob("%s/*md" % self.experiments_base)
Ejemplo n.º 3
0
class TestExperiment(TestCase):
    def setUp(self):

        self.ExpValidator = ExperimentValidator()
        self.base = "/scif/apps"
        self.experiments = glob("%s/*" % self.base)
        self.contenders = [os.path.basename(x) for x in self.experiments]

    def test_experiment(self):
        """test an experiment, including the markdown file, and repo itself
        """
        print("...Test: Experiment Validation")

        # First priority - the user gave an experiment folder
        if "config.json" in self.contenders:
            for experiment in self.experiments:
                name = os.path.basename(experiment)
                if name == "config.json":
                    valid = self.ExpValidator.validate(experiment,
                                                       validate_folder=False)
                    self.assertTrue(valid)

        # Otherwise, the user gave a folder with subfolders
        else:
            for experiment in self.experiments:
                name = os.path.basename(experiment)
                if os.path.isdir(experiment):
                    print("Found experiment %s" % name)
                    valid = self.ExpValidator.validate(experiment)
                    self.assertTrue(valid)
Ejemplo n.º 4
0
class TestExperiment(TestCase):

    def setUp(self):

        self.ExpValidator = ExperimentValidator()
        self.base = "/scif/apps"
        self.experiments = glob("%s/*" %self.base)
        self.contenders = [os.path.basename(x) for x in self.experiments]
        
    def test_experiment(self):
        '''test an experiment, including the markdown file, and repo itself
        '''
        print("...Test: Experiment Validation")

        # First priority - the user gave an experiment folder
        if "config.json" in self.contenders:
            for experiment in self.experiments:
                name = os.path.basename(experiment)
                if name == "config.json":
                    valid = self.ExpValidator.validate(experiment, validate_folder=False) 
                    self.assertTrue(valid)

        # Otherwise, the user gave a folder with subfolders
        else:
            for experiment in self.experiments:
                name = os.path.basename(experiment)
                if os.path.isdir(experiment):
                    print('Found experiment %s' %name)
                    valid = self.ExpValidator.validate(experiment) 
                    self.assertTrue(valid)
Ejemplo n.º 5
0
def validate(folder=None, cleanup=False):
    '''validate
    :param folder: full path to experiment folder with config.json. If path begins
                   with https, we assume to be starting from a repository.
    '''
    from expfactory.validator import ExperimentValidator
    cli = ExperimentValidator()
    return cli.validate(folder, cleanup=cleanup)
Ejemplo n.º 6
0
def validate(folder=None, cleanup=False):
    '''validate
    :param folder: full path to experiment folder with config.json. If path begins
                   with https, we assume to be starting from a repository.
    '''
    from expfactory.validator import ExperimentValidator
    cli = ExperimentValidator()
    return cli.validate(folder, cleanup=cleanup)
Ejemplo n.º 7
0
    def setUp(self):

        self.LibValidator = LibraryValidator()
        self.ExpValidator = ExperimentValidator()
        self.RuntimeValidator = RuntimeValidator()
        self.experiments_base = "%s/docs/_library" % (here)
        self.experiments = self.get_changed_files()
        self.added = [x for x in self.experiments if '_library' in x]
        print('Found %s changed or modified files.' % len(self.added))
Ejemplo n.º 8
0
    def setUp(self):

        self.LibValidator = LibraryValidator()
        self.ExpValidator = ExperimentValidator()
        self.RuntimeValidator = RuntimeValidator()
        self.experiments_base = "/scif/data" 
        self.experiments = glob("%s/*md" %self.experiments_base)
Ejemplo n.º 9
0
class TestContribution(TestCase):
    def setUp(self):

        self.LibValidator = LibraryValidator()
        self.ExpValidator = ExperimentValidator()
        self.RuntimeValidator = RuntimeValidator()
        self.experiments_base = "/scif/data"
        self.experiments = glob("%s/*md" % self.experiments_base)

    def test_contribution(self):
        '''test an experiment, including the markdown file, and repo itself
        '''
        if len(self.experiments) == 0:
            print(
                'Please bind the directory with your markdown files for the library.'
            )
            sys.exit(1)

        print("...Test: Global Library validation")
        for ymlfile in self.experiments:
            self.assertTrue(self.LibValidator.validate(ymlfile))
            url = self.LibValidator.metadata['github']
            self.assertTrue(self.ExpValidator.validate(url))
            result = self.RuntimeValidator.validate(url)
            print(result)
            print(url)
            self.assertTrue(result)
Ejemplo n.º 10
0
class TestContribution(TestCase):

    def setUp(self):

        self.LibValidator = LibraryValidator()
        self.ExpValidator = ExperimentValidator()
        self.RuntimeValidator = RuntimeValidator()
        self.experiments_base = "/scif/data" 
        self.experiments = glob("%s/*md" %self.experiments_base)
        
    def test_contribution(self):
        '''test an experiment, including the markdown file, and repo itself
        '''
        if len(self.experiments) == 0:
            print('Please bind the directory with your markdown files for the library.')
            sys.exit(1)

        print("...Test: Global Library validation")
        for ymlfile in self.experiments:
            self.assertTrue(self.LibValidator.validate(ymlfile))
            url = self.LibValidator.metadata['github']
            self.assertTrue(self.ExpValidator.validate(url))
            result = self.RuntimeValidator.validate(url)
            print(result)
            print(url)        
            self.assertTrue(result)
Ejemplo n.º 11
0
class TestLibrary(TestCase):
    def setUp(self):

        self.LibValidator = LibraryValidator()
        self.ExpValidator = ExperimentValidator()
        self.RuntimeValidator = RuntimeValidator()
        self.experiments_base = "%s/docs/_library" % (here)
        self.experiments = self.get_changed_files()
        self.added = [x for x in self.experiments if '_library' in x]
        print('Found %s changed or modified files.' % len(self.added))

    def get_changed_files(self):
        '''use the Github compare url (provided by circle) to find 
        changed files between commits'''

        # Fallback, return all files in experiment base
        experiments = glob("%s/*" % self.experiments_base)

        compare_url = os.environ.get("CIRCLE_COMPARE_URL")

        # If the variable exists, we are running on Circle
        if compare_url is not None:
            print('Detected running in Circle CI')

            # If defined, derive change list from compare url
            if compare_url != '':

                compare_url = "%s.patch" % compare_url
                print("Compare URL: %s" % compare_url)
                response = requests.get(compare_url)
                if response.status_code == 200:
                    experiments = set(
                        re.findall(' docs/_library/.+[.]md', response.text))
                    experiments = [x.strip() for x in experiments]

            # Otherwise, use all experiments
            else:
                print("No compare URL detected, using entire listing.")
                experiments = glob('%s/*.md' % self.experiments_base)
        else:
            print("Not running in Circle Ci")

        return experiments

    def test_experiment(self):
        '''test an experiment, including the markdown file, and repo itself
        '''
        print("...Test: Global Library validation")
        for ymlfile in self.experiments:
            if os.path.exists(ymlfile):
                print("TESTING %s" % ymlfile)
                self.assertTrue(self.LibValidator.validate(ymlfile))
                url = self.LibValidator.metadata['github']
                self.assertTrue(self.ExpValidator.validate(url))
                result = self.RuntimeValidator.validate(url)
                print(result)
                print(url)
                self.assertTrue(result)
Ejemplo n.º 12
0
    def validate(self, folder):
        '''validate is the first entrypoint function for running an experiment
           or survey robot. It ensures that the content is valid,
           and then calls _validate (should be defined in subclass)'''
            
        validator = ExperimentValidator()
        valid = validator.validate(folder)

        if valid is True:

            # IF missing favicon, add
            self._check_favicon(folder)

            valid = self._validate(folder)
            bot.log("[done] stopping web server...")
            self.httpd.server_close()
        else:
            bot.warning('%s is not valid, skipping robot testing.' %folder)
Ejemplo n.º 13
0
class TestLibrary(TestCase):
    def setUp(self):

        self.LibValidator = LibraryValidator()
        self.ExpValidator = ExperimentValidator()
        self.RuntimeValidator = RuntimeValidator()
        self.experiments_base = "%s/experiments" % (here)
        self.experiments = glob("%s/*" % self.experiments_base)

    def test_library(self):
        '''test_validate_library calls all subfunctions
        '''
        print("...Test: Global Library validation")
        for jsonfile in self.experiments:
            self.assertTrue(self.LibValidator.validate(jsonfile))

    def test_single_experiments(self):
        '''test_load_json ensures that all files load
        '''
        for jsonfile in self.experiments:
            print("...%s" % os.path.basename(jsonfile))
            config = read_json(jsonfile)
            self.assertTrue('github' in config)
            self.assertTrue(isinstance(config, dict))
            url = config['github']
            self.assertTrue(self.ExpValidator.validate(url))

    def test_previews(self):
        '''assert that each experiment is previewed at the Github page
           where served
        '''
        bot.test('Testing experiment previews...')
        for jsonfile in self.experiments:
            experiment = os.path.basename(jsonfile)
            print("...%s experiment preview?" % experiment)
            config = read_json(jsonfile)
            self.assertTrue('github' in config)
            self.assertTrue(isinstance(config, dict))
            url = config['github']
            result = self.RuntimeValidator.validate(url)
            print(result)
            print(url)
            self.assertTrue(result)
Ejemplo n.º 14
0
def main(args,parser,subparser):

    folder = args.folder
    if folder is None:
        folder = os.getcwd()

    source = args.src[0]
    if source is None:
        bot.error('Please provide a Github https address to install.')
        sys.exit(1)

    # Is the experiment valid?
    cli = ExperimentValidator()
    valid = cli.validate(source, cleanup=False)
    exp_id = os.path.basename(source).replace('.git','')

    if valid is True:

        # Local Install
        if os.path.exists(source):
            config = load_experiment(source)
            source = os.path.abspath(source)
        else:
            config = load_experiment("%s/%s" %(cli.tmpdir,exp_id))
            source = "%s/%s" %(cli.tmpdir,exp_id)

        exp_id = config['exp_id']
        python_module = exp_id.replace('-','_').lower()
    else:
        bot.error('%s is not valid.' % exp_id)
        sys.exit(1)

    # Move static files to output folder
    dest = "%s/%s" %(folder,exp_id)

    bot.log("Installing %s to %s" %(exp_id, dest))
    
    # Building container
    in_container = False
    if os.environ.get('SINGULARITY_IMAGE') is not None:
        in_container = True

    # Running, live container
    elif os.environ.get('EXPFACTORY_CONTAINER') is not None:
        in_container = True

    if in_container is True:

        # if in container, we always force
        args.force = True

        bot.log("Preparing experiment routes...")
        template = get_template('experiments/template.py')
        template = sub_template(template, '{{ exp_id }}', exp_id)
        template = sub_template(template, '{{ exp_id_python }}', python_module)

        # 1. Python blueprint
        views = get_viewsdir(base=args.base)
        view_output = "%s/%s.py" %(views, python_module)
        save_template(view_output, template, base=views)
    
        # 2. append to __init__
        init = "%s/__init__.py" % views
        with open(init,'a') as filey:
            filey.writelines('from .%s import *\n' %python_module)

        # 3. Instructions
        if "instructions" in config:
            instruct = "%s/%s.help" %(views, python_module)
        with open(instruct,'w') as filey:
            filey.writelines(config['instructions'])

    if not os.path.exists(dest):
        os.system('mkdir -p %s' %dest)
    else:
        if args.force is False:
            bot.error('%s is not empty! Use --force to delete and re-create.' %folder)
            sys.exit(1) 

    # We don't need to copy if experiment already there
    if source != dest:
        os.system('cp -R %s/* %s' %(source, dest))
Ejemplo n.º 15
0
    def setUp(self):

        self.ExpValidator = ExperimentValidator()
        self.base = "/scif/apps"
        self.experiments = glob("%s/*" % self.base)
        self.contenders = [os.path.basename(x) for x in self.experiments]
Ejemplo n.º 16
0
def main(args, parser, subparser):

    # List of experiments is required
    template = get_template('build/docker/Dockerfile.template')

    # For now, only one database provided
    database = args.database
    studyid = args.studyid
    experiments = args.experiments

    template = sub_template(template, "{{studyid}}", studyid)
    template = sub_template(template, "{{database}}", database)

    library = get_library(key='name')

    apps = "\n"

    # Add local experiments to library, first preference
    local_installs = 0
    for experiment in experiments:
        if os.path.exists(experiment):

            bot.info('local experiment %s found, validating...' % experiment)

            # Is the experiment valid?
            cli = ExperimentValidator()
            valid = cli.validate(experiment, cleanup=False)

            if valid is True:
                local_installs += 1
                config = load_experiment(experiment)
                exp_id = config['exp_id']

                # If we aren't building in the experiment directory, we need to copy there
                output_dir = "%s/%s" % (os.path.abspath(
                    os.path.dirname(args.output)), exp_id)
                experiment_dir = os.path.abspath(experiment)
                if output_dir != experiment_dir:
                    copy_directory(experiment_dir, output_dir)

                config['local'] = os.path.abspath(experiment)
                library[exp_id] = config

    # Warn the user that local installs are not reproducible (from recipe)
    if local_installs > 0:
        bot.warning(
            "%s local installs detected: build is not reproducible without experiment folders"
            % local_installs)

    # Build Image with Experiments
    for experiment in experiments:
        exp_id = os.path.basename(experiment)
        if exp_id in library:
            config = library[exp_id]

            app = "LABEL EXPERIMENT_%s /scif/apps/%s\n" % (exp_id, exp_id)

            # Here add custom build routine, should be list of lines
            if "install" in config:
                commands = "\n".join(
                    ["RUN %s " % s for x in config['install']]).strip('\n')
                app = "%s%s\n" % (app, commands)

            # The final installation step, either from Github (url) or local folder
            if "local" in config:
                app = "%sADD %s /scif/apps/%s\n" % (app, exp_id, exp_id)
                app = "%sWORKDIR /scif/apps\nRUN expfactory install %s\n" % (
                    app, exp_id)
            else:
                app = "%sWORKDIR /scif/apps\nRUN expfactory install %s\n" % (
                    app, config['github'])
            apps = "%s%s\n" % (apps, app)

        else:
            bot.warning('%s not in library, check spelling & punctuation.' %
                        exp_id)

    if apps == "\n":
        bot.error('No valid experiments found, cancelling recipe build.')
        sys.exit(1)

    template = sub_template(template, "{{experiments}}", apps)
    outfile = write_file(args.output, template)
    bot.log("Recipe written to %s" % outfile)
Ejemplo n.º 17
0
def main(args, parser, subparser):

    folder = args.folder
    if folder is None:
        folder = os.getcwd()

    source = args.src[0]
    if source is None:
        bot.error('Please provide a Github https address to install.')
        sys.exit(1)

    # Is the experiment valid?
    cli = ExperimentValidator()
    valid = cli.validate(source, cleanup=False)
    exp_id = os.path.basename(source).replace('.git', '')

    if valid is True:

        # Local Install
        if os.path.exists(source):
            config = load_experiment(source)
            source = os.path.abspath(source)
        else:
            config = load_experiment("%s/%s" % (cli.tmpdir, exp_id))
            source = "%s/%s" % (cli.tmpdir, exp_id)

        exp_id = config['exp_id']
        python_module = exp_id.replace('-', '_').lower()
    else:
        bot.error('%s is not valid.' % exp_id)
        sys.exit(1)

    # Move static files to output folder
    dest = "%s/%s" % (folder, exp_id)

    bot.log("Installing %s to %s" % (exp_id, dest))

    # Building container
    in_container = False
    if os.environ.get('SINGULARITY_IMAGE') is not None:
        in_container = True

    # Running, live container
    elif os.environ.get('EXPFACTORY_CONTAINER') is not None:
        in_container = True

    if in_container is True:

        # if in container, we always force
        args.force = True

        bot.log("Preparing experiment routes...")
        template = get_template('experiments/template.py')
        template = sub_template(template, '{{ exp_id }}', exp_id)
        template = sub_template(template, '{{ exp_id_python }}', python_module)

        # 1. Python blueprint
        views = get_viewsdir(base=args.base)
        view_output = "%s/%s.py" % (views, python_module)
        save_template(view_output, template, base=views)

        # 2. append to __init__
        init = "%s/__init__.py" % views
        with open(init, 'a') as filey:
            filey.writelines('from .%s import *\n' % python_module)

        # 3. Instructions
        if "instructions" in config:
            instruct = "%s/%s.help" % (views, python_module)
        with open(instruct, 'w') as filey:
            filey.writelines(config['instructions'])

    if not os.path.exists(dest):
        os.system('mkdir -p %s' % dest)
    else:
        if args.force is False:
            bot.error('%s is not empty! Use --force to delete and re-create.' %
                      folder)
            sys.exit(1)

    # We don't need to copy if experiment already there
    if source != dest:
        os.system('cp -R %s/* %s' % (source, dest))
Ejemplo n.º 18
0
def main(args, parser, subparser):

    template = "build/docker/Dockerfile.template"

    # Full path to template is required if provided via input
    if args.input is not None:
        template = args.input

    template = get_template(template)

    # For now, only one database provided
    database = args.database
    studyid = args.studyid
    experiments = args.experiments
    branch = "-b %s" % os.environ.get("EXPFACTORY_BRANCH", "master")

    headless = "false"
    if args.headless is True:
        headless = "true"

    template = sub_template(template, "{{studyid}}", studyid)
    template = sub_template(template, "{{database}}", database)
    template = sub_template(template, "{{headless}}", headless)
    template = sub_template(template, "{{branch}}", branch)

    if args.headless is True:
        bot.info(
            "Headless build detected, you will need to generate tokens for application entry with expfactory users --new"
        )

    library = get_library(key="name")

    apps = "\n"

    # Add local experiments to library, first preference
    local_installs = 0
    for experiment in experiments:
        if os.path.exists(experiment):

            bot.info("local experiment %s found, validating..." % experiment)

            # Is the experiment valid?
            cli = ExperimentValidator()
            valid = cli.validate(experiment, cleanup=False)

            if valid is True:
                local_installs += 1
                config = load_experiment(experiment)
                exp_id = config["exp_id"]

                # If we aren't building in the experiment directory, we need to copy there
                output_dir = "%s/%s" % (
                    os.path.abspath(os.path.dirname(args.output)),
                    exp_id,
                )
                experiment_dir = os.path.abspath(experiment)
                if output_dir != experiment_dir:
                    copy_directory(experiment_dir, output_dir)

                config["local"] = os.path.abspath(experiment)
                library[exp_id] = config

    # Warn the user that local installs are not reproducible (from recipe)
    if local_installs > 0:
        bot.warning(
            "%s local installs detected: build is not reproducible without experiment folders"
            % local_installs
        )

    # Build Image with Experiments
    for experiment in experiments:
        exp_id = os.path.basename(experiment)
        if exp_id in library:
            config = library[exp_id]

            app = "LABEL EXPERIMENT_%s /scif/apps/%s\n" % (exp_id, exp_id)

            # Here add custom build routine, should be list of lines
            if "install" in config:
                commands = "\n".join(["RUN %s " % s for x in config["install"]]).strip(
                    "\n"
                )
                app = "%s%s\n" % (app, commands)

            # The final installation step, either from Github (url) or local folder
            if "local" in config:
                app = "%sADD %s /scif/apps/%s\n" % (app, exp_id, exp_id)
                app = "%sWORKDIR /scif/apps\nRUN expfactory install %s\n" % (
                    app,
                    exp_id,
                )
            else:
                app = "%sWORKDIR /scif/apps\nRUN expfactory install %s\n" % (
                    app,
                    config["github"],
                )
            apps = "%s%s\n" % (apps, app)

        else:
            bot.warning("%s not in library, check spelling & punctuation." % exp_id)

    if apps == "\n":
        bot.error("No valid experiments found, cancelling recipe build.")
        sys.exit(1)

    template = sub_template(template, "{{experiments}}", apps)
    outfile = write_file(args.output, template)
    bot.log("Recipe written to %s" % outfile)
Ejemplo n.º 19
0
    def setUp(self):

        self.ExpValidator = ExperimentValidator()
        self.base = "/scif/apps"
        self.experiments = glob("%s/*" %self.base)
        self.contenders = [os.path.basename(x) for x in self.experiments]
Ejemplo n.º 20
0
def main(args,parser,subparser):

    template = 'build/docker/Dockerfile.template'

    # Full path to template is required if provided via input
    if args.input is not None:
        template = args.input

    template = get_template(template)
    
    # For now, only one database provided
    database = args.database
    studyid = args.studyid
    experiments = args.experiments
    branch = "-b %s" %os.environ.get('EXPFACTORY_BRANCH','master')

    headless = "false"
    if args.headless is True:
        headless = "true"

    template = sub_template(template,"{{studyid}}",studyid)
    template = sub_template(template,"{{database}}",database)
    template = sub_template(template,"{{headless}}",headless)
    template = sub_template(template,"{{branch}}",branch)

    if args.headless is True:
        bot.info("Headless build detected, you will need to generate tokens for application entry with expfactory users --new")

    library = get_library(key='name')

    apps = "\n"

    # Add local experiments to library, first preference
    local_installs = 0
    for experiment in experiments:
        if os.path.exists(experiment):

            bot.info('local experiment %s found, validating...' %experiment)

            # Is the experiment valid?
            cli = ExperimentValidator()
            valid = cli.validate(experiment, cleanup=False)

            if valid is True:
                local_installs +=1
                config = load_experiment(experiment)
                exp_id = config['exp_id']

                # If we aren't building in the experiment directory, we need to copy there
                output_dir = "%s/%s" %(os.path.abspath(os.path.dirname(args.output)), exp_id)
                experiment_dir = os.path.abspath(experiment)
                if output_dir != experiment_dir:
                    copy_directory(experiment_dir, output_dir)

                config['local'] = os.path.abspath(experiment)
                library[exp_id] = config


    # Warn the user that local installs are not reproducible (from recipe)
    if local_installs > 0:
        bot.warning("%s local installs detected: build is not reproducible without experiment folders" %local_installs)

    # Build Image with Experiments
    for experiment in experiments:
        exp_id = os.path.basename(experiment)
        if exp_id in library:
            config = library[exp_id]

            app = "LABEL EXPERIMENT_%s /scif/apps/%s\n" %(exp_id, exp_id)

            # Here add custom build routine, should be list of lines
            if "install" in config:
                commands = "\n".join(["RUN %s "%s for x in config['install']]).strip('\n')
                app = "%s%s\n" %(app, commands)

            # The final installation step, either from Github (url) or local folder
            if "local" in config:
                app = "%sADD %s /scif/apps/%s\n" %(app, exp_id, exp_id)
                app = "%sWORKDIR /scif/apps\nRUN expfactory install %s\n" %(app, exp_id)
            else:
                app = "%sWORKDIR /scif/apps\nRUN expfactory install %s\n" %(app, config['github'])  
            apps = "%s%s\n" %(apps,app)


        else:
            bot.warning('%s not in library, check spelling & punctuation.' %exp_id)

    if apps == "\n":
        bot.error('No valid experiments found, cancelling recipe build.')
        sys.exit(1)

    template = sub_template(template,"{{experiments}}",apps)
    outfile = write_file(args.output,template)
    bot.log("Recipe written to %s" %outfile)