mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
robustness: change mixedVersionOption to use ChoiceWeight.
Signed-off-by: Siyuan Zhang <sizhang@google.com>
This commit is contained in:
parent
debc8fb00b
commit
fff58bb809
@ -12,14 +12,14 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package traffic
|
||||
package random
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func randString(size int) string {
|
||||
func RandString(size int) string {
|
||||
data := strings.Builder{}
|
||||
data.Grow(size)
|
||||
for i := 0; i < size; i++ {
|
||||
@ -28,22 +28,22 @@ func randString(size int) string {
|
||||
return data.String()
|
||||
}
|
||||
|
||||
type choiceWeight[T any] struct {
|
||||
choice T
|
||||
weight int
|
||||
type ChoiceWeight[T any] struct {
|
||||
Choice T
|
||||
Weight int
|
||||
}
|
||||
|
||||
func pickRandom[T any](choices []choiceWeight[T]) T {
|
||||
func PickRandom[T any](choices []ChoiceWeight[T]) T {
|
||||
sum := 0
|
||||
for _, op := range choices {
|
||||
sum += op.weight
|
||||
sum += op.Weight
|
||||
}
|
||||
roll := rand.Int() % sum
|
||||
for _, op := range choices {
|
||||
if roll < op.weight {
|
||||
return op.choice
|
||||
if roll < op.Weight {
|
||||
return op.Choice
|
||||
}
|
||||
roll -= op.weight
|
||||
roll -= op.Weight
|
||||
}
|
||||
panic("unexpected")
|
||||
}
|
@ -24,6 +24,7 @@ import (
|
||||
"go.etcd.io/etcd/tests/v3/framework/e2e"
|
||||
"go.etcd.io/etcd/tests/v3/robustness/failpoint"
|
||||
"go.etcd.io/etcd/tests/v3/robustness/options"
|
||||
"go.etcd.io/etcd/tests/v3/robustness/random"
|
||||
"go.etcd.io/etcd/tests/v3/robustness/traffic"
|
||||
)
|
||||
|
||||
@ -69,23 +70,19 @@ func exploratoryScenarios(_ *testing.T) []testScenario {
|
||||
options.ClusterOptions{options.WithTickMs(100), options.WithElectionMs(2000)}),
|
||||
}
|
||||
|
||||
mixedVersionOption := options.WithClusterOptionGroups(
|
||||
mixedVersionOptionChoices := []random.ChoiceWeight[options.ClusterOptions]{
|
||||
// 60% with all members of current version
|
||||
options.ClusterOptions{options.WithVersion(e2e.CurrentVersion)},
|
||||
options.ClusterOptions{options.WithVersion(e2e.CurrentVersion)},
|
||||
options.ClusterOptions{options.WithVersion(e2e.CurrentVersion)},
|
||||
options.ClusterOptions{options.WithVersion(e2e.CurrentVersion)},
|
||||
options.ClusterOptions{options.WithVersion(e2e.CurrentVersion)},
|
||||
options.ClusterOptions{options.WithVersion(e2e.CurrentVersion)},
|
||||
{Choice: options.ClusterOptions{options.WithVersion(e2e.CurrentVersion)}, Weight: 60},
|
||||
// 10% with 2 members of current version, 1 member last version, leader is current version
|
||||
options.ClusterOptions{options.WithVersion(e2e.MinorityLastVersion), options.WithInitialLeaderIndex(0)},
|
||||
{Choice: options.ClusterOptions{options.WithVersion(e2e.MinorityLastVersion), options.WithInitialLeaderIndex(0)}, Weight: 10},
|
||||
// 10% with 2 members of current version, 1 member last version, leader is last version
|
||||
options.ClusterOptions{options.WithVersion(e2e.MinorityLastVersion), options.WithInitialLeaderIndex(2)},
|
||||
{Choice: options.ClusterOptions{options.WithVersion(e2e.MinorityLastVersion), options.WithInitialLeaderIndex(2)}, Weight: 10},
|
||||
// 10% with 2 members of last version, 1 member current version, leader is last version
|
||||
options.ClusterOptions{options.WithVersion(e2e.QuorumLastVersion), options.WithInitialLeaderIndex(0)},
|
||||
{Choice: options.ClusterOptions{options.WithVersion(e2e.QuorumLastVersion), options.WithInitialLeaderIndex(0)}, Weight: 10},
|
||||
// 10% with 2 members of last version, 1 member current version, leader is current version
|
||||
options.ClusterOptions{options.WithVersion(e2e.QuorumLastVersion), options.WithInitialLeaderIndex(2)},
|
||||
)
|
||||
{Choice: options.ClusterOptions{options.WithVersion(e2e.QuorumLastVersion), options.WithInitialLeaderIndex(2)}, Weight: 10},
|
||||
}
|
||||
mixedVersionOption := options.WithClusterOptionGroups(random.PickRandom[options.ClusterOptions](mixedVersionOptionChoices))
|
||||
|
||||
baseOptions := []e2e.EPClusterOption{
|
||||
options.WithSnapshotCount(50, 100, 1000),
|
||||
|
@ -26,6 +26,7 @@ import (
|
||||
"go.etcd.io/etcd/tests/v3/robustness/client"
|
||||
"go.etcd.io/etcd/tests/v3/robustness/identity"
|
||||
"go.etcd.io/etcd/tests/v3/robustness/model"
|
||||
"go.etcd.io/etcd/tests/v3/robustness/random"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -33,41 +34,41 @@ var (
|
||||
keyCount: 10,
|
||||
leaseTTL: DefaultLeaseTTL,
|
||||
largePutSize: 32769,
|
||||
requests: []choiceWeight[etcdRequestType]{
|
||||
{choice: Get, weight: 15},
|
||||
{choice: List, weight: 15},
|
||||
{choice: StaleGet, weight: 10},
|
||||
{choice: StaleList, weight: 10},
|
||||
{choice: Delete, weight: 5},
|
||||
{choice: MultiOpTxn, weight: 5},
|
||||
{choice: PutWithLease, weight: 5},
|
||||
{choice: LeaseRevoke, weight: 5},
|
||||
{choice: CompareAndSet, weight: 5},
|
||||
{choice: Put, weight: 15},
|
||||
{choice: LargePut, weight: 5},
|
||||
{choice: Compact, weight: 5},
|
||||
requests: []random.ChoiceWeight[etcdRequestType]{
|
||||
{Choice: Get, Weight: 15},
|
||||
{Choice: List, Weight: 15},
|
||||
{Choice: StaleGet, Weight: 10},
|
||||
{Choice: StaleList, Weight: 10},
|
||||
{Choice: Delete, Weight: 5},
|
||||
{Choice: MultiOpTxn, Weight: 5},
|
||||
{Choice: PutWithLease, Weight: 5},
|
||||
{Choice: LeaseRevoke, Weight: 5},
|
||||
{Choice: CompareAndSet, Weight: 5},
|
||||
{Choice: Put, Weight: 15},
|
||||
{Choice: LargePut, Weight: 5},
|
||||
{Choice: Compact, Weight: 5},
|
||||
},
|
||||
}
|
||||
EtcdPut = etcdTraffic{
|
||||
keyCount: 10,
|
||||
largePutSize: 32769,
|
||||
leaseTTL: DefaultLeaseTTL,
|
||||
requests: []choiceWeight[etcdRequestType]{
|
||||
{choice: Get, weight: 15},
|
||||
{choice: List, weight: 15},
|
||||
{choice: StaleGet, weight: 10},
|
||||
{choice: StaleList, weight: 10},
|
||||
{choice: MultiOpTxn, weight: 5},
|
||||
{choice: LargePut, weight: 5},
|
||||
{choice: Put, weight: 35},
|
||||
{choice: Compact, weight: 5},
|
||||
requests: []random.ChoiceWeight[etcdRequestType]{
|
||||
{Choice: Get, Weight: 15},
|
||||
{Choice: List, Weight: 15},
|
||||
{Choice: StaleGet, Weight: 10},
|
||||
{Choice: StaleList, Weight: 10},
|
||||
{Choice: MultiOpTxn, Weight: 5},
|
||||
{Choice: LargePut, Weight: 5},
|
||||
{Choice: Put, Weight: 35},
|
||||
{Choice: Compact, Weight: 5},
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
type etcdTraffic struct {
|
||||
keyCount int
|
||||
requests []choiceWeight[etcdRequestType]
|
||||
requests []random.ChoiceWeight[etcdRequestType]
|
||||
leaseTTL int64
|
||||
largePutSize int
|
||||
}
|
||||
@ -126,7 +127,7 @@ func (t etcdTraffic) Run(ctx context.Context, c *client.RecordingClient, limiter
|
||||
if shouldReturn = nonUniqueWriteLimiter.Take(); !shouldReturn {
|
||||
choices = filterOutNonUniqueEtcdWrites(choices)
|
||||
}
|
||||
requestType = pickRandom(choices)
|
||||
requestType = random.PickRandom(choices)
|
||||
} else {
|
||||
requestType = Get
|
||||
}
|
||||
@ -145,9 +146,9 @@ func (t etcdTraffic) Run(ctx context.Context, c *client.RecordingClient, limiter
|
||||
}
|
||||
}
|
||||
|
||||
func filterOutNonUniqueEtcdWrites(choices []choiceWeight[etcdRequestType]) (resp []choiceWeight[etcdRequestType]) {
|
||||
func filterOutNonUniqueEtcdWrites(choices []random.ChoiceWeight[etcdRequestType]) (resp []random.ChoiceWeight[etcdRequestType]) {
|
||||
for _, choice := range choices {
|
||||
if choice.choice != Delete && choice.choice != LeaseRevoke {
|
||||
if choice.Choice != Delete && choice.Choice != LeaseRevoke {
|
||||
resp = append(resp, choice)
|
||||
}
|
||||
}
|
||||
@ -193,7 +194,7 @@ func (c etcdTrafficClient) Request(ctx context.Context, request etcdRequestType,
|
||||
}
|
||||
case LargePut:
|
||||
var resp *clientv3.PutResponse
|
||||
resp, err = c.client.Put(opCtx, c.randomKey(), randString(c.largePutSize))
|
||||
resp, err = c.client.Put(opCtx, c.randomKey(), random.RandString(c.largePutSize))
|
||||
if resp != nil {
|
||||
rev = resp.Header.Revision
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ import (
|
||||
"go.etcd.io/etcd/pkg/v3/stringutil"
|
||||
"go.etcd.io/etcd/tests/v3/robustness/client"
|
||||
"go.etcd.io/etcd/tests/v3/robustness/identity"
|
||||
"go.etcd.io/etcd/tests/v3/robustness/random"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -36,11 +37,11 @@ var (
|
||||
averageKeyCount: 10,
|
||||
resource: "pods",
|
||||
namespace: "default",
|
||||
writeChoices: []choiceWeight[KubernetesRequestType]{
|
||||
{choice: KubernetesUpdate, weight: 85},
|
||||
{choice: KubernetesDelete, weight: 5},
|
||||
{choice: KubernetesCreate, weight: 5},
|
||||
{choice: KubernetesCompact, weight: 5},
|
||||
writeChoices: []random.ChoiceWeight[KubernetesRequestType]{
|
||||
{Choice: KubernetesUpdate, Weight: 85},
|
||||
{Choice: KubernetesDelete, Weight: 5},
|
||||
{Choice: KubernetesCreate, Weight: 5},
|
||||
{Choice: KubernetesCompact, Weight: 5},
|
||||
},
|
||||
}
|
||||
)
|
||||
@ -49,7 +50,7 @@ type kubernetesTraffic struct {
|
||||
averageKeyCount int
|
||||
resource string
|
||||
namespace string
|
||||
writeChoices []choiceWeight[KubernetesRequestType]
|
||||
writeChoices []random.ChoiceWeight[KubernetesRequestType]
|
||||
}
|
||||
|
||||
func (t kubernetesTraffic) ExpectUniqueRevision() bool {
|
||||
@ -161,7 +162,7 @@ func (t kubernetesTraffic) Write(ctx context.Context, kc *kubernetesClient, ids
|
||||
if shouldReturn = nonUniqueWriteLimiter.Take(); !shouldReturn {
|
||||
choices = filterOutNonUniqueKubernetesWrites(t.writeChoices)
|
||||
}
|
||||
op := pickRandom(choices)
|
||||
op := random.PickRandom(choices)
|
||||
switch op {
|
||||
case KubernetesDelete:
|
||||
_, err = kc.OptimisticDelete(writeCtx, key, rev)
|
||||
@ -186,9 +187,9 @@ func (t kubernetesTraffic) Write(ctx context.Context, kc *kubernetesClient, ids
|
||||
return nil
|
||||
}
|
||||
|
||||
func filterOutNonUniqueKubernetesWrites(choices []choiceWeight[KubernetesRequestType]) (resp []choiceWeight[KubernetesRequestType]) {
|
||||
func filterOutNonUniqueKubernetesWrites(choices []random.ChoiceWeight[KubernetesRequestType]) (resp []random.ChoiceWeight[KubernetesRequestType]) {
|
||||
for _, choice := range choices {
|
||||
if choice.choice != KubernetesDelete {
|
||||
if choice.Choice != KubernetesDelete {
|
||||
resp = append(resp, choice)
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user