|
1 | 1 | package flags |
2 | 2 |
|
3 | 3 | import ( |
| 4 | + "context" |
4 | 5 | "fmt" |
5 | 6 | "math" |
6 | 7 | "testing" |
7 | 8 |
|
8 | 9 | "github.com/stretchr/testify/assert" |
9 | 10 | "github.com/stretchr/testify/require" |
10 | 11 |
|
| 12 | + pb "github.com/aquasecurity/tracee/api/v1beta1" |
| 13 | + "github.com/aquasecurity/tracee/api/v1beta1/detection" |
| 14 | + "github.com/aquasecurity/tracee/pkg/detectors" |
11 | 15 | "github.com/aquasecurity/tracee/pkg/events" |
12 | 16 | "github.com/aquasecurity/tracee/pkg/filters" |
13 | 17 | k8s "github.com/aquasecurity/tracee/pkg/k8s/apis/tracee.aquasec.com/v1beta1" |
@@ -2488,3 +2492,148 @@ func TestParseEventFilters(t *testing.T) { |
2488 | 2492 | }) |
2489 | 2493 | } |
2490 | 2494 | } |
| 2495 | + |
| 2496 | +func TestParseEventFiltersDetectorTags(t *testing.T) { |
| 2497 | + // NOTE: Not using t.Parallel() because this test modifies global events.Core state |
| 2498 | + |
| 2499 | + // Save and restore events.Core |
| 2500 | + originalCore := events.Core |
| 2501 | + defer func() { events.Core = originalCore }() |
| 2502 | + |
| 2503 | + // Create fresh DefinitionGroup with core events |
| 2504 | + events.Core = events.NewDefinitionGroup() |
| 2505 | + err := events.Core.AddBatch(events.CoreEvents) |
| 2506 | + require.NoError(t, err) |
| 2507 | + |
| 2508 | + // Create mock detectors with tags and register their events |
| 2509 | + mockDetectors := []detection.EventDetector{ |
| 2510 | + createMockDetectorForTagTest("det1", "detector_event1", []string{"test_tag_a"}), |
| 2511 | + createMockDetectorForTagTest("det2", "detector_event2", []string{"test_tag_b"}), |
| 2512 | + createMockDetectorForTagTest("det3", "detector_event3", []string{"test_tag_a", "test_tag_c"}), |
| 2513 | + } |
| 2514 | + |
| 2515 | + // Register detector events in events.Core (simulating what happens at startup) |
| 2516 | + eventNameToID, err := detectors.CreateEventsFromDetectors(events.StartDetectorID, mockDetectors) |
| 2517 | + require.NoError(t, err) |
| 2518 | + |
| 2519 | + testCases := []struct { |
| 2520 | + name string |
| 2521 | + eventFlags []eventFlag |
| 2522 | + validate func(*testing.T, *policy.Policy, map[string]events.ID) |
| 2523 | + }{ |
| 2524 | + { |
| 2525 | + name: "detector tag selection - test_tag_a", |
| 2526 | + eventFlags: []eventFlag{{ |
| 2527 | + full: "test_tag_a", |
| 2528 | + eventName: "test_tag_a", |
| 2529 | + }}, |
| 2530 | + validate: func(t *testing.T, p *policy.Policy, eMap map[string]events.ID) { |
| 2531 | + // Should have detector_event1 and detector_event3 (both have "test_tag_a" tag) |
| 2532 | + assert.Contains(t, p.Rules, eMap["detector_event1"]) |
| 2533 | + assert.Contains(t, p.Rules, eMap["detector_event3"]) |
| 2534 | + assert.NotContains(t, p.Rules, eMap["detector_event2"]) |
| 2535 | + assert.Equal(t, 2, len(p.Rules), "Should have exactly 2 events selected") |
| 2536 | + }, |
| 2537 | + }, |
| 2538 | + { |
| 2539 | + name: "detector tag selection - test_tag_b", |
| 2540 | + eventFlags: []eventFlag{{ |
| 2541 | + full: "test_tag_b", |
| 2542 | + eventName: "test_tag_b", |
| 2543 | + }}, |
| 2544 | + validate: func(t *testing.T, p *policy.Policy, eMap map[string]events.ID) { |
| 2545 | + // Should have only detector_event2 |
| 2546 | + assert.Contains(t, p.Rules, eMap["detector_event2"]) |
| 2547 | + assert.NotContains(t, p.Rules, eMap["detector_event1"]) |
| 2548 | + assert.NotContains(t, p.Rules, eMap["detector_event3"]) |
| 2549 | + assert.Equal(t, 1, len(p.Rules), "Should have exactly 1 event selected") |
| 2550 | + }, |
| 2551 | + }, |
| 2552 | + { |
| 2553 | + name: "detector tag with regular event", |
| 2554 | + eventFlags: []eventFlag{ |
| 2555 | + { |
| 2556 | + full: "test_tag_a", |
| 2557 | + eventName: "test_tag_a", |
| 2558 | + }, |
| 2559 | + { |
| 2560 | + full: "write", |
| 2561 | + eventName: "write", |
| 2562 | + }, |
| 2563 | + }, |
| 2564 | + validate: func(t *testing.T, p *policy.Policy, eMap map[string]events.ID) { |
| 2565 | + // Should have test_tag_a detectors + write syscall |
| 2566 | + assert.Contains(t, p.Rules, eMap["detector_event1"]) |
| 2567 | + assert.Contains(t, p.Rules, eMap["detector_event3"]) |
| 2568 | + assert.Contains(t, p.Rules, events.Write) |
| 2569 | + assert.Equal(t, 3, len(p.Rules), "Should have 3 events selected") |
| 2570 | + }, |
| 2571 | + }, |
| 2572 | + { |
| 2573 | + name: "all detectors set", |
| 2574 | + eventFlags: []eventFlag{{ |
| 2575 | + full: "detectors", |
| 2576 | + eventName: "detectors", |
| 2577 | + }}, |
| 2578 | + validate: func(t *testing.T, p *policy.Policy, eMap map[string]events.ID) { |
| 2579 | + // Should have all detector events (including built-in detectors, so check for ours) |
| 2580 | + assert.Contains(t, p.Rules, eMap["detector_event1"]) |
| 2581 | + assert.Contains(t, p.Rules, eMap["detector_event2"]) |
| 2582 | + assert.Contains(t, p.Rules, eMap["detector_event3"]) |
| 2583 | + // Note: may have more than 3 if there are built-in detectors |
| 2584 | + assert.GreaterOrEqual(t, len(p.Rules), 3, "Should have at least our 3 detector events") |
| 2585 | + }, |
| 2586 | + }, |
| 2587 | + } |
| 2588 | + |
| 2589 | + for _, tc := range testCases { |
| 2590 | + t.Run(tc.name, func(t *testing.T) { |
| 2591 | + // Don't use t.Parallel() here because we need the events.Core state from parent test |
| 2592 | + // Create fresh policy for each test case |
| 2593 | + p := policy.NewPolicy() |
| 2594 | + |
| 2595 | + err := parseEventFilters(p, tc.eventFlags, mockDetectors) |
| 2596 | + require.NoError(t, err) |
| 2597 | + |
| 2598 | + if tc.validate != nil { |
| 2599 | + tc.validate(t, p, eventNameToID) |
| 2600 | + } |
| 2601 | + }) |
| 2602 | + } |
| 2603 | +} |
| 2604 | + |
| 2605 | +// createMockDetectorForTagTest creates a mock detector for tag testing |
| 2606 | +func createMockDetectorForTagTest(id, eventName string, tags []string) detection.EventDetector { |
| 2607 | + return &mockDetectorForPolicyTest{ |
| 2608 | + id: id, |
| 2609 | + eventName: eventName, |
| 2610 | + tags: tags, |
| 2611 | + } |
| 2612 | +} |
| 2613 | + |
| 2614 | +// mockDetectorForPolicyTest implements detection.EventDetector for policy testing |
| 2615 | +type mockDetectorForPolicyTest struct { |
| 2616 | + id string |
| 2617 | + eventName string |
| 2618 | + tags []string |
| 2619 | +} |
| 2620 | + |
| 2621 | +func (m *mockDetectorForPolicyTest) GetDefinition() detection.DetectorDefinition { |
| 2622 | + return detection.DetectorDefinition{ |
| 2623 | + ID: m.id, |
| 2624 | + ProducedEvent: pb.EventDefinition{ |
| 2625 | + Name: m.eventName, |
| 2626 | + Description: "Mock detector for policy test", |
| 2627 | + Tags: m.tags, |
| 2628 | + }, |
| 2629 | + Requirements: detection.DetectorRequirements{}, |
| 2630 | + } |
| 2631 | +} |
| 2632 | + |
| 2633 | +func (m *mockDetectorForPolicyTest) Init(params detection.DetectorParams) error { |
| 2634 | + return nil |
| 2635 | +} |
| 2636 | + |
| 2637 | +func (m *mockDetectorForPolicyTest) OnEvent(ctx context.Context, event *pb.Event) ([]detection.DetectorOutput, error) { |
| 2638 | + return nil, nil |
| 2639 | +} |
0 commit comments