From 46806b7b0b3c4d10779f505431856a809dea42c0 Mon Sep 17 00:00:00 2001 From: "Sascha L. Teichmann" Date: Fri, 29 Sep 2023 06:55:49 +0200 Subject: [PATCH] Fix year folder check --- cmd/csaf_checker/processor.go | 10 +++---- internal/models/models.go | 13 ++++++++ internal/models/models_test.go | 55 ++++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 6 deletions(-) diff --git a/cmd/csaf_checker/processor.go b/cmd/csaf_checker/processor.go index 552472fb..8eb64046 100644 --- a/cmd/csaf_checker/processor.go +++ b/cmd/csaf_checker/processor.go @@ -33,6 +33,7 @@ import ( "golang.org/x/time/rate" "github.com/csaf-poc/csaf_distribution/v3/csaf" + "github.com/csaf-poc/csaf_distribution/v3/internal/models" "github.com/csaf-poc/csaf_distribution/v3/util" ) @@ -666,12 +667,9 @@ func (p *processor) integrity( var folderYear *int if m := yearFromURL.FindStringSubmatch(u); m != nil { year, _ := strconv.Atoi(m[1]) - // Check if we are in checking time interval. - if accept := p.cfg.Range; accept != nil && !accept.Contains( - time.Date( - year, 12, 31, // Assume last day of year. - 23, 59, 59, 0, // 23:59:59 - time.UTC)) { + // Check if the year is in the accepted time interval. + if accept := p.cfg.Range; accept != nil && + !accept.Intersects(models.Year(year)) { continue } folderYear = &year diff --git a/internal/models/models.go b/internal/models/models.go index 3b834feb..fad85c34 100644 --- a/internal/models/models.go +++ b/internal/models/models.go @@ -28,6 +28,14 @@ func NewTimeInterval(a, b time.Time) TimeRange { return TimeRange{a, b} } +// Year returns the time range for a given year. +func Year(year int) TimeRange { + return TimeRange{ + time.Date(year, time.January, 1, 0, 0, 0, 0, time.UTC), + time.Date(year, time.December, 31, 23, 59, 59, int(time.Second-time.Nanosecond), time.UTC), + } +} + // guessDate tries to guess an RFC 3339 date time from a given string. func guessDate(s string) (time.Time, bool) { for _, layout := range []string{ @@ -100,3 +108,8 @@ func (tr *TimeRange) UnmarshalFlag(s string) error { func (tr TimeRange) Contains(t time.Time) bool { return !(t.Before(tr[0]) || t.After(tr[1])) } + +// Intersects returns true if the two time ranges intersects. +func (tr TimeRange) Intersects(other TimeRange) bool { + return !(other[1].Before(tr[0]) || tr[1].Before(other[0])) +} diff --git a/internal/models/models_test.go b/internal/models/models_test.go index 7da674f4..ffbcb9c0 100644 --- a/internal/models/models_test.go +++ b/internal/models/models_test.go @@ -111,3 +111,58 @@ func TestContains(t *testing.T) { t.Errorf("Failure: Did not recognize that a point in time was before a timerange correctly.") } } + +// TestTimeRangeIntersects checks if TimeRange.Intersects works. +func TestTimeRangeIntersects(t *testing.T) { + var ( + a = time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC) + b = a.AddDate(0, 0, 10) + c = b.AddDate(0, 0, 10) + d = c.AddDate(0, 0, 10) + ) + for _, x := range []struct { + ranges [2]TimeRange + expected bool + }{ + {ranges: [2]TimeRange{{a, b}, {a, b}}, expected: true}, // equal + {ranges: [2]TimeRange{{a, b}, {c, d}}, expected: false}, // disjoint + {ranges: [2]TimeRange{{a, b}, {b, c}}, expected: true}, // touching + {ranges: [2]TimeRange{{a, c}, {b, d}}, expected: true}, // overlapping + {ranges: [2]TimeRange{{a, d}, {b, c}}, expected: true}, // containing + {ranges: [2]TimeRange{{a, b}, {a, c}}, expected: true}, // containing touch left + {ranges: [2]TimeRange{{b, c}, {a, c}}, expected: true}, // containing touch right + } { + got1 := x.ranges[0].Intersects(x.ranges[1]) + got2 := x.ranges[1].Intersects(x.ranges[0]) + if got1 != got2 { + t.Fatalf("intersecting %v is not commutative", x.ranges) + } + if got1 != x.expected { + t.Fatalf("%v: got %t expected %t", x.ranges, got1, x.expected) + } + } +} + +// TestTimeRangeYear checks if the Year construction works. +func TestTimeRangeYear(t *testing.T) { + var ( + year = Year(1984) + first = time.Date(1984, time.January, 1, 0, 0, 0, 0, time.UTC) + before = first.Add(-time.Nanosecond) + after = time.Date(1984+1, time.January, 1, 0, 0, 0, 0, time.UTC) + last = after.Add(-time.Nanosecond) + ) + for _, x := range []struct { + t time.Time + expected bool + }{ + {t: first, expected: true}, + {t: before, expected: false}, + {t: last, expected: true}, + {t: after, expected: false}, + } { + if got := year.Contains(x.t); got != x.expected { + t.Fatalf("%v: got %t expected %t", x.t, got, x.expected) + } + } +}