kubernetes/pkg/kubectl/cmd/util/openapi/openapi_cache_test.go
Jordan Liggitt 4ee72eb300
Revert "Merge pull request #47353 from apelisse/http-cache"
This reverts commit fc89743dca, reversing
changes made to 29ab38e898.
2017-08-07 16:20:34 -04:00

269 lines
6.3 KiB
Go

/*
Copyright 2017 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 openapi_test
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"sync"
"gopkg.in/yaml.v2"
"github.com/googleapis/gnostic/OpenAPIv2"
"github.com/googleapis/gnostic/compiler"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
)
var _ = Describe("When reading openAPIData", func() {
var tmpDir string
var err error
var client *fakeOpenAPIClient
var instance *openapi.CachingOpenAPIClient
var expectedData openapi.Resources
BeforeEach(func() {
tmpDir, err = ioutil.TempDir("", "openapi_cache_test")
Expect(err).To(BeNil())
client = &fakeOpenAPIClient{}
instance = openapi.NewCachingOpenAPIClient(client, "v1.6", tmpDir)
d, err := data.OpenAPISchema()
Expect(err).To(BeNil())
expectedData, err = openapi.NewOpenAPIData(d)
Expect(err).To(BeNil())
})
AfterEach(func() {
os.RemoveAll(tmpDir)
})
It("should write to the cache", func() {
By("getting the live openapi spec from the server")
result, err := instance.OpenAPIData()
Expect(err).To(BeNil())
Expect(result).To(Equal(expectedData))
Expect(client.calls).To(Equal(1))
By("writing the live openapi spec to a local cache file")
names, err := getFilenames(tmpDir)
Expect(err).To(BeNil())
Expect(names).To(ConsistOf("v1.6"))
names, err = getFilenames(filepath.Join(tmpDir, "v1.6"))
Expect(err).To(BeNil())
Expect(names).To(HaveLen(1))
clientVersion := names[0]
names, err = getFilenames(filepath.Join(tmpDir, "v1.6", clientVersion))
Expect(err).To(BeNil())
Expect(names).To(ContainElement("openapi_cache"))
})
It("should read from the cache", func() {
// First call should use the client
result, err := instance.OpenAPIData()
Expect(err).To(BeNil())
Expect(result).To(Equal(expectedData))
Expect(client.calls).To(Equal(1))
// Second call shouldn't use the client
result, err = instance.OpenAPIData()
Expect(err).To(BeNil())
Expect(result).To(Equal(expectedData))
Expect(client.calls).To(Equal(1))
names, err := getFilenames(tmpDir)
Expect(err).To(BeNil())
Expect(names).To(ConsistOf("v1.6"))
})
It("propagate errors that are encountered", func() {
// Expect an error
client.err = fmt.Errorf("expected error")
result, err := instance.OpenAPIData()
Expect(err.Error()).To(Equal(client.err.Error()))
Expect(result).To(BeNil())
Expect(client.calls).To(Equal(1))
// No cache file is written
files, err := ioutil.ReadDir(tmpDir)
Expect(err).To(BeNil())
Expect(files).To(HaveLen(0))
// Client error is not cached
result, err = instance.OpenAPIData()
Expect(err.Error()).To(Equal(client.err.Error()))
Expect(result).To(BeNil())
Expect(client.calls).To(Equal(2))
})
})
var _ = Describe("Reading openAPIData", func() {
var tmpDir string
var serverVersion string
var cacheDir string
BeforeEach(func() {
var err error
tmpDir, err = ioutil.TempDir("", "openapi_cache_test")
Expect(err).To(BeNil())
})
AfterEach(func() {
os.RemoveAll(tmpDir)
})
// Set the serverVersion to empty
Context("when the server version is empty", func() {
BeforeEach(func() {
serverVersion = ""
cacheDir = tmpDir
})
It("should not cache the result", func() {
client := &fakeOpenAPIClient{}
instance := openapi.NewCachingOpenAPIClient(client, serverVersion, cacheDir)
d, err := data.OpenAPISchema()
Expect(err).To(BeNil())
expectedData, err := openapi.NewOpenAPIData(d)
Expect(err).To(BeNil())
By("getting the live openapi schema")
result, err := instance.OpenAPIData()
Expect(err).To(BeNil())
Expect(result).To(Equal(expectedData))
Expect(client.calls).To(Equal(1))
files, err := ioutil.ReadDir(tmpDir)
Expect(err).To(BeNil())
Expect(files).To(HaveLen(0))
})
})
Context("when the cache directory is empty", func() {
BeforeEach(func() {
serverVersion = "v1.6"
cacheDir = ""
})
It("should not cache the result", func() {
client := &fakeOpenAPIClient{}
instance := openapi.NewCachingOpenAPIClient(client, serverVersion, cacheDir)
d, err := data.OpenAPISchema()
Expect(err).To(BeNil())
expectedData, err := openapi.NewOpenAPIData(d)
Expect(err).To(BeNil())
By("getting the live openapi schema")
result, err := instance.OpenAPIData()
Expect(err).To(BeNil())
Expect(result).To(Equal(expectedData))
Expect(client.calls).To(Equal(1))
files, err := ioutil.ReadDir(tmpDir)
Expect(err).To(BeNil())
Expect(files).To(HaveLen(0))
})
})
})
// Test Utils
func getFilenames(path string) ([]string, error) {
files, err := ioutil.ReadDir(path)
if err != nil {
return nil, err
}
result := []string{}
for _, n := range files {
result = append(result, n.Name())
}
return result, nil
}
type fakeOpenAPIClient struct {
calls int
err error
}
func (f *fakeOpenAPIClient) OpenAPISchema() (*openapi_v2.Document, error) {
f.calls = f.calls + 1
if f.err != nil {
return nil, f.err
}
return data.OpenAPISchema()
}
// Test utils
var data apiData
type apiData struct {
sync.Once
data *openapi_v2.Document
err error
}
func (d *apiData) OpenAPISchema() (*openapi_v2.Document, error) {
d.Do(func() {
// Get the path to the swagger.json file
wd, err := os.Getwd()
if err != nil {
d.err = err
return
}
abs, err := filepath.Abs(wd)
if err != nil {
d.err = err
return
}
root := filepath.Dir(filepath.Dir(filepath.Dir(filepath.Dir(filepath.Dir(abs)))))
specpath := filepath.Join(root, "api", "openapi-spec", "swagger.json")
_, err = os.Stat(specpath)
if err != nil {
d.err = err
return
}
spec, err := ioutil.ReadFile(specpath)
if err != nil {
d.err = err
return
}
var info yaml.MapSlice
err = yaml.Unmarshal(spec, &info)
if err != nil {
d.err = err
return
}
d.data, d.err = openapi_v2.NewDocument(info, compiler.NewContext("$root", nil))
})
return d.data, d.err
}