mirror of
https://github.com/j3ssie/osmedeus.git
synced 2026-08-17 21:25:49 +02:00
- Add LLM executor supporting OpenAI vision, tool calling, embeddings, and structured outputs - Introduce event emitter/receiver workflows with deduplication and filtering (generate_event functions) - Add workflow extends/override system enabling inheritance chains and step merge modes - Update function naming to snake_case across all testdata (fileExists→file_exists, etc.) - Add comprehensive test fixtures for linter, events, CDN, step dependencies, and extends workflows
236 lines
5.9 KiB
Go
236 lines
5.9 KiB
Go
package database
|
|
|
|
import (
|
|
"context"
|
|
"path/filepath"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/j3ssie/osmedeus/v5/internal/config"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func setupDiffTestDB(t *testing.T) func() {
|
|
tmpDir := t.TempDir()
|
|
dbPath := filepath.Join(tmpDir, "test_diff.sqlite")
|
|
cfg := &config.Config{
|
|
BaseFolder: tmpDir,
|
|
Database: config.DatabaseConfig{
|
|
DBEngine: "sqlite",
|
|
DBPath: dbPath,
|
|
},
|
|
}
|
|
|
|
_, err := Connect(cfg)
|
|
require.NoError(t, err)
|
|
|
|
ctx := context.Background()
|
|
require.NoError(t, Migrate(ctx))
|
|
|
|
return func() {
|
|
_ = Close()
|
|
SetDB(nil)
|
|
}
|
|
}
|
|
|
|
func TestGetAssetDiff_Added(t *testing.T) {
|
|
cleanup := setupDiffTestDB(t)
|
|
defer cleanup()
|
|
|
|
ctx := context.Background()
|
|
workspace := "test-workspace"
|
|
now := time.Now()
|
|
fromTime := now.Add(-1 * time.Hour)
|
|
toTime := now
|
|
|
|
// Create a baseline asset (before fromTime)
|
|
oldAsset := &Asset{
|
|
Workspace: workspace,
|
|
AssetValue: "old.example.com",
|
|
URL: "https://old.example.com",
|
|
StatusCode: 200,
|
|
CreatedAt: fromTime.Add(-2 * time.Hour),
|
|
UpdatedAt: fromTime.Add(-2 * time.Hour),
|
|
LastSeenAt: fromTime.Add(-1 * time.Hour),
|
|
}
|
|
_, err := GetDB().NewInsert().Model(oldAsset).Exec(ctx)
|
|
require.NoError(t, err)
|
|
|
|
// Create a new asset (after fromTime)
|
|
newAsset := &Asset{
|
|
Workspace: workspace,
|
|
AssetValue: "new.example.com",
|
|
URL: "https://new.example.com",
|
|
StatusCode: 200,
|
|
CreatedAt: now.Add(-30 * time.Minute),
|
|
UpdatedAt: now.Add(-30 * time.Minute),
|
|
LastSeenAt: now,
|
|
}
|
|
_, err = GetDB().NewInsert().Model(newAsset).Exec(ctx)
|
|
require.NoError(t, err)
|
|
|
|
// Get diff
|
|
diff, err := GetAssetDiff(ctx, workspace, fromTime, toTime)
|
|
require.NoError(t, err)
|
|
|
|
// Assert
|
|
assert.Equal(t, workspace, diff.WorkspaceName)
|
|
assert.Equal(t, 1, diff.Summary.TotalAdded)
|
|
assert.Len(t, diff.Added, 1)
|
|
assert.Equal(t, "new.example.com", diff.Added[0].AssetValue)
|
|
}
|
|
|
|
func TestGetAssetDiff_Removed(t *testing.T) {
|
|
cleanup := setupDiffTestDB(t)
|
|
defer cleanup()
|
|
|
|
ctx := context.Background()
|
|
workspace := "test-workspace"
|
|
now := time.Now()
|
|
fromTime := now.Add(-1 * time.Hour)
|
|
toTime := now
|
|
|
|
// Create an old asset that hasn't been seen since before fromTime
|
|
oldAsset := &Asset{
|
|
Workspace: workspace,
|
|
AssetValue: "stale.example.com",
|
|
URL: "https://stale.example.com",
|
|
StatusCode: 200,
|
|
CreatedAt: fromTime.Add(-48 * time.Hour),
|
|
UpdatedAt: fromTime.Add(-48 * time.Hour),
|
|
LastSeenAt: fromTime.Add(-24 * time.Hour), // Last seen 24 hours before fromTime
|
|
}
|
|
_, err := GetDB().NewInsert().Model(oldAsset).Exec(ctx)
|
|
require.NoError(t, err)
|
|
|
|
// Get diff
|
|
diff, err := GetAssetDiff(ctx, workspace, fromTime, toTime)
|
|
require.NoError(t, err)
|
|
|
|
// Assert
|
|
assert.Equal(t, 1, diff.Summary.TotalRemoved)
|
|
assert.Len(t, diff.Removed, 1)
|
|
assert.Equal(t, "stale.example.com", diff.Removed[0].AssetValue)
|
|
}
|
|
|
|
func TestGetAssetDiff_Changed(t *testing.T) {
|
|
cleanup := setupDiffTestDB(t)
|
|
defer cleanup()
|
|
|
|
ctx := context.Background()
|
|
workspace := "test-workspace"
|
|
now := time.Now()
|
|
fromTime := now.Add(-1 * time.Hour)
|
|
toTime := now
|
|
|
|
// Create an asset that was created before fromTime but updated within the range
|
|
changedAsset := &Asset{
|
|
Workspace: workspace,
|
|
AssetValue: "changed.example.com",
|
|
URL: "https://changed.example.com",
|
|
StatusCode: 200,
|
|
CreatedAt: fromTime.Add(-2 * time.Hour), // Created before fromTime
|
|
UpdatedAt: now.Add(-30 * time.Minute), // Updated within range
|
|
LastSeenAt: now,
|
|
}
|
|
_, err := GetDB().NewInsert().Model(changedAsset).Exec(ctx)
|
|
require.NoError(t, err)
|
|
|
|
// Get diff
|
|
diff, err := GetAssetDiff(ctx, workspace, fromTime, toTime)
|
|
require.NoError(t, err)
|
|
|
|
// Assert
|
|
assert.Equal(t, 1, diff.Summary.TotalChanged)
|
|
assert.Len(t, diff.Changed, 1)
|
|
assert.Equal(t, "changed.example.com", diff.Changed[0].AssetValue)
|
|
}
|
|
|
|
func TestGetAssetDiff_Empty(t *testing.T) {
|
|
cleanup := setupDiffTestDB(t)
|
|
defer cleanup()
|
|
|
|
ctx := context.Background()
|
|
workspace := "empty-workspace"
|
|
now := time.Now()
|
|
fromTime := now.Add(-1 * time.Hour)
|
|
toTime := now
|
|
|
|
// Get diff for empty workspace
|
|
diff, err := GetAssetDiff(ctx, workspace, fromTime, toTime)
|
|
require.NoError(t, err)
|
|
|
|
// Assert
|
|
assert.Equal(t, workspace, diff.WorkspaceName)
|
|
assert.Equal(t, 0, diff.Summary.TotalAdded)
|
|
assert.Equal(t, 0, diff.Summary.TotalRemoved)
|
|
assert.Equal(t, 0, diff.Summary.TotalChanged)
|
|
assert.Empty(t, diff.Added)
|
|
assert.Empty(t, diff.Removed)
|
|
assert.Empty(t, diff.Changed)
|
|
}
|
|
|
|
func TestGetAssetDiff_NoDatabase(t *testing.T) {
|
|
// Ensure db is nil
|
|
originalDB := db
|
|
db = nil
|
|
defer func() { db = originalDB }()
|
|
|
|
ctx := context.Background()
|
|
diff, err := GetAssetDiff(ctx, "test", time.Now().Add(-1*time.Hour), time.Now())
|
|
|
|
assert.Error(t, err)
|
|
assert.Nil(t, diff)
|
|
assert.Contains(t, err.Error(), "database not connected")
|
|
}
|
|
|
|
func TestGetVulnerabilityDiff_Added(t *testing.T) {
|
|
cleanup := setupDiffTestDB(t)
|
|
defer cleanup()
|
|
|
|
ctx := context.Background()
|
|
workspace := "test-workspace"
|
|
now := time.Now()
|
|
fromTime := now.Add(-1 * time.Hour)
|
|
toTime := now
|
|
|
|
// Create a new vulnerability (after fromTime)
|
|
newVuln := &Vulnerability{
|
|
Workspace: workspace,
|
|
VulnInfo: "CVE-2024-1234",
|
|
VulnTitle: "Test Vulnerability",
|
|
Severity: "high",
|
|
AssetValue: "vulnerable.example.com",
|
|
CreatedAt: now.Add(-30 * time.Minute),
|
|
UpdatedAt: now.Add(-30 * time.Minute),
|
|
LastSeenAt: now,
|
|
}
|
|
_, err := GetDB().NewInsert().Model(newVuln).Exec(ctx)
|
|
require.NoError(t, err)
|
|
|
|
// Get diff
|
|
diff, err := GetVulnerabilityDiff(ctx, workspace, fromTime, toTime)
|
|
require.NoError(t, err)
|
|
|
|
// Assert
|
|
assert.Equal(t, workspace, diff.WorkspaceName)
|
|
assert.Equal(t, 1, diff.Summary.TotalAdded)
|
|
assert.Len(t, diff.Added, 1)
|
|
assert.Equal(t, "CVE-2024-1234", diff.Added[0].VulnInfo)
|
|
}
|
|
|
|
func TestImportStats(t *testing.T) {
|
|
stats := ImportStats{
|
|
New: 5,
|
|
Updated: 3,
|
|
Unchanged: 10,
|
|
Errors: 2,
|
|
}
|
|
|
|
assert.Equal(t, 5, stats.New)
|
|
assert.Equal(t, 3, stats.Updated)
|
|
assert.Equal(t, 10, stats.Unchanged)
|
|
assert.Equal(t, 2, stats.Errors)
|
|
}
|