delve/service/test/common_test.go
Alessandro Arzilli ccf57b9454 terminal: let 'list' work on file:line exprs that don't map to code (#1728)
Make the 'list' command succeed for file:line expressions that don't
map to any instruction.
Adds an argument to the FindLocations API call that makes FindLocations
return if the expression can be parsed, even if it doesn't end up
matching any instruction in debug_line.
2019-10-25 09:59:18 -07:00

134 lines
3.0 KiB
Go

package service_test
import (
"fmt"
"os"
"path/filepath"
"runtime"
"strings"
"testing"
"github.com/go-delve/delve/service/api"
)
func assertNoError(err error, t *testing.T, s string) {
if err != nil {
_, file, line, _ := runtime.Caller(1)
fname := filepath.Base(file)
t.Fatalf("failed assertion at %s:%d: %s - %s\n", fname, line, s, err)
}
}
func assertError(err error, t *testing.T, s string) {
if err == nil {
_, file, line, _ := runtime.Caller(1)
fname := filepath.Base(file)
t.Fatalf("failed assertion at %s:%d: %s (no error)\n", fname, line, s)
}
if strings.Contains(err.Error(), "Internal debugger error") {
_, file, line, _ := runtime.Caller(1)
fname := filepath.Base(file)
t.Fatalf("failed assertion at %s:%d: %s internal debugger error: %v\n", fname, line, s, err)
}
}
func init() {
runtime.GOMAXPROCS(2)
}
type nextTest struct {
begin, end int
}
func testProgPath(t *testing.T, name string) string {
fp, err := filepath.Abs(fmt.Sprintf("_fixtures/%s.go", name))
if err != nil {
t.Fatal(err)
}
if _, err := os.Stat(fp); err != nil {
fp, err = filepath.Abs(fmt.Sprintf("../../_fixtures/%s.go", name))
if err != nil {
t.Fatal(err)
}
}
sympath, err := filepath.EvalSymlinks(fp)
if err == nil {
fp = strings.Replace(sympath, "\\", "/", -1)
}
return fp
}
type BreakpointLister interface {
ListBreakpoints() ([]*api.Breakpoint, error)
}
func countBreakpoints(t *testing.T, c BreakpointLister) int {
bps, err := c.ListBreakpoints()
assertNoError(err, t, "ListBreakpoints()")
bpcount := 0
for _, bp := range bps {
if bp.ID >= 0 {
bpcount++
}
}
return bpcount
}
type locationFinder1 interface {
FindLocation(api.EvalScope, string) ([]api.Location, error)
}
type locationFinder2 interface {
FindLocation(api.EvalScope, string, bool) ([]api.Location, error)
}
func findLocationHelper(t *testing.T, c interface{}, loc string, shouldErr bool, count int, checkAddr uint64) []uint64 {
var locs []api.Location
var err error
switch c := c.(type) {
case locationFinder1:
locs, err = c.FindLocation(api.EvalScope{-1, 0, 0}, loc)
case locationFinder2:
locs, err = c.FindLocation(api.EvalScope{-1, 0, 0}, loc, false)
default:
t.Errorf("unexpected type %T passed to findLocationHelper", c)
}
t.Logf("FindLocation(\"%s\") → %v\n", loc, locs)
if shouldErr {
if err == nil {
t.Fatalf("Resolving location <%s> didn't return an error: %v", loc, locs)
}
} else {
if err != nil {
t.Fatalf("Error resolving location <%s>: %v", loc, err)
}
}
if (count >= 0) && (len(locs) != count) {
t.Fatalf("Wrong number of breakpoints returned for location <%s> (got %d, expected %d)", loc, len(locs), count)
}
if checkAddr != 0 && checkAddr != locs[0].PC {
t.Fatalf("Wrong address returned for location <%s> (got %#x, expected %#x)", loc, locs[0].PC, checkAddr)
}
addrs := make([]uint64, len(locs))
for i := range locs {
addrs[i] = locs[i].PC
}
return addrs
}
func getCurinstr(d3 api.AsmInstructions) *api.AsmInstruction {
for i := range d3 {
if d3[i].AtPC {
return &d3[i]
}
}
return nil
}