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  }