• Stars
    star
    223
  • Rank 175,053 (Top 4 %)
  • Language
    Java
  • License
    MIT License
  • Created about 8 years ago
  • Updated over 3 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

πŸ’ Bytecode-level fault injection for the JVM.

byte-monkey

Build Status Coverage Status

Byte-Monkey is a small Java library for testing failure scenarios in JVM applications - it works by instrumenting application code on the fly to deliberately introduce faults like exceptions and latency. Original blogpost here.

Download

Latest version: 1.0.0

How to use

java -javaagent:byte-monkey.jar -jar your-java-app.jar

Supported Modes

  • Fault: Throw exceptions from methods that declare those exceptions
  • Latency: Introduce latency on method-calls
  • Nullify: Replace the first non-primitive argument to the method with null
  • Short-circuit: Throw corresponding exceptions at the very beginning of try blocks

Options

  • mode: What mode to run in - currently supports fault, latency, nullify, and scircuit. Default is fault
  • rate: Value between 0 and 1 - how often to activate the fault. Default is 1, i.e. 100%
  • filter: Only instrument packages or methods matching the (java-style) regex. Default is .*, i.e. all methods

byte-monkey is configured with a comma-separated key-value pair string of the options as the agent argument.

java -javaagent:byte-monkey.jar=mode:fault,rate:0.5,filter:uk/co/probablyfine/ -jar your-java-app.jar

The example above would run in fault mode, activating on 50% of eligible method calls, for anything in the package tree below uk.co.probablyfine

Modes

Fault

Running byte-monkey in fault mode will cause the first declared exception in a method signature to be thrown.

CAVEAT: Byte-Monkey can only create Exceptions that expose a public default constructor as a result of how it instantiates them. If such a constructor doesn't exist, it falls back to a ByteMonkeyException instead.

Latency

Running byte-monkey in latency mode will cause the method to sleep before executing further instructions.

There is a configuration option available only during this mode:

  • latency: Duration (in millis) to wait on method calls, only valid when running in Latency mode. Default is 100ms

Example: java -javaagent:byte-monkey.jar=mode:latency,rate:0.5,latency:150 -jar your-java-app.jar

Nullify

Running byte-monkey in nullify mode will replace the first non-primitive argument to the method call with a null value.

Methods with only primitive arguments or no arguments at all will not be affected by the agent in this mode.

Short-circuit

Running byte-monkey in scircuit mode will throw corresponding exceptions in the very beginning of try blocks.

There is a configuration option available only during this mode:

  • tcindex: Index of which exception to throw when there are multiple catch blocks, e.g. tcindex=0 indicates the first type of exception in the catch block. Only valid when running in Short-circuit mode. Default is -1/first

Example:

java -javaagent:byte-monkey.jar=mode:scircuit,filter:package/path/ClassName/MethodName,tcindex=0 -jar your-java-app.jar

You can read this paper or this blog for more information about short-circuit testing.

Implementation Details

Byte-Monkey uses the JVM Instrumentation API. Implementing the API enables you to register transformers that can iterate over (and transform) class files as they are loaded by the JVM. Byte-Monkey uses Objectweb ASM which comes packaged with the JDK to chance the underlying bytecode of loaded classes

Injecting Failure

The bytecode of a simple "Hello, World!" method prior to having an exception injected looks like this:

  public void printSomething() throws java.io.IOException;
    Code:
       0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
       3: ldc           #3                  // String Hello!
       5: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
       8: return

After being transformed by the Byte-Monkey, it instead looks like this:

  public void printSomething() throws java.io.IOException;
    Code:
       0: ldc2_w        #18                 // double 0.5d
       3: invokestatic  #25                 // Method uk/co/probablyfine/bytemonkey/AddChanceOfFailure.shouldActivate:(D)Z
       6: ifeq          15
       9: ldc           #26                 // String java/io/IOException
      11: invokestatic  #32                 // Method uk/co/probablyfine/bytemonkey/CreateAndThrowException.throwOrDefault:(Ljava/lang/String;)Ljava/lang/Throwable;
      14: athrow
      15: getstatic     #38                 // Field java/lang/System.out:Ljava/io/PrintStream;
      18: ldc           #40                 // String Hello!
      20: invokevirtual #46                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      23: return

This is the core of how Byte-Monkey works:

  • 0: Load the failure injection rate onto the stack
  • 3: A call to AddChanceOfFailure.shouldActivate which returns true/false depending on the rate
  • 6: If shouldActivate was false, we jump straight to instruction 15 - the beginning of the original code.
  • 9: Load the name of the exception that would be thrown (here an IOException)
  • 11: Create the exception if it has a default constructor, or create a wrapper exception
  • 14: Throw the exception

For modes other than fault, instructions 9 to 14 are replaced with mode-specific instructions.

More Repositories

1

adr-viewer

Generate easy-to-read web pages for your Architecture Decision Records
Python
144
star
2

java-dirty

File-backed append-only object store.
Java
116
star
3

helixdns

DNS server that serves records from etcd.
Go
94
star
4

docker-flume

🐳 Docker image containing Apache Flume
Shell
52
star
5

ebook-publishers-vs-drm

List of publishers and whether or not they sell DRM-free ebooks
10
star
6

mrwilson-multipkg

Multipackage type and providers for Puppet
Ruby
7
star
7

fb-psql

PostgreSQL wrapper for Facebook's FQL api
Python
7
star
8

femto

A teeny-tiny dependency injection library written in pure standard Java
Java
6
star
9

squib

Sqlite3 extension library for statistical functions.
C
6
star
10

salt-config

Configuration for salt-stack
Scheme
5
star
11

ankirepo

Repository of all 3rd year revision Anki cards
5
star
12

advent-of-code-2021

It's back. It's worse.
jq
5
star
13

sopn-publish-date

πŸ—³οΈDerive publish dates of Statements of Persons Nominated for UK elections
Python
4
star
14

advent-of-code-2022

πŸ¦†I can't believe I'm doing this again πŸ¦†
Shell
4
star
15

ansible-sqlite

Ansible role for installing sqlite.
4
star
16

advent-of-code-2020

This place is not a place of honor. No highly esteemed deed is commemorated here. Nothing valued is here. What is here was dangerous and repulsive to us.
C
4
star
17

jqunit

A test framework for JQ, written in Rust, on top of libjq.
Rust
4
star
18

java-8-matchers

A hard fork of unruly/java-8-matchers
Java
3
star
19

wordle-text-description

A browser extension to generate a screen-reader-friendly representation of a Wordle game
JavaScript
3
star
20

beanstalk-lua

Lua client for beanstalkd
Lua
3
star
21

govuk-onelogin-webidentity-spike

JavaScript
3
star
22

java-working-days

🌍 πŸ—“οΈ A small library to calculate working days between dates for multiple countries
Java
2
star
23

shudder-py

An unofficial Python API client for horror streaming service Shudder
Python
2
star
24

leggings

Java
2
star
25

jenever

Java Package and Environment Manager
Java
2
star
26

conventional-commit

A small java library to parse conventional commits
Java
2
star
27

jump

Java
2
star
28

waste-receptacle-locations

πŸ“Š πŸ—‘οΈ ♻️ Open-data repository for public waste disposal locations
Python
1
star
29

rust-katas

A collection of coding katas implemented in rust
Rust
1
star
30

ansible-snitch

Ansible module for handling snitches at https://deadmanssnitch.com
1
star
31

exercises

Various experiments with code exercises and stuff
Java
1
star
32

terraform-aws-protonmail-dns

Terraform module for DNS records to support custom domains on ProtonMail
HCL
1
star
33

shelua

Shell commands from lua
Lua
1
star
34

scrobbler

A command line track scrobbler
1
star
35

holst

YAML-based dsl for iptables rules
Python
1
star
36

woofplayer

Small java media player
Java
1
star
37

maven-plugins

A collection of custom maven plugins
Java
1
star
38

insant

Java
1
star
39

gia

Executing groovy tests via annotations
Java
1
star
40

veggie-enhancement-suite

Improve UX for vegetarians / vegans on takeaway sites
JavaScript
1
star
41

flume-tailer-source

Apache Flume source to tail files
Java
1
star
42

gradle-test-commit-revert-plugin

βœ… A gradle plugin to facilitate a Test-Commit-Revert workflow.
Groovy
1
star
43

appg-social-media

Keeping track of social media accounts for All-Party Parliamentary Groups (APPGs)
Python
1
star