1
0
mirror of https://github.com/ceph/ceph-csi.git synced 2025-06-14 18:53:35 +00:00
Files
cephfs
deploy
pkg
rbd
vendor
github.com
golang.org
google.golang.org
k8s.io
apimachinery
kubernetes
.github
Godeps
api
build
cluster
cmd
docs
examples
hack
logo
pkg
api
apis
auth
capabilities
client
chaosclient
BUILD
OWNERS
chaosclient.go
chaosclient_test.go
clientset_generated
conditions
informers
leaderelectionconfig
listers
metrics
testdata
tests
OWNERS
cloudprovider
controller
credentialprovider
features
fieldpath
generated
kubeapiserver
kubectl
kubelet
kubemark
master
printers
probe
proxy
quota
registry
routes
scheduler
security
securitycontext
serviceaccount
ssh
util
version
volume
watch
.import-restrictions
BUILD
OWNERS
plugin
staging
test
third_party
translations
.generated_files
.gitattributes
.gitignore
CHANGELOG-1.10.md
CHANGELOG.md
CONTRIBUTING.md
LICENSE
OWNERS
OWNERS_ALIASES
README.md
SUPPORT.md
code-of-conduct.md
labels.yaml
utils
.gitignore
.travis.yml
Gopkg.lock
Gopkg.toml
LICENSE
Makefile
README.md
deploy-cephfs.sh
deploy-rbd.sh
ceph-csi/vendor/k8s.io/kubernetes/pkg/client/chaosclient/chaosclient.go

157 lines
4.7 KiB
Go
Raw Normal View History

2018-01-09 13:57:14 -05:00
/*
Copyright 2015 The Kubernetes Authors.
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 chaosclient makes it easy to simulate network latency, misbehaving
// servers, and random errors from servers. It is intended to stress test components
// under failure conditions and expose weaknesses in the error handling logic
// of the codebase.
package chaosclient
import (
"errors"
"fmt"
"log"
"math/rand"
"net/http"
"reflect"
"runtime"
"k8s.io/apimachinery/pkg/util/net"
)
// chaosrt provides the ability to perform simulations of HTTP client failures
// under the Golang http.Transport interface.
type chaosrt struct {
rt http.RoundTripper
notify ChaosNotifier
c []Chaos
}
// Chaos intercepts requests to a remote HTTP endpoint and can inject arbitrary
// failures.
type Chaos interface {
// Intercept should return true if the normal flow should be skipped, and the
// return response and error used instead. Modifications to the request will
// be ignored, but may be used to make decisions about types of failures.
Intercept(req *http.Request) (bool, *http.Response, error)
}
// ChaosNotifier notifies another component that the ChaosRoundTripper has simulated
// a failure.
type ChaosNotifier interface {
// OnChaos is invoked when a chaotic outcome was triggered. fn is the
// source of Chaos and req was the outgoing request
OnChaos(req *http.Request, c Chaos)
}
// ChaosFunc takes an http.Request and decides whether to alter the response. It
// returns true if it wishes to mutate the response, with a http.Response or
// error.
type ChaosFunc func(req *http.Request) (bool, *http.Response, error)
func (fn ChaosFunc) Intercept(req *http.Request) (bool, *http.Response, error) {
return fn.Intercept(req)
}
func (fn ChaosFunc) String() string {
return runtime.FuncForPC(reflect.ValueOf(fn).Pointer()).Name()
}
// NewChaosRoundTripper creates an http.RoundTripper that will intercept requests
// based on the provided Chaos functions. The notifier is invoked when a Chaos
// Intercept is fired.
func NewChaosRoundTripper(rt http.RoundTripper, notify ChaosNotifier, c ...Chaos) http.RoundTripper {
return &chaosrt{rt, notify, c}
}
// RoundTrip gives each ChaosFunc an opportunity to intercept the request. The first
// interceptor wins.
func (rt *chaosrt) RoundTrip(req *http.Request) (*http.Response, error) {
for _, c := range rt.c {
if intercept, resp, err := c.Intercept(req); intercept {
rt.notify.OnChaos(req, c)
return resp, err
}
}
return rt.rt.RoundTrip(req)
}
var _ = net.RoundTripperWrapper(&chaosrt{})
func (rt *chaosrt) WrappedRoundTripper() http.RoundTripper {
return rt.rt
}
// Seed represents a consistent stream of chaos.
type Seed struct {
*rand.Rand
}
// NewSeed creates an object that assists in generating random chaotic events
// based on a deterministic seed.
func NewSeed(seed int64) Seed {
return Seed{rand.New(rand.NewSource(seed))}
}
type pIntercept struct {
Chaos
s Seed
p float64
}
// P returns a ChaosFunc that fires with a probability of p (p between 0.0
// and 1.0 with 0.0 meaning never and 1.0 meaning always).
func (s Seed) P(p float64, c Chaos) Chaos {
return pIntercept{c, s, p}
}
// Intercept intercepts requests with the provided probability p.
func (c pIntercept) Intercept(req *http.Request) (bool, *http.Response, error) {
if c.s.Float64() < c.p {
return c.Chaos.Intercept(req)
}
return false, nil, nil
}
func (c pIntercept) String() string {
return fmt.Sprintf("P{%f %s}", c.p, c.Chaos)
}
// ErrSimulatedConnectionResetByPeer emulates the golang net error when a connection
// is reset by a peer.
// TODO: make this more accurate
// TODO: add other error types
// TODO: add a helper for returning multiple errors randomly.
var ErrSimulatedConnectionResetByPeer = Error{errors.New("connection reset by peer")}
// Error returns the nested error when C() is invoked.
type Error struct {
error
}
// C returns the nested error
func (e Error) Intercept(_ *http.Request) (bool, *http.Response, error) {
return true, nil, e.error
}
// LogChaos is the default ChaosNotifier and writes a message to the Golang log.
var LogChaos = ChaosNotifier(logChaos{})
type logChaos struct{}
func (logChaos) OnChaos(req *http.Request, c Chaos) {
log.Printf("Triggered chaotic behavior for %s %s: %v", req.Method, req.URL.String(), c)
}