2018-02-07 15:52:47 -05:00
|
|
|
package images // import "github.com/docker/docker/daemon/images"
|
2016-05-21 10:00:28 -04:00
|
|
|
|
|
|
|
import (
|
2018-04-19 18:30:59 -04:00
|
|
|
"context"
|
2016-12-25 01:37:31 -05:00
|
|
|
"errors"
|
2016-05-21 10:00:28 -04:00
|
|
|
"testing"
|
|
|
|
|
2016-09-06 14:18:12 -04:00
|
|
|
"github.com/docker/docker/api/types"
|
2022-03-02 10:03:38 -05:00
|
|
|
"github.com/docker/docker/api/types/filters"
|
2016-09-06 14:18:12 -04:00
|
|
|
registrytypes "github.com/docker/docker/api/types/registry"
|
2022-03-02 10:03:38 -05:00
|
|
|
"github.com/docker/docker/errdefs"
|
2016-05-21 10:00:28 -04:00
|
|
|
"github.com/docker/docker/registry"
|
2022-03-18 14:30:07 -04:00
|
|
|
"gotest.tools/v3/assert"
|
2016-05-21 10:00:28 -04:00
|
|
|
)
|
|
|
|
|
2022-02-25 17:45:49 -05:00
|
|
|
type fakeService struct {
|
|
|
|
registry.Service
|
2016-05-21 10:00:28 -04:00
|
|
|
shouldReturnError bool
|
|
|
|
|
|
|
|
term string
|
|
|
|
results []registrytypes.SearchResult
|
|
|
|
}
|
|
|
|
|
2022-02-25 17:45:49 -05:00
|
|
|
func (s *fakeService) Search(ctx context.Context, term string, limit int, authConfig *types.AuthConfig, userAgent string, headers map[string][]string) (*registrytypes.SearchResults, error) {
|
2016-05-21 10:00:28 -04:00
|
|
|
if s.shouldReturnError {
|
2022-03-02 10:03:38 -05:00
|
|
|
return nil, errdefs.Unknown(errors.New("search unknown error"))
|
2016-05-21 10:00:28 -04:00
|
|
|
}
|
|
|
|
return ®istrytypes.SearchResults{
|
|
|
|
Query: s.term,
|
|
|
|
NumResults: len(s.results),
|
|
|
|
Results: s.results,
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestSearchRegistryForImagesErrors(t *testing.T) {
|
|
|
|
errorCases := []struct {
|
2022-03-02 10:03:38 -05:00
|
|
|
filtersArgs filters.Args
|
2016-05-21 10:00:28 -04:00
|
|
|
shouldReturnError bool
|
|
|
|
expectedError string
|
|
|
|
}{
|
|
|
|
{
|
2022-03-02 10:03:38 -05:00
|
|
|
expectedError: "search unknown error",
|
2016-05-21 10:00:28 -04:00
|
|
|
shouldReturnError: true,
|
|
|
|
},
|
|
|
|
{
|
2022-03-02 10:03:38 -05:00
|
|
|
filtersArgs: filters.NewArgs(filters.Arg("type", "custom")),
|
2022-03-02 12:56:06 -05:00
|
|
|
expectedError: "invalid filter 'type'",
|
2016-05-21 10:00:28 -04:00
|
|
|
},
|
|
|
|
{
|
2022-03-02 10:03:38 -05:00
|
|
|
filtersArgs: filters.NewArgs(filters.Arg("is-automated", "invalid")),
|
2022-03-02 12:56:06 -05:00
|
|
|
expectedError: "invalid filter 'is-automated=[invalid]'",
|
2016-05-21 10:00:28 -04:00
|
|
|
},
|
|
|
|
{
|
2022-03-02 10:03:38 -05:00
|
|
|
filtersArgs: filters.NewArgs(
|
|
|
|
filters.Arg("is-automated", "true"),
|
|
|
|
filters.Arg("is-automated", "false"),
|
|
|
|
),
|
2022-03-02 12:56:06 -05:00
|
|
|
expectedError: "invalid filter 'is-automated",
|
2016-05-21 10:00:28 -04:00
|
|
|
},
|
|
|
|
{
|
2022-03-02 10:03:38 -05:00
|
|
|
filtersArgs: filters.NewArgs(filters.Arg("is-official", "invalid")),
|
2022-03-02 12:56:06 -05:00
|
|
|
expectedError: "invalid filter 'is-official=[invalid]'",
|
2016-05-21 10:00:28 -04:00
|
|
|
},
|
|
|
|
{
|
2022-03-02 10:03:38 -05:00
|
|
|
filtersArgs: filters.NewArgs(
|
|
|
|
filters.Arg("is-official", "true"),
|
|
|
|
filters.Arg("is-official", "false"),
|
|
|
|
),
|
2022-03-02 12:56:06 -05:00
|
|
|
expectedError: "invalid filter 'is-official",
|
2016-05-21 10:00:28 -04:00
|
|
|
},
|
|
|
|
{
|
2022-03-02 10:03:38 -05:00
|
|
|
filtersArgs: filters.NewArgs(filters.Arg("stars", "invalid")),
|
2022-03-02 12:56:06 -05:00
|
|
|
expectedError: "invalid filter 'stars=invalid'",
|
2016-05-21 10:00:28 -04:00
|
|
|
},
|
|
|
|
{
|
2022-03-02 10:03:38 -05:00
|
|
|
filtersArgs: filters.NewArgs(
|
|
|
|
filters.Arg("stars", "1"),
|
|
|
|
filters.Arg("stars", "invalid"),
|
|
|
|
),
|
2022-03-02 12:56:06 -05:00
|
|
|
expectedError: "invalid filter 'stars=invalid'",
|
2016-05-21 10:00:28 -04:00
|
|
|
},
|
|
|
|
}
|
2022-03-18 14:30:07 -04:00
|
|
|
for _, tc := range errorCases {
|
|
|
|
tc := tc
|
|
|
|
t.Run(tc.expectedError, func(t *testing.T) {
|
|
|
|
daemon := &ImageService{
|
|
|
|
registryService: &fakeService{
|
|
|
|
shouldReturnError: tc.shouldReturnError,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
_, err := daemon.SearchRegistryForImages(context.Background(), tc.filtersArgs, "term", 0, nil, map[string][]string{})
|
|
|
|
assert.ErrorContains(t, err, tc.expectedError)
|
|
|
|
if tc.shouldReturnError {
|
|
|
|
assert.Check(t, errdefs.IsUnknown(err), "got: %T: %v", err, err)
|
|
|
|
return
|
2022-03-02 10:03:38 -05:00
|
|
|
}
|
2022-03-18 14:30:07 -04:00
|
|
|
assert.Check(t, errdefs.IsInvalidParameter(err), "got: %T: %v", err, err)
|
|
|
|
})
|
2016-05-21 10:00:28 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestSearchRegistryForImages(t *testing.T) {
|
|
|
|
term := "term"
|
|
|
|
successCases := []struct {
|
2022-03-18 14:30:07 -04:00
|
|
|
name string
|
2022-03-02 10:03:38 -05:00
|
|
|
filtersArgs filters.Args
|
2016-05-21 10:00:28 -04:00
|
|
|
registryResults []registrytypes.SearchResult
|
|
|
|
expectedResults []registrytypes.SearchResult
|
|
|
|
}{
|
|
|
|
{
|
2022-03-18 14:30:07 -04:00
|
|
|
name: "empty results",
|
2016-05-21 10:00:28 -04:00
|
|
|
registryResults: []registrytypes.SearchResult{},
|
|
|
|
expectedResults: []registrytypes.SearchResult{},
|
|
|
|
},
|
|
|
|
{
|
2022-03-18 14:30:07 -04:00
|
|
|
name: "no filter",
|
2016-05-21 10:00:28 -04:00
|
|
|
registryResults: []registrytypes.SearchResult{
|
|
|
|
{
|
|
|
|
Name: "name",
|
|
|
|
Description: "description",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
expectedResults: []registrytypes.SearchResult{
|
|
|
|
{
|
|
|
|
Name: "name",
|
|
|
|
Description: "description",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
2022-03-18 14:30:07 -04:00
|
|
|
name: "is-automated=true, no results",
|
2022-03-02 10:03:38 -05:00
|
|
|
filtersArgs: filters.NewArgs(filters.Arg("is-automated", "true")),
|
2016-05-21 10:00:28 -04:00
|
|
|
registryResults: []registrytypes.SearchResult{
|
|
|
|
{
|
|
|
|
Name: "name",
|
|
|
|
Description: "description",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
expectedResults: []registrytypes.SearchResult{},
|
|
|
|
},
|
|
|
|
{
|
2022-03-18 14:30:07 -04:00
|
|
|
name: "is-automated=true",
|
2022-03-02 10:03:38 -05:00
|
|
|
filtersArgs: filters.NewArgs(filters.Arg("is-automated", "true")),
|
2016-05-21 10:00:28 -04:00
|
|
|
registryResults: []registrytypes.SearchResult{
|
|
|
|
{
|
|
|
|
Name: "name",
|
|
|
|
Description: "description",
|
|
|
|
IsAutomated: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
expectedResults: []registrytypes.SearchResult{
|
|
|
|
{
|
|
|
|
Name: "name",
|
|
|
|
Description: "description",
|
|
|
|
IsAutomated: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
2022-03-18 14:30:07 -04:00
|
|
|
name: "is-automated=false, no results",
|
2022-03-02 10:03:38 -05:00
|
|
|
filtersArgs: filters.NewArgs(filters.Arg("is-automated", "false")),
|
2016-05-21 10:00:28 -04:00
|
|
|
registryResults: []registrytypes.SearchResult{
|
|
|
|
{
|
|
|
|
Name: "name",
|
|
|
|
Description: "description",
|
|
|
|
IsAutomated: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
expectedResults: []registrytypes.SearchResult{},
|
|
|
|
},
|
|
|
|
{
|
2022-03-18 14:30:07 -04:00
|
|
|
name: "is-automated=false",
|
2022-03-02 10:03:38 -05:00
|
|
|
filtersArgs: filters.NewArgs(filters.Arg("is-automated", "false")),
|
2016-05-21 10:00:28 -04:00
|
|
|
registryResults: []registrytypes.SearchResult{
|
|
|
|
{
|
|
|
|
Name: "name",
|
|
|
|
Description: "description",
|
|
|
|
IsAutomated: false,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
expectedResults: []registrytypes.SearchResult{
|
|
|
|
{
|
|
|
|
Name: "name",
|
|
|
|
Description: "description",
|
|
|
|
IsAutomated: false,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
2022-03-18 14:30:07 -04:00
|
|
|
name: "is-official=true, no results",
|
2022-03-02 10:03:38 -05:00
|
|
|
filtersArgs: filters.NewArgs(filters.Arg("is-official", "true")),
|
2016-05-21 10:00:28 -04:00
|
|
|
registryResults: []registrytypes.SearchResult{
|
|
|
|
{
|
|
|
|
Name: "name",
|
|
|
|
Description: "description",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
expectedResults: []registrytypes.SearchResult{},
|
|
|
|
},
|
|
|
|
{
|
2022-03-18 14:30:07 -04:00
|
|
|
name: "is-official=true",
|
2022-03-02 10:03:38 -05:00
|
|
|
filtersArgs: filters.NewArgs(filters.Arg("is-official", "true")),
|
2016-05-21 10:00:28 -04:00
|
|
|
registryResults: []registrytypes.SearchResult{
|
|
|
|
{
|
|
|
|
Name: "name",
|
|
|
|
Description: "description",
|
|
|
|
IsOfficial: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
expectedResults: []registrytypes.SearchResult{
|
|
|
|
{
|
|
|
|
Name: "name",
|
|
|
|
Description: "description",
|
|
|
|
IsOfficial: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
2022-03-18 14:30:07 -04:00
|
|
|
name: "is-official=false, no results",
|
2022-03-02 10:03:38 -05:00
|
|
|
filtersArgs: filters.NewArgs(filters.Arg("is-official", "false")),
|
2016-05-21 10:00:28 -04:00
|
|
|
registryResults: []registrytypes.SearchResult{
|
|
|
|
{
|
|
|
|
Name: "name",
|
|
|
|
Description: "description",
|
|
|
|
IsOfficial: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
expectedResults: []registrytypes.SearchResult{},
|
|
|
|
},
|
|
|
|
{
|
2022-03-18 14:30:07 -04:00
|
|
|
name: "is-official=false",
|
2022-03-02 10:03:38 -05:00
|
|
|
filtersArgs: filters.NewArgs(filters.Arg("is-official", "false")),
|
2016-05-21 10:00:28 -04:00
|
|
|
registryResults: []registrytypes.SearchResult{
|
|
|
|
{
|
|
|
|
Name: "name",
|
|
|
|
Description: "description",
|
|
|
|
IsOfficial: false,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
expectedResults: []registrytypes.SearchResult{
|
|
|
|
{
|
|
|
|
Name: "name",
|
|
|
|
Description: "description",
|
|
|
|
IsOfficial: false,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
2022-03-18 14:30:07 -04:00
|
|
|
name: "stars=0",
|
2022-03-02 10:03:38 -05:00
|
|
|
filtersArgs: filters.NewArgs(filters.Arg("stars", "0")),
|
2016-05-21 10:00:28 -04:00
|
|
|
registryResults: []registrytypes.SearchResult{
|
|
|
|
{
|
|
|
|
Name: "name",
|
|
|
|
Description: "description",
|
|
|
|
StarCount: 0,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
expectedResults: []registrytypes.SearchResult{
|
|
|
|
{
|
|
|
|
Name: "name",
|
|
|
|
Description: "description",
|
|
|
|
StarCount: 0,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
2022-03-18 14:30:07 -04:00
|
|
|
name: "stars=0, no results",
|
2022-03-02 10:03:38 -05:00
|
|
|
filtersArgs: filters.NewArgs(filters.Arg("stars", "1")),
|
2016-05-21 10:00:28 -04:00
|
|
|
registryResults: []registrytypes.SearchResult{
|
|
|
|
{
|
|
|
|
Name: "name",
|
|
|
|
Description: "description",
|
|
|
|
StarCount: 0,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
expectedResults: []registrytypes.SearchResult{},
|
|
|
|
},
|
|
|
|
{
|
2022-03-18 14:30:07 -04:00
|
|
|
name: "stars=1",
|
2022-03-02 10:03:38 -05:00
|
|
|
filtersArgs: filters.NewArgs(filters.Arg("stars", "1")),
|
2016-05-21 10:00:28 -04:00
|
|
|
registryResults: []registrytypes.SearchResult{
|
|
|
|
{
|
|
|
|
Name: "name0",
|
|
|
|
Description: "description0",
|
|
|
|
StarCount: 0,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Name: "name1",
|
|
|
|
Description: "description1",
|
|
|
|
StarCount: 1,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
expectedResults: []registrytypes.SearchResult{
|
|
|
|
{
|
|
|
|
Name: "name1",
|
|
|
|
Description: "description1",
|
|
|
|
StarCount: 1,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
2022-03-18 14:30:07 -04:00
|
|
|
name: "stars=1, is-official=true, is-automated=true",
|
2022-03-02 10:03:38 -05:00
|
|
|
filtersArgs: filters.NewArgs(
|
|
|
|
filters.Arg("stars", "1"),
|
|
|
|
filters.Arg("is-official", "true"),
|
|
|
|
filters.Arg("is-automated", "true"),
|
|
|
|
),
|
2016-05-21 10:00:28 -04:00
|
|
|
registryResults: []registrytypes.SearchResult{
|
|
|
|
{
|
|
|
|
Name: "name0",
|
|
|
|
Description: "description0",
|
|
|
|
StarCount: 0,
|
|
|
|
IsOfficial: true,
|
|
|
|
IsAutomated: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Name: "name1",
|
|
|
|
Description: "description1",
|
|
|
|
StarCount: 1,
|
|
|
|
IsOfficial: false,
|
|
|
|
IsAutomated: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Name: "name2",
|
|
|
|
Description: "description2",
|
|
|
|
StarCount: 1,
|
|
|
|
IsOfficial: true,
|
|
|
|
IsAutomated: false,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Name: "name3",
|
|
|
|
Description: "description3",
|
|
|
|
StarCount: 2,
|
|
|
|
IsOfficial: true,
|
|
|
|
IsAutomated: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
expectedResults: []registrytypes.SearchResult{
|
|
|
|
{
|
|
|
|
Name: "name3",
|
|
|
|
Description: "description3",
|
|
|
|
StarCount: 2,
|
|
|
|
IsOfficial: true,
|
|
|
|
IsAutomated: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
2022-03-18 14:30:07 -04:00
|
|
|
for _, tc := range successCases {
|
|
|
|
tc := tc
|
|
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
|
|
daemon := &ImageService{
|
|
|
|
registryService: &fakeService{
|
|
|
|
term: term,
|
|
|
|
results: tc.registryResults,
|
|
|
|
},
|
2016-05-21 10:00:28 -04:00
|
|
|
}
|
2022-03-18 14:30:07 -04:00
|
|
|
results, err := daemon.SearchRegistryForImages(context.Background(), tc.filtersArgs, term, 0, nil, map[string][]string{})
|
|
|
|
assert.NilError(t, err)
|
|
|
|
assert.Equal(t, results.Query, term)
|
|
|
|
assert.Equal(t, results.NumResults, len(tc.expectedResults))
|
|
|
|
assert.DeepEqual(t, results.Results, tc.expectedResults)
|
|
|
|
})
|
2016-05-21 10:00:28 -04:00
|
|
|
}
|
|
|
|
}
|