@@ -15,6 +15,7 @@ import (
1515 "net/url"
1616 "os"
1717 "path/filepath"
18+ "strings"
1819 "sync"
1920 "testing"
2021 "time"
@@ -34,6 +35,39 @@ import (
3435 "github.com/stretchr/testify/require"
3536)
3637
38+ type fakeFSO struct {
39+ renameSrc , renameDst string
40+ renameExternalCalled bool
41+ }
42+
43+ func (f * fakeFSO ) File (ctx context.Context , file * mpi.File , tempFilePath , expectedHash string ) error {
44+ return nil
45+ }
46+
47+ func (f * fakeFSO ) UpdateOverview (ctx context.Context , instanceID string , filesToUpdate []* mpi.File , configPath string ,
48+ iteration int ,
49+ ) error {
50+ return nil
51+ }
52+
53+ func (f * fakeFSO ) ChunkedFile (ctx context.Context , file * mpi.File , tempFilePath , expectedHash string ) error {
54+ return nil
55+ }
56+ func (f * fakeFSO ) IsConnected () bool { return true }
57+ func (f * fakeFSO ) UpdateFile (ctx context.Context , instanceID string , fileToUpdate * mpi.File ) error {
58+ return nil
59+ }
60+ func (f * fakeFSO ) SetIsConnected (isConnected bool ) {}
61+ func (f * fakeFSO ) RenameFile (ctx context.Context , hash , fileName , tempDir string ) error { return nil }
62+ func (f * fakeFSO ) RenameExternalFile (ctx context.Context , fileName , tempDir string ) error {
63+ f .renameExternalCalled = true
64+ f .renameSrc = fileName
65+ f .renameDst = tempDir
66+
67+ return nil
68+ }
69+ func (f * fakeFSO ) UpdateClient (ctx context.Context , fileServiceClient mpi.FileServiceClient ) {}
70+
3771func TestFileManagerService_ConfigApply_Add (t * testing.T ) {
3872 ctx := context .Background ()
3973 tempDir := t .TempDir ()
@@ -1399,3 +1433,107 @@ func TestFileManagerService_downloadExternalFiles_Cases(t *testing.T) {
13991433 })
14001434 }
14011435}
1436+
1437+ func TestMoveOrDeleteFiles_ExternalFileRenameCalled (t * testing.T ) {
1438+ ctx := context .Background ()
1439+ fms := NewFileManagerService (nil , types .AgentConfig (), & sync.RWMutex {})
1440+
1441+ fake := & fakeFSO {}
1442+ fms .fileServiceOperator = fake
1443+
1444+ fileName := filepath .Join (t .TempDir (), "ext.conf" )
1445+ fms .fileActions = map [string ]* model.FileCache {
1446+ fileName : {
1447+ File : & mpi.File {FileMeta : & mpi.FileMeta {Name : fileName }},
1448+ Action : model .ExternalFile ,
1449+ },
1450+ }
1451+
1452+ tempPath := tempFilePath (fileName )
1453+ reqDir := filepath .Dir (tempPath )
1454+ require .NoError (t , os .MkdirAll (reqDir , 0o755 ))
1455+ require .NoError (t , os .WriteFile (tempPath , []byte ("data" ), 0o600 ))
1456+
1457+ err := fms .moveOrDeleteFiles (ctx , nil )
1458+ require .NoError (t , err )
1459+ assert .True (t , fake .renameExternalCalled )
1460+ assert .Equal (t , tempPath , fake .renameSrc )
1461+ assert .Equal (t , fileName , fake .renameDst )
1462+ }
1463+
1464+ func TestDownloadFileContent_MaxBytesLimit (t * testing.T ) {
1465+ ctx := context .Background ()
1466+ fms := NewFileManagerService (nil , types .AgentConfig (), & sync.RWMutex {})
1467+
1468+ // test server returns 10 bytes, we set MaxBytes to 4 and expect only 4 bytes returned
1469+ ts := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
1470+ w .Header ().Set ("ETag" , "etag-1" )
1471+ w .WriteHeader (http .StatusOK )
1472+ _ , _ = w .Write ([]byte ("0123456789" ))
1473+ }))
1474+ defer ts .Close ()
1475+
1476+ u , err := url .Parse (ts .URL )
1477+ require .NoError (t , err )
1478+
1479+ fms .agentConfig .ExternalDataSource = & config.ExternalDataSource {
1480+ AllowedDomains : []string {u .Hostname ()},
1481+ MaxBytes : 4 ,
1482+ }
1483+
1484+ fileName := filepath .Join (t .TempDir (), "external.conf" )
1485+ file := & mpi.File {
1486+ FileMeta : & mpi.FileMeta {Name : fileName },
1487+ ExternalDataSource : & mpi.ExternalDataSource {Location : ts .URL },
1488+ }
1489+
1490+ content , headers , err := fms .downloadFileContent (ctx , file )
1491+ require .NoError (t , err )
1492+ assert .Len (t , content , 4 )
1493+ assert .Equal (t , "etag-1" , headers .ETag )
1494+ }
1495+
1496+ func TestDownloadFileContent_InvalidProxyURL (t * testing.T ) {
1497+ ctx := context .Background ()
1498+ fms := NewFileManagerService (nil , types .AgentConfig (), & sync.RWMutex {})
1499+
1500+ downURL := "http://example.com/file"
1501+ fms .agentConfig .ExternalDataSource = & config.ExternalDataSource {
1502+ AllowedDomains : []string {"example.com" },
1503+ ProxyURL : config.ProxyURL {URL : "http://:" },
1504+ }
1505+
1506+ file := & mpi.File {
1507+ FileMeta : & mpi.FileMeta {Name : "/tmp/file" },
1508+ ExternalDataSource : & mpi.ExternalDataSource {Location : downURL },
1509+ }
1510+
1511+ _ , _ , err := fms .downloadFileContent (ctx , file )
1512+ require .Error (t , err )
1513+ if ! strings .Contains (err .Error (), "invalid proxy URL configured" ) &&
1514+ ! strings .Contains (err .Error (), "failed to execute download request" ) &&
1515+ ! strings .Contains (err .Error (), "proxyconnect" ) {
1516+ t .Fatalf ("unexpected error: %v" , err )
1517+ }
1518+ }
1519+
1520+ func TestIsDomainAllowed_EdgeCases (t * testing.T ) {
1521+ ok := isDomainAllowed ("http://%" , []string {"example.com" })
1522+ assert .False (t , ok )
1523+
1524+ ok = isDomainAllowed ("http://" , []string {"example.com" })
1525+ assert .False (t , ok )
1526+
1527+ ok = isDomainAllowed ("http://example.com/path" , []string {"" })
1528+ assert .False (t , ok )
1529+
1530+ ok = isDomainAllowed ("http://example.com/path" , []string {"example.com" })
1531+ assert .True (t , ok )
1532+
1533+ ok = isDomainAllowed ("http://sub.example.com/path" , []string {"*.example.com" })
1534+ assert .True (t , ok )
1535+
1536+ assert .True (t , isWildcardMatch ("example.com" , "*.example.com" ))
1537+ assert .True (t , isWildcardMatch ("sub.example.com" , "*.example.com" ))
1538+ assert .False (t , isWildcardMatch ("badexample.com" , "*.example.com" ))
1539+ }
0 commit comments