2025-12-22 04:38:48 -05:00
// Copyright The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package teststorage
import (
"errors"
2026-01-21 03:21:56 -05:00
"math"
2025-12-22 04:38:48 -05:00
"testing"
2026-01-14 08:48:33 -05:00
"github.com/prometheus/common/model"
2025-12-22 04:38:48 -05:00
"github.com/stretchr/testify/require"
"github.com/prometheus/prometheus/model/exemplar"
"github.com/prometheus/prometheus/model/labels"
"github.com/prometheus/prometheus/model/metadata"
2026-01-21 03:21:56 -05:00
"github.com/prometheus/prometheus/model/value"
2026-01-14 08:48:33 -05:00
"github.com/prometheus/prometheus/storage"
"github.com/prometheus/prometheus/tsdb/tsdbutil"
2025-12-22 04:38:48 -05:00
"github.com/prometheus/prometheus/util/testutil"
)
2026-01-14 08:48:33 -05:00
func testAppendableV1 ( t * testing . T , appTest * Appendable , a storage . Appendable ) {
for _ , commit := range [ ] bool { true , false } {
appTest . ResultReset ( )
app := a . Appender ( t . Context ( ) )
ref1 , err := app . Append ( 0 , labels . FromStrings ( model . MetricNameLabel , "test_metric1" , "app" , "v1" ) , 1 , 2 )
require . NoError ( t , err )
h := tsdbutil . GenerateTestHistogram ( 0 )
_ , err = app . AppendHistogram ( 0 , labels . FromStrings ( model . MetricNameLabel , "test_metric2" , "app" , "v1" ) , 2 , h , nil )
require . NoError ( t , err )
fh := tsdbutil . GenerateTestFloatHistogram ( 0 )
_ , err = app . AppendHistogram ( 0 , labels . FromStrings ( model . MetricNameLabel , "test_metric3" , "app" , "v1" ) , 3 , nil , fh )
require . NoError ( t , err )
// Update meta of first series.
m1 := metadata . Metadata { Type : "gauge" , Unit : "" , Help : "other help text" }
_ , err = app . UpdateMetadata ( ref1 , labels . FromStrings ( model . MetricNameLabel , "test_metric1" , "app" , "v1" ) , m1 )
require . NoError ( t , err )
// Add exemplars to the first series.
e1 := exemplar . Exemplar { Labels : labels . FromStrings ( model . MetricNameLabel , "yolo" ) , HasTs : true , Ts : 1 }
_ , err = app . AppendExemplar ( ref1 , labels . FromStrings ( model . MetricNameLabel , "test_metric1" , "app" , "v1" ) , e1 )
require . NoError ( t , err )
exp := [ ] Sample {
{ L : labels . FromStrings ( model . MetricNameLabel , "test_metric1" , "app" , "v1" ) , M : m1 , T : 1 , V : 2 , ES : [ ] exemplar . Exemplar { e1 } } ,
{ L : labels . FromStrings ( model . MetricNameLabel , "test_metric2" , "app" , "v1" ) , T : 2 , H : h } ,
{ L : labels . FromStrings ( model . MetricNameLabel , "test_metric3" , "app" , "v1" ) , T : 3 , FH : fh } ,
}
testutil . RequireEqual ( t , exp , appTest . PendingSamples ( ) )
require . Nil ( t , appTest . ResultSamples ( ) )
require . Nil ( t , appTest . RolledbackSamples ( ) )
if commit {
require . NoError ( t , app . Commit ( ) )
require . Nil ( t , appTest . PendingSamples ( ) )
testutil . RequireEqual ( t , exp , appTest . ResultSamples ( ) )
require . Nil ( t , appTest . RolledbackSamples ( ) )
break
}
require . NoError ( t , app . Rollback ( ) )
require . Nil ( t , appTest . PendingSamples ( ) )
require . Nil ( t , appTest . ResultSamples ( ) )
testutil . RequireEqual ( t , exp , appTest . RolledbackSamples ( ) )
}
}
func testAppendableV2 ( t * testing . T , appTest * Appendable , a storage . AppendableV2 ) {
for _ , commit := range [ ] bool { true , false } {
appTest . ResultReset ( )
app := a . AppenderV2 ( t . Context ( ) )
m1 := metadata . Metadata { Type : "gauge" , Unit : "" , Help : "other help text" }
e1 := exemplar . Exemplar { Labels : labels . FromStrings ( model . MetricNameLabel , "yolo" ) , HasTs : true , Ts : 1 }
_ , err := app . Append ( 0 , labels . FromStrings ( model . MetricNameLabel , "test_metric1" , "app" , "v2" ) , - 1 , 1 , 2 , nil , nil , storage . AOptions {
MetricFamilyName : "test_metric1" ,
Metadata : m1 ,
Exemplars : [ ] exemplar . Exemplar { e1 } ,
} )
require . NoError ( t , err )
h := tsdbutil . GenerateTestHistogram ( 0 )
_ , err = app . Append ( 0 , labels . FromStrings ( model . MetricNameLabel , "test_metric2" , "app" , "v2" ) , - 2 , 2 , 0 , h , nil , storage . AOptions { } )
require . NoError ( t , err )
fh := tsdbutil . GenerateTestFloatHistogram ( 0 )
_ , err = app . Append ( 0 , labels . FromStrings ( model . MetricNameLabel , "test_metric3" , "app" , "v2" ) , - 3 , 3 , 0 , nil , fh , storage . AOptions { } )
require . NoError ( t , err )
exp := [ ] Sample {
{ L : labels . FromStrings ( model . MetricNameLabel , "test_metric1" , "app" , "v2" ) , MF : "test_metric1" , M : m1 , ST : - 1 , T : 1 , V : 2 , ES : [ ] exemplar . Exemplar { e1 } } ,
{ L : labels . FromStrings ( model . MetricNameLabel , "test_metric2" , "app" , "v2" ) , ST : - 2 , T : 2 , H : h } ,
{ L : labels . FromStrings ( model . MetricNameLabel , "test_metric3" , "app" , "v2" ) , ST : - 3 , T : 3 , FH : fh } ,
}
testutil . RequireEqual ( t , exp , appTest . PendingSamples ( ) )
require . Nil ( t , appTest . ResultSamples ( ) )
require . Nil ( t , appTest . RolledbackSamples ( ) )
if commit {
require . NoError ( t , app . Commit ( ) )
require . Nil ( t , appTest . PendingSamples ( ) )
testutil . RequireEqual ( t , exp , appTest . ResultSamples ( ) )
require . Nil ( t , appTest . RolledbackSamples ( ) )
break
}
require . NoError ( t , app . Rollback ( ) )
require . Nil ( t , appTest . PendingSamples ( ) )
require . Nil ( t , appTest . ResultSamples ( ) )
testutil . RequireEqual ( t , exp , appTest . RolledbackSamples ( ) )
}
}
func TestAppendable ( t * testing . T ) {
appTest := NewAppendable ( )
testAppendableV1 ( t , appTest , appTest )
testAppendableV2 ( t , appTest , appTest )
}
func TestAppendable_Then ( t * testing . T ) {
nextAppTest := NewAppendable ( )
app := NewAppendable ( ) . Then ( nextAppTest )
// Ensure next mock record all the appends when appending to app.
testAppendableV1 ( t , nextAppTest , app )
// Ensure next mock record all the appends when appending to app.
testAppendableV2 ( t , nextAppTest , app )
}
2026-01-21 03:21:56 -05:00
// TestSample_RequireEqual.
2025-12-22 04:38:48 -05:00
func TestSample_RequireEqual ( t * testing . T ) {
a := [ ] Sample {
{ } ,
2026-01-14 08:48:33 -05:00
{ L : labels . FromStrings ( model . MetricNameLabel , "test_metric_total" ) , M : metadata . Metadata { Type : "counter" , Unit : "metric" , Help : "some help text" } } ,
{ L : labels . FromStrings ( model . MetricNameLabel , "test_metric2" , "foo" , "bar" ) , M : metadata . Metadata { Type : "gauge" , Unit : "" , Help : "other help text" } , V : 123.123 } ,
{ ES : [ ] exemplar . Exemplar { { Labels : labels . FromStrings ( model . MetricNameLabel , "yolo" ) } } } ,
2025-12-22 04:38:48 -05:00
}
2026-01-21 03:21:56 -05:00
RequireEqual ( t , a , a )
2025-12-22 04:38:48 -05:00
b1 := [ ] Sample {
{ } ,
2026-01-14 08:48:33 -05:00
{ L : labels . FromStrings ( model . MetricNameLabel , "test_metric_total" ) , M : metadata . Metadata { Type : "counter" , Unit : "metric" , Help : "some help text" } } ,
{ L : labels . FromStrings ( model . MetricNameLabel , "test_metric2_diff" , "foo" , "bar" ) , M : metadata . Metadata { Type : "gauge" , Unit : "" , Help : "other help text" } , V : 123.123 } , // test_metric2_diff is different.
{ ES : [ ] exemplar . Exemplar { { Labels : labels . FromStrings ( model . MetricNameLabel , "yolo" ) } } } ,
2025-12-22 04:38:48 -05:00
}
2026-01-21 03:21:56 -05:00
RequireNotEqual ( t , a , b1 )
2025-12-22 04:38:48 -05:00
b2 := [ ] Sample {
{ } ,
2026-01-14 08:48:33 -05:00
{ L : labels . FromStrings ( model . MetricNameLabel , "test_metric_total" ) , M : metadata . Metadata { Type : "counter" , Unit : "metric" , Help : "some help text" } } ,
{ L : labels . FromStrings ( model . MetricNameLabel , "test_metric2" , "foo" , "bar" ) , M : metadata . Metadata { Type : "gauge" , Unit : "" , Help : "other help text" } , V : 123.123 } ,
{ ES : [ ] exemplar . Exemplar { { Labels : labels . FromStrings ( model . MetricNameLabel , "yolo2" ) } } } , // exemplar is different.
2025-12-22 04:38:48 -05:00
}
2026-01-21 03:21:56 -05:00
RequireNotEqual ( t , a , b2 )
2025-12-22 04:38:48 -05:00
b3 := [ ] Sample {
{ } ,
2026-01-14 08:48:33 -05:00
{ L : labels . FromStrings ( model . MetricNameLabel , "test_metric_total" ) , M : metadata . Metadata { Type : "counter" , Unit : "metric" , Help : "some help text" } } ,
{ L : labels . FromStrings ( model . MetricNameLabel , "test_metric2" , "foo" , "bar" ) , M : metadata . Metadata { Type : "gauge" , Unit : "" , Help : "other help text" } , V : 123.123 , T : 123 } , // Timestamp is different.
{ ES : [ ] exemplar . Exemplar { { Labels : labels . FromStrings ( model . MetricNameLabel , "yolo" ) } } } ,
2025-12-22 04:38:48 -05:00
}
2026-01-21 03:21:56 -05:00
RequireNotEqual ( t , a , b3 )
2025-12-22 04:38:48 -05:00
b4 := [ ] Sample {
{ } ,
2026-01-14 08:48:33 -05:00
{ L : labels . FromStrings ( model . MetricNameLabel , "test_metric_total" ) , M : metadata . Metadata { Type : "counter" , Unit : "metric" , Help : "some help text" } } ,
{ L : labels . FromStrings ( model . MetricNameLabel , "test_metric2" , "foo" , "bar" ) , M : metadata . Metadata { Type : "gauge" , Unit : "" , Help : "other help text" } , V : 456.456 } , // Value is different.
{ ES : [ ] exemplar . Exemplar { { Labels : labels . FromStrings ( model . MetricNameLabel , "yolo" ) } } } ,
2025-12-22 04:38:48 -05:00
}
2026-01-21 03:21:56 -05:00
RequireNotEqual ( t , a , b4 )
2025-12-22 04:38:48 -05:00
b5 := [ ] Sample {
{ } ,
2026-01-14 08:48:33 -05:00
{ L : labels . FromStrings ( model . MetricNameLabel , "test_metric_total" ) , M : metadata . Metadata { Type : "counter2" , Unit : "metric" , Help : "some help text" } } , // Different type.
{ L : labels . FromStrings ( model . MetricNameLabel , "test_metric2" , "foo" , "bar" ) , M : metadata . Metadata { Type : "gauge" , Unit : "" , Help : "other help text" } , V : 123.123 } ,
{ ES : [ ] exemplar . Exemplar { { Labels : labels . FromStrings ( model . MetricNameLabel , "yolo" ) } } } ,
2025-12-22 04:38:48 -05:00
}
2026-01-21 03:21:56 -05:00
RequireNotEqual ( t , a , b5 )
// NaN comparison.
a = [ ] Sample {
{ } ,
{ L : labels . FromStrings ( model . MetricNameLabel , "test_metric_total" ) , M : metadata . Metadata { Type : "counter" , Unit : "metric" , Help : "some help text" } } ,
{ L : labels . FromStrings ( model . MetricNameLabel , "test_metric2" , "foo" , "bar" ) , M : metadata . Metadata { Type : "gauge" , Unit : "" , Help : "other help text" } , V : math . Float64frombits ( value . StaleNaN ) } ,
{ ES : [ ] exemplar . Exemplar { { Labels : labels . FromStrings ( model . MetricNameLabel , "yolo" ) } } } ,
}
RequireEqual ( t , a , a )
2025-12-22 04:38:48 -05:00
2026-01-21 03:21:56 -05:00
// NaN comparison with different order.
a = [ ] Sample {
{ } ,
{ L : labels . FromStrings ( model . MetricNameLabel , "test_metric_total" ) , M : metadata . Metadata { Type : "counter" , Unit : "metric" , Help : "some help text" } } ,
{ L : labels . FromStrings ( model . MetricNameLabel , "test_metric10" , "foo" , "bar" ) , M : metadata . Metadata { Type : "gauge" , Unit : "" , Help : "other help text" } , V : math . Float64frombits ( value . StaleNaN ) } ,
{ L : labels . FromStrings ( model . MetricNameLabel , "test_metric2" , "foo" , "bar" ) , M : metadata . Metadata { Type : "gauge" , Unit : "" , Help : "other help text" } , V : math . Float64frombits ( value . StaleNaN ) } ,
{ ES : [ ] exemplar . Exemplar { { Labels : labels . FromStrings ( model . MetricNameLabel , "yolo" ) } } } ,
}
b6 := [ ] Sample {
{ } ,
{ L : labels . FromStrings ( model . MetricNameLabel , "test_metric_total" ) , M : metadata . Metadata { Type : "counter" , Unit : "metric" , Help : "some help text" } } ,
{ L : labels . FromStrings ( model . MetricNameLabel , "test_metric2" , "foo" , "bar" ) , M : metadata . Metadata { Type : "gauge" , Unit : "" , Help : "other help text" } , V : math . Float64frombits ( value . StaleNaN ) } ,
{ L : labels . FromStrings ( model . MetricNameLabel , "test_metric10" , "foo" , "bar" ) , M : metadata . Metadata { Type : "gauge" , Unit : "" , Help : "other help text" } , V : math . Float64frombits ( value . StaleNaN ) } ,
{ ES : [ ] exemplar . Exemplar { { Labels : labels . FromStrings ( model . MetricNameLabel , "yolo" ) } } } ,
}
RequireEqual ( t , a , b6 )
// Not equal with NaNs.
b7 := [ ] Sample {
{ } ,
{ L : labels . FromStrings ( model . MetricNameLabel , "test_metric_total" ) , M : metadata . Metadata { Type : "counter" , Unit : "metric" , Help : "some help text" } } ,
{ L : labels . FromStrings ( model . MetricNameLabel , "test_metric10" , "foo" , "bar" ) , M : metadata . Metadata { Type : "gauge" , Unit : "" , Help : "other help text" } , V : math . Float64frombits ( value . StaleNaN ) } ,
{ L : labels . FromStrings ( model . MetricNameLabel , "test_metric2" , "foo" , "bar" ) , M : metadata . Metadata { Type : "gauge2" , Unit : "" , Help : "other help text" } , V : math . Float64frombits ( value . StaleNaN ) } , // metadata different
{ ES : [ ] exemplar . Exemplar { { Labels : labels . FromStrings ( model . MetricNameLabel , "yolo" ) } } } ,
2025-12-22 04:38:48 -05:00
}
2026-01-21 03:21:56 -05:00
RequireNotEqual ( t , a , b7 )
2025-12-22 04:38:48 -05:00
}
func TestConcurrentAppender_ReturnsErrAppender ( t * testing . T ) {
a := NewAppendable ( )
// Non-concurrent multiple use if fine.
app := a . Appender ( t . Context ( ) )
require . Equal ( t , int32 ( 1 ) , a . openAppenders . Load ( ) )
require . NoError ( t , app . Commit ( ) )
// Repeated commit fails.
require . Error ( t , app . Commit ( ) )
app = a . Appender ( t . Context ( ) )
require . NoError ( t , app . Rollback ( ) )
// Commit after rollback fails.
require . Error ( t , app . Commit ( ) )
a . WithErrs (
nil ,
nil ,
errors . New ( "commit err" ) ,
)
app = a . Appender ( t . Context ( ) )
require . Error ( t , app . Commit ( ) )
a . WithErrs ( nil , nil , nil )
app = a . Appender ( t . Context ( ) )
require . NoError ( t , app . Commit ( ) )
require . Equal ( t , int32 ( 0 ) , a . openAppenders . Load ( ) )
// Concurrent use should return appender that errors.
_ = a . Appender ( t . Context ( ) )
app = a . Appender ( t . Context ( ) )
_ , err := app . Append ( 0 , labels . EmptyLabels ( ) , 0 , 0 )
require . Error ( t , err )
_ , err = app . AppendHistogram ( 0 , labels . EmptyLabels ( ) , 0 , nil , nil )
require . Error ( t , err )
require . Error ( t , app . Commit ( ) )
require . Error ( t , app . Rollback ( ) )
}
2026-01-14 08:48:33 -05:00
func TestConcurrentAppenderV2_ReturnsErrAppender ( t * testing . T ) {
a := NewAppendable ( )
// Non-concurrent multiple use if fine.
app := a . AppenderV2 ( t . Context ( ) )
require . Equal ( t , int32 ( 1 ) , a . openAppenders . Load ( ) )
require . NoError ( t , app . Commit ( ) )
// Repeated commit fails.
require . Error ( t , app . Commit ( ) )
app = a . AppenderV2 ( t . Context ( ) )
require . NoError ( t , app . Rollback ( ) )
// Commit after rollback fails.
require . Error ( t , app . Commit ( ) )
a . WithErrs (
nil ,
nil ,
errors . New ( "commit err" ) ,
)
app = a . AppenderV2 ( t . Context ( ) )
require . Error ( t , app . Commit ( ) )
a . WithErrs ( nil , nil , nil )
app = a . AppenderV2 ( t . Context ( ) )
require . NoError ( t , app . Commit ( ) )
require . Equal ( t , int32 ( 0 ) , a . openAppenders . Load ( ) )
// Concurrent use should return appender that errors.
_ = a . AppenderV2 ( t . Context ( ) )
app = a . AppenderV2 ( t . Context ( ) )
_ , err := app . Append ( 0 , labels . EmptyLabels ( ) , 0 , 0 , 0 , nil , nil , storage . AOptions { } )
require . Error ( t , err )
require . Error ( t , app . Commit ( ) )
require . Error ( t , app . Rollback ( ) )
}
2026-01-21 10:25:31 -05:00
func TestReorderExpectedForStaleness ( t * testing . T ) {
testcases := [ ] struct {
name string
inExpected [ ] Sample
inGot [ ] Sample
expected [ ] Sample
} {
{
name : "no staleness markers" ,
inExpected : [ ] Sample {
{ L : labels . FromStrings ( "a" , "1" ) , T : 1 , V : 1 } ,
{ L : labels . FromStrings ( "a" , "2" ) , T : 1 , V : 2 } ,
} ,
inGot : [ ] Sample {
{ L : labels . FromStrings ( "a" , "2" ) , T : 1 , V : 2 } ,
{ L : labels . FromStrings ( "a" , "1" ) , T : 1 , V : 1 } ,
} ,
} ,
{
name : "with staleness markers" ,
inExpected : [ ] Sample {
{ L : labels . FromStrings ( "a" , "1" ) , T : 1 , V : 1 } ,
{ L : labels . FromStrings ( "a" , "2" ) , T : 2 , V : 2 } ,
{ L : labels . FromStrings ( "a" , "3" ) , T : 3 , V : math . Float64frombits ( value . StaleNaN ) } ,
{ L : labels . FromStrings ( "a" , "4" ) , T : 4 , V : math . Float64frombits ( value . StaleNaN ) } ,
} ,
inGot : [ ] Sample {
{ L : labels . FromStrings ( "a" , "1" ) , T : 1 , V : 1 } ,
{ L : labels . FromStrings ( "a" , "2" ) , T : 2 , V : 2 } ,
{ L : labels . FromStrings ( "a" , "3" ) , T : 3 , V : math . Float64frombits ( value . StaleNaN ) } ,
{ L : labels . FromStrings ( "a" , "4" ) , T : 4 , V : math . Float64frombits ( value . StaleNaN ) } ,
} ,
} ,
{
name : "with staleness markers wrong order" ,
inExpected : [ ] Sample {
{ L : labels . FromStrings ( "a" , "1" ) , T : 1 , V : 1 } ,
{ L : labels . FromStrings ( "a" , "2" ) , T : 2 , V : 2 } ,
{ L : labels . FromStrings ( "a" , "3" ) , T : 3 , V : math . Float64frombits ( value . StaleNaN ) } ,
{ L : labels . FromStrings ( "a" , "4" ) , T : 4 , V : math . Float64frombits ( value . StaleNaN ) } ,
} ,
inGot : [ ] Sample {
{ L : labels . FromStrings ( "a" , "2" ) , T : 2 , V : 2 } ,
{ L : labels . FromStrings ( "a" , "1" ) , T : 1 , V : 1 } ,
{ L : labels . FromStrings ( "a" , "4" ) , T : 4 , V : math . Float64frombits ( value . StaleNaN ) } ,
{ L : labels . FromStrings ( "a" , "3" ) , T : 3 , V : math . Float64frombits ( value . StaleNaN ) } ,
} ,
expected : [ ] Sample {
{ L : labels . FromStrings ( "a" , "1" ) , T : 1 , V : 1 } ,
{ L : labels . FromStrings ( "a" , "2" ) , T : 2 , V : 2 } ,
{ L : labels . FromStrings ( "a" , "4" ) , T : 4 , V : math . Float64frombits ( value . StaleNaN ) } ,
{ L : labels . FromStrings ( "a" , "3" ) , T : 3 , V : math . Float64frombits ( value . StaleNaN ) } ,
} ,
} ,
{
name : "with staleness markers wrong order but not consecutive" ,
inExpected : [ ] Sample {
{ L : labels . FromStrings ( "a" , "1" ) , T : 1 , V : 1 } ,
{ L : labels . FromStrings ( "a" , "3" ) , T : 3 , V : math . Float64frombits ( value . StaleNaN ) } ,
{ L : labels . FromStrings ( "a" , "2" ) , T : 2 , V : 2 } ,
{ L : labels . FromStrings ( "a" , "4" ) , T : 4 , V : math . Float64frombits ( value . StaleNaN ) } ,
} ,
inGot : [ ] Sample {
{ L : labels . FromStrings ( "a" , "2" ) , T : 2 , V : 2 } ,
{ L : labels . FromStrings ( "a" , "1" ) , T : 1 , V : 1 } ,
{ L : labels . FromStrings ( "a" , "4" ) , T : 4 , V : math . Float64frombits ( value . StaleNaN ) } ,
{ L : labels . FromStrings ( "a" , "3" ) , T : 3 , V : math . Float64frombits ( value . StaleNaN ) } ,
} ,
expected : [ ] Sample {
{ L : labels . FromStrings ( "a" , "1" ) , T : 1 , V : 1 } ,
{ L : labels . FromStrings ( "a" , "3" ) , T : 3 , V : math . Float64frombits ( value . StaleNaN ) } ,
{ L : labels . FromStrings ( "a" , "2" ) , T : 2 , V : 2 } ,
{ L : labels . FromStrings ( "a" , "4" ) , T : 4 , V : math . Float64frombits ( value . StaleNaN ) } ,
} ,
} ,
}
for _ , tc := range testcases {
t . Run ( tc . name , func ( t * testing . T ) {
if tc . expected == nil {
tc . expected = tc . inExpected
}
RequireEqual ( t , tc . expected , reorderExpectedForStaleness ( tc . inExpected , tc . inGot ) )
} )
}
}
func TestSampleIsStale ( t * testing . T ) {
s1 := Sample { V : 1 }
require . False ( t , s1 . IsStale ( ) )
s2 := Sample { V : math . Float64frombits ( value . StaleNaN ) }
require . True ( t , s2 . IsStale ( ) )
h := tsdbutil . GenerateTestHistogram ( 0 )
h1 := Sample { V : math . Float64frombits ( value . StaleNaN ) , H : h }
require . False ( t , h1 . IsStale ( ) ) // Histogram takes precedence over V.
h . Sum = math . Float64frombits ( value . StaleNaN )
h2 := Sample { V : 1 , H : h }
require . True ( t , h2 . IsStale ( ) )
fh := tsdbutil . GenerateTestFloatHistogram ( 0 )
fh1 := Sample { V : math . Float64frombits ( value . StaleNaN ) , H : h , FH : fh }
require . False ( t , fh1 . IsStale ( ) ) // FloatHistogram takes precedence over all.
fh . Sum = math . Float64frombits ( value . StaleNaN )
fh2 := Sample { V : 1 , H : tsdbutil . GenerateTestHistogram ( 1 ) , FH : fh }
require . True ( t , fh2 . IsStale ( ) )
}