Skip to content

Commit

Permalink
fix: orchestrion fail to instrument if is not in the go.mod folder (#466
Browse files Browse the repository at this point in the history
)

Load the configuration from the module root instead of the current
working directory, so that it no longer fails when building a package in
a sub-directory.

Fixes #464
  • Loading branch information
RomainMuller authored Dec 16, 2024
1 parent c28ad40 commit 0e69e71
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 16 deletions.
10 changes: 9 additions & 1 deletion internal/toolexec/aspect/oncompile.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"slices"
"strings"

"github.com/DataDog/orchestrion/internal/goenv"
"github.com/DataDog/orchestrion/internal/injector"
"github.com/DataDog/orchestrion/internal/injector/aspect"
"github.com/DataDog/orchestrion/internal/injector/config"
Expand Down Expand Up @@ -90,7 +91,14 @@ func (w Weaver) OnCompile(cmd *proxy.CompileCommand) (err error) {
err = writeLinkDeps(cmd, &linkDeps, orchestrionDir)
}()

cfg, err := config.NewLoader(".", false).Load()
goMod, err := goenv.GOMOD(".")
if err != nil {
return fmt.Errorf("go env GOMOD: %w", err)
}
goModDir := filepath.Dir(goMod)
log.Tracef("Identified module directory: %s\n", goModDir)

cfg, err := config.NewLoader(goModDir, false).Load()
if err != nil {
return fmt.Errorf("loading injector configuration: %w", err)
}
Expand Down
63 changes: 48 additions & 15 deletions main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,41 @@ import (
"golang.org/x/mod/semver"
)

type testCase interface {
func TestBuildFromModuleSubdirectory(t *testing.T) {
run := runner{dir: t.TempDir()}

run.exec(t, "go", "mod", "init", "github.com/DataDog/orchestrion.testing")
run.exec(t, "go", "mod", "edit", "-replace", fmt.Sprintf("github.com/DataDog/orchestrion=%s", rootDir))
require.NoError(t, os.Mkdir(filepath.Join(run.dir, "cmd"), 0o755))
require.NoError(t, os.WriteFile(filepath.Join(run.dir, "cmd", "main.go"), []byte(`package main
import (
"log"
"github.com/DataDog/orchestrion/runtime/built"
)
func main() {
if !built.WithOrchestrion {
log.Fatalln("Not built with orchestrion 🤨")
}
}
`), 0o644))
orchestrionBin := buildOrchestrion(t)
run.exec(t, orchestrionBin, "pin")

// Run the command from a working directory that is NOT the module root, so we can ensure the
// configuration is appopriately loaded from the module's root anyway.
runCmd := runner{dir: filepath.Join(run.dir, "cmd")}
runCmd.exec(t, orchestrionBin, "go", "run", ".")
}

type benchCase interface {
baseline(b *testing.B)
instrumented(b *testing.B)
}

var testCases = map[string]func(b *testing.B) testCase{
var benchCases = map[string]func(b *testing.B) benchCase{
"DataDog:orchestrion": benchmarkOrchestrion,
// normal build
"traefik:traefik": benchmarkGithub("traefik", "traefik", "./...", false),
Expand All @@ -41,7 +70,7 @@ var testCases = map[string]func(b *testing.B) testCase{
}

func Benchmark(b *testing.B) {
for name, create := range testCases {
for name, create := range benchCases {
b.Run(fmt.Sprintf("repo=%s", name), func(b *testing.B) {
tc := create(b)
b.Run("variant=baseline", func(b *testing.B) {
Expand All @@ -65,8 +94,8 @@ type benchGithub struct {
harness
}

func benchmarkGithub(owner string, repo string, build string, testbuild bool) func(b *testing.B) testCase {
return func(b *testing.B) testCase {
func benchmarkGithub(owner string, repo string, build string, testbuild bool) func(b *testing.B) benchCase {
return func(b *testing.B) benchCase {
b.Helper()

tc := &benchGithub{harness{build: build, testbuild: testbuild}}
Expand All @@ -89,12 +118,16 @@ type benchOrchestrion struct {
harness
}

func benchmarkOrchestrion(_ *testing.B) testCase {
return &benchOrchestrion{harness{dir: rootDir, build: ".", testbuild: false}}
func benchmarkOrchestrion(_ *testing.B) benchCase {
return &benchOrchestrion{harness{runner: runner{dir: rootDir}, build: ".", testbuild: false}}
}

type runner struct {
dir string // The directory where commands are to be executed
}

type harness struct {
dir string // The directory in which the source code of the package to be built is located.
runner
build string // The package to be built as part of the test.
testbuild bool // Whether the package to be built is a test package.
}
Expand Down Expand Up @@ -143,15 +176,15 @@ func (h *harness) instrumented(b *testing.B) {
require.NoError(b, err, "build failed:\n%s", output)
}

func (h *harness) exec(b *testing.B, name string, args ...string) {
func (r *runner) exec(tb testing.TB, name string, args ...string) {
cmd := exec.Command(name, args...)
cmd.Dir = h.dir
cmd.Env = append(os.Environ(), "GOCACHE="+b.TempDir())
cmd.Dir = r.dir
cmd.Env = append(os.Environ(), "GOCACHE="+tb.TempDir())
output := bytes.NewBuffer(make([]byte, 0, 4_096))
cmd.Stdout = output
cmd.Stderr = output

require.NoError(b, cmd.Run(), "command failed: %s\n%s", cmd, output)
require.NoError(tb, cmd.Run(), "command failed: %s\n%s", cmd, output)
}

func (*harness) findLatestGithubReleaseTag(b *testing.B, owner string, repo string) string {
Expand Down Expand Up @@ -227,14 +260,14 @@ var (
orchestrionBin string
)

func buildOrchestrion(b *testing.B) string {
b.Helper()
func buildOrchestrion(tb testing.TB) string {
tb.Helper()

orchestrionBinOnce.Do(func() {
orchestrionBin = filepath.Join(rootDir, "bin", "orchestrion.exe")

cmd := exec.Command("go", "build", fmt.Sprintf("-o=%s", orchestrionBin), rootDir)
require.NoError(b, cmd.Run())
require.NoError(tb, cmd.Run())
})

return orchestrionBin
Expand Down

0 comments on commit 0e69e71

Please sign in to comment.