mirror of
https://github.com/amnezia-vpn/amneziawg-go.git
synced 2025-08-02 01:42:54 +02:00
feat: create tests
This commit is contained in:
parent
65743536a2
commit
c66702372d
6 changed files with 398 additions and 6 deletions
37
device/awg/internal/mock.go
Normal file
37
device/awg/internal/mock.go
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
package internal
|
||||||
|
|
||||||
|
type mockGenerator struct {
|
||||||
|
size int
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewMockGenerator(size int) mockGenerator {
|
||||||
|
return mockGenerator{size: size}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m mockGenerator) Generate() []byte {
|
||||||
|
return make([]byte, m.size)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m mockGenerator) Size() int {
|
||||||
|
return m.size
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m mockGenerator) Name() string {
|
||||||
|
return "mock"
|
||||||
|
}
|
||||||
|
|
||||||
|
type mockByteGenerator struct {
|
||||||
|
data []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewMockByteGenerator(data []byte) mockByteGenerator {
|
||||||
|
return mockByteGenerator{data: data}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bg mockByteGenerator) Generate() []byte {
|
||||||
|
return bg.data
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bg mockByteGenerator) Size() int {
|
||||||
|
return len(bg.data)
|
||||||
|
}
|
|
@ -11,6 +11,7 @@ type SpecialHandshakeHandler struct {
|
||||||
|
|
||||||
nextItime time.Time
|
nextItime time.Time
|
||||||
ITimeout time.Duration // seconds
|
ITimeout time.Duration // seconds
|
||||||
|
|
||||||
// TODO: maybe atomic?
|
// TODO: maybe atomic?
|
||||||
PacketCounter uint64
|
PacketCounter uint64
|
||||||
IsSet bool
|
IsSet bool
|
||||||
|
@ -33,7 +34,7 @@ func (handler *SpecialHandshakeHandler) GenerateSpecialJunk() [][]byte {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
rv := handler.SpecialJunk.Generate()
|
rv := handler.SpecialJunk.GeneratePackets()
|
||||||
|
|
||||||
handler.nextItime = time.Now().Add(time.Duration(handler.ITimeout))
|
handler.nextItime = time.Now().Add(time.Duration(handler.ITimeout))
|
||||||
|
|
||||||
|
@ -45,5 +46,5 @@ func (handler *SpecialHandshakeHandler) isTimeToSendSpecial() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (handler *SpecialHandshakeHandler) PrepareControlledJunk() [][]byte {
|
func (handler *SpecialHandshakeHandler) PrepareControlledJunk() [][]byte {
|
||||||
return handler.ControlledJunk.Generate()
|
return handler.ControlledJunk.GeneratePackets()
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ func (tg *TagJunkGenerator) append(generator Generator) {
|
||||||
tg.packetSize += generator.Size()
|
tg.packetSize += generator.Size()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tg *TagJunkGenerator) generate() []byte {
|
func (tg *TagJunkGenerator) generatePacket() []byte {
|
||||||
packet := make([]byte, 0, tg.packetSize)
|
packet := make([]byte, 0, tg.packetSize)
|
||||||
for _, generator := range tg.generators {
|
for _, generator := range tg.generators {
|
||||||
packet = append(packet, generator.Generate()...)
|
packet = append(packet, generator.Generate()...)
|
||||||
|
|
|
@ -18,7 +18,11 @@ func (handler *TagJunkGeneratorHandler) AppendGenerator(generators TagJunkGenera
|
||||||
func (handler *TagJunkGeneratorHandler) Validate() error {
|
func (handler *TagJunkGeneratorHandler) Validate() error {
|
||||||
seen := make([]bool, len(handler.generators))
|
seen := make([]bool, len(handler.generators))
|
||||||
for _, generator := range handler.generators {
|
for _, generator := range handler.generators {
|
||||||
if index, err := generator.nameIndex(); err != nil {
|
index, err := generator.nameIndex()
|
||||||
|
if index > len(handler.generators) {
|
||||||
|
return fmt.Errorf("junk packet index should be consecutive")
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
return fmt.Errorf("name index: %w", err)
|
return fmt.Errorf("name index: %w", err)
|
||||||
} else {
|
} else {
|
||||||
seen[index-1] = true
|
seen[index-1] = true
|
||||||
|
@ -34,11 +38,11 @@ func (handler *TagJunkGeneratorHandler) Validate() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (handler *TagJunkGeneratorHandler) Generate() [][]byte {
|
func (handler *TagJunkGeneratorHandler) GeneratePackets() [][]byte {
|
||||||
var rv = make([][]byte, handler.length+handler.DefaultJunkCount)
|
var rv = make([][]byte, handler.length+handler.DefaultJunkCount)
|
||||||
for i, generator := range handler.generators {
|
for i, generator := range handler.generators {
|
||||||
rv[i] = make([]byte, generator.packetSize)
|
rv[i] = make([]byte, generator.packetSize)
|
||||||
copy(rv[i], generator.generate())
|
copy(rv[i], generator.generatePacket())
|
||||||
}
|
}
|
||||||
|
|
||||||
return rv
|
return rv
|
||||||
|
|
144
device/awg/tag_junk_generator_handler_test.go
Normal file
144
device/awg/tag_junk_generator_handler_test.go
Normal file
|
@ -0,0 +1,144 @@
|
||||||
|
package awg
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/amnezia-vpn/amneziawg-go/device/awg/internal"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestTagJunkGeneratorHandlerAppendGenerator(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
generator TagJunkGenerator
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "append single generator",
|
||||||
|
generator: newTagJunkGenerator("t1", 10),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
tt := tt
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
handler := &TagJunkGeneratorHandler{}
|
||||||
|
|
||||||
|
// Initial length should be 0
|
||||||
|
require.Equal(t, 0, handler.length)
|
||||||
|
require.Empty(t, handler.generators)
|
||||||
|
|
||||||
|
// After append, length should be 1 and generator should be added
|
||||||
|
handler.AppendGenerator(tt.generator)
|
||||||
|
require.Equal(t, 1, handler.length)
|
||||||
|
require.Len(t, handler.generators, 1)
|
||||||
|
require.Equal(t, tt.generator, handler.generators[0])
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTagJunkGeneratorHandlerValidate(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
generators []TagJunkGenerator
|
||||||
|
wantErr bool
|
||||||
|
errMsg string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "valid consecutive indices",
|
||||||
|
generators: []TagJunkGenerator{
|
||||||
|
newTagJunkGenerator("t1", 10),
|
||||||
|
newTagJunkGenerator("t2", 10),
|
||||||
|
},
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "non-consecutive indices",
|
||||||
|
generators: []TagJunkGenerator{
|
||||||
|
newTagJunkGenerator("t1", 10),
|
||||||
|
newTagJunkGenerator("t3", 10), // Missing t2
|
||||||
|
},
|
||||||
|
wantErr: true,
|
||||||
|
errMsg: "junk packet index should be consecutive",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "nameIndex error",
|
||||||
|
generators: []TagJunkGenerator{
|
||||||
|
newTagJunkGenerator("error", 10),
|
||||||
|
},
|
||||||
|
wantErr: true,
|
||||||
|
errMsg: "name must be 2 character long",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
tt := tt
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
handler := &TagJunkGeneratorHandler{}
|
||||||
|
for _, gen := range tt.generators {
|
||||||
|
handler.AppendGenerator(gen)
|
||||||
|
}
|
||||||
|
|
||||||
|
err := handler.Validate()
|
||||||
|
if tt.wantErr {
|
||||||
|
require.Error(t, err)
|
||||||
|
require.Contains(t, err.Error(), tt.errMsg)
|
||||||
|
} else {
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTagJunkGeneratorHandlerGenerate(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
mockByte1 := []byte{0x01, 0x02}
|
||||||
|
mockByte2 := []byte{0x03, 0x04, 0x05}
|
||||||
|
mockGen1 := internal.NewMockByteGenerator(mockByte1)
|
||||||
|
mockGen2 := internal.NewMockByteGenerator(mockByte2)
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
setupGenerator func() []TagJunkGenerator
|
||||||
|
expected [][]byte
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "generate with no default junk",
|
||||||
|
setupGenerator: func() []TagJunkGenerator {
|
||||||
|
tg1 := newTagJunkGenerator("t1", 0)
|
||||||
|
tg1.append(mockGen1)
|
||||||
|
tg1.append(mockGen2)
|
||||||
|
tg2 := newTagJunkGenerator("t2", 0)
|
||||||
|
tg2.append(mockGen2)
|
||||||
|
tg2.append(mockGen1)
|
||||||
|
|
||||||
|
return []TagJunkGenerator{tg1, tg2}
|
||||||
|
},
|
||||||
|
expected: [][]byte{
|
||||||
|
append(mockByte1, mockByte2...),
|
||||||
|
append(mockByte2, mockByte1...),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
tt := tt
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
handler := &TagJunkGeneratorHandler{}
|
||||||
|
generators := tt.setupGenerator()
|
||||||
|
for _, gen := range generators {
|
||||||
|
handler.AppendGenerator(gen)
|
||||||
|
}
|
||||||
|
|
||||||
|
result := handler.GeneratePackets()
|
||||||
|
require.Equal(t, result, tt.expected)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
206
device/awg/tag_junk_generator_test.go
Normal file
206
device/awg/tag_junk_generator_test.go
Normal file
|
@ -0,0 +1,206 @@
|
||||||
|
package awg
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/amnezia-vpn/amneziawg-go/device/awg/internal"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNewTagJunkGenerator(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
genName string
|
||||||
|
size int
|
||||||
|
expected TagJunkGenerator
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "Create new generator with empty name",
|
||||||
|
genName: "",
|
||||||
|
size: 0,
|
||||||
|
expected: TagJunkGenerator{
|
||||||
|
name: "",
|
||||||
|
packetSize: 0,
|
||||||
|
generators: make([]Generator, 0),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Create new generator with valid name",
|
||||||
|
genName: "T1",
|
||||||
|
size: 0,
|
||||||
|
expected: TagJunkGenerator{
|
||||||
|
name: "T1",
|
||||||
|
packetSize: 0,
|
||||||
|
generators: make([]Generator, 0),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Create new generator with non-zero size",
|
||||||
|
genName: "T2",
|
||||||
|
size: 5,
|
||||||
|
expected: TagJunkGenerator{
|
||||||
|
name: "T2",
|
||||||
|
packetSize: 0,
|
||||||
|
generators: make([]Generator, 5),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
tc := tc // capture range variable
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
result := newTagJunkGenerator(tc.genName, tc.size)
|
||||||
|
require.Equal(t, tc.expected.name, result.name)
|
||||||
|
require.Equal(t, tc.expected.packetSize, result.packetSize)
|
||||||
|
require.Len(t, result.generators, len(tc.expected.generators))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTagJunkGeneratorAppend(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
initialState TagJunkGenerator
|
||||||
|
mockSize int
|
||||||
|
expectedLength int
|
||||||
|
expectedSize int
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "Append to empty generator",
|
||||||
|
initialState: newTagJunkGenerator("T1", 0),
|
||||||
|
mockSize: 5,
|
||||||
|
expectedLength: 1,
|
||||||
|
expectedSize: 5,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Append to non-empty generator",
|
||||||
|
initialState: TagJunkGenerator{name: "T2", packetSize: 10, generators: make([]Generator, 2)},
|
||||||
|
mockSize: 7,
|
||||||
|
expectedLength: 3, // 2 existing + 1 new
|
||||||
|
expectedSize: 17, // 10 + 7
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
tc := tc // capture range variable
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
tg := tc.initialState
|
||||||
|
mockGen := internal.NewMockGenerator(tc.mockSize)
|
||||||
|
|
||||||
|
tg.append(mockGen)
|
||||||
|
|
||||||
|
require.Equal(t, tc.expectedLength, len(tg.generators))
|
||||||
|
require.Equal(t, tc.expectedSize, tg.packetSize)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTagJunkGeneratorGenerate(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
// Create mock generators for testing
|
||||||
|
mockGen1 := internal.NewMockByteGenerator([]byte{0x01, 0x02})
|
||||||
|
mockGen2 := internal.NewMockByteGenerator([]byte{0x03, 0x04, 0x05})
|
||||||
|
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
setupGenerator func() TagJunkGenerator
|
||||||
|
expected []byte
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "Generate with empty generators",
|
||||||
|
setupGenerator: func() TagJunkGenerator {
|
||||||
|
return newTagJunkGenerator("T1", 0)
|
||||||
|
},
|
||||||
|
expected: []byte{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Generate with single generator",
|
||||||
|
setupGenerator: func() TagJunkGenerator {
|
||||||
|
tg := newTagJunkGenerator("T2", 0)
|
||||||
|
tg.append(mockGen1)
|
||||||
|
return tg
|
||||||
|
},
|
||||||
|
expected: []byte{0x01, 0x02},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Generate with multiple generators",
|
||||||
|
setupGenerator: func() TagJunkGenerator {
|
||||||
|
tg := newTagJunkGenerator("T3", 0)
|
||||||
|
tg.append(mockGen1)
|
||||||
|
tg.append(mockGen2)
|
||||||
|
return tg
|
||||||
|
},
|
||||||
|
expected: []byte{0x01, 0x02, 0x03, 0x04, 0x05},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
tc := tc // capture range variable
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
tg := tc.setupGenerator()
|
||||||
|
result := tg.generatePacket()
|
||||||
|
|
||||||
|
require.Equal(t, tc.expected, result)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTagJunkGeneratorNameIndex(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
generatorName string
|
||||||
|
expectedIndex int
|
||||||
|
expectError bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "Valid name with digit",
|
||||||
|
generatorName: "T5",
|
||||||
|
expectedIndex: 5,
|
||||||
|
expectError: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Invalid name - too short",
|
||||||
|
generatorName: "T",
|
||||||
|
expectError: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Invalid name - too long",
|
||||||
|
generatorName: "T55",
|
||||||
|
expectError: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Invalid name - non-digit second character",
|
||||||
|
generatorName: "TX",
|
||||||
|
expectError: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
tc := tc // capture range variable
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
tg := TagJunkGenerator{name: tc.generatorName}
|
||||||
|
index, err := tg.nameIndex()
|
||||||
|
|
||||||
|
if tc.expectError {
|
||||||
|
require.Error(t, err)
|
||||||
|
} else {
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, tc.expectedIndex, index)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue