mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 03:41:45 +00:00
Add handling for method that use Pages() to retrieve results
Make functions take in *Key rather than value type.
This commit is contained in:
parent
7dadeee5e8
commit
447823b4a1
@ -276,7 +276,7 @@ type {{.WrapType}} interface {
|
||||
{{.WrapTypeOps}}
|
||||
{{- end}}
|
||||
{{- if .GenerateGet}}
|
||||
Get(ctx context.Context, key meta.Key) (*{{.FQObjectType}}, error)
|
||||
Get(ctx context.Context, key *meta.Key) (*{{.FQObjectType}}, error)
|
||||
{{- end -}}
|
||||
{{- if .GenerateList}}
|
||||
{{- if .KeyIsGlobal}}
|
||||
@ -290,10 +290,10 @@ type {{.WrapType}} interface {
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- if .GenerateInsert}}
|
||||
Insert(ctx context.Context, key meta.Key, obj *{{.FQObjectType}}) error
|
||||
Insert(ctx context.Context, key *meta.Key, obj *{{.FQObjectType}}) error
|
||||
{{- end -}}
|
||||
{{- if .GenerateDelete}}
|
||||
Delete(ctx context.Context, key meta.Key) error
|
||||
Delete(ctx context.Context, key *meta.Key) error
|
||||
{{- end -}}
|
||||
{{- if .AggregatedList}}
|
||||
AggregatedList(ctx context.Context, fl *filter.F) (map[string][]*{{.FQObjectType}}, error)
|
||||
@ -352,7 +352,7 @@ type {{.MockWrapType}} struct {
|
||||
// execution flow of the mock. Return (false, nil, nil) to continue with
|
||||
// normal mock behavior/ after the hook function executes.
|
||||
{{- if .GenerateGet}}
|
||||
GetHook func(m *{{.MockWrapType}}, ctx context.Context, key meta.Key) (bool, *{{.FQObjectType}}, error)
|
||||
GetHook func(m *{{.MockWrapType}}, ctx context.Context, key *meta.Key) (bool, *{{.FQObjectType}}, error)
|
||||
{{- end -}}
|
||||
{{- if .GenerateList}}
|
||||
{{- if .KeyIsGlobal}}
|
||||
@ -366,10 +366,10 @@ type {{.MockWrapType}} struct {
|
||||
{{- end}}
|
||||
{{- end -}}
|
||||
{{- if .GenerateInsert}}
|
||||
InsertHook func(m *{{.MockWrapType}}, ctx context.Context, key meta.Key, obj *{{.FQObjectType}}) (bool, error)
|
||||
InsertHook func(m *{{.MockWrapType}}, ctx context.Context, key *meta.Key, obj *{{.FQObjectType}}) (bool, error)
|
||||
{{- end -}}
|
||||
{{- if .GenerateDelete}}
|
||||
DeleteHook func(m *{{.MockWrapType}}, ctx context.Context, key meta.Key) (bool, error)
|
||||
DeleteHook func(m *{{.MockWrapType}}, ctx context.Context, key *meta.Key) (bool, error)
|
||||
{{- end -}}
|
||||
{{- if .AggregatedList}}
|
||||
AggregatedListHook func(m *{{.MockWrapType}}, ctx context.Context, fl *filter.F) (bool, map[string][]*{{.FQObjectType}}, error)
|
||||
@ -388,7 +388,7 @@ type {{.MockWrapType}} struct {
|
||||
|
||||
{{- if .GenerateGet}}
|
||||
// Get returns the object from the mock.
|
||||
func (m *{{.MockWrapType}}) Get(ctx context.Context, key meta.Key) (*{{.FQObjectType}}, error) {
|
||||
func (m *{{.MockWrapType}}) Get(ctx context.Context, key *meta.Key) (*{{.FQObjectType}}, error) {
|
||||
if m.GetHook != nil {
|
||||
if intercept, obj, err := m.GetHook(m, ctx, key); intercept {
|
||||
glog.V(5).Infof("{{.MockWrapType}}.Get(%v, %s) = %+v, %v", ctx, key, obj ,err)
|
||||
@ -399,11 +399,11 @@ func (m *{{.MockWrapType}}) Get(ctx context.Context, key meta.Key) (*{{.FQObject
|
||||
m.Lock.Lock()
|
||||
defer m.Lock.Unlock()
|
||||
|
||||
if err, ok := m.GetError[key]; ok {
|
||||
if err, ok := m.GetError[*key]; ok {
|
||||
glog.V(5).Infof("{{.MockWrapType}}.Get(%v, %s) = nil, %v", ctx, key, err)
|
||||
return nil, err
|
||||
}
|
||||
if obj, ok := m.Objects[key]; ok {
|
||||
if obj, ok := m.Objects[*key]; ok {
|
||||
typedObj := obj.To{{.VersionTitle}}()
|
||||
glog.V(5).Infof("{{.MockWrapType}}.Get(%v, %s) = %+v, nil", ctx, key, typedObj)
|
||||
return typedObj, nil
|
||||
@ -503,7 +503,7 @@ func (m *{{.MockWrapType}}) List(ctx context.Context, zone string, fl *filter.F)
|
||||
|
||||
{{- 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 {
|
||||
func (m *{{.MockWrapType}}) Insert(ctx context.Context, key *meta.Key, obj *{{.FQObjectType}}) error {
|
||||
if m.InsertHook != nil {
|
||||
if intercept, err := m.InsertHook(m, ctx, key, obj); intercept {
|
||||
glog.V(5).Infof("{{.MockWrapType}}.Insert(%v, %v, %+v) = %v", ctx, key, obj, err)
|
||||
@ -514,11 +514,11 @@ func (m *{{.MockWrapType}}) Insert(ctx context.Context, key meta.Key, obj *{{.FQ
|
||||
m.Lock.Lock()
|
||||
defer m.Lock.Unlock()
|
||||
|
||||
if err, ok := m.InsertError[key]; ok {
|
||||
if err, ok := m.InsertError[*key]; ok {
|
||||
glog.V(5).Infof("{{.MockWrapType}}.Insert(%v, %v, %+v) = %v", ctx, key, obj, err)
|
||||
return err
|
||||
}
|
||||
if _, ok := m.Objects[key]; ok {
|
||||
if _, ok := m.Objects[*key]; ok {
|
||||
err := &googleapi.Error{
|
||||
Code: http.StatusConflict,
|
||||
Message: fmt.Sprintf("{{.MockWrapType}} %v exists", key),
|
||||
@ -532,7 +532,7 @@ func (m *{{.MockWrapType}}) Insert(ctx context.Context, key meta.Key, obj *{{.FQ
|
||||
obj.SelfLink = SelfLink(meta.Version{{.VersionTitle}}, "mock-project", "{{.Resource}}", key)
|
||||
}
|
||||
|
||||
m.Objects[key] = &Mock{{.Service}}Obj{obj}
|
||||
m.Objects[*key] = &Mock{{.Service}}Obj{obj}
|
||||
glog.V(5).Infof("{{.MockWrapType}}.Insert(%v, %v, %+v) = nil", ctx, key, obj)
|
||||
return nil
|
||||
}
|
||||
@ -540,7 +540,7 @@ func (m *{{.MockWrapType}}) Insert(ctx context.Context, key meta.Key, obj *{{.FQ
|
||||
|
||||
{{- if .GenerateDelete}}
|
||||
// Delete is a mock for deleting the object.
|
||||
func (m *{{.MockWrapType}}) Delete(ctx context.Context, key meta.Key) error {
|
||||
func (m *{{.MockWrapType}}) Delete(ctx context.Context, key *meta.Key) error {
|
||||
if m.DeleteHook != nil {
|
||||
if intercept, err := m.DeleteHook(m, ctx, key); intercept {
|
||||
glog.V(5).Infof("{{.MockWrapType}}.Delete(%v, %v) = %v", ctx, key, err)
|
||||
@ -551,11 +551,11 @@ func (m *{{.MockWrapType}}) Delete(ctx context.Context, key meta.Key) error {
|
||||
m.Lock.Lock()
|
||||
defer m.Lock.Unlock()
|
||||
|
||||
if err, ok := m.DeleteError[key]; ok {
|
||||
if err, ok := m.DeleteError[*key]; ok {
|
||||
glog.V(5).Infof("{{.MockWrapType}}.Delete(%v, %v) = %v", ctx, key, err)
|
||||
return err
|
||||
}
|
||||
if _, ok := m.Objects[key]; !ok {
|
||||
if _, ok := m.Objects[*key]; !ok {
|
||||
err := &googleapi.Error{
|
||||
Code: http.StatusNotFound,
|
||||
Message: fmt.Sprintf("{{.MockWrapType}} %v not found", key),
|
||||
@ -564,7 +564,7 @@ func (m *{{.MockWrapType}}) Delete(ctx context.Context, key meta.Key) error {
|
||||
return err
|
||||
}
|
||||
|
||||
delete(m.Objects, key)
|
||||
delete(m.Objects, *key)
|
||||
glog.V(5).Infof("{{.MockWrapType}}.Delete(%v, %v) = nil", ctx, key)
|
||||
return nil
|
||||
}
|
||||
@ -621,16 +621,21 @@ func (m *{{.MockWrapType}}) Obj(o *{{.FQObjectType}}) *Mock{{.Service}}Obj {
|
||||
{{- range .}}
|
||||
// {{.Name}} is a mock for the corresponding method.
|
||||
func (m *{{.MockWrapType}}) {{.FcnArgs}} {
|
||||
{{- if eq .ReturnType "Operation"}}
|
||||
{{- if .IsOperation }}
|
||||
if m.{{.MockHookName}} != nil {
|
||||
return m.{{.MockHookName}}(m, ctx, key {{.CallArgs}})
|
||||
}
|
||||
return nil
|
||||
{{- else}}
|
||||
{{- else if .IsGet}}
|
||||
if m.{{.MockHookName}} != nil {
|
||||
return m.{{.MockHookName}}(m, ctx, key {{.CallArgs}})
|
||||
}
|
||||
return nil, fmt.Errorf("{{.MockHookName}} must be set")
|
||||
{{- else if .IsPaged}}
|
||||
if m.{{.MockHookName}} != nil {
|
||||
return m.{{.MockHookName}}(m, ctx, key {{.CallArgs}}, fl)
|
||||
}
|
||||
return nil, nil
|
||||
{{- end}}
|
||||
}
|
||||
{{end -}}
|
||||
@ -642,7 +647,7 @@ type {{.GCEWrapType}} struct {
|
||||
|
||||
{{- if .GenerateGet}}
|
||||
// Get the {{.Object}} named by key.
|
||||
func (g *{{.GCEWrapType}}) Get(ctx context.Context, key meta.Key) (*{{.FQObjectType}}, error) {
|
||||
func (g *{{.GCEWrapType}}) Get(ctx context.Context, key *meta.Key) (*{{.FQObjectType}}, error) {
|
||||
projectID := g.s.ProjectRouter.ProjectID(ctx, "{{.Version}}", "{{.Service}}")
|
||||
rk := &RateLimitKey{
|
||||
ProjectID: projectID,
|
||||
@ -714,7 +719,7 @@ rk := &RateLimitKey{
|
||||
|
||||
{{- if .GenerateInsert}}
|
||||
// Insert {{.Object}} with key of value obj.
|
||||
func (g *{{.GCEWrapType}}) Insert(ctx context.Context, key meta.Key, obj *{{.FQObjectType}}) error {
|
||||
func (g *{{.GCEWrapType}}) Insert(ctx context.Context, key *meta.Key, obj *{{.FQObjectType}}) error {
|
||||
projectID := g.s.ProjectRouter.ProjectID(ctx, "{{.Version}}", "{{.Service}}")
|
||||
rk := &RateLimitKey{
|
||||
ProjectID: projectID,
|
||||
@ -747,7 +752,7 @@ func (g *{{.GCEWrapType}}) Insert(ctx context.Context, key meta.Key, obj *{{.FQO
|
||||
|
||||
{{- if .GenerateDelete}}
|
||||
// Delete the {{.Object}} referenced by key.
|
||||
func (g *{{.GCEWrapType}}) Delete(ctx context.Context, key meta.Key) error {
|
||||
func (g *{{.GCEWrapType}}) Delete(ctx context.Context, key *meta.Key) error {
|
||||
projectID := g.s.ProjectRouter.ProjectID(ctx, "{{.Version}}", "{{.Service}}")
|
||||
rk := &RateLimitKey{
|
||||
ProjectID: projectID,
|
||||
@ -823,7 +828,7 @@ func (g *{{.GCEWrapType}}) {{.FcnArgs}} {
|
||||
Service: "{{.Service}}",
|
||||
}
|
||||
if err := g.s.RateLimiter.Accept(ctx, rk); err != nil {
|
||||
{{- if eq .ReturnType "Operation"}}
|
||||
{{- if .IsOperation}}
|
||||
return err
|
||||
{{- else}}
|
||||
return nil, err
|
||||
@ -838,15 +843,26 @@ func (g *{{.GCEWrapType}}) {{.FcnArgs}} {
|
||||
{{- if .KeyIsZonal}}
|
||||
call := g.s.{{.VersionTitle}}.{{.Service}}.{{.Name}}(projectID, key.Zone, key.Name {{.CallArgs}})
|
||||
{{- end}}
|
||||
{{- if .IsOperation}}
|
||||
call.Context(ctx)
|
||||
{{- if eq .ReturnType "Operation"}}
|
||||
op, err := call.Do()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return g.s.WaitForCompletion(ctx, op)
|
||||
{{- else}}
|
||||
{{- else if .IsGet}}
|
||||
call.Context(ctx)
|
||||
return call.Do()
|
||||
{{- else if .IsPaged}}
|
||||
var all []*{{.Version}}.{{.ItemType}}
|
||||
f := func(l *{{.Version}}.{{.ReturnType}}) error {
|
||||
all = append(all, l.Items...)
|
||||
return nil
|
||||
}
|
||||
if err := call.Pages(ctx, f); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return all, nil
|
||||
{{- end}}
|
||||
}
|
||||
{{end -}}
|
||||
@ -933,17 +949,17 @@ func Test{{.Service}}Group(t *testing.T) {
|
||||
|
||||
// Get not found.
|
||||
{{- if .HasAlpha}}{{- if .Alpha.GenerateGet}}
|
||||
if _, err := mock.Alpha{{.Service}}().Get(ctx, *key); err == nil {
|
||||
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 {
|
||||
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 {
|
||||
if _, err := mock.{{.Service}}().Get(ctx, key); err == nil {
|
||||
t.Errorf("{{.Service}}().Get(%v, %v) = _, nil; want error", ctx, key)
|
||||
}
|
||||
{{- end}}{{- end}}
|
||||
@ -952,41 +968,41 @@ func Test{{.Service}}Group(t *testing.T) {
|
||||
{{- 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, key, obj, err)
|
||||
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, key, obj, err)
|
||||
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, key, obj, err)
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
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}}
|
||||
@ -1077,35 +1093,35 @@ func Test{{.Service}}Group(t *testing.T) {
|
||||
|
||||
// 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, key, err)
|
||||
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, key, err)
|
||||
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, key, err)
|
||||
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, key)
|
||||
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, key)
|
||||
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, key)
|
||||
if err := mock.{{.Service}}().Delete(ctx, keyGA); err == nil {
|
||||
t.Errorf("{{.Service}}().Delete(%v, %v) = nil; want error", ctx, keyGA)
|
||||
}
|
||||
{{- end}}{{- end}}
|
||||
}
|
||||
|
@ -12,7 +12,6 @@ go_library(
|
||||
importpath = "k8s.io/kubernetes/pkg/cloudprovider/providers/gce/cloud/meta",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/google.golang.org/api/compute/v0.alpha:go_default_library",
|
||||
"//vendor/google.golang.org/api/compute/v0.beta:go_default_library",
|
||||
"//vendor/google.golang.org/api/compute/v1:go_default_library",
|
||||
|
@ -115,6 +115,18 @@ var AllServices = []*ServiceInfo{
|
||||
serviceType: reflect.TypeOf(&alpha.BackendServicesService{}),
|
||||
additionalMethods: []string{"Update"},
|
||||
},
|
||||
{
|
||||
Object: "BackendService",
|
||||
Service: "RegionBackendServices",
|
||||
Resource: "backendServices",
|
||||
version: VersionGA,
|
||||
keyType: Regional,
|
||||
serviceType: reflect.TypeOf(&ga.RegionBackendServicesService{}),
|
||||
additionalMethods: []string{
|
||||
"GetHealth",
|
||||
"Update",
|
||||
},
|
||||
},
|
||||
{
|
||||
Object: "BackendService",
|
||||
Service: "RegionBackendServices",
|
||||
@ -285,6 +297,7 @@ var AllServices = []*ServiceInfo{
|
||||
additionalMethods: []string{
|
||||
"AttachNetworkEndpoints",
|
||||
"DetachNetworkEndpoints",
|
||||
"ListNetworkEndpoints",
|
||||
},
|
||||
options: AggregatedList,
|
||||
},
|
||||
|
@ -20,8 +20,6 @@ import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
func newArg(t reflect.Type) *arg {
|
||||
@ -86,23 +84,60 @@ func (a *arg) String() string {
|
||||
|
||||
// newMethod returns a newly initialized method.
|
||||
func newMethod(s *ServiceInfo, m reflect.Method) *Method {
|
||||
ret := &Method{s, m, ""}
|
||||
ret := &Method{
|
||||
ServiceInfo: s,
|
||||
m: m,
|
||||
kind: MethodOperation,
|
||||
ReturnType: "",
|
||||
}
|
||||
ret.init()
|
||||
return ret
|
||||
}
|
||||
|
||||
// MethodKind is the type of method that we are generated code for.
|
||||
type MethodKind int
|
||||
|
||||
const (
|
||||
// MethodOperation is a long running method that returns an operation.
|
||||
MethodOperation MethodKind = iota
|
||||
// MethodGet is a method that immediately returns some data.
|
||||
MethodGet MethodKind = iota
|
||||
// MethodPaged is a method that returns a paged set of data.
|
||||
MethodPaged MethodKind = iota
|
||||
)
|
||||
|
||||
// Method is used to generate the calling code for non-standard methods.
|
||||
type Method struct {
|
||||
*ServiceInfo
|
||||
m reflect.Method
|
||||
|
||||
kind MethodKind
|
||||
// ReturnType is the return type for the method.
|
||||
ReturnType string
|
||||
// ItemType is the type of the individual elements returns from a
|
||||
// Pages() call. This is only applicable for MethodPaged kind.
|
||||
ItemType string
|
||||
}
|
||||
|
||||
// IsOperation is true if the method is an Operation.
|
||||
func (m *Method) IsOperation() bool {
|
||||
return m.kind == MethodOperation
|
||||
}
|
||||
|
||||
// IsPaged is true if the method paged.
|
||||
func (m *Method) IsPaged() bool {
|
||||
return m.kind == MethodPaged
|
||||
}
|
||||
|
||||
// IsGet is true if the method simple get.
|
||||
func (m *Method) IsGet() bool {
|
||||
return m.kind == MethodGet
|
||||
}
|
||||
|
||||
// argsSkip is the number of arguments to skip when generating the
|
||||
// synthesized method.
|
||||
func (mr *Method) argsSkip() int {
|
||||
switch mr.keyType {
|
||||
func (m *Method) argsSkip() int {
|
||||
switch m.keyType {
|
||||
case Zonal:
|
||||
return 4
|
||||
case Regional:
|
||||
@ -110,15 +145,15 @@ func (mr *Method) argsSkip() int {
|
||||
case Global:
|
||||
return 3
|
||||
}
|
||||
panic(fmt.Errorf("invalid KeyType %v", mr.keyType))
|
||||
panic(fmt.Errorf("invalid KeyType %v", m.keyType))
|
||||
}
|
||||
|
||||
// args return a list of arguments to the method, skipping the first skip
|
||||
// elements. If nameArgs is true, then the arguments will include a generated
|
||||
// parameter name (arg<N>). prefix will be added to the parameters.
|
||||
func (mr *Method) args(skip int, nameArgs bool, prefix []string) []string {
|
||||
func (m *Method) args(skip int, nameArgs bool, prefix []string) []string {
|
||||
var args []*arg
|
||||
fType := mr.m.Func.Type()
|
||||
fType := m.m.Func.Type()
|
||||
for i := 0; i < fType.NumIn(); i++ {
|
||||
t := fType.In(i)
|
||||
args = append(args, newArg(t))
|
||||
@ -135,24 +170,26 @@ func (mr *Method) args(skip int, nameArgs bool, prefix []string) []string {
|
||||
return append(prefix, a...)
|
||||
}
|
||||
|
||||
// init the method, preforming some rudimentary static checking.
|
||||
func (mr *Method) init() {
|
||||
fType := mr.m.Func.Type()
|
||||
if fType.NumIn() < mr.argsSkip() {
|
||||
// init the method. This performs some rudimentary static checking as well as
|
||||
// determines the kind of method by looking at the shape (method signature) of
|
||||
// the object.
|
||||
func (m *Method) init() {
|
||||
fType := m.m.Func.Type()
|
||||
if fType.NumIn() < m.argsSkip() {
|
||||
err := fmt.Errorf("method %q.%q, arity = %d which is less than required (< %d)",
|
||||
mr.Service, mr.Name(), fType.NumIn(), mr.argsSkip())
|
||||
m.Service, m.Name(), fType.NumIn(), m.argsSkip())
|
||||
panic(err)
|
||||
}
|
||||
// Skipped args should all be string (they will be projectID, zone, region etc).
|
||||
for i := 1; i < mr.argsSkip(); i++ {
|
||||
for i := 1; i < m.argsSkip(); i++ {
|
||||
if fType.In(i).Kind() != reflect.String {
|
||||
panic(fmt.Errorf("method %q.%q: skipped args can only be strings", mr.Service, mr.Name()))
|
||||
panic(fmt.Errorf("method %q.%q: skipped args can only be strings", m.Service, m.Name()))
|
||||
}
|
||||
}
|
||||
// Return of the method must return a single value of type *xxxCall.
|
||||
if fType.NumOut() != 1 || fType.Out(0).Kind() != reflect.Ptr || !strings.HasSuffix(fType.Out(0).Elem().Name(), "Call") {
|
||||
panic(fmt.Errorf("method %q.%q: generator only supports methods returning an *xxxCall object",
|
||||
mr.Service, mr.Name()))
|
||||
m.Service, m.Name()))
|
||||
}
|
||||
returnType := fType.Out(0)
|
||||
returnTypeName := fType.Out(0).Elem().Name()
|
||||
@ -160,48 +197,64 @@ func (mr *Method) init() {
|
||||
doMethod, ok := returnType.MethodByName("Do")
|
||||
if !ok {
|
||||
panic(fmt.Errorf("method %q.%q: return type %q does not have a Do() method",
|
||||
mr.Service, mr.Name(), returnTypeName))
|
||||
m.Service, m.Name(), returnTypeName))
|
||||
}
|
||||
_, hasPages := returnType.MethodByName("Pages")
|
||||
// Do() method must return (*T, error).
|
||||
switch doMethod.Func.Type().NumOut() {
|
||||
case 2:
|
||||
glog.Infof("Method %q.%q: return type %q of Do() = %v, %v",
|
||||
mr.Service, mr.Name(), returnTypeName, doMethod.Func.Type().Out(0), doMethod.Func.Type().Out(1))
|
||||
out0 := doMethod.Func.Type().Out(0)
|
||||
if out0.Kind() != reflect.Ptr {
|
||||
panic(fmt.Errorf("method %q.%q: return type %q of Do() = S, _; S must be pointer type (%v)",
|
||||
mr.Service, mr.Name(), returnTypeName, out0))
|
||||
m.Service, m.Name(), returnTypeName, out0))
|
||||
}
|
||||
mr.ReturnType = out0.Elem().Name()
|
||||
if out0.Elem().Name() == "Operation" {
|
||||
glog.Infof("Method %q.%q is an *Operation", mr.Service, mr.Name())
|
||||
} else {
|
||||
glog.Infof("Method %q.%q returns %v", mr.Service, mr.Name(), out0)
|
||||
m.ReturnType = out0.Elem().Name()
|
||||
switch {
|
||||
case out0.Elem().Name() == "Operation":
|
||||
m.kind = MethodOperation
|
||||
case hasPages:
|
||||
m.kind = MethodPaged
|
||||
// Pages() returns a xxxList that has the actual list
|
||||
// of objects in the xxxList.Items field.
|
||||
listType := out0.Elem()
|
||||
itemsField, ok := listType.FieldByName("Items")
|
||||
if !ok {
|
||||
panic(fmt.Errorf("method %q.%q: paged return type %q does not have a .Items field", m.Service, m.Name(), listType.Name()))
|
||||
}
|
||||
// itemsField will be a []*ItemType. Dereference to
|
||||
// extract the ItemType.
|
||||
itemsType := itemsField.Type
|
||||
if itemsType.Kind() != reflect.Slice && itemsType.Elem().Kind() != reflect.Ptr {
|
||||
panic(fmt.Errorf("method %q.%q: paged return type %q.Items is not an array of pointers", m.Service, m.Name(), listType.Name()))
|
||||
}
|
||||
m.ItemType = itemsType.Elem().Elem().Name()
|
||||
default:
|
||||
m.kind = MethodGet
|
||||
}
|
||||
// Second argument must be "error".
|
||||
if doMethod.Func.Type().Out(1).Name() != "error" {
|
||||
panic(fmt.Errorf("method %q.%q: return type %q of Do() = S, T; T must be 'error'",
|
||||
mr.Service, mr.Name(), returnTypeName))
|
||||
m.Service, m.Name(), returnTypeName))
|
||||
}
|
||||
break
|
||||
default:
|
||||
panic(fmt.Errorf("method %q.%q: %q Do() return type is not handled by the generator",
|
||||
mr.Service, mr.Name(), returnTypeName))
|
||||
m.Service, m.Name(), returnTypeName))
|
||||
}
|
||||
}
|
||||
|
||||
// Name is the name of the method.
|
||||
func (mr *Method) Name() string {
|
||||
return mr.m.Name
|
||||
func (m *Method) Name() string {
|
||||
return m.m.Name
|
||||
}
|
||||
|
||||
// CallArgs is a list of comma separated "argN" used for calling the method.
|
||||
// For example, if the method has two additional arguments, this will return
|
||||
// "arg0, arg1".
|
||||
func (mr *Method) CallArgs() string {
|
||||
func (m *Method) CallArgs() string {
|
||||
var args []string
|
||||
for i := mr.argsSkip(); i < mr.m.Func.Type().NumIn(); i++ {
|
||||
args = append(args, fmt.Sprintf("arg%d", i-mr.argsSkip()))
|
||||
for i := m.argsSkip(); i < m.m.Func.Type().NumIn(); i++ {
|
||||
args = append(args, fmt.Sprintf("arg%d", i-m.argsSkip()))
|
||||
}
|
||||
if len(args) == 0 {
|
||||
return ""
|
||||
@ -210,41 +263,74 @@ func (mr *Method) CallArgs() string {
|
||||
}
|
||||
|
||||
// MockHookName is the name of the hook function in the mock.
|
||||
func (mr *Method) MockHookName() string {
|
||||
return mr.m.Name + "Hook"
|
||||
func (m *Method) MockHookName() string {
|
||||
return m.m.Name + "Hook"
|
||||
}
|
||||
|
||||
// MockHook is the definition of the hook function.
|
||||
func (mr *Method) MockHook() string {
|
||||
args := mr.args(mr.argsSkip(), false, []string{
|
||||
fmt.Sprintf("*%s", mr.MockWrapType()),
|
||||
func (m *Method) MockHook() string {
|
||||
args := m.args(m.argsSkip(), false, []string{
|
||||
fmt.Sprintf("*%s", m.MockWrapType()),
|
||||
"context.Context",
|
||||
"meta.Key",
|
||||
"*meta.Key",
|
||||
})
|
||||
if mr.ReturnType == "Operation" {
|
||||
return fmt.Sprintf("%v func(%v) error", mr.MockHookName(), strings.Join(args, ", "))
|
||||
if m.kind == MethodPaged {
|
||||
args = append(args, "*filter.F")
|
||||
}
|
||||
|
||||
switch m.kind {
|
||||
case MethodOperation:
|
||||
return fmt.Sprintf("%v func(%v) error", m.MockHookName(), strings.Join(args, ", "))
|
||||
case MethodGet:
|
||||
return fmt.Sprintf("%v func(%v) (*%v.%v, error)", m.MockHookName(), strings.Join(args, ", "), m.Version(), m.ReturnType)
|
||||
case MethodPaged:
|
||||
return fmt.Sprintf("%v func(%v) ([]*%v.%v, error)", m.MockHookName(), strings.Join(args, ", "), m.Version(), m.ItemType)
|
||||
default:
|
||||
panic(fmt.Errorf("invalid method kind: %v", m.kind))
|
||||
}
|
||||
return fmt.Sprintf("%v func(%v) (*%v.%v, error)", mr.MockHookName(), strings.Join(args, ", "), mr.Version(), mr.ReturnType)
|
||||
}
|
||||
|
||||
// FcnArgs is the function signature for the definition of the method.
|
||||
func (mr *Method) FcnArgs() string {
|
||||
args := mr.args(mr.argsSkip(), true, []string{
|
||||
func (m *Method) FcnArgs() string {
|
||||
args := m.args(m.argsSkip(), true, []string{
|
||||
"ctx context.Context",
|
||||
"key meta.Key",
|
||||
"key *meta.Key",
|
||||
})
|
||||
|
||||
if mr.ReturnType == "Operation" {
|
||||
return fmt.Sprintf("%v(%v) error", mr.m.Name, strings.Join(args, ", "))
|
||||
if m.kind == MethodPaged {
|
||||
args = append(args, "fl *filter.F")
|
||||
}
|
||||
|
||||
switch m.kind {
|
||||
case MethodOperation:
|
||||
return fmt.Sprintf("%v(%v) error", m.m.Name, strings.Join(args, ", "))
|
||||
case MethodGet:
|
||||
return fmt.Sprintf("%v(%v) (*%v.%v, error)", m.m.Name, strings.Join(args, ", "), m.Version(), m.ReturnType)
|
||||
case MethodPaged:
|
||||
return fmt.Sprintf("%v(%v) ([]*%v.%v, error)", m.m.Name, strings.Join(args, ", "), m.Version(), m.ItemType)
|
||||
default:
|
||||
panic(fmt.Errorf("invalid method kind: %v", m.kind))
|
||||
}
|
||||
return fmt.Sprintf("%v(%v) (*%v.%v, error)", mr.m.Name, strings.Join(args, ", "), mr.Version(), mr.ReturnType)
|
||||
}
|
||||
|
||||
// InterfaceFunc is the function declaration of the method in the interface.
|
||||
func (mr *Method) InterfaceFunc() string {
|
||||
args := mr.args(mr.argsSkip(), false, []string{"context.Context", "meta.Key"})
|
||||
if mr.ReturnType == "Operation" {
|
||||
return fmt.Sprintf("%v(%v) error", mr.m.Name, strings.Join(args, ", "))
|
||||
func (m *Method) InterfaceFunc() string {
|
||||
args := []string{
|
||||
"context.Context",
|
||||
"*meta.Key",
|
||||
}
|
||||
args = m.args(m.argsSkip(), false, args)
|
||||
if m.kind == MethodPaged {
|
||||
args = append(args, "*filter.F")
|
||||
}
|
||||
|
||||
switch m.kind {
|
||||
case MethodOperation:
|
||||
return fmt.Sprintf("%v(%v) error", m.m.Name, strings.Join(args, ", "))
|
||||
case MethodGet:
|
||||
return fmt.Sprintf("%v(%v) (*%v.%v, error)", m.m.Name, strings.Join(args, ", "), m.Version(), m.ReturnType)
|
||||
case MethodPaged:
|
||||
return fmt.Sprintf("%v(%v) ([]*%v.%v, error)", m.m.Name, strings.Join(args, ", "), m.Version(), m.ItemType)
|
||||
default:
|
||||
panic(fmt.Errorf("invalid method kind: %v", m.kind))
|
||||
}
|
||||
return fmt.Sprintf("%v(%v) (*%v.%v, error)", mr.m.Name, strings.Join(args, ", "), mr.Version(), mr.ReturnType)
|
||||
}
|
||||
|
@ -45,42 +45,42 @@ func TestMocks(t *testing.T) {
|
||||
key := keyAlpha
|
||||
|
||||
// Get not found.
|
||||
if _, err := mock.AlphaAddresses().Get(ctx, *key); err == nil {
|
||||
if _, err := mock.AlphaAddresses().Get(ctx, key); err == nil {
|
||||
t.Errorf("AlphaAddresses().Get(%v, %v) = _, nil; want error", ctx, key)
|
||||
}
|
||||
if _, err := mock.BetaAddresses().Get(ctx, *key); err == nil {
|
||||
if _, err := mock.BetaAddresses().Get(ctx, key); err == nil {
|
||||
t.Errorf("BetaAddresses().Get(%v, %v) = _, nil; want error", ctx, key)
|
||||
}
|
||||
if _, err := mock.Addresses().Get(ctx, *key); err == nil {
|
||||
if _, err := mock.Addresses().Get(ctx, key); err == nil {
|
||||
t.Errorf("Addresses().Get(%v, %v) = _, nil; want error", ctx, key)
|
||||
}
|
||||
// Insert.
|
||||
{
|
||||
obj := &alpha.Address{}
|
||||
if err := mock.AlphaAddresses().Insert(ctx, *keyAlpha, obj); err != nil {
|
||||
if err := mock.AlphaAddresses().Insert(ctx, keyAlpha, obj); err != nil {
|
||||
t.Errorf("AlphaAddresses().Insert(%v, %v, %v) = %v; want nil", ctx, key, obj, err)
|
||||
}
|
||||
}
|
||||
{
|
||||
obj := &beta.Address{}
|
||||
if err := mock.BetaAddresses().Insert(ctx, *keyBeta, obj); err != nil {
|
||||
if err := mock.BetaAddresses().Insert(ctx, keyBeta, obj); err != nil {
|
||||
t.Errorf("BetaAddresses().Insert(%v, %v, %v) = %v; want nil", ctx, key, obj, err)
|
||||
}
|
||||
}
|
||||
{
|
||||
obj := &ga.Address{}
|
||||
if err := mock.Addresses().Insert(ctx, *keyGA, &ga.Address{Name: "ga"}); err != nil {
|
||||
if err := mock.Addresses().Insert(ctx, keyGA, &ga.Address{Name: "ga"}); err != nil {
|
||||
t.Errorf("Addresses().Insert(%v, %v, %v) = %v; want nil", ctx, key, obj, err)
|
||||
}
|
||||
}
|
||||
// Get across versions.
|
||||
if obj, err := mock.AlphaAddresses().Get(ctx, *key); err != nil {
|
||||
if obj, err := mock.AlphaAddresses().Get(ctx, key); err != nil {
|
||||
t.Errorf("AlphaAddresses().Get(%v, %v) = %v, %v; want nil", ctx, key, obj, err)
|
||||
}
|
||||
if obj, err := mock.BetaAddresses().Get(ctx, *key); err != nil {
|
||||
if obj, err := mock.BetaAddresses().Get(ctx, key); err != nil {
|
||||
t.Errorf("BetaAddresses().Get(%v, %v) = %v, %v; want nil", ctx, key, obj, err)
|
||||
}
|
||||
if obj, err := mock.Addresses().Get(ctx, *key); err != nil {
|
||||
if obj, err := mock.Addresses().Get(ctx, key); err != nil {
|
||||
t.Errorf("Addresses().Get(%v, %v) = %v, %v; want nil", ctx, key, obj, err)
|
||||
}
|
||||
// List across versions.
|
||||
@ -128,23 +128,23 @@ func TestMocks(t *testing.T) {
|
||||
}
|
||||
}
|
||||
// Delete across versions.
|
||||
if err := mock.AlphaAddresses().Delete(ctx, *keyAlpha); err != nil {
|
||||
if err := mock.AlphaAddresses().Delete(ctx, keyAlpha); err != nil {
|
||||
t.Errorf("AlphaAddresses().Delete(%v, %v) = %v; want nil", ctx, key, err)
|
||||
}
|
||||
if err := mock.BetaAddresses().Delete(ctx, *keyBeta); err != nil {
|
||||
if err := mock.BetaAddresses().Delete(ctx, keyBeta); err != nil {
|
||||
t.Errorf("BetaAddresses().Delete(%v, %v) = %v; want nil", ctx, key, err)
|
||||
}
|
||||
if err := mock.Addresses().Delete(ctx, *keyGA); err != nil {
|
||||
if err := mock.Addresses().Delete(ctx, keyGA); err != nil {
|
||||
t.Errorf("Addresses().Delete(%v, %v) = %v; want nil", ctx, key, err)
|
||||
}
|
||||
// Delete not found.
|
||||
if err := mock.AlphaAddresses().Delete(ctx, *keyAlpha); err == nil {
|
||||
if err := mock.AlphaAddresses().Delete(ctx, keyAlpha); err == nil {
|
||||
t.Errorf("AlphaAddresses().Delete(%v, %v) = nil; want error", ctx, key)
|
||||
}
|
||||
if err := mock.BetaAddresses().Delete(ctx, *keyBeta); err == nil {
|
||||
if err := mock.BetaAddresses().Delete(ctx, keyBeta); err == nil {
|
||||
t.Errorf("BetaAddresses().Delete(%v, %v) = nil; want error", ctx, key)
|
||||
}
|
||||
if err := mock.Addresses().Delete(ctx, *keyGA); err == nil {
|
||||
if err := mock.Addresses().Delete(ctx, keyGA); err == nil {
|
||||
t.Errorf("Addresses().Delete(%v, %v) = nil; want error", ctx, key)
|
||||
}
|
||||
}
|
||||
|
@ -142,7 +142,7 @@ func copyViaJSON(dest, src interface{}) error {
|
||||
}
|
||||
|
||||
// SelfLink returns the self link URL for the given object.
|
||||
func SelfLink(ver meta.Version, project, resource string, key meta.Key) string {
|
||||
func SelfLink(ver meta.Version, project, resource string, key *meta.Key) string {
|
||||
var prefix string
|
||||
switch ver {
|
||||
case meta.VersionAlpha:
|
||||
|
@ -165,28 +165,28 @@ func TestSelfLink(t *testing.T) {
|
||||
ver meta.Version
|
||||
project string
|
||||
resource string
|
||||
key meta.Key
|
||||
key *meta.Key
|
||||
want string
|
||||
}{
|
||||
{
|
||||
meta.VersionAlpha,
|
||||
"proj1",
|
||||
"addresses",
|
||||
*meta.RegionalKey("key1", "us-central1"),
|
||||
meta.RegionalKey("key1", "us-central1"),
|
||||
"https://www.googleapis.com/compute/alpha/projects/proj1/regions/us-central1/addresses/key1",
|
||||
},
|
||||
{
|
||||
meta.VersionBeta,
|
||||
"proj3",
|
||||
"disks",
|
||||
*meta.ZonalKey("key2", "us-central1-b"),
|
||||
meta.ZonalKey("key2", "us-central1-b"),
|
||||
"https://www.googleapis.com/compute/beta/projects/proj3/zones/us-central1-b/disks/key2",
|
||||
},
|
||||
{
|
||||
meta.VersionGA,
|
||||
"proj4",
|
||||
"urlMaps",
|
||||
*meta.GlobalKey("key3"),
|
||||
meta.GlobalKey("key3"),
|
||||
"https://www.googleapis.com/compute/v1/projects/proj4/urlMaps/key3",
|
||||
},
|
||||
} {
|
||||
|
Loading…
Reference in New Issue
Block a user