This is an automated email from the ASF dual-hosted git repository.

shahar1 pushed a commit to branch ci-runs-on-in-memory-docker
in repository https://gitbox.apache.org/repos/asf/airflow.git

commit 57a0c7ab1eef963c18ddacfece9540cbf671ad57
Author: Shahar Epstein <[email protected]>
AuthorDate: Sun Oct 25 22:05:41 2026 +0200

    Run the database test jobs on RunsOn with docker in RAM
    
    The longest CI jobs are the ones EC2 Spot reclaims: 6 of the first 8 Spot
    interruptions on RunsOn hit jobs running 20 minutes or more. Those jobs are
    not short of CPU - on 8 vCPU they average a load of 1.2-3 and use 11-14% of
    32 GB, and 32 vCPU did not make the lowest-dependencies or Latest Boto core
    tests any faster than 4 vCPU on GitHub-hosted runners. They wait on the
    database's disk syncs instead: MySQL core takes 42 minutes on RunsOn, where
    docker sits on EBS, against 29 minutes on GitHub-hosted runners, which move
    docker to a local SSD.
    
    Putting docker on a RAM disk on RunsOn removes that wait and shortens the
    time these jobs are exposed to Spot interruptions. The two jobs that did not
    benefit from 32 vCPU drop to 8. Public runners are unaffected, and the
    repository variable USE_IN_MEMORY_DOCKER=false moves docker back to disk
    without a code change if the RAM disk causes trouble.
    
    Claude-Session: https://claude.ai/code/session_012QXcAFfqfQ4mgFecQqVkim
---
 .github/workflows/ci-amd.yml                       |  18 +--
 .github/workflows/ci-arm.yml                       |  18 +--
 .github/workflows/special-tests.yml                |  20 +--
 dev/breeze/doc/ci/04_selective_checks.md           |  11 ++
 dev/breeze/src/airflow_breeze/global_constants.py  |  11 ++
 .../src/airflow_breeze/utils/selective_checks.py   |  21 ++++
 dev/breeze/tests/test_selective_checks.py          | 138 ++++++++++++++++++++-
 7 files changed, 214 insertions(+), 23 deletions(-)

diff --git a/.github/workflows/ci-amd.yml b/.github/workflows/ci-amd.yml
index a80606f666b..c5f24e5937b 100644
--- a/.github/workflows/ci-amd.yml
+++ b/.github/workflows/ci-amd.yml
@@ -352,6 +352,7 @@ jobs:
       run-breeze-integration-tests: ${{ 
steps.selective-checks.outputs.run-breeze-integration-tests }}
       run-scripts-tests: ${{ steps.selective-checks.outputs.run-scripts-tests 
}}
       runner-type: ${{ steps.selective-checks.outputs.runner-type }}
+      in-memory-runner-type: ${{ 
steps.selective-checks.outputs.in-memory-runner-type }}
       run-ui-tests: ${{ steps.selective-checks.outputs.run-ui-tests }}
       run-ui-e2e-tests: ${{ steps.selective-checks.outputs.run-ui-e2e-tests }}
       run-unit-tests: ${{ steps.selective-checks.outputs.run-unit-tests }}
@@ -461,6 +462,8 @@ jobs:
           GITHUB_CONTEXT_INPUT: "${{ runner.temp }}/github_context.json"
           # Repository variable: "true" moves every run, pushes included, back 
to public runners.
           USE_PUBLIC_RUNNERS: "${{ vars.USE_PUBLIC_RUNNERS }}"
+          # Repository variable: "false" keeps docker of the RunsOn jobs on 
disk instead of in RAM.
+          USE_IN_MEMORY_DOCKER: "${{ vars.USE_IN_MEMORY_DOCKER }}"
           PLATFORM: "linux/amd64"
           SELECTIVE_TESTS_ON_PUSH: "true"
           PUSH_BASE_COMMIT: ${{ 
needs.check-run-needed.outputs.push-base-commit }}
@@ -764,7 +767,7 @@ jobs:
       contents: read
       packages: read
     with:
-      runners: ${{ format(needs.build-info.outputs.runner-type, 8, 32) }}
+      runners: ${{ format(needs.build-info.outputs.in-memory-runner-type, 8, 
'32+64') }}
       platform: ${{ needs.build-info.outputs.platform }}
       backend: "postgres"
       test-name: "Postgres"
@@ -793,7 +796,7 @@ jobs:
       contents: read
       packages: read
     with:
-      runners: ${{ format(needs.build-info.outputs.runner-type, 8, 32) }}
+      runners: ${{ format(needs.build-info.outputs.in-memory-runner-type, 8, 
'32+64') }}
       platform: ${{ needs.build-info.outputs.platform }}
       backend: "postgres"
       test-name: "Postgres"
@@ -822,7 +825,7 @@ jobs:
       contents: read
       packages: read
     with:
-      runners: ${{ format(needs.build-info.outputs.runner-type, 8, 32) }}
+      runners: ${{ format(needs.build-info.outputs.in-memory-runner-type, 8, 
'32+64') }}
       platform: ${{ needs.build-info.outputs.platform }}
       backend: "mysql"
       test-name: "MySQL"
@@ -852,7 +855,7 @@ jobs:
       contents: read
       packages: read
     with:
-      runners: ${{ format(needs.build-info.outputs.runner-type, 8, 32) }}
+      runners: ${{ format(needs.build-info.outputs.in-memory-runner-type, 8, 
'32+64') }}
       platform: ${{ needs.build-info.outputs.platform }}
       backend: "mysql"
       test-name: "MySQL"
@@ -881,7 +884,7 @@ jobs:
       contents: read
       packages: read
     with:
-      runners: ${{ format(needs.build-info.outputs.runner-type, 8, 32) }}
+      runners: ${{ format(needs.build-info.outputs.in-memory-runner-type, 8, 
'32+64') }}
       platform: ${{ needs.build-info.outputs.platform }}
       backend: "sqlite"
       test-name: "Sqlite"
@@ -912,7 +915,7 @@ jobs:
       contents: read
       packages: read
     with:
-      runners: ${{ format(needs.build-info.outputs.runner-type, 8, 32) }}
+      runners: ${{ format(needs.build-info.outputs.in-memory-runner-type, 8, 
'32+64') }}
       platform: ${{ needs.build-info.outputs.platform }}
       backend: "sqlite"
       test-name: "Sqlite"
@@ -1010,6 +1013,7 @@ jobs:
     with:
       default-branch: ${{ needs.build-info.outputs.default-branch }}
       runners: ${{ needs.build-info.outputs.runner-type }}
+      in-memory-runners: ${{ needs.build-info.outputs.in-memory-runner-type }}
       platform: ${{ needs.build-info.outputs.platform }}
       core-test-types-list-as-strings-in-json: >
         ${{ needs.build-info.outputs.core-test-types-list-as-strings-in-json }}
@@ -1059,7 +1063,7 @@ jobs:
     if: >
       needs.build-info.outputs.run-unit-tests == 'true'
     with:
-      runners: ${{ format(needs.build-info.outputs.runner-type, 32, 128) }}
+      runners: ${{ format(needs.build-info.outputs.in-memory-runner-type, 8, 
'32+64') }}
       platform: ${{ needs.build-info.outputs.platform }}
       test-name: "LowestDeps"
       force-lowest-dependencies: "true"
diff --git a/.github/workflows/ci-arm.yml b/.github/workflows/ci-arm.yml
index dd6c85c035e..47c59be2367 100644
--- a/.github/workflows/ci-arm.yml
+++ b/.github/workflows/ci-arm.yml
@@ -234,6 +234,7 @@ jobs:
       run-breeze-integration-tests: ${{ 
steps.selective-checks.outputs.run-breeze-integration-tests }}
       run-scripts-tests: ${{ steps.selective-checks.outputs.run-scripts-tests 
}}
       runner-type: ${{ steps.selective-checks.outputs.runner-type }}
+      in-memory-runner-type: ${{ 
steps.selective-checks.outputs.in-memory-runner-type }}
       run-ui-tests: ${{ steps.selective-checks.outputs.run-ui-tests }}
       run-ui-e2e-tests: ${{ steps.selective-checks.outputs.run-ui-e2e-tests }}
       run-unit-tests: ${{ steps.selective-checks.outputs.run-unit-tests }}
@@ -343,6 +344,8 @@ jobs:
           GITHUB_CONTEXT_INPUT: "${{ runner.temp }}/github_context.json"
           # Repository variable: "true" moves every run, pushes included, back 
to public runners.
           USE_PUBLIC_RUNNERS: "${{ vars.USE_PUBLIC_RUNNERS }}"
+          # Repository variable: "false" keeps docker of the RunsOn jobs on 
disk instead of in RAM.
+          USE_IN_MEMORY_DOCKER: "${{ vars.USE_IN_MEMORY_DOCKER }}"
           PLATFORM: "linux/arm64"
           SELECTIVE_TESTS_ON_PUSH: "true"
           PUSH_BASE_COMMIT: ${{ 
needs.check-run-needed.outputs.push-base-commit }}
@@ -646,7 +649,7 @@ jobs:
       contents: read
       packages: read
     with:
-      runners: ${{ format(needs.build-info.outputs.runner-type, 8, 32) }}
+      runners: ${{ format(needs.build-info.outputs.in-memory-runner-type, 8, 
'32+64') }}
       platform: ${{ needs.build-info.outputs.platform }}
       backend: "postgres"
       test-name: "Postgres"
@@ -675,7 +678,7 @@ jobs:
       contents: read
       packages: read
     with:
-      runners: ${{ format(needs.build-info.outputs.runner-type, 8, 32) }}
+      runners: ${{ format(needs.build-info.outputs.in-memory-runner-type, 8, 
'32+64') }}
       platform: ${{ needs.build-info.outputs.platform }}
       backend: "postgres"
       test-name: "Postgres"
@@ -704,7 +707,7 @@ jobs:
       contents: read
       packages: read
     with:
-      runners: ${{ format(needs.build-info.outputs.runner-type, 8, 32) }}
+      runners: ${{ format(needs.build-info.outputs.in-memory-runner-type, 8, 
'32+64') }}
       platform: ${{ needs.build-info.outputs.platform }}
       backend: "mysql"
       test-name: "MySQL"
@@ -734,7 +737,7 @@ jobs:
       contents: read
       packages: read
     with:
-      runners: ${{ format(needs.build-info.outputs.runner-type, 8, 32) }}
+      runners: ${{ format(needs.build-info.outputs.in-memory-runner-type, 8, 
'32+64') }}
       platform: ${{ needs.build-info.outputs.platform }}
       backend: "mysql"
       test-name: "MySQL"
@@ -763,7 +766,7 @@ jobs:
       contents: read
       packages: read
     with:
-      runners: ${{ format(needs.build-info.outputs.runner-type, 8, 32) }}
+      runners: ${{ format(needs.build-info.outputs.in-memory-runner-type, 8, 
'32+64') }}
       platform: ${{ needs.build-info.outputs.platform }}
       backend: "sqlite"
       test-name: "Sqlite"
@@ -794,7 +797,7 @@ jobs:
       contents: read
       packages: read
     with:
-      runners: ${{ format(needs.build-info.outputs.runner-type, 8, 32) }}
+      runners: ${{ format(needs.build-info.outputs.in-memory-runner-type, 8, 
'32+64') }}
       platform: ${{ needs.build-info.outputs.platform }}
       backend: "sqlite"
       test-name: "Sqlite"
@@ -892,6 +895,7 @@ jobs:
     with:
       default-branch: ${{ needs.build-info.outputs.default-branch }}
       runners: ${{ needs.build-info.outputs.runner-type }}
+      in-memory-runners: ${{ needs.build-info.outputs.in-memory-runner-type }}
       platform: ${{ needs.build-info.outputs.platform }}
       core-test-types-list-as-strings-in-json: >
         ${{ needs.build-info.outputs.core-test-types-list-as-strings-in-json }}
@@ -941,7 +945,7 @@ jobs:
     if: >
       needs.build-info.outputs.run-unit-tests == 'true'
     with:
-      runners: ${{ format(needs.build-info.outputs.runner-type, 32, 128) }}
+      runners: ${{ format(needs.build-info.outputs.in-memory-runner-type, 8, 
'32+64') }}
       platform: ${{ needs.build-info.outputs.platform }}
       test-name: "LowestDeps"
       force-lowest-dependencies: "true"
diff --git a/.github/workflows/special-tests.yml 
b/.github/workflows/special-tests.yml
index ff56fbb9df5..4343e17b2e7 100644
--- a/.github/workflows/special-tests.yml
+++ b/.github/workflows/special-tests.yml
@@ -24,6 +24,10 @@ on:  # yamllint disable-line rule:truthy
         description: "The array of labels (in json form) determining runners."
         required: true
         type: string
+      in-memory-runners:
+        description: "The same as runners, with docker in RAM on self-hosted 
runners."
+        required: true
+        type: string
       platform:
         description: "Platform for the build - 'linux/amd64' or 'linux/arm64'"
         required: true
@@ -94,7 +98,7 @@ jobs:
       contents: read
       packages: read
     with:
-      runners: ${{ format(inputs.runners, 8, 32) }}
+      runners: ${{ format(inputs.in-memory-runners, 8, '32+64') }}
       platform: ${{ inputs.platform }}
       downgrade-sqlalchemy: "true"
       test-name: "MinSQLAlchemy-Postgres"
@@ -119,7 +123,7 @@ jobs:
       contents: read
       packages: read
     with:
-      runners: ${{ format(inputs.runners, 8, 32) }}
+      runners: ${{ format(inputs.in-memory-runners, 8, '32+64') }}
       platform: ${{ inputs.platform }}
       downgrade-sqlalchemy: "true"
       test-name: "MinSQLAlchemy-Postgres"
@@ -144,7 +148,7 @@ jobs:
       contents: read
       packages: read
     with:
-      runners: ${{ format(inputs.runners, 8, 32) }}
+      runners: ${{ format(inputs.in-memory-runners, 8, '32+64') }}
       platform: ${{ inputs.platform }}
       upgrade-sqlalchemy: "true"
       test-name: "LatestSQLAlchemy-Postgres"
@@ -169,7 +173,7 @@ jobs:
       contents: read
       packages: read
     with:
-      runners: ${{ format(inputs.runners, 8, 32) }}
+      runners: ${{ format(inputs.in-memory-runners, 8, '32+64') }}
       platform: ${{ inputs.platform }}
       upgrade-sqlalchemy: "true"
       test-name: "LatestSQLAlchemy-Postgres"
@@ -194,7 +198,7 @@ jobs:
       contents: read
       packages: read
     with:
-      runners: ${{ format(inputs.runners, 32, 128) }}
+      runners: ${{ format(inputs.in-memory-runners, 8, '32+64') }}
       platform: ${{ inputs.platform }}
       upgrade-boto: "true"
       test-name: "LatestBoto-Postgres"
@@ -220,7 +224,7 @@ jobs:
       contents: read
       packages: read
     with:
-      runners: ${{ format(inputs.runners, 8, 32) }}
+      runners: ${{ format(inputs.in-memory-runners, 8, '32+64') }}
       platform: ${{ inputs.platform }}
       upgrade-boto: "true"
       test-name: "LatestBoto-Postgres"
@@ -246,7 +250,7 @@ jobs:
       contents: read
       packages: read
     with:
-      runners: ${{ format(inputs.runners, 8, 32) }}
+      runners: ${{ format(inputs.in-memory-runners, 8, '32+64') }}
       platform: ${{ inputs.platform }}
       downgrade-pendulum: "true"
       test-name: "Pendulum2-Postgres"
@@ -272,7 +276,7 @@ jobs:
       contents: read
       packages: read
     with:
-      runners: ${{ format(inputs.runners, 8, 32) }}
+      runners: ${{ format(inputs.in-memory-runners, 8, '32+64') }}
       platform: ${{ inputs.platform }}
       downgrade-pendulum: "true"
       test-name: "Pendulum2-Postgres"
diff --git a/dev/breeze/doc/ci/04_selective_checks.md 
b/dev/breeze/doc/ci/04_selective_checks.md
index 15509596127..eaba2db9f35 100644
--- a/dev/breeze/doc/ci/04_selective_checks.md
+++ b/dev/breeze/doc/ci/04_selective_checks.md
@@ -671,6 +671,7 @@ GitHub Actions to pass the list of parameters to a command 
to execute
 | hatch-build-changed                                     | When hatch 
build.py changed in the PR.                                                     
             | false                                    |      |
 | helm-test-packages-list-as-string                       | List of helm 
packages to test as JSON array                                                  
           | \["airflow_aux", "airflow_core"\]        | *    |
 | helm-version                                            | Which Helm version 
to use for tests                                                                
     | v3.15.3                                  |      |
+| in-memory-runner-type                                   | Like runner-type, 
but the RunsOn template puts docker in RAM (`extras=tmpfs`) unless disabled     
      | \["ubuntu-22.04"\]                       |      |
 | include-success-outputs                                 | Whether to include 
outputs of successful parallel tests ("true"/"false")                           
     | false                                    |      |
 | individual-providers-test-types-list-as-strings-in-json | Which test types 
should be run for unit tests for providers (individually listed)                
       | Providers[\amazon\] Providers\[google\]  | *    |
 | is-committer-build                                      | Whether the build 
is triggered by a committer                                                     
      | false                                    |      |
@@ -770,6 +771,16 @@ gated on `runner.environment == 'self-hosted'`:
   the ASF stash action on both kinds of runners, so PRs on public runners keep 
the ones canary runs save;
   the price is that every RunsOn canary uploads the mount cache from AWS to 
GitHub.
 
+The `in-memory-runner-type` output is the same decision with a second RunsOn 
template, used by the
+jobs whose databases wait on disk syncs: the Postgres, MySQL and Sqlite test 
jobs, the lowest-dependencies
+core tests and the SQLAlchemy, Boto and Pendulum special tests. Its label adds
+[`extras=tmpfs`](https://runs-on.com/docs/runners/capabilities/yolo-mode/), 
which puts
+`/var/lib/docker`, `/tmp` and `/home/runner` on a RAM disk, and also accepts 
the memory-optimized
+r-family. The jobs ask for 8 CPUs and 32 or 64 GB (`ram=32+64`), as the RAM 
disk is capped at the
+runner's memory before RunsOn v3.5.0. On public runners the output equals 
`runner-type`, and so it does
+on RunsOn while the repository variable `USE_IN_MEMORY_DOCKER` is `false`: the 
switch for moving docker
+back to disk without a PR.
+
 The decision above is not a security boundary. Under the `pull_request` event 
the code that
 evaluates it is the PR's own: a fork PR runs its own workflow files and breeze 
sources, and can name
 RunsOn labels in `runs-on:` directly. RunsOn launches a runner for any job of 
a repository its GitHub
diff --git a/dev/breeze/src/airflow_breeze/global_constants.py 
b/dev/breeze/src/airflow_breeze/global_constants.py
index 15a98856e5e..336ada83fec 100644
--- a/dev/breeze/src/airflow_breeze/global_constants.py
+++ b/dev/breeze/src/airflow_breeze/global_constants.py
@@ -46,6 +46,17 @@ RUNS_ON_AMD_RUNNER_TEMPLATE = (
 RUNS_ON_ARM_RUNNER_TEMPLATE = (
     
"runs-on={run_id}/family=m8g+m7g+m6g/image=ubuntu22-full-arm64/volume=150gb/cpu={{0}}/ram={{1}}"
 )
+# The same runners with docker, /tmp and /home/runner on a RAM disk (RunsOn 
`extras=tmpfs`), for jobs whose
+# databases wait on disk syncs. The RAM disk is capped at 100% of RAM before 
RunsOn v3.5.0, so these jobs
+# ask for memory headroom and also accept the memory-optimized r-family.
+RUNS_ON_AMD_IN_MEMORY_RUNNER_TEMPLATE = (
+    
"runs-on={run_id}/family=m7a+m7i+m6a+m6i+r7a+r7i+r6a+r6i/image=ubuntu22-full-x64/volume=150gb"
+    "/cpu={{0}}/ram={{1}}/extras=tmpfs"
+)
+RUNS_ON_ARM_IN_MEMORY_RUNNER_TEMPLATE = (
+    
"runs-on={run_id}/family=m8g+m7g+m6g+r8g+r7g+r6g/image=ubuntu22-full-arm64/volume=150gb"
+    "/cpu={{0}}/ram={{1}}/extras=tmpfs"
+)
 
 # Platform the tests of a CI run execute on.
 CI_AMD_PLATFORM = "linux/amd64"
diff --git a/dev/breeze/src/airflow_breeze/utils/selective_checks.py 
b/dev/breeze/src/airflow_breeze/utils/selective_checks.py
index 7e0fdb841e5..39913be221a 100644
--- a/dev/breeze/src/airflow_breeze/utils/selective_checks.py
+++ b/dev/breeze/src/airflow_breeze/utils/selective_checks.py
@@ -56,7 +56,9 @@ from airflow_breeze.global_constants import (
     PROVIDERS_COMPATIBILITY_TESTS_MATRIX,
     PUBLIC_AMD_RUNNERS,
     PUBLIC_ARM_RUNNERS,
+    RUNS_ON_AMD_IN_MEMORY_RUNNER_TEMPLATE,
     RUNS_ON_AMD_RUNNER_TEMPLATE,
+    RUNS_ON_ARM_IN_MEMORY_RUNNER_TEMPLATE,
     RUNS_ON_ARM_RUNNER_TEMPLATE,
     TESTABLE_CORE_INTEGRATIONS,
     TESTABLE_PROVIDERS_INTEGRATION_OWNERS,
@@ -2315,6 +2317,25 @@ class SelectiveChecks:
         )
         return json.dumps([template.format(run_id=run_id)])
 
+    @cached_property
+    def in_memory_runner_type(self) -> str:
+        """Runner labels like ``runner_type``, with docker on a RAM disk when 
the run is on RunsOn.
+
+        The repository variable ``USE_IN_MEMORY_DOCKER=false`` keeps docker on 
disk.
+        """
+        # Reuses the routing decision of runner_type, which may have asked the 
GitHub API.
+        if (
+            self.runner_type in (PUBLIC_AMD_RUNNERS, PUBLIC_ARM_RUNNERS)
+            or os.environ.get("USE_IN_MEMORY_DOCKER", "").casefold() == "false"
+        ):
+            return self.runner_type
+        template = (
+            RUNS_ON_ARM_IN_MEMORY_RUNNER_TEMPLATE
+            if self._platform == CI_ARM_PLATFORM
+            else RUNS_ON_AMD_IN_MEMORY_RUNNER_TEMPLATE
+        )
+        return 
json.dumps([template.format(run_id=self._github_context_dict["run_id"])])
+
     def _use_runs_on_runners(self) -> bool:
         """Whether this run should use the self-hosted RunsOn runners.
 
diff --git a/dev/breeze/tests/test_selective_checks.py 
b/dev/breeze/tests/test_selective_checks.py
index efb8baa40a1..7587ed7357c 100644
--- a/dev/breeze/tests/test_selective_checks.py
+++ b/dev/breeze/tests/test_selective_checks.py
@@ -4912,14 +4912,23 @@ def 
test_providers_with_test_side_effects_are_shared_process_providers():
 
 RUNS_ON_AMD = 
'["runs-on=42/family=m7a+m7i+m6a+m6i/image=ubuntu22-full-x64/volume=150gb/cpu={0}/ram={1}"]'
 RUNS_ON_ARM = 
'["runs-on=42/family=m8g+m7g+m6g/image=ubuntu22-full-arm64/volume=150gb/cpu={0}/ram={1}"]'
+RUNS_ON_AMD_IN_MEMORY = (
+    
'["runs-on=42/family=m7a+m7i+m6a+m6i+r7a+r7i+r6a+r6i/image=ubuntu22-full-x64/volume=150gb'
+    '/cpu={0}/ram={1}/extras=tmpfs"]'
+)
+RUNS_ON_ARM_IN_MEMORY = (
+    
'["runs-on=42/family=m8g+m7g+m6g+r8g+r7g+r6g/image=ubuntu22-full-arm64/volume=150gb'
+    '/cpu={0}/ram={1}/extras=tmpfs"]'
+)
 
 
 HEAD_SHA = "a" * 40
 
 
 @pytest.fixture(autouse=True)
-def _no_use_public_runners_variable(monkeypatch):
+def _no_runner_variables(monkeypatch):
     monkeypatch.delenv("USE_PUBLIC_RUNNERS", raising=False)
+    monkeypatch.delenv("USE_IN_MEMORY_DOCKER", raising=False)
 
 
 def _pull_request_context(head_repo: str | None, author_type: str = "User") -> 
dict[str, Any]:
@@ -5125,6 +5134,133 @@ def test_runner_type(
     assert selective_checks.runner_type == expected
 
 
[email protected](
+    ("github_event", "github_repository", "github_context_dict", "pr_labels", 
"platform", "env", "expected"),
+    [
+        pytest.param(
+            GithubEvents.PUSH,
+            "apache/airflow",
+            {"run_id": 42},
+            (),
+            CI_AMD_PLATFORM,
+            {},
+            RUNS_ON_AMD_IN_MEMORY,
+            id="RunsOn run gets docker in RAM",
+        ),
+        pytest.param(
+            GithubEvents.SCHEDULE,
+            "apache/airflow",
+            {"run_id": 42},
+            (),
+            CI_ARM_PLATFORM,
+            {},
+            RUNS_ON_ARM_IN_MEMORY,
+            id="ARM RunsOn run gets docker in RAM",
+        ),
+        pytest.param(
+            GithubEvents.PUSH,
+            "apache/airflow",
+            {"run_id": 42},
+            (),
+            CI_AMD_PLATFORM,
+            {"USE_IN_MEMORY_DOCKER": "true"},
+            RUNS_ON_AMD_IN_MEMORY,
+            id="true keeps docker in RAM",
+        ),
+        pytest.param(
+            GithubEvents.PUSH,
+            "apache/airflow",
+            {"run_id": 42},
+            (),
+            CI_AMD_PLATFORM,
+            {"USE_IN_MEMORY_DOCKER": "False"},
+            RUNS_ON_AMD,
+            id="false keeps docker on disk",
+        ),
+        pytest.param(
+            GithubEvents.SCHEDULE,
+            "apache/airflow",
+            {"run_id": 42},
+            (),
+            CI_ARM_PLATFORM,
+            {"USE_IN_MEMORY_DOCKER": "false"},
+            RUNS_ON_ARM,
+            id="false keeps docker on disk on ARM",
+        ),
+        pytest.param(
+            GithubEvents.PULL_REQUEST,
+            "apache/airflow",
+            _pull_request_context("someone/airflow"),
+            (),
+            CI_AMD_PLATFORM,
+            {},
+            '["ubuntu-22.04"]',
+            id="fork PR stays on public runners",
+        ),
+        pytest.param(
+            GithubEvents.PUSH,
+            "apache/airflow",
+            {"run_id": 42},
+            (),
+            CI_AMD_PLATFORM,
+            {"USE_PUBLIC_RUNNERS": "true"},
+            '["ubuntu-22.04"]',
+            id="public runners variable wins",
+        ),
+        pytest.param(
+            GithubEvents.PULL_REQUEST,
+            "apache/airflow",
+            _pull_request_context("apache/airflow"),
+            ("use public runners",),
+            CI_AMD_PLATFORM,
+            {},
+            '["ubuntu-22.04"]',
+            id="public runners label wins",
+        ),
+        pytest.param(
+            GithubEvents.PUSH,
+            "apache/airflow",
+            {},
+            (),
+            CI_AMD_PLATFORM,
+            {},
+            '["ubuntu-22.04"]',
+            id="no run id stays on public runners",
+        ),
+        pytest.param(
+            GithubEvents.SCHEDULE,
+            "someone/airflow",
+            {"run_id": 42},
+            (),
+            CI_ARM_PLATFORM,
+            {},
+            '["ubuntu-22.04-arm"]',
+            id="fork repository stays on public ARM runners",
+        ),
+    ],
+)
+def test_in_memory_runner_type(
+    monkeypatch,
+    github_event: GithubEvents,
+    github_repository: str,
+    github_context_dict: dict[str, Any],
+    pr_labels: tuple[str, ...],
+    platform: str,
+    env: dict[str, str],
+    expected: str,
+):
+    for name, value in env.items():
+        monkeypatch.setenv(name, value)
+    selective_checks = SelectiveChecks(
+        github_event=github_event,
+        github_repository=github_repository,
+        github_context_dict=github_context_dict,
+        pr_labels=pr_labels,
+        platform=platform,
+    )
+    assert selective_checks.in_memory_runner_type == expected
+
+
 @pytest.mark.parametrize(
     ("value", "expected"),
     [

Reply via email to