From 374de23cdd1f7b7f6b6f61b17370cbf3b519052c Mon Sep 17 00:00:00 2001 From: Nikolaus Schuetz Date: Mon, 21 Sep 2026 21:08:52 -0400 Subject: [PATCH] test(config): make HasLoadedConfigurationBeenModified deterministic (#1786) * test(config): make HasLoadedConfigurationBeenModified deterministic The two subtests each slept a full second so a rewritten file's mod time (second precision) would advance past the load time. Advance the mod time explicitly with os.Chtimes instead, and give the directory subtest its own temp dir so the file subtest's future-dated config.yaml no longer leaks into it. Removes ~2s of wall-clock sleep and the coarse-clock dependence; the test is now deterministic. * test(config): trim comments to the forward-facing rationale --------- Co-authored-by: TwiN --- config/config_test.go | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/config/config_test.go b/config/config_test.go index 5abfe8e7..cbb6e62b 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -313,20 +313,32 @@ func TestConfig_HasLoadedConfigurationBeenModified(t *testing.T) { if config.HasLoadedConfigurationBeenModified() { t.Errorf("expected config.HasLoadedConfigurationBeenModified() to return false because nothing has happened since it was created") } - time.Sleep(time.Second) // Because the file mod time only has second precision, we have to wait for a second - // Update the config file - if err = os.WriteFile(filepath.Join(dir, "config.yaml"), []byte(`endpoints: + if err = os.WriteFile(configFilePath, []byte(`endpoints: - name: website url: https://twin.sh/health conditions: - "[STATUS] == 200"`), 0o644); err != nil { t.Fatalf("failed to overwrite config file: %v", err) } + // File mod times have second precision, so advance it explicitly. + future := time.Now().Add(2 * time.Second) + if err = os.Chtimes(configFilePath, future, future); err != nil { + t.Fatalf("failed to advance config file mod time: %v", err) + } if !config.HasLoadedConfigurationBeenModified() { - t.Errorf("expected config.HasLoadedConfigurationBeenModified() to return true because a new file has been added in the directory") + t.Errorf("expected config.HasLoadedConfigurationBeenModified() to return true because the config file has been modified") } }) t.Run("config-directory-as-config-path", func(t *testing.T) { + dir := t.TempDir() + if err := os.WriteFile(filepath.Join(dir, "config.yaml"), []byte(`endpoints: + - name: website + url: https://twin.sh/health + conditions: + - "[STATUS] == 200" +`), 0o644); err != nil { + t.Fatalf("failed to write config file: %v", err) + } config, err := LoadConfiguration(dir) if err != nil { t.Fatalf("failed to load configuration: %v", err) @@ -334,10 +346,13 @@ func TestConfig_HasLoadedConfigurationBeenModified(t *testing.T) { if config.HasLoadedConfigurationBeenModified() { t.Errorf("expected config.HasLoadedConfigurationBeenModified() to return false because nothing has happened since it was created") } - time.Sleep(time.Second) // Because the file mod time only has second precision, we have to wait for a second - // Update the config file if err = os.WriteFile(filepath.Join(dir, "metrics.yaml"), []byte(`metrics: true`), 0o644); err != nil { - t.Fatalf("failed to overwrite config file: %v", err) + t.Fatalf("failed to add config file: %v", err) + } + // File mod times have second precision, so advance it explicitly. + future := time.Now().Add(2 * time.Second) + if err = os.Chtimes(filepath.Join(dir, "metrics.yaml"), future, future); err != nil { + t.Fatalf("failed to advance config file mod time: %v", err) } if !config.HasLoadedConfigurationBeenModified() { t.Errorf("expected config.HasLoadedConfigurationBeenModified() to return true because a new file has been added in the directory")