github.com/pingcap/chaos@v0.0.0-20190710112158-c86faf4b3719/pkg/nemesis/generator.go (about) 1 package nemesis 2 3 import ( 4 "math/rand" 5 "time" 6 7 "github.com/pingcap/chaos/pkg/core" 8 ) 9 10 type killGenerator struct { 11 db string 12 name string 13 } 14 15 func (g killGenerator) Generate(nodes []string) []*core.NemesisOperation { 16 n := 1 17 switch g.name { 18 case "minor_kill": 19 n = len(nodes)/2 - 1 20 case "major_kill": 21 n = len(nodes)/2 + 1 22 case "all_kill": 23 n = len(nodes) 24 default: 25 n = 1 26 } 27 28 return killNodes(g.db, nodes, n) 29 } 30 31 func (g killGenerator) Name() string { 32 return g.name 33 } 34 35 func killNodes(db string, nodes []string, n int) []*core.NemesisOperation { 36 ops := make([]*core.NemesisOperation, len(nodes)) 37 38 // randomly shuffle the indecies and get the first n nodes to be partitioned. 39 indices := shuffleIndices(len(nodes)) 40 41 for i := 0; i < n; i++ { 42 ops[indices[i]] = &core.NemesisOperation{ 43 Name: "kill", 44 InvokeArgs: []string{db}, 45 RecoverArgs: []string{db}, 46 RunTime: time.Second * time.Duration(rand.Intn(10)+1), 47 } 48 } 49 50 return ops 51 } 52 53 // NewKillGenerator creates a generator. 54 // Name is random_kill, minor_kill, major_kill, and all_kill. 55 func NewKillGenerator(db string, name string) core.NemesisGenerator { 56 return killGenerator{db: db, name: name} 57 } 58 59 type dropGenerator struct { 60 name string 61 } 62 63 func (g dropGenerator) Generate(nodes []string) []*core.NemesisOperation { 64 n := 1 65 switch g.name { 66 case "minor_drop": 67 n = len(nodes)/2 - 1 68 case "major_drop": 69 n = len(nodes)/2 + 1 70 case "all_drop": 71 n = len(nodes) 72 default: 73 n = 1 74 } 75 return partitionNodes(nodes, n) 76 } 77 78 func (g dropGenerator) Name() string { 79 return g.name 80 } 81 82 func partitionNodes(nodes []string, n int) []*core.NemesisOperation { 83 ops := make([]*core.NemesisOperation, len(nodes)) 84 85 // randomly shuffle the indecies and get the first n nodes to be partitioned. 86 indices := shuffleIndices(len(nodes)) 87 88 partNodes := make([]string, n) 89 for i := 0; i < n; i++ { 90 partNodes[i] = nodes[indices[i]] 91 } 92 93 for i := 0; i < len(nodes); i++ { 94 ops[i] = &core.NemesisOperation{ 95 Name: "drop", 96 InvokeArgs: partNodes, 97 RunTime: time.Second * time.Duration(rand.Intn(10)+1), 98 } 99 } 100 101 return ops 102 } 103 104 func shuffleIndices(n int) []int { 105 indices := make([]int, n) 106 for i := 0; i < n; i++ { 107 indices[i] = i 108 } 109 for i := len(indices) - 1; i > 0; i-- { 110 j := rand.Intn(i + 1) 111 indices[i], indices[j] = indices[j], indices[i] 112 } 113 114 return indices 115 } 116 117 // NewDropGenerator creates a generator. 118 // Name is random_drop, minor_drop, major_drop, and all_drop. 119 func NewDropGenerator(name string) core.NemesisGenerator { 120 return dropGenerator{name: name} 121 }