blob: e9ce243c4d6a18cd05e29a2cd29cf7e388e62b16 [file] [log] [blame]
Jiri Simsa5293dcb2014-05-10 09:56:38 -07001package ipc
2
3import (
4 "errors"
5 "fmt"
Jiri Simsa5293dcb2014-05-10 09:56:38 -07006 "sync"
7
Jiri Simsa764efb72014-12-25 20:57:03 -08008 "v.io/core/veyron2/context"
9 "v.io/core/veyron2/ipc"
10 "v.io/core/veyron2/security"
Benjamin Prosnitz0db77a22015-01-20 14:25:15 -080011 "v.io/core/veyron2/vdl/valconv"
Jiri Simsa764efb72014-12-25 20:57:03 -080012 "v.io/core/veyron2/vlog"
Todd Wang3425a902015-01-21 18:43:59 -080013 "v.io/core/veyron2/vom"
Jiri Simsa5293dcb2014-05-10 09:56:38 -070014)
15
16// NewSimpleClient creates a new mocked ipc client where the given map of method name
17// to outputs is used for evaluating the method calls.
18// It also adds some testing features such as counters for number of times a method is called
19func NewSimpleClient(methodsResults map[string][]interface{}) *SimpleMockClient {
20 return &SimpleMockClient{
21 results: methodsResults,
22 timesCalled: make(map[string]int),
23 }
24}
25
26// SimpleMockClient implements ipc.Client
27type SimpleMockClient struct {
28 // Protects timesCalled
29 sync.Mutex
30
31 // results is a map of method names to results
32 results map[string][]interface{}
33 // timesCalled is a counter for number of times StartCall is called on a specific method name
34 timesCalled map[string]int
35}
36
37// TimesCalled returns number of times the given method has been called.
38func (c *SimpleMockClient) TimesCalled(method string) int {
39 return c.timesCalled[method]
40}
41
42// IPCBindOpt Implements ipc.Client
Mehrdad Afsharicd9852b2014-09-26 11:07:35 -070043func (c *SimpleMockClient) IPCBindOpt() {
44 //nologcall
45}
Jiri Simsa5293dcb2014-05-10 09:56:38 -070046
47// StartCall Implements ipc.Client
Matt Rosencrantz4f8ac602014-12-29 14:42:48 -080048func (c *SimpleMockClient) StartCall(ctx *context.T, name, method string, args []interface{}, opts ...ipc.CallOpt) (ipc.Call, error) {
Mehrdad Afsharicd9852b2014-09-26 11:07:35 -070049 defer vlog.LogCall()()
Jiri Simsa5293dcb2014-05-10 09:56:38 -070050 results, ok := c.results[method]
51 if !ok {
52 return nil, errors.New(fmt.Sprintf("method %s not found", method))
53 }
54
Benjamin Prosnitz0db77a22015-01-20 14:25:15 -080055 // Copy the results so that they can be modified without effecting the original.
56 // This must be done via vom encode and decode rather than a direct deep copy because (among other reasons)
57 // reflect-based deep copy on vdl.Type objects will fail because of their private fields. This is not a problem with vom
58 // as it manually creates the type objects. It is also more realistic to use the same mechanism as the ultimate calls.
Todd Wang3425a902015-01-21 18:43:59 -080059 vomBytes, err := vom.Encode(results)
Benjamin Prosnitz0db77a22015-01-20 14:25:15 -080060 if err != nil {
61 panic(fmt.Sprintf("Error copying value with vom (failed on encode): %v", err))
62 }
63 var copiedResults []interface{}
Todd Wang3425a902015-01-21 18:43:59 -080064 if err := vom.Decode(vomBytes, &copiedResults); err != nil {
Benjamin Prosnitz0db77a22015-01-20 14:25:15 -080065 panic(fmt.Sprintf("Error copying value with vom (failed on decode): %v", err))
66 }
67
Jiri Simsa5293dcb2014-05-10 09:56:38 -070068 clientCall := mockCall{
Benjamin Prosnitz0db77a22015-01-20 14:25:15 -080069 results: copiedResults,
Jiri Simsa5293dcb2014-05-10 09:56:38 -070070 }
71
72 c.Lock()
73 c.timesCalled[method]++
74 c.Unlock()
75
76 return &clientCall, nil
77}
78
Asim Shankar2d731a92014-09-29 17:46:38 -070079// Close implements ipc.Client
Jiri Simsa5293dcb2014-05-10 09:56:38 -070080func (*SimpleMockClient) Close() {
Mehrdad Afsharicd9852b2014-09-26 11:07:35 -070081 defer vlog.LogCall()()
Jiri Simsa5293dcb2014-05-10 09:56:38 -070082}
83
Matt Rosencrantzf5afcaf2014-06-02 11:31:22 -070084// mockCall implements ipc.Call
Jiri Simsa5293dcb2014-05-10 09:56:38 -070085type mockCall struct {
86 mockStream
87 results []interface{}
88}
89
Matt Rosencrantzf5afcaf2014-06-02 11:31:22 -070090// Cancel implements ipc.Call
Jiri Simsa5293dcb2014-05-10 09:56:38 -070091func (*mockCall) Cancel() {
Mehrdad Afsharicd9852b2014-09-26 11:07:35 -070092 defer vlog.LogCall()()
Jiri Simsa5293dcb2014-05-10 09:56:38 -070093}
94
Matt Rosencrantzf5afcaf2014-06-02 11:31:22 -070095// CloseSend implements ipc.Call
Jiri Simsa5293dcb2014-05-10 09:56:38 -070096func (*mockCall) CloseSend() error {
Mehrdad Afsharicd9852b2014-09-26 11:07:35 -070097 defer vlog.LogCall()()
Jiri Simsa5293dcb2014-05-10 09:56:38 -070098 return nil
99}
100
Matt Rosencrantzf5afcaf2014-06-02 11:31:22 -0700101// Finish implements ipc.Call
Jiri Simsa5293dcb2014-05-10 09:56:38 -0700102func (mc *mockCall) Finish(resultptrs ...interface{}) error {
Mehrdad Afsharicd9852b2014-09-26 11:07:35 -0700103 defer vlog.LogCall()()
Jiri Simsa5293dcb2014-05-10 09:56:38 -0700104 if got, want := len(resultptrs), len(mc.results); got != want {
105 return errors.New(fmt.Sprintf("wrong number of output results; expected resultptrs of size %d but got %d", want, got))
106 }
107 for ax, res := range resultptrs {
108 if mc.results[ax] != nil {
Benjamin Prosnitz0db77a22015-01-20 14:25:15 -0800109 if err := valconv.Convert(res, mc.results[ax]); err != nil {
110 panic(fmt.Sprintf("Error converting out argument %#v: %v", mc.results[ax], err))
111 }
Jiri Simsa5293dcb2014-05-10 09:56:38 -0700112 }
113 }
Jiri Simsa5293dcb2014-05-10 09:56:38 -0700114 return nil
115}
116
Asim Shankar2d731a92014-09-29 17:46:38 -0700117// RemoteBlessings implements ipc.Call
118func (*mockCall) RemoteBlessings() ([]string, security.Blessings) {
119 return []string{}, nil
120}
121
Jiri Simsa5293dcb2014-05-10 09:56:38 -0700122//mockStream implements ipc.Stream
123type mockStream struct{}
124
125//Send implements ipc.Stream
126func (*mockStream) Send(interface{}) error {
Mehrdad Afsharicd9852b2014-09-26 11:07:35 -0700127 defer vlog.LogCall()()
Jiri Simsa5293dcb2014-05-10 09:56:38 -0700128 return nil
129}
130
131//Recv implements ipc.Stream
132func (*mockStream) Recv(interface{}) error {
Mehrdad Afsharicd9852b2014-09-26 11:07:35 -0700133 defer vlog.LogCall()()
Jiri Simsa5293dcb2014-05-10 09:56:38 -0700134 return nil
135}