Skip to content
This repository was archived by the owner on Jun 27, 2023. It is now read-only.

Commit 7251cb7

Browse files
committed
More info when Do func has wrong signature
Catch panic and show a terser call stack and the file and line number of the function that has the wrong arguments Before: ``` ... Test Panicked reflect: Call using *[]*models.ImageDefinition as type int /usr/local/Cellar/go/1.10/libexec/src/runtime/panic.go:505 Full Stack Trace /usr/local/Cellar/go/1.10/libexec/src/runtime/panic.go:505 +0x229 reflect.Value.call(0x4889200, 0x49e60c0, 0x13, 0x49b4159, 0x4, 0xc4203c1c20, 0x3, 0x3, 0x49af000, 0x485f4c0, ...) /usr/local/Cellar/go/1.10/libexec/src/reflect/value.go:377 +0x1202 reflect.Value.Call(0x4889200, 0x49e60c0, 0x13, 0xc4203c1c20, 0x3, 0x3, 0x94, 0x0, 0x0) /usr/local/Cellar/go/1.10/libexec/src/reflect/value.go:308 +0xa4 git.corp.adobe.com/adobe-platform/flight-director/vendor/github.com/golang/mock/gomock.(*Call).Do.func1(0xc4202126c0, 0x3, 0x4, 0xc4201b7e40, 0x2, 0x2) /Users/abramowi/go/src/git.corp.adobe.com/adobe-platform/flight-director/vendor/github.com/golang/mock/gomock/call.go:154 +0x23f git.corp.adobe.com/adobe-platform/flight-director/vendor/github.com/golang/mock/gomock.(*Controller).Call(0xc420177230, 0x4913f80, 0xc42007f7a0, 0x49b5a9c, 0x6, 0xc4202126c0, 0x3, 0x4, 0x0, 0x0, ...) /Users/abramowi/go/src/git.corp.adobe.com/adobe-platform/flight-director/vendor/github.com/golang/mock/gomock/controller.go:170 +0x167 git.corp.adobe.com/adobe-platform/flight-director/mocks/shared/db.(*MockWrapper).Select(0xc42007f7a0, 0x4829a00, 0xc420212620, 0xc4201de180, 0x34, 0xc420478520, 0x1, 0x1, 0x40133b8, 0x120, ...) /Users/abramowi/go/src/git.corp.adobe.com/adobe-platform/flight-director/mocks/shared/db/wrapper.go:82 +0x218 git.corp.adobe.com/adobe-platform/flight-director/shared/db.(*QueryFilter).SelectIntoEntities(0xc420334988, 0x4a70c00, 0xc42007f7a0, 0x4829a00, 0xc420212620, 0x1, 0x0) /Users/abramowi/go/src/git.corp.adobe.com/adobe-platform/flight-director/shared/db/query_filter.go:74 +0x202 ... ``` After: ``` ... reflect: Call using *[]*models.ImageDefinition as type int (incorrect func args at /Users/abramowi/go/src/git.corp.adobe.com/adobe-platform/flight-director/server/routes/deploys/handlers_test.go:71?) git.corp.adobe.com/adobe-platform/flight-director/shared/db.(*QueryFilter).SelectIntoEntities /Users/abramowi/go/src/git.corp.adobe.com/adobe-platform/flight-director/shared/db/query_filter.go:74 ... ```
1 parent dd8d2a2 commit 7251cb7

File tree

1 file changed

+42
-1
lines changed

1 file changed

+42
-1
lines changed

gomock/call.go

+42-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ package gomock
1717
import (
1818
"fmt"
1919
"reflect"
20+
"runtime"
2021
"strconv"
2122
"strings"
2223
)
@@ -149,6 +150,27 @@ func (c *Call) Do(f interface{}) *Call {
149150
vargs[i] = reflect.Zero(ft.In(i))
150151
}
151152
}
153+
defer func() {
154+
if r := recover(); r != nil {
155+
errMsg, ok := r.(string)
156+
157+
// We only handle a very specific panic
158+
// If it's not that one, then we "rethrow" the panic
159+
// This allows users to use functions that panic in their tests
160+
if !ok {
161+
panic(r)
162+
}
163+
if !strings.Contains(errMsg, "reflect: Call using") &&
164+
!strings.Contains(errMsg, "reflect.Set: value of") {
165+
panic(r)
166+
}
167+
skipFrames := 8
168+
stackTraceStr := "\n\n" + currentStackTrace(skipFrames)
169+
funcPC := v.Pointer()
170+
file, line := runtime.FuncForPC(funcPC).FileLine(funcPC)
171+
c.t.Fatalf("%s (incorrect func args at %s:%d?)%+v", errMsg, file, line, stackTraceStr)
172+
}
173+
}()
152174
v.Call(vargs)
153175
return nil
154176
})
@@ -239,6 +261,25 @@ func (c *Call) SetArg(n int, value interface{}) *Call {
239261
case reflect.Slice:
240262
setSlice(args[n], v)
241263
default:
264+
defer func() {
265+
if r := recover(); r != nil {
266+
errMsg, ok := r.(string)
267+
268+
// We only handle a very specific panic
269+
// If it's not that one, then we "rethrow" the panic
270+
// This allows users to use functions that panic in their tests
271+
if !ok {
272+
panic(r)
273+
}
274+
if !strings.Contains(errMsg, "reflect: Call using") &&
275+
!strings.Contains(errMsg, "reflect.Set: value of") {
276+
panic(r)
277+
}
278+
skipFrames := 8
279+
stackTraceStr := "\n\n" + currentStackTrace(skipFrames)
280+
c.t.Fatalf("%s%+v", errMsg, stackTraceStr)
281+
}
282+
}()
242283
reflect.ValueOf(args[n]).Elem().Set(v)
243284
}
244285
return nil
@@ -382,7 +423,7 @@ func (c *Call) matches(args []interface{}) error {
382423

383424
// Check that the call is not exhausted.
384425
if c.exhausted() {
385-
return fmt.Errorf("Expected call at %s has already been called the max number of times.", c.origin)
426+
return fmt.Errorf("Expected call at %s has already been called the max number of times (%d).", c.origin, c.maxCalls)
386427
}
387428

388429
return nil

0 commit comments

Comments
 (0)