mirror of
https://github.com/sony/sonyflake.git
synced 2026-03-27 05:14:58 +00:00
Compare commits
2 Commits
master
...
copilot/fi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f8ce8840b5 | ||
|
|
806997932e |
86
v2/machine_bits_test.go
Normal file
86
v2/machine_bits_test.go
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
package sonyflake
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/sony/sonyflake/v2/mock"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TestDefaultMachineIDWithCustomBits tests that when using default machine ID
|
||||||
|
// with custom BitsMachineID, the machine ID is properly masked to fit within
|
||||||
|
// the specified bit length.
|
||||||
|
func TestDefaultMachineIDWithCustomBits(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
bitsMachineID int
|
||||||
|
mockIP net.IP
|
||||||
|
expectError bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "10 bits machine ID with IP that fits",
|
||||||
|
bitsMachineID: 10,
|
||||||
|
mockIP: net.IP{192, 168, 0, 1}, // lower 16 bits = 1, fits in 10 bits
|
||||||
|
expectError: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "10 bits machine ID with IP that exceeds without masking",
|
||||||
|
bitsMachineID: 10,
|
||||||
|
mockIP: net.IP{192, 168, 255, 255}, // lower 16 bits = 65535, needs masking to fit in 10 bits
|
||||||
|
expectError: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "8 bits machine ID",
|
||||||
|
bitsMachineID: 8,
|
||||||
|
mockIP: net.IP{192, 168, 100, 200}, // lower 16 bits = 25800
|
||||||
|
expectError: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "default 16 bits",
|
||||||
|
bitsMachineID: 0, // will use default 16
|
||||||
|
mockIP: net.IP{192, 168, 255, 255},
|
||||||
|
expectError: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
// Create a mock that returns our test IP
|
||||||
|
mockInterfaceAddrs := mock.NewInterfaceAddrsWithIP(tc.mockIP)
|
||||||
|
|
||||||
|
settings := Settings{
|
||||||
|
BitsMachineID: tc.bitsMachineID,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Temporarily replace the default interface addrs function
|
||||||
|
oldDefaultInterfaceAddrs := defaultInterfaceAddrs
|
||||||
|
defaultInterfaceAddrs = mockInterfaceAddrs
|
||||||
|
defer func() { defaultInterfaceAddrs = oldDefaultInterfaceAddrs }()
|
||||||
|
|
||||||
|
sf, err := New(settings)
|
||||||
|
|
||||||
|
if tc.expectError {
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("expected error but got none")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
if sf == nil {
|
||||||
|
t.Error("sonyflake instance should not be nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify the machine ID fits within the specified bits
|
||||||
|
expectedBits := tc.bitsMachineID
|
||||||
|
if expectedBits == 0 {
|
||||||
|
expectedBits = defaultBitsMachine
|
||||||
|
}
|
||||||
|
maxMachineID := 1 << expectedBits
|
||||||
|
if sf.machine >= maxMachineID {
|
||||||
|
t.Errorf("machine ID %d exceeds max for %d bits (%d)", sf.machine, expectedBits, maxMachineID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -34,3 +34,13 @@ func NewNilInterfaceAddrs() types.InterfaceAddrs {
|
|||||||
return []net.Addr{}, nil
|
return []net.Addr{}, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewInterfaceAddrsWithIP returns a private IP address with the given IP.
|
||||||
|
func NewInterfaceAddrsWithIP(ip net.IP) types.InterfaceAddrs {
|
||||||
|
ifat := make([]net.Addr, 0, 1)
|
||||||
|
ifat = append(ifat, &net.IPNet{IP: ip, Mask: []byte{255, 0, 0, 0}})
|
||||||
|
|
||||||
|
return func() ([]net.Addr, error) {
|
||||||
|
return ifat, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -36,7 +36,8 @@ import (
|
|||||||
//
|
//
|
||||||
// MachineID returns the unique ID of a Sonyflake instance.
|
// MachineID returns the unique ID of a Sonyflake instance.
|
||||||
// If MachineID returns an error, the instance will not be created.
|
// If MachineID returns an error, the instance will not be created.
|
||||||
// If MachineID is nil, the default MachineID is used, which returns the lower 16 bits of the private IP address.
|
// If MachineID is nil, the default MachineID is used, which returns the lower bits
|
||||||
|
// of the private IP address, masked to fit within BitsMachineID bits.
|
||||||
//
|
//
|
||||||
// CheckMachineID validates the uniqueness of a machine ID.
|
// CheckMachineID validates the uniqueness of a machine ID.
|
||||||
// If CheckMachineID returns false, the instance will not be created.
|
// If CheckMachineID returns false, the instance will not be created.
|
||||||
@@ -154,6 +155,10 @@ func New(st Settings) (*Sonyflake, error) {
|
|||||||
var err error
|
var err error
|
||||||
if st.MachineID == nil {
|
if st.MachineID == nil {
|
||||||
sf.machine, err = lower16BitPrivateIP(defaultInterfaceAddrs)
|
sf.machine, err = lower16BitPrivateIP(defaultInterfaceAddrs)
|
||||||
|
if err == nil {
|
||||||
|
// Mask to use only the required number of bits
|
||||||
|
sf.machine = sf.machine & (1<<sf.bitsMachine - 1)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
sf.machine, err = st.MachineID()
|
sf.machine, err = st.MachineID()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user