mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-05 10:19:50 +00:00
rename cache, add to integration test
This commit is contained in:
parent
235a57a29e
commit
604db6eb2a
@ -69,7 +69,6 @@ func NewGVKParser(models proto.Models, preserveUnknownFields bool) (*GvkParser,
|
|||||||
if len(gvk.Kind) > 0 {
|
if len(gvk.Kind) > 0 {
|
||||||
_, ok := parser.gvks[gvk]
|
_, ok := parser.gvks[gvk]
|
||||||
if ok {
|
if ok {
|
||||||
// TODO: double check why this is failing in real_cluster_script.go
|
|
||||||
return nil, fmt.Errorf("duplicate entry for %v", gvk)
|
return nil, fmt.Errorf("duplicate entry for %v", gvk)
|
||||||
}
|
}
|
||||||
parser.gvks[gvk] = modelName
|
parser.gvks[gvk] = modelName
|
||||||
|
@ -19,22 +19,22 @@ type UnstructuredExtractor interface {
|
|||||||
ExtractUnstructuredStatus(object *unstructured.Unstructured, fieldManager string) (*unstructured.Unstructured, error)
|
ExtractUnstructuredStatus(object *unstructured.Unstructured, fieldManager string) (*unstructured.Unstructured, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// objectTypeCache is a cache of typed.ParseableTypes
|
//// objectTypeCache is a cache of typed.ParseableTypes
|
||||||
type objectTypeCache interface {
|
//type objectTypeCache interface {
|
||||||
objectTypeForGVK(gvk schema.GroupVersionKind) (*typed.ParseableType, error)
|
// objectTypeForGVK(gvk schema.GroupVersionKind) (*typed.ParseableType, error)
|
||||||
}
|
//}
|
||||||
|
|
||||||
// nonCachingObjectTypeCache is a objectTypeCache that does no caching
|
// objectTypeCache is a objectTypeCache that does no caching
|
||||||
// (i.e. it downloads the OpenAPISchema every time)
|
// (i.e. it downloads the OpenAPISchema every time)
|
||||||
// Useful during the proof-of-concept stage until we agree on a caching solution.
|
// Useful during the proof-of-concept stage until we agree on a caching solution.
|
||||||
type nonCachingObjectTypeCache struct {
|
type objectTypeCache struct {
|
||||||
// TODO: lock this?
|
// TODO: lock this?
|
||||||
discoveryClient discovery.DiscoveryInterface
|
discoveryClient discovery.DiscoveryInterface
|
||||||
gvkParser *fieldmanager.GvkParser
|
gvkParser *fieldmanager.GvkParser
|
||||||
}
|
}
|
||||||
|
|
||||||
// objectTypeForGVK retrieves the typed.ParseableType for a given gvk from the cache
|
// objectTypeForGVK retrieves the typed.ParseableType for a given gvk from the cache
|
||||||
func (c *nonCachingObjectTypeCache) objectTypeForGVK(gvk schema.GroupVersionKind) (*typed.ParseableType, error) {
|
func (c *objectTypeCache) objectTypeForGVK(gvk schema.GroupVersionKind) (*typed.ParseableType, error) {
|
||||||
|
|
||||||
if !c.discoveryClient.HasOpenAPISchemaChanged() && c.gvkParser != nil {
|
if !c.discoveryClient.HasOpenAPISchemaChanged() && c.gvkParser != nil {
|
||||||
// cache hit
|
// cache hit
|
||||||
@ -67,14 +67,14 @@ func (c *nonCachingObjectTypeCache) objectTypeForGVK(gvk schema.GroupVersionKind
|
|||||||
}
|
}
|
||||||
|
|
||||||
type extractor struct {
|
type extractor struct {
|
||||||
cache objectTypeCache
|
cache *objectTypeCache
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewUnstructuredExtractor creates the extractor with which you can extract the applied configuration
|
// NewUnstructuredExtractor creates the extractor with which you can extract the applied configuration
|
||||||
// for a given manager from an unstructured object.
|
// for a given manager from an unstructured object.
|
||||||
func NewUnstructuredExtractor(dc discovery.DiscoveryInterface) UnstructuredExtractor {
|
func NewUnstructuredExtractor(dc discovery.DiscoveryInterface) UnstructuredExtractor {
|
||||||
return &extractor{
|
return &extractor{
|
||||||
cache: &nonCachingObjectTypeCache{
|
cache: &objectTypeCache{
|
||||||
discoveryClient: dc,
|
discoveryClient: dc,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -149,6 +149,10 @@ func (d *memCacheClient) OpenAPISchema() (*openapi_v2.Document, error) {
|
|||||||
return d.delegate.OpenAPISchema()
|
return d.delegate.OpenAPISchema()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *memCacheClient) HasOpenAPISchemaChanged() bool {
|
||||||
|
return d.delegate.HasOpenAPISchemaChanged()
|
||||||
|
}
|
||||||
|
|
||||||
func (d *memCacheClient) Fresh() bool {
|
func (d *memCacheClient) Fresh() bool {
|
||||||
d.lock.RLock()
|
d.lock.RLock()
|
||||||
defer d.lock.RUnlock()
|
defer d.lock.RUnlock()
|
||||||
|
@ -153,6 +153,10 @@ func (c *FakeDiscovery) OpenAPISchema() (*openapi_v2.Document, error) {
|
|||||||
return &openapi_v2.Document{}, nil
|
return &openapi_v2.Document{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *FakeDiscovery) HasOpenAPISchemaChanged() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
// RESTClient returns a RESTClient that is used to communicate with API server
|
// RESTClient returns a RESTClient that is used to communicate with API server
|
||||||
// by this client implementation.
|
// by this client implementation.
|
||||||
func (c *FakeDiscovery) RESTClient() restclient.Interface {
|
func (c *FakeDiscovery) RESTClient() restclient.Interface {
|
||||||
|
@ -302,6 +302,39 @@ func TestUnstructuredExtract(t *testing.T) {
|
|||||||
}
|
}
|
||||||
fmt.Printf("gotModified = %+v\n", gotModified)
|
fmt.Printf("gotModified = %+v\n", gotModified)
|
||||||
|
|
||||||
|
// extract again to test hitting the object type cache
|
||||||
|
extracted2, err := extractor.ExtractUnstructured(gotModified, mgr)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error when extracting for the second time")
|
||||||
|
}
|
||||||
|
|
||||||
|
// modify the object and apply the modified object again
|
||||||
|
modified2 := extracted2
|
||||||
|
modified2.SetLabels(map[string]string{"label2": "value2"})
|
||||||
|
modifiedData2, err := json.Marshal(modified2)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to marshal modified pod into bytes: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
actualModified2, err := dynamicClient.Resource(resource).Namespace("default").Patch(
|
||||||
|
context.TODO(),
|
||||||
|
name,
|
||||||
|
types.ApplyPatchType,
|
||||||
|
modifiedData2,
|
||||||
|
metav1.PatchOptions{FieldManager: mgr})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error when applying modified pod: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
gotModified2, err := dynamicClient.Resource(resource).Namespace("default").Get(context.TODO(), name, metav1.GetOptions{})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error when getting pod %q: %v", name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(actualModified2, gotModified2) {
|
||||||
|
t.Fatalf("unexpected pod in list. wanted %#v, got %#v", actualModified, gotModified)
|
||||||
|
}
|
||||||
|
|
||||||
// delete the object dynamically
|
// delete the object dynamically
|
||||||
err = dynamicClient.Resource(resource).Namespace("default").Delete(context.TODO(), name, metav1.DeleteOptions{})
|
err = dynamicClient.Resource(resource).Namespace("default").Delete(context.TODO(), name, metav1.DeleteOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user