Skip to content

Commit d6379bf

Browse files
committed
Add container prune testcases
Signed-off-by: ChengHao Yang <17496418+tico88612@users.noreply.github.com>
1 parent e64377f commit d6379bf

File tree

2 files changed

+87
-0
lines changed

2 files changed

+87
-0
lines changed

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ integration: init-block
176176
$(SWIFT) test -c $(BUILD_CONFIGURATION) $(SWIFT_CONFIGURATION) --filter TestCLIExecCommand || exit_code=1 ; \
177177
$(SWIFT) test -c $(BUILD_CONFIGURATION) $(SWIFT_CONFIGURATION) --filter TestCLICreateCommand || exit_code=1 ; \
178178
$(SWIFT) test -c $(BUILD_CONFIGURATION) $(SWIFT_CONFIGURATION) --filter TestCLIRunCommand || exit_code=1 ; \
179+
$(SWIFT) test -c $(BUILD_CONFIGURATION) $(SWIFT_CONFIGURATION) --filter TestCLIPruneCommand || exit_code=1 ; \
179180
$(SWIFT) test -c $(BUILD_CONFIGURATION) $(SWIFT_CONFIGURATION) --filter TestCLIStatsCommand || exit_code=1 ; \
180181
$(SWIFT) test -c $(BUILD_CONFIGURATION) $(SWIFT_CONFIGURATION) --filter TestCLIImagesCommand || exit_code=1 ; \
181182
$(SWIFT) test -c $(BUILD_CONFIGURATION) $(SWIFT_CONFIGURATION) --filter TestCLIRunBase || exit_code=1 ; \
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
//===----------------------------------------------------------------------===//
2+
// Copyright © 2025 Apple Inc. and the container project authors.
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// https://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
//===----------------------------------------------------------------------===//
16+
17+
import Foundation
18+
import Testing
19+
20+
@Suite(.serialized)
21+
class TestCLIPruneCommand: CLITest {
22+
private func getTestName() -> String {
23+
Test.current!.name.trimmingCharacters(in: ["(", ")"]).lowercased()
24+
}
25+
26+
@Test func testContainerPruneNoContainers() throws {
27+
let (_, output, error, status) = try run(arguments: ["prune"])
28+
if status != 0 {
29+
throw CLIError.executionFailed("container prune failed: \(error)")
30+
}
31+
32+
#expect(output.contains("No containers to prune"), "should show no containers message")
33+
}
34+
35+
@Test func testContainerPruneStoppedContainers() throws {
36+
let testName = getTestName()
37+
let npcName = "\(testName)_wont_be_pruned"
38+
let pc0Name = "\(testName)_pruned_0"
39+
let pc1Name = "\(testName)_pruned_1"
40+
41+
try doLongRun(name: npcName, containerArgs: ["sleep", "3600"], autoRemove: true)
42+
try doLongRun(name: pc0Name, containerArgs: ["sleep", "3600"], autoRemove: false)
43+
try doLongRun(name: pc1Name, containerArgs: ["sleep", "3600"], autoRemove: false)
44+
defer {
45+
try? doStop(name: npcName)
46+
try? doStop(name: pc0Name)
47+
try? doStop(name: pc1Name)
48+
try? doRemove(name: npcName)
49+
try? doRemove(name: pc0Name)
50+
try? doRemove(name: pc1Name)
51+
}
52+
try waitForContainerRunning(npcName)
53+
try waitForContainerRunning(pc0Name)
54+
try waitForContainerRunning(pc1Name)
55+
56+
try doStop(name: pc0Name)
57+
try doStop(name: pc1Name)
58+
59+
// Poll status until both containers are stopped, with interval checks and a timeout to avoid infinite loop
60+
let start = Date()
61+
let timeout: TimeInterval = 30 // seconds
62+
while true {
63+
let s0 = try getContainerStatus(pc0Name)
64+
let s1 = try getContainerStatus(pc1Name)
65+
if s0 == "stopped" && s1 == "stopped" { break }
66+
if Date().timeIntervalSince(start) > timeout {
67+
throw CLIError.executionFailed("Timeout waiting for containers to stop: pc0=\(s0), pc1=\(s1)")
68+
}
69+
Thread.sleep(forTimeInterval: 0.2)
70+
}
71+
72+
let (_, output, error, status) = try run(arguments: ["prune"])
73+
74+
if status != 0 {
75+
throw CLIError.executionFailed("container prune failed: \(error)")
76+
}
77+
78+
let lines = output.components(separatedBy: .newlines)
79+
80+
#expect(lines.count >= 5, "should have at least 5 lines included header, 2 lines, 1 empty line and 1 line space reclaimed")
81+
#expect(output.contains("Pruned containers"), "should remove the stopped containers and show no space reclaimed or no containers message")
82+
83+
let checkStatus = try getContainerStatus(npcName)
84+
#expect(checkStatus == "running", "not pruned container should still be running")
85+
}
86+
}

0 commit comments

Comments
 (0)