test: improve coverage across package
This commit is contained in:
22
modifier/interface_test.go
Normal file
22
modifier/interface_test.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package modifier
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestErrInvalidPacket_Error(t *testing.T) {
|
||||
e := &ErrInvalidPacket{Err: errors.New("bad checksum")}
|
||||
want := "invalid packet: bad checksum"
|
||||
if got := e.Error(); got != want {
|
||||
t.Errorf("Error() = %q, want %q", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestErrInvalidArgs_Error(t *testing.T) {
|
||||
e := &ErrInvalidArgs{Err: errors.New("missing 'a' arg")}
|
||||
want := "invalid args: missing 'a' arg"
|
||||
if got := e.Error(); got != want {
|
||||
t.Errorf("Error() = %q, want %q", got, want)
|
||||
}
|
||||
}
|
||||
205
modifier/udp/dns_test.go
Normal file
205
modifier/udp/dns_test.go
Normal file
@@ -0,0 +1,205 @@
|
||||
package udp
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.difuse.io/Difuse/Mellaris/modifier"
|
||||
|
||||
"github.com/google/gopacket"
|
||||
"github.com/google/gopacket/layers"
|
||||
)
|
||||
|
||||
func dnsResponseBytes(t *testing.T, id uint16, qtype layers.DNSType, name string) []byte {
|
||||
t.Helper()
|
||||
dns := &layers.DNS{
|
||||
ID: id,
|
||||
QR: true,
|
||||
OpCode: layers.DNSOpCodeQuery,
|
||||
AA: false,
|
||||
RD: true,
|
||||
RA: true,
|
||||
ResponseCode: layers.DNSResponseCodeNoErr,
|
||||
QDCount: 1,
|
||||
Questions: []layers.DNSQuestion{
|
||||
{
|
||||
Name: []byte(name),
|
||||
Type: qtype,
|
||||
Class: layers.DNSClassIN,
|
||||
},
|
||||
},
|
||||
}
|
||||
buf := gopacket.NewSerializeBuffer()
|
||||
err := gopacket.SerializeLayers(buf, gopacket.SerializeOptions{
|
||||
FixLengths: true,
|
||||
ComputeChecksums: true,
|
||||
}, dns)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to serialize DNS response: %v", err)
|
||||
}
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
||||
func TestDNSModifier_Name(t *testing.T) {
|
||||
m := &DNSModifier{}
|
||||
if m.Name() != "dns" {
|
||||
t.Errorf("Name() = %q, want dns", m.Name())
|
||||
}
|
||||
}
|
||||
|
||||
func TestDNSModifier_New_NoArgs(t *testing.T) {
|
||||
m := &DNSModifier{}
|
||||
inst, err := m.New(map[string]interface{}{})
|
||||
if err != nil {
|
||||
t.Fatalf("New() unexpected error: %v", err)
|
||||
}
|
||||
if inst == nil {
|
||||
t.Fatal("New() returned nil instance")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDNSModifier_New_WithA(t *testing.T) {
|
||||
m := &DNSModifier{}
|
||||
inst, err := m.New(map[string]interface{}{
|
||||
"a": "192.168.1.1",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("New() unexpected error: %v", err)
|
||||
}
|
||||
dnsInst, ok := inst.(*dnsModifierInstance)
|
||||
if !ok {
|
||||
t.Fatalf("New() returned wrong type: %T", inst)
|
||||
}
|
||||
if dnsInst.A == nil || dnsInst.A.String() != "192.168.1.1" {
|
||||
t.Errorf("A = %v, want 192.168.1.1", dnsInst.A)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDNSModifier_New_WithAAAA(t *testing.T) {
|
||||
m := &DNSModifier{}
|
||||
inst, err := m.New(map[string]interface{}{
|
||||
"aaaa": "2001:db8::1",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("New() unexpected error: %v", err)
|
||||
}
|
||||
dnsInst, ok := inst.(*dnsModifierInstance)
|
||||
if !ok {
|
||||
t.Fatalf("New() returned wrong type: %T", inst)
|
||||
}
|
||||
if dnsInst.AAAA == nil || dnsInst.AAAA.String() != "2001:db8::1" {
|
||||
t.Errorf("AAAA = %v, want 2001:db8::1", dnsInst.AAAA)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDNSModifier_New_InvalidA(t *testing.T) {
|
||||
m := &DNSModifier{}
|
||||
_, err := m.New(map[string]interface{}{
|
||||
"a": "not-an-ip",
|
||||
})
|
||||
if err == nil {
|
||||
t.Fatal("New() expected error for invalid A")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDNSModifier_New_InvalidAAAA(t *testing.T) {
|
||||
m := &DNSModifier{}
|
||||
_, err := m.New(map[string]interface{}{
|
||||
"aaaa": "not-an-ip",
|
||||
})
|
||||
if err == nil {
|
||||
t.Fatal("New() expected error for invalid AAAA")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDNSModifierInstance_Process_AType(t *testing.T) {
|
||||
m := &DNSModifier{}
|
||||
inst, err := m.New(map[string]interface{}{
|
||||
"a": "10.10.10.10",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
dnsResp := dnsResponseBytes(t, 1, layers.DNSTypeA, "example.com")
|
||||
modified, err := inst.(*dnsModifierInstance).Process(dnsResp)
|
||||
if err != nil {
|
||||
t.Fatalf("Process() error: %v", err)
|
||||
}
|
||||
|
||||
result := &layers.DNS{}
|
||||
err = result.DecodeFromBytes(modified, gopacket.NilDecodeFeedback)
|
||||
if err != nil {
|
||||
t.Fatalf("decode result: %v", err)
|
||||
}
|
||||
if len(result.Answers) != 1 {
|
||||
t.Fatalf("expected 1 answer, got %d", len(result.Answers))
|
||||
}
|
||||
if result.Answers[0].Type != layers.DNSTypeA {
|
||||
t.Errorf("answer type = %d, want A", result.Answers[0].Type)
|
||||
}
|
||||
if result.Answers[0].IP.String() != "10.10.10.10" {
|
||||
t.Errorf("answer IP = %s, want 10.10.10.10", result.Answers[0].IP)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDNSModifierInstance_Process_AAAAType(t *testing.T) {
|
||||
m := &DNSModifier{}
|
||||
inst, err := m.New(map[string]interface{}{
|
||||
"aaaa": "2001:db8::1",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
dnsResp := dnsResponseBytes(t, 1, layers.DNSTypeAAAA, "example.com")
|
||||
modified, err := inst.(*dnsModifierInstance).Process(dnsResp)
|
||||
if err != nil {
|
||||
t.Fatalf("Process() error: %v", err)
|
||||
}
|
||||
|
||||
result := &layers.DNS{}
|
||||
err = result.DecodeFromBytes(modified, gopacket.NilDecodeFeedback)
|
||||
if err != nil {
|
||||
t.Fatalf("decode result: %v", err)
|
||||
}
|
||||
if len(result.Answers) != 1 {
|
||||
t.Fatalf("expected 1 answer, got %d", len(result.Answers))
|
||||
}
|
||||
if result.Answers[0].Type != layers.DNSTypeAAAA {
|
||||
t.Errorf("answer type = %d, want AAAA", result.Answers[0].Type)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDNSModifierInstance_Process_NotAResponse(t *testing.T) {
|
||||
inst := &dnsModifierInstance{}
|
||||
query := dnsResponseBytes(t, 1, layers.DNSTypeA, "test.com")
|
||||
query[2] &^= 0x80 // clear QR bit
|
||||
|
||||
_, err := inst.Process(query)
|
||||
if err == nil {
|
||||
t.Fatal("expected error for non-response")
|
||||
}
|
||||
errPkt, ok := err.(*modifier.ErrInvalidPacket)
|
||||
if !ok {
|
||||
t.Fatalf("expected *ErrInvalidPacket, got %T", err)
|
||||
}
|
||||
_ = errPkt
|
||||
}
|
||||
|
||||
func TestDNSModifierInstance_Process_NoQuestions(t *testing.T) {
|
||||
inst := &dnsModifierInstance{}
|
||||
dns := &layers.DNS{
|
||||
ID: 1,
|
||||
QR: true,
|
||||
RD: true,
|
||||
RA: true,
|
||||
ResponseCode: layers.DNSResponseCodeNoErr,
|
||||
}
|
||||
buf := gopacket.NewSerializeBuffer()
|
||||
gopacket.SerializeLayers(buf, gopacket.SerializeOptions{FixLengths: true, ComputeChecksums: true}, dns)
|
||||
|
||||
_, err := inst.Process(buf.Bytes())
|
||||
if err == nil {
|
||||
t.Fatal("expected error for empty questions")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user