From 216077d8b8200658bb369266e0da8ec3e271c4bc Mon Sep 17 00:00:00 2001 From: aprindle Date: Wed, 6 Jul 2016 10:33:52 -0700 Subject: [PATCH] Added get-k8s-versions command and tests. --- cmd/minikube/cmd/get_kubernetes_versions.go | 38 ++++++ .../kubernetes_versions.go | 72 +++++++++++ .../kubernetes_versions_test.go | 121 ++++++++++++++++++ pkg/minikube/notify/notify_test.go | 10 +- 4 files changed, 236 insertions(+), 5 deletions(-) create mode 100644 cmd/minikube/cmd/get_kubernetes_versions.go create mode 100644 pkg/minikube/kubernetes_versions/kubernetes_versions.go create mode 100644 pkg/minikube/kubernetes_versions/kubernetes_versions_test.go diff --git a/cmd/minikube/cmd/get_kubernetes_versions.go b/cmd/minikube/cmd/get_kubernetes_versions.go new file mode 100644 index 0000000000..48c3cb84ef --- /dev/null +++ b/cmd/minikube/cmd/get_kubernetes_versions.go @@ -0,0 +1,38 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. + +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 cmd + +import ( + "os" + + "github.com/spf13/cobra" + "k8s.io/minikube/pkg/minikube/kubernetes_versions" +) + +// getK8sVersionsCmd represents the ip command +var getK8sVersionsCmd = &cobra.Command{ + Use: "get-k8s-versions", + Short: "Gets the list of available kubernetes versions available for minikube.", + Long: `Gets the list of available kubernetes versions available for minikube.`, + Run: func(cmd *cobra.Command, args []string) { + kubernetes_versions.PrintKubernetesVersionsFromGCS(os.Stdout) + }, +} + +func init() { + RootCmd.AddCommand(getK8sVersionsCmd) +} diff --git a/pkg/minikube/kubernetes_versions/kubernetes_versions.go b/pkg/minikube/kubernetes_versions/kubernetes_versions.go new file mode 100644 index 0000000000..c8b2a30f67 --- /dev/null +++ b/pkg/minikube/kubernetes_versions/kubernetes_versions.go @@ -0,0 +1,72 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. + +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 kubernetes_versions + +import ( + "encoding/json" + "fmt" + "io" + "net/http" + + "github.com/golang/glog" +) + +const kubernetesVersionGCSURL = "https://storage.googleapis.com/minikube/k8s_releases.json" + +func PrintKubernetesVersionsFromGCS(output io.Writer) { + PrintKubernetesVersions(output, kubernetesVersionGCSURL) +} + +func PrintKubernetesVersions(output io.Writer, url string) { + k8sVersions, err := getK8sVersionsFromURL(url) + if err != nil { + glog.Errorln(err) + return + } + fmt.Fprint(output, "The following Kubernetes versions are available: \n") + + for _, k8sVersion := range k8sVersions { + fmt.Fprintf(output, "\t- %s\n", k8sVersion.Version) + } +} + +type k8sRelease struct { + Version string +} + +type k8sReleases []k8sRelease + +func getJson(url string, target *k8sReleases) error { + r, err := http.Get(url) + if err != nil { + return err + } + defer r.Body.Close() + + return json.NewDecoder(r.Body).Decode(target) +} + +func getK8sVersionsFromURL(url string) (k8sReleases, error) { + var k8sVersions k8sReleases + if err := getJson(url, &k8sVersions); err != nil { + return k8sReleases{}, err + } + if len(k8sVersions) == 0 { + return k8sReleases{}, fmt.Errorf("There were no json k8s Releases at the url specified: %s", url) + } + return k8sVersions, nil +} diff --git a/pkg/minikube/kubernetes_versions/kubernetes_versions_test.go b/pkg/minikube/kubernetes_versions/kubernetes_versions_test.go new file mode 100644 index 0000000000..8eb82c652e --- /dev/null +++ b/pkg/minikube/kubernetes_versions/kubernetes_versions_test.go @@ -0,0 +1,121 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. + +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 kubernetes_versions + +import ( + "bytes" + "encoding/json" + "fmt" + "net/http" + "net/http/httptest" + "testing" +) + +type URLHandlerCorrect struct { + K8sReleases k8sReleases +} + +func (h *URLHandlerCorrect) ServeHTTP(w http.ResponseWriter, r *http.Request) { + b, err := json.Marshal(h.K8sReleases) + if err != nil { + fmt.Println(err) + return + } + w.Header().Set("Content-Type", "application/javascript") + fmt.Fprintf(w, string(b)) +} + +func TestGetK8sVersionsFromURLCorrect(t *testing.T) { + // test that the version is correctly parsed if returned if valid JSON is returned the url endpoint + version0 := "0.0.0" + version1 := "1.0.0" + handler := &URLHandlerCorrect{ + K8sReleases: []k8sRelease{{Version: version0}, {Version: version1}}, + } + server := httptest.NewServer(handler) + + k8sVersions, err := getK8sVersionsFromURL(server.URL) + if err != nil { + t.Fatalf(err.Error()) + } + if len(k8sVersions) != 2 { // TODO(aprindle) change to len(handler....) + //Check values here as well? Write eq method? + t.Fatalf("Expected two kubernetes versions from URL to be %s, it was instead %s", 2, len(k8sVersions)) + } +} + +type URLHandlerNone struct{} + +func (h *URLHandlerNone) ServeHTTP(w http.ResponseWriter, r *http.Request) { +} + +func TestGetK8sVersionsFromURLNone(t *testing.T) { + // test that an error is returned if nothing is returned at the url endpoint + handler := &URLHandlerNone{} + server := httptest.NewServer(handler) + + _, err := getK8sVersionsFromURL(server.URL) + if err == nil { + t.Fatalf("No kubernetes versions were returned from URL but no error was thrown") + } +} + +type URLHandlerMalformed struct{} + +func (h *URLHandlerMalformed) ServeHTTP(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/javascript") + fmt.Fprintf(w, "Malformed JSON") +} + +func TestGetK8sVersionsFromURLMalformed(t *testing.T) { + // test that an error is returned if malformed JSON is at the url endpoint + handler := &URLHandlerMalformed{} + server := httptest.NewServer(handler) + + _, err := getK8sVersionsFromURL(server.URL) + if err == nil { + t.Fatalf("Malformed version value was returned from URL but no error was thrown") + } +} + +func TestPrintKubernetesVersions(t *testing.T) { + // test that no kubernetes version text is printed if there are no versions being served + // TODO(aprindle) or should this be an error?!?! + handlerNone := &URLHandlerNone{} + server := httptest.NewServer(handlerNone) + + var outputBuffer bytes.Buffer + PrintKubernetesVersions(&outputBuffer, server.URL) + if len(outputBuffer.String()) != 0 { + t.Fatalf("Expected PrintKubernetesVersions to not output text as there are no versioned served at the current URL but output was [%s]", outputBuffer.String()) + } + + // test that update text is printed if the latest version is greater than the current version + // k8sVersionsFromURL = "100.0.0-dev" + version0 := "0.0.0" + version1 := "1.0.0" + handlerCorrect := &URLHandlerCorrect{ + K8sReleases: []k8sRelease{{Version: version0}, {Version: version1}}, + } + server = httptest.NewServer(handlerCorrect) + + PrintKubernetesVersions(&outputBuffer, server.URL) + if len(outputBuffer.String()) == 0 { + t.Fatalf("Expected PrintKubernetesVersion to output text as %s versions were served from URL but output was [%s]", + 2, outputBuffer.String()) //TODO(aprindle) change the 2 + } +} diff --git a/pkg/minikube/notify/notify_test.go b/pkg/minikube/notify/notify_test.go index cbc6ef01f0..63d27c3cec 100644 --- a/pkg/minikube/notify/notify_test.go +++ b/pkg/minikube/notify/notify_test.go @@ -43,26 +43,26 @@ func TestShouldCheckURL(t *testing.T) { // test that if users disable update notification in config, the URL version does not get checked viper.Set(config.WantUpdateNotification, false) if shouldCheckURLVersion(lastUpdateCheckFilePath) { - t.Fatalf("Error: shouldCheckURLVersion returned true even though config had WantUpdateNotification: false") + t.Fatalf("shouldCheckURLVersion returned true even though config had WantUpdateNotification: false") } // test that if users want update notification, the URL version does get checked viper.Set(config.WantUpdateNotification, true) if shouldCheckURLVersion(lastUpdateCheckFilePath) == false { - t.Fatalf("Error: shouldCheckURLVersion returned false even though there was no last_update_check file") + t.Fatalf("shouldCheckURLVersion returned false even though there was no last_update_check file") } // test that update notifications get triggered if it has been longer than 24 hours viper.Set(config.ReminderWaitPeriodInHours, 24) writeTimeToFile(lastUpdateCheckFilePath, time.Time{}) //time.Time{} returns time -> January 1, year 1, 00:00:00.000000000 UTC. if shouldCheckURLVersion(lastUpdateCheckFilePath) == false { - t.Fatalf("Error: shouldCheckURLVersion returned false even though longer than 24 hours since last update") + t.Fatalf("shouldCheckURLVersion returned false even though longer than 24 hours since last update") } // test that update notifications do not get triggered if it has been less than 24 hours writeTimeToFile(lastUpdateCheckFilePath, time.Now().UTC()) if shouldCheckURLVersion(lastUpdateCheckFilePath) == true { - t.Fatalf("Error: shouldCheckURLVersion returned false even though longer than 24 hours since last update") + t.Fatalf("shouldCheckURLVersion returned false even though longer than 24 hours since last update") } } @@ -129,7 +129,7 @@ func TestGetLatestVersionFromURLMalformed(t *testing.T) { _, err := getLatestVersionFromURL(server.URL) if err == nil { - t.Fatalf("Error: ") + t.Fatalf("Malformed version value was returned from URL but no error was thrown") } }