hunk.code_window:       value: |
           # Welcome!
           Thanks for suggesting an idea for Portainer!
           Before opening a new idea or feature request, make sure that we do not have any duplicates already open. You can ensure this by [searching this discussion cagetory](https://github.com/samdulam/dashy/discussions/categories/ideas). If there is a duplicate, please add a comment to the existing idea instead.
           Also, be sure to check our [knowledge base](https://portal.portainer.io/knowledge) and [documentation](https://docs.portainer.io) as they may point you toward a solution.
           **DO NOT FILE DUPLICATE REQUESTS.**
  
hunk.labels: keep keep keep keep keep replace keep keep keep keep keep
hunk.after_edit:         Before opening a new idea or feature request, make sure that we do not have any duplicates already open. You can ensure this by [searching this discussion cagetory](https://github.com/orgs/portainer/discussions/categories/ideas). If there is a duplicate, please add a comment to the existing idea instead.
  
hunk.file_path: .github/DISCUSSION_TEMPLATE/ideas.yaml
hunk.type: replace
file: package kubernetes
  
  import (
  	"errors"
  	"testing"
  
  	portainer "github.com/portainer/portainer/api"
  )
  
  func noTokFunc() (string, error) {
  	return "", errors.New("no token found")
  }
  
  func stringTok(tok string) func() (string, error) {
  	return func() (string, error) {
  		return tok, nil
  	}
  }
  
  func failFunc(t *testing.T) func() (string, error) {
  	return func() (string, error) {
  		t.FailNow()
  		return noTokFunc()
  	}
  }
  
  func TestTokenCacheDataRace(t *testing.T) {
  	ch := make(chan struct{})
  
  	for i := 0; i < 1000; i++ {
  		var tokenCache1, tokenCache2 *tokenCache
  
  		mgr := NewTokenCacheManager()
  
  		go func() {
  			tokenCache1 = mgr.GetOrCreateTokenCache(1)
  			ch <- struct{}{}
  		}()
  
  		go func() {
  			tokenCache2 = mgr.GetOrCreateTokenCache(1)
  			ch <- struct{}{}
  		}()
  
  		<-ch
  		<-ch
  
  		if tokenCache1 != tokenCache2 {
  			t.FailNow()
  		}
  	}
  }
  
  func TestTokenCache(t *testing.T) {
  	mgr := NewTokenCacheManager()
  	tc1 := mgr.GetOrCreateTokenCache(1)
  	tc2 := mgr.GetOrCreateTokenCache(2)
  	tc3 := mgr.GetOrCreateTokenCache(3)
  
  	uid := portainer.UserID(2)
  	tokenString1 := "token-string-1"
  	tokenString2 := "token-string-2"
  
  	tok, err := tc1.getOrAddToken(uid, stringTok(tokenString1))
  	if err != nil || tok != tokenString1 {
  		t.FailNow()
  	}
  
  	tok, err = tc1.getOrAddToken(uid, failFunc(t))
  	if err != nil || tok != tokenString1 {
  		t.FailNow()
  	}
  
  	tok, err = tc2.getOrAddToken(uid, stringTok(tokenString2))
  	if err != nil || tok != tokenString2 {
  		t.FailNow()
  	}
  
  	_, err = tc3.getOrAddToken(uid, noTokFunc)
  	if err == nil {
  		t.FailNow()
  	}
  
  	// Remove one user from all the caches
  
  	mgr.RemoveUserFromCache(uid)
  
  	_, err = tc1.getOrAddToken(uid, noTokFunc)
  	if err == nil {
  		t.FailNow()
  	}
  
  	_, err = tc2.getOrAddToken(uid, noTokFunc)
  	if err == nil {
  		t.FailNow()
  	}
  
  	_, err = tc3.getOrAddToken(uid, noTokFunc)
  	if err == nil {
  		t.FailNow()
  	}
  }
  