Redefining Go Functions

pboyd.io

38 points by todsacerdoti 3 hours ago


nasretdinov - 28 minutes ago

I've used a different approach to this: there's no real need to modify the compiled binary code because Go compiles everything from source, so you can patch the functions at the source level instead: https://github.com/YuriyNasretdinov/golang-soft-mocks

The way it works is that at the start of every function it adds an if statement that atomically checks whether or not the function has been intercepted, and if it did, then executes the replacement function instead.

My tool no longer works since it was rewriting GOPATH, and Go since effectively switched to Go Modules, but if you're persistent enough you can make it work with Go modules too — all you need to do is rewrite the Go module cache instead of GOPATH and you're good to go.

MadVikingGod - 2 hours ago

This is all possible and quite neat to dive into the specifics, but if you really want to be able swap a std lib call, just turn it into a variable and change it.

  // code.go
  var now = time.Now

  // code_test.go
  func TestCode(t *testing.T) {
      nowSwap := now
      t.Cleanup (func() {
          now = nowSwap
      }
      now = func() time.Time {
          return time.Date(...)
      }
  }

Examples Code: https://github.com/open-telemetry/opentelemetry-go/blob/main... Test: https://github.com/open-telemetry/opentelemetry-go/blob/490f...
jerf - 2 hours ago

Other prior art: https://github.com/bouk/monkey with accompanying blog post https://bou.ke/blog/monkey-patching-in-go/

pstuart - 2 hours ago

Yikes, I don't see any legitimate use for this, other than hacking for the sake of hacking. Interesting read though.