mirror of
				https://github.com/go-delve/delve.git
				synced 2025-10-31 10:47:27 +08:00 
			
		
		
		
	Consolidate test support/setup
Add a test support package which allows shared test functionality for both the unit and integration tests. Tests importing the proctl/test package will gain access to a special test entrypoint which precompiles fixtures and makes them available to tests.
This commit is contained in:
		| @ -3,29 +3,29 @@ package proctl | |||||||
| import ( | import ( | ||||||
| 	"bytes" | 	"bytes" | ||||||
| 	"encoding/binary" | 	"encoding/binary" | ||||||
| 	"os" |  | ||||||
| 	"os/exec" |  | ||||||
| 	"path/filepath" | 	"path/filepath" | ||||||
| 	"runtime" | 	"runtime" | ||||||
| 	"testing" | 	"testing" | ||||||
|  |  | ||||||
|  | 	protest "github.com/derekparker/delve/proctl/test" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func withTestProcess(name string, t *testing.T, fn func(p *DebuggedProcess)) { | func TestMain(m *testing.M) { | ||||||
| 	runtime.LockOSThread() | 	protest.RunTestsWithFixtures(m) | ||||||
| 	base := filepath.Base(name) | } | ||||||
| 	if err := exec.Command("go", "build", "-gcflags=-N -l", "-o", base, name+".go").Run(); err != nil { |  | ||||||
| 		t.Fatalf("Could not compile %s due to %s", name, err) |  | ||||||
| 	} |  | ||||||
| 	defer os.Remove("./" + base) |  | ||||||
|  |  | ||||||
| 	p, err := Launch([]string{"./" + base}) | func withTestProcess(name string, t *testing.T, fn func(p *DebuggedProcess, fixture protest.Fixture)) { | ||||||
|  | 	runtime.LockOSThread() | ||||||
|  |  | ||||||
|  | 	fixture := protest.Fixtures[name] | ||||||
|  | 	p, err := Launch([]string{fixture.Path}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatal("Launch():", err) | 		t.Fatal("Launch():", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	defer p.Process.Kill() | 	defer p.Process.Kill() | ||||||
|  |  | ||||||
| 	fn(p) | 	fn(p, fixture) | ||||||
| } | } | ||||||
|  |  | ||||||
| func getRegisters(p *DebuggedProcess, t *testing.T) Registers { | func getRegisters(p *DebuggedProcess, t *testing.T) Registers { | ||||||
| @ -72,7 +72,7 @@ func currentLineNumber(p *DebuggedProcess, t *testing.T) (string, int) { | |||||||
| } | } | ||||||
|  |  | ||||||
| func TestExit(t *testing.T) { | func TestExit(t *testing.T) { | ||||||
| 	withTestProcess("../_fixtures/continuetestprog", t, func(p *DebuggedProcess) { | 	withTestProcess("continuetestprog", t, func(p *DebuggedProcess, fixture protest.Fixture) { | ||||||
| 		err := p.Continue() | 		err := p.Continue() | ||||||
| 		pe, ok := err.(ProcessExitedError) | 		pe, ok := err.(ProcessExitedError) | ||||||
| 		if !ok { | 		if !ok { | ||||||
| @ -88,7 +88,7 @@ func TestExit(t *testing.T) { | |||||||
| } | } | ||||||
|  |  | ||||||
| func TestHalt(t *testing.T) { | func TestHalt(t *testing.T) { | ||||||
| 	withTestProcess("../_fixtures/testprog", t, func(p *DebuggedProcess) { | 	withTestProcess("testprog", t, func(p *DebuggedProcess, fixture protest.Fixture) { | ||||||
| 		go func() { | 		go func() { | ||||||
| 			for { | 			for { | ||||||
| 				if p.Running() { | 				if p.Running() { | ||||||
| @ -117,7 +117,7 @@ func TestHalt(t *testing.T) { | |||||||
| } | } | ||||||
|  |  | ||||||
| func TestStep(t *testing.T) { | func TestStep(t *testing.T) { | ||||||
| 	withTestProcess("../_fixtures/testprog", t, func(p *DebuggedProcess) { | 	withTestProcess("testprog", t, func(p *DebuggedProcess, fixture protest.Fixture) { | ||||||
| 		helloworldfunc := p.goSymTable.LookupFunc("main.helloworld") | 		helloworldfunc := p.goSymTable.LookupFunc("main.helloworld") | ||||||
| 		helloworldaddr := helloworldfunc.Entry | 		helloworldaddr := helloworldfunc.Entry | ||||||
|  |  | ||||||
| @ -139,7 +139,7 @@ func TestStep(t *testing.T) { | |||||||
| } | } | ||||||
|  |  | ||||||
| func TestBreakPoint(t *testing.T) { | func TestBreakPoint(t *testing.T) { | ||||||
| 	withTestProcess("../_fixtures/testprog", t, func(p *DebuggedProcess) { | 	withTestProcess("testprog", t, func(p *DebuggedProcess, fixture protest.Fixture) { | ||||||
| 		helloworldfunc := p.goSymTable.LookupFunc("main.helloworld") | 		helloworldfunc := p.goSymTable.LookupFunc("main.helloworld") | ||||||
| 		helloworldaddr := helloworldfunc.Entry | 		helloworldaddr := helloworldfunc.Entry | ||||||
|  |  | ||||||
| @ -160,7 +160,7 @@ func TestBreakPoint(t *testing.T) { | |||||||
| } | } | ||||||
|  |  | ||||||
| func TestBreakPointInSeperateGoRoutine(t *testing.T) { | func TestBreakPointInSeperateGoRoutine(t *testing.T) { | ||||||
| 	withTestProcess("../_fixtures/testthreads", t, func(p *DebuggedProcess) { | 	withTestProcess("testthreads", t, func(p *DebuggedProcess, fixture protest.Fixture) { | ||||||
| 		fn := p.goSymTable.LookupFunc("main.anotherthread") | 		fn := p.goSymTable.LookupFunc("main.anotherthread") | ||||||
| 		if fn == nil { | 		if fn == nil { | ||||||
| 			t.Fatal("No fn exists") | 			t.Fatal("No fn exists") | ||||||
| @ -189,7 +189,7 @@ func TestBreakPointInSeperateGoRoutine(t *testing.T) { | |||||||
| } | } | ||||||
|  |  | ||||||
| func TestBreakPointWithNonExistantFunction(t *testing.T) { | func TestBreakPointWithNonExistantFunction(t *testing.T) { | ||||||
| 	withTestProcess("../_fixtures/testprog", t, func(p *DebuggedProcess) { | 	withTestProcess("testprog", t, func(p *DebuggedProcess, fixture protest.Fixture) { | ||||||
| 		_, err := p.Break(0) | 		_, err := p.Break(0) | ||||||
| 		if err == nil { | 		if err == nil { | ||||||
| 			t.Fatal("Should not be able to break at non existant function") | 			t.Fatal("Should not be able to break at non existant function") | ||||||
| @ -198,7 +198,7 @@ func TestBreakPointWithNonExistantFunction(t *testing.T) { | |||||||
| } | } | ||||||
|  |  | ||||||
| func TestClearBreakPoint(t *testing.T) { | func TestClearBreakPoint(t *testing.T) { | ||||||
| 	withTestProcess("../_fixtures/testprog", t, func(p *DebuggedProcess) { | 	withTestProcess("testprog", t, func(p *DebuggedProcess, fixture protest.Fixture) { | ||||||
| 		fn := p.goSymTable.LookupFunc("main.sleepytime") | 		fn := p.goSymTable.LookupFunc("main.sleepytime") | ||||||
| 		bp, err := p.Break(fn.Entry) | 		bp, err := p.Break(fn.Entry) | ||||||
| 		assertNoError(err, t, "Break()") | 		assertNoError(err, t, "Break()") | ||||||
| @ -227,8 +227,7 @@ type nextTest struct { | |||||||
| } | } | ||||||
|  |  | ||||||
| func testnext(testcases []nextTest, initialLocation string, t *testing.T) { | func testnext(testcases []nextTest, initialLocation string, t *testing.T) { | ||||||
| 	var executablePath = "../_fixtures/testnextprog" | 	withTestProcess("testnextprog", t, func(p *DebuggedProcess, fixture protest.Fixture) { | ||||||
| 	withTestProcess(executablePath, t, func(p *DebuggedProcess) { |  | ||||||
| 		bp, err := p.BreakByLocation(initialLocation) | 		bp, err := p.BreakByLocation(initialLocation) | ||||||
| 		assertNoError(err, t, "Break()") | 		assertNoError(err, t, "Break()") | ||||||
| 		assertNoError(p.Continue(), t, "Continue()") | 		assertNoError(p.Continue(), t, "Continue()") | ||||||
| @ -298,8 +297,7 @@ func TestNextFunctionReturn(t *testing.T) { | |||||||
| } | } | ||||||
|  |  | ||||||
| func TestRuntimeBreakpoint(t *testing.T) { | func TestRuntimeBreakpoint(t *testing.T) { | ||||||
| 	var testfile, _ = filepath.Abs("../_fixtures/testruntimebreakpoint") | 	withTestProcess("testruntimebreakpoint", t, func(p *DebuggedProcess, fixture protest.Fixture) { | ||||||
| 	withTestProcess(testfile, t, func(p *DebuggedProcess) { |  | ||||||
| 		err := p.Continue() | 		err := p.Continue() | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			t.Fatal(err) | 			t.Fatal(err) | ||||||
| @ -316,16 +314,13 @@ func TestRuntimeBreakpoint(t *testing.T) { | |||||||
| } | } | ||||||
|  |  | ||||||
| func TestFindReturnAddress(t *testing.T) { | func TestFindReturnAddress(t *testing.T) { | ||||||
| 	var testfile, _ = filepath.Abs("../_fixtures/testnextprog") | 	withTestProcess("testnextprog", t, func(p *DebuggedProcess, fixture protest.Fixture) { | ||||||
|  |  | ||||||
| 	withTestProcess(testfile, t, func(p *DebuggedProcess) { |  | ||||||
| 		var ( | 		var ( | ||||||
| 			fdes = p.frameEntries | 			fdes = p.frameEntries | ||||||
| 			gsd  = p.goSymTable | 			gsd  = p.goSymTable | ||||||
| 		) | 		) | ||||||
|  |  | ||||||
| 		testsourcefile := testfile + ".go" | 		start, _, err := gsd.LineToPC(fixture.Source, 24) | ||||||
| 		start, _, err := gsd.LineToPC(testsourcefile, 24) |  | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			t.Fatal(err) | 			t.Fatal(err) | ||||||
| 		} | 		} | ||||||
| @ -369,9 +364,7 @@ func TestFindReturnAddress(t *testing.T) { | |||||||
| } | } | ||||||
|  |  | ||||||
| func TestSwitchThread(t *testing.T) { | func TestSwitchThread(t *testing.T) { | ||||||
| 	var testfile, _ = filepath.Abs("../_fixtures/testnextprog") | 	withTestProcess("testnextprog", t, func(p *DebuggedProcess, fixture protest.Fixture) { | ||||||
|  |  | ||||||
| 	withTestProcess(testfile, t, func(p *DebuggedProcess) { |  | ||||||
| 		// With invalid thread id | 		// With invalid thread id | ||||||
| 		err := p.SwitchThread(-1) | 		err := p.SwitchThread(-1) | ||||||
| 		if err == nil { | 		if err == nil { | ||||||
| @ -412,9 +405,7 @@ func TestSwitchThread(t *testing.T) { | |||||||
| } | } | ||||||
|  |  | ||||||
| func TestFunctionCall(t *testing.T) { | func TestFunctionCall(t *testing.T) { | ||||||
| 	var testfile, _ = filepath.Abs("../_fixtures/testprog") | 	withTestProcess("testprog", t, func(p *DebuggedProcess, fixture protest.Fixture) { | ||||||
|  |  | ||||||
| 	withTestProcess(testfile, t, func(p *DebuggedProcess) { |  | ||||||
| 		pc, err := p.FindLocation("main.main") | 		pc, err := p.FindLocation("main.main") | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			t.Fatal(err) | 			t.Fatal(err) | ||||||
|  | |||||||
							
								
								
									
										87
									
								
								proctl/test/support.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								proctl/test/support.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,87 @@ | |||||||
|  | package test | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"crypto/rand" | ||||||
|  | 	"encoding/hex" | ||||||
|  | 	"fmt" | ||||||
|  | 	"io/ioutil" | ||||||
|  | 	"os" | ||||||
|  | 	"os/exec" | ||||||
|  | 	"path/filepath" | ||||||
|  | 	"strings" | ||||||
|  | 	"testing" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // Fixture is a test binary. | ||||||
|  | type Fixture struct { | ||||||
|  | 	// Name is the short name of the fixture. | ||||||
|  | 	Name string | ||||||
|  | 	// Path is the absolute path to the test binary. | ||||||
|  | 	Path string | ||||||
|  | 	// Source is the absolute path of the test binary source. | ||||||
|  | 	Source string | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Fixtures is a map of Fixture.Name to Fixture. | ||||||
|  | var Fixtures map[string]Fixture = make(map[string]Fixture) | ||||||
|  |  | ||||||
|  | // RunTestsWithFixtures will pre-compile test fixtures before running test | ||||||
|  | // methods. Test binaries are deleted before exiting. | ||||||
|  | func RunTestsWithFixtures(m *testing.M) { | ||||||
|  | 	// Find the fixtures directory; this is necessary because the test file's | ||||||
|  | 	// nesting level can vary. Only look up to a maxdepth of 10 (which seems | ||||||
|  | 	// like a sane alternative to recursion). | ||||||
|  | 	parent := ".." | ||||||
|  | 	fixturesDir := filepath.Join(parent, "_fixtures") | ||||||
|  | 	for depth := 0; depth < 10; depth++ { | ||||||
|  | 		if _, err := os.Stat(fixturesDir); err == nil { | ||||||
|  | 			break | ||||||
|  | 		} | ||||||
|  | 		fixturesDir = filepath.Join("..", fixturesDir) | ||||||
|  | 	} | ||||||
|  | 	if _, err := os.Stat(fixturesDir); err != nil { | ||||||
|  | 		fmt.Println("Couldn't locate fixtures directory") | ||||||
|  | 		os.Exit(1) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Collect all files which look like fixture source files. | ||||||
|  | 	sources, err := ioutil.ReadDir(fixturesDir) | ||||||
|  | 	if err != nil { | ||||||
|  | 		fmt.Printf("Couldn't read fixtures dir: %v\n", err) | ||||||
|  | 		os.Exit(1) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Compile the fixtures. | ||||||
|  | 	for _, src := range sources { | ||||||
|  | 		if src.IsDir() { | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  | 		// Make a (good enough) random temporary file name | ||||||
|  | 		r := make([]byte, 4) | ||||||
|  | 		rand.Read(r) | ||||||
|  | 		path := filepath.Join(fixturesDir, src.Name()) | ||||||
|  | 		name := strings.TrimSuffix(src.Name(), filepath.Ext(src.Name())) | ||||||
|  | 		tmpfile := filepath.Join(os.TempDir(), fmt.Sprintf("%s.%s", name, hex.EncodeToString(r))) | ||||||
|  |  | ||||||
|  | 		// Build the test binary | ||||||
|  | 		if err := exec.Command("go", "build", "-gcflags=-N -l", "-o", tmpfile, path).Run(); err != nil { | ||||||
|  | 			fmt.Printf("Error compiling %s: %s\n", path, err) | ||||||
|  | 			os.Exit(1) | ||||||
|  | 		} | ||||||
|  | 		fmt.Printf("Compiled test binary %s: %s\n", name, tmpfile) | ||||||
|  |  | ||||||
|  | 		source, _ := filepath.Abs(path) | ||||||
|  | 		Fixtures[name] = Fixture{Name: name, Path: tmpfile, Source: source} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	status := m.Run() | ||||||
|  |  | ||||||
|  | 	// Remove the fixtures. | ||||||
|  | 	// TODO(danmace): Not sure why yet, but doing these removes in a defer isn't | ||||||
|  | 	// working. | ||||||
|  | 	for _, f := range Fixtures { | ||||||
|  | 		os.Remove(f.Path) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	os.Exit(status) | ||||||
|  | } | ||||||
| @ -2,9 +2,10 @@ package proctl | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"path/filepath" |  | ||||||
| 	"sort" | 	"sort" | ||||||
| 	"testing" | 	"testing" | ||||||
|  |  | ||||||
|  | 	protest "github.com/derekparker/delve/proctl/test" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| type varTest struct { | type varTest struct { | ||||||
| @ -29,13 +30,6 @@ func assertVariable(t *testing.T, variable *Variable, expected varTest) { | |||||||
| } | } | ||||||
|  |  | ||||||
| func TestVariableEvaluation(t *testing.T) { | func TestVariableEvaluation(t *testing.T) { | ||||||
| 	executablePath := "../_fixtures/testvariables" |  | ||||||
|  |  | ||||||
| 	fp, err := filepath.Abs(executablePath + ".go") |  | ||||||
| 	if err != nil { |  | ||||||
| 		t.Fatal(err) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	testcases := []varTest{ | 	testcases := []varTest{ | ||||||
| 		{"a1", "foofoofoofoofoofoo", "struct string", nil}, | 		{"a1", "foofoofoofoofoofoo", "struct string", nil}, | ||||||
| 		{"a10", "ofo", "struct string", nil}, | 		{"a10", "ofo", "struct string", nil}, | ||||||
| @ -73,8 +67,8 @@ func TestVariableEvaluation(t *testing.T) { | |||||||
| 		{"NonExistent", "", "", fmt.Errorf("could not find symbol value for NonExistent")}, | 		{"NonExistent", "", "", fmt.Errorf("could not find symbol value for NonExistent")}, | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	withTestProcess(executablePath, t, func(p *DebuggedProcess) { | 	withTestProcess("testvariables", t, func(p *DebuggedProcess, fixture protest.Fixture) { | ||||||
| 		pc, _, _ := p.goSymTable.LineToPC(fp, 57) | 		pc, _, _ := p.goSymTable.LineToPC(fixture.Source, 57) | ||||||
|  |  | ||||||
| 		_, err := p.Break(pc) | 		_, err := p.Break(pc) | ||||||
| 		assertNoError(err, t, "Break() returned an error") | 		assertNoError(err, t, "Break() returned an error") | ||||||
| @ -97,15 +91,8 @@ func TestVariableEvaluation(t *testing.T) { | |||||||
| } | } | ||||||
|  |  | ||||||
| func TestVariableFunctionScoping(t *testing.T) { | func TestVariableFunctionScoping(t *testing.T) { | ||||||
| 	executablePath := "../_fixtures/testvariables" | 	withTestProcess("testvariables", t, func(p *DebuggedProcess, fixture protest.Fixture) { | ||||||
|  | 		pc, _, _ := p.goSymTable.LineToPC(fixture.Source, 57) | ||||||
| 	fp, err := filepath.Abs(executablePath + ".go") |  | ||||||
| 	if err != nil { |  | ||||||
| 		t.Fatal(err) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	withTestProcess(executablePath, t, func(p *DebuggedProcess) { |  | ||||||
| 		pc, _, _ := p.goSymTable.LineToPC(fp, 57) |  | ||||||
|  |  | ||||||
| 		_, err := p.Break(pc) | 		_, err := p.Break(pc) | ||||||
| 		assertNoError(err, t, "Break() returned an error") | 		assertNoError(err, t, "Break() returned an error") | ||||||
| @ -121,7 +108,7 @@ func TestVariableFunctionScoping(t *testing.T) { | |||||||
| 		assertNoError(err, t, "Unable to find variable a1") | 		assertNoError(err, t, "Unable to find variable a1") | ||||||
|  |  | ||||||
| 		// Move scopes, a1 exists here by a2 does not | 		// Move scopes, a1 exists here by a2 does not | ||||||
| 		pc, _, _ = p.goSymTable.LineToPC(fp, 23) | 		pc, _, _ = p.goSymTable.LineToPC(fixture.Source, 23) | ||||||
|  |  | ||||||
| 		_, err = p.Break(pc) | 		_, err = p.Break(pc) | ||||||
| 		assertNoError(err, t, "Break() returned an error") | 		assertNoError(err, t, "Break() returned an error") | ||||||
| @ -157,13 +144,6 @@ func (s varArray) Less(i, j int) bool { | |||||||
| } | } | ||||||
|  |  | ||||||
| func TestLocalVariables(t *testing.T) { | func TestLocalVariables(t *testing.T) { | ||||||
| 	executablePath := "../_fixtures/testvariables" |  | ||||||
|  |  | ||||||
| 	fp, err := filepath.Abs(executablePath + ".go") |  | ||||||
| 	if err != nil { |  | ||||||
| 		t.Fatal(err) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	testcases := []struct { | 	testcases := []struct { | ||||||
| 		fn     func(*ThreadContext) ([]*Variable, error) | 		fn     func(*ThreadContext) ([]*Variable, error) | ||||||
| 		output []varTest | 		output []varTest | ||||||
| @ -203,8 +183,8 @@ func TestLocalVariables(t *testing.T) { | |||||||
| 				{"baz", "bazburzum", "struct string", nil}}}, | 				{"baz", "bazburzum", "struct string", nil}}}, | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	withTestProcess(executablePath, t, func(p *DebuggedProcess) { | 	withTestProcess("testvariables", t, func(p *DebuggedProcess, fixture protest.Fixture) { | ||||||
| 		pc, _, _ := p.goSymTable.LineToPC(fp, 57) | 		pc, _, _ := p.goSymTable.LineToPC(fixture.Source, 57) | ||||||
|  |  | ||||||
| 		_, err := p.Break(pc) | 		_, err := p.Break(pc) | ||||||
| 		assertNoError(err, t, "Break() returned an error") | 		assertNoError(err, t, "Break() returned an error") | ||||||
|  | |||||||
| @ -1,58 +1,16 @@ | |||||||
| package rest | package rest | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"crypto/rand" |  | ||||||
| 	"encoding/hex" |  | ||||||
| 	"fmt" |  | ||||||
| 	"io/ioutil" |  | ||||||
| 	"net" | 	"net" | ||||||
| 	"os" |  | ||||||
| 	"os/exec" |  | ||||||
| 	"path/filepath" |  | ||||||
| 	"strings" |  | ||||||
| 	"testing" | 	"testing" | ||||||
|  |  | ||||||
|  | 	protest "github.com/derekparker/delve/proctl/test" | ||||||
| 	"github.com/derekparker/delve/service" | 	"github.com/derekparker/delve/service" | ||||||
| 	"github.com/derekparker/delve/service/api" | 	"github.com/derekparker/delve/service/api" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var fixtures map[string]string = make(map[string]string) |  | ||||||
|  |  | ||||||
| func TestMain(m *testing.M) { | func TestMain(m *testing.M) { | ||||||
| 	fixturesDir := "../../_fixtures" | 	protest.RunTestsWithFixtures(m) | ||||||
| 	sources, err := ioutil.ReadDir(fixturesDir) |  | ||||||
| 	if err != nil { |  | ||||||
| 		fmt.Printf("Couldn't read fixtures dir: %v\n", err) |  | ||||||
| 		os.Exit(1) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	for _, src := range sources { |  | ||||||
| 		if src.IsDir() { |  | ||||||
| 			continue |  | ||||||
| 		} |  | ||||||
| 		// Make a (good enough) random temporary file name |  | ||||||
| 		r := make([]byte, 4) |  | ||||||
| 		rand.Read(r) |  | ||||||
| 		path := filepath.Join(fixturesDir, src.Name()) |  | ||||||
| 		name := strings.TrimSuffix(src.Name(), filepath.Ext(src.Name())) |  | ||||||
| 		tmpfile := filepath.Join(os.TempDir(), fmt.Sprintf("%s.%s", name, hex.EncodeToString(r))) |  | ||||||
|  |  | ||||||
| 		// Build the test binary |  | ||||||
| 		if err := exec.Command("go", "build", "-gcflags=-N -l", "-o", tmpfile, path).Run(); err != nil { |  | ||||||
| 			fmt.Printf("Error compiling %s: %s\n", path, err) |  | ||||||
| 			os.Exit(1) |  | ||||||
| 		} |  | ||||||
| 		fmt.Printf("Compiled test binary %s: %s\n", name, tmpfile) |  | ||||||
| 		fixtures[name] = tmpfile |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	status := m.Run() |  | ||||||
|  |  | ||||||
| 	for _, f := range fixtures { |  | ||||||
| 		os.Remove(f) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	os.Exit(status) |  | ||||||
| } | } | ||||||
|  |  | ||||||
| func withTestClient(name string, t *testing.T, fn func(c service.Client)) { | func withTestClient(name string, t *testing.T, fn func(c service.Client)) { | ||||||
| @ -60,16 +18,13 @@ func withTestClient(name string, t *testing.T, fn func(c service.Client)) { | |||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatalf("couldn't start listener: %s\n", err) | 		t.Fatalf("couldn't start listener: %s\n", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	server := NewServer(&Config{ | 	server := NewServer(&Config{ | ||||||
| 		Listener:    listener, | 		Listener:    listener, | ||||||
| 		ProcessArgs: []string{fixtures[name]}, | 		ProcessArgs: []string{protest.Fixtures[name].Path}, | ||||||
| 	}) | 	}) | ||||||
| 	go server.Run() | 	go server.Run() | ||||||
|  |  | ||||||
| 	client := NewClient(listener.Addr().String()) | 	client := NewClient(listener.Addr().String()) | ||||||
| 	defer client.Detach(true) | 	defer client.Detach(true) | ||||||
|  |  | ||||||
| 	fn(client) | 	fn(client) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 Dan Mace
					Dan Mace