| /* |
| Copyright 2017 The Kubernetes Authors. |
| |
| 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. |
| */ |
| |
| // Generator for GCE compute wrapper code. You must regenerate the code after |
| // modifying this file: |
| // |
| // $ go run gen/main.go > gen.go |
| package main |
| |
| import ( |
| "bytes" |
| "flag" |
| "fmt" |
| "io" |
| "log" |
| "os" |
| "os/exec" |
| "text/template" |
| "time" |
| |
| "k8s.io/kubernetes/pkg/cloudprovider/providers/gce/cloud/meta" |
| ) |
| |
| const ( |
| gofmt = "gofmt" |
| packageRoot = "k8s.io/kubernetes/pkg/cloudprovider/providers/gce/cloud" |
| |
| // readOnly specifies that the given resource is read-only and should not |
| // have insert() or delete() methods generated for the wrapper. |
| readOnly = iota |
| ) |
| |
| var flags = struct { |
| gofmt bool |
| mode string |
| }{} |
| |
| func init() { |
| flag.BoolVar(&flags.gofmt, "gofmt", true, "run output through gofmt") |
| flag.StringVar(&flags.mode, "mode", "src", "content to generate: src, test, dummy") |
| } |
| |
| // gofmtContent runs "gofmt" on the given contents. |
| func gofmtContent(r io.Reader) string { |
| cmd := exec.Command(gofmt, "-s") |
| out := &bytes.Buffer{} |
| cmd.Stdin = r |
| cmd.Stdout = out |
| cmdErr := &bytes.Buffer{} |
| cmd.Stderr = cmdErr |
| |
| if err := cmd.Run(); err != nil { |
| fmt.Fprintf(os.Stderr, cmdErr.String()) |
| panic(err) |
| } |
| return out.String() |
| } |
| |
| // genHeader generate the header for the file. |
| func genHeader(wr io.Writer) { |
| const text = `/* |
| Copyright {{.Year}} The Kubernetes Authors. |
| |
| 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. |
| */ |
| |
| // This file was generated by "go run gen/main.go > gen.go". Do not edit |
| // directly. |
| |
| package cloud |
| |
| import ( |
| "context" |
| "fmt" |
| "net/http" |
| "sync" |
| |
| "google.golang.org/api/googleapi" |
| "k8s.io/klog" |
| |
| "{{.PackageRoot}}/filter" |
| "{{.PackageRoot}}/meta" |
| |
| ` |
| tmpl := template.Must(template.New("header").Parse(text)) |
| values := map[string]string{ |
| "Year": fmt.Sprintf("%v", time.Now().Year()), |
| "PackageRoot": packageRoot, |
| } |
| if err := tmpl.Execute(wr, values); err != nil { |
| panic(err) |
| } |
| |
| var hasGA, hasAlpha, hasBeta bool |
| for _, s := range meta.AllServices { |
| switch s.Version() { |
| case meta.VersionGA: |
| hasGA = true |
| case meta.VersionAlpha: |
| hasAlpha = true |
| case meta.VersionBeta: |
| hasBeta = true |
| } |
| } |
| if hasAlpha { |
| fmt.Fprintln(wr, ` alpha "google.golang.org/api/compute/v0.alpha"`) |
| } |
| if hasBeta { |
| fmt.Fprintln(wr, ` beta "google.golang.org/api/compute/v0.beta"`) |
| } |
| if hasGA { |
| fmt.Fprintln(wr, ` ga "google.golang.org/api/compute/v1"`) |
| } |
| fmt.Fprintf(wr, ")\n\n") |
| } |
| |
| // genStubs generates the interface and wrapper stubs. |
| func genStubs(wr io.Writer) { |
| const text = `// Cloud is an interface for the GCE compute API. |
| type Cloud interface { |
| {{- range .All}} |
| {{.WrapType}}() {{.WrapType}} |
| {{- end}} |
| } |
| |
| // NewGCE returns a GCE. |
| func NewGCE(s *Service) *GCE { |
| g := &GCE{ |
| {{- range .All}} |
| {{.Field}}: &{{.GCEWrapType}}{s}, |
| {{- end}} |
| } |
| return g |
| } |
| |
| // GCE implements Cloud. |
| var _ Cloud = (*GCE)(nil) |
| |
| // GCE is the golang adapter for the compute APIs. |
| type GCE struct { |
| {{- range .All}} |
| {{.Field}} *{{.GCEWrapType}} |
| {{- end}} |
| } |
| |
| {{range .All}} |
| // {{.WrapType}} returns the interface for the {{.Version}} {{.Service}}. |
| func (gce *GCE) {{.WrapType}}() {{.WrapType}} { |
| return gce.{{.Field}} |
| } |
| {{- end}} |
| |
| // NewMockGCE returns a new mock for GCE. |
| func NewMockGCE(projectRouter ProjectRouter) *MockGCE { |
| {{- range .Groups}} |
| mock{{.Service}}Objs := map[meta.Key]*Mock{{.Service}}Obj{} |
| {{- end}} |
| |
| mock := &MockGCE{ |
| {{- range .All}} |
| {{.MockField}}: New{{.MockWrapType}}(projectRouter, mock{{.Service}}Objs), |
| {{- end}} |
| } |
| return mock |
| } |
| |
| // MockGCE implements Cloud. |
| var _ Cloud = (*MockGCE)(nil) |
| |
| // MockGCE is the mock for the compute API. |
| type MockGCE struct { |
| {{- range .All}} |
| {{.MockField}} *{{.MockWrapType}} |
| {{- end}} |
| } |
| {{range .All}} |
| // {{.WrapType}} returns the interface for the {{.Version}} {{.Service}}. |
| func (mock *MockGCE) {{.WrapType}}() {{.WrapType}} { |
| return mock.{{.MockField}} |
| } |
| {{end}} |
| |
| {{range .Groups}} |
| // Mock{{.Service}}Obj is used to store the various object versions in the shared |
| // map of mocked objects. This allows for multiple API versions to co-exist and |
| // share the same "view" of the objects in the backend. |
| type Mock{{.Service}}Obj struct { |
| Obj interface{} |
| } |
| {{- if .HasAlpha}} |
| // ToAlpha retrieves the given version of the object. |
| func (m *Mock{{.Service}}Obj) ToAlpha() *{{.Alpha.FQObjectType}} { |
| if ret, ok := m.Obj.(*{{.Alpha.FQObjectType}}); ok { |
| return ret |
| } |
| // Convert the object via JSON copying to the type that was requested. |
| ret := &{{.Alpha.FQObjectType}}{} |
| if err := copyViaJSON(ret, m.Obj); err != nil { |
| klog.Errorf("Could not convert %T to *{{.Alpha.FQObjectType}} via JSON: %v", m.Obj, err) |
| } |
| return ret |
| } |
| {{- end}} |
| {{- if .HasBeta}} |
| // ToBeta retrieves the given version of the object. |
| func (m *Mock{{.Service}}Obj) ToBeta() *{{.Beta.FQObjectType}} { |
| if ret, ok := m.Obj.(*{{.Beta.FQObjectType}}); ok { |
| return ret |
| } |
| // Convert the object via JSON copying to the type that was requested. |
| ret := &{{.Beta.FQObjectType}}{} |
| if err := copyViaJSON(ret, m.Obj); err != nil { |
| klog.Errorf("Could not convert %T to *{{.Beta.FQObjectType}} via JSON: %v", m.Obj, err) |
| } |
| return ret |
| } |
| {{- end}} |
| {{- if .HasGA}} |
| // ToGA retrieves the given version of the object. |
| func (m *Mock{{.Service}}Obj) ToGA() *{{.GA.FQObjectType}} { |
| if ret, ok := m.Obj.(*{{.GA.FQObjectType}}); ok { |
| return ret |
| } |
| // Convert the object via JSON copying to the type that was requested. |
| ret := &{{.GA.FQObjectType}}{} |
| if err := copyViaJSON(ret, m.Obj); err != nil { |
| klog.Errorf("Could not convert %T to *{{.GA.FQObjectType}} via JSON: %v", m.Obj, err) |
| } |
| return ret |
| } |
| {{- end}} |
| {{- end}} |
| ` |
| data := struct { |
| All []*meta.ServiceInfo |
| Groups map[string]*meta.ServiceGroup |
| }{meta.AllServices, meta.AllServicesByGroup} |
| |
| tmpl := template.Must(template.New("interface").Parse(text)) |
| if err := tmpl.Execute(wr, data); err != nil { |
| panic(err) |
| } |
| } |
| |
| // genTypes generates the type wrappers. |
| func genTypes(wr io.Writer) { |
| const text = `// {{.WrapType}} is an interface that allows for mocking of {{.Service}}. |
| type {{.WrapType}} interface { |
| {{- if .GenerateCustomOps}} |
| // {{.WrapTypeOps}} is an interface with additional non-CRUD type methods. |
| // This interface is expected to be implemented by hand (non-autogenerated). |
| {{.WrapTypeOps}} |
| {{- end}} |
| {{- if .GenerateGet}} |
| Get(ctx context.Context, key *meta.Key) (*{{.FQObjectType}}, error) |
| {{- end -}} |
| {{- if .GenerateList}} |
| {{- if .KeyIsGlobal}} |
| List(ctx context.Context, fl *filter.F) ([]*{{.FQObjectType}}, error) |
| {{- end -}} |
| {{- if .KeyIsRegional}} |
| List(ctx context.Context, region string, fl *filter.F) ([]*{{.FQObjectType}}, error) |
| {{- end -}} |
| {{- if .KeyIsZonal}} |
| List(ctx context.Context, zone string, fl *filter.F) ([]*{{.FQObjectType}}, error) |
| {{- end -}} |
| {{- end -}} |
| {{- if .GenerateInsert}} |
| Insert(ctx context.Context, key *meta.Key, obj *{{.FQObjectType}}) error |
| {{- end -}} |
| {{- if .GenerateDelete}} |
| Delete(ctx context.Context, key *meta.Key) error |
| {{- end -}} |
| {{- if .AggregatedList}} |
| AggregatedList(ctx context.Context, fl *filter.F) (map[string][]*{{.FQObjectType}}, error) |
| {{- end}} |
| {{- with .Methods -}} |
| {{- range .}} |
| {{.InterfaceFunc}} |
| {{- end -}} |
| {{- end}} |
| } |
| |
| // New{{.MockWrapType}} returns a new mock for {{.Service}}. |
| func New{{.MockWrapType}}(pr ProjectRouter, objs map[meta.Key]*Mock{{.Service}}Obj) *{{.MockWrapType}} { |
| mock := &{{.MockWrapType}}{ |
| ProjectRouter: pr, |
| |
| Objects: objs, |
| {{- if .GenerateGet}} |
| GetError: map[meta.Key]error{}, |
| {{- end -}} |
| {{- if .GenerateInsert}} |
| InsertError: map[meta.Key]error{}, |
| {{- end -}} |
| {{- if .GenerateDelete}} |
| DeleteError: map[meta.Key]error{}, |
| {{- end}} |
| } |
| return mock |
| } |
| |
| // {{.MockWrapType}} is the mock for {{.Service}}. |
| type {{.MockWrapType}} struct { |
| Lock sync.Mutex |
| |
| ProjectRouter ProjectRouter |
| |
| // Objects maintained by the mock. |
| Objects map[meta.Key]*Mock{{.Service}}Obj |
| |
| // If an entry exists for the given key and operation, then the error |
| // will be returned instead of the operation. |
| {{- if .GenerateGet}} |
| GetError map[meta.Key]error |
| {{- end -}} |
| {{- if .GenerateList}} |
| ListError *error |
| {{- end -}} |
| {{- if .GenerateInsert}} |
| InsertError map[meta.Key]error |
| {{- end -}} |
| {{- if .GenerateDelete}} |
| DeleteError map[meta.Key]error |
| {{- end -}} |
| {{- if .AggregatedList}} |
| AggregatedListError *error |
| {{- end}} |
| |
| // xxxHook allow you to intercept the standard processing of the mock in |
| // order to add your own logic. Return (true, _, _) to prevent the normal |
| // execution flow of the mock. Return (false, nil, nil) to continue with |
| // normal mock behavior/ after the hook function executes. |
| {{- if .GenerateGet}} |
| GetHook func(ctx context.Context, key *meta.Key, m *{{.MockWrapType}}) (bool, *{{.FQObjectType}}, error) |
| {{- end -}} |
| {{- if .GenerateList}} |
| {{- if .KeyIsGlobal}} |
| ListHook func(ctx context.Context, fl *filter.F, m *{{.MockWrapType}}) (bool, []*{{.FQObjectType}}, error) |
| {{- end -}} |
| {{- if .KeyIsRegional}} |
| ListHook func(ctx context.Context, region string, fl *filter.F, m *{{.MockWrapType}}) (bool, []*{{.FQObjectType}}, error) |
| {{- end -}} |
| {{- if .KeyIsZonal}} |
| ListHook func(ctx context.Context, zone string, fl *filter.F, m *{{.MockWrapType}}) (bool, []*{{.FQObjectType}}, error) |
| {{- end}} |
| {{- end -}} |
| {{- if .GenerateInsert}} |
| InsertHook func(ctx context.Context, key *meta.Key, obj *{{.FQObjectType}}, m *{{.MockWrapType}}) (bool, error) |
| {{- end -}} |
| {{- if .GenerateDelete}} |
| DeleteHook func(ctx context.Context, key *meta.Key, m *{{.MockWrapType}}) (bool, error) |
| {{- end -}} |
| {{- if .AggregatedList}} |
| AggregatedListHook func(ctx context.Context, fl *filter.F, m *{{.MockWrapType}}) (bool, map[string][]*{{.FQObjectType}}, error) |
| {{- end}} |
| |
| {{- with .Methods -}} |
| {{- range .}} |
| {{.MockHook}} |
| {{- end -}} |
| {{- end}} |
| |
| // X is extra state that can be used as part of the mock. Generated code |
| // will not use this field. |
| X interface{} |
| } |
| |
| {{- if .GenerateGet}} |
| // Get returns the object from the mock. |
| func (m *{{.MockWrapType}}) Get(ctx context.Context, key *meta.Key) (*{{.FQObjectType}}, error) { |
| if m.GetHook != nil { |
| if intercept, obj, err := m.GetHook(ctx, key, m); intercept { |
| klog.V(5).Infof("{{.MockWrapType}}.Get(%v, %s) = %+v, %v", ctx, key, obj ,err) |
| return obj, err |
| } |
| } |
| if !key.Valid() { |
| return nil, fmt.Errorf("invalid GCE key (%+v)", key) |
| } |
| |
| m.Lock.Lock() |
| defer m.Lock.Unlock() |
| |
| if err, ok := m.GetError[*key]; ok { |
| klog.V(5).Infof("{{.MockWrapType}}.Get(%v, %s) = nil, %v", ctx, key, err) |
| return nil, err |
| } |
| if obj, ok := m.Objects[*key]; ok { |
| typedObj := obj.To{{.VersionTitle}}() |
| klog.V(5).Infof("{{.MockWrapType}}.Get(%v, %s) = %+v, nil", ctx, key, typedObj) |
| return typedObj, nil |
| } |
| |
| err := &googleapi.Error{ |
| Code: http.StatusNotFound, |
| Message: fmt.Sprintf("{{.MockWrapType}} %v not found", key), |
| } |
| klog.V(5).Infof("{{.MockWrapType}}.Get(%v, %s) = nil, %v", ctx, key, err) |
| return nil, err |
| } |
| {{- end}} |
| |
| {{- if .GenerateList}} |
| {{if .KeyIsGlobal -}} |
| // List all of the objects in the mock. |
| func (m *{{.MockWrapType}}) List(ctx context.Context, fl *filter.F) ([]*{{.FQObjectType}}, error) { |
| {{- end -}} |
| {{- if .KeyIsRegional -}} |
| // List all of the objects in the mock in the given region. |
| func (m *{{.MockWrapType}}) List(ctx context.Context, region string, fl *filter.F) ([]*{{.FQObjectType}}, error) { |
| {{- end -}} |
| {{- if .KeyIsZonal -}} |
| // List all of the objects in the mock in the given zone. |
| func (m *{{.MockWrapType}}) List(ctx context.Context, zone string, fl *filter.F) ([]*{{.FQObjectType}}, error) { |
| {{- end}} |
| if m.ListHook != nil { |
| {{if .KeyIsGlobal -}} |
| if intercept, objs, err := m.ListHook(ctx, fl, m); intercept { |
| klog.V(5).Infof("{{.MockWrapType}}.List(%v, %v) = [%v items], %v", ctx, fl, len(objs), err) |
| {{- end -}} |
| {{- if .KeyIsRegional -}} |
| if intercept, objs, err := m.ListHook(ctx, region, fl, m); intercept { |
| klog.V(5).Infof("{{.MockWrapType}}.List(%v, %q, %v) = [%v items], %v", ctx, region, fl, len(objs), err) |
| {{- end -}} |
| {{- if .KeyIsZonal -}} |
| if intercept, objs, err := m.ListHook(ctx, zone, fl, m); intercept { |
| klog.V(5).Infof("{{.MockWrapType}}.List(%v, %q, %v) = [%v items], %v", ctx, zone, fl, len(objs), err) |
| {{- end}} |
| return objs, err |
| } |
| } |
| |
| m.Lock.Lock() |
| defer m.Lock.Unlock() |
| |
| if m.ListError != nil { |
| err := *m.ListError |
| {{if .KeyIsGlobal -}} |
| klog.V(5).Infof("{{.MockWrapType}}.List(%v, %v) = nil, %v", ctx, fl, err) |
| {{- end -}} |
| {{- if .KeyIsRegional -}} |
| klog.V(5).Infof("{{.MockWrapType}}.List(%v, %q, %v) = nil, %v", ctx, region, fl, err) |
| {{- end -}} |
| {{- if .KeyIsZonal -}} |
| klog.V(5).Infof("{{.MockWrapType}}.List(%v, %q, %v) = nil, %v", ctx, zone, fl, err) |
| {{- end}} |
| |
| return nil, *m.ListError |
| } |
| |
| var objs []*{{.FQObjectType}} |
| {{- if .KeyIsGlobal}} |
| for _, obj := range m.Objects { |
| {{- else}} |
| for key, obj := range m.Objects { |
| {{- end -}} |
| {{- if .KeyIsRegional}} |
| if key.Region != region { |
| continue |
| } |
| {{- end -}} |
| {{- if .KeyIsZonal}} |
| if key.Zone != zone { |
| continue |
| } |
| {{- end}} |
| if !fl.Match(obj.To{{.VersionTitle}}()) { |
| continue |
| } |
| objs = append(objs, obj.To{{.VersionTitle}}()) |
| } |
| |
| {{if .KeyIsGlobal -}} |
| klog.V(5).Infof("{{.MockWrapType}}.List(%v, %v) = [%v items], nil", ctx, fl, len(objs)) |
| {{- end -}} |
| {{- if .KeyIsRegional -}} |
| klog.V(5).Infof("{{.MockWrapType}}.List(%v, %q, %v) = [%v items], nil", ctx, region, fl, len(objs)) |
| {{- end -}} |
| {{- if .KeyIsZonal -}} |
| klog.V(5).Infof("{{.MockWrapType}}.List(%v, %q, %v) = [%v items], nil", ctx, zone, fl, len(objs)) |
| {{- end}} |
| return objs, nil |
| } |
| {{- end}} |
| |
| {{- if .GenerateInsert}} |
| // Insert is a mock for inserting/creating a new object. |
| func (m *{{.MockWrapType}}) Insert(ctx context.Context, key *meta.Key, obj *{{.FQObjectType}}) error { |
| if m.InsertHook != nil { |
| if intercept, err := m.InsertHook(ctx, key, obj, m); intercept { |
| klog.V(5).Infof("{{.MockWrapType}}.Insert(%v, %v, %+v) = %v", ctx, key, obj, err) |
| return err |
| } |
| } |
| if !key.Valid() { |
| return fmt.Errorf("invalid GCE key (%+v)", key) |
| } |
| |
| m.Lock.Lock() |
| defer m.Lock.Unlock() |
| |
| if err, ok := m.InsertError[*key]; ok { |
| klog.V(5).Infof("{{.MockWrapType}}.Insert(%v, %v, %+v) = %v", ctx, key, obj, err) |
| return err |
| } |
| if _, ok := m.Objects[*key]; ok { |
| err := &googleapi.Error{ |
| Code: http.StatusConflict, |
| Message: fmt.Sprintf("{{.MockWrapType}} %v exists", key), |
| } |
| klog.V(5).Infof("{{.MockWrapType}}.Insert(%v, %v, %+v) = %v", ctx, key, obj, err) |
| return err |
| } |
| |
| obj.Name = key.Name |
| projectID := m.ProjectRouter.ProjectID(ctx, "{{.Version}}", "{{.Resource}}") |
| obj.SelfLink = SelfLink(meta.Version{{.VersionTitle}}, projectID, "{{.Resource}}", key) |
| |
| m.Objects[*key] = &Mock{{.Service}}Obj{obj} |
| klog.V(5).Infof("{{.MockWrapType}}.Insert(%v, %v, %+v) = nil", ctx, key, obj) |
| return nil |
| } |
| {{- end}} |
| |
| {{- if .GenerateDelete}} |
| // Delete is a mock for deleting the object. |
| func (m *{{.MockWrapType}}) Delete(ctx context.Context, key *meta.Key) error { |
| if m.DeleteHook != nil { |
| if intercept, err := m.DeleteHook(ctx, key, m); intercept { |
| klog.V(5).Infof("{{.MockWrapType}}.Delete(%v, %v) = %v", ctx, key, err) |
| return err |
| } |
| } |
| if !key.Valid() { |
| return fmt.Errorf("invalid GCE key (%+v)", key) |
| } |
| |
| m.Lock.Lock() |
| defer m.Lock.Unlock() |
| |
| if err, ok := m.DeleteError[*key]; ok { |
| klog.V(5).Infof("{{.MockWrapType}}.Delete(%v, %v) = %v", ctx, key, err) |
| return err |
| } |
| if _, ok := m.Objects[*key]; !ok { |
| err := &googleapi.Error{ |
| Code: http.StatusNotFound, |
| Message: fmt.Sprintf("{{.MockWrapType}} %v not found", key), |
| } |
| klog.V(5).Infof("{{.MockWrapType}}.Delete(%v, %v) = %v", ctx, key, err) |
| return err |
| } |
| |
| delete(m.Objects, *key) |
| klog.V(5).Infof("{{.MockWrapType}}.Delete(%v, %v) = nil", ctx, key) |
| return nil |
| } |
| {{- end}} |
| |
| {{- if .AggregatedList}} |
| // AggregatedList is a mock for AggregatedList. |
| func (m *{{.MockWrapType}}) AggregatedList(ctx context.Context, fl *filter.F) (map[string][]*{{.FQObjectType}}, error) { |
| if m.AggregatedListHook != nil { |
| if intercept, objs, err := m.AggregatedListHook(ctx, fl, m); intercept { |
| klog.V(5).Infof("{{.MockWrapType}}.AggregatedList(%v, %v) = [%v items], %v", ctx, fl, len(objs), err) |
| return objs, err |
| } |
| } |
| |
| m.Lock.Lock() |
| defer m.Lock.Unlock() |
| |
| if m.AggregatedListError != nil { |
| err := *m.AggregatedListError |
| klog.V(5).Infof("{{.MockWrapType}}.AggregatedList(%v, %v) = nil, %v", ctx, fl, err) |
| return nil, err |
| } |
| |
| objs := map[string][]*{{.FQObjectType}}{} |
| for _, obj := range m.Objects { |
| res, err := ParseResourceURL(obj.To{{.VersionTitle}}().SelfLink) |
| {{- if .KeyIsRegional}} |
| location := res.Key.Region |
| {{- end -}} |
| {{- if .KeyIsZonal}} |
| location := res.Key.Zone |
| {{- end}} |
| if err != nil { |
| klog.V(5).Infof("{{.MockWrapType}}.AggregatedList(%v, %v) = nil, %v", ctx, fl, err) |
| return nil, err |
| } |
| if !fl.Match(obj.To{{.VersionTitle}}()) { |
| continue |
| } |
| objs[location] = append(objs[location], obj.To{{.VersionTitle}}()) |
| } |
| klog.V(5).Infof("{{.MockWrapType}}.AggregatedList(%v, %v) = [%v items], nil", ctx, fl, len(objs)) |
| return objs, nil |
| } |
| {{- end}} |
| |
| // Obj wraps the object for use in the mock. |
| func (m *{{.MockWrapType}}) Obj(o *{{.FQObjectType}}) *Mock{{.Service}}Obj { |
| return &Mock{{.Service}}Obj{o} |
| } |
| |
| {{with .Methods -}} |
| {{- range .}} |
| // {{.Name}} is a mock for the corresponding method. |
| func (m *{{.MockWrapType}}) {{.FcnArgs}} { |
| {{- if .IsOperation }} |
| if m.{{.MockHookName}} != nil { |
| return m.{{.MockHookName}}(ctx, key {{.CallArgs}}, m) |
| } |
| return nil |
| {{- else if .IsGet}} |
| if m.{{.MockHookName}} != nil { |
| return m.{{.MockHookName}}(ctx, key {{.CallArgs}}, m) |
| } |
| return nil, fmt.Errorf("{{.MockHookName}} must be set") |
| {{- else if .IsPaged}} |
| if m.{{.MockHookName}} != nil { |
| return m.{{.MockHookName}}(ctx, key {{.CallArgs}}, fl, m) |
| } |
| return nil, nil |
| {{- end}} |
| } |
| {{end -}} |
| {{- end}} |
| // {{.GCEWrapType}} is a simplifying adapter for the GCE {{.Service}}. |
| type {{.GCEWrapType}} struct { |
| s *Service |
| } |
| |
| {{- if .GenerateGet}} |
| // Get the {{.Object}} named by key. |
| func (g *{{.GCEWrapType}}) Get(ctx context.Context, key *meta.Key) (*{{.FQObjectType}}, error) { |
| klog.V(5).Infof("{{.GCEWrapType}}.Get(%v, %v): called", ctx, key) |
| |
| if !key.Valid() { |
| klog.V(2).Infof("{{.GCEWrapType}}.Get(%v, %v): key is invalid (%#v)", ctx, key, key) |
| return nil, fmt.Errorf("invalid GCE key (%#v)", key) |
| } |
| projectID := g.s.ProjectRouter.ProjectID(ctx, "{{.Version}}", "{{.Service}}") |
| rk := &RateLimitKey{ |
| ProjectID: projectID, |
| Operation: "Get", |
| Version: meta.Version("{{.Version}}"), |
| Service: "{{.Service}}", |
| } |
| klog.V(5).Infof("{{.GCEWrapType}}.Get(%v, %v): projectID = %v, rk = %+v", ctx, key, projectID, rk) |
| if err := g.s.RateLimiter.Accept(ctx, rk); err != nil { |
| klog.V(4).Infof("{{.GCEWrapType}}.Get(%v, %v): RateLimiter error: %v", ctx, key, err) |
| return nil, err |
| } |
| {{- if .KeyIsGlobal}} |
| call := g.s.{{.VersionTitle}}.{{.Service}}.Get(projectID, key.Name) |
| {{- end -}} |
| {{- if .KeyIsRegional}} |
| call := g.s.{{.VersionTitle}}.{{.Service}}.Get(projectID, key.Region, key.Name) |
| {{- end -}} |
| {{- if .KeyIsZonal}} |
| call := g.s.{{.VersionTitle}}.{{.Service}}.Get(projectID, key.Zone, key.Name) |
| {{- end}} |
| call.Context(ctx) |
| v, err := call.Do() |
| klog.V(4).Infof("{{.GCEWrapType}}.Get(%v, %v) = %+v, %v", ctx, key, v, err) |
| return v, err |
| } |
| {{- end}} |
| |
| {{- if .GenerateList}} |
| // List all {{.Object}} objects. |
| {{- if .KeyIsGlobal}} |
| func (g *{{.GCEWrapType}}) List(ctx context.Context, fl *filter.F) ([]*{{.FQObjectType}}, error) { |
| klog.V(5).Infof("{{.GCEWrapType}}.List(%v, %v) called", ctx, fl) |
| {{- end -}} |
| {{- if .KeyIsRegional}} |
| func (g *{{.GCEWrapType}}) List(ctx context.Context, region string, fl *filter.F) ([]*{{.FQObjectType}}, error) { |
| klog.V(5).Infof("{{.GCEWrapType}}.List(%v, %v, %v) called", ctx, region, fl) |
| {{- end -}} |
| {{- if .KeyIsZonal}} |
| func (g *{{.GCEWrapType}}) List(ctx context.Context, zone string, fl *filter.F) ([]*{{.FQObjectType}}, error) { |
| klog.V(5).Infof("{{.GCEWrapType}}.List(%v, %v, %v) called", ctx, zone, fl) |
| {{- end}} |
| projectID := g.s.ProjectRouter.ProjectID(ctx, "{{.Version}}", "{{.Service}}") |
| rk := &RateLimitKey{ |
| ProjectID: projectID, |
| Operation: "List", |
| Version: meta.Version("{{.Version}}"), |
| Service: "{{.Service}}", |
| } |
| if err := g.s.RateLimiter.Accept(ctx, rk); err != nil { |
| return nil, err |
| } |
| {{- if .KeyIsGlobal}} |
| klog.V(5).Infof("{{.GCEWrapType}}.List(%v, %v): projectID = %v, rk = %+v", ctx, fl, projectID, rk) |
| call := g.s.{{.VersionTitle}}.{{.Service}}.List(projectID) |
| {{- end -}} |
| {{- if .KeyIsRegional}} |
| klog.V(5).Infof("{{.GCEWrapType}}.List(%v, %v, %v): projectID = %v, rk = %+v", ctx, region, fl, projectID, rk) |
| call := g.s.{{.VersionTitle}}.{{.Service}}.List(projectID, region) |
| {{- end -}} |
| {{- if .KeyIsZonal}} |
| klog.V(5).Infof("{{.GCEWrapType}}.List(%v, %v, %v): projectID = %v, rk = %+v", ctx, zone, fl, projectID, rk) |
| call := g.s.{{.VersionTitle}}.{{.Service}}.List(projectID, zone) |
| {{- end}} |
| if fl != filter.None { |
| call.Filter(fl.String()) |
| } |
| var all []*{{.FQObjectType}} |
| f := func(l *{{.ObjectListType}}) error { |
| klog.V(5).Infof("{{.GCEWrapType}}.List(%v, ..., %v): page %+v", ctx, fl, l) |
| all = append(all, l.Items...) |
| return nil |
| } |
| if err := call.Pages(ctx, f); err != nil { |
| klog.V(4).Infof("{{.GCEWrapType}}.List(%v, ..., %v) = %v, %v", ctx, fl, nil, err) |
| return nil, err |
| } |
| |
| if klog.V(4) { |
| klog.V(4).Infof("{{.GCEWrapType}}.List(%v, ..., %v) = [%v items], %v", ctx, fl, len(all), nil) |
| } else if klog.V(5) { |
| var asStr []string |
| for _, o := range all { |
| asStr = append(asStr, fmt.Sprintf("%+v", o)) |
| } |
| klog.V(5).Infof("{{.GCEWrapType}}.List(%v, ..., %v) = %v, %v", ctx, fl, asStr, nil) |
| } |
| |
| return all, nil |
| } |
| {{- end}} |
| |
| {{- if .GenerateInsert}} |
| // Insert {{.Object}} with key of value obj. |
| func (g *{{.GCEWrapType}}) Insert(ctx context.Context, key *meta.Key, obj *{{.FQObjectType}}) error { |
| klog.V(5).Infof("{{.GCEWrapType}}.Insert(%v, %v, %+v): called", ctx, key, obj) |
| if !key.Valid() { |
| klog.V(2).Infof("{{.GCEWrapType}}.Insert(%v, %v, ...): key is invalid (%#v)", ctx, key, key) |
| return fmt.Errorf("invalid GCE key (%+v)", key) |
| } |
| projectID := g.s.ProjectRouter.ProjectID(ctx, "{{.Version}}", "{{.Service}}") |
| rk := &RateLimitKey{ |
| ProjectID: projectID, |
| Operation: "Insert", |
| Version: meta.Version("{{.Version}}"), |
| Service: "{{.Service}}", |
| } |
| klog.V(5).Infof("{{.GCEWrapType}}.Insert(%v, %v, ...): projectID = %v, rk = %+v", ctx, key, projectID, rk) |
| if err := g.s.RateLimiter.Accept(ctx, rk); err != nil { |
| klog.V(4).Infof("{{.GCEWrapType}}.Insert(%v, %v, ...): RateLimiter error: %v", ctx, key, err) |
| return err |
| } |
| obj.Name = key.Name |
| {{- if .KeyIsGlobal}} |
| call := g.s.{{.VersionTitle}}.{{.Service}}.Insert(projectID, obj) |
| {{- end -}} |
| {{- if .KeyIsRegional}} |
| call := g.s.{{.VersionTitle}}.{{.Service}}.Insert(projectID, key.Region, obj) |
| {{- end -}} |
| {{- if .KeyIsZonal}} |
| call := g.s.{{.VersionTitle}}.{{.Service}}.Insert(projectID, key.Zone, obj) |
| {{- end}} |
| call.Context(ctx) |
| |
| op, err := call.Do() |
| if err != nil { |
| klog.V(4).Infof("{{.GCEWrapType}}.Insert(%v, %v, ...) = %+v", ctx, key, err) |
| return err |
| } |
| |
| err = g.s.WaitForCompletion(ctx, op) |
| klog.V(4).Infof("{{.GCEWrapType}}.Insert(%v, %v, %+v) = %+v", ctx, key, obj, err) |
| return err |
| } |
| {{- end}} |
| |
| {{- if .GenerateDelete}} |
| // Delete the {{.Object}} referenced by key. |
| func (g *{{.GCEWrapType}}) Delete(ctx context.Context, key *meta.Key) error { |
| klog.V(5).Infof("{{.GCEWrapType}}.Delete(%v, %v): called", ctx, key) |
| if !key.Valid() { |
| klog.V(2).Infof("{{.GCEWrapType}}.Delete(%v, %v): key is invalid (%#v)", ctx, key, key) |
| return fmt.Errorf("invalid GCE key (%+v)", key) |
| } |
| projectID := g.s.ProjectRouter.ProjectID(ctx, "{{.Version}}", "{{.Service}}") |
| rk := &RateLimitKey{ |
| ProjectID: projectID, |
| Operation: "Delete", |
| Version: meta.Version("{{.Version}}"), |
| Service: "{{.Service}}", |
| } |
| klog.V(5).Infof("{{.GCEWrapType}}.Delete(%v, %v): projectID = %v, rk = %+v", ctx, key, projectID, rk) |
| if err := g.s.RateLimiter.Accept(ctx, rk); err != nil { |
| klog.V(4).Infof("{{.GCEWrapType}}.Delete(%v, %v): RateLimiter error: %v", ctx, key, err) |
| return err |
| } |
| {{- if .KeyIsGlobal}} |
| call := g.s.{{.VersionTitle}}.{{.Service}}.Delete(projectID, key.Name) |
| {{end -}} |
| {{- if .KeyIsRegional}} |
| call := g.s.{{.VersionTitle}}.{{.Service}}.Delete(projectID, key.Region, key.Name) |
| {{- end -}} |
| {{- if .KeyIsZonal}} |
| call := g.s.{{.VersionTitle}}.{{.Service}}.Delete(projectID, key.Zone, key.Name) |
| {{- end}} |
| call.Context(ctx) |
| |
| op, err := call.Do() |
| if err != nil { |
| klog.V(4).Infof("{{.GCEWrapType}}.Delete(%v, %v) = %v", ctx, key, err) |
| return err |
| } |
| |
| err = g.s.WaitForCompletion(ctx, op) |
| klog.V(4).Infof("{{.GCEWrapType}}.Delete(%v, %v) = %v", ctx, key, err) |
| return err |
| } |
| {{end -}} |
| |
| {{- if .AggregatedList}} |
| // AggregatedList lists all resources of the given type across all locations. |
| func (g *{{.GCEWrapType}}) AggregatedList(ctx context.Context, fl *filter.F) (map[string][]*{{.FQObjectType}}, error) { |
| klog.V(5).Infof("{{.GCEWrapType}}.AggregatedList(%v, %v) called", ctx, fl) |
| |
| projectID := g.s.ProjectRouter.ProjectID(ctx, "{{.Version}}", "{{.Service}}") |
| rk := &RateLimitKey{ |
| ProjectID: projectID, |
| Operation: "AggregatedList", |
| Version: meta.Version("{{.Version}}"), |
| Service: "{{.Service}}", |
| } |
| |
| klog.V(5).Infof("{{.GCEWrapType}}.AggregatedList(%v, %v): projectID = %v, rk = %+v", ctx, fl, projectID, rk) |
| if err := g.s.RateLimiter.Accept(ctx, rk); err != nil { |
| klog.V(5).Infof("{{.GCEWrapType}}.AggregatedList(%v, %v): RateLimiter error: %v", ctx, fl, err) |
| return nil, err |
| } |
| |
| call := g.s.{{.VersionTitle}}.{{.Service}}.AggregatedList(projectID) |
| call.Context(ctx) |
| if fl != filter.None { |
| call.Filter(fl.String()) |
| } |
| |
| all := map[string][]*{{.FQObjectType}}{} |
| f := func(l *{{.ObjectAggregatedListType}}) error { |
| for k, v := range l.Items { |
| klog.V(5).Infof("{{.GCEWrapType}}.AggregatedList(%v, %v): page[%v]%+v", ctx, fl, k, v) |
| all[k] = append(all[k], v.{{.AggregatedListField}}...) |
| } |
| return nil |
| } |
| if err := call.Pages(ctx, f); err != nil { |
| klog.V(4).Infof("{{.GCEWrapType}}.AggregatedList(%v, %v) = %v, %v", ctx, fl, nil, err) |
| return nil, err |
| } |
| if klog.V(4) { |
| klog.V(4).Infof("{{.GCEWrapType}}.AggregatedList(%v, %v) = [%v items], %v", ctx, fl, len(all), nil) |
| } else if klog.V(5) { |
| var asStr []string |
| for _, o := range all { |
| asStr = append(asStr, fmt.Sprintf("%+v", o)) |
| } |
| klog.V(5).Infof("{{.GCEWrapType}}.AggregatedList(%v, %v) = %v, %v", ctx, fl, asStr, nil) |
| } |
| return all, nil |
| } |
| {{- end}} |
| |
| {{- with .Methods -}} |
| {{- range .}} |
| // {{.Name}} is a method on {{.GCEWrapType}}. |
| func (g *{{.GCEWrapType}}) {{.FcnArgs}} { |
| klog.V(5).Infof("{{.GCEWrapType}}.{{.Name}}(%v, %v, ...): called", ctx, key) |
| |
| if !key.Valid() { |
| klog.V(2).Infof("{{.GCEWrapType}}.{{.Name}}(%v, %v, ...): key is invalid (%#v)", ctx, key, key) |
| {{- if .IsOperation}} |
| return fmt.Errorf("invalid GCE key (%+v)", key) |
| {{- else if .IsGet}} |
| return nil, fmt.Errorf("invalid GCE key (%+v)", key) |
| {{- else if .IsPaged}} |
| return nil, fmt.Errorf("invalid GCE key (%+v)", key) |
| {{- end}} |
| } |
| projectID := g.s.ProjectRouter.ProjectID(ctx, "{{.Version}}", "{{.Service}}") |
| rk := &RateLimitKey{ |
| ProjectID: projectID, |
| Operation: "{{.Name}}", |
| Version: meta.Version("{{.Version}}"), |
| Service: "{{.Service}}", |
| } |
| klog.V(5).Infof("{{.GCEWrapType}}.{{.Name}}(%v, %v, ...): projectID = %v, rk = %+v", ctx, key, projectID, rk) |
| |
| if err := g.s.RateLimiter.Accept(ctx, rk); err != nil { |
| klog.V(4).Infof("{{.GCEWrapType}}.{{.Name}}(%v, %v, ...): RateLimiter error: %v", ctx, key, err) |
| {{- if .IsOperation}} |
| return err |
| {{- else}} |
| return nil, err |
| {{- end}} |
| } |
| {{- if .KeyIsGlobal}} |
| call := g.s.{{.VersionTitle}}.{{.Service}}.{{.Name}}(projectID, key.Name {{.CallArgs}}) |
| {{- end -}} |
| {{- if .KeyIsRegional}} |
| call := g.s.{{.VersionTitle}}.{{.Service}}.{{.Name}}(projectID, key.Region, key.Name {{.CallArgs}}) |
| {{- end -}} |
| {{- if .KeyIsZonal}} |
| call := g.s.{{.VersionTitle}}.{{.Service}}.{{.Name}}(projectID, key.Zone, key.Name {{.CallArgs}}) |
| {{- end}} |
| {{- if .IsOperation}} |
| call.Context(ctx) |
| op, err := call.Do() |
| if err != nil { |
| klog.V(4).Infof("{{.GCEWrapType}}.{{.Name}}(%v, %v, ...) = %+v", ctx, key, err) |
| return err |
| } |
| err = g.s.WaitForCompletion(ctx, op) |
| klog.V(4).Infof("{{.GCEWrapType}}.{{.Name}}(%v, %v, ...) = %+v", ctx, key, err) |
| return err |
| {{- else if .IsGet}} |
| call.Context(ctx) |
| v, err := call.Do() |
| klog.V(4).Infof("{{.GCEWrapType}}.{{.Name}}(%v, %v, ...) = %+v, %v", ctx, key, v, err) |
| return v, err |
| {{- else if .IsPaged}} |
| var all []*{{.Version}}.{{.ItemType}} |
| f := func(l *{{.Version}}.{{.ReturnType}}) error { |
| klog.V(5).Infof("{{.GCEWrapType}}.{{.Name}}(%v, %v, ...): page %+v", ctx, key, l) |
| all = append(all, l.Items...) |
| return nil |
| } |
| if err := call.Pages(ctx, f); err != nil { |
| klog.V(4).Infof("{{.GCEWrapType}}.{{.Name}}(%v, %v, ...) = %v, %v", ctx, key, nil, err) |
| return nil, err |
| } |
| if klog.V(4) { |
| klog.V(4).Infof("{{.GCEWrapType}}.{{.Name}}(%v, %v, ...) = [%v items], %v", ctx, key, len(all), nil) |
| } else if klog.V(5) { |
| var asStr []string |
| for _, o := range all { |
| asStr = append(asStr, fmt.Sprintf("%+v", o)) |
| } |
| klog.V(5).Infof("{{.GCEWrapType}}.{{.Name}}(%v, %v, ...) = %v, %v", ctx, key, asStr, nil) |
| } |
| return all, nil |
| {{- end}} |
| } |
| {{end -}} |
| {{- end}} |
| ` |
| tmpl := template.Must(template.New("interface").Parse(text)) |
| for _, s := range meta.AllServices { |
| if err := tmpl.Execute(wr, s); err != nil { |
| panic(err) |
| } |
| } |
| } |
| |
| // genTypes generates the type wrappers. |
| func genResourceIDs(wr io.Writer) { |
| const text = ` |
| // New{{.Service}}ResourceID creates a ResourceID for the {{.Service}} resource. |
| {{- if .KeyIsProject}} |
| func New{{.Service}}ResourceID(project string) *ResourceID { |
| var key *meta.Key |
| {{- else}} |
| {{- if .KeyIsGlobal}} |
| func New{{.Service}}ResourceID(project, name string) *ResourceID { |
| key := meta.GlobalKey(name) |
| {{- end}} |
| {{- if .KeyIsRegional}} |
| func New{{.Service}}ResourceID(project, region, name string) *ResourceID { |
| key := meta.RegionalKey(name, region) |
| {{- end}} |
| {{- if .KeyIsZonal}} |
| func New{{.Service}}ResourceID(project, zone, name string) *ResourceID { |
| key := meta.ZonalKey(name, zone) |
| {{- end -}} |
| {{end}} |
| return &ResourceID{project, "{{.Resource}}", key} |
| } |
| ` |
| tmpl := template.Must(template.New("resourceIDs").Parse(text)) |
| for _, sg := range meta.SortedServicesGroups { |
| if err := tmpl.Execute(wr, sg.ServiceInfo()); err != nil { |
| panic(err) |
| } |
| } |
| } |
| |
| func genUnitTestHeader(wr io.Writer) { |
| const text = `/* |
| Copyright {{.Year}} The Kubernetes Authors. |
| |
| 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. |
| */ |
| |
| // This file was generated by "go run gen/main.go -mode test > gen_test.go". Do not edit |
| // directly. |
| |
| package cloud |
| |
| import ( |
| "context" |
| "reflect" |
| "testing" |
| |
| alpha "google.golang.org/api/compute/v0.alpha" |
| beta "google.golang.org/api/compute/v0.beta" |
| ga "google.golang.org/api/compute/v1" |
| |
| "{{.PackageRoot}}/filter" |
| "{{.PackageRoot}}/meta" |
| ) |
| |
| const location = "location" |
| ` |
| tmpl := template.Must(template.New("header").Parse(text)) |
| values := map[string]string{ |
| "Year": fmt.Sprintf("%v", time.Now().Year()), |
| "PackageRoot": packageRoot, |
| } |
| if err := tmpl.Execute(wr, values); err != nil { |
| panic(err) |
| } |
| } |
| |
| func genUnitTestServices(wr io.Writer) { |
| const text = ` |
| func Test{{.Service}}Group(t *testing.T) { |
| t.Parallel() |
| |
| ctx := context.Background() |
| pr := &SingleProjectRouter{"mock-project"} |
| mock := NewMockGCE(pr) |
| |
| var key *meta.Key |
| {{- if .HasAlpha}} |
| keyAlpha := meta.{{.Alpha.MakeKey "key-alpha" "location"}} |
| key = keyAlpha |
| {{- end}} |
| {{- if .HasBeta}} |
| keyBeta := meta.{{.Beta.MakeKey "key-beta" "location"}} |
| key = keyBeta |
| {{- end}} |
| {{- if .HasGA}} |
| keyGA := meta.{{.GA.MakeKey "key-ga" "location"}} |
| key = keyGA |
| {{- end}} |
| // Ignore unused variables. |
| _, _, _ = ctx, mock, key |
| |
| // Get not found. |
| {{- if .HasAlpha}}{{- if .Alpha.GenerateGet}} |
| if _, err := mock.Alpha{{.Service}}().Get(ctx, key); err == nil { |
| t.Errorf("Alpha{{.Service}}().Get(%v, %v) = _, nil; want error", ctx, key) |
| } |
| {{- end}}{{- end}} |
| {{- if .HasBeta}}{{- if .Beta.GenerateGet}} |
| if _, err := mock.Beta{{.Service}}().Get(ctx, key); err == nil { |
| t.Errorf("Beta{{.Service}}().Get(%v, %v) = _, nil; want error", ctx, key) |
| } |
| {{- end}}{{- end}} |
| {{- if .HasGA}}{{- if .GA.GenerateGet}} |
| if _, err := mock.{{.Service}}().Get(ctx, key); err == nil { |
| t.Errorf("{{.Service}}().Get(%v, %v) = _, nil; want error", ctx, key) |
| } |
| {{- end}}{{- end}} |
| |
| // Insert. |
| {{- if .HasAlpha}}{{- if .Alpha.GenerateInsert}} |
| { |
| obj := &alpha.{{.Alpha.Object}}{} |
| if err := mock.Alpha{{.Service}}().Insert(ctx, keyAlpha, obj); err != nil { |
| t.Errorf("Alpha{{.Service}}().Insert(%v, %v, %v) = %v; want nil", ctx, keyAlpha, obj, err) |
| } |
| } |
| {{- end}}{{- end}} |
| {{- if .HasBeta}}{{- if .Beta.GenerateInsert}} |
| { |
| obj := &beta.{{.Beta.Object}}{} |
| if err := mock.Beta{{.Service}}().Insert(ctx, keyBeta, obj); err != nil { |
| t.Errorf("Beta{{.Service}}().Insert(%v, %v, %v) = %v; want nil", ctx, keyBeta, obj, err) |
| } |
| } |
| {{- end}}{{- end}} |
| {{- if .HasGA}}{{- if .GA.GenerateInsert}} |
| { |
| obj := &ga.{{.GA.Object}}{} |
| if err := mock.{{.Service}}().Insert(ctx, keyGA, obj); err != nil { |
| t.Errorf("{{.Service}}().Insert(%v, %v, %v) = %v; want nil", ctx, keyGA, obj, err) |
| } |
| } |
| {{- end}}{{- end}} |
| |
| // Get across versions. |
| {{- if .HasAlpha}}{{- if .Alpha.GenerateInsert}} |
| if obj, err := mock.Alpha{{.Service}}().Get(ctx, key); err != nil { |
| t.Errorf("Alpha{{.Service}}().Get(%v, %v) = %v, %v; want nil", ctx, key, obj, err) |
| } |
| {{- end}}{{- end}} |
| {{- if .HasBeta}}{{- if .Beta.GenerateInsert}} |
| if obj, err := mock.Beta{{.Service}}().Get(ctx, key); err != nil { |
| t.Errorf("Beta{{.Service}}().Get(%v, %v) = %v, %v; want nil", ctx, key, obj, err) |
| } |
| {{- end}}{{- end}} |
| {{- if .HasGA}}{{- if .GA.GenerateInsert}} |
| if obj, err := mock.{{.Service}}().Get(ctx, key); err != nil { |
| t.Errorf("{{.Service}}().Get(%v, %v) = %v, %v; want nil", ctx, key, obj, err) |
| } |
| {{- end}}{{- end}} |
| |
| // List. |
| {{- if .HasAlpha}} |
| mock.MockAlpha{{.Service}}.Objects[*keyAlpha] = mock.MockAlpha{{.Service}}.Obj(&alpha.{{.Alpha.Object}}{Name: keyAlpha.Name}) |
| {{- end}} |
| {{- if .HasBeta}} |
| mock.MockBeta{{.Service}}.Objects[*keyBeta] = mock.MockBeta{{.Service}}.Obj(&beta.{{.Beta.Object}}{Name: keyBeta.Name}) |
| {{- end}} |
| {{- if .HasGA}} |
| mock.Mock{{.Service}}.Objects[*keyGA] = mock.Mock{{.Service}}.Obj(&ga.{{.GA.Object}}{Name: keyGA.Name}) |
| {{- end}} |
| want := map[string]bool{ |
| {{- if .HasAlpha}} |
| "key-alpha": true, |
| {{- end}} |
| {{- if .HasBeta}} |
| "key-beta": true, |
| {{- end}} |
| {{- if .HasGA}} |
| "key-ga": true, |
| {{- end}} |
| } |
| _ = want // ignore unused variables. |
| |
| {{- if .HasAlpha}}{{- if .Alpha.GenerateList}} |
| { |
| {{- if .Alpha.KeyIsGlobal }} |
| objs, err := mock.Alpha{{.Service}}().List(ctx, filter.None) |
| {{- else}} |
| objs, err := mock.Alpha{{.Service}}().List(ctx, location, filter.None) |
| {{- end}} |
| if err != nil { |
| t.Errorf("Alpha{{.Service}}().List(%v, %v, %v) = %v, %v; want _, nil", ctx, location, filter.None, objs, err) |
| } else { |
| got := map[string]bool{} |
| for _, obj := range objs { |
| got[obj.Name] = true |
| } |
| if !reflect.DeepEqual(got, want) { |
| t.Errorf("Alpha{{.Service}}().List(); got %+v, want %+v", got, want) |
| } |
| } |
| } |
| {{- end}}{{- end}} |
| {{- if .HasBeta}}{{- if .Beta.GenerateList}} |
| { |
| {{- if .Beta.KeyIsGlobal }} |
| objs, err := mock.Beta{{.Service}}().List(ctx, filter.None) |
| {{- else}} |
| objs, err := mock.Beta{{.Service}}().List(ctx, location, filter.None) |
| {{- end}} |
| if err != nil { |
| t.Errorf("Beta{{.Service}}().List(%v, %v, %v) = %v, %v; want _, nil", ctx, location, filter.None, objs, err) |
| } else { |
| got := map[string]bool{} |
| for _, obj := range objs { |
| got[obj.Name] = true |
| } |
| if !reflect.DeepEqual(got, want) { |
| t.Errorf("Beta{{.Service}}().List(); got %+v, want %+v", got, want) |
| } |
| } |
| } |
| {{- end}}{{- end}} |
| {{- if .HasGA}}{{- if .GA.GenerateList}} |
| { |
| {{- if .GA.KeyIsGlobal }} |
| objs, err := mock.{{.Service}}().List(ctx, filter.None) |
| {{- else}} |
| objs, err := mock.{{.Service}}().List(ctx, location, filter.None) |
| {{- end}} |
| if err != nil { |
| t.Errorf("{{.Service}}().List(%v, %v, %v) = %v, %v; want _, nil", ctx, location, filter.None, objs, err) |
| } else { |
| got := map[string]bool{} |
| for _, obj := range objs { |
| got[obj.Name] = true |
| } |
| if !reflect.DeepEqual(got, want) { |
| t.Errorf("{{.Service}}().List(); got %+v, want %+v", got, want) |
| } |
| } |
| } |
| {{- end}}{{- end}} |
| |
| // Delete across versions. |
| {{- if .HasAlpha}}{{- if .Alpha.GenerateDelete}} |
| if err := mock.Alpha{{.Service}}().Delete(ctx, keyAlpha); err != nil { |
| t.Errorf("Alpha{{.Service}}().Delete(%v, %v) = %v; want nil", ctx, keyAlpha, err) |
| } |
| {{- end}}{{- end}} |
| {{- if .HasBeta}}{{- if .Beta.GenerateDelete}} |
| if err := mock.Beta{{.Service}}().Delete(ctx, keyBeta); err != nil { |
| t.Errorf("Beta{{.Service}}().Delete(%v, %v) = %v; want nil", ctx, keyBeta, err) |
| } |
| {{- end}}{{- end}} |
| {{- if .HasGA}}{{- if .GA.GenerateDelete}} |
| if err := mock.{{.Service}}().Delete(ctx, keyGA); err != nil { |
| t.Errorf("{{.Service}}().Delete(%v, %v) = %v; want nil", ctx, keyGA, err) |
| } |
| {{- end}}{{- end}} |
| |
| // Delete not found. |
| {{- if .HasAlpha}}{{- if .Alpha.GenerateDelete}} |
| if err := mock.Alpha{{.Service}}().Delete(ctx, keyAlpha); err == nil { |
| t.Errorf("Alpha{{.Service}}().Delete(%v, %v) = nil; want error", ctx, keyAlpha) |
| } |
| {{- end}}{{- end}} |
| {{- if .HasBeta}}{{- if .Beta.GenerateDelete}} |
| if err := mock.Beta{{.Service}}().Delete(ctx, keyBeta); err == nil { |
| t.Errorf("Beta{{.Service}}().Delete(%v, %v) = nil; want error", ctx, keyBeta) |
| } |
| {{- end}}{{- end}} |
| {{- if .HasGA}}{{- if .GA.GenerateDelete}} |
| if err := mock.{{.Service}}().Delete(ctx, keyGA); err == nil { |
| t.Errorf("{{.Service}}().Delete(%v, %v) = nil; want error", ctx, keyGA) |
| } |
| {{- end}}{{- end}} |
| } |
| ` |
| tmpl := template.Must(template.New("unittest").Parse(text)) |
| for _, sg := range meta.SortedServicesGroups { |
| if err := tmpl.Execute(wr, sg); err != nil { |
| panic(err) |
| } |
| } |
| } |
| |
| func genUnitTestResourceIDConversion(wr io.Writer) { |
| const text = ` |
| func TestResourceIDConversion(t *testing.T) { |
| t.Parallel() |
| |
| for _, id := range []*ResourceID{ |
| {{- range .Groups}} |
| {{- with .ServiceInfo}} |
| {{- if .KeyIsProject}} |
| New{{.Service}}ResourceID("my-{{.Resource}}-resource"), |
| {{- else}} |
| {{- if .KeyIsGlobal}} |
| New{{.Service}}ResourceID("some-project", "my-{{.Resource}}-resource"), |
| {{- end}} |
| {{- if .KeyIsRegional}} |
| New{{.Service}}ResourceID("some-project", "us-central1", "my-{{.Resource}}-resource"), |
| {{- end}} |
| {{- if .KeyIsZonal}} |
| New{{.Service}}ResourceID("some-project", "us-east1-b", "my-{{.Resource}}-resource"), |
| {{- end -}} |
| {{end -}} |
| {{end -}} |
| {{end}} |
| } { |
| t.Run(id.Resource, func(t *testing.T) { |
| // Test conversion to and from full URL. |
| fullURL := id.SelfLink(meta.VersionGA) |
| parsedID, err := ParseResourceURL(fullURL) |
| if err != nil { |
| t.Errorf("ParseResourceURL(%s) = _, %v, want nil", fullURL, err) |
| } |
| if !reflect.DeepEqual(id, parsedID) { |
| t.Errorf("SelfLink(%+v) -> ParseResourceURL(%s) = %+v, want original ID", id, fullURL, parsedID) |
| } |
| |
| // Test conversion to and from relative resource name. |
| relativeName := id.RelativeResourceName() |
| parsedID, err = ParseResourceURL(relativeName) |
| if err != nil { |
| t.Errorf("ParseResourceURL(%s) = _, %v, want nil", relativeName, err) |
| } |
| if !reflect.DeepEqual(id, parsedID) { |
| t.Errorf("RelativeResourceName(%+v) -> ParseResourceURL(%s) = %+v, want original ID", id, relativeName, parsedID) |
| } |
| |
| // Do not test ResourcePath for projects. |
| if id.Resource == "projects" { |
| return |
| } |
| |
| // Test conversion to and from resource path. |
| resourcePath := id.ResourcePath() |
| parsedID, err = ParseResourceURL(resourcePath) |
| if err != nil { |
| t.Errorf("ParseResourceURL(%s) = _, %v, want nil", resourcePath, err) |
| } |
| id.ProjectID = "" |
| if !reflect.DeepEqual(id, parsedID) { |
| t.Errorf("ResourcePath(%+v) -> ParseResourceURL(%s) = %+v, want %+v", id, resourcePath, parsedID, id) |
| } |
| }) |
| } |
| } |
| ` |
| data := struct { |
| Groups []*meta.ServiceGroup |
| }{meta.SortedServicesGroups} |
| tmpl := template.Must(template.New("unittest-resourceIDs").Parse(text)) |
| if err := tmpl.Execute(wr, data); err != nil { |
| panic(err) |
| } |
| } |
| |
| func main() { |
| flag.Parse() |
| |
| out := &bytes.Buffer{} |
| |
| switch flags.mode { |
| case "src": |
| genHeader(out) |
| genStubs(out) |
| genTypes(out) |
| genResourceIDs(out) |
| case "test": |
| genUnitTestHeader(out) |
| genUnitTestServices(out) |
| genUnitTestResourceIDConversion(out) |
| default: |
| log.Fatalf("Invalid -mode: %q", flags.mode) |
| } |
| |
| if flags.gofmt { |
| fmt.Print(gofmtContent(out)) |
| } else { |
| fmt.Print(out.String()) |
| } |
| } |