@@ -47,6 +47,7 @@ import (
4747
4848 "github.com/pelicanplatform/pelican/config"
4949 "github.com/pelicanplatform/pelican/param"
50+ "github.com/pelicanplatform/pelican/pelican_url"
5051 "github.com/pelicanplatform/pelican/server_structs"
5152 "github.com/pelicanplatform/pelican/server_utils"
5253 "github.com/pelicanplatform/pelican/test_utils"
@@ -1294,6 +1295,76 @@ func TestDirectorRegistration(t *testing.T) {
12941295
12951296}
12961297
1298+ func TestUpdateDowntimeFromRegistry (t * testing.T ) {
1299+ server_utils .ResetTestState ()
1300+ ctx , cancel , egrp := test_utils .TestContext (context .Background (), t )
1301+ t .Cleanup (func () {
1302+ cancel ()
1303+ assert .NoError (t , egrp .Wait ())
1304+ server_utils .ResetTestState ()
1305+ })
1306+
1307+ // Mock Registry that always returns an empty downtime list
1308+ ts := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
1309+ if r .Method == http .MethodGet && strings .HasSuffix (r .URL .Path , "/api/v1.0/downtime" ) {
1310+ w .Header ().Set ("Content-Type" , "application/json" )
1311+ _ , _ = w .Write ([]byte ("[]" )) // empty list
1312+ return
1313+ }
1314+ w .WriteHeader (http .StatusNotFound )
1315+ }))
1316+ defer ts .Close ()
1317+
1318+ // Satisfy config.GetFederation() expectations in updateDowntimeFromRegistry func
1319+ config .SetFederation (pelican_url.FederationDiscovery {
1320+ RegistryEndpoint : ts .URL ,
1321+ })
1322+ fedInfo , err := config .GetFederation (ctx )
1323+ require .NoError (t , err )
1324+ require .Equal (t , ts .URL , fedInfo .RegistryEndpoint )
1325+
1326+ now := time .Now ().UTC ().UnixMilli ()
1327+ makeDT := func (start , end int64 ) server_structs.Downtime {
1328+ return server_structs.Downtime {
1329+ UUID : "00000000-0000-0000-0000-000000000000" ,
1330+ ServerName : "test-cache" ,
1331+ CreatedBy : "testuser" ,
1332+ UpdatedBy : "testuser" ,
1333+ Source : "cache" ,
1334+ Class : server_structs .SCHEDULED ,
1335+ Description : "" ,
1336+ Severity : server_structs .Outage ,
1337+ StartTime : start ,
1338+ EndTime : end ,
1339+ CreatedAt : now ,
1340+ UpdatedAt : now ,
1341+ DeletedAt : nil ,
1342+ }
1343+ }
1344+
1345+ // Tests that when the Registry (source of fed admin downtimes) reports no current downtimes for a server,
1346+ // any previously recorded Registry-set downtimes for that server are cleared in the Director.
1347+ t .Run ("clears-registry-downtime-when-deleted" , func (t * testing.T ) {
1348+ // Pre-seed state as if a Registry-set downtime is active
1349+ filteredServersMutex .Lock ()
1350+ filteredServers ["test-cache" ] = tempFiltered
1351+ filteredServersMutex .Unlock ()
1352+ federationDowntimes = map [string ][]server_structs.Downtime {
1353+ "test-cache" : {makeDT (now - 10_000 , now + 10_000 )},
1354+ }
1355+
1356+ require .NoError (t , updateDowntimeFromRegistry (ctx ))
1357+
1358+ // Expect the Registry-derived filter to be gone
1359+ filteredServersMutex .RLock ()
1360+ _ , ok := filteredServers ["test-cache" ]
1361+ filteredServersMutex .RUnlock ()
1362+ assert .False (t , ok , "tempFiltered entry should be removed" )
1363+
1364+ assert .Empty (t , federationDowntimes , "federationDowntimes should be cleared" )
1365+ })
1366+ }
1367+
12971368func TestGetAuthzEscaped (t * testing.T ) {
12981369 // Test passing a token via header with no bearer prefix
12991370 req , err := http .NewRequest (http .MethodPost , "http://fake-server.com" , bytes .NewBuffer ([]byte ("a body" )))
0 commit comments