Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -1898,5 +1898,5 @@ func ResetConfig() {

ResetClientInitialized()

// other than what's above, resetting Origin exports will be done by ResetTestState() in server_utils pkg
// There are other test state resets in server_utils.ResetTestState()
}
9 changes: 4 additions & 5 deletions director/cache_ads.go
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ func getCachedDowntimes(serverName string) ([]server_structs.Downtime, error) {
// Get the downtimes set by federation admin in the Registry
func updateDowntimeFromRegistry(ctx context.Context) error {
fedInfo, err := config.GetFederation(ctx)
if err != nil || fedInfo.DirectorEndpoint == "" {
if err != nil || fedInfo.RegistryEndpoint == "" {
log.Error("Failed to get federation info: ", err)
return errors.Wrap(err, "failed to get federation info")
}
Expand Down Expand Up @@ -398,10 +398,9 @@ func updateDowntimeFromRegistry(ctx context.Context) error {
return errors.Wrap(err, "failed to marshal response in to JSON")
}

if len(latestFedDowntimes) == 0 {
log.Debug("No downtimes set by federation admin in the Registry")
return nil
}
// If `latestFedDowntimes` is empty, it means there's no downtime set by federation admin,
// or the downtime is expired (deleted). In either case, we still need to proceed to use
// it to update `filteredServers` and `federationDowntimes`, clearing out stale info.

filteredServersMutex.Lock()
defer filteredServersMutex.Unlock()
Expand Down
71 changes: 71 additions & 0 deletions director/director_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import (

"github.com/pelicanplatform/pelican/config"
"github.com/pelicanplatform/pelican/param"
"github.com/pelicanplatform/pelican/pelican_url"
"github.com/pelicanplatform/pelican/server_structs"
"github.com/pelicanplatform/pelican/server_utils"
"github.com/pelicanplatform/pelican/test_utils"
Expand Down Expand Up @@ -1294,6 +1295,76 @@ func TestDirectorRegistration(t *testing.T) {

}

func TestUpdateDowntimeFromRegistry(t *testing.T) {
server_utils.ResetTestState()
ctx, cancel, egrp := test_utils.TestContext(context.Background(), t)
t.Cleanup(func() {
cancel()
assert.NoError(t, egrp.Wait())
server_utils.ResetTestState()
})

// Mock Registry that always returns an empty downtime list
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodGet && strings.HasSuffix(r.URL.Path, "/api/v1.0/downtime") {
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write([]byte("[]")) // empty list
return
}
w.WriteHeader(http.StatusNotFound)
}))
defer ts.Close()

// Satisfy config.GetFederation() expectations in updateDowntimeFromRegistry func
config.SetFederation(pelican_url.FederationDiscovery{
RegistryEndpoint: ts.URL,
})
fedInfo, err := config.GetFederation(ctx)
require.NoError(t, err)
require.Equal(t, ts.URL, fedInfo.RegistryEndpoint)

now := time.Now().UTC().UnixMilli()
makeDT := func(start, end int64) server_structs.Downtime {
return server_structs.Downtime{
UUID: "00000000-0000-0000-0000-000000000000",
ServerName: "test-cache",
CreatedBy: "testuser",
UpdatedBy: "testuser",
Source: "cache",
Class: server_structs.SCHEDULED,
Description: "",
Severity: server_structs.Outage,
StartTime: start,
EndTime: end,
CreatedAt: now,
UpdatedAt: now,
DeletedAt: nil,
}
}

// Tests that when the Registry (source of fed admin downtimes) reports no current downtimes for a server,
// any previously recorded Registry-set downtimes for that server are cleared in the Director.
t.Run("clears-registry-downtime-when-deleted", func(t *testing.T) {
// Pre-seed state as if a Registry-set downtime is active
filteredServersMutex.Lock()
filteredServers["test-cache"] = tempFiltered
filteredServersMutex.Unlock()
federationDowntimes = map[string][]server_structs.Downtime{
"test-cache": {makeDT(now-10_000, now+10_000)},
}

require.NoError(t, updateDowntimeFromRegistry(ctx))

// Expect the Registry-derived filter to be gone
filteredServersMutex.RLock()
_, ok := filteredServers["test-cache"]
filteredServersMutex.RUnlock()
assert.False(t, ok, "tempFiltered entry should be removed")

assert.Empty(t, federationDowntimes, "federationDowntimes should be cleared")
})
}

func TestGetAuthzEscaped(t *testing.T) {
// Test passing a token via header with no bearer prefix
req, err := http.NewRequest(http.MethodPost, "http://fake-server.com", bytes.NewBuffer([]byte("a body")))
Expand Down
Loading