package oci import ( "reflect" "testing" "time" "github.com/oracle/oci-go-sdk/v65/audit" "github.com/oracle/oci-go-sdk/v65/common" ) func TestToAuditEvent(t *testing.T) { eventTime := time.Date(2026, 7, 6, 10, 30, 0, 0, time.UTC) tests := []struct { name string ev audit.AuditEvent want AuditEvent }{ { name: "全字段齐全", ev: audit.AuditEvent{ EventId: common.String("evt-abc"), Source: common.String("ComputeApi"), EventTime: &common.SDKTime{Time: eventTime}, Data: &audit.Data{ EventName: common.String("TerminateInstance"), ResourceName: common.String("web-1"), CompartmentName: common.String("prod"), Identity: &audit.Identity{ PrincipalName: common.String("api-admin"), IpAddress: common.String("1.2.3.4"), }, Request: &audit.Request{ Action: common.String("DELETE"), Path: common.String("/20160918/instances/ocid1..."), }, Response: &audit.Response{Status: common.String("204")}, }, }, want: AuditEvent{ EventId: "evt-abc", EventTime: &eventTime, EventName: "TerminateInstance", Source: "ComputeApi", ResourceName: "web-1", CompartmentName: "prod", PrincipalName: "api-admin", IPAddress: "1.2.3.4", Status: "204", RequestAction: "DELETE", RequestPath: "/20160918/instances/ocid1...", }, }, { name: "Data 为 nil 时只保留信封字段", ev: audit.AuditEvent{ Source: common.String("VcnApi"), EventTime: &common.SDKTime{Time: eventTime}, }, want: AuditEvent{EventTime: &eventTime, Source: "VcnApi"}, }, { name: "嵌套局部 nil 各自安全跳过", ev: audit.AuditEvent{ Data: &audit.Data{ EventName: common.String("GetInstance"), Identity: nil, Request: &audit.Request{Path: common.String("/instances")}, Response: nil, }, }, want: AuditEvent{EventName: "GetInstance", RequestPath: "/instances"}, }, { name: "空事件全部零值", ev: audit.AuditEvent{}, want: AuditEvent{}, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if got := toAuditEvent(tt.ev); !auditEventEqual(got, tt.want) { t.Errorf("toAuditEvent() = %+v, want %+v", got, tt.want) } }) } } // auditEventEqual 比较两个 DTO:EventTime 按值比较,Raw 不参与,其余反射比较。 func auditEventEqual(a, b AuditEvent) bool { if (a.EventTime == nil) != (b.EventTime == nil) { return false } if a.EventTime != nil && !a.EventTime.Equal(*b.EventTime) { return false } a.EventTime, b.EventTime = nil, nil a.Raw, b.Raw = nil, nil return reflect.DeepEqual(a, b) } func TestSortAuditEvents(t *testing.T) { t1 := time.Date(2026, 7, 6, 8, 0, 0, 0, time.UTC) t2 := time.Date(2026, 7, 6, 9, 0, 0, 0, time.UTC) items := []AuditEvent{ {EventName: "old", EventTime: &t1}, {EventName: "no-time", EventTime: nil}, {EventName: "new", EventTime: &t2}, } sortAuditEvents(items) got := []string{items[0].EventName, items[1].EventName, items[2].EventName} want := []string{"new", "old", "no-time"} for i := range want { if got[i] != want[i] { t.Fatalf("sortAuditEvents() order = %v, want %v", got, want) } } } func TestKeepAuditEvent(t *testing.T) { cases := []struct { name string event AuditEvent keep bool }{ {"公网IP的普通事件保留", AuditEvent{EventName: "CreateUser", IPAddress: "203.0.113.7"}, true}, {"SummarizeMetricsData 噪声排除", AuditEvent{EventName: "SummarizeMetricsData", IPAddress: "203.0.113.7"}, false}, {"内网10段发起排除", AuditEvent{EventName: "ListInstances", IPAddress: "10.1.2.3"}, false}, {"内网172.16段发起排除", AuditEvent{EventName: "ListInstances", IPAddress: "172.20.0.1"}, false}, {"172.15不属内网保留", AuditEvent{EventName: "ListInstances", IPAddress: "172.15.0.1"}, true}, {"内网192.168段发起排除", AuditEvent{EventName: "ListInstances", IPAddress: "192.168.1.1"}, false}, {"CGNAT 100.64段排除", AuditEvent{EventName: "ListInstances", IPAddress: "100.100.0.1"}, false}, {"100.128不属CGNAT保留", AuditEvent{EventName: "ListInstances", IPAddress: "100.128.0.1"}, true}, {"IP为空保留(控制面事件)", AuditEvent{EventName: "TerminateInstance", IPAddress: ""}, true}, {"IP不可解析保留", AuditEvent{EventName: "ListInstances", IPAddress: "not-an-ip"}, true}, } for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { if got := keepAuditEvent(tc.event); got != tc.keep { t.Fatalf("keepAuditEvent(%+v) = %v, want %v", tc.event, got, tc.keep) } }) } }