Loading cache.go +9 −3 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ type TestCache struct { Entries map[string]*CacheEntry // entryTimeout determines how long a cache entry is valid for. entryTimeout time.Duration errorEntryTimeout time.Duration l sync.Mutex } Loading Loading @@ -124,7 +125,12 @@ func (tc *TestCache) IsCached(bridgeLine string) *CacheEntry { now := time.Now().UTC() tc.l.Lock() for index, entry := range (*tc).Entries { if entry.Time.Before(now.Add(-(*tc).entryTimeout)) { // If the test returned an error, shorten the time it is cached // to errorEntryTimeout (default 1 hour) so it can be tested again // more quickly. This aims to prevent bridges that are temporarily // down due to unfortunate test timing from being marked as `gone` // by rdsys if entry.Error != "" && entry.Time.Before(now.Add(-(*tc).errorEntryTimeout)) || entry.Time.Before(now.Add(-(*tc).entryTimeout)) { log.Printf("Deleting cache entry: %s", index) delete((*tc).Entries, index) } Loading cache_test.go +26 −2 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ func init() { func NewCache() *TestCache { return &TestCache{ Entries: make(map[string]*CacheEntry), errorEntryTimeout: 1 * time.Hour, entryTimeout: 18 * time.Hour, } } Loading Loading @@ -57,6 +58,29 @@ func TestCacheFunctions(t *testing.T) { if e != nil { t.Errorf("Got non-nil cache entry for bogus bridge line.") } // A failed bridge should only be cached for 1 hour. failedBridgeLine := "obfs4 127.0.0.1:1 cert=foo iat-mode=0" cache.AddEntry(failedBridgeLine, nil, time.Now().UTC().Add(-(time.Second * 6000))) e = cache.IsCached(failedBridgeLine) if e == nil { t.Errorf("Could not retrieve existing element from cache.") } testError = fmt.Errorf("bridge is restarting at an unfortunate time") // Manipulate entry time to be less than 5 seconds before the 1 hour mark // so we can check it is cached and removed from the cache within a // reasonable amount of time cache.AddEntry(failedBridgeLine, testError, time.Now().UTC().Add(-(time.Second * 3595))) e = cache.IsCached(failedBridgeLine) if e.Error != testError.Error() { t.Errorf("Got test result %q but expected %q.", e.Error, testError) } time.Sleep(6 * time.Second) e = cache.IsCached(failedBridgeLine) if e != nil { t.Errorf("Cache is empty but marks bridge line as existing.") } } func TestCacheFracFunctional(t *testing.T) { Loading main.go +3 −1 Original line number Diff line number Diff line Loading @@ -116,7 +116,7 @@ func main() { var torBinary string var obfs4proxyBinary string var webtunnelBinary string var testTimeout, cacheTimeout int var testTimeout, cacheTimeout, errorCacheTimeout int var logFile string flag.StringVar(&addr, "addr", ":5000", "Address to listen on.") Loading @@ -134,6 +134,7 @@ func main() { flag.StringVar(&webtunnelBinary, "webtunnel", "./webtunnel", "Path to obfs4proxy executable.") flag.StringVar(&logFile, "log", "", "File to write logs to.") flag.IntVar(&testTimeout, "test-timeout", 60, "Test timeout in seconds.") flag.IntVar(&errorCacheTimeout, "error-cache-timeout", 1, "Test timeout in hours for tests that have errored.") flag.IntVar(&cacheTimeout, "cache-timeout", 18, "Cache timeout in hours.") flag.Parse() Loading Loading @@ -188,6 +189,7 @@ func main() { log.Printf("Could not read cache: %s", err) } cache.entryTimeout = time.Duration(cacheTimeout) * time.Hour cache.errorEntryTimeout = time.Duration(errorCacheTimeout) * time.Hour log.Printf("Set cache timeout to %s.", cache.entryTimeout) if printCache { printPrettyCache() Loading Loading
cache.go +9 −3 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ type TestCache struct { Entries map[string]*CacheEntry // entryTimeout determines how long a cache entry is valid for. entryTimeout time.Duration errorEntryTimeout time.Duration l sync.Mutex } Loading Loading @@ -124,7 +125,12 @@ func (tc *TestCache) IsCached(bridgeLine string) *CacheEntry { now := time.Now().UTC() tc.l.Lock() for index, entry := range (*tc).Entries { if entry.Time.Before(now.Add(-(*tc).entryTimeout)) { // If the test returned an error, shorten the time it is cached // to errorEntryTimeout (default 1 hour) so it can be tested again // more quickly. This aims to prevent bridges that are temporarily // down due to unfortunate test timing from being marked as `gone` // by rdsys if entry.Error != "" && entry.Time.Before(now.Add(-(*tc).errorEntryTimeout)) || entry.Time.Before(now.Add(-(*tc).entryTimeout)) { log.Printf("Deleting cache entry: %s", index) delete((*tc).Entries, index) } Loading
cache_test.go +26 −2 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ func init() { func NewCache() *TestCache { return &TestCache{ Entries: make(map[string]*CacheEntry), errorEntryTimeout: 1 * time.Hour, entryTimeout: 18 * time.Hour, } } Loading Loading @@ -57,6 +58,29 @@ func TestCacheFunctions(t *testing.T) { if e != nil { t.Errorf("Got non-nil cache entry for bogus bridge line.") } // A failed bridge should only be cached for 1 hour. failedBridgeLine := "obfs4 127.0.0.1:1 cert=foo iat-mode=0" cache.AddEntry(failedBridgeLine, nil, time.Now().UTC().Add(-(time.Second * 6000))) e = cache.IsCached(failedBridgeLine) if e == nil { t.Errorf("Could not retrieve existing element from cache.") } testError = fmt.Errorf("bridge is restarting at an unfortunate time") // Manipulate entry time to be less than 5 seconds before the 1 hour mark // so we can check it is cached and removed from the cache within a // reasonable amount of time cache.AddEntry(failedBridgeLine, testError, time.Now().UTC().Add(-(time.Second * 3595))) e = cache.IsCached(failedBridgeLine) if e.Error != testError.Error() { t.Errorf("Got test result %q but expected %q.", e.Error, testError) } time.Sleep(6 * time.Second) e = cache.IsCached(failedBridgeLine) if e != nil { t.Errorf("Cache is empty but marks bridge line as existing.") } } func TestCacheFracFunctional(t *testing.T) { Loading
main.go +3 −1 Original line number Diff line number Diff line Loading @@ -116,7 +116,7 @@ func main() { var torBinary string var obfs4proxyBinary string var webtunnelBinary string var testTimeout, cacheTimeout int var testTimeout, cacheTimeout, errorCacheTimeout int var logFile string flag.StringVar(&addr, "addr", ":5000", "Address to listen on.") Loading @@ -134,6 +134,7 @@ func main() { flag.StringVar(&webtunnelBinary, "webtunnel", "./webtunnel", "Path to obfs4proxy executable.") flag.StringVar(&logFile, "log", "", "File to write logs to.") flag.IntVar(&testTimeout, "test-timeout", 60, "Test timeout in seconds.") flag.IntVar(&errorCacheTimeout, "error-cache-timeout", 1, "Test timeout in hours for tests that have errored.") flag.IntVar(&cacheTimeout, "cache-timeout", 18, "Cache timeout in hours.") flag.Parse() Loading Loading @@ -188,6 +189,7 @@ func main() { log.Printf("Could not read cache: %s", err) } cache.entryTimeout = time.Duration(cacheTimeout) * time.Hour cache.errorEntryTimeout = time.Duration(errorCacheTimeout) * time.Hour log.Printf("Set cache timeout to %s.", cache.entryTimeout) if printCache { printPrettyCache() Loading