def history_model(test_list, options):
    """
    Test package distribution based on history.

    @type test_list: C{list}
    @param test_list: List of test packages

    @type options: C{Options}
    @param options: Testrun options in an ots.server.hub.options object
    
    @rtype: C{list}
    @return: List of conductor_commands 

    """

    commands = []
    
    req_options = REQUEST_OPTIONS
    
    max_runtime = int(req_options.get("target_execution_time", DEFAULT_RUNTIME))
    max_groups = int(req_options.get("max_worker_amount", DEFAULT_GROUPS))
    
    if not test_list:
        raise ValueError("test_list not defined for distribution model")

    if 'device' in test_list:
        test_packages = test_list['device'].split(",")
        test_history = get_test_package_history(test_packages)
        LOG.debug(test_history)
        package_groups = group_packages(test_history, max_runtime, max_groups)
        LOG.debug(package_groups)
        for group in package_groups:
            options['test_packages'] = string.join(group, ",")
            cmd = conductor_command(options, 
                                    host_testing = False,
                                    chroot_testing = False)
            commands.append(Task(cmd))
        
        # Rest groups are for host based packages
        max_groups = max_groups - len(package_groups)

    # If we have host based packages
    # Lets use rest of the groups for them
    if 'host' in test_list:
        test_packages = test_list['host'].split(",")
        test_history = get_test_package_history(test_packages)
        LOG.debug(test_history)
        if max_groups <= 0:
            max_groups = 1
        LOG.debug(max_groups)
        package_groups = group_packages(test_history, max_runtime, max_groups)
        LOG.debug(package_groups)
        for group in package_groups:
            options['test_packages'] = string.join(group, ",")
            cmd = conductor_command(options, 
                                    host_testing = True,
                                    chroot_testing = False)
            commands.append(Task(cmd))

    return commands
def perpackage_distribution(test_list, options):
    """Creates a separate task (conductor command) for each test package"""

    commands = []

    if not test_list:
        raise ValueError("test_list not defined for distribution model")

    if 'device' in test_list:
        for test_package in test_list['device'].split(","):
            options['test_packages'] = test_package
            cmd = conductor_command(options,
                                    host_testing = False,
                                    chroot_testing = False)
            commands.append(Task(cmd))

    if 'host' in test_list:
        for test_package in test_list['host'].split(","):
            options['test_packages'] = test_package
            cmd = conductor_command(options,
                                    host_testing = True,
                                    chroot_testing = False)
            commands.append(Task(cmd))
    
    if 'hw_testplans' in test_list:
        test_plans = test_list.get("hw_testplans")
        options['test_packages'] = ""
        for test_plan in test_plans:
            options['testplan_name'] = test_plan.name
            cmd = conductor_command(options,
                                    host_testing = False,
                                    chroot_testing = False)
            task = Task(cmd)
            task.set_test_plan(test_plan)
            commands.append(task)
        
    if 'host_testplans' in test_list:
        test_plans = test_list.get("host_testplans")
        options['test_packages'] = ""
        for test_plan in test_plans:
            options['testplan_name'] = test_plan.name
            cmd = conductor_command(options,
                                    host_testing = True,
                                    chroot_testing = False)
            task = Task(cmd)
            task.set_test_plan(test_plan)
            commands.append(task)

    if 'chroot' in test_list:
        for test_package in test_list['chroot'].split(","):
            options['test_packages'] = test_package
            cmd = conductor_command(options,
                                    host_testing = False,
                                    chroot_testing = True)
            commands.append(Task(cmd))

    return commands
    def test_conductor_command_without_testpackages(self):
        options = {'image_url':"www.nokia.com", 
                   'testrun_id':1, 'storage_address':"foo", 'testfilter':"", 
                   'flasherurl':"", 'test_packages':"", 'timeout':"30",
                   'use_libssh2': False, 'resume': False}
        expected = ['conductor',  
                    "-u", 'www.nokia.com', '-i', '1', '-c', 'foo', '-m', '30']

        result = conductor_command(options,
                                   host_testing = False,
                                   chroot_testing = False)
        self.assertEquals(expected, result) 
    def test_conductor_command_with_flasher_bootmode_set(self):
        options = {'image_url':"www.nokia.com", 'flasher_options':"bootmode:normal",
                   'testrun_id':1, 'storage_address':"foo", 'testfilter':"",
                   'flasherurl':"asdfasdf/asdf", 'test_packages':"my-tests",
                   'timeout':"30", 'use_libssh2': False,
                   'resume': False}
        expected = ['conductor',
                    "-u", 'www.nokia.com',
                    '-i', '1',
                    '-c', 'foo',
                    '--flasherurl', "asdfasdf/asdf",
                    "-t", "my-tests", '-m', '30', '--flasher_options=bootmode:normal']

        result = conductor_command(options,
                                   host_testing = False,
                                   chroot_testing = False)
        self.assertEquals(result, expected)
    def test_conductor_command_with_resume(self):
        options = {'image_url':"www.nokia.com", 'testrun_id':1,
                   'storage_address':"foo", 'testfilter':"",
                   'flasherurl':"asdfasdf/asdf",
                   'use_libssh2': False, 'resume': True,
                   'timeout':"30", 'test_packages':''}
        expected = ['conductor',
                    '-u', 'www.nokia.com',
                    '-i', '1',
                    '-c', 'foo',
                    '--flasherurl', "asdfasdf/asdf",
                    '-m', '30', '--resume', '-o']

        result = conductor_command(options,
                                   host_testing=True,
                                   chroot_testing=False)
        self.assertEquals(result, expected)
def single_task_distribution(test_list, options):
    """Creates a single task (one command line) for all test packages"""

    single_cmd = []
    tasks = []

    if not test_list:
        options['test_packages'] = ""
        cmd = conductor_command(options,
                                host_testing = False,
                                chroot_testing = False)
        single_cmd.extend(cmd)

    if 'device' in test_list:
        options['test_packages'] = test_list['device']
        cmd = conductor_command(options,
                                host_testing = False,
                                chroot_testing = False)
        single_cmd.extend(cmd)

    if 'host' in test_list:
        options['test_packages'] = test_list['host']
        cmd = conductor_command(options,
                                host_testing = True,
                                chroot_testing = False)
        # If there are device tests, have a ; to do them both.
        # Note: This means they're run under one timeout, in one shell.
        #       Coming improvements in task distribution could soon
        #       facilitate in improving this too.
        if single_cmd:
            single_cmd.append(';')
        single_cmd.extend(cmd)
        
    if 'chroot' in test_list:
        options['test_packages'] = test_list['chroot']
        cmd = conductor_command(options,
                                host_testing = False,
                                chroot_testing = True)

        if single_cmd:
            single_cmd.append(';')
        single_cmd.extend(cmd)
    
    if len(single_cmd) > 0:
        tasks.append(Task(single_cmd))
    
    # For test plan based executions
    # hw and host are in own tasks.
    # Test plan merging is not working.
    if 'hw_testplans' in test_list:
        test_plans = test_list.get("hw_testplans")
        options['test_packages'] = ""
        for test_plan in test_plans:
            options['testplan_name'] = test_plan.name
            cmd = conductor_command(options,
                                    host_testing = False,
                                    chroot_testing = False)
            task = Task(cmd)
            task.set_test_plan(test_plan)
            tasks.append(task)
        
    if 'host_testplans' in test_list:
        test_plans = test_list.get("host_testplans")
        options['test_packages'] = ""
        for test_plan in test_plans:
            options['testplan_name'] = test_plan.name
            cmd = conductor_command(options,
                                    host_testing = True,
                                    chroot_testing = False)
            task = Task(cmd)
            task.set_test_plan(test_plan)
            tasks.append(task)

    return tasks