mirror of
https://github.com/danderson/netboot.git
synced 2025-10-17 18:41:26 +02:00
146 lines
5.7 KiB
Go
146 lines
5.7 KiB
Go
package dhcp6
|
|
|
|
import (
|
|
"testing"
|
|
"net"
|
|
"time"
|
|
)
|
|
|
|
func TestReserveAddress(t *testing.T) {
|
|
expectedIP1 := net.ParseIP("2001:db8:f00f:cafe::1")
|
|
expectedIP2 := net.ParseIP("2001:db8:f00f:cafe::2")
|
|
expectedClientID := []byte("Client-id")
|
|
expectedIAID1 := []byte("interface-id-1")
|
|
expectedIAID2 := []byte("interface-id-2")
|
|
expectedTime := time.Now()
|
|
expectedMaxLifetime := uint32(100)
|
|
|
|
pool := NewRandomAddressPool(expectedIP1, 2, expectedMaxLifetime)
|
|
pool.timeNow = func() time.Time { return expectedTime }
|
|
ias, _ := pool.ReserveAddresses(expectedClientID, [][]byte{expectedIAID1, expectedIAID2})
|
|
|
|
if len(ias) != 2 {
|
|
t.Fatalf("Expected 2 identity associations but received %d", len(ias))
|
|
}
|
|
if string(ias[0].IPAddress) != string(expectedIP1) && string(ias[0].IPAddress) != string(expectedIP2) {
|
|
t.Fatalf("Unexpected ip address: %v", ias[0].IPAddress)
|
|
}
|
|
if string(ias[0].ClientID) != string(expectedClientID) {
|
|
t.Fatalf("Expected Client id: %v, but got: %v", expectedClientID, ias[0].ClientID)
|
|
}
|
|
if string(ias[0].InterfaceID) != string(expectedIAID1) {
|
|
t.Fatalf("Expected interface id: %v, but got: %v", expectedIAID1, ias[0].InterfaceID)
|
|
}
|
|
if ias[0].CreatedAt != expectedTime {
|
|
t.Fatalf("Expected creation time: %v, but got: %v", expectedTime, ias[0].CreatedAt)
|
|
}
|
|
|
|
if string(ias[1].IPAddress) != string(expectedIP1) && string(ias[1].IPAddress) != string(expectedIP2) {
|
|
t.Fatalf("Unexpected ip address: %v", ias[0].IPAddress)
|
|
}
|
|
if string(ias[1].ClientID) != string(expectedClientID) {
|
|
t.Fatalf("Expected Client id: %v, but got: %v", expectedClientID, ias[1].ClientID)
|
|
}
|
|
if string(ias[1].InterfaceID) != string(expectedIAID2) {
|
|
t.Fatalf("Expected interface id: %v, but got: %v", expectedIAID2, ias[1].InterfaceID)
|
|
}
|
|
if ias[1].CreatedAt != expectedTime {
|
|
t.Fatalf("Expected creation time: %v, but got: %v", expectedTime, ias[1].CreatedAt)
|
|
}
|
|
}
|
|
|
|
func TestReserveAddressUpdatesAddressPool(t *testing.T) {
|
|
expectedClientID := []byte("Client-id")
|
|
expectedIAID := []byte("interface-id")
|
|
expectedTime := time.Now()
|
|
expectedMaxLifetime := uint32(100)
|
|
|
|
pool := NewRandomAddressPool(net.ParseIP("2001:db8:f00f:cafe::1"), 1, expectedMaxLifetime)
|
|
pool.timeNow = func() time.Time { return expectedTime }
|
|
pool.ReserveAddresses(expectedClientID, [][]byte{expectedIAID})
|
|
expectedIdx := pool.calculateIAIDHash(expectedClientID, expectedIAID)
|
|
|
|
a, exists := pool.identityAssociations[expectedIdx]
|
|
if !exists {
|
|
t.Fatalf("Expected to find identity association at %d but didn't", expectedIdx)
|
|
}
|
|
if string(a.ClientID) != string(expectedClientID) || string(a.InterfaceID) != string(expectedIAID) {
|
|
t.Fatalf("Expected ia association with Client id %x and ia id %x, but got %x %x respectively",
|
|
expectedClientID, expectedIAID, a.ClientID, a.InterfaceID)
|
|
}
|
|
}
|
|
|
|
func TestReserveAddressKeepsTrackOfUsedAddresses(t *testing.T) {
|
|
expectedClientID := []byte("Client-id")
|
|
expectedIAID := []byte("interface-id")
|
|
expectedTime := time.Now()
|
|
expectedMaxLifetime := uint32(100)
|
|
|
|
pool := NewRandomAddressPool(net.ParseIP("2001:db8:f00f:cafe::1"), 1, expectedMaxLifetime)
|
|
pool.timeNow = func() time.Time { return expectedTime }
|
|
pool.ReserveAddresses(expectedClientID, [][]byte{expectedIAID})
|
|
|
|
_, exists := pool.usedIps[0x01]; if !exists {
|
|
t.Fatal("'2001:db8:f00f:cafe::1' should be marked as in use")
|
|
}
|
|
}
|
|
|
|
func TestReserveAddressKeepsTrackOfAssociationExpiration(t *testing.T) {
|
|
expectedClientID := []byte("Client-id")
|
|
expectedIAID := []byte("interface-id")
|
|
expectedTime := time.Now()
|
|
expectedMaxLifetime := uint32(100)
|
|
|
|
pool := NewRandomAddressPool(net.ParseIP("2001:db8:f00f:cafe::1"), 1, expectedMaxLifetime)
|
|
pool.timeNow = func() time.Time { return expectedTime }
|
|
pool.ReserveAddresses(expectedClientID, [][]byte{expectedIAID})
|
|
|
|
expiration := pool.identityAssociationExpirations.Peek().(*AssociationExpiration)
|
|
if expiration == nil {
|
|
t.Fatal("Expected an identity association expiration, but got nil")
|
|
}
|
|
if expiration.expiresAt != pool.calculateAssociationExpiration(expectedTime) {
|
|
t.Fatalf("Expected association to expire at %v, but got %v",
|
|
pool.calculateAssociationExpiration(expectedTime), expiration.expiresAt)
|
|
}
|
|
}
|
|
|
|
func TestReserveAddressReturnsExistingAssociation(t *testing.T) {
|
|
expectedClientID := []byte("Client-id")
|
|
expectedIAID := []byte("interface-id")
|
|
expectedTime := time.Now()
|
|
expectedMaxLifetime := uint32(100)
|
|
|
|
pool := NewRandomAddressPool(net.ParseIP("2001:db8:f00f:cafe::1"), 1, expectedMaxLifetime)
|
|
pool.timeNow = func() time.Time { return expectedTime }
|
|
firstAssociation, _ := pool.ReserveAddresses(expectedClientID, [][]byte{expectedIAID})
|
|
secondAssociation, _ := pool.ReserveAddresses(expectedClientID, [][]byte{expectedIAID})
|
|
|
|
if len(firstAssociation) < 1 {
|
|
t.Fatalf("No associations returned from the first call to ReserveAddresses")
|
|
}
|
|
if len(secondAssociation) < 1 {
|
|
t.Fatalf("No associations returned from the second call to ReserveAddresses")
|
|
}
|
|
if string(firstAssociation[0].IPAddress) != string(secondAssociation[0].IPAddress) {
|
|
t.Fatal("Expected return of the same ip address on both invocations")
|
|
}
|
|
}
|
|
|
|
func TestReleaseAddress(t *testing.T) {
|
|
expectedClientID := []byte("Client-id")
|
|
expectedIAID := []byte("interface-id")
|
|
expectedTime := time.Now()
|
|
expectedMaxLifetime := uint32(100)
|
|
|
|
pool := NewRandomAddressPool(net.ParseIP("2001:db8:f00f:cafe::1"), 1, expectedMaxLifetime)
|
|
pool.timeNow = func() time.Time { return expectedTime }
|
|
a, _ := pool.ReserveAddresses(expectedClientID, [][]byte{expectedIAID})
|
|
|
|
pool.ReleaseAddresses(expectedClientID, [][]byte{expectedIAID})
|
|
|
|
_, exists := pool.identityAssociations[pool.calculateIAIDHash(expectedClientID, expectedIAID)]; if exists {
|
|
t.Fatalf("identity association for %v should've been removed, but is still available", a[0].IPAddress)
|
|
}
|
|
}
|