blob: cd4f96a5dc88fc3f55caa01b22502a237470f98f [file] [log] [blame]
Keita NISHIMOTO9708e042018-10-27 09:24:44 +09001/*
2 * Copyright 2018-present Open Networking Foundation
3
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7
8 * http://www.apache.org/licenses/LICENSE-2.0
9
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package core
18
19import (
20 "context"
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090021 "os/exec"
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090022 "sync"
Matteo Scandolo88e91892018-11-06 16:29:19 -080023 "time"
24
25 "gerrit.opencord.org/voltha-bbsim/common/logger"
26 log "github.com/sirupsen/logrus"
27 "golang.org/x/sync/errgroup"
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090028)
29
30const (
31 DEFAULT Mode = iota
32 AAA
33 BOTH
34)
35
36type Mode int
37
38type Tester struct {
39 Mode Mode
40 AAAWait int
41 DhcpWait int
42 DhcpServerIP string
43 Processes []string
44 Intvl int
45 cancel context.CancelFunc
46}
47
Matteo Scandolo88e91892018-11-06 16:29:19 -080048func NewTester(opt *option) *Tester {
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090049 t := new(Tester)
50 t.AAAWait = opt.aaawait
51 t.DhcpWait = opt.dhcpwait
52 t.DhcpServerIP = opt.dhcpservip
53 t.Intvl = opt.intvl_test
54 t.Mode = opt.Mode
55 return t
56}
57
58//Blocking
Matteo Scandolo88e91892018-11-06 16:29:19 -080059func (t *Tester) Start(s *Server) error {
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090060 ctx := context.Background()
61 ctx, cancel := context.WithCancel(ctx)
62 t.cancel = cancel
Matteo Scandolo88e91892018-11-06 16:29:19 -080063 defer func() {
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090064 cancel()
65 t.Initialize()
66 logger.Debug("Tester Done")
67 }()
68 logger.Info("Tester Run() start")
69 if t.Mode == DEFAULT {
70 //Empty
71 } else if t.Mode == AAA || t.Mode == BOTH {
72 eg, child := errgroup.WithContext(ctx)
73 child, cancel := context.WithCancel(child)
74 eg.Go(func() error {
75 defer func() {
76 logger.Debug("exeAAATest Done")
77 }()
78 err := t.exeAAATest(child, s, t.AAAWait)
79 return err
80 })
81
82 if t.Mode == BOTH {
83 eg.Go(func() error {
84 defer func() {
85 logger.Debug("exeDHCPTest Done")
86 }()
87
88 err := t.exeDHCPTest(ctx, s, t.DhcpWait)
89 return err
90 })
91 }
92 if err := eg.Wait(); err != nil {
93 logger.Error("Error happened in tester: %s", err)
94 cancel()
95 return err
96 } else {
97 logger.Debug("Test successfully finished")
98 }
99 }
100 return nil
101}
102
103func (t *Tester) Stop(s *Server) error {
104 if t.cancel != nil {
105 t.cancel()
106 }
107 return nil
108}
109
Matteo Scandolo88e91892018-11-06 16:29:19 -0800110func (t *Tester) Initialize() {
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900111 logger.Info("Tester Initialize () called")
112 processes := t.Processes
113 logger.Debug("Runnig Process: %s", processes)
114 KillProcesses(processes)
Matteo Scandolo88e91892018-11-06 16:29:19 -0800115 exec.Command("rm", "/var/run/dhcpd.pid").Run() //This is for DHCP server activation
116 exec.Command("touch", "/var/run/dhcpd.pid").Run() //This is for DHCP server activation
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900117}
118
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900119func (t *Tester) exeAAATest(ctx context.Context, s *Server, wait int) error {
120 tick := time.NewTicker(time.Second)
121 defer tick.Stop()
122 logger.Info("exeAAATest stands by....")
123 infos, err := s.GetUniIoinfos("outside")
124 if err != nil {
125 return err
126 }
127
128 univeths := []string{}
129 for _, info := range infos {
130 univeths = append(univeths, info.Name)
131 }
132
Matteo Scandolo88e91892018-11-06 16:29:19 -0800133 for sec := 1; sec <= wait; sec++ {
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900134 select {
135 case <-ctx.Done():
136 logger.Debug("exeAAATest thread receives close ")
137 return nil
138 case <-tick.C:
Matteo Scandolo88e91892018-11-06 16:29:19 -0800139 logger.WithField("seconds", wait-sec).Info("exeAAATest stands by ...")
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900140 if sec == wait {
141 wg := sync.WaitGroup{}
142 wg.Add(1)
Matteo Scandolo88e91892018-11-06 16:29:19 -0800143 go func() error {
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900144 defer wg.Done()
145 err = activateWPASups(ctx, univeths, t.Intvl)
146 if err != nil {
147 return err
148 }
149 logger.Info("WPA supplicants are successfully activated ")
150 t.Processes = append(t.Processes, "wpa_supplicant")
151 logger.Debug("Running Process:%s", t.Processes)
152 return nil
153 }()
154 wg.Wait()
155 }
156 }
157 }
158 return nil
159}
160
161func (t *Tester) exeDHCPTest(ctx context.Context, s *Server, wait int) error {
162 tick := time.NewTicker(time.Second)
163 defer tick.Stop()
164 logger.Info("exeDHCPTest stands by....")
165 info, err := s.IdentifyNniIoinfo("outside")
166 if err != nil {
167 return err
168 }
169
170 err = activateDHCPServer(info.Name, t.DhcpServerIP)
171 if err != nil {
172 return err
173 }
174 t.Processes = append(t.Processes, "dhcpd")
175 logger.Debug("Running Process:%s", t.Processes)
176
177 infos, err := s.GetUniIoinfos("outside")
178 if err != nil {
179 return err
180 }
181
182 univeths := []string{}
183 for _, info := range infos {
184 univeths = append(univeths, info.Name)
185 }
186
Matteo Scandolo88e91892018-11-06 16:29:19 -0800187 for sec := 1; sec <= wait; sec++ {
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900188 select {
Matteo Scandolo88e91892018-11-06 16:29:19 -0800189 case <-ctx.Done():
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900190 logger.Debug("exeDHCPTest thread receives close ")
191 return nil
Matteo Scandolo88e91892018-11-06 16:29:19 -0800192 case <-tick.C:
193 logger.WithField("seconds", wait-sec).Info("exeDHCPTest stands by ...")
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900194 if sec == wait {
195 wg := sync.WaitGroup{}
196 wg.Add(1)
Matteo Scandolo88e91892018-11-06 16:29:19 -0800197 go func() error {
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900198 defer wg.Done()
199 err = activateDHCPClients(ctx, univeths, t.Intvl)
200 if err != nil {
201 return err
202 }
Matteo Scandolo88e91892018-11-06 16:29:19 -0800203 logger.WithFields(log.Fields{
204 "univeths": univeths,
205 }).Info("DHCP clients are successfully activated")
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900206 t.Processes = append(t.Processes, "dhclient")
Matteo Scandolo88e91892018-11-06 16:29:19 -0800207 logger.Debug("Running Process: ", t.Processes)
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900208 return nil
209 }()
210 wg.Wait()
211 }
212 }
213 }
214 return nil
215}
216
217func KillProcesses(pnames []string) error {
218 for _, pname := range pnames {
219 killProcess(pname)
220 }
221 return nil
222}
223
224func activateWPASups(ctx context.Context, vethnames []string, intvl int) error {
225 tick := time.NewTicker(time.Duration(intvl) * time.Second)
226 defer tick.Stop()
227 i := 0
228 for {
Matteo Scandolo88e91892018-11-06 16:29:19 -0800229 select {
230 case <-tick.C:
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900231 if i < len(vethnames) {
232 vethname := vethnames[i]
233 if err := activateWPASupplicant(vethname); err != nil {
234 return err
235 }
236 logger.Debug("activateWPASupplicant for interface %v\n", vethname)
Matteo Scandolo88e91892018-11-06 16:29:19 -0800237 i++
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900238 }
Matteo Scandolo88e91892018-11-06 16:29:19 -0800239 case <-ctx.Done():
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900240 logger.Debug("activateWPASups was canceled by context.")
241 return nil
242 }
243 }
244 return nil
245}
246
247func activateDHCPClients(ctx context.Context, vethnames []string, intvl int) error {
248 tick := time.NewTicker(time.Duration(intvl) * time.Second)
249 defer tick.Stop()
250 i := 0
251 for {
Matteo Scandolo88e91892018-11-06 16:29:19 -0800252 select {
253 case <-tick.C:
254 if i < len(vethnames) {
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900255 vethname := vethnames[i]
256 if err := activateDHCPClient(vethname); err != nil {
257 return err
258 }
Matteo Scandolo88e91892018-11-06 16:29:19 -0800259 logger.WithFields(log.Fields{
260 "interface": vethname,
261 }).Debug("activateDHCPClient")
262 i++
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900263 }
Matteo Scandolo88e91892018-11-06 16:29:19 -0800264 case <-ctx.Done():
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900265 logger.Debug("activateDHCPClients was canceled by context.")
266 return nil
267 }
268 }
269 return nil
270}
271
272func killProcess(name string) error {
273 err := exec.Command("pkill", name).Run()
274 if err != nil {
275 logger.Error("Fail to pkill %s: %v\n", name, err)
276 return err
277 }
278 logger.Info("Successfully killed %s\n", name)
279 return nil
280}
281
282func activateWPASupplicant(vethname string) (err error) {
283 cmd := "/sbin/wpa_supplicant"
284 conf := "/etc/wpa_supplicant/wpa_supplicant.conf"
285 err = exec.Command(cmd, "-D", "wired", "-i", vethname, "-c", conf).Start()
286 if err != nil {
287 logger.Error("Fail to activateWPASupplicant() for :%s %v\n", vethname, err)
288 return
289 }
290 logger.Info("activateWPASupplicant() for :%s\n", vethname)
291 return
292}
293
294func activateDHCPClient(vethname string) (err error) {
295 logger.Debug("activateDHCPClient() start for: %s\n", vethname)
296 cmd := exec.Command("/usr/local/bin/dhclient", vethname)
297 // if err := cmd.Run(); err != nil {
298 if err := cmd.Start(); err != nil {
299 logger.Error("Fail to activateDHCPClient() for: %s", vethname)
Matteo Scandolo88e91892018-11-06 16:29:19 -0800300 logger.Panic(err)
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900301 }
302 logger.Debug("activateDHCPClient() done for: %s\n", vethname)
303 return
304}
305
306func activateDHCPServer(veth string, serverip string) error {
307 err := exec.Command("ip", "addr", "add", serverip, "dev", veth).Run()
308 if err != nil {
309 logger.Error("Fail to add ip to %s address: %s\n", veth, err)
310 return err
311 }
312 err = exec.Command("ip", "link", "set", veth, "up").Run()
313 if err != nil {
314 logger.Error("Fail to set %s up: %s\n", veth, err)
315 return err
316 }
317 cmd := "/usr/local/bin/dhcpd"
318 conf := "/etc/dhcp/dhcpd.conf"
319 err = exec.Command(cmd, "-cf", conf, veth).Run()
320 if err != nil {
321 logger.Error("Fail to activateDHCP Server (): %s\n", err)
322 return err
323 }
324 logger.Info("DHCP Server is successfully activated !\n")
325 return err
326}