Giter VIP home page Giter VIP logo

monkey's Introduction

Monkey

Go Reference License: MIT Go Test

"Monkey" is a library for monkey-patching functions. This may be useful to get determined test result with functions that have side effect (like time.Now()).

Why does this library exist?

Earlier I found library github.com/bouk/monkey with same name and functionality and sometimes used it in tests. But this library was unstable, and currently it's archived. So I decided to create new one with different approach.

Usage

Monkey-patching time.Now() in tests:

package sometest

import (
	"testing"
	"time"
	
	"github.com/xakep666/monkey"
)

func init() {
	monkey.NewPatcher().
		Apply(func(patcher *monkey.Patcher) {
			monkey.RegisterReplacement(patcher, time.Now, func() time.Time {
				return time.Date(1980, 1, 2, 3, 4, 5, 6, time.UTC)
			})
		}).
		MustPatchAndExec()
}

func TestTime(t *testing.T) {
	if now := time.Now(); !now.Equal(time.Date(1980, 1, 2, 3, 4, 5, 6, time.UTC)) {
		t.Errorf("Time not patched, returned: %s", now)
	}
}

More examples can be found here.

How does it work

  • Developer register own replacements for specified functions.
  • Some checks performed i.e. for cyclic replacements.
  • Current executable copied to temporary directory. Further operations will be performed with new temporary executable.
  • Unconditional jump instructions inserted at the beginning of specified functions.
  • New patched binary executed.

To prevent recursive self-(re)start this library adds special environment variable when it starts patched binary.

Comparison with github.com/bouk/monkey

Unlike mentioned library this performs patching before binary execution. This results in major advantages but has same disadvantages.

Advantages:

  • No unsafe imported.
  • No mprotect-like system calls. Some systems refused to set writeable and executable flag on pages.
  • Process memory (executable code) not modified in runtime.
  • No data-races during patch and call processes. It follows from the previous paragraph.

Disadvantages:

  • Disk activity (writing to temporary folder).
  • Impossible to "unpatch" or somehow call original version of function.
  • Sometimes may fail to locate address of function inside executable.

Here is some points why patch may fail:

  • OS temp directory not available for writing or binaries executing.
  • Unsupported architecture. This library contains binary opcodes of unconditional jump instructions for different architectures.
  • Target function inlined by compiler. To avoid this use //go:noinline pragma or -gcflags=-l compiler flag.
  • Attempt to patch interface method. But sometimes it may work (see example).
  • Missing symbol table and/or PC-Line table needed to locate function address in executable by name. I've seen this only on Windows with under such circumstances:
    • go test without -o
    • go run
    • go build with -ldflags=-s

monkey's People

Contributors

xakep666 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

monkey's Issues

But... Why?

Monkey patching is a total evil in programming (except too specific cases, which are still not an argument)... For god sake, why did you publish that?

Also, looks like you didn't read original monkeypatching library license:

Don't use it.

Even author answered, why monkeypatching must not be exist in this world


I also must note you, that publishing projects in opensource is awesome thing, more opensourced projects โ€” better life for developers. But it's better to keep code quality in opensource projects, cause if we won't look on code quality, opensource will become an evil too. Which is unacceptable/

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.