예제 #1
0
def pcs_full():
    """
    Returns:
        PCS: object with performance control system, initialized with some files and stuff
    """
    # Change working dir into the temporary directory
    profiles = stored_profile_pool()
    pcs_path = tempfile.mkdtemp()
    os.chdir(pcs_path)
    commands.init_perun_at(pcs_path, False,
                           {'vcs': {
                               'url': '../',
                               'type': 'git'
                           }})

    # Construct the PCS object
    pcs_obj = pcs.PCS(pcs_path)

    # Initialize git
    vcs.init('git', pcs_path, {})

    # Populate repo with commits
    repo = git.Repo(pcs_path)

    # Create first commit
    file1 = os.path.join(pcs_path, "file1")
    store.touch_file(file1)
    repo.index.add([file1])
    root = repo.index.commit("root")

    # Create second commit
    file2 = os.path.join(pcs_path, "file2")
    store.touch_file(file2)
    repo.index.add([file2])
    current_head = repo.index.commit("second commit")

    # Populate PCS with profiles
    root_profile = Helpers.prepare_profile(pcs_obj, profiles[0], str(root))
    commands.add([root_profile], str(root))
    chead_profile1 = Helpers.prepare_profile(pcs_obj, profiles[1],
                                             str(current_head))
    chead_profile2 = Helpers.prepare_profile(pcs_obj, profiles[2],
                                             str(current_head))
    commands.add([chead_profile1, chead_profile2], str(current_head))

    # Assert that we have five blobs: 2 for commits and 3 for profiles
    pcs_object_dir = os.path.join(pcs_path, ".perun", "objects")
    number_of_perun_objects = sum(
        len(os.listdir(os.path.join(pcs_object_dir, sub)))
        for sub in os.listdir(pcs_object_dir))
    assert number_of_perun_objects == 5

    yield pcs_obj

    # clean up the directory
    shutil.rmtree(pcs_path)
예제 #2
0
def init_local_config_at(path, wrapped_vcs):
    """
    Arguments:
        path(str): path where the empty shared config will be initialized
        wrapped_vcs(dict): dictionary with wrapped vcs of type {'vcs': {'type', 'url'}}
    """
    if not path.endswith('local.yml') and not path.endswith('local.yaml'):
        path = os.path.join(path, 'local.yml')
    store.touch_file(path)

    # Create a config for user to set up
    local_config = streams.safely_load_yaml_from_stream("""
vcs:
  type: {0}
  url: {1}

## To collect profiling data from the binary using the set of collectors,
## uncomment and edit the following region:
# cmds:
#   - echo

## To add set of parameters for the profiled command/binary,
## uncomment and edit the following region:
# args:
#   - -e

## To add workloads/inputs for the profiled command/binary,
## uncomment and edit the following region:
# workloads:
#   - hello
#   - world

## To register a collector for generating profiling data,
## uncomment and edit the following region:
# collectors:
#   - name: time
## Try '$ perun collect --help' to obtain list of supported collectors!

## To register a postprocessor for generated profiling data,
## uncomment and edit the following region (!order matters!):
# postprocessors:
#   - name: normalizer
#     params: --remove-zero
#   - name: filter
## Try '$ perun postprocessby --help' to obtain list of supported collectors!
    """.format(wrapped_vcs['vcs']['type'], wrapped_vcs['vcs']['url']))

    write_config_file(local_config, path)
예제 #3
0
def test_status_no_profiles(pcs_full, capsys):
    """Test calling 'perun status', without any assigned profiles

    Expecting no error and long display of the current status of the perun, without any pending.
    """
    # First we will do a new commit, with no profiles
    git_repo = git.Repo(pcs_full.vcs_path)
    file = os.path.join(os.getcwd(), 'file3')
    store.touch_file(file)
    git_repo.index.add([file])
    git_repo.index.commit("new commit")

    commands.status()

    out = capsys.readouterr()[0].split('\n')
    assert_info(out, git_repo, [], [])
예제 #4
0
def init_shared_config_at(path):
    """Creates the new configuration at given path with sane defaults of e.g. editor, paging of
    outputs or formats for status or log commands.

    :param str path: path where the empty global config will be initialized
    """
    if not path.endswith('shared.yml') and not path.endswith('shared.yaml'):
        path = os.path.join(path, 'shared.yml')
    store.touch_file(path)

    shared_config = streams.safely_load_yaml_from_stream("""
general:
    editor: vim
    paging: only-log

format:
    status: "\u2503 %type% \u2503 %collector%  \u2503 (%time%) \u2503 %source% \u2503"
    shortlog: "%checksum:6% (%stats%) %desc% %changes%"
    output_profile_template: "%collector%-%cmd%-%args%-%workload%-%date%"
    output_show_template: "%collector%-%cmd%-%args%-%workload%-%date%"
    sort_profiles_by: time

degradation:
    apply: all
    strategies:
      - method: average_amount_threshold

generators:
    workload:
      - id: basic_strings
        type: string
        min_len: 8
        max_len: 128
        step: 8
      - id: basic_integers
        type: integer
        min_range: 100
        max_range: 10000
        step: 200
      - id: basic_files
        type: textfile
        min_lines: 10
        max_lines: 10000
        step: 1000
    """)

    write_config_to(path, shared_config)
예제 #5
0
def init_shared_config_at(path):
    """
    Arguments:
        path(str): path where the empty global config will be initialized
    """
    if not path.endswith('shared.yml') and not path.endswith('shared.yaml'):
        path = os.path.join(path, 'shared.yml')
    store.touch_file(path)

    shared_config = streams.safely_load_yaml_from_stream("""
global:
    profile_info_fmt: "\u2503 [type] \u2503 [cmd] \u2503 [workload] \u2503 [collector]  \u2503 ([time]) \u2503 [id] \u2503"
    minor_version_info_fmt: "[id:6] ([stats]) [desc]"
    editor: vim
    """)

    write_config_file(shared_config, path)
예제 #6
0
def test_status_short_no_profiles(pcs_full, capsys):
    """Test calling 'perun status --short', without any asigned profiles

    Expecting no errors and short display of status of the profiles
    """
    # First we will do a new commit, with no profiles
    git_repo = git.Repo(pcs_full.vcs_path)
    file = os.path.join(os.getcwd(), 'file3')
    store.touch_file(file)
    git_repo.index.add([file])
    git_repo.index.commit("new commit")

    commands.status(**{'short': True})

    # Assert the repo
    out = capsys.readouterr()[0].split('\n')
    assert_short_info(out, git_repo, [], [])
예제 #7
0
def init_local_config_at(path, wrapped_vcs, config_template='master'):
    """Creates the new local configuration at given path with sane defaults and helper comments
    for use in order to initialize the config matrix.

    :param str path: path where the empty shared config will be initialized
    :param dict wrapped_vcs: dictionary with wrapped vcs of type {'vcs': {'type', 'url'}}
    :param str config_template: name of the template that will be used to initialize the local
    """
    if not path.endswith('local.yml') and not path.endswith('local.yaml'):
        path = os.path.join(path, 'local.yml')
    store.touch_file(path)

    # Get configuration template
    predefined_config = templates.get_predefined_configuration(
        config_template, wrapped_vcs)

    # Create a config for user to set up
    local_config = streams.safely_load_yaml_from_stream(predefined_config)

    write_config_to(path, local_config)
예제 #8
0
def test_rm_no_profiles(helpers, pcs_full, capsys):
    """Test calling 'perun rm', when there are no profiles to be removed

    Expecting error message and nothing removed at all
    """
    before_count = helpers.count_contents_on_path(pcs_full.path)

    git_repo = git.Repo(pcs_full.vcs_path)
    file = os.path.join(os.getcwd(), 'file3')
    store.touch_file(file)
    git_repo.index.add([file])
    git_repo.index.commit("new commit")

    with pytest.raises(EntryNotFoundException):
        commands.remove(['nonexistent.perf'], None)

    out, _ = capsys.readouterr()
    assert out == ''

    # Assert that nothing was removed
    after_count = helpers.count_contents_on_path(pcs_full.path)
    assert before_count == after_count
예제 #9
0
파일: test_log.py 프로젝트: xlisci02/perun
def test_log_short(pcs_full, capsys):
    """Test calling 'perun log --short', which outputs shorter info

    Expecting no error, everything on standard output, and list of commits with number of profiles
    for each of them starting from the head.
    """
    git_repo = git.Repo(pcs_full.get_vcs_path())
    commits = list(git_repo.iter_commits())

    commands.log(None, short=True)

    out, err = capsys.readouterr()

    # Assert nothing was printed on error stream
    assert len(err) == 0
    # Assert we have one line per each commit + 1 for header
    assert len(out.split('\n')) - 1 == len(commits) + 1

    for commit in commits:
        c_binsha = binascii.hexlify(commit.binsha).decode('utf-8')[:6]
        c_short_msg = commit.message[:60]

        assert c_binsha in out
        assert c_short_msg in out

    file = os.path.join(os.getcwd(), 'file3')
    store.touch_file(file)
    git_repo.index.add([file])
    git_repo.index.commit("new commit")

    commands.log(None, short=True)

    out, err = capsys.readouterr()
    # Assert nothing was printed on error stream
    assert len(err) == 0
    # Assert we have one line per each commit + 1 for header
    assert len(out.split('\n')) - 1 == len(commits) + 2
예제 #10
0
def test_user_config():
    """ Test initialization of user configuration """
    pcs_path = os.getcwd()
    git_path = os.path.join(pcs_path, 'repo')

    # Prepare the user config with some helper data
    main_build = os.path.join(pcs_path, 'build')
    main_workload = os.path.join(pcs_path, 'workload')
    store.touch_dir(main_build)
    store.touch_dir(main_workload)
    os.symlink(spawn.find_executable('cat'), os.path.join(main_build, 'lecat'))
    store.touch_file(os.path.join(main_workload, 'file1'))

    subproject_path = os.path.join(pcs_path, 'subproject')
    sub_build = os.path.join(subproject_path, '_build')
    sub_workload = os.path.join(subproject_path, '_workload')
    bogus_workload = os.path.join(subproject_path, "werklerd")
    store.touch_dir(subproject_path)
    store.touch_dir(sub_build)
    store.touch_dir(sub_workload)
    store.touch_dir(bogus_workload)
    os.symlink(spawn.find_executable('wc'), os.path.join(sub_build, 'lewc'))
    store.touch_file(os.path.join(sub_workload, 'file2'))
    store.touch_file(os.path.join(bogus_workload, 'file3'))

    # Init perun together with git on different path
    commands.init(pcs_path,
                  configuration_template='user',
                  **{
                      'vcs_type': 'git',
                      'vcs_path': git_path,
                      'vcs_params': {
                          'bare': True
                      }
                  })

    # Assert everything was correctly created
    assert_perun_successfully_init_at(pcs_path)
    assert_git_successfully_init_at(git_path, is_bare=True)

    # Assert that the directory is bare
    assert git.Repo(git_path).bare

    with open(os.path.join(pcs_path, '.perun', 'local.yml'),
              'r') as local_config:
        contents = "".join(local_config.readlines())
        assert 'make' in contents
        assert 'collect_before_check' in contents
        assert 'time' in contents
        assert 'cmds' in contents
        assert 'lewc' in contents
        assert 'lecat' in contents
        assert 'workloads' in contents
        assert 'file1' in contents
        assert 'file2' in contents
        assert 'file3' not in contents
예제 #11
0
파일: conftest.py 프로젝트: xlisci02/perun
def pcs_with_degradations():
    """
    """
    pool_path = os.path.join(os.path.split(__file__)[0], 'degradation_profiles')
    profiles = [
        os.path.join(pool_path, 'linear_base.perf'),
        os.path.join(pool_path, 'linear_base_degradated.perf'),
        os.path.join(pool_path, 'quad_base.perf')
    ]
    # Change working dir into the temporary directory
    pcs_path = tempfile.mkdtemp()
    os.chdir(pcs_path)
    commands.init_perun_at(pcs_path, False, {'vcs': {'url': '../', 'type': 'git'}})

    # Initialize git
    vcs.init({})

    # Populate repo with commits
    repo = git.Repo(pcs_path)

    # Create first commit
    file1 = os.path.join(pcs_path, "file1")
    store.touch_file(file1)
    repo.index.add([file1])
    root = repo.index.commit("root")

    # Create second commit
    repo.git.checkout('-b', 'develop')
    file2 = os.path.join(pcs_path, "file2")
    store.touch_file(file2)
    repo.index.add([file2])
    middle_head = repo.index.commit("second commit")

    # Create third commit
    repo.git.checkout('master')
    file3 = os.path.join(pcs_path, "file3")
    store.touch_file(file3)
    repo.index.add([file3])
    repo.index.commit("parallel commit")
    repo.git.merge('--no-ff', 'develop')
    current_head = str(repo.head.commit)

    # Populate PCS with profiles
    jobs_dir = pcs.get_job_directory()
    root_profile = Helpers.prepare_profile(jobs_dir, profiles[0], str(root))
    commands.add([root_profile], str(root))
    middle_profile = Helpers.prepare_profile(jobs_dir, profiles[1], str(middle_head))
    commands.add([middle_profile], str(middle_head))
    head_profile = Helpers.prepare_profile(jobs_dir, profiles[2], str(current_head))
    commands.add([head_profile], str(current_head))

    yield pcs

    # clean up the directory
    shutil.rmtree(pcs_path)