Skip to content

Commit 5ec9f93

Browse files
Merge pull request #139 from gbenhaim/make_downloader_testable
Make downloader.go testable
2 parents 9189552 + 0d63ca2 commit 5ec9f93

File tree

370 files changed

+24399
-17359
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

370 files changed

+24399
-17359
lines changed

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ require (
2828
k8s.io/apimachinery v0.0.0-20191004115801-a2eda9f80ab8
2929
k8s.io/client-go v0.0.0-20191016111102-bec269661e48
3030
k8s.io/klog v1.0.0
31+
k8s.io/kubectl v0.0.0-20191016120415-2ed914427d51
3132
)
3233

3334
replace github.com/docker/docker => github.com/moby/moby v0.7.3-0.20190826074503-38ab9da00309 // Required by Helm

go.sum

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbt
1616
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
1717
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
1818
github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E=
19+
github.com/MakeNowJust/heredoc v0.0.0-20171113091838-e9091a26100e h1:eb0Pzkt15Bm7f2FFYv7sjY7NPFi3cPkS3tv1CcrFBWA=
1920
github.com/MakeNowJust/heredoc v0.0.0-20171113091838-e9091a26100e/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E=
2021
github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
2122
github.com/Masterminds/semver/v3 v3.0.1 h1:2kKm5lb7dKVrt5TYUiAavE6oFc1cFT0057UVGT+JqLk=
@@ -126,6 +127,7 @@ github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDD
126127
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
127128
github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE=
128129
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
130+
github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c h1:ZfSZ3P3BedhKGUhzj7BQlPSU4OvT6tfOKe3DVHzOA7s=
129131
github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
130132
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
131133
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
@@ -140,6 +142,7 @@ github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT
140142
github.com/emicklei/go-restful v2.11.1+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
141143
github.com/evanphx/json-patch v4.2.0+incompatible h1:fUDGZCv/7iAN7u0puUVhvKCcsR6vRfwrJatElLBEf0I=
142144
github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
145+
github.com/evanphx/json-patch v4.5.0+incompatible h1:ouOWdg56aJriqS0huScTkVXPC5IcNrDCXZ6OoTAWu7M=
143146
github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
144147
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4=
145148
github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc=
@@ -370,11 +373,13 @@ github.com/miekg/dns v0.0.0-20181005163659-0d29b283ac0f/go.mod h1:W1PPwlIAgtquWB
370373
github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ=
371374
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
372375
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
376+
github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4=
373377
github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
374378
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
375379
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
376380
github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY=
377381
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
382+
github.com/moby/moby v0.7.3-0.20190826074503-38ab9da00309 h1:cvy4lBOYN3gKfKj8Lzz5Q9TfviP+L7koMHY7SvkyTKs=
378383
github.com/moby/moby v0.7.3-0.20190826074503-38ab9da00309/go.mod h1:fDXVQ6+S340veQPv35CzDahGBmHsiclFwfEygB/TWMc=
379384
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
380385
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
@@ -732,7 +737,9 @@ k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8=
732737
k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
733738
k8s.io/kube-openapi v0.0.0-20190816220812-743ec37842bf h1:EYm5AW/UUDbnmnI+gK0TJDVK9qPLhM+sRHYanNKw0EQ=
734739
k8s.io/kube-openapi v0.0.0-20190816220812-743ec37842bf/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E=
740+
k8s.io/kube-openapi v0.0.0-20190918143330-0270cf2f1c1d h1:Xpe6sK+RY4ZgCTyZ3y273UmFmURhjtoJiwOMbQsXitY=
735741
k8s.io/kube-openapi v0.0.0-20190918143330-0270cf2f1c1d/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E=
742+
k8s.io/kubectl v0.0.0-20191016120415-2ed914427d51 h1:RBkTKVMF+xsNsSOVc0+HdC0B5gD1sr6s6Cu5w9qNbuQ=
736743
k8s.io/kubectl v0.0.0-20191016120415-2ed914427d51/go.mod h1:gL826ZTIfD4vXTGlmzgTbliCAT9NGiqpCqK2aNYv5MQ=
737744
k8s.io/metrics v0.0.0-20191016113814-3b1a734dba6e/go.mod h1:ve7/vMWeY5lEBkZf6Bt5TTbGS3b8wAxwGbdXAsufjRs=
738745
k8s.io/utils v0.0.0-20190801114015-581e00157fb1 h1:+ySTxfHnfzZb9ys375PXNlLhkJPLKgHajBU0N62BDvE=

pkg/appregistry/appregistry.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,7 @@ func NewLoader(kubeconfig string, dbName string, downloadPath string, logger *lo
3838
input: &inputParser{
3939
sourceSpecifier: specifier,
4040
},
41-
downloader: &downloader{
42-
logger: logger,
43-
kubeClient: *kubeClient,
44-
},
41+
downloader: newDownloader(logger, kubeClient),
4542
downloadPath: downloadPath,
4643
decoder: decoder,
4744
loader: loader,

pkg/appregistry/downloader.go

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,39 @@ func (d *downloadItem) String() string {
2626
return fmt.Sprintf("%s", d.RepositoryMetadata)
2727
}
2828

29+
type registryOptionsGetter interface {
30+
GetRegistryOptions(source *Source) (*apprclient.Options, error)
31+
}
32+
33+
type secretRegistryOptionsGetter struct {
34+
kubeClient kubernetes.Interface
35+
}
36+
37+
type sourceQuerier interface {
38+
QuerySource(source *Source) ([]*apprclient.RegistryMetadata, error)
39+
}
40+
41+
type appRegistrySourceQuerier struct {
42+
kubeClient kubernetes.Interface
43+
regOptionGetter registryOptionsGetter
44+
}
45+
2946
type downloader struct {
30-
logger *logrus.Entry
31-
kubeClient kubernetes.Clientset
47+
logger *logrus.Entry
48+
kubeClient kubernetes.Interface
49+
querier sourceQuerier
50+
regOptionGetter registryOptionsGetter
51+
}
52+
53+
// NewDownloader returns a new instance of downloader
54+
func newDownloader(logger *logrus.Entry, kubeClient kubernetes.Interface) *downloader {
55+
regOptionGetter := &secretRegistryOptionsGetter{kubeClient}
56+
return &downloader{
57+
logger,
58+
kubeClient,
59+
&appRegistrySourceQuerier{kubeClient, regOptionGetter},
60+
regOptionGetter,
61+
}
3262
}
3363

3464
// Download downloads manifest(s) associated with the specified package(s) from
@@ -74,7 +104,7 @@ func (d *downloader) Prepare(input *Input) (items []*downloadItem, err error) {
74104
break
75105
}
76106

77-
repositoryList, err := d.QuerySource(source)
107+
repositoryList, err := d.querier.QuerySource(source)
78108
if err != nil {
79109
allErrors = append(allErrors, err)
80110
d.logger.Infof("skipping operator source due to error: %s", source)
@@ -126,7 +156,7 @@ func (d *downloader) DownloadRepositories(items []*downloadItem) (manifests []*a
126156

127157
d.logger.Infof("downloading repository: %s from %s", item.RepositoryMetadata, endpoint)
128158

129-
options, err := d.SetupRegistryOptions(item.Source)
159+
options, err := d.regOptionGetter.GetRegistryOptions(item.Source)
130160
if err != nil {
131161
allErrors = append(allErrors, err)
132162
d.logger.Infof("skipping repository: %s", item.RepositoryMetadata)
@@ -164,12 +194,12 @@ func (d *downloader) DownloadRepositories(items []*downloadItem) (manifests []*a
164194
// The function returns the spec ( associated with the OperatorSource object )
165195
// in the cluster and the list of repositories in remote registry associated
166196
// with it.
167-
func (d *downloader) QuerySource(source *Source) (repositories []*apprclient.RegistryMetadata, err error) {
197+
func (a *appRegistrySourceQuerier) QuerySource(source *Source) (repositories []*apprclient.RegistryMetadata, err error) {
168198
if source == nil {
169199
return nil, errors.New("specified source is <nil>")
170200
}
171201

172-
options, err := d.SetupRegistryOptions(source)
202+
options, err := a.regOptionGetter.GetRegistryOptions(source)
173203
if err != nil {
174204
return
175205
}
@@ -187,17 +217,17 @@ func (d *downloader) QuerySource(source *Source) (repositories []*apprclient.Reg
187217
return
188218
}
189219

190-
// SetupRegistryOptions generates an Options object based on the OperatorSource spec. It passes along
220+
// GetRegistryOptions generates an Options object based on the OperatorSource spec. It passes along
191221
// the opsrc endpoint and, if defined, retrieves the authorization token from the specified Secret
192222
// object.
193-
func (d *downloader) SetupRegistryOptions(source *Source) (*apprclient.Options, error) {
223+
func (s *secretRegistryOptionsGetter) GetRegistryOptions(source *Source) (*apprclient.Options, error) {
194224
if source == nil {
195225
return nil, errors.New("specified source is <nil>")
196226
}
197227

198228
token := ""
199229
if source.IsSecretSpecified() {
200-
secret, err := d.kubeClient.CoreV1().Secrets(source.Secret.Namespace).Get(source.Secret.Name, metav1.GetOptions{})
230+
secret, err := s.kubeClient.CoreV1().Secrets(source.Secret.Namespace).Get(source.Secret.Name, metav1.GetOptions{})
201231
if err != nil {
202232
return nil, err
203233
}

pkg/appregistry/downloader_test.go

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
package appregistry
2+
3+
import (
4+
"errors"
5+
"testing"
6+
7+
"github.com/operator-framework/operator-registry/pkg/apprclient"
8+
"github.com/sirupsen/logrus"
9+
"github.com/stretchr/testify/assert"
10+
utilerrors "k8s.io/apimachinery/pkg/util/errors"
11+
"k8s.io/client-go/kubernetes/fake"
12+
)
13+
14+
var testPrepare = []struct {
15+
input *Input
16+
sourceQuerier sourceQuerier
17+
expectedDownloadItems []*downloadItem
18+
expectedError utilerrors.Aggregate
19+
}{
20+
{
21+
input: &Input{
22+
Sources: []*Source{
23+
{
24+
Endpoint: "quay.io",
25+
RegistryNamespace: "",
26+
},
27+
},
28+
Packages: []string{
29+
"Kubevirt",
30+
"etcd",
31+
},
32+
},
33+
sourceQuerier: &fakeSourceQuerier{
34+
map[Source][]*apprclient.RegistryMetadata{
35+
Source{
36+
Endpoint: "quay.io",
37+
RegistryNamespace: "",
38+
}: {
39+
&apprclient.RegistryMetadata{Name: "Kubevirt"},
40+
},
41+
},
42+
map[Source]error{},
43+
},
44+
expectedDownloadItems: []*downloadItem{
45+
&downloadItem{
46+
&apprclient.RegistryMetadata{Name: "Kubevirt"},
47+
&Source{Endpoint: "quay.io", RegistryNamespace: ""},
48+
},
49+
},
50+
expectedError: nil,
51+
},
52+
{
53+
input: &Input{
54+
Sources: []*Source{
55+
{
56+
Endpoint: "quay.io",
57+
RegistryNamespace: "",
58+
},
59+
{
60+
Endpoint: "other-endpoint.io",
61+
RegistryNamespace: "",
62+
},
63+
},
64+
Packages: []string{
65+
"Kubevirt",
66+
"etcd",
67+
},
68+
},
69+
sourceQuerier: &fakeSourceQuerier{
70+
map[Source][]*apprclient.RegistryMetadata{
71+
Source{
72+
Endpoint: "quay.io",
73+
RegistryNamespace: "",
74+
}: {
75+
&apprclient.RegistryMetadata{Name: "Kubevirt"},
76+
},
77+
},
78+
map[Source]error{
79+
Source{
80+
Endpoint: "other-endpoint.io",
81+
RegistryNamespace: "",
82+
}: errors.New("Failed to fetch sources from other-endpoint.io"),
83+
},
84+
},
85+
expectedDownloadItems: []*downloadItem{
86+
&downloadItem{
87+
&apprclient.RegistryMetadata{Name: "Kubevirt"},
88+
&Source{Endpoint: "quay.io", RegistryNamespace: ""},
89+
},
90+
},
91+
expectedError: utilerrors.NewAggregate(
92+
[]error{
93+
errors.New("Failed to fetch sources from other-endpoint.io"),
94+
},
95+
),
96+
},
97+
}
98+
99+
type fakeSourceQuerier struct {
100+
mapping map[Source][]*apprclient.RegistryMetadata
101+
errMapping map[Source]error
102+
}
103+
104+
func (f *fakeSourceQuerier) QuerySource(source *Source) (repositories []*apprclient.RegistryMetadata, err error) {
105+
err, ok := f.errMapping[*source]
106+
if ok {
107+
return nil, err
108+
}
109+
return f.mapping[*source], nil
110+
}
111+
112+
func TestPrepare(t *testing.T) {
113+
logger := logrus.WithField("test", "prepare")
114+
clientset := fake.NewSimpleClientset()
115+
116+
for _, testItem := range testPrepare {
117+
d := downloader{
118+
logger,
119+
clientset,
120+
testItem.sourceQuerier,
121+
nil,
122+
}
123+
124+
downloadItems, err := d.Prepare(testItem.input)
125+
assert.Equal(t, testItem.expectedDownloadItems, downloadItems)
126+
if testItem.expectedError != nil {
127+
assert.Equal(t, testItem.expectedError, err)
128+
} else {
129+
assert.NoError(t, err)
130+
}
131+
}
132+
}

vendor/github.com/MakeNowJust/heredoc/heredoc.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/docker/spdystream/connection.go

Lines changed: 6 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/docker/spdystream/handlers.go

Lines changed: 1 addition & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/evanphx/json-patch/.travis.yml

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)