Skip to content

v0.94.0

Compare
Choose a tag to compare
@adamluzsi adamluzsi released this 14 Jul 09:18

upgrade testcase to the latest

  • a new fault injection framework
    • allows injecting errors into a specific package/receiver/function's context.Err call
    • includes a fault injection middleware/round-tripper that allows propagating faults in distributed systems.
    • Added the ability to propagate injected faults in the round-tripper
    • allows the ability to inject errors through the HTTP API in a controlled manner
    • has a Global Enable Disable toggle to exclude all possibilities where faults injection is are not expected on an environment.
      • default is off
defer faultinject.Enable()()

ctx := context.Background()

// all fault field is optional.
// in case left as zero value,
// it will match every caller context,
// and returns on the first .Err() / .Value(faultinject.Fault{})
ctx = faultinject.Inject(ctx, faultinject.CallerFault{
	Package:  "targetpkg",
	Receiver: "*myreceiver",
	Function: "myfunction",
}, errors.New("boom"))

// from and after call stack reached: targetpkg.(*myreceiver).myfunction
if err := ctx.Err(); err != nil {
	fmt.Println(err) // in the position defined by the Fault, it will yield an error
}
  • added support for a deterministic random generation as io.Reader with random.Random
rnd := random.New(rand.NewSource(time.Now().Unix()))

p := make([]byte, 42)
n, err := rnd.Read(p)

_, _ = n, err
  • added support for deterministic random error generation
rnd := random.New(rand.NewSource(time.Now().Unix()))
err := rnd.Error()
_ = err
var v = testcase.Var[int]{
	ID:   "myvar",
	Init: func(t *testcase.T) int { return 42 },
	Before: func(t *testcase.T, v testcase.Var[int]) {
		t.Logf(`I'm from the Var.Before block, and the value: %#v`, v.Get(t))
	},
}
  • [EXPERIMENT] deprecate Around, AroundAll, After, AfterAll to trim down on the testcase's API
    • They can be expressed using a Before/BeforeAll with T.Defer or T.Cleanup
  • added support for sandboxing function blocks
    • This allows testing test helpers easily without letting your test exit with runtime.Goexit on testing.TB.FailNow
var tb testing.TB = &testcase.StubTB{}
outcome := testcase.Sandbox(func() {
	// some test helper function calls fatal, which cause runtime.Goexit after marking the test failed.
	tb.FailNow()
})

fmt.Println("The sandbox run has finished without an issue", outcome.OK)
fmt.Println("runtime.Goexit was called:", outcome.Goexit)
fmt.Println("panic value:", outcome.PanicValue)
  • added support for assert.NoError
var tb testing.TB
assert.NoError(tb, nil)                // passes
assert.NoError(tb, errors.New("boom")) // fails
  • improved the usability of StubTB to make it easier to assert the log content
stub := &testcase.StubTB{}
stub.Log("hello", "world")
fmt.Println(stub.Logs.String())
  • added commonly used charsets to make random string generation more convenient for a given charset
rnd := random.New(rand.NewSource(time.Now().Unix()))
rnd.StringNWithCharset(42, random.Charset())
rnd.StringNWithCharset(42, random.CharsetASCII())
rnd.StringNWithCharset(42, random.CharsetAlpha())
rnd.StringNWithCharset(42, "ABC")
  • added alias for random.StringWithCharset to make it easier to use
rnd := random.New(rand.NewSource(time.Now().Unix()))
rnd.StringNC(42, random.Charset())
  • extend assert.ErrorIs to check equality even with wrapped values
  • move Eventually async test helper into the assert package
    • backward compatibility is ensured for awhile
  • add more safety guards to prevent variables without ID
  • added http.Handler middleware contract to httpspec
    • if you write an http.Handler-based middleware ensures that the minimum expectations are there.
myHandlerWithFaultInjectionMiddleware := fihttp.Handler{
	Next:        myHandler,
	ServiceName: "our-service-name",
	FaultsMapping: fihttp.FaultsMapping{
		"mapped-fault-name": func(ctx context.Context) context.Context {
			return faultinject.Inject(ctx, FaultTag{}, errors.New("boom"))
		},
	},
}
  • many small improvements