Skip to content

Commit

Permalink
introduce CommandExecutor
Browse files Browse the repository at this point in the history
  • Loading branch information
pdelewski committed Aug 22, 2023
1 parent 1bf7cb0 commit 1158338
Show file tree
Hide file tree
Showing 2 changed files with 179 additions and 50 deletions.
114 changes: 112 additions & 2 deletions instrgen/driver/instrgen_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package main

import (
"bytes"
"encoding/json"
"fmt"
"os"
"path/filepath"
Expand All @@ -38,7 +39,8 @@ var testcases = map[string]string{
var failures []string

func TestCommand(t *testing.T) {
err := executeCommand("--unknown", "./testdata/basic", "testdata/basic", "yes", "main.main")
executor := &NullExecutor{}
err := executeCommand("--unknown", "./testdata/basic", "testdata/basic", "yes", "main.main", executor)
_ = err
}

Expand Down Expand Up @@ -68,6 +70,7 @@ func TestInstrumentation(t *testing.T) {
numOfFiles := len(expectedFiles)
fmt.Println("Go Files:", len(files))
fmt.Println("Expected Go Files:", len(expectedFiles))
assert.True(t, len(files) > 0)
numOfComparisons := 0
for _, file := range files {
fmt.Println(filepath.Base(file))
Expand All @@ -93,11 +96,28 @@ func TestInstrumentation(t *testing.T) {
}
}

type NullExecutor struct {
}

func (executor *NullExecutor) Execute(_ string, _ []string) {
}

func (executor *NullExecutor) Run() error {
return nil
}

func TestToolExecMain(t *testing.T) {
for k := range testcases {
var args []string
files := alib.SearchFiles(k, ".go")
args = append(args, "-o")
args = append(args, "/tmp/go-build")
args = append(args, "-p")
args = append(args, "main")
args = append(args, "-pack")
args = append(args, "-asmhdr")
args = append(args, "go_asm.h")

args = append(args, files...)
var instrgenCfg InstrgenCmd
instrgenCfg.FilePattern = k
Expand All @@ -111,15 +131,105 @@ func TestToolExecMain(t *testing.T) {
rewriterS = makeRewriters(instrgenCfg)
analyze(args, rewriterS)
}
for k := range testcases {
var args []string
files := alib.SearchFiles(k, ".go")
args = append(args, "-pack")
args = append(args, "-asmhdr")
args = append(args, "go_asm.h")
args = append(args, files...)
var instrgenCfg InstrgenCmd
instrgenCfg.FilePattern = k
instrgenCfg.EntryPoint.Pkg = "main"
instrgenCfg.EntryPoint.FunName = "main"
instrgenCfg.Replace = "no"
instrgenCfg.Cmd = "prune"
rewriterS := makeRewriters(instrgenCfg)
analyze(args, rewriterS)
instrgenCfg.Cmd = "inject"
rewriterS = makeRewriters(instrgenCfg)
analyze(args, rewriterS)
}
for k := range testcases {
var instrgenCfg InstrgenCmd
instrgenCfg.FilePattern = k
instrgenCfg.EntryPoint.Pkg = "main"
instrgenCfg.EntryPoint.FunName = "main"
instrgenCfg.Replace = "yes"
instrgenCfg.Cmd = "prune"
rewriterS := makeRewriters(instrgenCfg)
var args []string
executor := &NullExecutor{}
toolExecMain(args, rewriterS, executor)
}
}

func TestGetCommandName(t *testing.T) {
cmd := GetCommandName([]string{"/usr/local/go/compile"})
assert.True(t, cmd == "compile")
cmd = GetCommandName([]string{"/usr/local/go/compile.exe"})
assert.True(t, cmd == "compile")
cmd = GetCommandName([]string{})
assert.True(t, cmd == "")
}

func TestExecutePass(t *testing.T) {
require.NoError(t, executePass([]string{"go", "version"}))
executor := &ToolExecutor{}
require.NoError(t, executePass([]string{"go", "version"}, executor))
}

func TestDriverMain(t *testing.T) {
executor := &NullExecutor{}
for k := range testcases {
var args []string
files := alib.SearchFiles(k, ".go")
args = append(args, "-o")
args = append(args, "/tmp/go-build")
args = append(args, "-p")
args = append(args, "main")
args = append(args, "-pack")
args = append(args, "-asmhdr")
args = append(args, "go_asm.h")
args = append(args, files...)
var instrgenCfg InstrgenCmd
instrgenCfg.FilePattern = k
instrgenCfg.EntryPoint.Pkg = "main"
instrgenCfg.EntryPoint.FunName = "main"
instrgenCfg.Replace = "yes"
instrgenCfg.Cmd = "prune"
err := driverMain(args, executor)
_ = err
instrgenCfg.Cmd = "inject"
err = driverMain(args, executor)
_ = err
}
{
var args []string
args = append(args, "compile")
var instrgenCfg InstrgenCmd
instrgenCfg.FilePattern = "/testdata/basic"
instrgenCfg.EntryPoint.Pkg = "main"
instrgenCfg.EntryPoint.FunName = "main"
instrgenCfg.Replace = "yes"
instrgenCfg.Cmd = "inject"
file, _ := json.MarshalIndent(instrgenCfg, "", " ")
err := os.WriteFile("instrgen_cmd.json", file, 0644)
require.NoError(t, err)
err = driverMain(args, executor)
require.NoError(t, err)
}
for k := range testcases {
var args []string
args = append(args, "--inject")
args = append(args, k)
args = append(args, "yes")
args = append(args, "main.main")
err := driverMain(args, executor)
_ = err
}
{
var args []string
err := driverMain(args, executor)
_ = err
}
}
115 changes: 67 additions & 48 deletions instrgen/driver/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,30 @@ type InstrgenCmd struct {
EntryPoint EntryPoint
}

// CommandExecutor.
type CommandExecutor interface {
Execute(cmd string, args []string)
Run() error
}

// ToolExecutor.
type ToolExecutor struct {
cmd *exec.Cmd
}

// Wraps Execute.
func (executor *ToolExecutor) Execute(cmd string, args []string) {
executor.cmd = exec.Command(cmd, args...)
executor.cmd.Stdin = os.Stdin
executor.cmd.Stdout = os.Stdout
executor.cmd.Stderr = os.Stderr
}

// Wraps Run.
func (executor *ToolExecutor) Run() error {
return executor.cmd.Run()
}

func isDirectory(path string) (bool, error) {
fileInfo, err := os.Stat(path)
if err != nil {
Expand All @@ -61,7 +85,7 @@ func isDirectory(path string) (bool, error) {
return fileInfo.IsDir(), err
}

func executeCommand(command string, projectPath string, packagePattern string, replaceSource string, entryPoint string) error {
func executeCommand(command string, projectPath string, packagePattern string, replaceSource string, entryPoint string, executor CommandExecutor) error {
isDir, err := isDirectory(projectPath)
if !isDir {
return errors.New("[path to go project] argument must be directory")
Expand All @@ -80,13 +104,11 @@ func executeCommand(command string, projectPath string, packagePattern string, r
file, _ := json.MarshalIndent(data, "", " ")
err := os.WriteFile("instrgen_cmd.json", file, 0644)
if err != nil {
fmt.Println(err)
return err
}
cmd := exec.Command("go", "build", "-work", "-a", "-toolexec", "driver")
fmt.Println("invoke : " + cmd.String())
if err := cmd.Run(); err != nil {
fmt.Println(err)
executor.Execute("go", []string{"build", "-work", "-a", "-toolexec", "driver"})
//fmt.Println("invoke : " + executor.cmd.String())
if err := executor.Run(); err != nil {
return err
}
return nil
Expand All @@ -96,20 +118,17 @@ func executeCommand(command string, projectPath string, packagePattern string, r
}

func checkArgs(args []string) error {
if len(args) != 5 {
if len(args) != 4 {
return errors.New("wrong arguments")
}
return nil
}

func executePass(args []string) error {
func executePass(args []string, executor CommandExecutor) error {
path := args[0]
args = args[1:]
cmd := exec.Command(path, args...)
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
return cmd.Run()
executor.Execute(path, args)
return executor.Run()
}

// GetCommandName extracts command name from args.
Expand Down Expand Up @@ -142,8 +161,6 @@ func analyzePackage(rewriter alib.PackageRewriter, pkg string, filePaths map[str
for filePath, index := range filePaths {
file, err := parser.ParseFile(fset, filePath, nil, parser.ParseComments)
if err != nil {
fmt.Println(err)
// TODO handle that
continue

Check warning on line 164 in instrgen/driver/main.go

View check run for this annotation

Codecov / codecov/patch

instrgen/driver/main.go#L164

Added line #L164 was not covered by tests
}
if rewriter.Inject(pkg, filePath) {
Expand Down Expand Up @@ -226,33 +243,16 @@ func analyze(args []string, rewriterS []alib.PackageRewriter) []string {
return args
}

func toolExecMain(args []string, rewriterS []alib.PackageRewriter) {
func toolExecMain(args []string, rewriterS []alib.PackageRewriter, executor CommandExecutor) {
args = analyze(args, rewriterS)
if len(args) > 0 {
err := executePass(args[0:])
if err != nil {
fmt.Println(err)
}
} else {
usage()
}
}

func executeCommandProxy(cmdName string) {
fmt.Println("instrgen compiler")
err := checkArgs(os.Args)
if err != nil {
if len(args) == 0 {
usage()
return
}
replace := "no"
if len(os.Args) > 3 {
replace = os.Args[3]
}
err = executeCommand(os.Args[1], ".", os.Args[2], replace, os.Args[4])

err := executePass(args[0:], executor)
if err != nil {
fmt.Println(err)
return
}

Check warning on line 256 in instrgen/driver/main.go

View check run for this annotation

Codecov / codecov/patch

instrgen/driver/main.go#L255-L256

Added lines #L255 - L256 were not covered by tests
}

Expand All @@ -272,38 +272,57 @@ func makeRewriters(instrgenCfg InstrgenCmd) []alib.PackageRewriter {
return rewriterS
}

func main() {
args := os.Args[1:]
func driverMain(args []string, executor CommandExecutor) error {
cmdName := GetCommandName(args)
if cmdName != "compile" {
switch cmdName {
case "--inject", "--prune":
executeCommandProxy(cmdName)
return
fmt.Println("instrgen compiler")
err := checkArgs(args)
if err != nil {
usage()
return err
}

Check warning on line 285 in instrgen/driver/main.go

View check run for this annotation

Codecov / codecov/patch

instrgen/driver/main.go#L283-L285

Added lines #L283 - L285 were not covered by tests
replace := "no"
if len(args) > 2 {
replace = args[2]
}
err = executeCommand(args[0], ".", args[1], replace, args[3], executor)
if err != nil {
return err
}

Check warning on line 293 in instrgen/driver/main.go

View check run for this annotation

Codecov / codecov/patch

instrgen/driver/main.go#L292-L293

Added lines #L292 - L293 were not covered by tests
return nil
}
if len(args) > 0 {
err := executePass(args[0:])
err := executePass(args[0:], executor)
if err != nil {
fmt.Println(err)
return err
}

Check warning on line 300 in instrgen/driver/main.go

View check run for this annotation

Codecov / codecov/patch

instrgen/driver/main.go#L299-L300

Added lines #L299 - L300 were not covered by tests
} else {
usage()
}
return
return nil
}
content, err := os.ReadFile("./instrgen_cmd.json")
if err != nil {
fmt.Println("Error when opening file: ", err)
return
return err
}

Check warning on line 309 in instrgen/driver/main.go

View check run for this annotation

Codecov / codecov/patch

instrgen/driver/main.go#L308-L309

Added lines #L308 - L309 were not covered by tests

var instrgenCfg InstrgenCmd
err = json.Unmarshal(content, &instrgenCfg)
if err != nil {
fmt.Println("Error during Unmarshal(): ", err)
return
return err
}

Check warning on line 315 in instrgen/driver/main.go

View check run for this annotation

Codecov / codecov/patch

instrgen/driver/main.go#L314-L315

Added lines #L314 - L315 were not covered by tests

rewriterS := makeRewriters(instrgenCfg)
toolExecMain(args, rewriterS)
toolExecMain(args, rewriterS, executor)
return nil
}

func main() {
executor := &ToolExecutor{}
err := driverMain(os.Args[1:], executor)

Check warning on line 324 in instrgen/driver/main.go

View check run for this annotation

Codecov / codecov/patch

instrgen/driver/main.go#L322-L324

Added lines #L322 - L324 were not covered by tests
if err != nil {
fmt.Println(err)

Check warning on line 326 in instrgen/driver/main.go

View check run for this annotation

Codecov / codecov/patch

instrgen/driver/main.go#L326

Added line #L326 was not covered by tests
}
}

0 comments on commit 1158338

Please sign in to comment.