.github/workflows: Keep scst_user fork coverage manual

Reserve the legacy-kernel fork checks for manual runs instead of adding
two VM jobs and extra kernel builds to the regular CI selection. Remove
the Linux 5.8/5.9 Ginkgo jobs and regression matrix entries, retaining the
kernel pins and local-only VM runner for reproduction.

Label the fork spec manual and exclude that label from both ci-pr and
ci-push. Move smoke to the READ CAPACITY entries so their existing CI
coverage remains intact. Keep full manual runs inclusive, update the
selection checks, and document focused manual execution.
This commit is contained in:
Gleb Chesnokov
2026-10-20 08:49:25 +03:00
parent 24a4c28245
commit 46208a5ba0
8 changed files with 48 additions and 80 deletions
-2
View File
@@ -23,8 +23,6 @@ GITHUB_REGRESSION_KERNEL_SELECTORS="\
6.1 \
5.15 \
5.10 \
5.9 \
5.8 \
5.4 \
4.19 \
4.14 \
-60
View File
@@ -66,63 +66,3 @@ jobs:
${{ runner.temp }}/ginkgo-image/*.json
${{ runner.temp }}/ginkgo-image/*.txt
${{ runner.temp }}/ginkgo-results/
user-kernels:
# Run the local scst_user specs on both sides of the Linux 5.9 boundary of
# dev_user_map_buf(). Named like the regression jobs; the build step checks
# each name against its scripts/ci/<pin>.env.
name: ${{ matrix.name }}
runs-on: ubuntu-24.04
timeout-minutes: 120
strategy:
fail-fast: false
matrix:
include:
- pin: kernel-5.8
name: 5.8.18-300.fc33^Fedora^33
- pin: kernel-5.9
name: 5.9.16-200.fc33^Fedora^33
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
fetch-depth: 0
- name: Select Ginkgo checks
id: changes
env:
BASE_SHA: ${{ github.event.pull_request.base.sha }}
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
run: |
python3 scripts/ci/select_checks.py --check ginkgo --event "$GITHUB_EVENT_NAME" \
--base "$BASE_SHA" --head "$HEAD_SHA"
- name: Install build and VM tools
if: steps.changes.outputs.run == 'true'
run: |
sudo apt-get update
sudo apt-get install -y qemu-system-x86 qemu-utils openssh-client e2fsprogs fakeroot
- name: Build SCST image with the kernel from scripts/ci/${{ matrix.pin }}.env
if: steps.changes.outputs.run == 'true'
timeout-minutes: 60
env:
PIN: ${{ matrix.pin }}
NAME: ${{ matrix.name }}
run: |
source "scripts/ci/$PIN.env"
[[ $NAME == "$KERNEL_BUILD^"* ]] || { echo "::error::$NAME does not match $PIN.env"; exit 1; }
bash scripts/ci/build-image ginkgo "$RUNNER_TEMP/ginkgo-image" "$PIN"
- name: Run local scst_user tests against the compiled SCST
if: steps.changes.outputs.run == 'true'
run: |
python3 scripts/ci/vm.py ginkgo "$RUNNER_TEMP/ginkgo-image" \
"$RUNNER_TEMP/ginkgo-results" --timeout 3000 --local-only --ginkgo-label user
- name: Save build logs, reports and serial console
if: always() && steps.changes.outputs.run == 'true'
uses: actions/upload-artifact@v4
with:
name: ginkgo-${{ matrix.pin }}-results
retention-days: 7
path: |
${{ runner.temp }}/ginkgo-image/*.log
${{ runner.temp }}/ginkgo-image/*.json
${{ runner.temp }}/ginkgo-image/*.txt
${{ runner.temp }}/ginkgo-results/
+18 -6
View File
@@ -32,14 +32,18 @@ Kernel matrices are maintained through `.github/kernel-matrix.conf` and
`nightly/conf/nightly.conf`; VM kernel pins are in `scripts/ci/kernel.env`
and `kernel.SHA256SUMS` and must be updated together.
Further Ginkgo jobs run the local `user` specs on Fedora 33's Linux 5.8.18 and
5.9.16, pinned in `scripts/ci/kernel-5.8.env` and `kernel-5.9.env` with their
`SHA256SUMS`. Linux 5.9 is the first release where `fork()` copies pinned
Manual Ginkgo runs can use Fedora 33's Linux 5.8.18 and 5.9.16, pinned in
`scripts/ci/kernel-5.8.env` and `kernel-5.9.env` with their `SHA256SUMS`.
These kernels have no dedicated Ginkgo jobs or entries in the GitHub
regression matrix; the nightly support list is unchanged.
Linux 5.9 is the first release where `fork()` copies pinned
ordinary anonymous pages, which scst_user relies on. The 5.8 fork fixture
uses the documented `MADV_DONTFORK` protection; the 5.9 fixture exercises
pinning without it. Both require correct geometry and data after the fork.
The invalid-capacity specs check the exact SCSI rejection on both kernels.
The images are otherwise built the same way; these jobs have no iSCSI initiator.
The images are otherwise built the same way; `--local-only` runs have no
iSCSI initiator. The fork spec has the `manual` label and is excluded from
both automatic Ginkgo selections.
## Results
@@ -75,8 +79,16 @@ python3 scripts/ci/vm.py ginkgo /tmp/scst-ginkgo-image /tmp/scst-ginkgo-results
```
Use `--ginkgo-label ci-push` for the master selection; omit it for all specs.
For the scst_user kernel jobs, add the pin name, such as `kernel-5.9`, to
`build-image` and run `vm.py` with `--local-only --ginkgo-label user`.
To run the fork spec manually on Linux 5.9:
```sh
bash scripts/ci/build-image ginkgo /tmp/scst-ginkgo-5.9-image kernel-5.9
python3 scripts/ci/vm.py ginkgo /tmp/scst-ginkgo-5.9-image /tmp/scst-ginkgo-5.9-results \
--timeout 3000 --local-only --ginkgo-label 'user && manual'
```
Use `kernel-5.8` and new output directories for Linux 5.8. Use
`--ginkgo-label user` to include the invalid-capacity specs as well.
`--local-only` intersects the resolved label expression with `local`; without
`--ginkgo-label`, it selects all local specs.
QEMU tries KVM then TCG; `--accel tcg` forces emulation. To check the VM
+3 -2
View File
@@ -277,7 +277,8 @@ class ConsoleTests(unittest.TestCase):
def test_ginkgo_label_sets_reach_both_suites_and_are_reported(self):
for label, expression in (('basic || smoke', 'basic || smoke'),
('ci-pr', 'basic || smoke'), ('ci-push', '!race')):
('ci-pr', '(basic || smoke) && !manual'),
('ci-push', '!race && !manual')):
with self.subTest(label=label):
self.output = self.root / label
result, output = self.run_guest('ginkgo', ginkgo_label=label)
@@ -298,7 +299,7 @@ class ConsoleTests(unittest.TestCase):
def test_local_only_restricts_the_label_filter_to_local_specs(self):
for label, expression in (('', 'local'), ('user', 'local && (user)'),
('basic || smoke', 'local && (basic || smoke)'),
('ci-pr', 'local && (basic || smoke)')):
('ci-pr', 'local && ((basic || smoke) && !manual)')):
with self.subTest(label=label):
self.output = self.root / f'filter-{label or "all"}'
result, output = self.run_guest('ginkgo', ginkgo_label=label, local_only=True)
+14 -4
View File
@@ -57,13 +57,14 @@ by the local runner and VM supervisor:
| Label set | Ginkgo expression |
| --- | --- |
| `ci-pr` | `basic || smoke` |
| `ci-push` | `!race` |
| `ci-pr` | `(basic || smoke) && !manual` |
| `ci-push` | `!race && !manual` |
Each set aliases a whole filter; its definition combines ordinary Ginkgo labels.
Pass either a set name or a Ginkgo expression as `GINKGO_LABEL`. Manual workflow
runs use an empty filter and select all specs, including timing-dependent
`race` scenarios. Other stress tests remain in `ci-push`.
runs use an empty filter and select all specs, including `manual` and
timing-dependent `race` scenarios. The `manual` label excludes a spec from
both automatic CI sets. Other stress tests remain in `ci-push`.
```sh
# List the pull-request selection:
@@ -142,6 +143,15 @@ particular cached buffer to produce an error. The invalid-capacity cases
require CHECK CONDITION with sense `0b/44/00` on every kernel.
The specs need a C compiler on the target to build the hook;
`ginkgo-test-build` also builds `usr`, and the local suite loads `scst_user`.
The fork spec is labelled `manual`; the invalid-capacity specs remain in
`smoke`. To select only the fork spec on a disposable local target:
```sh
make ginkgo-list GINKGO_LABEL='user && manual'
make ginkgo-test-build GINKGO_CONFIG=tests/ginkgo/config.local.json GINKGO_LABEL='user && manual'
```
For manual VM runs on Linux 5.8 or 5.9, see [CI reproduction](../../doc/CI.md#local-reproduction).
The `unmap` specs exercise temporary thin-provisioned fileio exports over
`scst_local` and TCP iSCSI. They require util-linux `fallocate` on the target
+2 -2
View File
@@ -1,4 +1,4 @@
{
"ci-pr": "basic || smoke",
"ci-push": "!race"
"ci-pr": "(basic || smoke) && !manual",
"ci-push": "!race && !manual"
}
@@ -17,10 +17,17 @@ func TestLabelSetSelection(t *testing.T) {
{"ci-pr", []string{"iscsi", "scsi", "smoke"}, true},
{"ci-pr", []string{"iscsi", "stress", "race", "issue-367"}, false},
{"ci-pr", []string{"local", "stress"}, false},
{"ci-pr", []string{"local", "user", "manual"}, false},
{"ci-pr", []string{"local", "basic", "manual"}, false},
{"ci-pr", []string{"local", "smoke", "manual"}, false},
{"ci-push", []string{"local", "stress"}, true},
{" ci-push ", []string{"iscsi", "scsi"}, true},
{"ci-push", []string{"iscsi", "stress", "race", "issue-367"}, false},
{"ci-push", []string{"local", "user", "manual"}, false},
{"", []string{"iscsi", "race"}, true},
{"", []string{"local", "user", "manual"}, true},
{"user && manual", []string{"local", "user", "manual"}, true},
{"user && manual", []string{"local", "user", "negative", "smoke"}, false},
{"iscsi && race", []string{"iscsi", "race"}, true},
{"iscsi && race", []string{"local", "stress"}, false},
} {
+4 -4
View File
@@ -116,7 +116,7 @@ func (f *fixture) stopUserDevice(ctx SpecContext, p *testhost.Process, name stri
}
}
var _ = Describe("User-space handler devices", Label("scsi", "user", "smoke"), func() {
var _ = Describe("User-space handler devices", Label("scsi", "user"), func() {
DescribeTable("keep replies, geometry and data intact across a handler fault",
func(ctx SpecContext, action string, capacityCDB []byte) {
timeout := testcfg.Duration(cfg.CommandTimeout)
@@ -169,9 +169,9 @@ var _ = Describe("User-space handler devices", Label("scsi", "user", "smoke"), f
}
Expect(err).To(Succeed())
},
Entry("handler forks", "fork", nil),
Entry("handler returns an invalid READ CAPACITY(10) block length", Label("negative"),
Entry("handler forks", Label("manual"), "fork", nil),
Entry("handler returns an invalid READ CAPACITY(10) block length", Label("negative", "smoke"),
"capacity", dataio.ReadCapacity10),
Entry("handler returns an invalid READ CAPACITY(16) block length", Label("negative"),
Entry("handler returns an invalid READ CAPACITY(16) block length", Label("negative", "smoke"),
"capacity", dataio.ReadCapacity16))
})