blob: f0caf010bd7f79316d4e9eaa740eb56917140d4b [file] [log] [blame]
package lib
import (
"reflect"
"testing"
mocks_ipc "veyron/runtimes/google/testing/mocks/ipc"
"veyron2/ipc"
"veyron2/rt"
"veyron2/vdl/vdlutil"
"veyron2/wiretype"
)
const (
name = "/veyron/name"
)
func init() {
rt.Init()
}
func expectedSignature() ipc.ServiceSignature {
return ipc.ServiceSignature{
Methods: make(map[string]ipc.MethodSignature),
TypeDefs: []vdlutil.Any{
wiretype.NamedPrimitiveType{
Name: "veyron2/vdlutil.AnyData",
Type: wiretype.TypeIDInterface,
},
},
}
}
func client() *mocks_ipc.SimpleMockClient {
return mocks_ipc.NewSimpleClient(
map[string][]interface{}{
"Signature": []interface{}{expectedSignature(), nil},
},
)
}
func assertMethodSignatureAsExpected(t *testing.T, got, expected ipc.MethodSignature) {
if !reflect.DeepEqual(got.InArgs, expected.InArgs) {
t.Errorf(`InArgs do not match: result "%v", want "%v"`, got.InArgs, expected.InArgs)
return
}
if !reflect.DeepEqual(got.OutArgs, expected.OutArgs) {
t.Errorf(`OutArgs do not match: result "%v", want "%v"`, got.OutArgs, expected.OutArgs)
return
}
if got.InStream != expected.InStream {
t.Errorf(`InStreams do not match: result "%v", want "%v"`, got.InStream, expected.InStream)
return
}
if got.OutStream != expected.OutStream {
t.Errorf(`OutStream do not match: result "%v", want "%v"`, got.OutStream, expected.OutStream)
return
}
}
func assertSignatureAsExpected(t *testing.T, got, expected *ipc.ServiceSignature) {
if !reflect.DeepEqual(got.TypeDefs, expected.TypeDefs) {
t.Errorf(`TypeDefs do not match: result "%v", want "%v"`, got.TypeDefs, expected.TypeDefs)
return
}
if n, m := len(got.Methods), len(expected.Methods); n != m {
t.Errorf(`Wrong number of signature methods: result "%d", want "%d"`, n, m)
return
}
for gotName, gotMethod := range got.Methods {
expectedMethod, ok := expected.Methods[gotName]
if !ok {
t.Errorf(`Method "%v" was expected but not found`, gotName)
return
}
assertMethodSignatureAsExpected(t, gotMethod, expectedMethod)
}
}
func TestFetching(t *testing.T) {
sm := NewSignatureManager()
got, err := sm.Signature(rt.R().NewContext(), name, client())
if err != nil {
t.Errorf(`Did not expect an error but got %v`, err)
return
}
expected := expectedSignature()
assertSignatureAsExpected(t, got, &expected)
}
func TestThatCachedAfterFetching(t *testing.T) {
sm := NewSignatureManager().(*signatureManager)
sig, _ := sm.Signature(rt.R().NewContext(), name, client())
cache, ok := sm.cache[name]
if !ok {
t.Errorf(`Signature manager did not cache the results`)
return
}
assertSignatureAsExpected(t, &cache.signature, sig)
}
func TestThatCacheIsUsed(t *testing.T) {
client := client()
sm := NewSignatureManager()
// call twice
sm.Signature(rt.R().NewContext(), name, client)
sm.Signature(rt.R().NewContext(), name, client)
// expect number of calls to Signature method of client to still be 1 since cache
// should have been used despite the second call
if client.TimesCalled("Signature") != 1 {
t.Errorf("Signature cache was not used for the second call")
}
}
func TestThatLastAccessedGetUpdated(t *testing.T) {
client := client()
sm := NewSignatureManager().(*signatureManager)
sm.Signature(rt.R().NewContext(), name, client)
// make last accessed be in the past to account for the fact that
// two consecutive calls to time.Now() can return identical values.
sm.cache[name].lastAccessed = sm.cache[name].lastAccessed.Add(-ttl / 2)
prevAccess := sm.cache[name].lastAccessed
// access again
sm.Signature(rt.R().NewContext(), name, client)
newAccess := sm.cache[name].lastAccessed
if !newAccess.After(prevAccess) {
t.Errorf("LastAccessed was not updated for cache entry")
}
}
func TestThatTTLExpires(t *testing.T) {
client := client()
sm := NewSignatureManager().(*signatureManager)
sm.Signature(rt.R().NewContext(), name, client)
// make last accessed go over the ttl
sm.cache[name].lastAccessed = sm.cache[name].lastAccessed.Add(-2 * ttl)
// make a second call
sm.Signature(rt.R().NewContext(), name, client)
// expect number of calls to Signature method of client to be 2 since cache should have expired
if client.TimesCalled("Signature") != 2 {
t.Errorf("Cache was still used but TTL had passed. It should have been fetched again")
}
}