Skip to content

Commit f92c0cd

Browse files
authored
containerization: Add additional tests (#273)
Add additional tests, with varying levels of utility. Before: Overall Code Coverage: 41.73% After: Overall Code Coverage: 42.95% Signed-off-by: Eric Ernst <[email protected]>
1 parent 4099bdc commit f92c0cd

File tree

7 files changed

+325
-0
lines changed

7 files changed

+325
-0
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
//===----------------------------------------------------------------------===//
2+
// Copyright © 2025 Apple Inc. and the Containerization project authors. All rights reserved.
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+
@testable import Containerization
21+
22+
struct DNSTests {
23+
24+
@Test func dnsResolvConfWithAllFields() {
25+
let dns = DNS(
26+
nameservers: ["8.8.8.8", "1.1.1.1"],
27+
domain: "example.com",
28+
searchDomains: ["internal.com", "test.com"],
29+
options: ["ndots:2", "timeout:1"]
30+
)
31+
32+
let expected = "nameserver 8.8.8.8\nnameserver 1.1.1.1\ndomain example.com\nsearch internal.com test.com\nopts ndots:2 timeout:1\n"
33+
#expect(dns.resolvConf == expected)
34+
}
35+
36+
@Test func dnsResolvConfWithEmptyFields() {
37+
let dns = DNS(
38+
nameservers: [],
39+
domain: nil,
40+
searchDomains: [],
41+
options: []
42+
)
43+
44+
// Should return empty string when all fields are empty
45+
#expect(dns.resolvConf == "")
46+
}
47+
48+
@Test func dnsResolvConfWithOnlyNameservers() {
49+
let dns = DNS(nameservers: ["8.8.8.8"])
50+
51+
let expected = "nameserver 8.8.8.8\n"
52+
#expect(dns.resolvConf == expected)
53+
}
54+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
//===----------------------------------------------------------------------===//
2+
// Copyright © 2025 Apple Inc. and the Containerization project authors. All rights reserved.
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+
@testable import Containerization
21+
22+
struct HashTests {
23+
24+
@Test func hashMountSourceWithValidString() throws {
25+
let result = try hashMountSource(source: "/valid/path")
26+
27+
// Should produce a non-empty hash
28+
#expect(!result.isEmpty)
29+
30+
// Same input should produce same hash (deterministic)
31+
let result2 = try hashMountSource(source: "/valid/path")
32+
#expect(result == result2)
33+
34+
// Different inputs should produce different hashes
35+
let result3 = try hashMountSource(source: "/different/path")
36+
#expect(result != result3)
37+
}
38+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
//===----------------------------------------------------------------------===//
2+
// Copyright © 2025 Apple Inc. and the Containerization project authors. All rights reserved.
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+
@testable import Containerization
21+
22+
struct HostsTests {
23+
24+
@Test func hostsEntryRenderedWithAllFields() {
25+
let entry = Hosts.Entry(
26+
ipAddress: "192.168.1.100",
27+
hostnames: ["myserver", "server.local"],
28+
comment: "My local server"
29+
)
30+
31+
let expected = "192.168.1.100 myserver server.local # My local server "
32+
#expect(entry.rendered == expected)
33+
}
34+
35+
@Test func hostsEntryRenderedWithoutComment() {
36+
let entry = Hosts.Entry(
37+
ipAddress: "10.0.0.1",
38+
hostnames: ["gateway"]
39+
)
40+
41+
let expected = "10.0.0.1 gateway"
42+
#expect(entry.rendered == expected)
43+
}
44+
45+
@Test func hostsEntryRenderedWithEmptyHostnames() {
46+
let entry = Hosts.Entry(
47+
ipAddress: "172.16.0.1",
48+
hostnames: [],
49+
comment: "Empty hostnames"
50+
)
51+
52+
let expected = "172.16.0.1 # Empty hostnames "
53+
#expect(entry.rendered == expected)
54+
}
55+
56+
@Test func hostsFileWithCommentAndEntries() {
57+
let hosts = Hosts(
58+
entries: [
59+
Hosts.Entry(ipAddress: "127.0.0.1", hostnames: ["localhost"]),
60+
Hosts.Entry(ipAddress: "192.168.1.10", hostnames: ["server"], comment: "Main server"),
61+
],
62+
comment: "Generated hosts file"
63+
)
64+
65+
let expected = "# Generated hosts file\n127.0.0.1 localhost\n192.168.1.10 server # Main server \n"
66+
#expect(hosts.hostsFile == expected)
67+
}
68+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
//===----------------------------------------------------------------------===//
2+
// Copyright © 2025 Apple Inc. and the Containerization project authors. All rights reserved.
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 ContainerizationOCI
18+
import Foundation
19+
import Testing
20+
21+
@testable import Containerization
22+
23+
struct ImageTests {
24+
25+
@Test func imageDescriptionComputedProperties() {
26+
let descriptor = Descriptor(
27+
mediaType: "application/vnd.oci.image.manifest.v1+json",
28+
digest: "sha256:abc123def456",
29+
size: 1024
30+
)
31+
let description = Image.Description(reference: "myapp:latest", descriptor: descriptor)
32+
33+
#expect(description.digest == "sha256:abc123def456")
34+
#expect(description.mediaType == "application/vnd.oci.image.manifest.v1+json")
35+
#expect(description.reference == "myapp:latest")
36+
}
37+
}

Tests/ContainerizationTests/KernelTests.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,20 @@ final class KernelTests {
3939
let cmdline = kernel.commandLine.kernelArgs.joined(separator: " ")
4040
#expect(cmdline == expected)
4141
}
42+
43+
@Test func kernelCommandLineInitWithDebugTrue() {
44+
let commandLine = Kernel.CommandLine(debug: true, panic: 5, initArgs: ["--verbose"])
45+
46+
#expect(commandLine.kernelArgs == ["console=hvc0", "tsc=reliable", "debug", "panic=5"])
47+
#expect(commandLine.initArgs == ["--verbose"])
48+
}
49+
50+
@Test func kernelCommandLineMutatingMethods() {
51+
var commandLine = Kernel.CommandLine(kernelArgs: ["console=hvc0"], initArgs: [])
52+
53+
commandLine.addDebug()
54+
commandLine.addPanic(level: 10)
55+
56+
#expect(commandLine.kernelArgs == ["console=hvc0", "debug", "panic=10"])
57+
}
4258
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
//===----------------------------------------------------------------------===//
2+
// Copyright © 2025 Apple Inc. and the Containerization project authors. All rights reserved.
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 ContainerizationOCI
18+
import Foundation
19+
import Testing
20+
21+
@testable import Containerization
22+
23+
struct LinuxContainerTests {
24+
25+
@Test func processInitFromImageConfigWithAllFields() {
26+
let imageConfig = ImageConfig(
27+
user: "appuser",
28+
env: ["NODE_ENV=production", "PORT=3000"],
29+
entrypoint: ["/usr/bin/node"],
30+
cmd: ["app.js", "--verbose"],
31+
workingDir: "/app"
32+
)
33+
34+
let process = LinuxContainer.Configuration.Process(from: imageConfig)
35+
36+
#expect(process.workingDirectory == "/app")
37+
#expect(process.environmentVariables == ["NODE_ENV=production", "PORT=3000"])
38+
#expect(process.arguments == ["/usr/bin/node", "app.js", "--verbose"])
39+
#expect(process.user.username == "appuser")
40+
}
41+
42+
@Test func processInitFromImageConfigWithNilValues() {
43+
let imageConfig = ImageConfig(
44+
user: nil,
45+
env: nil,
46+
entrypoint: nil,
47+
cmd: nil,
48+
workingDir: nil
49+
)
50+
51+
let process = LinuxContainer.Configuration.Process(from: imageConfig)
52+
53+
#expect(process.workingDirectory == "/")
54+
#expect(process.environmentVariables == [])
55+
#expect(process.arguments == [])
56+
#expect(process.user.username == "") // Default User() has empty string username
57+
}
58+
59+
@Test func processInitFromImageConfigEntrypointAndCmdConcatenation() {
60+
let imageConfig = ImageConfig(
61+
entrypoint: ["/bin/sh", "-c"],
62+
cmd: ["echo 'hello'", "&&", "sleep 10"]
63+
)
64+
65+
let process = LinuxContainer.Configuration.Process(from: imageConfig)
66+
67+
#expect(process.arguments == ["/bin/sh", "-c", "echo 'hello'", "&&", "sleep 10"])
68+
}
69+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
//===----------------------------------------------------------------------===//
2+
// Copyright © 2025 Apple Inc. and the Containerization project authors. All rights reserved.
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+
@testable import Containerization
21+
22+
struct MountTests {
23+
24+
@Test func mountShareCreatesVirtiofsMount() {
25+
let mount = Mount.share(
26+
source: "/host/shared",
27+
destination: "/guest/shared",
28+
options: ["rw", "noatime"],
29+
runtimeOptions: ["tag=shared"]
30+
)
31+
32+
#expect(mount.type == "virtiofs")
33+
#expect(mount.source == "/host/shared")
34+
#expect(mount.destination == "/guest/shared")
35+
#expect(mount.options == ["rw", "noatime"])
36+
37+
if case .virtiofs(let opts) = mount.runtimeOptions {
38+
#expect(opts == ["tag=shared"])
39+
} else {
40+
#expect(Bool(false), "Expected virtiofs runtime options")
41+
}
42+
}
43+
}

0 commit comments

Comments
 (0)