Wanted for the case where the answers are moving: an operator correcting their
own QRZ record, or chasing a DXpedition whose page changes during the operation,
otherwise waits out thirty days before OpsLog will ask again. Clearing the cache
by hand works once; this is the setting for a whole session.
Nothing is read from it and nothing is written to it — rows stored while it is
off would only sit there going stale, waiting for the day it comes back on.
Switching off is NOT clearing: what it already holds stays, and the Clear cache
button remains the way to throw that away.
Two distinctions the code now has to keep, both load-bearing:
An EXPLICIT stored zero is off; an ABSENT key is the thirty-day default. Every
operator who has never opened this setting has nothing stored, and reading that
blank as a zero would silently switch the cache off for all of them.
The CONSTRUCTOR's zero is still the default, not off. At startup the settings
have not been read yet, and beginning with no cache would hammer the provider
for the first seconds of every launch. Only SetTTL, called once the operator's
settings are known, can switch it off.
A negative lifetime is meaningless and is ignored rather than rounded into
either meaning.
The input had to change too: it derived its value from the stored number on
every keystroke, so the box could not be emptied — and 0 was unreachable
outright, since parseInt('0') || 30 is 30.
75 lines
2.5 KiB
Go
75 lines
2.5 KiB
Go
package lookup
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
// A TTL of zero means no cache: nothing is read from it, and nothing is written
|
|
// to it either.
|
|
//
|
|
// It is a real thing to want. An operator correcting their own QRZ record — or
|
|
// chasing a DXpedition whose page changes during the operation — otherwise
|
|
// waits out thirty days before OpsLog will ask again. Clearing the cache by
|
|
// hand works once; switching it off is the setting for a session where the
|
|
// answers are moving.
|
|
func TestATTLOfZeroSwitchesTheCacheOff(t *testing.T) {
|
|
c := testCache(t)
|
|
ctx := context.Background()
|
|
|
|
if err := c.Put(ctx, Result{Callsign: "M0ABC", Name: "Ann", Source: "qrz"}); err != nil {
|
|
t.Fatalf("put: %v", err)
|
|
}
|
|
if _, ok := c.Get(ctx, "M0ABC"); !ok {
|
|
t.Fatal("the cache did not hold a fresh entry while switched on")
|
|
}
|
|
|
|
c.SetTTL(0)
|
|
if c.Enabled() {
|
|
t.Error("Enabled() is true with a zero TTL")
|
|
}
|
|
if _, ok := c.Get(ctx, "M0ABC"); ok {
|
|
t.Error("a cached entry was still returned with the cache off — the provider would never be asked again")
|
|
}
|
|
// And nothing new is stored: those rows would only sit there going stale,
|
|
// waiting for the day the cache is switched back on.
|
|
if err := c.Put(ctx, Result{Callsign: "M0XYZ", Name: "Bob", Source: "qrz"}); err != nil {
|
|
t.Fatalf("put with the cache off: %v", err)
|
|
}
|
|
c.SetTTL(30 * 24 * time.Hour)
|
|
if _, ok := c.Get(ctx, "M0XYZ"); ok {
|
|
t.Error("a lookup made while the cache was off was written to it anyway")
|
|
}
|
|
// The entry from before it was switched off is still there — switching off
|
|
// is not the same as clearing, and the Clear cache button remains the way to
|
|
// throw the contents away.
|
|
if _, ok := c.Get(ctx, "M0ABC"); !ok {
|
|
t.Error("switching the cache off discarded what it already held")
|
|
}
|
|
}
|
|
|
|
// A negative lifetime is meaningless, and rounding it into either "off" or a
|
|
// default would be a guess. It is ignored instead.
|
|
func TestANegativeTTLIsIgnored(t *testing.T) {
|
|
c := testCache(t)
|
|
c.SetTTL(7 * 24 * time.Hour)
|
|
c.SetTTL(-1)
|
|
if !c.Enabled() {
|
|
t.Fatal("a negative TTL switched the cache off")
|
|
}
|
|
if c.ttl != 7*24*time.Hour {
|
|
t.Errorf("ttl = %v after a negative value, want the 7 days it already had", c.ttl)
|
|
}
|
|
}
|
|
|
|
// The constructor's zero is the DEFAULT, not "off": at startup the settings
|
|
// have not been read, and beginning with no cache would hammer the provider for
|
|
// the first seconds of every launch.
|
|
func TestNewCacheWithZeroStillCaches(t *testing.T) {
|
|
c := testCache(t) // built with NewCache(conn, 0)
|
|
if !c.Enabled() {
|
|
t.Error("a cache built with a zero TTL started switched off")
|
|
}
|
|
}
|