forked from forgejo/forgejo
Update to last common bleve (#3986)
This commit is contained in:
parent
1b7cd3d0b0
commit
917b9641ec
184 changed files with 39576 additions and 121 deletions
161
vendor/github.com/mschoch/smat/smat.go
generated
vendored
Normal file
161
vendor/github.com/mschoch/smat/smat.go
generated
vendored
Normal file
|
@ -0,0 +1,161 @@
|
|||
// Copyright (c) 2016 Marty Schoch
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the
|
||||
// License. You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an "AS
|
||||
// IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
// express or implied. See the License for the specific language
|
||||
// governing permissions and limitations under the License.
|
||||
|
||||
package smat
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"math/rand"
|
||||
)
|
||||
|
||||
// Logger is a configurable logger used by this package
|
||||
// by default output is discarded
|
||||
var Logger = log.New(ioutil.Discard, "smat ", log.LstdFlags)
|
||||
|
||||
// Context is a container for any user state
|
||||
type Context interface{}
|
||||
|
||||
// State is a function which describes which action to perform in the event
|
||||
// that a particular byte is seen
|
||||
type State func(next byte) ActionID
|
||||
|
||||
// PercentAction describes the frequency with which an action should occur
|
||||
// for example: Action{Percent:10, Action:DonateMoney} means that 10% of
|
||||
// the time you should donate money.
|
||||
type PercentAction struct {
|
||||
Percent int
|
||||
Action ActionID
|
||||
}
|
||||
|
||||
// Action is any function which returns the next state to transition to
|
||||
// it can optionally mutate the provided context object
|
||||
// if any error occurs, it may return an error which will abort execution
|
||||
type Action func(Context) (State, error)
|
||||
|
||||
// ActionID is a unique identifier for an action
|
||||
type ActionID int
|
||||
|
||||
// NopAction does nothing and simply continues to the next input
|
||||
var NopAction ActionID = -1
|
||||
|
||||
// ActionMap is a mapping form ActionID to Action
|
||||
type ActionMap map[ActionID]Action
|
||||
|
||||
func (a ActionMap) findSetupTeardown(setup, teardown ActionID) (Action, Action, error) {
|
||||
setupFunc, ok := a[setup]
|
||||
if !ok {
|
||||
return nil, nil, ErrSetupMissing
|
||||
}
|
||||
teardownFunc, ok := a[teardown]
|
||||
if !ok {
|
||||
return nil, nil, ErrTeardownMissing
|
||||
}
|
||||
return setupFunc, teardownFunc, nil
|
||||
}
|
||||
|
||||
// Fuzz runs the fuzzing state machine with the provided context
|
||||
// first, the setup action is executed unconditionally
|
||||
// the start state is determined by this action
|
||||
// actionMap is a lookup table for all actions
|
||||
// the data byte slice determines all future state transitions
|
||||
// finally, the teardown action is executed unconditionally for cleanup
|
||||
func Fuzz(ctx Context, setup, teardown ActionID, actionMap ActionMap, data []byte) int {
|
||||
reader := bytes.NewReader(data)
|
||||
err := runReader(ctx, setup, teardown, actionMap, reader, nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return 1
|
||||
}
|
||||
|
||||
// Longevity runs the state machine with the provided context
|
||||
// first, the setup action is executed unconditionally
|
||||
// the start state is determined by this action
|
||||
// actionMap is a lookup table for all actions
|
||||
// random bytes are generated to determine all future state transitions
|
||||
// finally, the teardown action is executed unconditionally for cleanup
|
||||
func Longevity(ctx Context, setup, teardown ActionID, actionMap ActionMap, seed int64, closeChan chan struct{}) error {
|
||||
source := rand.NewSource(seed)
|
||||
return runReader(ctx, setup, teardown, actionMap, rand.New(source), closeChan)
|
||||
}
|
||||
|
||||
var (
|
||||
// ErrSetupMissing is returned when the setup action cannot be found
|
||||
ErrSetupMissing = fmt.Errorf("setup action missing")
|
||||
// ErrTeardownMissing is returned when the teardown action cannot be found
|
||||
ErrTeardownMissing = fmt.Errorf("teardown action missing")
|
||||
// ErrClosed is returned when the closeChan was closed to cancel the op
|
||||
ErrClosed = fmt.Errorf("closed")
|
||||
// ErrActionNotPossible is returned when an action is encountered in a
|
||||
// FuzzCase that is not possible in the current state
|
||||
ErrActionNotPossible = fmt.Errorf("action not possible in state")
|
||||
)
|
||||
|
||||
func runReader(ctx Context, setup, teardown ActionID, actionMap ActionMap, r io.Reader, closeChan chan struct{}) error {
|
||||
setupFunc, teardownFunc, err := actionMap.findSetupTeardown(setup, teardown)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
Logger.Printf("invoking setup action")
|
||||
state, err := setupFunc(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
Logger.Printf("invoking teardown action")
|
||||
_, _ = teardownFunc(ctx)
|
||||
}()
|
||||
|
||||
reader := bufio.NewReader(r)
|
||||
for next, err := reader.ReadByte(); err == nil; next, err = reader.ReadByte() {
|
||||
select {
|
||||
case <-closeChan:
|
||||
return ErrClosed
|
||||
default:
|
||||
actionID := state(next)
|
||||
action, ok := actionMap[actionID]
|
||||
if !ok {
|
||||
Logger.Printf("no such action defined, continuing")
|
||||
continue
|
||||
}
|
||||
Logger.Printf("invoking action - %d", actionID)
|
||||
state, err = action(ctx)
|
||||
if err != nil {
|
||||
Logger.Printf("it was action %d that returned err %v", actionID, err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// PercentExecute interprets the next byte as a random value and normalizes it
|
||||
// to values 0-99, it then looks to see which action should be execued based
|
||||
// on the action distributions
|
||||
func PercentExecute(next byte, pas ...PercentAction) ActionID {
|
||||
percent := int(99 * int(next) / 255)
|
||||
|
||||
sofar := 0
|
||||
for _, pa := range pas {
|
||||
sofar = sofar + pa.Percent
|
||||
if percent < sofar {
|
||||
return pa.Action
|
||||
}
|
||||
|
||||
}
|
||||
return NopAction
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue