//===----------------------------------------------------------------------===// // Copyright © 2025-2026 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 Testing @testable import ContainerizationExtras struct BufferTest { // MARK: - hexEncodedString Tests @Test func testArrayHexEncodedStringEmpty() { let buffer: [UInt8] = [] #expect(buffer.hexEncodedString() == "") } @Test func testArrayHexEncodedStringSingleByte() { let buffer: [UInt8] = [0xFF] #expect(buffer.hexEncodedString() == "ff") } @Test func testArrayHexEncodedStringMultipleBytes() { let buffer: [UInt8] = [0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF] #expect(buffer.hexEncodedString() == "0123456789abcdef") } @Test func testArrayHexEncodedStringZeroes() { let buffer: [UInt8] = [0x00, 0x00, 0x00] #expect(buffer.hexEncodedString() == "000000") } @Test func testArraySliceHexEncodedStringEmpty() { let buffer: [UInt8] = [0x01, 0x02, 0x03] let slice = buffer[0..<0] #expect(slice.hexEncodedString() == "") } @Test func testArraySliceHexEncodedStringSingleByte() { let buffer: [UInt8] = [0x01, 0x02, 0x03] let slice = buffer[1..<2] #expect(slice.hexEncodedString() == "02") } @Test func testArraySliceHexEncodedStringMultipleBytes() { let buffer: [UInt8] = [0x00, 0xAA, 0xBB, 0xCC, 0x00] let slice = buffer[1..<4] #expect(slice.hexEncodedString() == "aabbcc") } // MARK: - bind Tests @Test func testBufferBind() throws { let expectedValue: UInt64 = 0x0102_0304_0506_0708 let expectedBuffer: [UInt8] = [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, ] var buffer = [UInt8](repeating: 0, count: 3 * MemoryLayout.size) guard let ptr = buffer.bind(as: UInt64.self, offset: 2 * MemoryLayout.size) else { #expect(Bool(false), "could not bind value to buffer") return } ptr.pointee = expectedValue #expect(buffer == expectedBuffer) } @Test func testBufferBindZeroOffset() { let expectedValue: UInt32 = 0x1234_5678 var buffer = [UInt8](repeating: 0, count: 8) guard let ptr = buffer.bind(as: UInt32.self, offset: 0) else { #expect(Bool(false), "could not bind value to buffer at offset 0") return } ptr.pointee = expectedValue #expect(buffer[0] == 0x78) #expect(buffer[1] == 0x56) #expect(buffer[2] == 0x34) #expect(buffer[3] == 0x12) } @Test func testBufferBindRangeError() throws { var buffer = [UInt8](repeating: 0, count: 3 * MemoryLayout.size) #expect(buffer.bind(as: UInt64.self, offset: 2 * MemoryLayout.size + 1) == nil) } @Test func testBufferBindRangeErrorExactBoundary() { var buffer = [UInt8](repeating: 0, count: 8) // Trying to bind UInt64 at offset 1 requires 9 bytes total #expect(buffer.bind(as: UInt64.self, offset: 1) == nil) } @Test func testBufferBindWithCustomSize() { var buffer = [UInt8](repeating: 0, count: 16) // Request a size larger than the type guard let ptr = buffer.bind(as: UInt32.self, offset: 4, size: 8) else { #expect(Bool(false), "could not bind with custom size") return } ptr.pointee = 0xAABB_CCDD #expect(buffer[4] == 0xDD) #expect(buffer[5] == 0xCC) #expect(buffer[6] == 0xBB) #expect(buffer[7] == 0xAA) } @Test func testBufferBindWithCustomSizeRangeError() { var buffer = [UInt8](repeating: 0, count: 10) // Request size 8 at offset 4 would require 12 bytes total #expect(buffer.bind(as: UInt32.self, offset: 4, size: 8) == nil) } // MARK: - copyIn Tests @Test func testCopyInUInt8() { var buffer = [UInt8](repeating: 0, count: 4) let value: UInt8 = 0x42 guard let offset = buffer.copyIn(as: UInt8.self, value: value, offset: 2) else { #expect(Bool(false), "could not copy UInt8 to buffer") return } #expect(offset == 3) #expect(buffer[2] == 0x42) } @Test func testCopyInUInt16() { var buffer = [UInt8](repeating: 0, count: 8) let value: UInt16 = 0x1234 guard let offset = buffer.copyIn(as: UInt16.self, value: value, offset: 3) else { #expect(Bool(false), "could not copy UInt16 to buffer") return } #expect(offset == 5) #expect(buffer[3] == 0x34) #expect(buffer[4] == 0x12) } @Test func testCopyInUInt32() { var buffer = [UInt8](repeating: 0, count: 8) let value: UInt32 = 0x1234_5678 guard let offset = buffer.copyIn(as: UInt32.self, value: value, offset: 0) else { #expect(Bool(false), "could not copy UInt32 to buffer") return } #expect(offset == 4) #expect(buffer[0] == 0x78) #expect(buffer[1] == 0x56) #expect(buffer[2] == 0x34) #expect(buffer[3] == 0x12) } @Test func testCopyInUInt64() { var buffer = [UInt8](repeating: 0, count: 16) let value: UInt64 = 0x0102_0304_0506_0708 guard let offset = buffer.copyIn(as: UInt64.self, value: value, offset: 4) else { #expect(Bool(false), "could not copy UInt64 to buffer") return } #expect(offset == 12) #expect(buffer[4] == 0x08) #expect(buffer[5] == 0x07) #expect(buffer[6] == 0x06) #expect(buffer[7] == 0x05) #expect(buffer[8] == 0x04) #expect(buffer[9] == 0x03) #expect(buffer[10] == 0x02) #expect(buffer[11] == 0x01) } @Test func testCopyInRangeError() { var buffer = [UInt8](repeating: 0, count: 8) let value: UInt64 = 0x1234_5678_90AB_CDEF // Offset 4 + size 8 = 12, but buffer only has 8 bytes #expect(buffer.copyIn(as: UInt64.self, value: value, offset: 4) == nil) } @Test func testCopyInExactBoundary() { var buffer = [UInt8](repeating: 0, count: 8) let value: UInt64 = 0xFEDC_BA98_7654_3210 guard let offset = buffer.copyIn(as: UInt64.self, value: value, offset: 0) else { #expect(Bool(false), "could not copy UInt64 at exact boundary") return } #expect(offset == 8) } @Test func testCopyInWithCustomSize() { var buffer = [UInt8](repeating: 0, count: 16) let value: UInt32 = 0xAABB_CCDD // Copy with custom size of 8 (larger than UInt32's 4 bytes) guard let offset = buffer.copyIn(as: UInt32.self, value: value, offset: 2, size: 8) else { #expect(Bool(false), "could not copy with custom size") return } #expect(offset == 6) // offset + MemoryLayout.size #expect(buffer[2] == 0xDD) #expect(buffer[3] == 0xCC) #expect(buffer[4] == 0xBB) #expect(buffer[5] == 0xAA) } @Test func testCopyInWithCustomSizeRangeError() { var buffer = [UInt8](repeating: 0, count: 8) let value: UInt32 = 0x1234_5678 // Request size 8 at offset 2 would require 10 bytes total #expect(buffer.copyIn(as: UInt32.self, value: value, offset: 2, size: 8) == nil) } // MARK: - copyOut Tests @Test func testCopyOutUInt8() { let buffer: [UInt8] = [0x00, 0x11, 0x22, 0x33] guard let (offset, value) = buffer.copyOut(as: UInt8.self, offset: 2) else { #expect(Bool(false), "could not copy out UInt8") return } #expect(offset == 3) #expect(value == 0x22) } @Test func testCopyOutUInt16() { let buffer: [UInt8] = [0x00, 0x11, 0x22, 0x33, 0x44, 0x55] guard let (offset, value) = buffer.copyOut(as: UInt16.self, offset: 2) else { #expect(Bool(false), "could not copy out UInt16") return } #expect(offset == 4) #expect(value == 0x3322) } @Test func testCopyOutUInt32() { let buffer: [UInt8] = [0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0] guard let (offset, value) = buffer.copyOut(as: UInt32.self, offset: 0) else { #expect(Bool(false), "could not copy out UInt32") return } #expect(offset == 4) #expect(value == 0x7856_3412) } @Test func testCopyOutUInt64() { let buffer: [UInt8] = [ 0x00, 0x00, 0x00, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0xFF, 0xFF, ] guard let (offset, value) = buffer.copyOut(as: UInt64.self, offset: 4) else { #expect(Bool(false), "could not copy out UInt64") return } #expect(offset == 12) #expect(value == 0x8877_6655_4433_2211) } @Test func testCopyOutRangeError() { let buffer: [UInt8] = [0x00, 0x11, 0x22, 0x33] // Trying to read UInt64 from offset 0 with only 4 bytes #expect(buffer.copyOut(as: UInt64.self, offset: 0) == nil) } @Test func testCopyOutExactBoundary() { let buffer: [UInt8] = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08] guard let (offset, value) = buffer.copyOut(as: UInt64.self, offset: 0) else { #expect(Bool(false), "could not copy out at exact boundary") return } #expect(offset == 8) #expect(value == 0x0807_0605_0403_0201) } @Test func testCopyOutWithCustomSize() { let buffer: [UInt8] = [0x00, 0x00, 0x11, 0x22, 0x33, 0x44, 0xFF, 0xFF, 0xFF, 0xFF] guard let (offset, value) = buffer.copyOut(as: UInt32.self, offset: 2, size: 8) else { #expect(Bool(false), "could not copy out with custom size") return } #expect(offset == 6) // offset + MemoryLayout.size #expect(value == 0x4433_2211) } @Test func testCopyOutWithCustomSizeRangeError() { let buffer: [UInt8] = [0x00, 0x11, 0x22, 0x33, 0x44, 0x55] // Request size 8 at offset 2 would require 10 bytes total, but buffer only has 6 #expect(buffer.copyOut(as: UInt32.self, offset: 2, size: 8) == nil) } // MARK: - copyIn(buffer:) and copyOut(buffer:) Tests @Test func testBufferCopy() throws { let inputBuffer: [UInt8] = [0x01, 0x02, 0x03] var buffer = [UInt8](repeating: 0, count: 9) guard let offset = buffer.copyIn(buffer: inputBuffer, offset: 4) else { #expect(Bool(false), "could not copy to buffer") return } #expect(offset == 7) guard let offset = buffer.copyIn(buffer: inputBuffer, offset: 6) else { #expect(Bool(false), "could not copy to buffer") return } #expect(offset == 9) let expectedBuffer: [UInt8] = [ 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x01, 0x02, 0x03, ] #expect(expectedBuffer == buffer) var outputBuffer = [UInt8](repeating: 0, count: 3) guard let offset = buffer.copyOut(buffer: &outputBuffer, offset: 6) else { #expect(Bool(false), "could not copy to buffer") return } #expect(offset == 9) let expectedOutputBuffer: [UInt8] = [ 0x01, 0x02, 0x03, ] #expect(expectedOutputBuffer == outputBuffer) } @Test func testBufferCopyZeroOffset() { let inputBuffer: [UInt8] = [0xAA, 0xBB, 0xCC] var buffer = [UInt8](repeating: 0, count: 5) guard let offset = buffer.copyIn(buffer: inputBuffer, offset: 0) else { #expect(Bool(false), "could not copy to buffer at offset 0") return } #expect(offset == 3) #expect(buffer[0] == 0xAA) #expect(buffer[1] == 0xBB) #expect(buffer[2] == 0xCC) } @Test func testBufferCopyEmptyBuffer() { let inputBuffer: [UInt8] = [] var buffer = [UInt8](repeating: 0, count: 5) guard let offset = buffer.copyIn(buffer: inputBuffer, offset: 2) else { #expect(Bool(false), "could not copy empty buffer") return } #expect(offset == 2) } @Test func testBufferCopyExactFit() { let inputBuffer: [UInt8] = [0x01, 0x02, 0x03] var buffer = [UInt8](repeating: 0, count: 6) guard let offset = buffer.copyIn(buffer: inputBuffer, offset: 3) else { #expect(Bool(false), "could not copy to exact fit") return } #expect(offset == 6) } @Test func testBufferCopyRangeError() throws { let inputBuffer: [UInt8] = [0x01, 0x02, 0x03] var buffer = [UInt8](repeating: 0, count: 9) #expect(buffer.copyIn(buffer: inputBuffer, offset: 7) == nil) var outputBuffer = [UInt8](repeating: 0, count: 3) #expect(buffer.copyOut(buffer: &outputBuffer, offset: 7) == nil) } @Test func testBufferCopyOutZeroOffset() { let buffer: [UInt8] = [0x11, 0x22, 0x33, 0x44, 0x55] var outputBuffer = [UInt8](repeating: 0, count: 3) guard let offset = buffer.copyOut(buffer: &outputBuffer, offset: 0) else { #expect(Bool(false), "could not copy out at offset 0") return } #expect(offset == 3) #expect(outputBuffer[0] == 0x11) #expect(outputBuffer[1] == 0x22) #expect(outputBuffer[2] == 0x33) } @Test func testBufferCopyOutEmptyBuffer() { let buffer: [UInt8] = [0x11, 0x22, 0x33] var outputBuffer: [UInt8] = [] guard let offset = buffer.copyOut(buffer: &outputBuffer, offset: 1) else { #expect(Bool(false), "could not copy out to empty buffer") return } #expect(offset == 1) } @Test func testBufferCopyOutExactFit() { let buffer: [UInt8] = [0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF] var outputBuffer = [UInt8](repeating: 0, count: 3) guard let offset = buffer.copyOut(buffer: &outputBuffer, offset: 3) else { #expect(Bool(false), "could not copy out exact fit") return } #expect(offset == 6) #expect(outputBuffer[0] == 0xDD) #expect(outputBuffer[1] == 0xEE) #expect(outputBuffer[2] == 0xFF) } }