From bcb0978e9e4370261903a6fc74539fdf681ef5ea Mon Sep 17 00:00:00 2001 From: Shizun Ge Date: Fri, 1 Dec 2023 15:16:05 -0800 Subject: [PATCH] improve scheduler tests. Capture timeNow() before calculation next check at. Check if the desired interval is set. --- internal/config/config_test.go | 14 ++-- internal/model/feed_test.go | 134 +++++++++++++++++++++++---------- 2 files changed, 100 insertions(+), 48 deletions(-) diff --git a/internal/config/config_test.go b/internal/config/config_test.go index f32302ac..a149d7f0 100644 --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -829,7 +829,7 @@ func TestPollingScheduler(t *testing.T) { } } -func TestDefautSchedulerCountBasedMaxIntervalValue(t *testing.T) { +func TestDefautSchedulerEntryFrequencyMaxIntervalValue(t *testing.T) { os.Clearenv() parser := NewParser() @@ -846,7 +846,7 @@ func TestDefautSchedulerCountBasedMaxIntervalValue(t *testing.T) { } } -func TestDefautSchedulerCountBasedMaxInterval(t *testing.T) { +func TestSchedulerEntryFrequencyMaxInterval(t *testing.T) { os.Clearenv() os.Setenv("SCHEDULER_ENTRY_FREQUENCY_MAX_INTERVAL", "30") @@ -864,7 +864,7 @@ func TestDefautSchedulerCountBasedMaxInterval(t *testing.T) { } } -func TestDefautSchedulerCountBasedMinIntervalValue(t *testing.T) { +func TestDefautSchedulerEntryFrequencyMinIntervalValue(t *testing.T) { os.Clearenv() parser := NewParser() @@ -881,7 +881,7 @@ func TestDefautSchedulerCountBasedMinIntervalValue(t *testing.T) { } } -func TestDefautSchedulerCountBasedMinInterval(t *testing.T) { +func TestSchedulerEntryFrequencyMinInterval(t *testing.T) { os.Clearenv() os.Setenv("SCHEDULER_ENTRY_FREQUENCY_MIN_INTERVAL", "30") @@ -916,7 +916,7 @@ func TestDefautSchedulerEntryFrequencyFactorValue(t *testing.T) { } } -func TestDefautSchedulerEntryFrequencyFactor(t *testing.T) { +func TestSchedulerEntryFrequencyFactor(t *testing.T) { os.Clearenv() os.Setenv("SCHEDULER_ENTRY_FREQUENCY_FACTOR", "2") @@ -934,7 +934,7 @@ func TestDefautSchedulerEntryFrequencyFactor(t *testing.T) { } } -func TestSchedulerRoundRobinValue(t *testing.T) { +func TestDefaultSchedulerRoundRobinValue(t *testing.T) { os.Clearenv() parser := NewParser() @@ -951,7 +951,7 @@ func TestSchedulerRoundRobinValue(t *testing.T) { } } -func TestSchedulerRoundRobinDefault(t *testing.T) { +func TestSchedulerRoundRobin(t *testing.T) { os.Clearenv() os.Setenv("SCHEDULER_ROUND_ROBIN_MIN_INTERVAL", "15") diff --git a/internal/model/feed_test.go b/internal/model/feed_test.go index 26b2a919..df5c6885 100644 --- a/internal/model/feed_test.go +++ b/internal/model/feed_test.go @@ -12,6 +12,11 @@ import ( "miniflux.app/v2/internal/config" ) +const ( + largeWeeklyCount = 10080 + noNewTTL = 0 +) + func TestFeedCategorySetter(t *testing.T) { feed := &Feed{} feed.WithCategoryID(int64(123)) @@ -62,7 +67,18 @@ func TestFeedCheckedNow(t *testing.T) { } } +func checkTargetInterval(t *testing.T, feed *Feed, targetInterval int, timeBefore time.Time, message string) { + if feed.NextCheckAt.Before(timeBefore.Add(time.Minute * time.Duration(targetInterval))) { + t.Errorf(`The next_check_at should be after timeBefore + %s`, message) + } + if feed.NextCheckAt.After(time.Now().Add(time.Minute * time.Duration(targetInterval))) { + t.Errorf(`The next_check_at should be before now + %s`, message) + } +} + func TestFeedScheduleNextCheckDefault(t *testing.T) { + os.Clearenv() + var err error parser := config.NewParser() config.Opts, err = parser.ParseEnvironmentVariables() @@ -70,18 +86,17 @@ func TestFeedScheduleNextCheckDefault(t *testing.T) { t.Fatalf(`Parsing failure: %v`, err) } + timeBefore := time.Now() feed := &Feed{} weeklyCount := 10 - newTTL := 0 - feed.ScheduleNextCheck(weeklyCount, newTTL) + feed.ScheduleNextCheck(weeklyCount, noNewTTL) if feed.NextCheckAt.IsZero() { t.Error(`The next_check_at must be set`) } - if feed.NextCheckAt.After(time.Now().Add(time.Minute * time.Duration(config.Opts.PollingFrequency()))) { - t.Error(`The next_check_at should not be after the now + polling frequency`) - } + targetInterval := config.Opts.SchedulerRoundRobinMinInterval() + checkTargetInterval(t, feed, targetInterval, timeBefore, "default SchedulerRoundRobinMinInterval") } func TestFeedScheduleNextCheckRoundRobinMinInterval(t *testing.T) { @@ -96,21 +111,21 @@ func TestFeedScheduleNextCheckRoundRobinMinInterval(t *testing.T) { if err != nil { t.Fatalf(`Parsing failure: %v`, err) } + + timeBefore := time.Now() feed := &Feed{} weeklyCount := 100 - newTTL := 0 - feed.ScheduleNextCheck(weeklyCount, newTTL) + feed.ScheduleNextCheck(weeklyCount, noNewTTL) if feed.NextCheckAt.IsZero() { t.Error(`The next_check_at must be set`) } - if feed.NextCheckAt.After(time.Now().Add(time.Minute * time.Duration(minInterval))) { - t.Error(`The next_check_at should not be after the now + min interval`) - } + targetInterval := minInterval + checkTargetInterval(t, feed, targetInterval, timeBefore, "round robin min interval") } -func TestFeedScheduleNextCheckEntryCountBasedMaxInterval(t *testing.T) { +func TestFeedScheduleNextCheckEntryFrequencyMaxInterval(t *testing.T) { maxInterval := 5 minInterval := 1 os.Clearenv() @@ -124,21 +139,51 @@ func TestFeedScheduleNextCheckEntryCountBasedMaxInterval(t *testing.T) { if err != nil { t.Fatalf(`Parsing failure: %v`, err) } + + timeBefore := time.Now() feed := &Feed{} - weeklyCount := maxInterval * 100 - newTTL := 0 - feed.ScheduleNextCheck(weeklyCount, newTTL) + // Use a very small weekly count to trigger the max interval + weeklyCount := 1 + feed.ScheduleNextCheck(weeklyCount, noNewTTL) if feed.NextCheckAt.IsZero() { t.Error(`The next_check_at must be set`) } - if feed.NextCheckAt.After(time.Now().Add(time.Minute * time.Duration(maxInterval))) { - t.Error(`The next_check_at should not be after the now + max interval`) - } + targetInterval := maxInterval + checkTargetInterval(t, feed, targetInterval, timeBefore, "entry frequency max interval") } -func TestFeedScheduleNextCheckEntryCountBasedMinInterval(t *testing.T) { +func TestFeedScheduleNextCheckEntryFrequencyMaxIntervalZeroWeeklyCount(t *testing.T) { + maxInterval := 5 + minInterval := 1 + os.Clearenv() + os.Setenv("POLLING_SCHEDULER", "entry_frequency") + os.Setenv("SCHEDULER_ENTRY_FREQUENCY_MAX_INTERVAL", fmt.Sprintf("%d", maxInterval)) + os.Setenv("SCHEDULER_ENTRY_FREQUENCY_MIN_INTERVAL", fmt.Sprintf("%d", minInterval)) + + var err error + parser := config.NewParser() + config.Opts, err = parser.ParseEnvironmentVariables() + if err != nil { + t.Fatalf(`Parsing failure: %v`, err) + } + + timeBefore := time.Now() + feed := &Feed{} + // Use a very small weekly count to trigger the max interval + weeklyCount := 0 + feed.ScheduleNextCheck(weeklyCount, noNewTTL) + + if feed.NextCheckAt.IsZero() { + t.Error(`The next_check_at must be set`) + } + + targetInterval := maxInterval + checkTargetInterval(t, feed, targetInterval, timeBefore, "entry frequency max interval") +} + +func TestFeedScheduleNextCheckEntryFrequencyMinInterval(t *testing.T) { maxInterval := 500 minInterval := 100 os.Clearenv() @@ -152,18 +197,19 @@ func TestFeedScheduleNextCheckEntryCountBasedMinInterval(t *testing.T) { if err != nil { t.Fatalf(`Parsing failure: %v`, err) } + + timeBefore := time.Now() feed := &Feed{} - weeklyCount := minInterval / 2 - newTTL := 0 - feed.ScheduleNextCheck(weeklyCount, newTTL) + // Use a very large weekly count to trigger the min interval + weeklyCount := largeWeeklyCount + feed.ScheduleNextCheck(weeklyCount, noNewTTL) if feed.NextCheckAt.IsZero() { t.Error(`The next_check_at must be set`) } - if feed.NextCheckAt.Before(time.Now().Add(time.Minute * time.Duration(minInterval))) { - t.Error(`The next_check_at should not be before the now + min interval`) - } + targetInterval := minInterval + checkTargetInterval(t, feed, targetInterval, timeBefore, "entry frequency min interval") } func TestFeedScheduleNextCheckEntryFrequencyFactor(t *testing.T) { @@ -178,18 +224,18 @@ func TestFeedScheduleNextCheckEntryFrequencyFactor(t *testing.T) { if err != nil { t.Fatalf(`Parsing failure: %v`, err) } + + timeBefore := time.Now() feed := &Feed{} weeklyCount := 7 - newTTL := 0 - feed.ScheduleNextCheck(weeklyCount, newTTL) + feed.ScheduleNextCheck(weeklyCount, noNewTTL) if feed.NextCheckAt.IsZero() { t.Error(`The next_check_at must be set`) } - if feed.NextCheckAt.After(time.Now().Add(time.Minute * time.Duration(config.Opts.SchedulerEntryFrequencyMaxInterval()/factor))) { - t.Error(`The next_check_at should not be after the now + factor * count`) - } + targetInterval := config.Opts.SchedulerEntryFrequencyMaxInterval() / factor + checkTargetInterval(t, feed, targetInterval, timeBefore, "factor * count") } func TestFeedScheduleNextCheckEntryFrequencySmallNewTTL(t *testing.T) { @@ -207,8 +253,11 @@ func TestFeedScheduleNextCheckEntryFrequencySmallNewTTL(t *testing.T) { if err != nil { t.Fatalf(`Parsing failure: %v`, err) } + + timeBefore := time.Now() feed := &Feed{} - weeklyCount := minInterval / 2 + // Use a very large weekly count to trigger the min interval + weeklyCount := largeWeeklyCount // TTL is smaller than minInterval. newTTL := minInterval / 2 feed.ScheduleNextCheck(weeklyCount, newTTL) @@ -217,11 +266,11 @@ func TestFeedScheduleNextCheckEntryFrequencySmallNewTTL(t *testing.T) { t.Error(`The next_check_at must be set`) } - if feed.NextCheckAt.Before(time.Now().Add(time.Minute * time.Duration(minInterval))) { - t.Error(`The next_check_at should not be before the now + min interval`) - } - if feed.NextCheckAt.Before(time.Now().Add(time.Minute * time.Duration(newTTL))) { - t.Error(`The next_check_at should not be before the now + TTL`) + targetInterval := minInterval + checkTargetInterval(t, feed, targetInterval, timeBefore, "entry frequency min interval") + + if feed.NextCheckAt.Before(timeBefore.Add(time.Minute * time.Duration(newTTL))) { + t.Error(`The next_check_at should be after timeBefore + TTL`) } } @@ -240,9 +289,12 @@ func TestFeedScheduleNextCheckEntryFrequencyLargeNewTTL(t *testing.T) { if err != nil { t.Fatalf(`Parsing failure: %v`, err) } + + timeBefore := time.Now() feed := &Feed{} + // Use a very large weekly count to trigger the min interval + weeklyCount := largeWeeklyCount // TTL is larger than minInterval. - weeklyCount := minInterval / 2 newTTL := minInterval * 2 feed.ScheduleNextCheck(weeklyCount, newTTL) @@ -250,10 +302,10 @@ func TestFeedScheduleNextCheckEntryFrequencyLargeNewTTL(t *testing.T) { t.Error(`The next_check_at must be set`) } - if feed.NextCheckAt.Before(time.Now().Add(time.Minute * time.Duration(minInterval))) { - t.Error(`The next_check_at should not be before the now + min interval`) - } - if feed.NextCheckAt.Before(time.Now().Add(time.Minute * time.Duration(newTTL))) { - t.Error(`The next_check_at should not be before the now + TTL`) + targetInterval := newTTL + checkTargetInterval(t, feed, targetInterval, timeBefore, "TTL") + + if feed.NextCheckAt.Before(timeBefore.Add(time.Minute * time.Duration(minInterval))) { + t.Error(`The next_check_at should be after timeBefore + entry frequency min interval`) } }