github.com/timstclair/heapster@v0.20.0-alpha1/Godeps/_workspace/src/google.golang.org/appengine/internal/aetesting/fake.go (about) 1 // Copyright 2011 Google Inc. All rights reserved. 2 // Use of this source code is governed by the Apache 2.0 3 // license that can be found in the LICENSE file. 4 5 // Package aetesting provides utilities for testing App Engine packages. 6 // This is not for testing user applications. 7 package aetesting 8 9 import ( 10 "fmt" 11 "reflect" 12 "testing" 13 14 "github.com/golang/protobuf/proto" 15 "golang.org/x/net/context" 16 17 "google.golang.org/appengine/internal" 18 ) 19 20 // FakeSingleContext returns a context whose Call invocations will be serviced 21 // by f, which should be a function that has two arguments of the input and output 22 // protocol buffer type, and one error return. 23 func FakeSingleContext(t *testing.T, service, method string, f interface{}) context.Context { 24 fv := reflect.ValueOf(f) 25 if fv.Kind() != reflect.Func { 26 t.Fatal("not a function") 27 } 28 ft := fv.Type() 29 if ft.NumIn() != 2 || ft.NumOut() != 1 { 30 t.Fatalf("f has %d in and %d out, want 2 in and 1 out", ft.NumIn(), ft.NumOut()) 31 } 32 for i := 0; i < 2; i++ { 33 at := ft.In(i) 34 if !at.Implements(protoMessageType) { 35 t.Fatalf("arg %d does not implement proto.Message", i) 36 } 37 } 38 if ft.Out(0) != errorType { 39 t.Fatalf("f's return is %v, want error", ft.Out(0)) 40 } 41 s := &single{ 42 t: t, 43 service: service, 44 method: method, 45 f: fv, 46 } 47 return internal.WithCallOverride(context.Background(), s.call) 48 } 49 50 var ( 51 protoMessageType = reflect.TypeOf((*proto.Message)(nil)).Elem() 52 errorType = reflect.TypeOf((*error)(nil)).Elem() 53 ) 54 55 type single struct { 56 t *testing.T 57 service, method string 58 f reflect.Value 59 } 60 61 func (s *single) call(ctx context.Context, service, method string, in, out proto.Message) error { 62 if service == "__go__" { 63 if method == "GetNamespace" { 64 return nil // always yield an empty namespace 65 } 66 return fmt.Errorf("Unknown API call /%s.%s", service, method) 67 } 68 if service != s.service || method != s.method { 69 s.t.Fatalf("Unexpected call to /%s.%s", service, method) 70 } 71 ins := []reflect.Value{ 72 reflect.ValueOf(in), 73 reflect.ValueOf(out), 74 } 75 outs := s.f.Call(ins) 76 if outs[0].IsNil() { 77 return nil 78 } 79 return outs[0].Interface().(error) 80 }