Skip to content

Commit

Permalink
improve scheduler tests.
Browse files Browse the repository at this point in the history
Capture timeNow() before calculation next check at.
Check if the desired interval is set.
  • Loading branch information
shizunge committed Dec 2, 2023
1 parent 5de0714 commit e600796
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 47 deletions.
14 changes: 7 additions & 7 deletions internal/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -829,7 +829,7 @@ func TestPollingScheduler(t *testing.T) {
}
}

func TestDefautSchedulerCountBasedMaxIntervalValue(t *testing.T) {
func TestDefautSchedulerEntryFrequencyMaxIntervalValue(t *testing.T) {
os.Clearenv()

parser := NewParser()
Expand All @@ -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")

Expand All @@ -864,7 +864,7 @@ func TestDefautSchedulerCountBasedMaxInterval(t *testing.T) {
}
}

func TestDefautSchedulerCountBasedMinIntervalValue(t *testing.T) {
func TestDefautSchedulerEntryFrequencyMinIntervalValue(t *testing.T) {
os.Clearenv()

parser := NewParser()
Expand All @@ -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")

Expand Down Expand Up @@ -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")

Expand All @@ -934,7 +934,7 @@ func TestDefautSchedulerEntryFrequencyFactor(t *testing.T) {
}
}

func TestSchedulerRoundRobinValue(t *testing.T) {
func TestDefaultSchedulerRoundRobinValue(t *testing.T) {
os.Clearenv()

parser := NewParser()
Expand All @@ -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")

Expand Down
132 changes: 92 additions & 40 deletions internal/model/feed_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down Expand Up @@ -62,26 +67,36 @@ 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()
if err != nil {
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) {
Expand All @@ -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()
Expand All @@ -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 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 TestFeedScheduleNextCheckEntryCountBasedMinInterval(t *testing.T) {
func TestFeedScheduleNextCheckEntryFrequencyMinInterval(t *testing.T) {
maxInterval := 500
minInterval := 100
os.Clearenv()
Expand All @@ -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) {
Expand All @@ -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) {
Expand All @@ -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)
Expand All @@ -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`)
}
}

Expand All @@ -240,20 +289,23 @@ 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)

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`)
}
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`)
}
}

0 comments on commit e600796

Please sign in to comment.