tasks/test.py
def test(
    ctx,
    module=None,
    targets=None,
    coverage=False,
    build_include=None,
    build_exclude=None,
    verbose=False,
    race=False,
    profile=False,
    fail_on_fmt=False,
    rtloader_root=None,
    python_home_2=None,
    python_home_3=None,
    cpus=0,
    major_version='7',
    python_runtimes='3',
    timeout=180,
    arch="x64",
    cache=True,
    skip_linters=False,
    save_result_json=None,
    rerun_fails=None,
    go_mod="mod",
    junit_tar="",
):
    """
    Run all the tools and tests on the given module and targets.

    A module should be provided as the path to one of the go modules in the repository.

    Targets should be provided as a comma-separated list of relative paths within the given module.
    If targets are provided but no module is set, the main module (".") is used.

    If no module or target is set the tests are run against all modules and targets.

    Example invokation:
        inv test --targets=./pkg/collector/check,./pkg/aggregator --race
        inv test --module=. --race
    """
    if isinstance(module, str):
        # when this function is called from the command line, targets are passed
        # as comma separated tokens in a string
        if isinstance(targets, str):
            modules = [GoModule(module, targets=targets.split(','))]
        else:
            modules = [m for m in DEFAULT_MODULES.values() if m.path == module]
    elif isinstance(targets, str):
        modules = [GoModule(".", targets=targets.split(','))]
    else:
        print("Using default modules and targets")
        modules = DEFAULT_MODULES.values()

    build_include = (
        get_default_build_tags(build="test-with-process-tags", arch=arch)
        if build_include is None
        else filter_incompatible_tags(build_include.split(","), arch=arch)
    )
    build_exclude = [] if build_exclude is None else build_exclude.split(",")
    build_tags = get_build_tags(build_include, build_exclude)

    timeout = int(timeout)

    # explicitly run these tasks instead of using pre-tasks so we can
    # pass the `target` param (pre-tasks are invoked without parameters)
    print("--- go generating:")
    generate(ctx)

    if skip_linters:
        print("--- [skipping Go linters]")
    else:
        # Until all packages whitelisted in .golangci.yml are fixed and removed
        # from the 'skip-dirs' list we need to keep using the old functions that
        # lint without build flags (linting some file is better than no linting).
        print("--- Vetting and linting (legacy):")
        for module in modules:
            print(f"----- Module '{module.full_path()}'")
            if not module.condition():
                print("----- Skipped")
                continue

            with ctx.cd(module.full_path()):
                vet(ctx, targets=module.targets, rtloader_root=rtloader_root, build_tags=build_tags, arch=arch)
                fmt(ctx, targets=module.targets, fail_on_fmt=fail_on_fmt)
                lint(ctx, targets=module.targets)
                misspell(ctx, targets=module.targets)
                ineffassign(ctx, targets=module.targets)
                staticcheck(ctx, targets=module.targets, build_tags=build_tags, arch=arch)

        # for now we only run golangci_lint on Unix as the Windows env need more work
        if sys.platform != 'win32':
            print("--- golangci_lint:")
            for module in modules:
                print(f"----- Module '{module.full_path()}'")
                if not module.condition():
                    print("----- Skipped")
                    continue

                with ctx.cd(module.full_path()):
                    golangci_lint(
                        ctx, targets=module.targets, rtloader_root=rtloader_root, build_tags=build_tags, arch=arch
                    )

    with open(PROFILE_COV, "w") as f_cov:
        f_cov.write("mode: count")

    ldflags, gcflags, env = get_build_flags(
        ctx,
        rtloader_root=rtloader_root,
        python_home_2=python_home_2,
        python_home_3=python_home_3,
        major_version=major_version,
        python_runtimes=python_runtimes,
    )

    if sys.platform == 'win32':
        env['CGO_LDFLAGS'] += ' -Wl,--allow-multiple-definition'

    if profile:
        test_profiler = TestProfiler()
    else:
        test_profiler = None  # Use stdout

    race_opt = ""
    covermode_opt = ""
    build_cpus_opt = ""
    if cpus:
        build_cpus_opt = f"-p {cpus}"
    if race:
        # race doesn't appear to be supported on non-x64 platforms
        if arch == "x86":
            print("\n -- Warning... disabling race test, not supported on this platform --\n")
        else:
            race_opt = "-race"

        # Needed to fix an issue when using -race + gcc 10.x on Windows
        # https://github.com/bazelbuild/rules_go/issues/2614
        if sys.platform == 'win32':
            ldflags += " -linkmode=external"

    if coverage:
        if race:
            # atomic is quite expensive but it's the only way to run
            # both the coverage and the race detector at the same time
            # without getting false positives from the cover counter
            covermode_opt = "-covermode=atomic"
        else:
            covermode_opt = "-covermode=count"

    print("\n--- Running unit tests:")

    coverprofile = ""
    if coverage:
        coverprofile = f"-coverprofile={PROFILE_COV}"

    nocache = '-count=1' if not cache else ''

    build_tags.append("test")
    TMP_JSON = 'tmp.json'
    if save_result_json and os.path.isfile(save_result_json):
        # Remove existing file since we append to it.
        # We don't need to do that for TMP_JSON since gotestsum overwrites the output.
        print(f"Removing existing '{save_result_json}' file")
        os.remove(save_result_json)

    junit_file_flag = ""
    junit_file = "junit-out.xml"
    if junit_tar:
        junit_file_flag = "--junitfile " + junit_file

    cmd = 'gotestsum {junit_file_flag} {json_flag} --format pkgname {rerun_fails} --packages="{packages}" -- {verbose} -mod={go_mod} -vet=off -timeout {timeout}s -tags "{go_build_tags}" -gcflags="{gcflags}" '
    cmd += '-ldflags="{ldflags}" {build_cpus} {race_opt} -short {covermode_opt} {coverprofile} {nocache}'
    args = {
        "go_mod": go_mod,
        "go_build_tags": " ".join(build_tags),
        "gcflags": gcflags,
        "ldflags": ldflags,
        "race_opt": race_opt,
        "build_cpus": build_cpus_opt,
        "covermode_opt": covermode_opt,
        "coverprofile": coverprofile,
        "timeout": timeout,
        "verbose": '-v' if verbose else '',
        "nocache": nocache,
        "json_flag": f'--jsonfile "{TMP_JSON}" ' if save_result_json else "",
        "rerun_fails": f"--rerun-fails={rerun_fails}" if rerun_fails else "",
        "junit_file_flag": junit_file_flag,
    }

    failed_modules = []
    junit_files = []
    for module in modules:
        print(f"----- Module '{module.full_path()}'")
        if not module.condition():
            print("----- Skipped")
            continue

        with ctx.cd(module.full_path()):
            res = ctx.run(
                cmd.format(
                    packages=' '.join(f"{t}/..." if not t.endswith("/...") else t for t in module.targets), **args
                ),
                env=env,
                out_stream=test_profiler,
                warn=True,
            )

        if res.exited is None or res.exited > 0:
            failed_modules.append(module.full_path())

        if save_result_json:
            with open(save_result_json, 'ab') as json_file, open(
                os.path.join(module.full_path(), TMP_JSON), 'rb'
            ) as module_file:
                json_file.write(module_file.read())

        junit_files.append(os.path.join(module.full_path(), junit_file))

    if junit_tar:
        produce_junit_tar(junit_files, junit_tar)

    if failed_modules:
        # Exit if any of the modules failed
        raise Exit(code=1, message=f"Unit tests failed in the following modules: {', '.join(failed_modules)}")

    if coverage:
        print("\n--- Test coverage:")
        ctx.run(f"go tool cover -func {PROFILE_COV}")

    if profile:
        print("\n--- Top 15 packages sorted by run time:")
        test_profiler.print_sorted(15)

    Run all the tools and tests on the given module and targets.

    A module should be provided as the path to one of the go modules in the repository.

    Targets should be provided as a comma-separated list of relative paths within the given module.
    If targets are provided but no module is set, the main module (".") is used.

    If no module or target is set the tests are run against all modules and targets.

    Example invokation:
        inv test --targets=./pkg/collector/check,./pkg/aggregator --race
        inv test --module=. --race
    
Run all the tools and tests on the given module and targets.
A module should be provided as the path to one of the go modules in the repository.

Targets should be provided as a comma-separated list of relative paths within the given module.
If targets are provided but no module is set, the main module (".") is used.

If no module or target is set the tests are run against all modules and targets.


Run all the tools and tests on the given module and targets . A module should be provided as the path to one of the go modules in the repository . Targets should be provided as a comma - separated list of relative paths within the given module . If targets are provided but no module is set the main module ( " . " ) is used . If no module or target is set the tests are run against all modules and targets .
def test(
    ctx,
    module=None,
    targets=None,
    coverage=False,
    build_include=None,
    build_exclude=None,
    verbose=False,
    race=False,
    profile=False,
    fail_on_fmt=False,
    rtloader_root=None,
    python_home_2=None,
    python_home_3=None,
    cpus=0,
    major_version='7',
    python_runtimes='3',
    timeout=180,
    arch="x64",
    cache=True,
    skip_linters=False,
    save_result_json=None,
    rerun_fails=None,
    go_mod="mod",
    junit_tar="",
):
    if isinstance(module, str):
        if isinstance(targets, str):
            modules = [GoModule(module, targets=targets.split(','))]
        else:
            modules = [m for m in DEFAULT_MODULES.values() if m.path == module]
    elif isinstance(targets, str):
        modules = [GoModule(".", targets=targets.split(','))]
    else:
        print("Using default modules and targets")
        modules = DEFAULT_MODULES.values()
    build_include = (
        get_default_build_tags(build="test-with-process-tags", arch=arch)
        if build_include is None
        else filter_incompatible_tags(build_include.split(","), arch=arch)
    )
    build_exclude = [] if build_exclude is None else build_exclude.split(",")
    build_tags = get_build_tags(build_include, build_exclude)
    timeout = int(timeout)
    print("--- go generating:")
    generate(ctx)
    if skip_linters:
        print("--- [skipping Go linters]")
    else:
        print("--- Vetting and linting (legacy):")
        for module in modules:
            print(f"----- Module '{module.full_path()}'")
            if not module.condition():
                print("----- Skipped")
                continue
            with ctx.cd(module.full_path()):
                vet(ctx, targets=module.targets, rtloader_root=rtloader_root, build_tags=build_tags, arch=arch)
                fmt(ctx, targets=module.targets, fail_on_fmt=fail_on_fmt)
                lint(ctx, targets=module.targets)
                misspell(ctx, targets=module.targets)
                ineffassign(ctx, targets=module.targets)
                staticcheck(ctx, targets=module.targets, build_tags=build_tags, arch=arch)
        if sys.platform != 'win32':
            print("--- golangci_lint:")
            for module in modules:
                print(f"----- Module '{module.full_path()}'")
                if not module.condition():
                    print("----- Skipped")
                    continue
                with ctx.cd(module.full_path()):
                    golangci_lint(
                        ctx, targets=module.targets, rtloader_root=rtloader_root, build_tags=build_tags, arch=arch
                    )
    with open(PROFILE_COV, "w") as f_cov:
        f_cov.write("mode: count")
    ldflags, gcflags, env = get_build_flags(
        ctx,
        rtloader_root=rtloader_root,
        python_home_2=python_home_2,
        python_home_3=python_home_3,
        major_version=major_version,
        python_runtimes=python_runtimes,
    )
    if sys.platform == 'win32':
        env['CGO_LDFLAGS'] += ' -Wl,--allow-multiple-definition'
    if profile:
        test_profiler = TestProfiler()
    else:
        test_profiler = None  
    race_opt = ""
    covermode_opt = ""
    build_cpus_opt = ""
    if cpus:
        build_cpus_opt = f"-p {cpus}"
    if race:
        if arch == "x86":
            print("\n -- Warning... disabling race test, not supported on this platform --\n")
        else:
            race_opt = "-race"
        if sys.platform == 'win32':
            ldflags += " -linkmode=external"
    if coverage:
        if race:
            covermode_opt = "-covermode=atomic"
        else:
            covermode_opt = "-covermode=count"
    print("\n--- Running unit tests:")
    coverprofile = ""
    if coverage:
        coverprofile = f"-coverprofile={PROFILE_COV}"
    nocache = '-count=1' if not cache else ''
    build_tags.append("test")
    TMP_JSON = 'tmp.json'
    if save_result_json and os.path.isfile(save_result_json):
        print(f"Removing existing '{save_result_json}' file")
        os.remove(save_result_json)
    junit_file_flag = ""
    junit_file = "junit-out.xml"
    if junit_tar:
        junit_file_flag = "--junitfile " + junit_file
    cmd = 'gotestsum {junit_file_flag} {json_flag} --format pkgname {rerun_fails} --packages="{packages}" -- {verbose} -mod={go_mod} -vet=off -timeout {timeout}s -tags "{go_build_tags}" -gcflags="{gcflags}" '
    cmd += '-ldflags="{ldflags}" {build_cpus} {race_opt} -short {covermode_opt} {coverprofile} {nocache}'
    args = {
        "go_mod": go_mod,
        "go_build_tags": " ".join(build_tags),
        "gcflags": gcflags,
        "ldflags": ldflags,
        "race_opt": race_opt,
        "build_cpus": build_cpus_opt,
        "covermode_opt": covermode_opt,
        "coverprofile": coverprofile,
        "timeout": timeout,
        "verbose": '-v' if verbose else '',
        "nocache": nocache,
        "json_flag": f'--jsonfile "{TMP_JSON}" ' if save_result_json else "",
        "rerun_fails": f"--rerun-fails={rerun_fails}" if rerun_fails else "",
        "junit_file_flag": junit_file_flag,
    }
    failed_modules = []
    junit_files = []
    for module in modules:
        print(f"----- Module '{module.full_path()}'")
        if not module.condition():
            print("----- Skipped")
            continue
        with ctx.cd(module.full_path()):
            res = ctx.run(
                cmd.format(
                    packages=' '.join(f"{t}/..." if not t.endswith("/...") else t for t in module.targets), **args
                ),
                env=env,
                out_stream=test_profiler,
                warn=True,
            )
        if res.exited is None or res.exited > 0:
            failed_modules.append(module.full_path())
        if save_result_json:
            with open(save_result_json, 'ab') as json_file, open(
                os.path.join(module.full_path(), TMP_JSON), 'rb'
            ) as module_file:
                json_file.write(module_file.read())
        junit_files.append(os.path.join(module.full_path(), junit_file))
    if junit_tar:
        produce_junit_tar(junit_files, junit_tar)
    if failed_modules:
        raise Exit(code=1, message=f"Unit tests failed in the following modules: {', '.join(failed_modules)}")
    if coverage:
        print("\n--- Test coverage:")
        ctx.run(f"go tool cover -func {PROFILE_COV}")
    if profile:
        print("\n--- Top 15 packages sorted by run time:")
        test_profiler.print_sorted(15)
def test ( ctx , module = None , targets = None , coverage = False , build_include = None , build_exclude = None , verbose = False , race = False , profile = False , fail_on_fmt = False , rtloader_root = None , python_home_2 = None , python_home_3 = None , cpus = 0 , major_version = '7' , python_runtimes = '3' , timeout = 180 , arch = "x64" , cache = True , skip_linters = False , save_result_json = None , rerun_fails = None , go_mod = "mod" , junit_tar = "" , ) : if isinstance ( module , str ) : if isinstance ( targets , str ) : modules = [ GoModule ( module , targets = targets . split ( ',' ) ) ] else : modules = [ m for m in DEFAULT_MODULES . values ( ) if m . path == module ] elif isinstance ( targets , str ) : modules = [ GoModule ( "." , targets = targets . split ( ',' ) ) ] else : print ( "Using default modules and targets" ) modules = DEFAULT_MODULES . values ( ) build_include = ( get_default_build_tags ( build = "test-with-process-tags" , arch = arch ) if build_include is None else filter_incompatible_tags ( build_include . split ( "," ) , arch = arch ) ) build_exclude = [ ] if build_exclude is None else build_exclude . split ( "," ) build_tags = get_build_tags ( build_include , build_exclude ) timeout = int ( timeout ) print ( "--- go generating:" ) generate ( ctx ) if skip_linters : print ( "--- [skipping Go linters]" ) else : print ( "--- Vetting and linting (legacy):" ) for module in modules : print ( f"----- Module '{module.full_path()}'" ) if not module . condition ( ) : print ( "----- Skipped" ) continue with ctx . cd ( module . full_path ( ) ) : vet ( ctx , targets = module . targets , rtloader_root = rtloader_root , build_tags = build_tags , arch = arch ) fmt ( ctx , targets = module . targets , fail_on_fmt = fail_on_fmt ) lint ( ctx , targets = module . targets ) misspell ( ctx , targets = module . targets ) ineffassign ( ctx , targets = module . targets ) staticcheck ( ctx , targets = module . targets , build_tags = build_tags , arch = arch ) if sys . platform != 'win32' : print ( "--- golangci_lint:" ) for module in modules : print ( f"----- Module '{module.full_path()}'" ) if not module . condition ( ) : print ( "----- Skipped" ) continue with ctx . cd ( module . full_path ( ) ) : golangci_lint ( ctx , targets = module . targets , rtloader_root = rtloader_root , build_tags = build_tags , arch = arch ) with open ( PROFILE_COV , "w" ) as f_cov : f_cov . write ( "mode: count" ) ldflags , gcflags , env = get_build_flags ( ctx , rtloader_root = rtloader_root , python_home_2 = python_home_2 , python_home_3 = python_home_3 , major_version = major_version , python_runtimes = python_runtimes , ) if sys . platform == 'win32' : env [ 'CGO_LDFLAGS' ] += ' -Wl,--allow-multiple-definition' if profile : test_profiler = TestProfiler ( ) else : test_profiler = None race_opt = "" covermode_opt = "" build_cpus_opt = "" if cpus : build_cpus_opt = f"-p {cpus}" if race : if arch == "x86" : print ( "\n -- Warning... disabling race test, not supported on this platform --\n" ) else : race_opt = "-race" if sys . platform == 'win32' : ldflags += " -linkmode=external" if coverage : if race : covermode_opt = "-covermode=atomic" else : covermode_opt = "-covermode=count" print ( "\n--- Running unit tests:" ) coverprofile = "" if coverage : coverprofile = f"-coverprofile={PROFILE_COV}" nocache = '-count=1' if not cache else '' build_tags . append ( "test" ) TMP_JSON = 'tmp.json' if save_result_json and os . path . isfile ( save_result_json ) : print ( f"Removing existing '{save_result_json}' file" ) os . remove ( save_result_json ) junit_file_flag = "" junit_file = "junit-out.xml" if junit_tar : junit_file_flag = "--junitfile " + junit_file cmd = 'gotestsum {junit_file_flag} {json_flag} --format pkgname {rerun_fails} --packages="{packages}" -- {verbose} -mod={go_mod} -vet=off -timeout {timeout}s -tags "{go_build_tags}" -gcflags="{gcflags}" ' cmd += '-ldflags="{ldflags}" {build_cpus} {race_opt} -short {covermode_opt} {coverprofile} {nocache}' args = { "go_mod" : go_mod , "go_build_tags" : " " . join ( build_tags ) , "gcflags" : gcflags , "ldflags" : ldflags , "race_opt" : race_opt , "build_cpus" : build_cpus_opt , "covermode_opt" : covermode_opt , "coverprofile" : coverprofile , "timeout" : timeout , "verbose" : '-v' if verbose else '' , "nocache" : nocache , "json_flag" : f'--jsonfile "{TMP_JSON}" ' if save_result_json else "" , "rerun_fails" : f"--rerun-fails={rerun_fails}" if rerun_fails else "" , "junit_file_flag" : junit_file_flag , } failed_modules = [ ] junit_files = [ ] for module in modules : print ( f"----- Module '{module.full_path()}'" ) if not module . condition ( ) : print ( "----- Skipped" ) continue with ctx . cd ( module . full_path ( ) ) : res = ctx . run ( cmd . format ( packages = ' ' . join ( f"{t}/..." if not t . endswith ( "/..." ) else t for t in module . targets ) , ** args ) , env = env , out_stream = test_profiler , warn = True , ) if res . exited is None or res . exited > 0 : failed_modules . append ( module . full_path ( ) ) if save_result_json : with open ( save_result_json , 'ab' ) as json_file , open ( os . path . join ( module . full_path ( ) , TMP_JSON ) , 'rb' ) as module_file : json_file . write ( module_file . read ( ) ) junit_files . append ( os . path . join ( module . full_path ( ) , junit_file ) ) if junit_tar : produce_junit_tar ( junit_files , junit_tar ) if failed_modules : raise Exit ( code = 1 , message = f"Unit tests failed in the following modules: {', '.join(failed_modules)}" ) if coverage : print ( "\n--- Test coverage:" ) ctx . run ( f"go tool cover -func {PROFILE_COV}" ) if profile : print ( "\n--- Top 15 packages sorted by run time:" ) test_profiler . print_sorted ( 15 )
Run all the tools and tests on the given module and targets.
Run all the tools and tests on the given module and targets .
"""
    Run all the tools and tests on the given module and targets.

    A module should be provided as the path to one of the go modules in the repository.

    Targets should be provided as a comma-separated list of relative paths within the given module.
    If targets are provided but no module is set, the main module (".") is used.

    If no module or target is set the tests are run against all modules and targets.

    Example invokation:
        inv test --targets=./pkg/collector/check,./pkg/aggregator --race
        inv test --module=. --race
    """ # when this function is called from the command line, targets are passed # as comma separated tokens in a string # explicitly run these tasks instead of using pre-tasks so we can # pass the `target` param (pre-tasks are invoked without parameters) # Until all packages whitelisted in .golangci.yml are fixed and removed # from the 'skip-dirs' list we need to keep using the old functions that # lint without build flags (linting some file is better than no linting). # for now we only run golangci_lint on Unix as the Windows env need more work # Use stdout # race doesn't appear to be supported on non-x64 platforms # Needed to fix an issue when using -race + gcc 10.x on Windows # https://github.com/bazelbuild/rules_go/issues/2614 # atomic is quite expensive but it's the only way to run # both the coverage and the race detector at the same time # without getting false positives from the cover counter # Remove existing file since we append to it. # We don't need to do that for TMP_JSON since gotestsum overwrites the output. # Exit if any of the modules failed
ctx
module
targets
coverage
build_include
build_exclude
verbose
race
profile
fail_on_fmt
rtloader_root
python_home_2
python_home_3
cpus
major_version
python_runtimes
timeout
arch
cache
skip_linters
save_result_json
rerun_fails
go_mod
junit_tar