mirror of
https://github.com/netbirdio/netbird.git
synced 2026-03-31 06:34:14 -04:00
211 lines
4.7 KiB
Go
211 lines
4.7 KiB
Go
package sshauth
|
|
|
|
import (
|
|
"testing"
|
|
)
|
|
|
|
func TestHashUserID(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
userID string
|
|
}{
|
|
{
|
|
name: "simple user ID",
|
|
userID: "user@example.com",
|
|
},
|
|
{
|
|
name: "UUID format",
|
|
userID: "550e8400-e29b-41d4-a716-446655440000",
|
|
},
|
|
{
|
|
name: "numeric ID",
|
|
userID: "12345",
|
|
},
|
|
{
|
|
name: "empty string",
|
|
userID: "",
|
|
},
|
|
{
|
|
name: "special characters",
|
|
userID: "user+test@domain.com",
|
|
},
|
|
{
|
|
name: "unicode characters",
|
|
userID: "用户@example.com",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
hash, err := HashUserID(tt.userID)
|
|
if err != nil {
|
|
t.Errorf("HashUserID() error = %v, want nil", err)
|
|
return
|
|
}
|
|
|
|
// Verify hash is non-zero for non-empty inputs
|
|
if tt.userID != "" && hash == [16]byte{} {
|
|
t.Errorf("HashUserID() returned zero hash for non-empty input")
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestHashUserID_Consistency(t *testing.T) {
|
|
userID := "test@example.com"
|
|
|
|
hash1, err1 := HashUserID(userID)
|
|
if err1 != nil {
|
|
t.Fatalf("First HashUserID() error = %v", err1)
|
|
}
|
|
|
|
hash2, err2 := HashUserID(userID)
|
|
if err2 != nil {
|
|
t.Fatalf("Second HashUserID() error = %v", err2)
|
|
}
|
|
|
|
if hash1 != hash2 {
|
|
t.Errorf("HashUserID() is not consistent: got %v and %v for same input", hash1, hash2)
|
|
}
|
|
}
|
|
|
|
func TestHashUserID_Uniqueness(t *testing.T) {
|
|
tests := []struct {
|
|
userID1 string
|
|
userID2 string
|
|
}{
|
|
{"user1@example.com", "user2@example.com"},
|
|
{"alice@domain.com", "bob@domain.com"},
|
|
{"test", "test1"},
|
|
{"", "a"},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
hash1, err1 := HashUserID(tt.userID1)
|
|
if err1 != nil {
|
|
t.Fatalf("HashUserID(%s) error = %v", tt.userID1, err1)
|
|
}
|
|
|
|
hash2, err2 := HashUserID(tt.userID2)
|
|
if err2 != nil {
|
|
t.Fatalf("HashUserID(%s) error = %v", tt.userID2, err2)
|
|
}
|
|
|
|
if hash1 == hash2 {
|
|
t.Errorf("HashUserID() collision: %s and %s produced same hash %v", tt.userID1, tt.userID2, hash1)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestUserIDHash_String(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
hash UserIDHash
|
|
expected string
|
|
}{
|
|
{
|
|
name: "zero hash",
|
|
hash: [16]byte{},
|
|
expected: "00000000000000000000000000000000",
|
|
},
|
|
{
|
|
name: "small value",
|
|
hash: [16]byte{15: 0xff},
|
|
expected: "000000000000000000000000000000ff",
|
|
},
|
|
{
|
|
name: "large value",
|
|
hash: [16]byte{8: 0xde, 9: 0xad, 10: 0xbe, 11: 0xef, 12: 0xca, 13: 0xfe, 14: 0xba, 15: 0xbe},
|
|
expected: "0000000000000000deadbeefcafebabe",
|
|
},
|
|
{
|
|
name: "max value",
|
|
hash: [16]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
|
|
expected: "ffffffffffffffffffffffffffffffff",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result := tt.hash.String()
|
|
if result != tt.expected {
|
|
t.Errorf("UserIDHash.String() = %v, want %v", result, tt.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestUserIDHash_String_Length(t *testing.T) {
|
|
// Test that String() always returns 32 hex characters (16 bytes * 2)
|
|
userID := "test@example.com"
|
|
hash, err := HashUserID(userID)
|
|
if err != nil {
|
|
t.Fatalf("HashUserID() error = %v", err)
|
|
}
|
|
|
|
result := hash.String()
|
|
if len(result) != 32 {
|
|
t.Errorf("UserIDHash.String() length = %d, want 32", len(result))
|
|
}
|
|
|
|
// Verify it's valid hex
|
|
for i, c := range result {
|
|
if !((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f')) {
|
|
t.Errorf("UserIDHash.String() contains non-hex character at position %d: %c", i, c)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestHashUserID_KnownValues(t *testing.T) {
|
|
// Test with known BLAKE2b-128 values to ensure correct implementation
|
|
tests := []struct {
|
|
name string
|
|
userID string
|
|
expected UserIDHash
|
|
}{
|
|
{
|
|
name: "empty string",
|
|
userID: "",
|
|
// BLAKE2b-128 of empty string
|
|
expected: [16]byte{0xca, 0xe6, 0x69, 0x41, 0xd9, 0xef, 0xbd, 0x40, 0x4e, 0x4d, 0x88, 0x75, 0x8e, 0xa6, 0x76, 0x70},
|
|
},
|
|
{
|
|
name: "single character 'a'",
|
|
userID: "a",
|
|
// BLAKE2b-128 of "a"
|
|
expected: [16]byte{0x27, 0xc3, 0x5e, 0x6e, 0x93, 0x73, 0x87, 0x7f, 0x29, 0xe5, 0x62, 0x46, 0x4e, 0x46, 0x49, 0x7e},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
hash, err := HashUserID(tt.userID)
|
|
if err != nil {
|
|
t.Errorf("HashUserID() error = %v", err)
|
|
return
|
|
}
|
|
|
|
if hash != tt.expected {
|
|
t.Errorf("HashUserID(%q) = %x, want %x",
|
|
tt.userID, hash, tt.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func BenchmarkHashUserID(b *testing.B) {
|
|
userID := "user@example.com"
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_, _ = HashUserID(userID)
|
|
}
|
|
}
|
|
|
|
func BenchmarkUserIDHash_String(b *testing.B) {
|
|
hash := UserIDHash([16]byte{8: 0xde, 9: 0xad, 10: 0xbe, 11: 0xef, 12: 0xca, 13: 0xfe, 14: 0xba, 15: 0xbe})
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_ = hash.String()
|
|
}
|
|
}
|