Esempio n. 1
0
def add_arguments(parser: ArgumentParser) -> ArgumentParser:
    '''
    Adds new arguments to the specified ArgumentParser object.
    '''
    def __dotnet_configuration(configuration: str) -> str:
        for config in get_supported_configurations():
            is_valid = config.casefold() == configuration.casefold()
            if is_valid:
                return config
        raise ArgumentTypeError(
            'Unknown configuration: {}.'.format(configuration))

    supported_configurations = get_supported_configurations()
    parser.add_argument(
        '-c', '--configuration',
        required=False,
        default=supported_configurations[0],
        choices=supported_configurations,
        type=__dotnet_configuration,
        help=SUPPRESS,
    )

    parser.add_argument(
        '-f', '--frameworks',
        required=False,
        choices=ChannelMap.get_supported_frameworks(),
        nargs='+',
        help='''The framework to build/run for. '''
             '''The target framework must also be specified in the project '''
             '''file.''',
    )

    parser.add_argument(
        '--incremental',
        required=False,
        default='yes',
        choices=['yes', 'no'],
        type=str,
        help='''Controls whether previous packages/bin/obj folders should '''
             '''be kept or removed before the dotnet restore/build/run are '''
             '''executed (Default yes).''',
    )

    # BenchmarkDotNet
    parser.add_argument(
        '--enable-hardware-counters',
        dest='enable_pmc',
        required=False,
        default=False,
        action='store_true',
        help='''Enables the following performance metric counters: '''
             '''BranchMispredictions+CacheMisses+InstructionRetired''',
    )

    parser.add_argument(
        '--filter',
        required=False,
        nargs='+',
        help='Glob patterns to execute benchmarks that match.',
    )

    def __valid_file_path(file_path: str) -> str:
        '''Verifies that specified file path exists.'''
        file_path = path.abspath(file_path)
        if not path.isfile(file_path):
            raise ArgumentTypeError('{} does not exist.'.format(file_path))
        return file_path

    parser.add_argument(
        '--corerun',
        dest='corerun',
        required=False,
        nargs='+',
        type=__valid_file_path,
        help='Full path to CoreRun.exe (corerun on Unix)',
    )
    parser.add_argument(
        '--cli',
        dest='cli',
        required=False,
        type=__valid_file_path,
        help='Full path to dotnet.exe',
    )

    def __get_bdn_arguments(user_input: str) -> list:
        file = StringIO(user_input)
        reader = csv.reader(file, delimiter=' ')
        for args in reader:
            return args
        return []

    parser.add_argument(
        '--wasm',
        dest='wasm',
        required=False,
        default=False,
        action='store_true',
        help='Tests should be run with the wasm runtime'
    )

    parser.add_argument(
        '--bdn-arguments',
        dest='bdn_arguments',
        required=False,
        type=__get_bdn_arguments,
        help='''Command line arguments to be passed to the BenchmarkDotNet '''
             '''harness.''',
    )

    parser.add_argument(
        '--bdn-artifacts',
        dest='bdn_artifacts',
        required=False,
        type=str,
        help='''Path to artifacts directory to be passed to the BenchmarkDotNet '''
             '''harness.''',
    )

    def __valid_dir_path(file_path: str) -> str:
        '''Verifies that specified file path exists.'''
        file_path = path.abspath(file_path)
        if not path.isdir(file_path):
            raise ArgumentTypeError('{} does not exist.'.format(file_path))
        return file_path

    def __csproj_file_path(file_path: str) -> dotnet.CSharpProjFile:
        file_path = __valid_file_path(file_path)
        return dotnet.CSharpProjFile(
            file_name=file_path,
            working_directory=path.dirname(file_path)
        )

    microbenchmarks_csproj = path.join(
        get_repo_root_path(), 'src', 'benchmarks', 'micro',
        'MicroBenchmarks.csproj'
    )
    parser.add_argument(
        '--csproj',
        dest='csprojfile',
        required=False,
        type=__csproj_file_path,
        default=dotnet.CSharpProjFile(
            file_name=microbenchmarks_csproj,
            working_directory=path.dirname(microbenchmarks_csproj)
        ),
        help='''C# project file name with the benchmarks to build/run. '''
             '''The default project is the MicroBenchmarks.csproj'''
    )

    def __absolute_path(file_path: str) -> str:
        '''
        Return a normalized absolutized version of the specified file_path
        path.
        '''
        return path.abspath(file_path)

    parser.add_argument(
        '--bin-directory',
        dest='bin_directory',
        required=False,
        default=path.join(get_repo_root_path(), 'artifacts', 'bin'),
        type=__absolute_path,
        help='Root of the bin directory',
    )

    return parser
Esempio n. 2
0
def install(
        architecture: str,
        channels: list,
        versions: str,
        verbose: bool,
        install_dir: str = None) -> None:
    '''
    Downloads dotnet cli into the tools folder.
    '''
    __log_script_header("Downloading DotNet Cli")

    if not install_dir:
        install_dir = __get_directory(architecture)
    if not path.exists(install_dir):
        makedirs(install_dir)

    getLogger().info("DotNet Install Path: '%s'", install_dir)

    # Download appropriate dotnet install script
    dotnetInstallScriptExtension = '.ps1' if platform == 'win32' else '.sh'
    dotnetInstallScriptName = 'dotnet-install' + dotnetInstallScriptExtension
    url = 'https://dot.net/v1/'
    dotnetInstallScriptUrl = url + dotnetInstallScriptName

    dotnetInstallScriptPath = path.join(install_dir, dotnetInstallScriptName)

    getLogger().info('Downloading %s', dotnetInstallScriptUrl)
    urlretrieve(dotnetInstallScriptUrl, dotnetInstallScriptPath)

    if platform != 'win32':
        chmod(dotnetInstallScriptPath, S_IRWXU)

    dotnetInstallInterpreter = [
        'powershell.exe',
        '-NoProfile',
        '-ExecutionPolicy', 'Bypass',
        dotnetInstallScriptPath
    ] if platform == 'win32' else [dotnetInstallScriptPath]

    # If Version is supplied, pull down the specified version

    common_cmdline_args = dotnetInstallInterpreter + [
        '-InstallDir', install_dir,
        '-Architecture', architecture
    ]

    # Install Runtime/SDKs
    if versions:
        for version in versions:
            cmdline_args = common_cmdline_args + ['-Version', version]
            RunCommand(cmdline_args, verbose=verbose).run(
                get_repo_root_path()
            )

    # Only check channels if versions are not supplied.
    # When we supply a version, but still pull down with -Channel, we will use
    # whichever sdk is newer. So if we are trying to check an older version,
    # or if there is a new version between when we start a run and when we actually
    # run, we will be testing the "wrong" version, ie, not the version we specified.
    if (not versions) and channels:
        for channel in channels:
            cmdline_args = common_cmdline_args + ['-Channel', channel]
            RunCommand(cmdline_args, verbose=verbose).run(
                get_repo_root_path()
            )

    # Set DotNet Cli environment variables.
    environ['DOTNET_CLI_TELEMETRY_OPTOUT'] = '1'
    environ['DOTNET_MULTILEVEL_LOOKUP'] = '0'
    environ['UseSharedCompilation'] = 'false'
    environ['DOTNET_ROOT'] = install_dir

    # Add installed dotnet cli to PATH
    environ["PATH"] = install_dir + pathsep + environ["PATH"]

    # If we have copied dotnet from a different machine, it will not be executable. Fix this
    if platform != 'win32':
        chmod(path.join(install_dir, 'dotnet'), S_IRWXU)
Esempio n. 3
0
def __main(args: list) -> int:
    validate_supported_runtime()
    args = __process_arguments(args)
    verbose = not args.quiet
    setup_loggers(verbose=verbose)

    # if repository is not set, then we are doing a core-sdk in performance repo run
    # if repository is set, user needs to supply the commit_sha
    if not ((args.commit_sha is None) == (args.repository is None)):
        raise ValueError(
            'Either both commit_sha and repository should be set or neither')

    target_framework_monikers = micro_benchmarks \
        .FrameworkAction \
        .get_target_framework_monikers(args.frameworks)

    # Acquire necessary tools (dotnet, and BenchView)
    # For arm64 runs, download the x64 version so we can get the information we need, but set all variables
    # as if we were running normally. This is a workaround due to the fact that arm64 binaries cannot run
    # in the cross containers, so we are running the ci setup script in a normal ubuntu container
    architecture = 'x64' if args.architecture == 'arm64' else args.architecture

    init_tools(architecture=architecture,
               dotnet_versions=args.dotnet_versions,
               target_framework_monikers=target_framework_monikers,
               verbose=verbose)

    # dotnet --info
    dotnet.info(verbose=verbose)

    variable_format = 'set %s=%s\n' if sys.platform == 'win32' else 'export %s=%s\n'
    owner, repo = ('dotnet', 'core-sdk') if args.repository is None else (
        dotnet.get_repository(args.repository))
    config_string = ';'.join(
        args.build_configs) if sys.platform == 'win32' else '"%s"' % ';'.join(
            args.build_configs)

    is_netcoreapp_30 = False

    output = ''

    with push_dir(get_repo_root_path()):
        output = check_output(['git', 'rev-parse', 'HEAD'])

    decoded_lines = []

    for line in output.splitlines():
        decoded_lines = decoded_lines + [line.decode('utf-8')]

    decoded_output = ''.join(decoded_lines)

    perfHash = decoded_output if args.get_perf_hash else args.perf_hash

    for framework in target_framework_monikers:
        if framework.startswith('netcoreapp'):
            if framework == 'netcoreapp3.0':
                is_netcoreapp_30 = True
            target_framework_moniker = micro_benchmarks.FrameworkAction.get_target_framework_moniker(
                framework)
            dotnet_version = dotnet.get_dotnet_version(
                target_framework_moniker, args.cli)
            commit_sha = dotnet.get_dotnet_sdk(
                target_framework_moniker,
                args.cli) if args.commit_sha is None else args.commit_sha
            source_timestamp = dotnet.get_commit_date(target_framework_moniker,
                                                      commit_sha,
                                                      args.repository)

            branch = micro_benchmarks.FrameworkAction.get_branch(
                target_framework_moniker) if not args.branch else args.branch

            getLogger().info("Writing script to %s" % args.output_file)

            with open(args.output_file, 'w') as out_file:
                out_file.write(variable_format % ('PERFLAB_INLAB', '1'))
                out_file.write(variable_format %
                               ('PERFLAB_REPO', '/'.join([owner, repo])))
                out_file.write(variable_format % ('PERFLAB_BRANCH', branch))
                out_file.write(variable_format %
                               ('PERFLAB_PERFHASH', perfHash))
                out_file.write(variable_format % ('PERFLAB_HASH', commit_sha))
                out_file.write(variable_format % ('PERFLAB_QUEUE', args.queue))
                out_file.write(variable_format %
                               ('PERFLAB_BUILDNUM', args.build_number))
                out_file.write(variable_format %
                               ('PERFLAB_BUILDARCH', args.architecture))
                out_file.write(variable_format %
                               ('PERFLAB_LOCALE', args.locale))
                out_file.write(variable_format %
                               ('PERFLAB_BUILDTIMESTAMP', source_timestamp))
                out_file.write(variable_format %
                               ('PERFLAB_CONFIGS', config_string))
                out_file.write(variable_format %
                               ('DOTNET_VERSION', dotnet_version))

        else:
            with open(args.output_file, 'w') as out_file:
                out_file.write(variable_format % ('PERFLAB_INLAB', '0'))

    # On non-windows platforms, delete dotnet, so that we don't have to deal with chmoding it on the helix machines
    # This is only necessary for netcoreapp3.0
    if sys.platform != 'win32' and is_netcoreapp_30:
        dotnet.remove_dotnet(architecture)
Esempio n. 4
0
def shutdown_server(verbose: bool) -> None:
    '''
    Shuts down the dotnet server
    '''
    cmdline = ['dotnet', 'build-server', 'shutdown']
    RunCommand(cmdline, verbose=verbose).run(get_repo_root_path())
Esempio n. 5
0
 def bin_path(self) -> str:
     '''Gets the directory in which the built binaries will be placed.'''
     return path.join(get_repo_root_path(), 'bin')
Esempio n. 6
0
def install(
        architecture: str,
        channels: list,
        versions: str,
        verbose: bool,
        install_dir: str = None) -> None:
    '''
    Downloads dotnet cli into the tools folder.
    '''
    __log_script_header("Downloading DotNet Cli")

    if not install_dir:
        install_dir = __get_directory(architecture)
    if not path.exists(install_dir):
        makedirs(install_dir)

    getLogger().info("DotNet Install Path: '%s'", install_dir)

    # Download appropriate dotnet install script
    dotnetInstallScriptExtension = '.ps1' if platform == 'win32' else '.sh'
    dotnetInstallScriptName = 'dotnet-install' + dotnetInstallScriptExtension
    url = 'https://dot.net/v1/'  
    dotnetInstallScriptUrl = url + dotnetInstallScriptName

    dotnetInstallScriptPath = path.join(install_dir, dotnetInstallScriptName)

    getLogger().info('Downloading %s', dotnetInstallScriptUrl)
    count = 0
    while count < 3:
        try:
            with urlopen(dotnetInstallScriptUrl, context=ssl._create_unverified_context()) as response:
                if "html" in response.info()['Content-Type']:
                    count = count + 1
                    sleep(1) # sleep one second
                    continue
                with open(dotnetInstallScriptPath, 'wb') as outfile:
                    outfile.write(response.read())
                    break
        except Exception:
            count = count + 1
            sleep(1)
            continue

    if count == 3:
        getLogger().error("Fatal error: could not download dotnet-install script")
        raise Exception("Fatal error: could not download dotnet-install script")

    if platform != 'win32':
        chmod(dotnetInstallScriptPath, S_IRWXU)

    dotnetInstallInterpreter = [
        'powershell.exe',
        '-NoProfile',
        '-ExecutionPolicy', 'Bypass',
        dotnetInstallScriptPath
    ] if platform == 'win32' else [dotnetInstallScriptPath]

    # If Version is supplied, pull down the specified version

    common_cmdline_args = dotnetInstallInterpreter + [
        '-InstallDir', install_dir,
        '-Architecture', architecture
    ]

    # Install Runtime/SDKs
    if versions:
        for version in versions:
            cmdline_args = common_cmdline_args + ['-Version', version]
            RunCommand(cmdline_args, verbose=verbose, retry=1).run(
                get_repo_root_path()
            )

    # Only check channels if versions are not supplied.
    # When we supply a version, but still pull down with -Channel, we will use
    # whichever sdk is newer. So if we are trying to check an older version,
    # or if there is a new version between when we start a run and when we actually
    # run, we will be testing the "wrong" version, ie, not the version we specified.
    if (not versions) and channels:
        for channel in channels:
            cmdline_args = common_cmdline_args + ['-Channel', ChannelMap.get_branch(channel)]
            if ChannelMap.get_quality_from_channel(channel) is not None:
                cmdline_args += ['-Quality', ChannelMap.get_quality_from_channel(channel)]
            RunCommand(cmdline_args, verbose=verbose, retry=1).run(
                get_repo_root_path()
            )

    # Set DotNet Cli environment variables.
    environ['DOTNET_CLI_TELEMETRY_OPTOUT'] = '1'
    environ['DOTNET_MULTILEVEL_LOOKUP'] = '0'
    environ['UseSharedCompilation'] = 'false'
    environ['DOTNET_ROOT'] = install_dir

    # Add installed dotnet cli to PATH
    environ["PATH"] = install_dir + pathsep + environ["PATH"]

    # If we have copied dotnet from a different machine, then it may not be
    # marked as executable. Fix this.
    if platform != 'win32':
        chmod(path.join(install_dir, 'dotnet'), S_IRWXU)
Esempio n. 7
0
def __main(args: list) -> int:
    validate_supported_runtime()
    args = __process_arguments(args)
    verbose = not args.quiet
    setup_loggers(verbose=verbose)

    # if repository is not set, then we are doing a core-sdk in performance repo run
    # if repository is set, user needs to supply the commit_sha
    if not ((args.commit_sha is None) == (args.repository is None)):
        raise ValueError('Either both commit_sha and repository should be set or neither')

    # Acquire necessary tools (dotnet)
    # For arm64 runs, download the x64 version so we can get the information we need, but set all variables
    # as if we were running normally. This is a workaround due to the fact that arm64 binaries cannot run
    # in the cross containers, so we are running the ci setup script in a normal ubuntu container
    architecture = 'x64' if args.architecture == 'arm64' else args.architecture

    init_tools(
        architecture=architecture,
        dotnet_versions=args.dotnet_versions,
        channel=args.channel,
        verbose=verbose,
        install_dir=args.install_dir
    )

    # dotnet --info
    dotnet.info(verbose=verbose)

    # When running on internal repos, the repository comes to us incorrectly
    # (ie https://github.com/dotnet-coreclr). Replace dashes with slashes in that case.
    repo_url = None if args.repository is None else args.repository.replace('-','/')

    variable_format = 'set %s=%s\n' if sys.platform == 'win32' else 'export %s=%s\n'
    path_variable = 'set PATH=%%PATH%%;%s\n' if sys.platform == 'win32' else 'export PATH=$PATH:%s\n'
    dotnet_path = '%HELIX_CORRELATION_PAYLOAD%\dotnet' if sys.platform == 'win32' else '$HELIX_CORRELATION_PAYLOAD/dotnet'
    owner, repo = ('dotnet', 'core-sdk') if args.repository is None else (dotnet.get_repository(repo_url))
    config_string = ';'.join(args.build_configs) if sys.platform == 'win32' else '"%s"' % ';'.join(args.build_configs)

    remove_dotnet = False

    output = ''

    with push_dir(get_repo_root_path()):
        output = check_output(['git', 'rev-parse', 'HEAD'])

    decoded_lines = []

    for line in output.splitlines():
        decoded_lines = decoded_lines + [line.decode('utf-8')]

    decoded_output = ''.join(decoded_lines)

    perfHash = decoded_output if args.get_perf_hash else args.perf_hash

    remove_frameworks = ['netcoreapp3.0', 'netcoreapp5.0']

    framework = ChannelMap.get_target_framework_moniker(args.channel)
    if framework.startswith('netcoreapp'):
        if framework in remove_frameworks:
            remove_dotnet = True
        target_framework_moniker = dotnet.FrameworkAction.get_target_framework_moniker(framework)
        dotnet_version = dotnet.get_dotnet_version(target_framework_moniker, args.cli)
        commit_sha = dotnet.get_dotnet_sdk(target_framework_moniker, args.cli) if args.commit_sha is None else args.commit_sha
        source_timestamp = dotnet.get_commit_date(target_framework_moniker, commit_sha, repo_url)

        branch = ChannelMap.get_branch(args.channel) if not args.branch else args.branch

        getLogger().info("Writing script to %s" % args.output_file)

        with open(args.output_file, 'w') as out_file:
            out_file.write(variable_format % ('PERFLAB_INLAB', '1'))
            out_file.write(variable_format % ('PERFLAB_REPO', '/'.join([owner, repo])))
            out_file.write(variable_format % ('PERFLAB_BRANCH', branch))
            out_file.write(variable_format % ('PERFLAB_PERFHASH', perfHash))
            out_file.write(variable_format % ('PERFLAB_HASH', commit_sha))
            out_file.write(variable_format % ('PERFLAB_QUEUE', args.queue))
            out_file.write(variable_format % ('PERFLAB_BUILDNUM', args.build_number))
            out_file.write(variable_format % ('PERFLAB_BUILDARCH', args.architecture))
            out_file.write(variable_format % ('PERFLAB_LOCALE', args.locale))
            out_file.write(variable_format % ('PERFLAB_BUILDTIMESTAMP', source_timestamp))
            out_file.write(variable_format % ('PERFLAB_CONFIGS', config_string))
            out_file.write(variable_format % ('DOTNET_VERSION', dotnet_version))
            out_file.write(variable_format % ('PERFLAB_TARGET_FRAMEWORKS', framework))
            out_file.write(variable_format % ('DOTNET_CLI_TELEMETRY_OPTOUT', '1'))
            out_file.write(variable_format % ('DOTNET_MULTILEVEL_LOOKUP', '0'))
            out_file.write(variable_format % ('UseSharedCompilation', 'false'))
            out_file.write(variable_format % ('DOTNET_ROOT', dotnet_path))
            out_file.write(path_variable % dotnet_path)

    else:
        with open(args.output_file, 'w') as out_file:
            out_file.write(variable_format % ('PERFLAB_INLAB', '0'))
            out_file.write(variable_format % ('PERFLAB_TARGET_FRAMEWORKS', framework))
            out_file.write(path_variable % dotnet_path)

    # On non-windows platforms, delete dotnet, so that we don't have to deal with chmoding it on the helix machines
    # This is only necessary for netcoreapp3.0 and netcoreapp5.0
    if sys.platform != 'win32' and remove_dotnet:
        dotnet.remove_dotnet(architecture)
    
    # The '_Framework' is needed for specifying frameworks in proj files and for building tools later in the pipeline
    __write_pipeline_variable('_Framework', framework)
def _get_gcinfra_path() -> str:
    return os.path.join(get_repo_root_path(), "src", "benchmarks", "gc")
Esempio n. 9
0
    __log_script_header("Running .NET micro benchmarks for '{}'".format(
        framework
    ))
    # dotnet run
    BENCHMARKS_CSPROJ.run(configuration, framework, verbose, *args)


def __log_script_header(message: str):
    getLogger().info('-' * len(message))
    getLogger().info(message)
    getLogger().info('-' * len(message))


BENCHMARKS_CSPROJ = dotnet.CSharpProject(
    working_directory=path.join(
        get_repo_root_path(), 'src', 'benchmarks', 'micro'),
    csproj_file='MicroBenchmarks.csproj'
)


def __main(args: list) -> int:
    try:
        validate_supported_runtime()
        args = __process_arguments(args)

        configuration = args.configuration
        frameworks = args.frameworks
        incremental = args.incremental
        verbose = args.verbose

        setup_loggers(verbose=verbose)