mirror of
https://github.com/shadow1ng/fscan.git
synced 2026-09-25 12:41:53 +08:00
test: 补充单元测试覆盖率 29.9% → 36.6%
新建 18 个测试文件,追加 30 个已有测试文件,覆盖协议解析、 错误分类、CEL 表达式求值、YAML 反序列化、字节编码等纯函数。
This commit is contained in:
@@ -38,3 +38,192 @@ func appendNTLMAVPair(dst []byte, id uint16, value string) []byte {
|
||||
}
|
||||
return append(dst, buf...)
|
||||
}
|
||||
|
||||
// --- NetBIOSInfo.Summary ---
|
||||
|
||||
func TestNetBIOSInfoSummary(t *testing.T) {
|
||||
p := NewNetBIOSPlugin()
|
||||
_ = p // 仅用于确认插件可实例化,Summary 是值方法
|
||||
|
||||
cases := []struct {
|
||||
name string
|
||||
info NetBIOSInfo
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "invalid returns empty",
|
||||
info: NetBIOSInfo{Valid: false},
|
||||
want: "",
|
||||
},
|
||||
{
|
||||
name: "computer + domain no dot",
|
||||
info: NetBIOSInfo{Valid: true, ComputerName: "PC01", DomainName: "CORP"},
|
||||
want: "CORP\\PC01",
|
||||
},
|
||||
{
|
||||
name: "computer with dot ignores domain prefix",
|
||||
info: NetBIOSInfo{Valid: true, ComputerName: "pc01.corp.local", DomainName: "CORP"},
|
||||
want: "pc01.corp.local",
|
||||
},
|
||||
{
|
||||
name: "no computer uses server service + domain",
|
||||
info: NetBIOSInfo{Valid: true, ServerService: "SRV01", DomainName: "CORP"},
|
||||
want: "CORP\\SRV01",
|
||||
},
|
||||
{
|
||||
name: "no computer uses workstation + netbios domain",
|
||||
info: NetBIOSInfo{Valid: true, WorkstationService: "WKS01", NetBIOSDomainName: "WORKGROUP"},
|
||||
want: "WORKGROUP\\WKS01",
|
||||
},
|
||||
{
|
||||
name: "domain controller prefix",
|
||||
info: NetBIOSInfo{Valid: true, ComputerName: "DC1", DomainName: "CORP", DomainControllers: "CORP"},
|
||||
want: "DC:CORP\\DC1",
|
||||
},
|
||||
{
|
||||
name: "os version appended",
|
||||
info: NetBIOSInfo{Valid: true, ComputerName: "PC01", DomainName: "CORP", OSVersion: "Windows 10"},
|
||||
want: "CORP\\PC01 Windows 10",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
got := tc.info.Summary()
|
||||
if got != tc.want {
|
||||
t.Errorf("got %q, want %q", got, tc.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// --- parseNetBIOSNames ---
|
||||
|
||||
func TestParseNetBIOSNames(t *testing.T) {
|
||||
p := &NetBIOSPlugin{}
|
||||
|
||||
t.Run("data too short", func(t *testing.T) {
|
||||
_, err := p.parseNetBIOSNames(make([]byte, 40))
|
||||
if err == nil {
|
||||
t.Fatal("expected error for short data")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("numNames zero", func(t *testing.T) {
|
||||
data := make([]byte, 57) // index 56 = 0
|
||||
_, err := p.parseNetBIOSNames(data)
|
||||
if err == nil {
|
||||
t.Fatal("expected error for zero numNames")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("parses workstation and domain records", func(t *testing.T) {
|
||||
header := make([]byte, 57)
|
||||
header[56] = 2 // 2 records
|
||||
|
||||
// Record 1: WorkstationService — flagByte=0x00, nameFlags=0x04 (unique, <128)
|
||||
rec1 := make([]byte, 18)
|
||||
copy(rec1, []byte("TESTPC ")) // 15 bytes
|
||||
rec1[15] = 0x00 // flagByte = WorkstationService
|
||||
rec1[16] = 0x04 // nameFlags unique
|
||||
rec1[17] = 0x00
|
||||
|
||||
// Record 2: DomainName — flagByte=0x00, nameFlags=0x84 (group, >=128)
|
||||
rec2 := make([]byte, 18)
|
||||
copy(rec2, []byte("WORKGROUP ")) // 15 bytes
|
||||
rec2[15] = 0x00 // flagByte = DomainName for group
|
||||
rec2[16] = 0x84 // nameFlags group
|
||||
rec2[17] = 0x00
|
||||
|
||||
data := append(header, rec1...)
|
||||
data = append(data, rec2...)
|
||||
|
||||
info, err := p.parseNetBIOSNames(data)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if !info.Valid {
|
||||
t.Fatal("expected Valid=true")
|
||||
}
|
||||
if info.WorkstationService != "TESTPC" {
|
||||
t.Errorf("WorkstationService = %q, want TESTPC", info.WorkstationService)
|
||||
}
|
||||
if info.DomainName != "WORKGROUP" {
|
||||
t.Errorf("DomainName = %q, want WORKGROUP", info.DomainName)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// --- cleanOSString ---
|
||||
|
||||
func TestCleanOSString(t *testing.T) {
|
||||
p := &NetBIOSPlugin{}
|
||||
|
||||
cases := []struct {
|
||||
name string
|
||||
data []byte
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "empty",
|
||||
data: []byte{},
|
||||
want: "",
|
||||
},
|
||||
{
|
||||
name: "plain ascii",
|
||||
data: []byte("Windows Server 2019"),
|
||||
want: "Windows Server 2019",
|
||||
},
|
||||
{
|
||||
name: "double null splits sections, first is returned",
|
||||
data: append([]byte("Windows 10\x00\x00"), []byte("Service Pack 1")...),
|
||||
want: "Windows 10",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
got := p.cleanOSString(tc.data)
|
||||
if got != tc.want {
|
||||
t.Errorf("got %q, want %q", got, tc.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// --- parseUnicodeString (NetBIOSPlugin) ---
|
||||
|
||||
func TestNetBIOSParseUnicodeString(t *testing.T) {
|
||||
p := &NetBIOSPlugin{}
|
||||
|
||||
cases := []struct {
|
||||
name string
|
||||
data []byte
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "empty",
|
||||
data: []byte{},
|
||||
want: "",
|
||||
},
|
||||
{
|
||||
name: "odd length returns empty",
|
||||
data: []byte{0x41},
|
||||
want: "",
|
||||
},
|
||||
{
|
||||
name: "UTF-16LE AB",
|
||||
data: []byte{0x41, 0x00, 0x42, 0x00},
|
||||
want: "AB",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
got := p.parseUnicodeString(tc.data)
|
||||
if got != tc.want {
|
||||
t.Errorf("got %q, want %q", got, tc.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user