randfill

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 4, 2025 License: Apache-2.0 Imports: 9 Imported by: 3

README

randfill

randfill is a library for populating go objects with random values.

This is a fork of github.com/google/gofuzz, which was archived.

NOTE: This repo is supported only for use within Kubernetes. It is not our intention to support general use. That said, if it works for you, that's great! If you have a problem, please feel free to file an issue, but be aware that it may not be a priority for us to fix it unless it is affecting Kubernetes. PRs are welcome, within reason.

GoDoc

This is useful for testing:

  • Do your project's objects really serialize/unserialize correctly in all cases?
  • Is there an incorrectly formatted object that will cause your project to panic?

Import with import "sigs.k8s.io/randfill"

You can use it on single variables:

f := randfill.New()
var myInt int
f.Fill(&myInt) // myInt gets a random value.

You can use it on maps:

f := randfill.New().NilChance(0).NumElements(1, 1)
var myMap map[ComplexKeyType]string
f.Fill(&myMap) // myMap will have exactly one element.

Customize the chance of getting a nil pointer:

f := randfill.New().NilChance(.5)
var fancyStruct struct {
  A, B, C, D *string
}
f.Fill(&fancyStruct) // About half the pointers should be set.

You can even customize the randomization completely if needed:

type MyEnum string
const (
        A MyEnum = "A"
        B MyEnum = "B"
)
type MyInfo struct {
        Type MyEnum
        AInfo *string
        BInfo *string
}

f := randfill.New().NilChance(0).Funcs(
        func(e *MyInfo, c randfill.Continue) {
                switch c.Intn(2) {
                case 0:
                        e.Type = A
                        c.Fill(&e.AInfo)
                case 1:
                        e.Type = B
                        c.Fill(&e.BInfo)
                }
        },
)

var myObject MyInfo
f.Fill(&myObject) // Type will correspond to whether A or B info is set.

See more examples in example_test.go.

dvyukov/go-fuzz integration

You can use this library for easier go-fuzzing. go-fuzz provides the user a byte-slice, which should be converted to different inputs for the tested function. This library can help convert the byte slice. Consider for example a fuzz test for a the function mypackage.MyFunc that takes an int arguments:

// +build gofuzz
package mypackage

import "sigs.k8s.io/randfill"

func Fuzz(data []byte) int {
        var i int
        randfill.NewFromGoFuzz(data).Fill(&i)
        MyFunc(i)
        return 0
}

Happy testing!

Documentation

Overview

Package randfill is a library for populating go objects with random values.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Continue

type Continue struct {

	// For convenience, Continue implements rand.Rand via embedding.
	// Use this for generating any randomness if you want your filling
	// to be repeatable for a given seed.
	*rand.Rand
	// contains filtered or unexported fields
}

Continue can be passed to custom fill functions to allow them to use the correct source of randomness and to continue filling their members.

func (Continue) Bool

func (c Continue) Bool() bool

Bool returns true or false randomly.

func (Continue) Fill

func (c Continue) Fill(obj interface{})

Fill continues filling obj. obj must be a pointer or a reflect.Value of a pointer. See Filler.Fill.

func (Continue) FillNoCustom

func (c Continue) FillNoCustom(obj interface{})

FillNoCustom continues filling obj, except that any custom fill function for obj's type will not be called and obj will not be tested for SimpleSelfFiller or NativeSelfFiller. See Filler.FillNoCustom.

func (Continue) String

func (c Continue) String(n int) string

String makes a random string up to n characters long. If n is 0, the default size range is [0-20). The returned string may include a variety of (valid) UTF-8 encodings.

func (Continue) Uint64

func (c Continue) Uint64() uint64

Uint64 makes random 64 bit numbers. Weirdly, rand doesn't have a function that gives you 64 random bits.

type Filler

type Filler struct {
	// contains filtered or unexported fields
}

Filler knows how to fill any object with random fields.

func New

func New() *Filler

New returns a new Filler. Customize your Filler further by calling Funcs, RandSource, NilChance, or NumElements in any order.

func NewFromGoFuzz

func NewFromGoFuzz(data []byte) *Filler

NewFromGoFuzz is a helper function that enables using randfill (this project) with go-fuzz (https://github.com/dvyukov/go-fuzz) for continuous fuzzing. Essentially, it enables translating the fuzzing bytes from go-fuzz to any Go object using this library.

This implementation promises a constant translation from a given slice of bytes to the fuzzed objects. This promise will remain over future versions of Go and of this library.

Note: the returned Filler should not be shared between multiple goroutines, as its deterministic output will no longer be available.

Example: use go-fuzz to test the function `MyFunc(int)` in the package `mypackage`. Add the file: "mypackage_fuzz.go" with the content:

// +build gofuzz package mypackage import "sigs.k8s.io/randfill"

func Fuzz(data []byte) int {
	var i int
	randfill.NewFromGoFuzz(data).Fill(&i)
	MyFunc(i)
	return 0
}

func NewWithSeed

func NewWithSeed(seed int64) *Filler

func (*Filler) AllowUnexportedFields

func (f *Filler) AllowUnexportedFields(flag bool) *Filler

AllowUnexportedFields defines whether to fill unexported fields.

func (*Filler) Fill

func (f *Filler) Fill(obj interface{})

Fill recursively fills all of obj's fields with something random. First this tries to find a custom fill function (see Funcs). If there is no custom function, this tests whether the object implements SimpleSelfFiller or NativeSelfFiller and if so, calls RandFill on it to fill itself. If that fails, this will see if there is a default fill function provided by this package. If all of that fails, this will generate random values for all primitive fields and then recurse for all non-primitives.

This is safe for cyclic or tree-like structs, up to a limit. Use the MaxDepth method to adjust how deep you need it to recurse.

obj must be a pointer. Exported (public) fields can always be set, and if the AllowUnexportedFields() modifier was called it can try to set unexported (private) fields, too.

This is intended for tests, so will panic on bad input or unimplemented types. This method takes a lock for the whole Filler, so it is not reentrant. See Continue.

func (*Filler) FillNoCustom

func (f *Filler) FillNoCustom(obj interface{})

FillNoCustom is just like Fill, except that any custom fill function for obj's type will not be called and obj will not be tested for SimpleSelfFiller or NativeSelfFiller. This applies only to obj and not other instances of obj's type or to obj's child fields.

obj must be a pointer. Exported (public) fields can always be set, and if the AllowUnexportedFields() modifier was called it can try to set unexported (private) fields, too.

This is intended for tests, so will panic on bad input or unimplemented types. This method takes a lock for the whole Filler, so it is not reentrant. See Continue.

func (*Filler) Funcs

func (f *Filler) Funcs(customFuncs ...interface{}) *Filler

Funcs registers custom fill functions for this Filler.

Each entry in customFuncs must be a function taking two parameters. The first parameter must be a pointer or map. It is the variable that function will fill with random data. The second parameter must be a randfill.Continue, which will provide a source of randomness and a way to automatically continue filling smaller pieces of the first parameter.

These functions are called sensibly, e.g., if you wanted custom string filling, the function `func(s *string, c randfill.Continue)` would get called and passed the address of strings. Maps and pointers will always be made/new'd for you, ignoring the NilChance option. For slices, it doesn't make much sense to pre-create them--Filler doesn't know how long you want your slice--so take a pointer to a slice, and make it yourself. (If you don't want your map/pointer type pre-made, take a pointer to it, and make it yourself.) See the examples for a range of custom functions.

If a function is already registered for a type, and a new function is provided, the previous function will be replaced with the new one.

func (*Filler) MaxDepth

func (f *Filler) MaxDepth(d int) *Filler

MaxDepth sets the maximum number of recursive fill calls that will be made before stopping. This includes struct members, pointers, and map and slice elements.

func (*Filler) NilChance

func (f *Filler) NilChance(p float64) *Filler

NilChance sets the probability of creating a nil pointer, map, or slice to 'p'. 'p' should be between 0 (no nils) and 1 (all nils), inclusive.

func (*Filler) NumElements

func (f *Filler) NumElements(min, max int) *Filler

NumElements sets the minimum and maximum number of elements that will be added to a non-nil map or slice.

func (*Filler) RandSource

func (f *Filler) RandSource(s rand.Source) *Filler

RandSource causes this Filler to get values from the given source of randomness. Use this if you want deterministic filling.

func (*Filler) SkipFieldsWithPattern

func (f *Filler) SkipFieldsWithPattern(pattern *regexp.Regexp) *Filler

SkipFieldsWithPattern tells this Filler to skip any field whose name matches the supplied pattern. Call this multiple times if needed. This is useful to skip XXX_ fields generated by protobuf.

type NativeSelfFiller

type NativeSelfFiller interface {
	// RandFill fills the current object with random data.
	RandFill(c Continue)
}

NativeSelfFiller represents an object that knows how to randfill itself.

Unlike SimpleSelfFiller, this interface allows for recursive filling of child objects with the same rules as the parent Filler.

type SimpleSelfFiller

type SimpleSelfFiller interface {
	// RandFill fills the current object with random data.
	RandFill(r *rand.Rand)
}

SimpleSelfFiller represents an object that knows how to randfill itself.

Unlike NativeSelfFiller, this interface does not cause the type in question to depend on the randfill package. This is most useful for simple types. For more complex types, consider using NativeSelfFiller.

type UnicodeRange

type UnicodeRange struct {
	First, Last rune
}

UnicodeRange describes a sequential range of unicode characters. Last must be numerically greater than First.

func (UnicodeRange) CustomStringFillFunc

func (ur UnicodeRange) CustomStringFillFunc(n int) func(s *string, c Continue)

CustomStringFillFunc constructs a FillFunc which produces random strings. Each character is selected from the range ur. If there are no characters in the range (cr.Last < cr.First), this will panic.

type UnicodeRanges

type UnicodeRanges []UnicodeRange

UnicodeRanges describes an arbitrary number of sequential ranges of unicode characters. To be useful, each range must have at least one character (First <= Last) and there must be at least one range.

func (UnicodeRanges) CustomStringFillFunc

func (ur UnicodeRanges) CustomStringFillFunc(n int) func(s *string, c Continue)

CustomStringFillFunc constructs a FillFunc which produces random strings. Each character is selected from one of the ranges of ur(UnicodeRanges). Each range has an equal probability of being chosen. If there are no ranges, or a selected range has no characters (.Last < .First), this will panic. Do not modify any of the ranges in ur after calling this function.

Directories

Path Synopsis
Package bytesource provides a rand.Source64 that is determined by a slice of bytes.
Package bytesource provides a rand.Source64 that is determined by a slice of bytes.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL