k8s.io/client-go@v0.22.2/discovery/cached/disk/cached_discovery_test.go (about)

     1  /*
     2  Copyright 2016 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package disk
    18  
    19  import (
    20  	"io/ioutil"
    21  	"os"
    22  	"path/filepath"
    23  	"testing"
    24  	"time"
    25  
    26  	openapi_v2 "github.com/googleapis/gnostic/openapiv2"
    27  	"github.com/stretchr/testify/assert"
    28  
    29  	"k8s.io/apimachinery/pkg/api/errors"
    30  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    31  	"k8s.io/apimachinery/pkg/runtime/schema"
    32  	"k8s.io/apimachinery/pkg/version"
    33  	"k8s.io/client-go/discovery"
    34  	restclient "k8s.io/client-go/rest"
    35  	"k8s.io/client-go/rest/fake"
    36  )
    37  
    38  func TestCachedDiscoveryClient_Fresh(t *testing.T) {
    39  	assert := assert.New(t)
    40  
    41  	d, err := ioutil.TempDir("", "")
    42  	assert.NoError(err)
    43  	defer os.RemoveAll(d)
    44  
    45  	c := fakeDiscoveryClient{}
    46  	cdc := newCachedDiscoveryClient(&c, d, 60*time.Second)
    47  	assert.True(cdc.Fresh(), "should be fresh after creation")
    48  
    49  	cdc.ServerGroups()
    50  	assert.True(cdc.Fresh(), "should be fresh after groups call without cache")
    51  	assert.Equal(c.groupCalls, 1)
    52  
    53  	cdc.ServerGroups()
    54  	assert.True(cdc.Fresh(), "should be fresh after another groups call")
    55  	assert.Equal(c.groupCalls, 1)
    56  
    57  	cdc.ServerResources()
    58  	assert.True(cdc.Fresh(), "should be fresh after resources call")
    59  	assert.Equal(c.resourceCalls, 1)
    60  
    61  	cdc.ServerResources()
    62  	assert.True(cdc.Fresh(), "should be fresh after another resources call")
    63  	assert.Equal(c.resourceCalls, 1)
    64  
    65  	cdc = newCachedDiscoveryClient(&c, d, 60*time.Second)
    66  	cdc.ServerGroups()
    67  	assert.False(cdc.Fresh(), "should NOT be fresh after recreation with existing groups cache")
    68  	assert.Equal(c.groupCalls, 1)
    69  
    70  	cdc.ServerResources()
    71  	assert.False(cdc.Fresh(), "should NOT be fresh after recreation with existing resources cache")
    72  	assert.Equal(c.resourceCalls, 1)
    73  
    74  	cdc.Invalidate()
    75  	assert.True(cdc.Fresh(), "should be fresh after cache invalidation")
    76  
    77  	cdc.ServerResources()
    78  	assert.True(cdc.Fresh(), "should ignore existing resources cache after invalidation")
    79  	assert.Equal(c.resourceCalls, 2)
    80  }
    81  
    82  func TestNewCachedDiscoveryClient_TTL(t *testing.T) {
    83  	assert := assert.New(t)
    84  
    85  	d, err := ioutil.TempDir("", "")
    86  	assert.NoError(err)
    87  	defer os.RemoveAll(d)
    88  
    89  	c := fakeDiscoveryClient{}
    90  	cdc := newCachedDiscoveryClient(&c, d, 1*time.Nanosecond)
    91  	cdc.ServerGroups()
    92  	assert.Equal(c.groupCalls, 1)
    93  
    94  	time.Sleep(1 * time.Second)
    95  
    96  	cdc.ServerGroups()
    97  	assert.Equal(c.groupCalls, 2)
    98  }
    99  
   100  func TestNewCachedDiscoveryClient_PathPerm(t *testing.T) {
   101  	assert := assert.New(t)
   102  
   103  	d, err := ioutil.TempDir("", "")
   104  	assert.NoError(err)
   105  	os.RemoveAll(d)
   106  	defer os.RemoveAll(d)
   107  
   108  	c := fakeDiscoveryClient{}
   109  	cdc := newCachedDiscoveryClient(&c, d, 1*time.Nanosecond)
   110  	cdc.ServerGroups()
   111  
   112  	err = filepath.Walk(d, func(path string, info os.FileInfo, err error) error {
   113  		if err != nil {
   114  			return err
   115  		}
   116  		if info.IsDir() {
   117  			assert.Equal(os.FileMode(0750), info.Mode().Perm())
   118  		} else {
   119  			assert.Equal(os.FileMode(0660), info.Mode().Perm())
   120  		}
   121  		return nil
   122  	})
   123  	assert.NoError(err)
   124  }
   125  
   126  type fakeDiscoveryClient struct {
   127  	groupCalls    int
   128  	resourceCalls int
   129  	versionCalls  int
   130  	openAPICalls  int
   131  
   132  	serverResourcesHandler func() ([]*metav1.APIResourceList, error)
   133  }
   134  
   135  var _ discovery.DiscoveryInterface = &fakeDiscoveryClient{}
   136  
   137  func (c *fakeDiscoveryClient) RESTClient() restclient.Interface {
   138  	return &fake.RESTClient{}
   139  }
   140  
   141  func (c *fakeDiscoveryClient) ServerGroups() (*metav1.APIGroupList, error) {
   142  	c.groupCalls = c.groupCalls + 1
   143  	return c.serverGroups()
   144  }
   145  
   146  func (c *fakeDiscoveryClient) serverGroups() (*metav1.APIGroupList, error) {
   147  	return &metav1.APIGroupList{
   148  		Groups: []metav1.APIGroup{
   149  			{
   150  				Name: "a",
   151  				Versions: []metav1.GroupVersionForDiscovery{
   152  					{
   153  						GroupVersion: "a/v1",
   154  						Version:      "v1",
   155  					},
   156  				},
   157  				PreferredVersion: metav1.GroupVersionForDiscovery{
   158  					GroupVersion: "a/v1",
   159  					Version:      "v1",
   160  				},
   161  			},
   162  		},
   163  	}, nil
   164  }
   165  
   166  func (c *fakeDiscoveryClient) ServerResourcesForGroupVersion(groupVersion string) (*metav1.APIResourceList, error) {
   167  	c.resourceCalls = c.resourceCalls + 1
   168  	if groupVersion == "a/v1" {
   169  		return &metav1.APIResourceList{APIResources: []metav1.APIResource{{Name: "widgets", Kind: "Widget"}}}, nil
   170  	}
   171  
   172  	return nil, errors.NewNotFound(schema.GroupResource{}, "")
   173  }
   174  
   175  // Deprecated: use ServerGroupsAndResources instead.
   176  func (c *fakeDiscoveryClient) ServerResources() ([]*metav1.APIResourceList, error) {
   177  	_, rs, err := c.ServerGroupsAndResources()
   178  	return rs, err
   179  }
   180  
   181  func (c *fakeDiscoveryClient) ServerGroupsAndResources() ([]*metav1.APIGroup, []*metav1.APIResourceList, error) {
   182  	c.resourceCalls = c.resourceCalls + 1
   183  
   184  	gs, _ := c.serverGroups()
   185  	resultGroups := []*metav1.APIGroup{}
   186  	for i := range gs.Groups {
   187  		resultGroups = append(resultGroups, &gs.Groups[i])
   188  	}
   189  
   190  	if c.serverResourcesHandler != nil {
   191  		rs, err := c.serverResourcesHandler()
   192  		return resultGroups, rs, err
   193  	}
   194  	return resultGroups, []*metav1.APIResourceList{}, nil
   195  }
   196  
   197  func (c *fakeDiscoveryClient) ServerPreferredResources() ([]*metav1.APIResourceList, error) {
   198  	c.resourceCalls = c.resourceCalls + 1
   199  	return nil, nil
   200  }
   201  
   202  func (c *fakeDiscoveryClient) ServerPreferredNamespacedResources() ([]*metav1.APIResourceList, error) {
   203  	c.resourceCalls = c.resourceCalls + 1
   204  	return nil, nil
   205  }
   206  
   207  func (c *fakeDiscoveryClient) ServerVersion() (*version.Info, error) {
   208  	c.versionCalls = c.versionCalls + 1
   209  	return &version.Info{}, nil
   210  }
   211  
   212  func (c *fakeDiscoveryClient) OpenAPISchema() (*openapi_v2.Document, error) {
   213  	c.openAPICalls = c.openAPICalls + 1
   214  	return &openapi_v2.Document{}, nil
   215  }