Files
container/Tests/ContainerizationOCITests/OCISpecTests.swift
T
Kathryn Baldauf a27fefbb59 Add custom decoder inits for various oci types that use omitempty (#347)
Many fields on the various OCI types use "omitempty" for encoding and
decoding the json representation in golang. This PR adds custom json
decoder functions to allow for behavior similar to "omitempty".

---------

Signed-off-by: Kathryn Baldauf <k_baldauf@apple.com>
2025-10-24 15:05:40 -07:00

147 lines
4.9 KiB
Swift

//===----------------------------------------------------------------------===//
// Copyright © 2025 Apple Inc. and the Containerization 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
@testable import ContainerizationOCI
struct OCISpecTests {
@Test func minimalSpecDecode() throws {
let version = "1.2.3"
let minSpec =
"""
{
"ociVersion": "\(version)"
}
"""
guard let data = minSpec.data(using: .utf8) else {
Issue.record("test spec is not valid: \(minSpec)")
return
}
let decodedSpec = try JSONDecoder().decode(ContainerizationOCI.Spec.self, from: data)
#expect(decodedSpec.version == version)
#expect(decodedSpec.hooks == nil)
#expect(decodedSpec.process == nil)
#expect(decodedSpec.hostname == "")
#expect(decodedSpec.domainname == "")
#expect(decodedSpec.mounts.isEmpty)
#expect(decodedSpec.annotations == nil)
#expect(decodedSpec.root == nil)
#expect(decodedSpec.linux == nil)
}
@Test func minimalProcessSpecDecode() throws {
let cwd = "/test"
let minProcessSpec =
"""
{
"cwd": "\(cwd)",
"user": {
"uid": 10,
"gid": 11
}
}
"""
guard let data = minProcessSpec.data(using: .utf8) else {
Issue.record("test process spec is not valid: \(minProcessSpec)")
return
}
let decodedSpec = try JSONDecoder().decode(ContainerizationOCI.Process.self, from: data)
#expect(decodedSpec.cwd == cwd)
#expect(decodedSpec.env.isEmpty)
#expect(decodedSpec.consoleSize == nil)
#expect(decodedSpec.selinuxLabel == "")
#expect(decodedSpec.noNewPrivileges == false)
#expect(decodedSpec.commandLine == "")
#expect(decodedSpec.oomScoreAdj == nil)
#expect(decodedSpec.capabilities == nil)
#expect(decodedSpec.apparmorProfile == "")
#expect(decodedSpec.user.uid == 10)
#expect(decodedSpec.user.gid == 11)
#expect(decodedSpec.rlimits.isEmpty)
#expect(decodedSpec.terminal == false)
}
@Test func minimalUserSpecDecode() throws {
let minUserSpec =
"""
{
"uid": 10,
"gid": 11
}
"""
guard let data = minUserSpec.data(using: .utf8) else {
Issue.record("test user spec is not valid: \(minUserSpec)")
return
}
let decodedSpec = try JSONDecoder().decode(ContainerizationOCI.User.self, from: data)
#expect(decodedSpec.uid == 10)
#expect(decodedSpec.gid == 11)
#expect(decodedSpec.umask == nil)
#expect(decodedSpec.additionalGids.isEmpty)
#expect(decodedSpec.username == "")
}
@Test func minimalRootSpecDecode() throws {
let path = "/testpath"
let minRootSpec =
"""
{
"path": "\(path)"
}
"""
guard let data = minRootSpec.data(using: .utf8) else {
Issue.record("test root spec is not valid: \(minRootSpec)")
return
}
let decodedSpec = try JSONDecoder().decode(ContainerizationOCI.Root.self, from: data)
#expect(decodedSpec.path == path)
#expect(decodedSpec.readonly == false)
}
@Test func minimalMountSpecDecode() throws {
let destination = "/testdest"
let minMountSpec =
"""
{
"destination": "\(destination)"
}
"""
guard let data = minMountSpec.data(using: .utf8) else {
Issue.record("test mount spec is not valid: \(minMountSpec)")
return
}
let decodedSpec = try JSONDecoder().decode(ContainerizationOCI.Mount.self, from: data)
#expect(decodedSpec.type == "")
#expect(decodedSpec.source == "")
#expect(decodedSpec.destination == destination)
#expect(decodedSpec.options.isEmpty)
#expect(decodedSpec.uidMappings.isEmpty)
#expect(decodedSpec.gidMappings.isEmpty)
}
}