Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
| ... | ... |
@@ -105,7 +105,7 @@ github.com/docker/containerd 9048e5e50717ea4497b757314bad98ea3763c145 |
| 105 | 105 |
github.com/tonistiigi/fifo 1405643975692217d6720f8b54aeee1bf2cd5cf4 |
| 106 | 106 |
|
| 107 | 107 |
# cluster |
| 108 |
-github.com/docker/swarmkit d2e48a332063ccd4ea26b6262ee717de997de560 |
|
| 108 |
+github.com/docker/swarmkit d5232280c510d70755ab11305d46a5704735371a |
|
| 109 | 109 |
github.com/golang/mock bd3c8e81be01eef76d4b503f5e687d2d1354d2d9 |
| 110 | 110 |
github.com/gogo/protobuf 8d70fb3182befc465c4a1eac8ad4d38ff49778e2 |
| 111 | 111 |
github.com/cloudflare/cfssl 7fb22c8cba7ecaf98e4082d22d65800cf45e042a |
| 112 | 112 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,75 @@ |
| 0 |
+package exec |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "github.com/docker/swarmkit/api" |
|
| 4 |
+ "golang.org/x/net/context" |
|
| 5 |
+ "runtime" |
|
| 6 |
+ "strings" |
|
| 7 |
+) |
|
| 8 |
+ |
|
| 9 |
+// StubController implements the Controller interface, |
|
| 10 |
+// but allows you to specify behaviors for each of its methods. |
|
| 11 |
+type StubController struct {
|
|
| 12 |
+ Controller |
|
| 13 |
+ UpdateFn func(ctx context.Context, t *api.Task) error |
|
| 14 |
+ PrepareFn func(ctx context.Context) error |
|
| 15 |
+ StartFn func(ctx context.Context) error |
|
| 16 |
+ WaitFn func(ctx context.Context) error |
|
| 17 |
+ ShutdownFn func(ctx context.Context) error |
|
| 18 |
+ TerminateFn func(ctx context.Context) error |
|
| 19 |
+ RemoveFn func(ctx context.Context) error |
|
| 20 |
+ CloseFn func() error |
|
| 21 |
+ calls map[string]int |
|
| 22 |
+ cstatus *api.ContainerStatus |
|
| 23 |
+} |
|
| 24 |
+ |
|
| 25 |
+// NewStubController returns an initialized StubController |
|
| 26 |
+func NewStubController() *StubController {
|
|
| 27 |
+ return &StubController{
|
|
| 28 |
+ calls: make(map[string]int), |
|
| 29 |
+ } |
|
| 30 |
+} |
|
| 31 |
+ |
|
| 32 |
+// If function A calls updateCountsForSelf, |
|
| 33 |
+// The callCount[A] value will be incremented |
|
| 34 |
+func (sc *StubController) called() {
|
|
| 35 |
+ pc, _, _, ok := runtime.Caller(1) |
|
| 36 |
+ if !ok {
|
|
| 37 |
+ panic("Failed to find caller of function")
|
|
| 38 |
+ } |
|
| 39 |
+ // longName looks like 'github.com/docker/swarmkit/agent/exec.(*StubController).Prepare:1' |
|
| 40 |
+ longName := runtime.FuncForPC(pc).Name() |
|
| 41 |
+ parts := strings.Split(longName, ".") |
|
| 42 |
+ tail := strings.Split(parts[len(parts)-1], ":") |
|
| 43 |
+ sc.calls[tail[0]]++ |
|
| 44 |
+} |
|
| 45 |
+ |
|
| 46 |
+// Update is part of the Controller interface |
|
| 47 |
+func (sc *StubController) Update(ctx context.Context, t *api.Task) error {
|
|
| 48 |
+ sc.called() |
|
| 49 |
+ return sc.UpdateFn(ctx, t) |
|
| 50 |
+} |
|
| 51 |
+ |
|
| 52 |
+// Prepare is part of the Controller interface |
|
| 53 |
+func (sc *StubController) Prepare(ctx context.Context) error { sc.called(); return sc.PrepareFn(ctx) }
|
|
| 54 |
+ |
|
| 55 |
+// Start is part of the Controller interface |
|
| 56 |
+func (sc *StubController) Start(ctx context.Context) error { sc.called(); return sc.StartFn(ctx) }
|
|
| 57 |
+ |
|
| 58 |
+// Wait is part of the Controller interface |
|
| 59 |
+func (sc *StubController) Wait(ctx context.Context) error { sc.called(); return sc.WaitFn(ctx) }
|
|
| 60 |
+ |
|
| 61 |
+// Shutdown is part of the Controller interface |
|
| 62 |
+func (sc *StubController) Shutdown(ctx context.Context) error { sc.called(); return sc.ShutdownFn(ctx) }
|
|
| 63 |
+ |
|
| 64 |
+// Terminate is part of the Controller interface |
|
| 65 |
+func (sc *StubController) Terminate(ctx context.Context) error {
|
|
| 66 |
+ sc.called() |
|
| 67 |
+ return sc.TerminateFn(ctx) |
|
| 68 |
+} |
|
| 69 |
+ |
|
| 70 |
+// Remove is part of the Controller interface |
|
| 71 |
+func (sc *StubController) Remove(ctx context.Context) error { sc.called(); return sc.RemoveFn(ctx) }
|
|
| 72 |
+ |
|
| 73 |
+// Close is part of the Controller interface |
|
| 74 |
+func (sc *StubController) Close() error { sc.called(); return sc.CloseFn() }
|
| 0 | 75 |
deleted file mode 100644 |
| ... | ... |
@@ -1,270 +0,0 @@ |
| 1 |
-// Automatically generated by MockGen. DO NOT EDIT! |
|
| 2 |
-// Source: controller.go |
|
| 3 |
- |
|
| 4 |
-package exec |
|
| 5 |
- |
|
| 6 |
-import ( |
|
| 7 |
- api "github.com/docker/swarmkit/api" |
|
| 8 |
- gomock "github.com/golang/mock/gomock" |
|
| 9 |
- context "golang.org/x/net/context" |
|
| 10 |
-) |
|
| 11 |
- |
|
| 12 |
-// Mock of Controller interface |
|
| 13 |
-type MockController struct {
|
|
| 14 |
- ctrl *gomock.Controller |
|
| 15 |
- recorder *_MockControllerRecorder |
|
| 16 |
-} |
|
| 17 |
- |
|
| 18 |
-// Recorder for MockController (not exported) |
|
| 19 |
-type _MockControllerRecorder struct {
|
|
| 20 |
- mock *MockController |
|
| 21 |
-} |
|
| 22 |
- |
|
| 23 |
-func NewMockController(ctrl *gomock.Controller) *MockController {
|
|
| 24 |
- mock := &MockController{ctrl: ctrl}
|
|
| 25 |
- mock.recorder = &_MockControllerRecorder{mock}
|
|
| 26 |
- return mock |
|
| 27 |
-} |
|
| 28 |
- |
|
| 29 |
-func (_m *MockController) EXPECT() *_MockControllerRecorder {
|
|
| 30 |
- return _m.recorder |
|
| 31 |
-} |
|
| 32 |
- |
|
| 33 |
-func (_m *MockController) Update(ctx context.Context, t *api.Task) error {
|
|
| 34 |
- ret := _m.ctrl.Call(_m, "Update", ctx, t) |
|
| 35 |
- ret0, _ := ret[0].(error) |
|
| 36 |
- return ret0 |
|
| 37 |
-} |
|
| 38 |
- |
|
| 39 |
-func (_mr *_MockControllerRecorder) Update(arg0, arg1 interface{}) *gomock.Call {
|
|
| 40 |
- return _mr.mock.ctrl.RecordCall(_mr.mock, "Update", arg0, arg1) |
|
| 41 |
-} |
|
| 42 |
- |
|
| 43 |
-func (_m *MockController) Prepare(ctx context.Context) error {
|
|
| 44 |
- ret := _m.ctrl.Call(_m, "Prepare", ctx) |
|
| 45 |
- ret0, _ := ret[0].(error) |
|
| 46 |
- return ret0 |
|
| 47 |
-} |
|
| 48 |
- |
|
| 49 |
-func (_mr *_MockControllerRecorder) Prepare(arg0 interface{}) *gomock.Call {
|
|
| 50 |
- return _mr.mock.ctrl.RecordCall(_mr.mock, "Prepare", arg0) |
|
| 51 |
-} |
|
| 52 |
- |
|
| 53 |
-func (_m *MockController) Start(ctx context.Context) error {
|
|
| 54 |
- ret := _m.ctrl.Call(_m, "Start", ctx) |
|
| 55 |
- ret0, _ := ret[0].(error) |
|
| 56 |
- return ret0 |
|
| 57 |
-} |
|
| 58 |
- |
|
| 59 |
-func (_mr *_MockControllerRecorder) Start(arg0 interface{}) *gomock.Call {
|
|
| 60 |
- return _mr.mock.ctrl.RecordCall(_mr.mock, "Start", arg0) |
|
| 61 |
-} |
|
| 62 |
- |
|
| 63 |
-func (_m *MockController) Wait(ctx context.Context) error {
|
|
| 64 |
- ret := _m.ctrl.Call(_m, "Wait", ctx) |
|
| 65 |
- ret0, _ := ret[0].(error) |
|
| 66 |
- return ret0 |
|
| 67 |
-} |
|
| 68 |
- |
|
| 69 |
-func (_mr *_MockControllerRecorder) Wait(arg0 interface{}) *gomock.Call {
|
|
| 70 |
- return _mr.mock.ctrl.RecordCall(_mr.mock, "Wait", arg0) |
|
| 71 |
-} |
|
| 72 |
- |
|
| 73 |
-func (_m *MockController) Shutdown(ctx context.Context) error {
|
|
| 74 |
- ret := _m.ctrl.Call(_m, "Shutdown", ctx) |
|
| 75 |
- ret0, _ := ret[0].(error) |
|
| 76 |
- return ret0 |
|
| 77 |
-} |
|
| 78 |
- |
|
| 79 |
-func (_mr *_MockControllerRecorder) Shutdown(arg0 interface{}) *gomock.Call {
|
|
| 80 |
- return _mr.mock.ctrl.RecordCall(_mr.mock, "Shutdown", arg0) |
|
| 81 |
-} |
|
| 82 |
- |
|
| 83 |
-func (_m *MockController) Terminate(ctx context.Context) error {
|
|
| 84 |
- ret := _m.ctrl.Call(_m, "Terminate", ctx) |
|
| 85 |
- ret0, _ := ret[0].(error) |
|
| 86 |
- return ret0 |
|
| 87 |
-} |
|
| 88 |
- |
|
| 89 |
-func (_mr *_MockControllerRecorder) Terminate(arg0 interface{}) *gomock.Call {
|
|
| 90 |
- return _mr.mock.ctrl.RecordCall(_mr.mock, "Terminate", arg0) |
|
| 91 |
-} |
|
| 92 |
- |
|
| 93 |
-func (_m *MockController) Remove(ctx context.Context) error {
|
|
| 94 |
- ret := _m.ctrl.Call(_m, "Remove", ctx) |
|
| 95 |
- ret0, _ := ret[0].(error) |
|
| 96 |
- return ret0 |
|
| 97 |
-} |
|
| 98 |
- |
|
| 99 |
-func (_mr *_MockControllerRecorder) Remove(arg0 interface{}) *gomock.Call {
|
|
| 100 |
- return _mr.mock.ctrl.RecordCall(_mr.mock, "Remove", arg0) |
|
| 101 |
-} |
|
| 102 |
- |
|
| 103 |
-func (_m *MockController) Close() error {
|
|
| 104 |
- ret := _m.ctrl.Call(_m, "Close") |
|
| 105 |
- ret0, _ := ret[0].(error) |
|
| 106 |
- return ret0 |
|
| 107 |
-} |
|
| 108 |
- |
|
| 109 |
-func (_mr *_MockControllerRecorder) Close() *gomock.Call {
|
|
| 110 |
- return _mr.mock.ctrl.RecordCall(_mr.mock, "Close") |
|
| 111 |
-} |
|
| 112 |
- |
|
| 113 |
-// Mock of ControllerLogs interface |
|
| 114 |
-type MockControllerLogs struct {
|
|
| 115 |
- ctrl *gomock.Controller |
|
| 116 |
- recorder *_MockControllerLogsRecorder |
|
| 117 |
-} |
|
| 118 |
- |
|
| 119 |
-// Recorder for MockControllerLogs (not exported) |
|
| 120 |
-type _MockControllerLogsRecorder struct {
|
|
| 121 |
- mock *MockControllerLogs |
|
| 122 |
-} |
|
| 123 |
- |
|
| 124 |
-func NewMockControllerLogs(ctrl *gomock.Controller) *MockControllerLogs {
|
|
| 125 |
- mock := &MockControllerLogs{ctrl: ctrl}
|
|
| 126 |
- mock.recorder = &_MockControllerLogsRecorder{mock}
|
|
| 127 |
- return mock |
|
| 128 |
-} |
|
| 129 |
- |
|
| 130 |
-func (_m *MockControllerLogs) EXPECT() *_MockControllerLogsRecorder {
|
|
| 131 |
- return _m.recorder |
|
| 132 |
-} |
|
| 133 |
- |
|
| 134 |
-func (_m *MockControllerLogs) Logs(ctx context.Context, publisher LogPublisher, options api.LogSubscriptionOptions) error {
|
|
| 135 |
- ret := _m.ctrl.Call(_m, "Logs", ctx, publisher, options) |
|
| 136 |
- ret0, _ := ret[0].(error) |
|
| 137 |
- return ret0 |
|
| 138 |
-} |
|
| 139 |
- |
|
| 140 |
-func (_mr *_MockControllerLogsRecorder) Logs(arg0, arg1, arg2 interface{}) *gomock.Call {
|
|
| 141 |
- return _mr.mock.ctrl.RecordCall(_mr.mock, "Logs", arg0, arg1, arg2) |
|
| 142 |
-} |
|
| 143 |
- |
|
| 144 |
-// Mock of LogPublisher interface |
|
| 145 |
-type MockLogPublisher struct {
|
|
| 146 |
- ctrl *gomock.Controller |
|
| 147 |
- recorder *_MockLogPublisherRecorder |
|
| 148 |
-} |
|
| 149 |
- |
|
| 150 |
-// Recorder for MockLogPublisher (not exported) |
|
| 151 |
-type _MockLogPublisherRecorder struct {
|
|
| 152 |
- mock *MockLogPublisher |
|
| 153 |
-} |
|
| 154 |
- |
|
| 155 |
-func NewMockLogPublisher(ctrl *gomock.Controller) *MockLogPublisher {
|
|
| 156 |
- mock := &MockLogPublisher{ctrl: ctrl}
|
|
| 157 |
- mock.recorder = &_MockLogPublisherRecorder{mock}
|
|
| 158 |
- return mock |
|
| 159 |
-} |
|
| 160 |
- |
|
| 161 |
-func (_m *MockLogPublisher) EXPECT() *_MockLogPublisherRecorder {
|
|
| 162 |
- return _m.recorder |
|
| 163 |
-} |
|
| 164 |
- |
|
| 165 |
-func (_m *MockLogPublisher) Publish(ctx context.Context, message api.LogMessage) error {
|
|
| 166 |
- ret := _m.ctrl.Call(_m, "Publish", ctx, message) |
|
| 167 |
- ret0, _ := ret[0].(error) |
|
| 168 |
- return ret0 |
|
| 169 |
-} |
|
| 170 |
- |
|
| 171 |
-func (_mr *_MockLogPublisherRecorder) Publish(arg0, arg1 interface{}) *gomock.Call {
|
|
| 172 |
- return _mr.mock.ctrl.RecordCall(_mr.mock, "Publish", arg0, arg1) |
|
| 173 |
-} |
|
| 174 |
- |
|
| 175 |
-// Mock of LogPublisherProvider interface |
|
| 176 |
-type MockLogPublisherProvider struct {
|
|
| 177 |
- ctrl *gomock.Controller |
|
| 178 |
- recorder *_MockLogPublisherProviderRecorder |
|
| 179 |
-} |
|
| 180 |
- |
|
| 181 |
-// Recorder for MockLogPublisherProvider (not exported) |
|
| 182 |
-type _MockLogPublisherProviderRecorder struct {
|
|
| 183 |
- mock *MockLogPublisherProvider |
|
| 184 |
-} |
|
| 185 |
- |
|
| 186 |
-func NewMockLogPublisherProvider(ctrl *gomock.Controller) *MockLogPublisherProvider {
|
|
| 187 |
- mock := &MockLogPublisherProvider{ctrl: ctrl}
|
|
| 188 |
- mock.recorder = &_MockLogPublisherProviderRecorder{mock}
|
|
| 189 |
- return mock |
|
| 190 |
-} |
|
| 191 |
- |
|
| 192 |
-func (_m *MockLogPublisherProvider) EXPECT() *_MockLogPublisherProviderRecorder {
|
|
| 193 |
- return _m.recorder |
|
| 194 |
-} |
|
| 195 |
- |
|
| 196 |
-func (_m *MockLogPublisherProvider) Publisher(ctx context.Context, subscriptionID string) (LogPublisher, func(), error) {
|
|
| 197 |
- ret := _m.ctrl.Call(_m, "Publisher", ctx, subscriptionID) |
|
| 198 |
- ret0, _ := ret[0].(LogPublisher) |
|
| 199 |
- ret1, _ := ret[1].(func()) |
|
| 200 |
- ret2, _ := ret[2].(error) |
|
| 201 |
- return ret0, ret1, ret2 |
|
| 202 |
-} |
|
| 203 |
- |
|
| 204 |
-func (_mr *_MockLogPublisherProviderRecorder) Publisher(arg0, arg1 interface{}) *gomock.Call {
|
|
| 205 |
- return _mr.mock.ctrl.RecordCall(_mr.mock, "Publisher", arg0, arg1) |
|
| 206 |
-} |
|
| 207 |
- |
|
| 208 |
-// Mock of ContainerStatuser interface |
|
| 209 |
-type MockContainerStatuser struct {
|
|
| 210 |
- ctrl *gomock.Controller |
|
| 211 |
- recorder *_MockContainerStatuserRecorder |
|
| 212 |
-} |
|
| 213 |
- |
|
| 214 |
-// Recorder for MockContainerStatuser (not exported) |
|
| 215 |
-type _MockContainerStatuserRecorder struct {
|
|
| 216 |
- mock *MockContainerStatuser |
|
| 217 |
-} |
|
| 218 |
- |
|
| 219 |
-func NewMockContainerStatuser(ctrl *gomock.Controller) *MockContainerStatuser {
|
|
| 220 |
- mock := &MockContainerStatuser{ctrl: ctrl}
|
|
| 221 |
- mock.recorder = &_MockContainerStatuserRecorder{mock}
|
|
| 222 |
- return mock |
|
| 223 |
-} |
|
| 224 |
- |
|
| 225 |
-func (_m *MockContainerStatuser) EXPECT() *_MockContainerStatuserRecorder {
|
|
| 226 |
- return _m.recorder |
|
| 227 |
-} |
|
| 228 |
- |
|
| 229 |
-func (_m *MockContainerStatuser) ContainerStatus(ctx context.Context) (*api.ContainerStatus, error) {
|
|
| 230 |
- ret := _m.ctrl.Call(_m, "ContainerStatus", ctx) |
|
| 231 |
- ret0, _ := ret[0].(*api.ContainerStatus) |
|
| 232 |
- ret1, _ := ret[1].(error) |
|
| 233 |
- return ret0, ret1 |
|
| 234 |
-} |
|
| 235 |
- |
|
| 236 |
-func (_mr *_MockContainerStatuserRecorder) ContainerStatus(arg0 interface{}) *gomock.Call {
|
|
| 237 |
- return _mr.mock.ctrl.RecordCall(_mr.mock, "ContainerStatus", arg0) |
|
| 238 |
-} |
|
| 239 |
- |
|
| 240 |
-// Mock of PortStatuser interface |
|
| 241 |
-type MockPortStatuser struct {
|
|
| 242 |
- ctrl *gomock.Controller |
|
| 243 |
- recorder *_MockPortStatuserRecorder |
|
| 244 |
-} |
|
| 245 |
- |
|
| 246 |
-// Recorder for MockPortStatuser (not exported) |
|
| 247 |
-type _MockPortStatuserRecorder struct {
|
|
| 248 |
- mock *MockPortStatuser |
|
| 249 |
-} |
|
| 250 |
- |
|
| 251 |
-func NewMockPortStatuser(ctrl *gomock.Controller) *MockPortStatuser {
|
|
| 252 |
- mock := &MockPortStatuser{ctrl: ctrl}
|
|
| 253 |
- mock.recorder = &_MockPortStatuserRecorder{mock}
|
|
| 254 |
- return mock |
|
| 255 |
-} |
|
| 256 |
- |
|
| 257 |
-func (_m *MockPortStatuser) EXPECT() *_MockPortStatuserRecorder {
|
|
| 258 |
- return _m.recorder |
|
| 259 |
-} |
|
| 260 |
- |
|
| 261 |
-func (_m *MockPortStatuser) PortStatus(ctx context.Context) (*api.PortStatus, error) {
|
|
| 262 |
- ret := _m.ctrl.Call(_m, "PortStatus", ctx) |
|
| 263 |
- ret0, _ := ret[0].(*api.PortStatus) |
|
| 264 |
- ret1, _ := ret[1].(error) |
|
| 265 |
- return ret0, ret1 |
|
| 266 |
-} |
|
| 267 |
- |
|
| 268 |
-func (_mr *_MockPortStatuserRecorder) PortStatus(arg0 interface{}) *gomock.Call {
|
|
| 269 |
- return _mr.mock.ctrl.RecordCall(_mr.mock, "PortStatus", arg0) |
|
| 270 |
-} |
| ... | ... |
@@ -148,8 +148,6 @@ func New(cluster Cluster, c *Config) *Dispatcher {
|
| 148 | 148 |
downNodes: newNodeStore(defaultNodeDownPeriod, 0, 1, 0), |
| 149 | 149 |
store: cluster.MemoryStore(), |
| 150 | 150 |
cluster: cluster, |
| 151 |
- taskUpdates: make(map[string]*api.TaskStatus), |
|
| 152 |
- nodeUpdates: make(map[string]nodeUpdate), |
|
| 153 | 151 |
processUpdatesTrigger: make(chan struct{}, 1),
|
| 154 | 152 |
config: c, |
| 155 | 153 |
} |
| ... | ... |
@@ -181,6 +179,14 @@ func getWeightedPeers(cluster Cluster) []*api.WeightedPeer {
|
| 181 | 181 |
// Run runs dispatcher tasks which should be run on leader dispatcher. |
| 182 | 182 |
// Dispatcher can be stopped with cancelling ctx or calling Stop(). |
| 183 | 183 |
func (d *Dispatcher) Run(ctx context.Context) error {
|
| 184 |
+ d.taskUpdatesLock.Lock() |
|
| 185 |
+ d.taskUpdates = make(map[string]*api.TaskStatus) |
|
| 186 |
+ d.taskUpdatesLock.Unlock() |
|
| 187 |
+ |
|
| 188 |
+ d.nodeUpdatesLock.Lock() |
|
| 189 |
+ d.nodeUpdates = make(map[string]nodeUpdate) |
|
| 190 |
+ d.nodeUpdatesLock.Unlock() |
|
| 191 |
+ |
|
| 184 | 192 |
d.mu.Lock() |
| 185 | 193 |
if d.isRunning() {
|
| 186 | 194 |
d.mu.Unlock() |
| ... | ... |
@@ -155,18 +155,23 @@ func (u *Updater) Run(ctx context.Context, slots []orchestrator.Slot) {
|
| 155 | 155 |
u.startUpdate(ctx, service.ID) |
| 156 | 156 |
} |
| 157 | 157 |
|
| 158 |
- var monitoringPeriod time.Duration |
|
| 158 |
+ var ( |
|
| 159 |
+ monitoringPeriod time.Duration |
|
| 160 |
+ updateConfig *api.UpdateConfig |
|
| 161 |
+ ) |
|
| 159 | 162 |
|
| 160 |
- updateConfig := service.Spec.Update |
|
| 161 | 163 |
if service.UpdateStatus != nil && service.UpdateStatus.State == api.UpdateStatus_ROLLBACK_STARTED {
|
| 162 | 164 |
monitoringPeriod, _ = gogotypes.DurationFromProto(defaults.Service.Rollback.Monitor) |
| 163 | 165 |
updateConfig = service.Spec.Rollback |
| 164 | 166 |
if updateConfig == nil {
|
| 165 | 167 |
updateConfig = defaults.Service.Rollback |
| 166 | 168 |
} |
| 167 |
- } else if updateConfig == nil {
|
|
| 169 |
+ } else {
|
|
| 168 | 170 |
monitoringPeriod, _ = gogotypes.DurationFromProto(defaults.Service.Update.Monitor) |
| 169 |
- updateConfig = defaults.Service.Update |
|
| 171 |
+ updateConfig = service.Spec.Update |
|
| 172 |
+ if updateConfig == nil {
|
|
| 173 |
+ updateConfig = defaults.Service.Update |
|
| 174 |
+ } |
|
| 170 | 175 |
} |
| 171 | 176 |
|
| 172 | 177 |
parallelism := int(updateConfig.Parallelism) |
| 173 | 178 |
deleted file mode 100644 |
| ... | ... |
@@ -1,202 +0,0 @@ |
| 1 |
- |
|
| 2 |
- Apache License |
|
| 3 |
- Version 2.0, January 2004 |
|
| 4 |
- http://www.apache.org/licenses/ |
|
| 5 |
- |
|
| 6 |
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION |
|
| 7 |
- |
|
| 8 |
- 1. Definitions. |
|
| 9 |
- |
|
| 10 |
- "License" shall mean the terms and conditions for use, reproduction, |
|
| 11 |
- and distribution as defined by Sections 1 through 9 of this document. |
|
| 12 |
- |
|
| 13 |
- "Licensor" shall mean the copyright owner or entity authorized by |
|
| 14 |
- the copyright owner that is granting the License. |
|
| 15 |
- |
|
| 16 |
- "Legal Entity" shall mean the union of the acting entity and all |
|
| 17 |
- other entities that control, are controlled by, or are under common |
|
| 18 |
- control with that entity. For the purposes of this definition, |
|
| 19 |
- "control" means (i) the power, direct or indirect, to cause the |
|
| 20 |
- direction or management of such entity, whether by contract or |
|
| 21 |
- otherwise, or (ii) ownership of fifty percent (50%) or more of the |
|
| 22 |
- outstanding shares, or (iii) beneficial ownership of such entity. |
|
| 23 |
- |
|
| 24 |
- "You" (or "Your") shall mean an individual or Legal Entity |
|
| 25 |
- exercising permissions granted by this License. |
|
| 26 |
- |
|
| 27 |
- "Source" form shall mean the preferred form for making modifications, |
|
| 28 |
- including but not limited to software source code, documentation |
|
| 29 |
- source, and configuration files. |
|
| 30 |
- |
|
| 31 |
- "Object" form shall mean any form resulting from mechanical |
|
| 32 |
- transformation or translation of a Source form, including but |
|
| 33 |
- not limited to compiled object code, generated documentation, |
|
| 34 |
- and conversions to other media types. |
|
| 35 |
- |
|
| 36 |
- "Work" shall mean the work of authorship, whether in Source or |
|
| 37 |
- Object form, made available under the License, as indicated by a |
|
| 38 |
- copyright notice that is included in or attached to the work |
|
| 39 |
- (an example is provided in the Appendix below). |
|
| 40 |
- |
|
| 41 |
- "Derivative Works" shall mean any work, whether in Source or Object |
|
| 42 |
- form, that is based on (or derived from) the Work and for which the |
|
| 43 |
- editorial revisions, annotations, elaborations, or other modifications |
|
| 44 |
- represent, as a whole, an original work of authorship. For the purposes |
|
| 45 |
- of this License, Derivative Works shall not include works that remain |
|
| 46 |
- separable from, or merely link (or bind by name) to the interfaces of, |
|
| 47 |
- the Work and Derivative Works thereof. |
|
| 48 |
- |
|
| 49 |
- "Contribution" shall mean any work of authorship, including |
|
| 50 |
- the original version of the Work and any modifications or additions |
|
| 51 |
- to that Work or Derivative Works thereof, that is intentionally |
|
| 52 |
- submitted to Licensor for inclusion in the Work by the copyright owner |
|
| 53 |
- or by an individual or Legal Entity authorized to submit on behalf of |
|
| 54 |
- the copyright owner. For the purposes of this definition, "submitted" |
|
| 55 |
- means any form of electronic, verbal, or written communication sent |
|
| 56 |
- to the Licensor or its representatives, including but not limited to |
|
| 57 |
- communication on electronic mailing lists, source code control systems, |
|
| 58 |
- and issue tracking systems that are managed by, or on behalf of, the |
|
| 59 |
- Licensor for the purpose of discussing and improving the Work, but |
|
| 60 |
- excluding communication that is conspicuously marked or otherwise |
|
| 61 |
- designated in writing by the copyright owner as "Not a Contribution." |
|
| 62 |
- |
|
| 63 |
- "Contributor" shall mean Licensor and any individual or Legal Entity |
|
| 64 |
- on behalf of whom a Contribution has been received by Licensor and |
|
| 65 |
- subsequently incorporated within the Work. |
|
| 66 |
- |
|
| 67 |
- 2. Grant of Copyright License. Subject to the terms and conditions of |
|
| 68 |
- this License, each Contributor hereby grants to You a perpetual, |
|
| 69 |
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable |
|
| 70 |
- copyright license to reproduce, prepare Derivative Works of, |
|
| 71 |
- publicly display, publicly perform, sublicense, and distribute the |
|
| 72 |
- Work and such Derivative Works in Source or Object form. |
|
| 73 |
- |
|
| 74 |
- 3. Grant of Patent License. Subject to the terms and conditions of |
|
| 75 |
- this License, each Contributor hereby grants to You a perpetual, |
|
| 76 |
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable |
|
| 77 |
- (except as stated in this section) patent license to make, have made, |
|
| 78 |
- use, offer to sell, sell, import, and otherwise transfer the Work, |
|
| 79 |
- where such license applies only to those patent claims licensable |
|
| 80 |
- by such Contributor that are necessarily infringed by their |
|
| 81 |
- Contribution(s) alone or by combination of their Contribution(s) |
|
| 82 |
- with the Work to which such Contribution(s) was submitted. If You |
|
| 83 |
- institute patent litigation against any entity (including a |
|
| 84 |
- cross-claim or counterclaim in a lawsuit) alleging that the Work |
|
| 85 |
- or a Contribution incorporated within the Work constitutes direct |
|
| 86 |
- or contributory patent infringement, then any patent licenses |
|
| 87 |
- granted to You under this License for that Work shall terminate |
|
| 88 |
- as of the date such litigation is filed. |
|
| 89 |
- |
|
| 90 |
- 4. Redistribution. You may reproduce and distribute copies of the |
|
| 91 |
- Work or Derivative Works thereof in any medium, with or without |
|
| 92 |
- modifications, and in Source or Object form, provided that You |
|
| 93 |
- meet the following conditions: |
|
| 94 |
- |
|
| 95 |
- (a) You must give any other recipients of the Work or |
|
| 96 |
- Derivative Works a copy of this License; and |
|
| 97 |
- |
|
| 98 |
- (b) You must cause any modified files to carry prominent notices |
|
| 99 |
- stating that You changed the files; and |
|
| 100 |
- |
|
| 101 |
- (c) You must retain, in the Source form of any Derivative Works |
|
| 102 |
- that You distribute, all copyright, patent, trademark, and |
|
| 103 |
- attribution notices from the Source form of the Work, |
|
| 104 |
- excluding those notices that do not pertain to any part of |
|
| 105 |
- the Derivative Works; and |
|
| 106 |
- |
|
| 107 |
- (d) If the Work includes a "NOTICE" text file as part of its |
|
| 108 |
- distribution, then any Derivative Works that You distribute must |
|
| 109 |
- include a readable copy of the attribution notices contained |
|
| 110 |
- within such NOTICE file, excluding those notices that do not |
|
| 111 |
- pertain to any part of the Derivative Works, in at least one |
|
| 112 |
- of the following places: within a NOTICE text file distributed |
|
| 113 |
- as part of the Derivative Works; within the Source form or |
|
| 114 |
- documentation, if provided along with the Derivative Works; or, |
|
| 115 |
- within a display generated by the Derivative Works, if and |
|
| 116 |
- wherever such third-party notices normally appear. The contents |
|
| 117 |
- of the NOTICE file are for informational purposes only and |
|
| 118 |
- do not modify the License. You may add Your own attribution |
|
| 119 |
- notices within Derivative Works that You distribute, alongside |
|
| 120 |
- or as an addendum to the NOTICE text from the Work, provided |
|
| 121 |
- that such additional attribution notices cannot be construed |
|
| 122 |
- as modifying the License. |
|
| 123 |
- |
|
| 124 |
- You may add Your own copyright statement to Your modifications and |
|
| 125 |
- may provide additional or different license terms and conditions |
|
| 126 |
- for use, reproduction, or distribution of Your modifications, or |
|
| 127 |
- for any such Derivative Works as a whole, provided Your use, |
|
| 128 |
- reproduction, and distribution of the Work otherwise complies with |
|
| 129 |
- the conditions stated in this License. |
|
| 130 |
- |
|
| 131 |
- 5. Submission of Contributions. Unless You explicitly state otherwise, |
|
| 132 |
- any Contribution intentionally submitted for inclusion in the Work |
|
| 133 |
- by You to the Licensor shall be under the terms and conditions of |
|
| 134 |
- this License, without any additional terms or conditions. |
|
| 135 |
- Notwithstanding the above, nothing herein shall supersede or modify |
|
| 136 |
- the terms of any separate license agreement you may have executed |
|
| 137 |
- with Licensor regarding such Contributions. |
|
| 138 |
- |
|
| 139 |
- 6. Trademarks. This License does not grant permission to use the trade |
|
| 140 |
- names, trademarks, service marks, or product names of the Licensor, |
|
| 141 |
- except as required for reasonable and customary use in describing the |
|
| 142 |
- origin of the Work and reproducing the content of the NOTICE file. |
|
| 143 |
- |
|
| 144 |
- 7. Disclaimer of Warranty. Unless required by applicable law or |
|
| 145 |
- agreed to in writing, Licensor provides the Work (and each |
|
| 146 |
- Contributor provides its Contributions) on an "AS IS" BASIS, |
|
| 147 |
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or |
|
| 148 |
- implied, including, without limitation, any warranties or conditions |
|
| 149 |
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A |
|
| 150 |
- PARTICULAR PURPOSE. You are solely responsible for determining the |
|
| 151 |
- appropriateness of using or redistributing the Work and assume any |
|
| 152 |
- risks associated with Your exercise of permissions under this License. |
|
| 153 |
- |
|
| 154 |
- 8. Limitation of Liability. In no event and under no legal theory, |
|
| 155 |
- whether in tort (including negligence), contract, or otherwise, |
|
| 156 |
- unless required by applicable law (such as deliberate and grossly |
|
| 157 |
- negligent acts) or agreed to in writing, shall any Contributor be |
|
| 158 |
- liable to You for damages, including any direct, indirect, special, |
|
| 159 |
- incidental, or consequential damages of any character arising as a |
|
| 160 |
- result of this License or out of the use or inability to use the |
|
| 161 |
- Work (including but not limited to damages for loss of goodwill, |
|
| 162 |
- work stoppage, computer failure or malfunction, or any and all |
|
| 163 |
- other commercial damages or losses), even if such Contributor |
|
| 164 |
- has been advised of the possibility of such damages. |
|
| 165 |
- |
|
| 166 |
- 9. Accepting Warranty or Additional Liability. While redistributing |
|
| 167 |
- the Work or Derivative Works thereof, You may choose to offer, |
|
| 168 |
- and charge a fee for, acceptance of support, warranty, indemnity, |
|
| 169 |
- or other liability obligations and/or rights consistent with this |
|
| 170 |
- License. However, in accepting such obligations, You may act only |
|
| 171 |
- on Your own behalf and on Your sole responsibility, not on behalf |
|
| 172 |
- of any other Contributor, and only if You agree to indemnify, |
|
| 173 |
- defend, and hold each Contributor harmless for any liability |
|
| 174 |
- incurred by, or claims asserted against, such Contributor by reason |
|
| 175 |
- of your accepting any such warranty or additional liability. |
|
| 176 |
- |
|
| 177 |
- END OF TERMS AND CONDITIONS |
|
| 178 |
- |
|
| 179 |
- APPENDIX: How to apply the Apache License to your work. |
|
| 180 |
- |
|
| 181 |
- To apply the Apache License to your work, attach the following |
|
| 182 |
- boilerplate notice, with the fields enclosed by brackets "[]" |
|
| 183 |
- replaced with your own identifying information. (Don't include |
|
| 184 |
- the brackets!) The text should be enclosed in the appropriate |
|
| 185 |
- comment syntax for the file format. We also recommend that a |
|
| 186 |
- file or class name and description of purpose be included on the |
|
| 187 |
- same "printed page" as the copyright notice for easier |
|
| 188 |
- identification within third-party archives. |
|
| 189 |
- |
|
| 190 |
- Copyright [yyyy] [name of copyright owner] |
|
| 191 |
- |
|
| 192 |
- Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 193 |
- you may not use this file except in compliance with the License. |
|
| 194 |
- You may obtain a copy of the License at |
|
| 195 |
- |
|
| 196 |
- http://www.apache.org/licenses/LICENSE-2.0 |
|
| 197 |
- |
|
| 198 |
- Unless required by applicable law or agreed to in writing, software |
|
| 199 |
- distributed under the License is distributed on an "AS IS" BASIS, |
|
| 200 |
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 201 |
- See the License for the specific language governing permissions and |
|
| 202 |
- limitations under the License. |
| 203 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,81 +0,0 @@ |
| 1 |
-GoMock is a mocking framework for the [Go programming language][golang]. It |
|
| 2 |
-integrates well with Go's built-in `testing` package, but can be used in other |
|
| 3 |
-contexts too. |
|
| 4 |
- |
|
| 5 |
- |
|
| 6 |
-Installation |
|
| 7 |
- |
|
| 8 |
-Once you have [installed Go][golang-install], run these commands |
|
| 9 |
-to install the `gomock` package and the `mockgen` tool: |
|
| 10 |
- |
|
| 11 |
- go get github.com/golang/mock/gomock |
|
| 12 |
- go get github.com/golang/mock/mockgen |
|
| 13 |
- |
|
| 14 |
- |
|
| 15 |
-Documentation |
|
| 16 |
- |
|
| 17 |
-After installing, you can use `go doc` to get documentation: |
|
| 18 |
- |
|
| 19 |
- go doc github.com/golang/mock/gomock |
|
| 20 |
- |
|
| 21 |
-Alternatively, there is an online reference for the package hosted on GoPkgDoc |
|
| 22 |
-[here][gomock-ref]. |
|
| 23 |
- |
|
| 24 |
- |
|
| 25 |
-Running mockgen |
|
| 26 |
- |
|
| 27 |
-`mockgen` has two modes of operation: source and reflect. |
|
| 28 |
-Source mode generates mock interfaces from a source file. |
|
| 29 |
-It is enabled by using the -source flag. Other flags that |
|
| 30 |
-may be useful in this mode are -imports and -aux_files. |
|
| 31 |
- |
|
| 32 |
-Example: |
|
| 33 |
- |
|
| 34 |
- mockgen -source=foo.go [other options] |
|
| 35 |
- |
|
| 36 |
-Reflect mode generates mock interfaces by building a program |
|
| 37 |
-that uses reflection to understand interfaces. It is enabled |
|
| 38 |
-by passing two non-flag arguments: an import path, and a |
|
| 39 |
-comma-separated list of symbols. |
|
| 40 |
- |
|
| 41 |
-Example: |
|
| 42 |
- |
|
| 43 |
- mockgen database/sql/driver Conn,Driver |
|
| 44 |
- |
|
| 45 |
-The `mockgen` command is used to generate source code for a mock |
|
| 46 |
-class given a Go source file containing interfaces to be mocked. |
|
| 47 |
-It supports the following flags: |
|
| 48 |
- |
|
| 49 |
- * `-source`: A file containing interfaces to be mocked. |
|
| 50 |
- |
|
| 51 |
- * `-destination`: A file to which to write the resulting source code. If you |
|
| 52 |
- don't set this, the code is printed to standard output. |
|
| 53 |
- |
|
| 54 |
- * `-package`: The package to use for the resulting mock class |
|
| 55 |
- source code. If you don't set this, the package name is `mock_` concatenated |
|
| 56 |
- with the package of the input file. |
|
| 57 |
- |
|
| 58 |
- * `-imports`: A list of explicit imports that should be used in the resulting |
|
| 59 |
- source code, specified as a comma-separated list of elements of the form |
|
| 60 |
- `foo=bar/baz`, where `bar/baz` is the package being imported and `foo` is |
|
| 61 |
- the identifier to use for the package in the generated source code. |
|
| 62 |
- |
|
| 63 |
- * `-aux_files`: A list of additional files that should be consulted to |
|
| 64 |
- resolve e.g. embedded interfaces defined in a different file. This is |
|
| 65 |
- specified as a comma-separated list of elements of the form |
|
| 66 |
- `foo=bar/baz.go`, where `bar/baz.go` is the source file and `foo` is the |
|
| 67 |
- package name of that file used by the -source file. |
|
| 68 |
- |
|
| 69 |
-For an example of the use of `mockgen`, see the `sample/` directory. In simple |
|
| 70 |
-cases, you will need only the `-source` flag. |
|
| 71 |
- |
|
| 72 |
- |
|
| 73 |
-TODO: Brief overview of how to create mock objects and set up expectations, and |
|
| 74 |
-an example. |
|
| 75 |
- |
|
| 76 |
-[golang]: http://golang.org/ |
|
| 77 |
-[golang-install]: http://golang.org/doc/install.html#releases |
|
| 78 |
-[gomock-ref]: http://godoc.org/github.com/golang/mock/gomock |
| 79 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,268 +0,0 @@ |
| 1 |
-// Copyright 2010 Google Inc. |
|
| 2 |
-// |
|
| 3 |
-// Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 4 |
-// you may not use this file except in compliance with the License. |
|
| 5 |
-// You may obtain a copy of the License at |
|
| 6 |
-// |
|
| 7 |
-// http://www.apache.org/licenses/LICENSE-2.0 |
|
| 8 |
-// |
|
| 9 |
-// Unless required by applicable law or agreed to in writing, software |
|
| 10 |
-// distributed under the License is distributed on an "AS IS" BASIS, |
|
| 11 |
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 12 |
-// See the License for the specific language governing permissions and |
|
| 13 |
-// limitations under the License. |
|
| 14 |
- |
|
| 15 |
-package gomock |
|
| 16 |
- |
|
| 17 |
-import ( |
|
| 18 |
- "fmt" |
|
| 19 |
- "reflect" |
|
| 20 |
- "strings" |
|
| 21 |
-) |
|
| 22 |
- |
|
| 23 |
-// Call represents an expected call to a mock. |
|
| 24 |
-type Call struct {
|
|
| 25 |
- t TestReporter // for triggering test failures on invalid call setup |
|
| 26 |
- |
|
| 27 |
- receiver interface{} // the receiver of the method call
|
|
| 28 |
- method string // the name of the method |
|
| 29 |
- args []Matcher // the args |
|
| 30 |
- rets []interface{} // the return values (if any)
|
|
| 31 |
- |
|
| 32 |
- preReqs []*Call // prerequisite calls |
|
| 33 |
- |
|
| 34 |
- // Expectations |
|
| 35 |
- minCalls, maxCalls int |
|
| 36 |
- |
|
| 37 |
- numCalls int // actual number made |
|
| 38 |
- |
|
| 39 |
- // Actions |
|
| 40 |
- doFunc reflect.Value |
|
| 41 |
- setArgs map[int]reflect.Value |
|
| 42 |
-} |
|
| 43 |
- |
|
| 44 |
-// AnyTimes allows the expectation to be called 0 or more times |
|
| 45 |
-func (c *Call) AnyTimes() *Call {
|
|
| 46 |
- c.minCalls, c.maxCalls = 0, 1e8 // close enough to infinity |
|
| 47 |
- return c |
|
| 48 |
-} |
|
| 49 |
- |
|
| 50 |
-// MinTimes requires the call to occur at least n times. If AnyTimes or MaxTimes have not been called, MinTimes also |
|
| 51 |
-// sets the maximum number of calls to infinity. |
|
| 52 |
-func (c *Call) MinTimes(n int) *Call {
|
|
| 53 |
- c.minCalls = n |
|
| 54 |
- if c.maxCalls == 1 {
|
|
| 55 |
- c.maxCalls = 1e8 |
|
| 56 |
- } |
|
| 57 |
- return c |
|
| 58 |
-} |
|
| 59 |
- |
|
| 60 |
-// MaxTimes limits the number of calls to n times. If AnyTimes or MinTimes have not been called, MaxTimes also |
|
| 61 |
-// sets the minimum number of calls to 0. |
|
| 62 |
-func (c *Call) MaxTimes(n int) *Call {
|
|
| 63 |
- c.maxCalls = n |
|
| 64 |
- if c.minCalls == 1 {
|
|
| 65 |
- c.minCalls = 0 |
|
| 66 |
- } |
|
| 67 |
- return c |
|
| 68 |
-} |
|
| 69 |
- |
|
| 70 |
-// Do declares the action to run when the call is matched. |
|
| 71 |
-// It takes an interface{} argument to support n-arity functions.
|
|
| 72 |
-func (c *Call) Do(f interface{}) *Call {
|
|
| 73 |
- // TODO: Check arity and types here, rather than dying badly elsewhere. |
|
| 74 |
- c.doFunc = reflect.ValueOf(f) |
|
| 75 |
- return c |
|
| 76 |
-} |
|
| 77 |
- |
|
| 78 |
-func (c *Call) Return(rets ...interface{}) *Call {
|
|
| 79 |
- mt := c.methodType() |
|
| 80 |
- if len(rets) != mt.NumOut() {
|
|
| 81 |
- c.t.Fatalf("wrong number of arguments to Return for %T.%v: got %d, want %d",
|
|
| 82 |
- c.receiver, c.method, len(rets), mt.NumOut()) |
|
| 83 |
- } |
|
| 84 |
- for i, ret := range rets {
|
|
| 85 |
- if got, want := reflect.TypeOf(ret), mt.Out(i); got == want {
|
|
| 86 |
- // Identical types; nothing to do. |
|
| 87 |
- } else if got == nil {
|
|
| 88 |
- // Nil needs special handling. |
|
| 89 |
- switch want.Kind() {
|
|
| 90 |
- case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: |
|
| 91 |
- // ok |
|
| 92 |
- default: |
|
| 93 |
- c.t.Fatalf("argument %d to Return for %T.%v is nil, but %v is not nillable",
|
|
| 94 |
- i, c.receiver, c.method, want) |
|
| 95 |
- } |
|
| 96 |
- } else if got.AssignableTo(want) {
|
|
| 97 |
- // Assignable type relation. Make the assignment now so that the generated code |
|
| 98 |
- // can return the values with a type assertion. |
|
| 99 |
- v := reflect.New(want).Elem() |
|
| 100 |
- v.Set(reflect.ValueOf(ret)) |
|
| 101 |
- rets[i] = v.Interface() |
|
| 102 |
- } else {
|
|
| 103 |
- c.t.Fatalf("wrong type of argument %d to Return for %T.%v: %v is not assignable to %v",
|
|
| 104 |
- i, c.receiver, c.method, got, want) |
|
| 105 |
- } |
|
| 106 |
- } |
|
| 107 |
- |
|
| 108 |
- c.rets = rets |
|
| 109 |
- return c |
|
| 110 |
-} |
|
| 111 |
- |
|
| 112 |
-func (c *Call) Times(n int) *Call {
|
|
| 113 |
- c.minCalls, c.maxCalls = n, n |
|
| 114 |
- return c |
|
| 115 |
-} |
|
| 116 |
- |
|
| 117 |
-// SetArg declares an action that will set the nth argument's value, |
|
| 118 |
-// indirected through a pointer. |
|
| 119 |
-func (c *Call) SetArg(n int, value interface{}) *Call {
|
|
| 120 |
- if c.setArgs == nil {
|
|
| 121 |
- c.setArgs = make(map[int]reflect.Value) |
|
| 122 |
- } |
|
| 123 |
- mt := c.methodType() |
|
| 124 |
- // TODO: This will break on variadic methods. |
|
| 125 |
- // We will need to check those at invocation time. |
|
| 126 |
- if n < 0 || n >= mt.NumIn() {
|
|
| 127 |
- c.t.Fatalf("SetArg(%d, ...) called for a method with %d args", n, mt.NumIn())
|
|
| 128 |
- } |
|
| 129 |
- // Permit setting argument through an interface. |
|
| 130 |
- // In the interface case, we don't (nay, can't) check the type here. |
|
| 131 |
- at := mt.In(n) |
|
| 132 |
- switch at.Kind() {
|
|
| 133 |
- case reflect.Ptr: |
|
| 134 |
- dt := at.Elem() |
|
| 135 |
- if vt := reflect.TypeOf(value); !vt.AssignableTo(dt) {
|
|
| 136 |
- c.t.Fatalf("SetArg(%d, ...) argument is a %v, not assignable to %v", n, vt, dt)
|
|
| 137 |
- } |
|
| 138 |
- case reflect.Interface: |
|
| 139 |
- // nothing to do |
|
| 140 |
- default: |
|
| 141 |
- c.t.Fatalf("SetArg(%d, ...) referring to argument of non-pointer non-interface type %v", n, at)
|
|
| 142 |
- } |
|
| 143 |
- c.setArgs[n] = reflect.ValueOf(value) |
|
| 144 |
- return c |
|
| 145 |
-} |
|
| 146 |
- |
|
| 147 |
-// isPreReq returns true if other is a direct or indirect prerequisite to c. |
|
| 148 |
-func (c *Call) isPreReq(other *Call) bool {
|
|
| 149 |
- for _, preReq := range c.preReqs {
|
|
| 150 |
- if other == preReq || preReq.isPreReq(other) {
|
|
| 151 |
- return true |
|
| 152 |
- } |
|
| 153 |
- } |
|
| 154 |
- return false |
|
| 155 |
-} |
|
| 156 |
- |
|
| 157 |
-// After declares that the call may only match after preReq has been exhausted. |
|
| 158 |
-func (c *Call) After(preReq *Call) *Call {
|
|
| 159 |
- if preReq.isPreReq(c) {
|
|
| 160 |
- msg := fmt.Sprintf( |
|
| 161 |
- "Loop in call order: %v is a prerequisite to %v (possibly indirectly).", |
|
| 162 |
- c, preReq, |
|
| 163 |
- ) |
|
| 164 |
- panic(msg) |
|
| 165 |
- } |
|
| 166 |
- |
|
| 167 |
- c.preReqs = append(c.preReqs, preReq) |
|
| 168 |
- return c |
|
| 169 |
-} |
|
| 170 |
- |
|
| 171 |
-// Returns true iff the minimum number of calls have been made. |
|
| 172 |
-func (c *Call) satisfied() bool {
|
|
| 173 |
- return c.numCalls >= c.minCalls |
|
| 174 |
-} |
|
| 175 |
- |
|
| 176 |
-// Returns true iff the maximum number of calls have been made. |
|
| 177 |
-func (c *Call) exhausted() bool {
|
|
| 178 |
- return c.numCalls >= c.maxCalls |
|
| 179 |
-} |
|
| 180 |
- |
|
| 181 |
-func (c *Call) String() string {
|
|
| 182 |
- args := make([]string, len(c.args)) |
|
| 183 |
- for i, arg := range c.args {
|
|
| 184 |
- args[i] = arg.String() |
|
| 185 |
- } |
|
| 186 |
- arguments := strings.Join(args, ", ") |
|
| 187 |
- return fmt.Sprintf("%T.%v(%s)", c.receiver, c.method, arguments)
|
|
| 188 |
-} |
|
| 189 |
- |
|
| 190 |
-// Tests if the given call matches the expected call. |
|
| 191 |
-func (c *Call) matches(args []interface{}) bool {
|
|
| 192 |
- if len(args) != len(c.args) {
|
|
| 193 |
- return false |
|
| 194 |
- } |
|
| 195 |
- for i, m := range c.args {
|
|
| 196 |
- if !m.Matches(args[i]) {
|
|
| 197 |
- return false |
|
| 198 |
- } |
|
| 199 |
- } |
|
| 200 |
- |
|
| 201 |
- // Check that all prerequisite calls have been satisfied. |
|
| 202 |
- for _, preReqCall := range c.preReqs {
|
|
| 203 |
- if !preReqCall.satisfied() {
|
|
| 204 |
- return false |
|
| 205 |
- } |
|
| 206 |
- } |
|
| 207 |
- |
|
| 208 |
- return true |
|
| 209 |
-} |
|
| 210 |
- |
|
| 211 |
-// dropPrereqs tells the expected Call to not re-check prerequite calls any |
|
| 212 |
-// longer, and to return its current set. |
|
| 213 |
-func (c *Call) dropPrereqs() (preReqs []*Call) {
|
|
| 214 |
- preReqs = c.preReqs |
|
| 215 |
- c.preReqs = nil |
|
| 216 |
- return |
|
| 217 |
-} |
|
| 218 |
- |
|
| 219 |
-func (c *Call) call(args []interface{}) (rets []interface{}, action func()) {
|
|
| 220 |
- c.numCalls++ |
|
| 221 |
- |
|
| 222 |
- // Actions |
|
| 223 |
- if c.doFunc.IsValid() {
|
|
| 224 |
- doArgs := make([]reflect.Value, len(args)) |
|
| 225 |
- ft := c.doFunc.Type() |
|
| 226 |
- for i := 0; i < ft.NumIn(); i++ {
|
|
| 227 |
- if args[i] != nil {
|
|
| 228 |
- doArgs[i] = reflect.ValueOf(args[i]) |
|
| 229 |
- } else {
|
|
| 230 |
- // Use the zero value for the arg. |
|
| 231 |
- doArgs[i] = reflect.Zero(ft.In(i)) |
|
| 232 |
- } |
|
| 233 |
- } |
|
| 234 |
- action = func() { c.doFunc.Call(doArgs) }
|
|
| 235 |
- } |
|
| 236 |
- for n, v := range c.setArgs {
|
|
| 237 |
- reflect.ValueOf(args[n]).Elem().Set(v) |
|
| 238 |
- } |
|
| 239 |
- |
|
| 240 |
- rets = c.rets |
|
| 241 |
- if rets == nil {
|
|
| 242 |
- // Synthesize the zero value for each of the return args' types. |
|
| 243 |
- mt := c.methodType() |
|
| 244 |
- rets = make([]interface{}, mt.NumOut())
|
|
| 245 |
- for i := 0; i < mt.NumOut(); i++ {
|
|
| 246 |
- rets[i] = reflect.Zero(mt.Out(i)).Interface() |
|
| 247 |
- } |
|
| 248 |
- } |
|
| 249 |
- |
|
| 250 |
- return |
|
| 251 |
-} |
|
| 252 |
- |
|
| 253 |
-func (c *Call) methodType() reflect.Type {
|
|
| 254 |
- recv := reflect.ValueOf(c.receiver) |
|
| 255 |
- for i := 0; i < recv.Type().NumMethod(); i++ {
|
|
| 256 |
- if recv.Type().Method(i).Name == c.method {
|
|
| 257 |
- return recv.Method(i).Type() |
|
| 258 |
- } |
|
| 259 |
- } |
|
| 260 |
- panic(fmt.Sprintf("gomock: failed finding method %s on %T", c.method, c.receiver))
|
|
| 261 |
-} |
|
| 262 |
- |
|
| 263 |
-// InOrder declares that the given calls should occur in order. |
|
| 264 |
-func InOrder(calls ...*Call) {
|
|
| 265 |
- for i := 1; i < len(calls); i++ {
|
|
| 266 |
- calls[i].After(calls[i-1]) |
|
| 267 |
- } |
|
| 268 |
-} |
| 269 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,76 +0,0 @@ |
| 1 |
-// Copyright 2011 Google Inc. |
|
| 2 |
-// |
|
| 3 |
-// Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 4 |
-// you may not use this file except in compliance with the License. |
|
| 5 |
-// You may obtain a copy of the License at |
|
| 6 |
-// |
|
| 7 |
-// http://www.apache.org/licenses/LICENSE-2.0 |
|
| 8 |
-// |
|
| 9 |
-// Unless required by applicable law or agreed to in writing, software |
|
| 10 |
-// distributed under the License is distributed on an "AS IS" BASIS, |
|
| 11 |
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 12 |
-// See the License for the specific language governing permissions and |
|
| 13 |
-// limitations under the License. |
|
| 14 |
- |
|
| 15 |
-package gomock |
|
| 16 |
- |
|
| 17 |
-// callSet represents a set of expected calls, indexed by receiver and method |
|
| 18 |
-// name. |
|
| 19 |
-type callSet map[interface{}]map[string][]*Call
|
|
| 20 |
- |
|
| 21 |
-// Add adds a new expected call. |
|
| 22 |
-func (cs callSet) Add(call *Call) {
|
|
| 23 |
- methodMap, ok := cs[call.receiver] |
|
| 24 |
- if !ok {
|
|
| 25 |
- methodMap = make(map[string][]*Call) |
|
| 26 |
- cs[call.receiver] = methodMap |
|
| 27 |
- } |
|
| 28 |
- methodMap[call.method] = append(methodMap[call.method], call) |
|
| 29 |
-} |
|
| 30 |
- |
|
| 31 |
-// Remove removes an expected call. |
|
| 32 |
-func (cs callSet) Remove(call *Call) {
|
|
| 33 |
- methodMap, ok := cs[call.receiver] |
|
| 34 |
- if !ok {
|
|
| 35 |
- return |
|
| 36 |
- } |
|
| 37 |
- sl := methodMap[call.method] |
|
| 38 |
- for i, c := range sl {
|
|
| 39 |
- if c == call {
|
|
| 40 |
- // quick removal; we don't need to maintain call order |
|
| 41 |
- if len(sl) > 1 {
|
|
| 42 |
- sl[i] = sl[len(sl)-1] |
|
| 43 |
- } |
|
| 44 |
- methodMap[call.method] = sl[:len(sl)-1] |
|
| 45 |
- break |
|
| 46 |
- } |
|
| 47 |
- } |
|
| 48 |
-} |
|
| 49 |
- |
|
| 50 |
-// FindMatch searches for a matching call. Returns nil if no call matched. |
|
| 51 |
-func (cs callSet) FindMatch(receiver interface{}, method string, args []interface{}) *Call {
|
|
| 52 |
- methodMap, ok := cs[receiver] |
|
| 53 |
- if !ok {
|
|
| 54 |
- return nil |
|
| 55 |
- } |
|
| 56 |
- calls, ok := methodMap[method] |
|
| 57 |
- if !ok {
|
|
| 58 |
- return nil |
|
| 59 |
- } |
|
| 60 |
- |
|
| 61 |
- // Search through the unordered set of calls expected on a method on a |
|
| 62 |
- // receiver. |
|
| 63 |
- for _, call := range calls {
|
|
| 64 |
- // A call should not normally still be here if exhausted, |
|
| 65 |
- // but it can happen if, for instance, .Times(0) was used. |
|
| 66 |
- // Pretend the call doesn't match. |
|
| 67 |
- if call.exhausted() {
|
|
| 68 |
- continue |
|
| 69 |
- } |
|
| 70 |
- if call.matches(args) {
|
|
| 71 |
- return call |
|
| 72 |
- } |
|
| 73 |
- } |
|
| 74 |
- |
|
| 75 |
- return nil |
|
| 76 |
-} |
| 77 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,167 +0,0 @@ |
| 1 |
-// Copyright 2010 Google Inc. |
|
| 2 |
-// |
|
| 3 |
-// Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 4 |
-// you may not use this file except in compliance with the License. |
|
| 5 |
-// You may obtain a copy of the License at |
|
| 6 |
-// |
|
| 7 |
-// http://www.apache.org/licenses/LICENSE-2.0 |
|
| 8 |
-// |
|
| 9 |
-// Unless required by applicable law or agreed to in writing, software |
|
| 10 |
-// distributed under the License is distributed on an "AS IS" BASIS, |
|
| 11 |
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 12 |
-// See the License for the specific language governing permissions and |
|
| 13 |
-// limitations under the License. |
|
| 14 |
- |
|
| 15 |
-// GoMock - a mock framework for Go. |
|
| 16 |
-// |
|
| 17 |
-// Standard usage: |
|
| 18 |
-// (1) Define an interface that you wish to mock. |
|
| 19 |
-// type MyInterface interface {
|
|
| 20 |
-// SomeMethod(x int64, y string) |
|
| 21 |
-// } |
|
| 22 |
-// (2) Use mockgen to generate a mock from the interface. |
|
| 23 |
-// (3) Use the mock in a test: |
|
| 24 |
-// func TestMyThing(t *testing.T) {
|
|
| 25 |
-// mockCtrl := gomock.NewController(t) |
|
| 26 |
-// defer mockCtrl.Finish() |
|
| 27 |
-// |
|
| 28 |
-// mockObj := something.NewMockMyInterface(mockCtrl) |
|
| 29 |
-// mockObj.EXPECT().SomeMethod(4, "blah") |
|
| 30 |
-// // pass mockObj to a real object and play with it. |
|
| 31 |
-// } |
|
| 32 |
-// |
|
| 33 |
-// By default, expected calls are not enforced to run in any particular order. |
|
| 34 |
-// Call order dependency can be enforced by use of InOrder and/or Call.After. |
|
| 35 |
-// Call.After can create more varied call order dependencies, but InOrder is |
|
| 36 |
-// often more convenient. |
|
| 37 |
-// |
|
| 38 |
-// The following examples create equivalent call order dependencies. |
|
| 39 |
-// |
|
| 40 |
-// Example of using Call.After to chain expected call order: |
|
| 41 |
-// |
|
| 42 |
-// firstCall := mockObj.EXPECT().SomeMethod(1, "first") |
|
| 43 |
-// secondCall := mockObj.EXPECT().SomeMethod(2, "second").After(firstCall) |
|
| 44 |
-// mockObj.EXPECT().SomeMethod(3, "third").After(secondCall) |
|
| 45 |
-// |
|
| 46 |
-// Example of using InOrder to declare expected call order: |
|
| 47 |
-// |
|
| 48 |
-// gomock.InOrder( |
|
| 49 |
-// mockObj.EXPECT().SomeMethod(1, "first"), |
|
| 50 |
-// mockObj.EXPECT().SomeMethod(2, "second"), |
|
| 51 |
-// mockObj.EXPECT().SomeMethod(3, "third"), |
|
| 52 |
-// ) |
|
| 53 |
-// |
|
| 54 |
-// TODO: |
|
| 55 |
-// - Handle different argument/return types (e.g. ..., chan, map, interface). |
|
| 56 |
-package gomock |
|
| 57 |
- |
|
| 58 |
-import "sync" |
|
| 59 |
- |
|
| 60 |
-// A TestReporter is something that can be used to report test failures. |
|
| 61 |
-// It is satisfied by the standard library's *testing.T. |
|
| 62 |
-type TestReporter interface {
|
|
| 63 |
- Errorf(format string, args ...interface{})
|
|
| 64 |
- Fatalf(format string, args ...interface{})
|
|
| 65 |
-} |
|
| 66 |
- |
|
| 67 |
-// A Controller represents the top-level control of a mock ecosystem. |
|
| 68 |
-// It defines the scope and lifetime of mock objects, as well as their expectations. |
|
| 69 |
-// It is safe to call Controller's methods from multiple goroutines. |
|
| 70 |
-type Controller struct {
|
|
| 71 |
- mu sync.Mutex |
|
| 72 |
- t TestReporter |
|
| 73 |
- expectedCalls callSet |
|
| 74 |
-} |
|
| 75 |
- |
|
| 76 |
-func NewController(t TestReporter) *Controller {
|
|
| 77 |
- return &Controller{
|
|
| 78 |
- t: t, |
|
| 79 |
- expectedCalls: make(callSet), |
|
| 80 |
- } |
|
| 81 |
-} |
|
| 82 |
- |
|
| 83 |
-func (ctrl *Controller) RecordCall(receiver interface{}, method string, args ...interface{}) *Call {
|
|
| 84 |
- // TODO: check arity, types. |
|
| 85 |
- margs := make([]Matcher, len(args)) |
|
| 86 |
- for i, arg := range args {
|
|
| 87 |
- if m, ok := arg.(Matcher); ok {
|
|
| 88 |
- margs[i] = m |
|
| 89 |
- } else if arg == nil {
|
|
| 90 |
- // Handle nil specially so that passing a nil interface value |
|
| 91 |
- // will match the typed nils of concrete args. |
|
| 92 |
- margs[i] = Nil() |
|
| 93 |
- } else {
|
|
| 94 |
- margs[i] = Eq(arg) |
|
| 95 |
- } |
|
| 96 |
- } |
|
| 97 |
- |
|
| 98 |
- ctrl.mu.Lock() |
|
| 99 |
- defer ctrl.mu.Unlock() |
|
| 100 |
- |
|
| 101 |
- call := &Call{t: ctrl.t, receiver: receiver, method: method, args: margs, minCalls: 1, maxCalls: 1}
|
|
| 102 |
- |
|
| 103 |
- ctrl.expectedCalls.Add(call) |
|
| 104 |
- return call |
|
| 105 |
-} |
|
| 106 |
- |
|
| 107 |
-func (ctrl *Controller) Call(receiver interface{}, method string, args ...interface{}) []interface{} {
|
|
| 108 |
- ctrl.mu.Lock() |
|
| 109 |
- defer ctrl.mu.Unlock() |
|
| 110 |
- |
|
| 111 |
- expected := ctrl.expectedCalls.FindMatch(receiver, method, args) |
|
| 112 |
- if expected == nil {
|
|
| 113 |
- ctrl.t.Fatalf("no matching expected call: %T.%v(%v)", receiver, method, args)
|
|
| 114 |
- } |
|
| 115 |
- |
|
| 116 |
- // Two things happen here: |
|
| 117 |
- // * the matching call no longer needs to check prerequite calls, |
|
| 118 |
- // * and the prerequite calls are no longer expected, so remove them. |
|
| 119 |
- preReqCalls := expected.dropPrereqs() |
|
| 120 |
- for _, preReqCall := range preReqCalls {
|
|
| 121 |
- ctrl.expectedCalls.Remove(preReqCall) |
|
| 122 |
- } |
|
| 123 |
- |
|
| 124 |
- rets, action := expected.call(args) |
|
| 125 |
- if expected.exhausted() {
|
|
| 126 |
- ctrl.expectedCalls.Remove(expected) |
|
| 127 |
- } |
|
| 128 |
- |
|
| 129 |
- // Don't hold the lock while doing the call's action (if any) |
|
| 130 |
- // so that actions may execute concurrently. |
|
| 131 |
- // We use the deferred Unlock to capture any panics that happen above; |
|
| 132 |
- // here we add a deferred Lock to balance it. |
|
| 133 |
- ctrl.mu.Unlock() |
|
| 134 |
- defer ctrl.mu.Lock() |
|
| 135 |
- if action != nil {
|
|
| 136 |
- action() |
|
| 137 |
- } |
|
| 138 |
- |
|
| 139 |
- return rets |
|
| 140 |
-} |
|
| 141 |
- |
|
| 142 |
-func (ctrl *Controller) Finish() {
|
|
| 143 |
- ctrl.mu.Lock() |
|
| 144 |
- defer ctrl.mu.Unlock() |
|
| 145 |
- |
|
| 146 |
- // If we're currently panicking, probably because this is a deferred call, |
|
| 147 |
- // pass through the panic. |
|
| 148 |
- if err := recover(); err != nil {
|
|
| 149 |
- panic(err) |
|
| 150 |
- } |
|
| 151 |
- |
|
| 152 |
- // Check that all remaining expected calls are satisfied. |
|
| 153 |
- failures := false |
|
| 154 |
- for _, methodMap := range ctrl.expectedCalls {
|
|
| 155 |
- for _, calls := range methodMap {
|
|
| 156 |
- for _, call := range calls {
|
|
| 157 |
- if !call.satisfied() {
|
|
| 158 |
- ctrl.t.Errorf("missing call(s) to %v", call)
|
|
| 159 |
- failures = true |
|
| 160 |
- } |
|
| 161 |
- } |
|
| 162 |
- } |
|
| 163 |
- } |
|
| 164 |
- if failures {
|
|
| 165 |
- ctrl.t.Fatalf("aborting test due to missing call(s)")
|
|
| 166 |
- } |
|
| 167 |
-} |
| 168 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,97 +0,0 @@ |
| 1 |
-// Copyright 2010 Google Inc. |
|
| 2 |
-// |
|
| 3 |
-// Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 4 |
-// you may not use this file except in compliance with the License. |
|
| 5 |
-// You may obtain a copy of the License at |
|
| 6 |
-// |
|
| 7 |
-// http://www.apache.org/licenses/LICENSE-2.0 |
|
| 8 |
-// |
|
| 9 |
-// Unless required by applicable law or agreed to in writing, software |
|
| 10 |
-// distributed under the License is distributed on an "AS IS" BASIS, |
|
| 11 |
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 12 |
-// See the License for the specific language governing permissions and |
|
| 13 |
-// limitations under the License. |
|
| 14 |
- |
|
| 15 |
-package gomock |
|
| 16 |
- |
|
| 17 |
-import ( |
|
| 18 |
- "fmt" |
|
| 19 |
- "reflect" |
|
| 20 |
-) |
|
| 21 |
- |
|
| 22 |
-// A Matcher is a representation of a class of values. |
|
| 23 |
-// It is used to represent the valid or expected arguments to a mocked method. |
|
| 24 |
-type Matcher interface {
|
|
| 25 |
- // Matches returns whether y is a match. |
|
| 26 |
- Matches(x interface{}) bool
|
|
| 27 |
- |
|
| 28 |
- // String describes what the matcher matches. |
|
| 29 |
- String() string |
|
| 30 |
-} |
|
| 31 |
- |
|
| 32 |
-type anyMatcher struct{}
|
|
| 33 |
- |
|
| 34 |
-func (anyMatcher) Matches(x interface{}) bool {
|
|
| 35 |
- return true |
|
| 36 |
-} |
|
| 37 |
- |
|
| 38 |
-func (anyMatcher) String() string {
|
|
| 39 |
- return "is anything" |
|
| 40 |
-} |
|
| 41 |
- |
|
| 42 |
-type eqMatcher struct {
|
|
| 43 |
- x interface{}
|
|
| 44 |
-} |
|
| 45 |
- |
|
| 46 |
-func (e eqMatcher) Matches(x interface{}) bool {
|
|
| 47 |
- return reflect.DeepEqual(e.x, x) |
|
| 48 |
-} |
|
| 49 |
- |
|
| 50 |
-func (e eqMatcher) String() string {
|
|
| 51 |
- return fmt.Sprintf("is equal to %v", e.x)
|
|
| 52 |
-} |
|
| 53 |
- |
|
| 54 |
-type nilMatcher struct{}
|
|
| 55 |
- |
|
| 56 |
-func (nilMatcher) Matches(x interface{}) bool {
|
|
| 57 |
- if x == nil {
|
|
| 58 |
- return true |
|
| 59 |
- } |
|
| 60 |
- |
|
| 61 |
- v := reflect.ValueOf(x) |
|
| 62 |
- switch v.Kind() {
|
|
| 63 |
- case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, |
|
| 64 |
- reflect.Ptr, reflect.Slice: |
|
| 65 |
- return v.IsNil() |
|
| 66 |
- } |
|
| 67 |
- |
|
| 68 |
- return false |
|
| 69 |
-} |
|
| 70 |
- |
|
| 71 |
-func (nilMatcher) String() string {
|
|
| 72 |
- return "is nil" |
|
| 73 |
-} |
|
| 74 |
- |
|
| 75 |
-type notMatcher struct {
|
|
| 76 |
- m Matcher |
|
| 77 |
-} |
|
| 78 |
- |
|
| 79 |
-func (n notMatcher) Matches(x interface{}) bool {
|
|
| 80 |
- return !n.m.Matches(x) |
|
| 81 |
-} |
|
| 82 |
- |
|
| 83 |
-func (n notMatcher) String() string {
|
|
| 84 |
- // TODO: Improve this if we add a NotString method to the Matcher interface. |
|
| 85 |
- return "not(" + n.m.String() + ")"
|
|
| 86 |
-} |
|
| 87 |
- |
|
| 88 |
-// Constructors |
|
| 89 |
-func Any() Matcher { return anyMatcher{} }
|
|
| 90 |
-func Eq(x interface{}) Matcher { return eqMatcher{x} }
|
|
| 91 |
-func Nil() Matcher { return nilMatcher{} }
|
|
| 92 |
-func Not(x interface{}) Matcher {
|
|
| 93 |
- if m, ok := x.(Matcher); ok {
|
|
| 94 |
- return notMatcher{m}
|
|
| 95 |
- } |
|
| 96 |
- return notMatcher{Eq(x)}
|
|
| 97 |
-} |