[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[tor-commits] [Git][tpo/applications/tor-browser-bundle-testsuite][main] 2 commits: Bug 40107: Execute xpcshell tests on CI



Title: GitLab

brizental pushed to branch main at The Tor Project / Applications / tor-browser-bundle-testsuite

Commits:

  • ce7fa79b
    by Beatriz Rizental at 2026-09-16T14:32:16-03:00
    Bug 40107: Execute xpcshell tests on CI
    
  • 03eca1fb
    by Beatriz Rizental at 2026-09-16T16:09:52-03:00
    Bug 40107: Pass base-browser as a test tag for all browsers
    

8 changed files:

Changes:

  • .gitlab-ci.yml
    ... ... @@ -3,6 +3,7 @@ spec:
    3 3
         - local: '.gitlab/_inputs.yml'
    
    4 4
     ---
    
    5 5
     stages:
    
    6
    +  - test-xpcshell
    
    6 7
       - test-marionette
    
    7 8
     
    
    8 9
     default:
    
    ... ... @@ -17,7 +18,7 @@ include:
    17 18
       - local: '.gitlab/_base.yml'
    
    18 19
         inputs:
    
    19 20
           mozharness_url: $[[ inputs.mozharness_url ]]
    
    20
    -      tag: $[[ inputs.tag ]]
    
    21
    +      tags: $[[ inputs.tags ]]
    
    21 22
           android_x86_64_installer_url: $[[ inputs.android_x86_64_installer_url ]]
    
    22 23
           android_x86_64_package_name: $[[ inputs.android_x86_64_package_name ]]
    
    23 24
           android_x86_64_artifacts_url: $[[ inputs.android_x86_64_artifacts_url ]]
    
    ... ... @@ -31,4 +32,5 @@ include:
    31 32
           windows_x86_64_installer_url: $[[ inputs.windows_x86_64_installer_url ]]
    
    32 33
           windows_x86_64_artifacts_url: $[[ inputs.windows_x86_64_artifacts_url ]]
    
    33 34
           windows_x86_64_sha256sums_url: $[[ inputs.windows_x86_64_sha256sums_url ]]
    
    35
    +  - local: '.gitlab/test_xpcshell.yml'
    
    34 36
       - local: '.gitlab/test_marionette.yml'

  • .gitlab/_base.yml
    ... ... @@ -4,9 +4,10 @@ spec:
    4 4
     ---
    
    5 5
     variables:
    
    6 6
       MOZHARNESS_URL: "$[[ inputs.mozharness_url ]]"
    
    7
    -  TAG: "$[[ inputs.tag ]]"
    
    7
    +  TAGS: "$[[ inputs.tags ]]"
    
    8 8
     
    
    9 9
     .common:
    
    10
    +  allow_failure: true
    
    10 11
       before_script:
    
    11 12
         - python3 .gitlab/scripts/before_script.py
    
    12 13
     
    
    ... ... @@ -16,6 +17,10 @@ variables:
    16 17
     .debian-x86_64:
    
    17 18
       extends: .common
    
    18 19
     
    
    20
    +  before_script:
    
    21
    +    - Xvfb :99 -screen 0 1280x1024x24 >/dev/null 2>&1 &
    
    22
    +    - !reference [.common, before_script]
    
    23
    +
    
    19 24
       tags:
    
    20 25
         - debian-trixie-x86_64
    
    21 26
     
    
    ... ... @@ -25,9 +30,11 @@ variables:
    25 30
         - when: never
    
    26 31
     
    
    27 32
       variables:
    
    33
    +    DISPLAY: ":99"
    
    28 34
         MOZ_FETCHES_DIR: "/home/gitlab-runner/fetches"
    
    29 35
         MINIDUMP_STACKWALK_URL: "https://github.com/rust-minidump/rust-minidump/releases/download/v0.26.1/minidump-stackwalk-x86_64-unknown-linux-gnu.tar.xz"
    
    30 36
         MINIDUMP_STACKWALK_SHA256: "f789997f086dab6e46c46ab4560fc28676124613770ddac3b89a6e2e0e4963d8"
    
    37
    +    NODEJS_PATH: "/home/gitlab-runner/.nvm/versions/node/v22.16.0/bin/node"
    
    31 38
         INSTALLER_URL: "$[[ inputs.debian_x86_64_installer_url ]]"
    
    32 39
         ARTIFACTS_URL: "$[[ inputs.debian_x86_64_artifacts_url ]]"
    
    33 40
         SHA256SUMS_URL: "$[[ inputs.debian_x86_64_sha256sums_url ]]"
    
    ... ... @@ -35,6 +42,11 @@ variables:
    35 42
     .macos-x86_64:
    
    36 43
       extends: .common
    
    37 44
     
    
    45
    +  # Overwrite just so we can change $PATH
    
    46
    +  before_script:
    
    47
    +    - export PATH="/usr/local/bin:$PATH"
    
    48
    +    - !reference [.common, before_script]
    
    49
    +
    
    38 50
       tags:
    
    39 51
         - macos-sonoma-x86_64
    
    40 52
     
    
    ... ... @@ -47,6 +59,7 @@ variables:
    47 59
         MOZ_FETCHES_DIR: "/Users/gitlab-runner/fetches"
    
    48 60
         MINIDUMP_STACKWALK_URL: "https://github.com/rust-minidump/rust-minidump/releases/download/v0.26.1/minidump-stackwalk-x86_64-apple-darwin.tar.xz"
    
    49 61
         MINIDUMP_STACKWALK_SHA256: "7a3e274a09bc35ccc35e9d3dcd60e738ab14e54ea3306be94a4a8dedaf7a468d"
    
    62
    +    NODEJS_PATH: "/Users/gitlab-runner/.nvm/versions/node/v22.16.0/bin/node"
    
    50 63
         INSTALLER_URL: "$[[ inputs.macos_x86_64_installer_url ]]"
    
    51 64
         ARTIFACTS_URL: "$[[ inputs.macos_x86_64_artifacts_url ]]"
    
    52 65
         SHA256SUMS_URL: "$[[ inputs.macos_x86_64_sha256sums_url ]]"
    
    ... ... @@ -66,6 +79,7 @@ variables:
    66 79
         MOZ_FETCHES_DIR: 'C:\windoes\fetches'
    
    67 80
         MINIDUMP_STACKWALK_URL: 'https://github.com/rust-minidump/rust-minidump/releases/download/v0.26.1/minidump-stackwalk-x86_64-pc-windows-msvc.zip'
    
    68 81
         MINIDUMP_STACKWALK_SHA256: "dc6da411047ef15b784bffe0f9bf7ecb9221186c4c8fd655e3d8a3fbba0a9c61"
    
    82
    +    NODEJS_PATH: 'C:\Program Files\nodejs\node.exe'
    
    69 83
         INSTALLER_URL: "$[[ inputs.windows_x86_64_installer_url ]]"
    
    70 84
         ARTIFACTS_URL: "$[[ inputs.windows_x86_64_artifacts_url ]]"
    
    71 85
         SHA256SUMS_URL: "$[[ inputs.windows_x86_64_sha256sums_url ]]"
    

  • .gitlab/_inputs.yml
    ... ... @@ -3,10 +3,10 @@ inputs:
    3 3
         type: string
    
    4 4
         default: ""
    
    5 5
         description: "Location of the mozharness.zip archive"
    
    6
    -  tag:
    
    6
    +  tags:
    
    7 7
         type: string
    
    8 8
         default: ""
    
    9
    -    description: "Tag used to filter tests"
    
    9
    +    description: "Space-separated --tag flags (e.g. '--tag foo --tag bar'). Will run all tests if not provided"
    
    10 10
     
    
    11 11
       android_x86_64_installer_url:
    
    12 12
         type: string
    

  • .gitlab/scripts/before_script.py
    1 1
     import hashlib
    
    2 2
     import os
    
    3
    +import platform
    
    3 4
     import shutil
    
    4 5
     import subprocess
    
    5 6
     import time
    
    ... ... @@ -32,12 +33,17 @@ def download_file(url: str, dest: Path, sha256: str = "") -> None:
    32 33
     
    
    33 34
     
    
    34 35
     def extract_tar(tar_path: Path, dest_dir: Path) -> None:
    
    35
    -    subprocess.run(
    
    36
    +    result = subprocess.run(
    
    36 37
             # --strip-components=1: all the archives we fetch have contents nested inside a
    
    37 38
             # top-level directory rather than at the root, so we strip it on extraction.
    
    38
    -        ["tar", "-xf", str(tar_path), "-C", str(dest_dir), "--strip-components=1"],
    
    39
    -        check=True,
    
    39
    +        #
    
    40
    +        # NOTE: The `v` flag is _required_ for tar to work on MacOS ¯\_(ツ)_/¯
    
    41
    +        ["tar", f"-x{'v' if platform.system() == 'Darwin' else ''}f", str(tar_path), "-C", str(dest_dir), "--strip-components=1"],
    
    42
    +        stderr=subprocess.PIPE,
    
    43
    +        text=True,
    
    40 44
         )
    
    45
    +    if result.returncode != 0:
    
    46
    +        raise RuntimeError(f"tar failed (exit {result.returncode}):\n{result.stderr}")
    
    41 47
     
    
    42 48
     
    
    43 49
     def check_sha256sums_url(sha256sums_url: str) -> None:
    
    ... ... @@ -159,6 +165,22 @@ def setup_android_sdk(moz_fetches_dir: str) -> None:
    159 165
         print(f"Moved AVD -> {android_device_dir / 'avd'}")
    
    160 166
     
    
    161 167
     
    
    168
    +
    
    169
    +def download_hostutils(moz_fetches_dir: str) -> None:
    
    170
    +    # Stable mirror of  https://firefox-ci-tc.services.mozilla.com/api/index/v1/task/gecko.cache.level-3.toolchains.v3.linux64-hostutils.latest/artifacts/public%2Fbuild%2Fhostutils.tar.zst
    
    171
    +    HOSTUTILS_URL = "https://build-sources.tbb.torproject.org/hostutils.tar.zst"
    
    172
    +    HOSTUTILS_SHA256 = (
    
    173
    +        "90ff9390181d7dc015c882f11e11800ef03be39f003c29b22bda01ad21c04a9e"
    
    174
    +    )
    
    175
    +
    
    176
    +    hostutils_dir = Path(moz_fetches_dir) / "hostutils"
    
    177
    +    hostutils_dir.mkdir(parents=True, exist_ok=True)
    
    178
    +
    
    179
    +    tar_zst_path = Path("hostutils.tar.zst")
    
    180
    +    download_file(HOSTUTILS_URL, tar_zst_path, HOSTUTILS_SHA256)
    
    181
    +    extract_tar(tar_zst_path, hostutils_dir)
    
    182
    +
    
    183
    +
    
    162 184
     def before_script(
    
    163 185
         mozharness_url: str,
    
    164 186
         minidump_stackwalk_url: str,
    
    ... ... @@ -175,6 +197,7 @@ def before_script(
    175 197
     
    
    176 198
         if setup_android:
    
    177 199
             setup_android_sdk(moz_fetches_dir)
    
    200
    +        download_hostutils(moz_fetches_dir)
    
    178 201
     
    
    179 202
     
    
    180 203
     if __name__ == "__main__":
    

  • .gitlab/test_marionette.yml
    1
    -.marionette-desktop:
    
    1
    +debian-x86_64_marionette:
    
    2
    +  extends: .debian-x86_64
    
    2 3
       stage: test-marionette
    
    3 4
       script:
    
    4 5
         - >
    
    ... ... @@ -6,23 +7,32 @@
    6 7
           --config-file "$(pwd)/mozharness/configs/marionette/prod_config.py"
    
    7 8
           --installer-url "$INSTALLER_URL"
    
    8 9
           --test-packages-url "$ARTIFACTS_URL/target.test_packages.json"
    
    9
    -      --tag "$TAG"
    
    10 10
           --headless
    
    11
    -
    
    12
    -debian-x86_64_marionette:
    
    13
    -  extends:
    
    14
    -    - .debian-x86_64
    
    15
    -    - .marionette-desktop
    
    11
    +      $TAGS
    
    16 12
     
    
    17 13
     macos-x86_64_marionette:
    
    18
    -  extends:
    
    19
    -    - .macos-x86_64
    
    20
    -    - .marionette-desktop
    
    14
    +  extends: .macos-x86_64
    
    15
    +  stage: test-marionette
    
    16
    +  script:
    
    17
    +    - >
    
    18
    +      python3 "$(pwd)/mozharness/scripts/marionette.py"
    
    19
    +      --config-file "$(pwd)/mozharness/configs/marionette/prod_config.py"
    
    20
    +      --installer-url "$INSTALLER_URL"
    
    21
    +      --test-packages-url "$ARTIFACTS_URL/target.test_packages.json"
    
    22
    +      --headless
    
    23
    +      $TAGS
    
    21 24
     
    
    22 25
     windows-x86_64_marionette:
    
    23
    -  extends:
    
    24
    -    - .windows-x86_64
    
    25
    -    - .marionette-desktop
    
    26
    +  extends: .windows-x86_64
    
    27
    +  stage: test-marionette
    
    28
    +  script:
    
    29
    +    - >
    
    30
    +      python3 "$(pwd)/mozharness/scripts/marionette.py"
    
    31
    +      --config-file "$(pwd)/mozharness/configs/marionette/prod_config.py"
    
    32
    +      --installer-url "$INSTALLER_URL"
    
    33
    +      --test-packages-url "$ARTIFACTS_URL/target.test_packages.json"
    
    34
    +      --headless
    
    35
    +      ($env:TAGS -split ' ')
    
    26 36
     
    
    27 37
     android-x86_64_marionette:
    
    28 38
       extends: .android-x86_64
    
    ... ... @@ -36,4 +46,4 @@ android-x86_64_marionette:
    36 46
           --installer-url "$INSTALLER_URL"
    
    37 47
           --test-packages-url "$ARTIFACTS_URL/target.test_packages.json"
    
    38 48
           --package-name "$PACKAGE_NAME"
    
    39
    -      --tag "$TAG"
    49
    +      $TAGS

  • .gitlab/test_xpcshell.yml
    1
    +debian-x86_64_xpcshell:
    
    2
    +  extends: .debian-x86_64
    
    3
    +  stage: test-xpcshell
    
    4
    +  script:
    
    5
    +    - >
    
    6
    +      python3 "$(pwd)/mozharness/scripts/desktop_unittest.py"
    
    7
    +      --config-file "$(pwd)/mozharness/configs/unittests/linux_unittest.py"
    
    8
    +      --xpcshell-suite xpcshell
    
    9
    +      --installer-url "$INSTALLER_URL"
    
    10
    +      --test-packages-url "$ARTIFACTS_URL/target.test_packages.json"
    
    11
    +      $TAGS
    
    12
    +
    
    13
    +macos-x86_64_xpcshell:
    
    14
    +  extends: .macos-x86_64
    
    15
    +  stage: test-xpcshell
    
    16
    +  script:
    
    17
    +    - >
    
    18
    +      python3 "$(pwd)/mozharness/scripts/desktop_unittest.py"
    
    19
    +      --config-file "$(pwd)/mozharness/configs/unittests/mac_unittest.py"
    
    20
    +      --xpcshell-suite xpcshell
    
    21
    +      --installer-url "$INSTALLER_URL"
    
    22
    +      --test-packages-url "$ARTIFACTS_URL/target.test_packages.json"
    
    23
    +      $TAGS
    
    24
    +
    
    25
    +windows-x86_64_xpcshell:
    
    26
    +  extends: .windows-x86_64
    
    27
    +  stage: test-xpcshell
    
    28
    +  script:
    
    29
    +    - >
    
    30
    +      python3 "$(pwd)/mozharness/scripts/desktop_unittest.py"
    
    31
    +      --config-file "$(pwd)/mozharness/configs/unittests/win_unittest.py"
    
    32
    +      --xpcshell-suite xpcshell
    
    33
    +      --installer-url "$INSTALLER_URL"
    
    34
    +      --test-packages-url "$ARTIFACTS_URL/target.test_packages.json"
    
    35
    +      --pip-index
    
    36
    +      ($env:TAGS -split ' ')
    
    37
    +
    
    38
    +android-x86_64_xpcshell:
    
    39
    +  extends: .android-x86_64
    
    40
    +  stage: test-xpcshell
    
    41
    +  script:
    
    42
    +    - >
    
    43
    +      python3 "$(pwd)/mozharness/scripts/android_emulator_unittest.py"
    
    44
    +      --config-file "$(pwd)/mozharness/configs/android/android_common.py"
    
    45
    +      --config-file "$(pwd)/mozharness/configs/android/android14-x86_64.py"
    
    46
    +      --test-suite=xpcshell
    
    47
    +      --installer-url "$ARTIFACTS_URL/test_runner.apk"
    
    48
    +      --test-packages-url "$ARTIFACTS_URL/target.test_packages.json"
    
    49
    +      --package-name "$PACKAGE_NAME"
    
    50
    +      $TAGS

  • config/tb-build-06.torproject.org
    ... ... @@ -37,13 +37,13 @@ my $test_post = sub {
    37 37
         return unless $test->{results} && $test->{results}{success};
    
    38 38
         return unless $test->{publish_dir};
    
    39 39
     
    
    40
    -    my $tag = $test->{name} =~ /^torbrowser/ ? 'tor' : 'mullvad-browser';
    
    40
    +    my $browser_tag = $test->{name} =~ /^torbrowser/ ? 'tor' : 'mullvad-browser';
    
    41 41
         my ($stdout, $stderr, $success) = capture_exec(
    
    42 42
             'python3', "$FindBin::Bin/tools/trigger-test-pipeline.py",
    
    43 43
             '--step-name', $test->{name},
    
    44 44
             '--publish-url', $publish_url,
    
    45 45
             '--publish-dir', $test->{publish_dir},
    
    46
    -        '--tag', $tag,
    
    46
    +        '--tags', "$browser_tag,base-browser",
    
    47 47
         );
    
    48 48
         write_file(
    
    49 49
           "$tbbinfos->{'results-dir'}/$test->{name}.trigger-test-pipeline.stderr.txt",
    

  • tools/trigger-test-pipeline.py
    ... ... @@ -35,6 +35,13 @@ def setup_logging() -> None:
    35 35
         )
    
    36 36
     
    
    37 37
     
    
    38
    +def comma_separated_list(value):
    
    39
    +    items = [item.strip() for item in value.split(",") if item.strip()]
    
    40
    +    if not items:
    
    41
    +        raise argparse.ArgumentTypeError("must provide at least one tag")
    
    42
    +    return items
    
    43
    +
    
    44
    +
    
    38 45
     def parse_args() -> argparse.Namespace:
    
    39 46
         parser = argparse.ArgumentParser(
    
    40 47
             description="Post-build trigger hook for triggering GitLab CI pipelines."
    
    ... ... @@ -59,9 +66,10 @@ def parse_args() -> argparse.Namespace:
    59 66
             help="Subdirectory within the publish URL where build artifacts are located.",
    
    60 67
         )
    
    61 68
         parser.add_argument(
    
    62
    -        "--tag",
    
    69
    +        "--tags",
    
    63 70
             required=False,
    
    64
    -        help="Tag used to filter tests.",
    
    71
    +        type=comma_separated_list,
    
    72
    +        help="Comma separated list of tags used to filter tests. Will run all tests if not provided",
    
    65 73
         )
    
    66 74
         parser.add_argument(
    
    67 75
             "--dry-run",
    
    ... ... @@ -71,7 +79,7 @@ def parse_args() -> argparse.Namespace:
    71 79
         return parser.parse_args()
    
    72 80
     
    
    73 81
     
    
    74
    -def build_inputs(step_name: str, publish_url: str, publish_dir: str, tag: str) -> dict[str, str] | None:
    
    82
    +def build_inputs(step_name: str, publish_url: str, publish_dir: str, tags: list[str] | None) -> dict[str, str] | None:
    
    75 83
         # Add the architecture as padding, to address the macos case which doesn't
    
    76 84
         # have architecture in the step name since it is a universal build.
    
    77 85
         browser, channel, platform, architecture = (step_name.split("-") + ["x86_64"])[:4]
    
    ... ... @@ -116,8 +124,8 @@ def build_inputs(step_name: str, publish_url: str, publish_dir: str, tag: str) -
    116 124
         if platform == "android":
    
    117 125
             inputs[f"{input_prefix}_package_name"] = f"org.torproject.{browser}_{channel}"
    
    118 126
     
    
    119
    -    if tag:
    
    120
    -        inputs["tag"] = tag
    
    127
    +    if tags:
    
    128
    +        inputs["tags"] = " ".join(f"--tag {tag}" for tag in tags)
    
    121 129
     
    
    122 130
         return inputs
    
    123 131
     
    
    ... ... @@ -157,7 +165,7 @@ def main() -> int:
    157 165
         with open(token_file) as f:
    
    158 166
             trigger_token = f.read().strip()
    
    159 167
     
    
    160
    -    inputs = build_inputs(args.step_name, args.publish_url, args.publish_dir, args.tag)
    
    168
    +    inputs = build_inputs(args.step_name, args.publish_url, args.publish_dir, args.tags)
    
    161 169
         if inputs is None:
    
    162 170
             logger.info(f"No CI inputs for step {args.step_name!r}, skipping.")
    
    163 171
             return 0
    

  • _______________________________________________
    tor-commits mailing list -- tor-commits@xxxxxxxxxxxxxxxxxxxx
    To unsubscribe send an email to tor-commits-leave@xxxxxxxxxxxxxxxxxxxx