Exemplo n.º 1
0
def degradation_in_minor(minor_version, quiet=False):
    """Checks for degradation according to the profiles stored for the given minor version.

    :param str minor_version: representation of head point of degradation checking
    :param bool quiet: if set to true then nothing will be printed
    :returns: list of found changes
    """
    minor_version_info = vcs.get_minor_version_info(minor_version)
    baseline_version_queue = minor_version_info.parents
    pre_collect_profiles(minor_version_info)
    target_profile_queue = profiles_to_queue(minor_version)
    detected_changes = []
    while target_profile_queue and baseline_version_queue:
        # Pop the nearest baseline
        baseline = baseline_version_queue.pop(0)

        # Enqueue the parents in BFS manner
        baseline_info = vcs.get_minor_version_info(baseline)
        baseline_version_queue.extend(baseline_info.parents)

        # Precollect profiles if this is set
        pre_collect_profiles(baseline_info)

        # Print header if there is at least some profile to check against
        baseline_profiles = profiles_to_queue(baseline)

        # Iterate through the profiles and check degradation between those of same configuration
        for baseline_config, baseline_profile in baseline_profiles.items():
            target_profile = target_profile_queue.get(baseline_config)
            cmdstr = profiles.config_tuple_to_cmdstr(baseline_config)
            if target_profile:
                # Print information about configuration
                # and extend the list of the detected changes including the configuration
                # and source minor version.
                detected_changes.extend([
                    (deg, cmdstr, baseline_info.checksum)
                    for deg in degradation_between_profiles(
                        baseline_profile, target_profile)
                    if deg.result != PerformanceChange.NoChange
                ])
                del target_profile_queue[target_profile.config_tuple]

        # Store the detected degradation
        store.save_degradation_list_for(pcs.get_object_directory(),
                                        minor_version, detected_changes)
    if not quiet:
        log.print_list_of_degradations(detected_changes)
    return detected_changes
Exemplo n.º 2
0
def test_collect_trace_fail(monkeypatch, helpers, pcs_full, trace_collect_job):
    """Test failed collecting using trace collector"""
    global _mocked_stap_code
    global _mocked_stap_file
    head = vcs.get_minor_version_info(vcs.get_minor_head())

    monkeypatch.setattr(stap, 'systemtap_collect', _mocked_stap)

    before_object_count = helpers.count_contents_on_path(
        pcs_full.get_path())[0]

    # Test malformed file that ends in unexpected way
    _mocked_stap_file = 'record_malformed.txt'
    cmd, args, work, collectors, posts, config = trace_collect_job
    runner.run_single_job(cmd, args, work, collectors, posts, [head], **config)

    # Assert that nothing was added
    after_object_count = helpers.count_contents_on_path(pcs_full.get_path())[0]
    assert before_object_count == after_object_count

    # Test malformed file that ends in another unexpected way
    _mocked_stap_file = 'record_malformed2.txt'
    runner.run_single_job(cmd, args, work, collectors, posts, [head], **config)

    # Assert that nothing was added
    after_object_count = helpers.count_contents_on_path(pcs_full.get_path())[0]
    assert before_object_count == after_object_count

    # Simulate the failure of the systemTap
    _mocked_stap_code = 1
    runner.run_single_job(cmd, args, work, collectors, posts, [head], **config)

    # Assert that nothing was added
    after_object_count = helpers.count_contents_on_path(pcs_full.get_path())[0]
    assert before_object_count == after_object_count
Exemplo n.º 3
0
def test_collect_memory(capsys, helpers, pcs_full, memory_collect_job,
                        memory_collect_no_debug_job):
    """Test collecting the profile using the memory collector"""
    # Fixme: Add check that the profile was correctly generated
    before_object_count = helpers.count_contents_on_path(
        pcs_full.get_path())[0]
    head = vcs.get_minor_version_info(vcs.get_minor_head())
    memory_collect_job += ([head], )

    runner.run_single_job(*memory_collect_job)

    # Assert that nothing was removed
    after_object_count = helpers.count_contents_on_path(pcs_full.get_path())[0]
    assert before_object_count + 1 == after_object_count

    profiles = os.listdir(os.path.join(pcs_full.get_path(), 'jobs'))
    new_profile = profiles[0]
    assert len(profiles) == 1
    assert new_profile.endswith(".perf")

    cmd, args, _, colls, posts, _ = memory_collect_job
    runner.run_single_job(cmd, args, ["hello"], colls, posts, [head], **{
        'no_func': 'fun',
        'sampling': 0.1
    })

    profiles = os.listdir(os.path.join(pcs_full.get_path(), 'jobs'))
    new_smaller_profile = [p for p in profiles if p != new_profile][0]
    assert len(profiles) == 2
    assert new_smaller_profile.endswith(".perf")

    # Assert that nothing was removed
    after_second_object_count = helpers.count_contents_on_path(
        pcs_full.get_path())[0]
    assert after_object_count + 1 == after_second_object_count

    # Fixme: Add check that the profile was correctly generated

    memory_collect_no_debug_job += ([head], )
    runner.run_single_job(*memory_collect_no_debug_job)
    last_object_count = helpers.count_contents_on_path(pcs_full.get_path())[0]
    _, err = capsys.readouterr()
    assert after_second_object_count == last_object_count
    assert 'debug info' in err

    target_bin = memory_collect_job[0][0]
    collector_unit = Unit('memory', {'all': False, 'no_func': 'main'})
    job = Job('memory', [], str(target_bin), '', '')
    _, prof = runner.run_collector(collector_unit, job)

    assert len(list(query.all_resources_of(prof))) == 2

    collector_unit = Unit('memory', {
        'all': False,
        'no_source': 'memory_collect_test.c'
    })
    job = Job('memory', [], str(target_bin), '', '')
    _, prof = runner.run_collector(collector_unit, job)

    assert len(list(query.all_resources_of(prof))) == 0
Exemplo n.º 4
0
def test_collect_time(monkeypatch, helpers, pcs_full, capsys):
    """Test collecting the profile using the time collector"""
    # Count the state before running the single job
    before_object_count = helpers.count_contents_on_path(
        pcs_full.get_path())[0]
    head = vcs.get_minor_version_info(vcs.get_minor_head())

    runner.run_single_job(["echo"], "", ["hello"], ["time"], [], [head])

    # Assert outputs
    out, err = capsys.readouterr()
    assert err == ''
    assert 'Successfully collected data from echo' in out

    # Assert that just one profile was created
    after_object_count = helpers.count_contents_on_path(pcs_full.get_path())[0]
    assert before_object_count + 1 == after_object_count

    profiles = os.listdir(os.path.join(pcs_full.get_path(), 'jobs'))
    new_profile = profiles[0]
    assert len(profiles) == 1
    assert new_profile.endswith(".perf")

    # Test running time with error
    runner.run_single_job(["echo"], "", ["hello"], ["time"], [], [head])

    def collect_raising_exception(**kwargs):
        raise Exception("Something happened lol!")

    monkeypatch.setattr("perun.collect.time.run.collect",
                        collect_raising_exception)
    runner.run_single_job(["echo"], "", ["hello"], ["time"], [], [head])
    _, err = capsys.readouterr()
    assert 'Something happened lol!' in err
Exemplo n.º 5
0
def get_single_minor_version_info(vcs_type, vcs_path, minor_version_sha):
    """Function for loading minor version information
    :param str vcs_type: type of the version control system
    :param str vcs_path: path to the repository
    :param str minor_version_sha: minor version SHA
    :return: dictionary with minor version data
    """
    try:
        minor_version = vcs.get_minor_version_info(vcs_type, vcs_path, minor_version_sha)
        return jsonify({'commit': formatter.format_single_minor_version_info(minor_version, '')})
    
    except Exception as e:
        eprint(e)
        return create_response(e, 404)
Exemplo n.º 6
0
def status(short=False, **_):
    """Prints the status of performance control system

    :param bool short: true if the output should be short (i.e. without some information)
    """
    # Obtain both of the heads
    major_head = vcs.get_head_major_version()
    minor_head = vcs.get_minor_head()

    # Print the status of major head.
    print("On major version {} ".format(
        termcolor.colored(major_head, TEXT_EMPH_COLOUR, attrs=TEXT_ATTRS)),
          end='')

    # Print the index of the current head
    print("(minor version: {})".format(
        termcolor.colored(minor_head, TEXT_EMPH_COLOUR, attrs=TEXT_ATTRS)))

    # Print in long format, the additional information about head commit, by default print
    if not short:
        print("")
        minor_version = vcs.get_minor_version_info(minor_head)
        print_minor_version_info(minor_version)

    # Print profiles
    minor_version_profiles = profile.load_list_for_minor_version(minor_head)
    untracked_profiles = get_untracked_profiles()
    maxs = calculate_maximal_lengths_for_object_list(
        minor_version_profiles + untracked_profiles,
        profile.ProfileInfo.valid_attributes)
    print_profile_info_list(minor_version_profiles, maxs, short)
    if not short:
        print("")
    print_profile_info_list(untracked_profiles, maxs, short, 'untracked')

    # Print degradation info
    degradation_list = store.load_degradation_list_for(
        pcs.get_object_directory(), minor_head)
    if not short:
        print("")
    perun_log.print_short_summary_of_degradations(degradation_list)
    if not short:
        print("")
        perun_log.print_list_of_degradations(degradation_list)
Exemplo n.º 7
0
def minor_version_list_callback(ctx, _, value):
    """Callback function for parsing the minor version list for running the automation

    :param Context ctx: context of the called command
    :param click.Option _: parameter that is being parsed and read from commandline
    :param str value: value that is being read from the commandline
    :returns list: list of MinorVersion objects
    """
    minors = []
    if value:
        for minor_version in value:
            massaged_version = vcs.massage_parameter(minor_version)
            # If we should crawl all of the parents, we collect them
            if ctx.params.get('crawl_parents', False):
                minors.extend(vcs.walk_minor_versions(massaged_version))
            # Otherwise we retrieve the minor version info for the param
            else:
                minors.append(vcs.get_minor_version_info(massaged_version))
    return minors
Exemplo n.º 8
0
def collect_profile_using_job_matrix(vcs_type, repo_path, minor_version):
    """Function for collecting new profiles using predefined job matrix from local.yml
    :param str path_to_repo: path to repository
    :param str minor_version: commmit on which the collection is to be performed
    :return: list of performance profiles belonging to the specidied minor version
    """
    try:
        original_path = os.getcwd()
        os.chdir(repo_path)
        minor_version_obj = vcs.get_minor_version_info(vcs_type, repo_path, minor_version)
        runner.run_matrix_job([minor_version_obj])
        objs, output, jsn = get_single_minor_version_profiles(minor_version, '', repo_path)
        os.chdir(original_path)
        return jsonify({'profiles': output})
    
    except Exception as e:
        os.chdir(original_path)
        eprint(e)
        return create_response(e, 404)
Exemplo n.º 9
0
def test_collect_trace(monkeypatch, helpers, pcs_full, trace_collect_job):
    """Test collecting the profile using trace collector"""
    head = vcs.get_minor_version_info(vcs.get_minor_head())
    monkeypatch.setattr(stap, 'systemtap_collect', _mocked_stap)

    before_object_count = helpers.count_contents_on_path(
        pcs_full.get_path())[0]

    cmd, args, work, collectors, posts, config = trace_collect_job
    config['collector_params']['trace']['binary'] = os.path.join(
        os.path.dirname(__file__), 'collect_trace', 'tst')
    runner.run_single_job(cmd, args, work, collectors, posts, [head], **config)

    # Assert that nothing was removed
    after_object_count = helpers.count_contents_on_path(pcs_full.get_path())[0]
    assert before_object_count + 1 == after_object_count
    profiles = os.listdir(os.path.join(pcs_full.get_path(), 'jobs'))

    new_profile = profiles[0]
    assert len(profiles) == 1
    assert new_profile.endswith(".perf")
Exemplo n.º 10
0
def test_major_versions(pcs_full):
    """Test whether getting the major version for given VCS is correct

    Expecting correct behaviour and no error
    """
    major_versions = list(vcs.walk_major_versions())

    assert len(major_versions) == 1
    major_version = major_versions[0]
    assert major_version.name == 'master'
    assert store.is_sha1(major_version.head)

    head_major = vcs.get_head_major_version()
    assert not store.is_sha1(str(head_major))
    assert str(head_major) == 'master'

    prev_commit = vcs.get_minor_version_info(vcs.get_minor_head()).parents[0]
    git_repo = git.Repo(pcs_full.get_vcs_path())
    git_repo.git.checkout(prev_commit)
    # Try to detach head
    head_major = vcs.get_head_major_version()
    assert store.is_sha1(head_major)
Exemplo n.º 11
0
def status(pcs, short=False):
    """Prints the status of performance control system

    Arguments:
        pcs(PCS): performance control system
        short(bool): true if the output should be short (i.e. without some information)
    """
    # Obtain both of the heads
    major_head = vcs.get_head_major_version(pcs.vcs_type, pcs.vcs_path)
    minor_head = vcs.get_minor_head(pcs.vcs_type, pcs.vcs_path)

    # Print the status of major head.
    print("On major version {} ".format(
        termcolor.colored(major_head, TEXT_EMPH_COLOUR, attrs=TEXT_ATTRS)),
          end='')

    # Print the index of the current head
    print("(minor version: {})".format(
        termcolor.colored(minor_head, TEXT_EMPH_COLOUR, attrs=TEXT_ATTRS)))

    # Print in long format, the additional information about head commit, by default print
    if not short:
        print("")
        minor_version = vcs.get_minor_version_info(pcs.vcs_type, pcs.vcs_path,
                                                   minor_head)
        print_minor_version_info(minor_version)

    # Print profiles
    minor_version_profiles = get_minor_version_profiles(pcs, minor_head)
    untracked_profiles = get_untracked_profiles(pcs)
    maxs = calculate_maximal_lenghts_for_profile_infos(minor_version_profiles +
                                                       untracked_profiles)
    print_profile_info_list(pcs, minor_version_profiles, maxs, short)
    if not short:
        print("")
    print_profile_info_list(pcs, untracked_profiles, maxs, short, 'untracked')