|
|
@@ -0,0 +1,146 @@
|
|
|
+package client
|
|
|
+
|
|
|
+import (
|
|
|
+ "fmt"
|
|
|
+ "sync"
|
|
|
+ "testing"
|
|
|
+ "time"
|
|
|
+
|
|
|
+ "github.com/jcmturner/gokrb5/v8/messages"
|
|
|
+ "github.com/jcmturner/gokrb5/v8/types"
|
|
|
+ "github.com/stretchr/testify/assert"
|
|
|
+)
|
|
|
+
|
|
|
+func TestCache_addEntry_getEntry_remove_clear(t *testing.T) {
|
|
|
+ t.Parallel()
|
|
|
+ c := NewCache()
|
|
|
+ cnt := 10
|
|
|
+ var wg sync.WaitGroup
|
|
|
+ for i := 0; i < cnt; i++ {
|
|
|
+ wg.Add(1)
|
|
|
+ tkt := messages.Ticket{
|
|
|
+ SName: types.PrincipalName{
|
|
|
+ NameType: 1,
|
|
|
+ NameString: []string{fmt.Sprintf("%d", i), "test.cache"},
|
|
|
+ },
|
|
|
+ }
|
|
|
+ key := types.EncryptionKey{
|
|
|
+ KeyType: 1,
|
|
|
+ KeyValue: []byte{byte(i)},
|
|
|
+ }
|
|
|
+ go func(i int) {
|
|
|
+ e := c.addEntry(tkt, time.Unix(int64(0+i), 0).UTC(), time.Unix(int64(10+i), 0).UTC(), time.Unix(int64(20+i), 0).UTC(), time.Unix(int64(30+i), 0).UTC(), key)
|
|
|
+ assert.Equal(t, fmt.Sprintf("%d/test.cache", i), e.SPN, "SPN cache key not as expected")
|
|
|
+ wg.Done()
|
|
|
+ }(i)
|
|
|
+ }
|
|
|
+ wg.Wait()
|
|
|
+ for i := 0; i < cnt; i++ {
|
|
|
+ wg.Add(1)
|
|
|
+ go func(i int) {
|
|
|
+ e, ok := c.getEntry(fmt.Sprintf("%d/test.cache", i))
|
|
|
+ assert.True(t, ok, "cache entry %d was not found", i)
|
|
|
+ assert.Equal(t, time.Unix(int64(0+i), 0).UTC(), e.AuthTime, "auth time not as expected")
|
|
|
+ assert.Equal(t, time.Unix(int64(10+i), 0).UTC(), e.StartTime, "start time not as expected")
|
|
|
+ assert.Equal(t, time.Unix(int64(20+i), 0).UTC(), e.EndTime, "end time not as expected")
|
|
|
+ assert.Equal(t, time.Unix(int64(30+i), 0).UTC(), e.RenewTill, "renew time not as expected")
|
|
|
+ assert.Equal(t, []string{fmt.Sprintf("%d", i), "test.cache"}, e.Ticket.SName.NameString, "ticket not correct")
|
|
|
+ assert.Equal(t, []byte{byte(i)}, e.SessionKey.KeyValue, "session key not correct")
|
|
|
+ wg.Done()
|
|
|
+ }(i)
|
|
|
+ }
|
|
|
+ wg.Wait()
|
|
|
+ _, ok := c.getEntry(fmt.Sprintf("%d/test.cache", cnt+1))
|
|
|
+ assert.False(t, ok, "entry found in cache when it shouldn't have been")
|
|
|
+
|
|
|
+ // Remove just the even entries
|
|
|
+ for i := 0; i < cnt; i += 2 {
|
|
|
+ wg.Add(1)
|
|
|
+ go func(i int) {
|
|
|
+ c.RemoveEntry(fmt.Sprintf("%d/test.cache", i))
|
|
|
+ wg.Done()
|
|
|
+ }(i)
|
|
|
+ }
|
|
|
+ wg.Wait()
|
|
|
+
|
|
|
+ for i := 0; i < cnt; i++ {
|
|
|
+ wg.Add(1)
|
|
|
+ go func(i int) {
|
|
|
+ if i%2 == 0 {
|
|
|
+ _, ok := c.getEntry(fmt.Sprintf("%d/test.cache", cnt+1))
|
|
|
+ assert.False(t, ok, "entry %d found in cache when it shouldn't have been", i)
|
|
|
+ } else {
|
|
|
+ e, ok := c.getEntry(fmt.Sprintf("%d/test.cache", i))
|
|
|
+ assert.True(t, ok, "cache entry %d was not found", i)
|
|
|
+ assert.Equal(t, time.Unix(int64(0+i), 0).UTC(), e.AuthTime, "auth time not as expected")
|
|
|
+ assert.Equal(t, time.Unix(int64(10+i), 0).UTC(), e.StartTime, "start time not as expected")
|
|
|
+ assert.Equal(t, time.Unix(int64(20+i), 0).UTC(), e.EndTime, "end time not as expected")
|
|
|
+ assert.Equal(t, time.Unix(int64(30+i), 0).UTC(), e.RenewTill, "renew time not as expected")
|
|
|
+ assert.Equal(t, []string{fmt.Sprintf("%d", i), "test.cache"}, e.Ticket.SName.NameString, "ticket not correct")
|
|
|
+ assert.Equal(t, []byte{byte(i)}, e.SessionKey.KeyValue, "session key not correct")
|
|
|
+ }
|
|
|
+ wg.Done()
|
|
|
+ }(i)
|
|
|
+ }
|
|
|
+ wg.Wait()
|
|
|
+
|
|
|
+ // Clear the cache
|
|
|
+ c.clear()
|
|
|
+ for i := 0; i < cnt; i++ {
|
|
|
+ wg.Add(1)
|
|
|
+ go func(i int) {
|
|
|
+ _, ok := c.getEntry(fmt.Sprintf("%d/test.cache", cnt+1))
|
|
|
+ assert.False(t, ok, "entry %d found in cache when it shouldn't have been", i)
|
|
|
+ wg.Done()
|
|
|
+ }(i)
|
|
|
+ }
|
|
|
+ wg.Wait()
|
|
|
+}
|
|
|
+
|
|
|
+func TestCache_JSON(t *testing.T) {
|
|
|
+ t.Parallel()
|
|
|
+ c := NewCache()
|
|
|
+ cnt := 3
|
|
|
+ for i := 0; i < cnt; i++ {
|
|
|
+ tkt := messages.Ticket{
|
|
|
+ SName: types.PrincipalName{
|
|
|
+ NameType: 1,
|
|
|
+ NameString: []string{fmt.Sprintf("%d", i), "test.cache"},
|
|
|
+ },
|
|
|
+ }
|
|
|
+ key := types.EncryptionKey{
|
|
|
+ KeyType: 1,
|
|
|
+ KeyValue: []byte{byte(i)},
|
|
|
+ }
|
|
|
+ e := c.addEntry(tkt, time.Unix(int64(0+i), 0).UTC(), time.Unix(int64(10+i), 0).UTC(), time.Unix(int64(20+i), 0).UTC(), time.Unix(int64(30+i), 0).UTC(), key)
|
|
|
+ assert.Equal(t, fmt.Sprintf("%d/test.cache", i), e.SPN, "SPN cache key not as expected")
|
|
|
+ }
|
|
|
+ expected := `[
|
|
|
+ {
|
|
|
+ "SPN": "0/test.cache",
|
|
|
+ "AuthTime": "1970-01-01T00:00:00Z",
|
|
|
+ "StartTime": "1970-01-01T00:00:10Z",
|
|
|
+ "EndTime": "1970-01-01T00:00:20Z",
|
|
|
+ "RenewTill": "1970-01-01T00:00:30Z"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "SPN": "1/test.cache",
|
|
|
+ "AuthTime": "1970-01-01T00:00:01Z",
|
|
|
+ "StartTime": "1970-01-01T00:00:11Z",
|
|
|
+ "EndTime": "1970-01-01T00:00:21Z",
|
|
|
+ "RenewTill": "1970-01-01T00:00:31Z"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "SPN": "2/test.cache",
|
|
|
+ "AuthTime": "1970-01-01T00:00:02Z",
|
|
|
+ "StartTime": "1970-01-01T00:00:12Z",
|
|
|
+ "EndTime": "1970-01-01T00:00:22Z",
|
|
|
+ "RenewTill": "1970-01-01T00:00:32Z"
|
|
|
+ }
|
|
|
+]`
|
|
|
+ j, err := c.JSON()
|
|
|
+ if err != nil {
|
|
|
+ t.Errorf("error getting json output of cache: %v", err)
|
|
|
+ }
|
|
|
+ assert.Equal(t, expected, j, "json output not as expected")
|
|
|
+}
|