From e71d2f36a61215534f6db41f3c21c8f7e3b1ea00 Mon Sep 17 00:00:00 2001 From: Fornax <23104993+0xfornax@users.noreply.github.com> Date: Wed, 7 Oct 2026 14:00:42 -0300 Subject: [PATCH] Add lastChecked for version checks --- .../collectors/version-update-collector.go | 7 ++ .../version-update-collector_test.go | 67 +++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/rocketpool/node/collectors/version-update-collector.go b/rocketpool/node/collectors/version-update-collector.go index 1dec5e4c4..5f448aebc 100644 --- a/rocketpool/node/collectors/version-update-collector.go +++ b/rocketpool/node/collectors/version-update-collector.go @@ -17,6 +17,7 @@ import ( const ( githubLatestReleaseURL = "https://api.github.com/repos/rocket-pool/smartnode/releases/latest" + versionCheckInterval = time.Hour versionCheckTimeout = 15 * time.Second ) @@ -31,6 +32,7 @@ type VersionUpdateCollector struct { mu sync.Mutex updateAvailable float64 latestVersion string + lastChecked time.Time } type githubReleaseResponse struct { @@ -76,6 +78,11 @@ func (collector *VersionUpdateCollector) checkIfDue(ctx context.Context) { collector.mu.Lock() defer collector.mu.Unlock() + if time.Since(collector.lastChecked) < versionCheckInterval { + return + } + collector.lastChecked = time.Now() + updateAvailable, latestVersion, err := collector.checkForUpdate(ctx) if err != nil { if collector.logf != nil { diff --git a/rocketpool/node/collectors/version-update-collector_test.go b/rocketpool/node/collectors/version-update-collector_test.go index 2c9e5b0d5..7ff837bcf 100644 --- a/rocketpool/node/collectors/version-update-collector_test.go +++ b/rocketpool/node/collectors/version-update-collector_test.go @@ -5,6 +5,7 @@ import ( "net/http" "net/http/httptest" "testing" + "time" ) func TestIsNewerVersion(t *testing.T) { @@ -76,3 +77,69 @@ func TestCheckIfDueCachesLatestVersion(t *testing.T) { t.Fatalf("latestVersion = %q, want %q", collector.latestVersion, "v1.20.3") } } + +func TestCheckIfDueHitsGitHubAtMostHourly(t *testing.T) { + var hits int + tag := "v1.20.3" + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + hits++ + _, err := w.Write([]byte(`{"tag_name":"` + tag + `"}`)) + if err != nil { + t.Errorf("error writing response: %v", err) + } + })) + defer server.Close() + + collector := NewVersionUpdateCollector(nil) + collector.current = "1.20.2" + collector.latestURL = server.URL + collector.client = server.Client() + + collector.checkIfDue(context.Background()) + collector.checkIfDue(context.Background()) + if hits != 1 { + t.Fatalf("hits = %d, want 1", hits) + } + if collector.latestVersion != "v1.20.3" { + t.Fatalf("latestVersion = %q, want %q", collector.latestVersion, "v1.20.3") + } + + tag = "v1.20.4" + collector.lastChecked = time.Now().Add(-versionCheckInterval - time.Second) + collector.checkIfDue(context.Background()) + if hits != 2 { + t.Fatalf("hits = %d, want 2", hits) + } + if collector.latestVersion != "v1.20.4" { + t.Fatalf("latestVersion = %q, want %q", collector.latestVersion, "v1.20.4") + } + if collector.updateAvailable != 1 { + t.Fatalf("updateAvailable = %f, want 1", collector.updateAvailable) + } +} + +func TestCheckIfDueBacksOffAfterGitHubError(t *testing.T) { + var hits int + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + hits++ + w.WriteHeader(http.StatusForbidden) + })) + defer server.Close() + + collector := NewVersionUpdateCollector(nil) + collector.current = "1.20.2" + collector.latestURL = server.URL + collector.client = server.Client() + + collector.checkIfDue(context.Background()) + collector.checkIfDue(context.Background()) + if hits != 1 { + t.Fatalf("hits = %d, want 1", hits) + } + if collector.latestVersion != "" { + t.Fatalf("latestVersion = %q, want empty", collector.latestVersion) + } + if collector.updateAvailable != 0 { + t.Fatalf("updateAvailable = %f, want 0", collector.updateAvailable) + } +}