diff options
author | Jhon Honce <jhonce@redhat.com> | 2020-05-18 18:05:02 -0700 |
---|---|---|
committer | Jhon Honce <jhonce@redhat.com> | 2020-05-20 10:21:30 -0700 |
commit | f9c392f50a631a181bc2aa194b9c46504506d657 (patch) | |
tree | 226b022eb0d7aef35ad65dcaa10c6a2ec9f56e7c /pkg/api/handlers/utils/handler_test.go | |
parent | 09f8f14b4f7d09946d3d5cfc5460ec9923f7da59 (diff) | |
download | podman-f9c392f50a631a181bc2aa194b9c46504506d657.tar.gz podman-f9c392f50a631a181bc2aa194b9c46504506d657.tar.bz2 podman-f9c392f50a631a181bc2aa194b9c46504506d657.zip |
V2 API Version Support
* Update blang/semver to allow ParseTolerant() support
* Provide helper functions for API handlers to obtain client's 'version'
path variable focused on API endpoint tree: libpod vs. compat
* Introduce new errors:
* version not given in path, endpoints may determine if this is a hard
error (ErrVersionNotGiven)
* given version not supported (ErrVersionNotSupported), only a soft
error if the handler is going to hijack the connection
* Added unit tests for version parsing
* bindings check version on connect:
* client <= Server API version connection is continued
* client >= Server API version connection fails
Signed-off-by: Jhon Honce <jhonce@redhat.com>
Diffstat (limited to 'pkg/api/handlers/utils/handler_test.go')
-rw-r--r-- | pkg/api/handlers/utils/handler_test.go | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/pkg/api/handlers/utils/handler_test.go b/pkg/api/handlers/utils/handler_test.go new file mode 100644 index 000000000..6009432b5 --- /dev/null +++ b/pkg/api/handlers/utils/handler_test.go @@ -0,0 +1,139 @@ +package utils + +import ( + "errors" + "fmt" + "net/http" + "net/http/httptest" + "testing" + + "github.com/gorilla/mux" +) + +func TestSupportedVersion(t *testing.T) { + req, err := http.NewRequest("GET", + fmt.Sprintf("/v%s/libpod/testing/versions", ApiVersion[LibpodTree][CurrentApiVersion]), + nil) + if err != nil { + t.Fatal(err) + } + req = mux.SetURLVars(req, map[string]string{"version": ApiVersion[LibpodTree][CurrentApiVersion].String()}) + + rr := httptest.NewRecorder() + handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + _, err := SupportedVersionWithDefaults(r) + switch { + case errors.Is(err, ErrVersionNotGiven): // for compat endpoints version optional + w.WriteHeader(http.StatusInternalServerError) + fmt.Fprint(w, err.Error()) + case errors.Is(err, ErrVersionNotSupported): // version given but not supported + w.WriteHeader(http.StatusBadRequest) + fmt.Fprint(w, err.Error()) + case err != nil: + w.WriteHeader(http.StatusInternalServerError) + fmt.Fprint(w, err.Error()) + default: // all good + w.WriteHeader(http.StatusOK) + fmt.Fprint(w, "OK") + } + }) + handler.ServeHTTP(rr, req) + + if status := rr.Code; status != http.StatusOK { + t.Errorf("handler returned wrong status code: got %v want %v", + status, http.StatusOK) + } + + // Check the response body is what we expect. + expected := `OK` + if rr.Body.String() != expected { + t.Errorf("handler returned unexpected body: got %q want %q", + rr.Body.String(), expected) + } +} + +func TestUnsupportedVersion(t *testing.T) { + version := "999.999.999" + req, err := http.NewRequest("GET", + fmt.Sprintf("/v%s/libpod/testing/versions", version), + nil) + if err != nil { + t.Fatal(err) + } + req = mux.SetURLVars(req, map[string]string{"version": version}) + + rr := httptest.NewRecorder() + handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + _, err := SupportedVersionWithDefaults(r) + switch { + case errors.Is(err, ErrVersionNotGiven): // for compat endpoints version optional + w.WriteHeader(http.StatusInternalServerError) + fmt.Fprint(w, err.Error()) + case errors.Is(err, ErrVersionNotSupported): // version given but not supported + w.WriteHeader(http.StatusBadRequest) + fmt.Fprint(w, err.Error()) + case err != nil: + w.WriteHeader(http.StatusInternalServerError) + fmt.Fprint(w, err.Error()) + default: // all good + w.WriteHeader(http.StatusOK) + fmt.Fprint(w, "OK") + } + }) + handler.ServeHTTP(rr, req) + + if status := rr.Code; status != http.StatusBadRequest { + t.Errorf("handler returned wrong status code: got %v want %v", + status, http.StatusBadRequest) + } + + // Check the response body is what we expect. + expected := ErrVersionNotSupported.Error() + if rr.Body.String() != expected { + t.Errorf("handler returned unexpected body: got %q want %q", + rr.Body.String(), expected) + } +} + +func TestEqualVersion(t *testing.T) { + version := "1.30.0" + req, err := http.NewRequest("GET", + fmt.Sprintf("/v%s/libpod/testing/versions", version), + nil) + if err != nil { + t.Fatal(err) + } + req = mux.SetURLVars(req, map[string]string{"version": version}) + + rr := httptest.NewRecorder() + handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + _, err := SupportedVersion(r, "=="+version) + switch { + case errors.Is(err, ErrVersionNotGiven): // for compat endpoints version optional + w.WriteHeader(http.StatusInternalServerError) + fmt.Fprint(w, err.Error()) + case errors.Is(err, ErrVersionNotSupported): // version given but not supported + w.WriteHeader(http.StatusBadRequest) + fmt.Fprint(w, err.Error()) + case err != nil: + w.WriteHeader(http.StatusInternalServerError) + fmt.Fprint(w, err.Error()) + default: // all good + w.WriteHeader(http.StatusOK) + fmt.Fprint(w, "OK") + } + }) + handler.ServeHTTP(rr, req) + + if status := rr.Code; status != http.StatusOK { + t.Errorf("handler returned wrong status code: got %v want %v", + status, http.StatusOK) + } + + // Check the response body is what we expect. + expected := http.StatusText(http.StatusOK) + if rr.Body.String() != expected { + t.Errorf("handler returned unexpected body: got %q want %q", + rr.Body.String(), expected) + } +} |