github.com/mattyw/juju@v0.0.0-20140610034352-732aecd63861/state/apiserver/root_test.go (about) 1 // Copyright 2012, 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package apiserver_test 5 6 import ( 7 "fmt" 8 "reflect" 9 "time" 10 11 jc "github.com/juju/testing/checkers" 12 gc "launchpad.net/gocheck" 13 14 "github.com/juju/juju/rpc/rpcreflect" 15 "github.com/juju/juju/state/apiserver" 16 "github.com/juju/juju/testing" 17 ) 18 19 type rootSuite struct{} 20 21 var _ = gc.Suite(&rootSuite{}) 22 23 var allowedDiscardedMethods = []string{ 24 "AuthClient", 25 "AuthEnvironManager", 26 "AuthMachineAgent", 27 "AuthOwner", 28 "AuthUnitAgent", 29 "GetAuthEntity", 30 "GetAuthTag", 31 } 32 33 func (*rootSuite) TestDiscardedAPIMethods(c *gc.C) { 34 t := rpcreflect.TypeOf(apiserver.RootType) 35 // We must have some root-level methods. 36 c.Assert(t.MethodNames(), gc.Not(gc.HasLen), 0) 37 c.Assert(t.DiscardedMethods(), gc.DeepEquals, allowedDiscardedMethods) 38 39 for _, name := range t.MethodNames() { 40 m, err := t.Method(name) 41 c.Assert(err, gc.IsNil) 42 // We must have some methods on every object returned 43 // by a root-level method. 44 c.Assert(m.ObjType.MethodNames(), gc.Not(gc.HasLen), 0) 45 // We don't allow any methods that don't implement 46 // an RPC entry point. 47 c.Assert(m.ObjType.DiscardedMethods(), gc.HasLen, 0) 48 } 49 } 50 51 func (r *rootSuite) TestPingTimeout(c *gc.C) { 52 closedc := make(chan time.Time, 1) 53 action := func() { 54 closedc <- time.Now() 55 } 56 timeout := apiserver.NewPingTimeout(action, 50*time.Millisecond) 57 for i := 0; i < 2; i++ { 58 time.Sleep(10 * time.Millisecond) 59 timeout.Ping() 60 } 61 // Expect action to be executed about 50ms after last ping. 62 broken := time.Now() 63 var closed time.Time 64 select { 65 case closed = <-closedc: 66 case <-time.After(testing.LongWait): 67 c.Fatalf("action never executed") 68 } 69 closeDiff := closed.Sub(broken) / time.Millisecond 70 c.Assert(50 <= closeDiff && closeDiff <= 100, gc.Equals, true) 71 } 72 73 func (r *rootSuite) TestPingTimeoutStopped(c *gc.C) { 74 closedc := make(chan time.Time, 1) 75 action := func() { 76 closedc <- time.Now() 77 } 78 timeout := apiserver.NewPingTimeout(action, 20*time.Millisecond) 79 timeout.Ping() 80 timeout.Stop() 81 // The action should never trigger 82 select { 83 case <-closedc: 84 c.Fatalf("action triggered after Stop()") 85 case <-time.After(testing.ShortWait): 86 } 87 } 88 89 type errRootSuite struct { 90 testing.BaseSuite 91 } 92 93 var _ = gc.Suite(&errRootSuite{}) 94 95 func (s *errRootSuite) TestErrorRoot(c *gc.C) { 96 origErr := fmt.Errorf("my custom error") 97 errRoot := apiserver.NewErrRoot(origErr) 98 st, err := errRoot.Admin("") 99 c.Check(st, gc.IsNil) 100 c.Check(err, gc.Equals, origErr) 101 } 102 103 func (s *errRootSuite) TestErrorRootViaRPC(c *gc.C) { 104 origErr := fmt.Errorf("my custom error") 105 errRoot := apiserver.NewErrRoot(origErr) 106 val := rpcreflect.ValueOf(reflect.ValueOf(errRoot)) 107 caller, err := val.MethodCaller("Admin", "Login") 108 c.Assert(err, gc.IsNil) 109 resp, err := caller.Call("", reflect.Value{}) 110 c.Check(err, gc.Equals, origErr) 111 c.Check(resp.IsValid(), jc.IsFalse) 112 }