@@ -205,6 +205,73 @@ func TestTargetCache_Success(t *testing.T) {
205205 }
206206}
207207
208+ func TestTargetCache_EmptyEntry (t * testing.T ) {
209+ var handler func () []* Target
210+
211+ ts := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
212+ var resp apiResponse
213+ resp .Status = "success"
214+ resp .Data .ActiveTargets = handler ()
215+ if err := json .NewEncoder (w ).Encode (resp ); err != nil {
216+ t .Fatal (err )
217+ }
218+ }))
219+
220+ ctx , cancel := context .WithCancel (context .Background ())
221+ defer cancel ()
222+
223+ u , err := url .Parse (ts .URL )
224+ if err != nil {
225+ t .Fatal (err )
226+ }
227+
228+ c := NewCache (nil , nil , u )
229+ // Initialize cache with negative-cached target.
230+ c .targets [cacheKey ("job1" , "instance-not-exists" )] = nil
231+
232+ // No target in initial response.
233+ handler = func () []* Target {
234+ return []* Target {}
235+ }
236+ c .Get (ctx , labels .FromStrings ("__name__" , "metric1" , "job" , "job1" , "instance" , "instance1" ))
237+
238+ // Empty entry should be kept in cache.
239+ val , ok := c .targets [cacheKey ("job1" , "instance-not-exists" )]
240+ if ! ok {
241+ t .Fatalf ("Negative cache should be kept." )
242+ }
243+ if val != nil {
244+ t .Fatalf ("Unexpected value job1/instance-not-exists: %v" , val )
245+ }
246+
247+ // Create a new empty entry by querying job/instance pair not available.
248+ c .Get (ctx , labels .FromStrings ("__name__" , "metric2" , "job" , "job2" , "instance" , "instance-not-exists" ))
249+ val , ok = c .targets [cacheKey ("job2" , "instance-not-exists" )]
250+ if ! ok {
251+ t .Fatalf ("Negative cache should be kept." )
252+ }
253+ if val != nil {
254+ t .Fatalf ("Unexpected value job2/instance-not-exists: %v" , val )
255+ }
256+
257+ // Add a new instance into response, which will trigger replacing cache.
258+ handler = func () []* Target {
259+ return []* Target {
260+ {Labels : labels .FromStrings ("job" , "job1" , "instance" , "instance1" )},
261+ }
262+ }
263+ c .Get (ctx , labels .FromStrings ("__name__" , "metric1" , "job" , "job1" , "instance" , "instance1" ))
264+
265+ // Empty entry created should be kept in cache.
266+ val , ok = c .targets [cacheKey ("job2" , "instance-not-exists" )]
267+ if ! ok {
268+ t .Fatalf ("Negative cache should be kept." )
269+ }
270+ if val != nil {
271+ t .Fatalf ("Unexpected value job2/instance-not-exists: %v" , val )
272+ }
273+ }
274+
208275func TestDropTargetLabels (t * testing.T ) {
209276 cases := []struct {
210277 series , target , result labels.Labels
0 commit comments