Files
Kathryn Baldauf 4a79060595 Ensure test filenames match test suite names and each file has a single suite defined (#1877)
This PR cleans up some of the new IntegrationTests files to ensure that
each file has a single test suite defined within it and the name of the
file matches the name of the test suite.

Signed-off-by: Kathryn Baldauf <k_baldauf@apple.com>
2026-07-01 16:03:03 -07:00

116 lines
4.9 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 Testing
@Suite
struct TestCLIExecCommand {
@Test func testCreateExecCommand() async throws {
try await ContainerFixture.with { f in
let image = try f.copyWarmupImage(ContainerFixture.warmupImages[0])
let name = "\(f.testID)-c"
try f.doCreate(name: name, image: image)
f.addCleanup { try? f.doStop(name) }
try f.doStart(name)
try await f.waitForContainerRunning(name)
let uname = try f.doExec(name, cmd: ["uname"])
.trimmingCharacters(in: .whitespacesAndNewlines)
#expect(uname == "Linux", "expected OS to be Linux, got \(uname)")
try f.doStop(name)
}
}
@Test func testExecDetach() async throws {
try await ContainerFixture.with { f in
let image = try f.copyWarmupImage(ContainerFixture.warmupImages[0])
let name = "\(f.testID)-c"
try f.doCreate(name: name, image: image)
f.addCleanup { try? f.doStop(name) }
try f.doStart(name)
try await f.waitForContainerRunning(name)
let output = try f.doExec(name, cmd: ["sh", "-c", "touch /tmp/detach_test_marker"], detach: true)
try #require(
output.trimmingCharacters(in: .whitespacesAndNewlines) == name,
"exec --detach should print the container name")
let ls = try f.doExec(name, cmd: ["ls", "/"])
.trimmingCharacters(in: .whitespacesAndNewlines)
try #require(ls.contains("tmp"), "container should still be running after detached exec")
// Retry until the detached process creates the marker file.
var markerFound = false
for _ in 0..<3 {
let result = try f.run(["exec", name, "test", "-f", "/tmp/detach_test_marker"])
if result.status == 0 {
markerFound = true
break
}
try await Task.sleep(for: .seconds(1))
}
try #require(markerFound, "marker file should be created by detached process within 3 seconds")
try f.doStop(name)
}
}
@Test func testExecDetachProcessRunning() async throws {
try await ContainerFixture.with { f in
let image = try f.copyWarmupImage(ContainerFixture.warmupImages[0])
let name = "\(f.testID)-c"
try f.doCreate(name: name, image: image)
f.addCleanup { try? f.doStop(name) }
try f.doStart(name)
try await f.waitForContainerRunning(name)
let output = try f.doExec(name, cmd: ["sleep", "10"], detach: true)
try #require(
output.trimmingCharacters(in: .whitespacesAndNewlines) == name,
"exec --detach should print the container name")
let ps = try f.doExec(name, cmd: ["ps", "aux"])
.trimmingCharacters(in: .whitespacesAndNewlines)
try #require(ps.contains("sleep 10"), "detached 'sleep 10' should appear in ps output")
try f.doStop(name)
}
}
@Test func testExecOnExitingContainer() async throws {
try await ContainerFixture.with { f in
let image = try f.copyWarmupImage(ContainerFixture.warmupImages[0])
let name = "\(f.testID)-c"
// sh exits immediately in detached mode with no stdin; container stops on its own.
try f.doLongRun(name: name, image: image, containerArgs: ["sh"], autoRemove: false)
f.addCleanup { try? f.doRemove(name) }
try await Task.sleep(for: .seconds(1))
try f.doStart(name)
let execResult = try f.run(["exec", name, "sleep", "infinity"])
if execResult.status != 0 {
#expect(
execResult.error.contains("is not running")
|| execResult.error.contains("failed to create process"),
"expected 'not running' error, got: \(execResult.error)")
}
try await Task.sleep(for: .seconds(1))
// Container should still exist even if exec failed.
_ = try f.getContainerStatus(name)
}
}
}