/* Copyright 2022 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package v2 import ( "bytes" "encoding/json" "fmt" "testing" "github.com/stretchr/testify/require" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/client-go/openapi/openapitest" ) var apiGroupsPath = "apis/discovery.k8s.io/v1" var apiGroupsGVR = schema.GroupVersionResource{ Group: "discovery.k8s.io", Version: "v1", Resource: "apigroups", } func TestExplainErrors(t *testing.T) { var buf bytes.Buffer // Validate error when GVR is not found in returned paths map. fakeClient := openapitest.NewFakeClient() err := PrintModelDescription(nil, &buf, fakeClient, schema.GroupVersionResource{ Group: "test0.example.com", Version: "v1", Resource: "doesntmatter", }, false, "unknown-format") require.ErrorContains(t, err, "couldn't find resource for \"test0.example.com/v1, Resource=doesntmatter\"") // Validate error when openapi client returns error. fakeClient.ForcedErr = fmt.Errorf("Always fails") err = PrintModelDescription(nil, &buf, fakeClient, apiGroupsGVR, false, "unknown-format") require.ErrorContains(t, err, "failed to fetch list of groupVersions") // Validate error when GroupVersion "Schema()" call returns error. fakeClient = openapitest.NewFakeClient() forceErrorGV := openapitest.FakeGroupVersion{ForcedErr: fmt.Errorf("Always fails")} fakeClient.PathsMap["apis/test1.example.com/v1"] = &forceErrorGV err = PrintModelDescription(nil, &buf, fakeClient, schema.GroupVersionResource{ Group: "test1.example.com", Version: "v1", Resource: "doesntmatter", }, false, "unknown-format") require.ErrorContains(t, err, "failed to fetch openapi schema ") // Validate error when returned bytes from GroupVersion "Schema" are invalid. parseErrorGV := openapitest.FakeGroupVersion{GVSpec: []byte(``)} fakeClient.PathsMap["apis/test2.example.com/v1"] = &parseErrorGV err = PrintModelDescription(nil, &buf, fakeClient, schema.GroupVersionResource{ Group: "test2.example.com", Version: "v1", Resource: "doesntmatter", }, false, "unknown-format") require.ErrorContains(t, err, "failed to parse openapi schema") // Validate error when render template is not recognized. client := openapitest.NewEmbeddedFileClient() err = PrintModelDescription(nil, &buf, client, apiGroupsGVR, false, "unknown-format") require.ErrorContains(t, err, "unrecognized format: unknown-format") } // Shows that the correct GVR is fetched from the open api client when // given to explain func TestExplainOpenAPIClient(t *testing.T) { var buf bytes.Buffer fileClient := openapitest.NewEmbeddedFileClient() paths, err := fileClient.Paths() require.NoError(t, err) gv, found := paths[apiGroupsPath] require.True(t, found) discoveryBytes, err := gv.Schema("application/json") require.NoError(t, err) var doc map[string]interface{} err = json.Unmarshal(discoveryBytes, &doc) require.NoError(t, err) gen := NewGenerator() err = gen.AddTemplate("Context", "{{ toJson . }}") require.NoError(t, err) expectedContext := TemplateContext{ Document: doc, GVR: apiGroupsGVR, Recursive: false, FieldPath: nil, } err = printModelDescriptionWithGenerator(gen, nil, &buf, fileClient, apiGroupsGVR, false, "Context") require.NoError(t, err) var actualContext TemplateContext err = json.Unmarshal(buf.Bytes(), &actualContext) require.NoError(t, err) require.Equal(t, expectedContext, actualContext) }