Merge branch '20690-remove-wb1-from-installer'. Closes #20690
[arvados.git] / lib / controller / handler_test.go
index 654eaffe1d6f42fff3327462b38d958a7012527a..0c50a6c4be59b85fc23140d93c4346e1f8e8a9ae 100644 (file)
@@ -139,11 +139,6 @@ func (s *HandlerSuite) TestDiscoveryDocCache(c *check.C) {
                        ent.refreshLock.Unlock()
                }
        }
-       expireCache := func() {
-               for _, ent := range s.handler.cache {
-                       ent.refreshAfter = time.Now()
-               }
-       }
        waitPendingUpdates := func() {
                for _, ent := range s.handler.cache {
                        ent.refreshLock.Lock()
@@ -152,6 +147,18 @@ func (s *HandlerSuite) TestDiscoveryDocCache(c *check.C) {
                        defer ent.mtx.Unlock()
                }
        }
+       refreshNow := func() {
+               waitPendingUpdates()
+               for _, ent := range s.handler.cache {
+                       ent.refreshAfter = time.Now()
+               }
+       }
+       expireNow := func() {
+               waitPendingUpdates()
+               for _, ent := range s.handler.cache {
+                       ent.expireAfter = time.Now()
+               }
+       }
 
        // Easy path: first req fetches, subsequent reqs use cache.
        c.Check(countRailsReqs(), check.Equals, 0)
@@ -181,7 +188,7 @@ func (s *HandlerSuite) TestDiscoveryDocCache(c *check.C) {
 
        // Race after expiry: concurrent reqs return the cached data
        // but initiate a new fetch in the background.
-       expireCache()
+       refreshNow()
        holdReqs = make(chan struct{})
        wg = getDDConcurrently(5, http.StatusOK, check.Commentf("race after expiry"))
        reqsBefore = countRailsReqs()
@@ -208,7 +215,7 @@ func (s *HandlerSuite) TestDiscoveryDocCache(c *check.C) {
        // make an upstream attempt for each incoming request because
        // we have nothing better to return
        clearCache()
-       wantError = true
+       wantError, wantBadContent = true, false
        reqsBefore = countRailsReqs()
        holdReqs = make(chan struct{})
        wg = getDDConcurrently(5, http.StatusBadGateway, check.Commentf("error at startup"))
@@ -217,47 +224,75 @@ func (s *HandlerSuite) TestDiscoveryDocCache(c *check.C) {
        c.Check(countRailsReqs(), check.Equals, reqsBefore+5)
 
        // Response status is OK but body is not a discovery document
-       wantError = false
-       wantBadContent = true
+       wantError, wantBadContent = false, true
        reqsBefore = countRailsReqs()
        c.Check(getDD(), check.Equals, http.StatusBadGateway)
        c.Check(countRailsReqs(), check.Equals, reqsBefore+1)
 
        // Error condition clears => caller gets OK, cache is warmed
        // up
-       wantBadContent = false
+       wantError, wantBadContent = false, false
        reqsBefore = countRailsReqs()
        getDDConcurrently(5, http.StatusOK, check.Commentf("success after errors at startup")).Wait()
        c.Check(countRailsReqs(), check.Equals, reqsBefore+1)
 
        // Error with warm cache => caller gets OK (with no attempt to
        // re-fetch)
-       wantError = true
+       wantError, wantBadContent = true, false
        reqsBefore = countRailsReqs()
        getDDConcurrently(5, http.StatusOK, check.Commentf("error with warm cache")).Wait()
        c.Check(countRailsReqs(), check.Equals, reqsBefore)
-       expireCache()
 
-       // Error with expired cache => caller gets OK with stale data
+       // Error with stale cache => caller gets OK with stale data
        // while the re-fetch is attempted in the background
+       refreshNow()
+       wantError, wantBadContent = true, false
        reqsBefore = countRailsReqs()
        holdReqs = make(chan struct{})
-       getDDConcurrently(5, http.StatusOK, check.Commentf("error with expired cache")).Wait()
+       getDDConcurrently(5, http.StatusOK, check.Commentf("error with stale cache")).Wait()
        close(holdReqs)
        // Only one attempt to re-fetch (holdReqs ensured the first
        // update took long enough for the last incoming request to
        // arrive)
        c.Check(countRailsReqs(), check.Equals, reqsBefore+1)
 
-       waitPendingUpdates()
-       expireCache()
-       wantError = false
+       refreshNow()
+       wantError, wantBadContent = false, false
        reqsBefore = countRailsReqs()
        holdReqs = make(chan struct{})
        getDDConcurrently(5, http.StatusOK, check.Commentf("refresh cache after error condition clears")).Wait()
        close(holdReqs)
        waitPendingUpdates()
        c.Check(countRailsReqs(), check.Equals, reqsBefore+1)
+
+       // Make sure expireAfter is getting set
+       waitPendingUpdates()
+       exp := s.handler.cache["/discovery/v1/apis/arvados/v1/rest"].expireAfter.Sub(time.Now())
+       c.Check(exp > cacheTTL, check.Equals, true)
+       c.Check(exp < cacheExpire, check.Equals, true)
+
+       // After the cache *expires* it behaves as if uninitialized:
+       // each incoming request does a new upstream request until one
+       // succeeds.
+       //
+       // First check failure after expiry:
+       expireNow()
+       wantError, wantBadContent = true, false
+       reqsBefore = countRailsReqs()
+       holdReqs = make(chan struct{})
+       wg = getDDConcurrently(5, http.StatusBadGateway, check.Commentf("error after expiry"))
+       close(holdReqs)
+       wg.Wait()
+       c.Check(countRailsReqs(), check.Equals, reqsBefore+5)
+
+       // Success after expiry:
+       wantError, wantBadContent = false, false
+       reqsBefore = countRailsReqs()
+       holdReqs = make(chan struct{})
+       wg = getDDConcurrently(5, http.StatusOK, check.Commentf("success after expiry"))
+       close(holdReqs)
+       wg.Wait()
+       c.Check(countRailsReqs(), check.Equals, reqsBefore+1)
 }
 
 func (s *HandlerSuite) TestVocabularyExport(c *check.C) {
@@ -604,7 +639,7 @@ func (s *HandlerSuite) TestGetObjects(c *check.C) {
        testCases := map[string]map[string]bool{
                "api_clients/" + arvadostest.TrustedWorkbenchAPIClientUUID:     nil,
                "api_client_authorizations/" + auth.UUID:                       {"href": true, "modified_by_client_uuid": true, "modified_by_user_uuid": true},
-               "authorized_keys/" + arvadostest.AdminAuthorizedKeysUUID:       nil,
+               "authorized_keys/" + arvadostest.AdminAuthorizedKeysUUID:       {"href": true},
                "collections/" + arvadostest.CollectionWithUniqueWordsUUID:     {"href": true},
                "containers/" + arvadostest.RunningContainerUUID:               nil,
                "container_requests/" + arvadostest.QueuedContainerRequestUUID: nil,