Skip to content

Commit f0b2b96

Browse files
authored
Use enum for warmup images. (#1990)
- Closes #1982. - Makes warmup image code more readable in tests.
1 parent 968dbe4 commit f0b2b96

29 files changed

Lines changed: 121 additions & 106 deletions

Sources/ContainerTestSupport/ContainerFixture+ContainerHelpers.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ extension ContainerFixture {
5757
autoRemove: Bool = true,
5858
containerEnv: [String: String] = [:]
5959
) throws {
60-
let imageRef = image ?? ContainerFixture.warmupImages[0]
60+
let imageRef = image ?? WarmupImage.alpine320.rawValue
6161
var runArgs = ["run"]
6262
if autoRemove { runArgs.append("--rm") }
6363
runArgs += ["--name", name, "-d"]
@@ -78,7 +78,7 @@ extension ContainerFixture {
7878
networks: [String] = [],
7979
ports: [String] = []
8080
) throws {
81-
let imageRef = image ?? ContainerFixture.warmupImages[0]
81+
let imageRef = image ?? WarmupImage.alpine320.rawValue
8282
var createArgs = ["create", "--rm", "--name", name]
8383
createArgs += proxyEnvironmentArgs
8484
for v in volumes { createArgs += ["-v", v] }

Sources/ContainerTestSupport/ContainerFixture.swift

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -59,16 +59,6 @@ import Testing
5959
/// pattern the structured helpers don't cover.
6060
public final class ContainerFixture: Sendable {
6161

62-
// MARK: - Configuration
63-
64-
/// Images preloaded by the ``ImageWarmup`` suite before concurrent tests run.
65-
/// Add new commonly-used images here; the warmup pass pulls them in parallel.
66-
public static let warmupImages: [String] = [
67-
"ghcr.io/linuxcontainers/alpine:3.20",
68-
"ghcr.io/linuxcontainers/alpine:3.18",
69-
"ghcr.io/containerd/busybox:1.36",
70-
]
71-
7262
// MARK: - State
7363

7464
/// Short random identifier prefixed to every resource this test creates.
@@ -249,7 +239,8 @@ public final class ContainerFixture: Sendable {
249239
/// The returned name is `{testID}-{imageName}:{tag}`, e.g.
250240
/// `a3f7c2b1-alpine:3.20`. Tests operate freely on this reference;
251241
/// the canonical warmup image is never touched.
252-
public func copyWarmupImage(_ canonical: String) throws -> String {
242+
public func copyWarmupImage(_ image: WarmupImage) throws -> String {
243+
let canonical = image.rawValue
253244
let lastComponent = canonical.split(separator: "/").last.map(String.init) ?? canonical
254245
let parts = lastComponent.split(separator: ":", maxSplits: 1)
255246
let name = String(parts[0])
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//===----------------------------------------------------------------------===//
2+
// Copyright © 2026 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+
/// Images preloaded by the ``ImageWarmup`` suite before concurrent tests run.
18+
/// Add new commonly-used images here; the warmup pass pulls them in parallel.
19+
public enum WarmupImage: String, CaseIterable, Sendable {
20+
case alpine320 = "ghcr.io/linuxcontainers/alpine:3.20"
21+
case alpine318 = "ghcr.io/linuxcontainers/alpine:3.18"
22+
case busybox136 = "ghcr.io/containerd/busybox:1.36"
23+
}

Tests/IntegrationTests/Build/TestCLIBuilderSerial.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -876,7 +876,7 @@ struct TestCLIBuilderSerial {
876876
let dir = try f.createTempDir()
877877
try f.createContext(
878878
dir: dir,
879-
dockerfile: "FROM \(ContainerFixture.warmupImages[0])\nADD emptyFile /",
879+
dockerfile: "FROM \(WarmupImage.alpine320.rawValue)\nADD emptyFile /",
880880
context: [.file("emptyFile", content: .zeroFilled(size: 1))])
881881
let image = "registry.local/no-cache-pull:\(UUID().uuidString)"
882882
try f.buildWithPaths(tags: [image], contextDir: dir, otherArgs: ["--pull", "--no-cache"])

Tests/IntegrationTests/Containers/TestCLICopyCommand.swift

Lines changed: 35 additions & 35 deletions
Large diffs are not rendered by default.

Tests/IntegrationTests/Containers/TestCLICreateCommand.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import Testing
2323
struct TestCLICreateCommand {
2424
@Test func testCreateArgsPassthrough() async throws {
2525
try await ContainerFixture.with { f in
26-
let image = try f.copyWarmupImage(ContainerFixture.warmupImages[0])
26+
let image = try f.copyWarmupImage(.alpine320)
2727
let name = "\(f.testID)-c"
2828
try f.doCreate(name: name, image: image, args: ["echo", "-n", "hello", "world"])
2929
try f.doRemove(name)
@@ -32,7 +32,7 @@ struct TestCLICreateCommand {
3232

3333
@Test func testCreateWithMACAddress() async throws {
3434
try await ContainerFixture.with { f in
35-
let image = try f.copyWarmupImage(ContainerFixture.warmupImages[0])
35+
let image = try f.copyWarmupImage(.alpine320)
3636
let name = "\(f.testID)-c"
3737
let expectedMAC = try MACAddress("02:42:ac:11:00:03")
3838

@@ -52,7 +52,7 @@ struct TestCLICreateCommand {
5252

5353
@Test func testPublishPortParserMaxPorts() async throws {
5454
try await ContainerFixture.with { f in
55-
let image = try f.copyWarmupImage(ContainerFixture.warmupImages[0])
55+
let image = try f.copyWarmupImage(.alpine320)
5656
let name = "\(f.testID)-c"
5757
var args: [String] = ["create", "--name", name]
5858
for i in 0..<64 {
@@ -68,7 +68,7 @@ struct TestCLICreateCommand {
6868

6969
@Test func testPublishPortParserTooManyPorts() async throws {
7070
try await ContainerFixture.with { f in
71-
let image = try f.copyWarmupImage(ContainerFixture.warmupImages[0])
71+
let image = try f.copyWarmupImage(.alpine320)
7272
let name = "\(f.testID)-c"
7373
var args: [String] = ["create", "--name", name]
7474
for i in 0..<65 {
@@ -84,7 +84,7 @@ struct TestCLICreateCommand {
8484

8585
@Test func testCreateWithFQDNName() async throws {
8686
try await ContainerFixture.with { f in
87-
let image = try f.copyWarmupImage(ContainerFixture.warmupImages[0])
87+
let image = try f.copyWarmupImage(.alpine320)
8888
// Prefix with testID to avoid name collisions; hostname is the first FQDN component.
8989
let name = "\(f.testID).example.com"
9090
let expectedHostname = f.testID

Tests/IntegrationTests/Containers/TestCLIExecCommand.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import Testing
2121
struct TestCLIExecCommand {
2222
@Test func testCreateExecCommand() async throws {
2323
try await ContainerFixture.with { f in
24-
let image = try f.copyWarmupImage(ContainerFixture.warmupImages[0])
24+
let image = try f.copyWarmupImage(.alpine320)
2525
let name = "\(f.testID)-c"
2626
try f.doCreate(name: name, image: image)
2727
f.addCleanup { try? f.doStop(name) }
@@ -36,7 +36,7 @@ struct TestCLIExecCommand {
3636

3737
@Test func testExecDetach() async throws {
3838
try await ContainerFixture.with { f in
39-
let image = try f.copyWarmupImage(ContainerFixture.warmupImages[0])
39+
let image = try f.copyWarmupImage(.alpine320)
4040
let name = "\(f.testID)-c"
4141
try f.doCreate(name: name, image: image)
4242
f.addCleanup { try? f.doStop(name) }
@@ -70,7 +70,7 @@ struct TestCLIExecCommand {
7070

7171
@Test func testExecDetachProcessRunning() async throws {
7272
try await ContainerFixture.with { f in
73-
let image = try f.copyWarmupImage(ContainerFixture.warmupImages[0])
73+
let image = try f.copyWarmupImage(.alpine320)
7474
let name = "\(f.testID)-c"
7575
try f.doCreate(name: name, image: image)
7676
f.addCleanup { try? f.doStop(name) }
@@ -92,7 +92,7 @@ struct TestCLIExecCommand {
9292

9393
@Test func testExecOnExitingContainer() async throws {
9494
try await ContainerFixture.with { f in
95-
let image = try f.copyWarmupImage(ContainerFixture.warmupImages[0])
95+
let image = try f.copyWarmupImage(.alpine320)
9696
let name = "\(f.testID)-c"
9797
// sh exits immediately in detached mode with no stdin; container stops on its own.
9898
try f.doLongRun(name: name, image: image, containerArgs: ["sh"], autoRemove: false)

Tests/IntegrationTests/Containers/TestCLIExportCommand.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import Testing
2323
struct TestCLIExportCommand {
2424
@Test func testExportCommand() async throws {
2525
try await ContainerFixture.with { f in
26-
let image = try f.copyWarmupImage(ContainerFixture.warmupImages[0])
26+
let image = try f.copyWarmupImage(.alpine320)
2727
try await f.withContainer(image: image, autoRemove: false) { name in
2828
let mustBeInImage = "must-be-in-image"
2929
try f.doExec(name, cmd: ["sh", "-c", "echo \(mustBeInImage) > /foo"])

Tests/IntegrationTests/Containers/TestCLIPruneCommandSerial.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ struct TestCLIPruneCommandSerial {
3737

3838
@Test func testContainerPruneStoppedContainers() async throws {
3939
try await ContainerFixture.with { f in
40-
let image = ContainerFixture.warmupImages[0]
40+
let image = WarmupImage.alpine320.rawValue
4141
if try !f.isImagePresent(image) { try f.doPull(image) }
4242

4343
// One running container that must survive the prune.

Tests/IntegrationTests/Containers/TestCLIRemove.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import Testing
2323
struct TestCLIRemove {
2424
@Test func testDeleteStopped() async throws {
2525
try await ContainerFixture.with { f in
26-
let image = try f.copyWarmupImage(ContainerFixture.warmupImages[0])
26+
let image = try f.copyWarmupImage(.alpine320)
2727
let name = "\(f.testID)-c"
2828
// create without --rm so the container persists after being stopped
2929
try f.doCreate(name: name, image: image)
@@ -35,7 +35,7 @@ struct TestCLIRemove {
3535

3636
@Test func testDeleteAlias() async throws {
3737
try await ContainerFixture.with { f in
38-
let image = try f.copyWarmupImage(ContainerFixture.warmupImages[0])
38+
let image = try f.copyWarmupImage(.alpine320)
3939
let name = "\(f.testID)-c"
4040
try f.doCreate(name: name, image: image)
4141
try f.run(["rm", name]).check("rm alias failed")
@@ -46,7 +46,7 @@ struct TestCLIRemove {
4646

4747
@Test func testDeleteForceRunning() async throws {
4848
try await ContainerFixture.with { f in
49-
let image = try f.copyWarmupImage(ContainerFixture.warmupImages[0])
49+
let image = try f.copyWarmupImage(.alpine320)
5050
try await f.withContainer(image: image) { name in
5151
try f.doRemove(name, force: true)
5252
let result = try f.run(["inspect", name])
@@ -72,7 +72,7 @@ struct TestCLIRemove {
7272

7373
@Test func testDeleteDuplicateIds() async throws {
7474
try await ContainerFixture.with { f in
75-
let image = try f.copyWarmupImage(ContainerFixture.warmupImages[0])
75+
let image = try f.copyWarmupImage(.alpine320)
7676
let name = "\(f.testID)-c"
7777
try f.doCreate(name: name, image: image)
7878
f.addCleanup { try f.doRemoveIfExists(name, force: true, ignoreFailure: true) }

0 commit comments

Comments
 (0)