Files
wehub-resource-sync e84fb4a79e
container project - merge build / Invoke build (push) Successful in 1s
chore: import upstream snapshot with attribution
2026-07-13 12:06:18 +08:00

111 lines
4.3 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
@Suite(.serialized)
struct TestCLIVolumesSerial {
private let alpine = ContainerFixture.warmupImages[0]
@Test func testVolumePruneNoVolumes() async throws {
try await ContainerFixture.with { f in
let result = try f.run(["volume", "prune"]).check()
#expect(result.error.contains("Zero KB"), "should show no space reclaimed")
}
}
@Test func testVolumePruneUnusedVolumes() async throws {
try await ContainerFixture.with { f in
let v1 = "\(f.testID)-vol1"
let v2 = "\(f.testID)-vol2"
f.addCleanup {
f.doVolumeDeleteIfExists(v1)
f.doVolumeDeleteIfExists(v2)
}
try f.doVolumeCreate(v1)
try f.doVolumeCreate(v2)
let list = try f.run(["volume", "list", "--quiet"]).check().output
#expect(list.contains(v1) && list.contains(v2))
let result = try f.run(["volume", "prune"]).check()
#expect(result.output.contains(v1))
#expect(result.output.contains(v2))
#expect(result.error.contains("Reclaimed"))
let listAfter = try f.run(["volume", "list", "--quiet"]).check().output
#expect(!listAfter.contains(v1) && !listAfter.contains(v2))
}
}
@Test func testVolumePruneSkipsVolumeInUse() async throws {
try await ContainerFixture.with { f in
let vInUse = "\(f.testID)-inuse"
let vUnused = "\(f.testID)-unused"
let c = "\(f.testID)-c1"
try f.doPull(alpine)
let image = alpine
f.addCleanup {
try? f.doStop(c)
try? f.doRemoveIfExists(c, force: true, ignoreFailure: true)
f.doVolumeDeleteIfExists(vInUse)
f.doVolumeDeleteIfExists(vUnused)
}
try f.doVolumeCreate(vInUse)
try f.doVolumeCreate(vUnused)
try f.doLongRun(name: c, image: image, args: ["-v", "\(vInUse):/data"], autoRemove: false)
try await f.waitForContainerRunning(c)
try f.run(["volume", "prune"]).check()
let listAfter = try f.run(["volume", "list", "--quiet"]).check().output
#expect(listAfter.contains(vInUse), "in-use volume should NOT be pruned")
#expect(!listAfter.contains(vUnused), "unused volume should be pruned")
try f.doStop(c)
try? f.doRemoveIfExists(c, force: true, ignoreFailure: true)
f.doVolumeDeleteIfExists(vInUse)
}
}
@Test func testVolumePruneSkipsVolumeAttachedToStoppedContainer() async throws {
try await ContainerFixture.with { f in
let vol = "\(f.testID)-vol"
let c = "\(f.testID)-c1"
try f.doPull(alpine)
let image = alpine
f.addCleanup {
try? f.doRemoveIfExists(c, force: true, ignoreFailure: true)
f.doVolumeDeleteIfExists(vol)
}
try f.doVolumeCreate(vol)
try f.doCreate(name: c, image: image, volumes: ["\(vol):/data"])
try await Task.sleep(for: .seconds(1))
try f.run(["volume", "prune"]).check()
#expect(try f.volumeExists(vol), "volume attached to stopped container should NOT be pruned")
try? f.doRemoveIfExists(c, force: true, ignoreFailure: true)
try f.run(["volume", "prune"]).check()
#expect(!(try f.volumeExists(vol)), "volume should be pruned after container is deleted")
}
}
}