1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package netem
17
18 import (
19 "math"
20 "strconv"
21 "strings"
22 "time"
23
24 chaosdaemon "github.com/chaos-mesh/chaos-mesh/pkg/chaosdaemon/pb"
25 )
26
27
28
29
30
31
32
33 func MergeNetem(a, b *chaosdaemon.Netem) *chaosdaemon.Netem {
34 if a == nil && b == nil {
35 return nil
36 }
37
38
39 if a == nil {
40 a = &chaosdaemon.Netem{}
41 }
42 if b == nil {
43 b = &chaosdaemon.Netem{}
44 }
45 return &chaosdaemon.Netem{
46 Time: maxDurationString(a.GetTime(), b.GetTime()),
47 Jitter: maxDurationString(a.GetJitter(), b.GetJitter()),
48 DelayCorr: maxf32(a.GetDelayCorr(), b.GetDelayCorr()),
49 Limit: maxu32(a.GetLimit(), b.GetLimit()),
50 Loss: maxf32(a.GetLoss(), b.GetLoss()),
51 LossCorr: maxf32(a.GetLossCorr(), b.GetLossCorr()),
52 Gap: maxu32(a.GetGap(), b.GetGap()),
53 Duplicate: maxf32(a.GetDuplicate(), b.GetDuplicate()),
54 DuplicateCorr: maxf32(a.GetDuplicateCorr(), b.GetDuplicateCorr()),
55 Reorder: maxf32(a.GetReorder(), b.GetReorder()),
56 ReorderCorr: maxf32(a.GetReorderCorr(), b.GetReorderCorr()),
57 Corrupt: maxf32(a.GetCorrupt(), b.GetCorrupt()),
58 CorruptCorr: maxf32(a.GetCorruptCorr(), b.GetCorruptCorr()),
59 Rate: maxRateString(a.GetRate(), b.GetRate()),
60 }
61 }
62
63 func maxDurationString(a, b string) string {
64 ad, err := time.ParseDuration(a)
65 if err != nil {
66 ad = 0
67 }
68 bd, err := time.ParseDuration(b)
69 if err != nil {
70 bd = 0
71 }
72 if ad > bd {
73 return a
74 }
75 return b
76 }
77
78 func maxu32(a, b uint32) uint32 {
79 if a > b {
80 return a
81 }
82 return b
83 }
84
85 func maxf32(a, b float32) float32 {
86 return float32(math.Max(float64(a), float64(b)))
87 }
88
89 func parseRate(nu string) uint64 {
90
91 s := strings.ToLower(strings.TrimSpace(nu))
92
93 for i, u := range []string{"tbps", "gbps", "mbps", "kbps", "bps"} {
94 if strings.HasSuffix(s, u) {
95 ts := strings.TrimSuffix(s, u)
96 s := strings.TrimSpace(ts)
97
98 n, err := strconv.ParseUint(s, 10, 64)
99
100 if err != nil {
101 return 0
102 }
103
104
105 for j := 4 - i; j > 0; j-- {
106 n = n * 1024
107 }
108
109 return n
110 }
111 }
112
113 for i, u := range []string{"tbit", "gbit", "mbit", "kbit", "bit"} {
114 if strings.HasSuffix(s, u) {
115 ts := strings.TrimSuffix(s, u)
116 s := strings.TrimSpace(ts)
117
118 n, err := strconv.ParseUint(s, 10, 64)
119
120 if err != nil {
121 return 0
122 }
123
124
125 for j := 4 - i; j > 0; j-- {
126 n = n * 1000
127 }
128 n = n / 8
129
130 return n
131 }
132 }
133
134 return 0
135 }
136
137 func maxRateString(a, b string) string {
138 if parseRate(a) > parseRate(b) {
139 return a
140 }
141 return b
142 }
143