mirror of
https://github.com/cozystack/cozystack.git
synced 2026-11-12 23:54:01 +09:00
fix(observability-proxy): name the logs time out of range exactly
When both bounds were out of range the answer named one of them at random, as the check walked a map, and it printed the instant without its fraction, so a time one nanosecond past the last one vlselect can hold was shown as a time inside the range. The end is now checked first and the instant is printed in full; tests pin the inclusive bound. Assisted-by: LLM Signed-off-by: ZverGuy <maximbel2003@gmail.com>
This commit is contained in:
1 parent
f8ff307f71
commit
f48a94de6d
2 files changed
+30
-5
No files matched your search
@@ -160,10 +160,11 @@ func window(in url.Values, now time.Time, lim LogsLimits) (time.Time, time.Time,
|
||||
if end.Sub(start) > lim.MaxRange {
|
||||
start = end.Add(-lim.MaxRange)
|
||||
}
|
||||
for k, t := range map[string]time.Time{"start": start, "end": end} {
|
||||
if herr := sendableTime(k, t); herr != nil {
|
||||
return time.Time{}, time.Time{}, herr
|
||||
}
|
||||
if herr := sendableTime("end", end); herr != nil {
|
||||
return time.Time{}, time.Time{}, herr
|
||||
}
|
||||
if herr := sendableTime("start", start); herr != nil {
|
||||
return time.Time{}, time.Time{}, herr
|
||||
}
|
||||
return start.UTC(), end.UTC(), nil
|
||||
}
|
||||
@@ -337,7 +338,7 @@ func scaleDuration(f float64, unit time.Duration) (time.Duration, bool) {
|
||||
// actually sent are checked; an older start is clamped first.
|
||||
func sendableTime(key string, t time.Time) *HTTPError {
|
||||
if t.Before(time.Unix(0, math.MinInt64)) || t.After(time.Unix(0, math.MaxInt64)) {
|
||||
return errorf(http.StatusBadRequest, "invalid %s: %s is outside 1677..2262", key, t.Format(time.RFC3339))
|
||||
return errorf(http.StatusBadRequest, "invalid %s: %s is outside 1677..2262", key, t.UTC().Format(time.RFC3339Nano))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ limitations under the License.
|
||||
package observabilityproxy
|
||||
|
||||
import (
|
||||
"math"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"sort"
|
||||
@@ -408,3 +409,26 @@ func TestBuildLogsParamsOldTimesClamped(t *testing.T) {
|
||||
t.Errorf("start_offset = %s, want the %s cap", got, lim.MaxTailResume)
|
||||
}
|
||||
}
|
||||
|
||||
// TestBuildLogsParamsSendableBoundary pins the inclusive int64-nanosecond
|
||||
// bound and that the refusal names the instant exactly.
|
||||
func TestBuildLogsParamsSendableBoundary(t *testing.T) {
|
||||
last := time.Unix(0, math.MaxInt64).UTC()
|
||||
in := url.Values{"start": {last.Add(-time.Hour).Format(time.RFC3339Nano)}, "end": {last.Format(time.RFC3339Nano)}}
|
||||
if _, herr := BuildLogsParams("query", in, "tenant-a", testNow, testLimits()); herr != nil {
|
||||
t.Fatalf("the last int64 nanosecond refused: %v", herr)
|
||||
}
|
||||
past := last.Add(time.Nanosecond).Format(time.RFC3339Nano)
|
||||
in = url.Values{"start": {last.Add(-time.Hour).Format(time.RFC3339Nano)}, "end": {past}}
|
||||
_, herr := BuildLogsParams("query", in, "tenant-a", testNow, testLimits())
|
||||
if herr == nil || !strings.Contains(herr.Message, "invalid end") || !strings.Contains(herr.Message, past) {
|
||||
t.Fatalf("one nanosecond past answered %v, want end refused naming %s", herr, past)
|
||||
}
|
||||
// Both out of range: the answer names end, deterministically.
|
||||
for range 20 {
|
||||
_, herr := BuildLogsParams("query", url.Values{"start": {"0001-01-01T00:00:00Z"}, "end": {"0001-01-02T00:00:00Z"}}, "tenant-a", testNow, testLimits())
|
||||
if herr == nil || !strings.Contains(herr.Message, "invalid end") {
|
||||
t.Fatalf("answer = %v, want end named", herr)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user