github.com/moby/docker@v26.1.3+incompatible/api/server/middleware/version_test.go (about)

     1  package middleware // import "github.com/docker/docker/api/server/middleware"
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"net/http"
     7  	"net/http/httptest"
     8  	"runtime"
     9  	"testing"
    10  
    11  	"github.com/docker/docker/api"
    12  	"github.com/docker/docker/api/server/httputils"
    13  	"gotest.tools/v3/assert"
    14  	is "gotest.tools/v3/assert/cmp"
    15  )
    16  
    17  func TestNewVersionMiddlewareValidation(t *testing.T) {
    18  	tests := []struct {
    19  		doc, defaultVersion, minVersion, expectedErr string
    20  	}{
    21  		{
    22  			doc:            "defaults",
    23  			defaultVersion: api.DefaultVersion,
    24  			minVersion:     api.MinSupportedAPIVersion,
    25  		},
    26  		{
    27  			doc:            "invalid default lower than min",
    28  			defaultVersion: api.MinSupportedAPIVersion,
    29  			minVersion:     api.DefaultVersion,
    30  			expectedErr:    fmt.Sprintf("invalid API version: the minimum API version (%s) is higher than the default version (%s)", api.DefaultVersion, api.MinSupportedAPIVersion),
    31  		},
    32  		{
    33  			doc:            "invalid default too low",
    34  			defaultVersion: "0.1",
    35  			minVersion:     api.MinSupportedAPIVersion,
    36  			expectedErr:    fmt.Sprintf("invalid default API version (0.1): must be between %s and %s", api.MinSupportedAPIVersion, api.DefaultVersion),
    37  		},
    38  		{
    39  			doc:            "invalid default too high",
    40  			defaultVersion: "9999.9999",
    41  			minVersion:     api.DefaultVersion,
    42  			expectedErr:    fmt.Sprintf("invalid default API version (9999.9999): must be between %s and %s", api.MinSupportedAPIVersion, api.DefaultVersion),
    43  		},
    44  		{
    45  			doc:            "invalid minimum too low",
    46  			defaultVersion: api.MinSupportedAPIVersion,
    47  			minVersion:     "0.1",
    48  			expectedErr:    fmt.Sprintf("invalid minimum API version (0.1): must be between %s and %s", api.MinSupportedAPIVersion, api.DefaultVersion),
    49  		},
    50  		{
    51  			doc:            "invalid minimum too high",
    52  			defaultVersion: api.DefaultVersion,
    53  			minVersion:     "9999.9999",
    54  			expectedErr:    fmt.Sprintf("invalid minimum API version (9999.9999): must be between %s and %s", api.MinSupportedAPIVersion, api.DefaultVersion),
    55  		},
    56  	}
    57  
    58  	for _, tc := range tests {
    59  		tc := tc
    60  		t.Run(tc.doc, func(t *testing.T) {
    61  			_, err := NewVersionMiddleware("1.2.3", tc.defaultVersion, tc.minVersion)
    62  			if tc.expectedErr == "" {
    63  				assert.Check(t, err)
    64  			} else {
    65  				assert.Check(t, is.Error(err, tc.expectedErr))
    66  			}
    67  		})
    68  	}
    69  }
    70  
    71  func TestVersionMiddlewareVersion(t *testing.T) {
    72  	expectedVersion := "<not set>"
    73  	handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
    74  		v := httputils.VersionFromContext(ctx)
    75  		assert.Check(t, is.Equal(expectedVersion, v))
    76  		return nil
    77  	}
    78  
    79  	m, err := NewVersionMiddleware("1.2.3", api.DefaultVersion, api.MinSupportedAPIVersion)
    80  	assert.NilError(t, err)
    81  	h := m.WrapHandler(handler)
    82  
    83  	req, _ := http.NewRequest(http.MethodGet, "/containers/json", nil)
    84  	resp := httptest.NewRecorder()
    85  	ctx := context.Background()
    86  
    87  	tests := []struct {
    88  		reqVersion      string
    89  		expectedVersion string
    90  		errString       string
    91  	}{
    92  		{
    93  			expectedVersion: api.DefaultVersion,
    94  		},
    95  		{
    96  			reqVersion:      api.MinSupportedAPIVersion,
    97  			expectedVersion: api.MinSupportedAPIVersion,
    98  		},
    99  		{
   100  			reqVersion: "0.1",
   101  			errString:  fmt.Sprintf("client version 0.1 is too old. Minimum supported API version is %s, please upgrade your client to a newer version", api.MinSupportedAPIVersion),
   102  		},
   103  		{
   104  			reqVersion: "9999.9999",
   105  			errString:  fmt.Sprintf("client version 9999.9999 is too new. Maximum supported API version is %s", api.DefaultVersion),
   106  		},
   107  	}
   108  
   109  	for _, test := range tests {
   110  		expectedVersion = test.expectedVersion
   111  
   112  		err := h(ctx, resp, req, map[string]string{"version": test.reqVersion})
   113  
   114  		if test.errString != "" {
   115  			assert.Check(t, is.Error(err, test.errString))
   116  		} else {
   117  			assert.Check(t, err)
   118  		}
   119  	}
   120  }
   121  
   122  func TestVersionMiddlewareWithErrorsReturnsHeaders(t *testing.T) {
   123  	handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
   124  		v := httputils.VersionFromContext(ctx)
   125  		assert.Check(t, len(v) != 0)
   126  		return nil
   127  	}
   128  
   129  	m, err := NewVersionMiddleware("1.2.3", api.DefaultVersion, api.MinSupportedAPIVersion)
   130  	assert.NilError(t, err)
   131  	h := m.WrapHandler(handler)
   132  
   133  	req, _ := http.NewRequest(http.MethodGet, "/containers/json", nil)
   134  	resp := httptest.NewRecorder()
   135  	ctx := context.Background()
   136  
   137  	vars := map[string]string{"version": "0.1"}
   138  	err = h(ctx, resp, req, vars)
   139  	assert.Check(t, is.ErrorContains(err, ""))
   140  
   141  	hdr := resp.Result().Header
   142  	assert.Check(t, is.Contains(hdr.Get("Server"), "Docker/1.2.3"))
   143  	assert.Check(t, is.Contains(hdr.Get("Server"), runtime.GOOS))
   144  	assert.Check(t, is.Equal(hdr.Get("API-Version"), api.DefaultVersion))
   145  	assert.Check(t, is.Equal(hdr.Get("OSType"), runtime.GOOS))
   146  }