//===----------------------------------------------------------------------===// // 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 @testable import ContainerNetworkServer struct AttachmentAllocatorTest { @Test func testAllocateSingleHostname() async throws { let allocator = try AttachmentAllocator(lower: 100, size: 10) let address = try await allocator.allocate(hostname: "test-host") #expect(address >= 100) #expect(address < 110) } @Test func testAllocateSameHostnameTwice() async throws { let allocator = try AttachmentAllocator(lower: 100, size: 10) let address1 = try await allocator.allocate(hostname: "test-host") let address2 = try await allocator.allocate(hostname: "test-host") #expect(address1 == address2) } @Test func testAllocateMultipleHostnames() async throws { let allocator = try AttachmentAllocator(lower: 100, size: 10) let address1 = try await allocator.allocate(hostname: "host1") let address2 = try await allocator.allocate(hostname: "host2") let address3 = try await allocator.allocate(hostname: "host3") #expect(address1 != address2) #expect(address2 != address3) #expect(address1 != address3) } @Test func testLookupAllocatedHostname() async throws { let allocator = try AttachmentAllocator(lower: 100, size: 10) let allocatedAddress = try await allocator.allocate(hostname: "test-host") let lookedUpAddress = try await allocator.lookup(hostname: "test-host") #expect(lookedUpAddress == allocatedAddress) } @Test func testLookupNonExistentHostname() async throws { let allocator = try AttachmentAllocator(lower: 100, size: 10) let address = try await allocator.lookup(hostname: "non-existent") #expect(address == nil) } @Test func testDeallocateAllocatedHostname() async throws { let allocator = try AttachmentAllocator(lower: 100, size: 10) let allocatedAddress = try await allocator.allocate(hostname: "test-host") let deallocatedAddress = try await allocator.deallocate(hostname: "test-host") #expect(deallocatedAddress == allocatedAddress) // After deallocation, lookup should return nil let lookedUpAddress = try await allocator.lookup(hostname: "test-host") #expect(lookedUpAddress == nil) } @Test func testDeallocateNonExistentHostname() async throws { let allocator = try AttachmentAllocator(lower: 100, size: 10) let deallocatedAddress = try await allocator.deallocate(hostname: "non-existent") #expect(deallocatedAddress == nil) } @Test func testReallocateAfterDeallocation() async throws { let allocator = try AttachmentAllocator(lower: 100, size: 10) let address1 = try await allocator.allocate(hostname: "test-host") let released1 = try await allocator.deallocate(hostname: "test-host") #expect(address1 == released1) let address2 = try await allocator.allocate(hostname: "test-host") // After deallocation, allocating the same hostname should give a new address #expect(address2 >= 100) #expect(address2 < 110) } @Test func testAllocateUntilFull() async throws { let size = 5 let allocator = try AttachmentAllocator(lower: 100, size: size) // Allocate up to the limit for i in 0..= 100) #expect(newAddress < 103) // The three remaining allocations should all be different let finalAddress1 = try await allocator.lookup(hostname: "host1") let finalAddress3 = try await allocator.lookup(hostname: "host3") let finalAddress4 = try await allocator.lookup(hostname: "host4") #expect(finalAddress1 == address1) #expect(finalAddress3 == address3) #expect(finalAddress4 == newAddress) } @Test func testMultipleDeallocationsOfSameHostname() async throws { let allocator = try AttachmentAllocator(lower: 100, size: 10) let address = try await allocator.allocate(hostname: "test-host") let firstDeallocate = try await allocator.deallocate(hostname: "test-host") #expect(firstDeallocate == address) // Second deallocation should return nil since it's already deallocated let secondDeallocate = try await allocator.deallocate(hostname: "test-host") #expect(secondDeallocate == nil) } }