Documentation
¶
Overview ¶
Example ¶
package main import ( "context" "fmt" "github.com/adamluzsi/testcase/faultinject" ) type FaultTag struct{} func main() { defer faultinject.Enable()() ctx := context.Background() fmt.Println(ctx.Err()) // no error as expected // arrange one fault injection for FaultTag ctx = faultinject.Inject(ctx, FaultTag{}, fmt.Errorf("example error to inject")) if err, ok := ctx.Value(FaultTag{}).(error); ok { fmt.Println(err) // prints the injected error } if err, ok := ctx.Value(FaultTag{}).(error); ok { fmt.Println(err) // code not reached as injectedFault is already consumed } }
Output:
Example (ChaosEngineeringWithExplicitFaultPoints) ¶
package main import ( "context" "errors" "fmt" "github.com/adamluzsi/testcase/faultinject" ) type FaultTag struct{} func main() { defer faultinject.Enable()() ctx := context.Background() fmt.Println(MyFuncWithChaosEngineeringFaultPoints(ctx)) // no error ctx = faultinject.Inject(ctx, FaultTag{}, errors.New("boom")) // arrange fault injection for FaultTag fmt.Println(MyFuncWithChaosEngineeringFaultPoints(ctx)) // "boom" is returned } func MyFuncWithChaosEngineeringFaultPoints(ctx context.Context) error { if err, ok := ctx.Value(FaultTag{}).(error); ok { return err } if err := ctx.Err(); err != nil { return err } return nil }
Output:
Example (FaultInjectWithFixErrorReplyFromTheFaultPoint) ¶
package main import ( "context" "errors" "fmt" "github.com/adamluzsi/testcase/faultinject" ) type FaultTag struct{} func main() { defer faultinject.Enable()() ctx := context.Background() ctx = faultinject.Inject(ctx, FaultTag{}, errors.New("ignored")) fmt.Println(MyFuncWithFixErrorReplyFromTheFaultPoin(ctx)) // error is returned } func MyFuncWithFixErrorReplyFromTheFaultPoin(ctx context.Context) error { if _, ok := ctx.Value(FaultTag{}).(error); ok { return errors.New("my error value") } return nil }
Output:
Index ¶
- Constants
- func Check(ctx context.Context, faults ...any) error
- func Enable() (Disable func())
- func EnableForTest(tb testingTB)
- func Enabled() bool
- func Finish(returnErr *error, ctx context.Context, faults ...any)
- func Inject(ctx context.Context, fault any, err error) context.Context
- type CallerFault
Examples ¶
Constants ¶
const DefaultErr errT = "fault injected"
Variables ¶
This section is empty.
Functions ¶
func Check ¶
Check is a fault-injection helper method which check if there is an injected fault(s) in the given context. It checks for errors injected as context value, or ensures to trigger a CallerFault. It is safe to use from production code.
Example ¶
package main import ( "context" "github.com/adamluzsi/testcase/faultinject" ) func main() { type FaultName struct{} ctx := context.Background() if err := faultinject.Check(ctx, FaultName{}); err != nil { return // err } }
Output:
func EnableForTest ¶ added in v0.87.0
func EnableForTest(tb testingTB)
func Finish ¶ added in v0.113.0
Finish is function that can be called from a deferred context, and will inject fault when a function finished its execution. The error pointer should point to the function's named return error variable. If the function encountered an actual error, fault injection is skipped. It is safe to use from production code.
Example ¶
package main import ( "context" "github.com/adamluzsi/testcase/faultinject" ) func main() { type FaultName struct{} ctx := context.Background() _ = func(ctx context.Context) (rErr error) { defer faultinject.Finish(&rErr, ctx, FaultName{}) return nil }(ctx) }
Output:
func Inject ¶
Inject will arrange context to trigger fault injection for the provided fault.
Example (ByTargetingCaller) ¶
package main import ( "context" "errors" "fmt" "github.com/adamluzsi/testcase/faultinject" ) func main() { ctx := faultinject.Inject( context.Background(), faultinject.CallerFault{ Package: "", // empty will match everything Receiver: "", // Function: "", // }, errors.New("boom"), ) fmt.Println(ctx.Err()) // "boom" }
Output:
Types ¶
type CallerFault ¶ added in v0.91.0
CallerFault allows you to inject Fault by Caller stack position.
Example ¶
package main import ( "context" "fmt" "github.com/adamluzsi/testcase/faultinject" "github.com/adamluzsi/testcase/random" ) func main() { defer faultinject.Enable()() ctx := context.Background() fmt.Println(MyFuncWithStandardContextErrCheck(ctx)) // no error fault := faultinject.CallerFault{ // inject Fault that targets a specific context Err check Function: "MyFuncWithStandardContextErrCheck", // selector to tell where to inject } err := random.New(random.CryptoSeed{}).Error() ctx = faultinject.Inject(ctx, fault, err) // some random error) fmt.Println(MyFuncWithStandardContextErrCheck(ctx)) // Fault.Error injected and returned } func MyFuncWithStandardContextErrCheck(ctx context.Context) error { if err := ctx.Err(); err != nil { return err } return nil }
Output: