Files
J Logan 76f387e3be Restore reverted migrations, migrate last tests. (#1880)
- Part of #1833.
- CLI progress and registry test migrations were inadventently reverted
by #1857.
- Migrate TestCLINoParallelCases to TestCLIImagePruneSerial and
TestCLINetworkPruneSerial.
- Clean up test selection patterns in Makefile.
- Remove all legacy CLITests files.
- Use swift-testing `withKnownIssue` to run but ignore failures on flaky
`testCreateNameLongestValid` and `testIsolatedNetwork`.
- Extracts a fixture helper for tests requiring a retry loop.
2026-07-02 15:34:46 -07:00

86 lines
4.2 KiB
Swift

//===----------------------------------------------------------------------===//
// Copyright © 2026 Apple Inc. and the container project authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//===----------------------------------------------------------------------===//
import Foundation
import Testing
/// Serial prune tests — `container prune` affects all stopped containers regardless of name.
@Suite(.serialized)
struct TestCLIPruneCommandSerial {
@Test func testContainerPruneNoContainers() async throws {
try await ContainerFixture.with { f in
// Establish empty state — the serial global pass runs after the concurrent
// pass, and any test that failed mid-cleanup could leave stopped containers
// that would break the "reclaimed zero" assertion. Machine-backing containers
// are excluded from `container delete --all` by design so this doesn't
// interfere with the machine plugin.
_ = try? f.run(["delete", "--all", "--force"])
let result = try f.run(["prune"]).check()
#expect(result.error.contains("Reclaimed Zero KB in disk space"), "should show no containers message")
}
}
@Test func testContainerPruneStoppedContainers() async throws {
try await ContainerFixture.with { f in
let image = ContainerFixture.warmupImages[0]
if try !f.isImagePresent(image) { try f.doPull(image) }
// One running container that must survive the prune.
try await f.withContainer(image: image, tag: "running", containerArgs: ["sleep", "3600"]) { npcName in
// Two containers to stop and prune.
try await f.withContainer(
image: image, tag: "prune0", containerArgs: ["sleep", "3600"], autoRemove: false
) { pc0Name in
try await f.withContainer(
image: image, tag: "prune1", containerArgs: ["sleep", "3600"], autoRemove: false
) { pc1Name in
let pc0Id = try f.getContainerId(pc0Name)
let pc1Id = try f.getContainerId(pc1Name)
try f.doStop(pc0Name)
try f.doStop(pc1Name)
// Poll until both containers reach stopped state.
let deadline = Date().addingTimeInterval(30)
while true {
let s0 = try f.getContainerStatus(pc0Name)
let s1 = try f.getContainerStatus(pc1Name)
if s0 == "stopped" && s1 == "stopped" { break }
guard Date() < deadline else {
throw CommandError.executionFailed(
"Timeout waiting for containers to stop: pc0=\(s0), pc1=\(s1)")
}
try await Task.sleep(for: .milliseconds(200))
}
let result = try f.run(["prune"]).check()
#expect(
result.output.contains(pc0Id) && result.output.contains(pc1Id),
"prune output should list stopped container IDs")
#expect(
!result.error.contains("Reclaimed Zero KB in disk space"),
"reclaimed space should not be zero")
let npcStatus = try f.getContainerStatus(npcName)
#expect(npcStatus == "running", "running container should not be pruned")
}
}
}
}
}
}