blob: 4f9ccafa49cc93149254ebae0298831a6cd1364f [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"
Matteo Scandolo2aca22c2018-11-08 14:12:07 -080026 "gerrit.opencord.org/voltha-bbsim/common/utils"
Matteo Scandolo88e91892018-11-06 16:29:19 -080027 log "github.com/sirupsen/logrus"
28 "golang.org/x/sync/errgroup"
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090029)
30
31const (
32 DEFAULT Mode = iota
33 AAA
34 BOTH
35)
36
37type Mode int
38
39type Tester struct {
40 Mode Mode
41 AAAWait int
42 DhcpWait int
43 DhcpServerIP string
44 Processes []string
45 Intvl int
46 cancel context.CancelFunc
47}
48
Matteo Scandolo88e91892018-11-06 16:29:19 -080049func NewTester(opt *option) *Tester {
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090050 t := new(Tester)
51 t.AAAWait = opt.aaawait
52 t.DhcpWait = opt.dhcpwait
53 t.DhcpServerIP = opt.dhcpservip
54 t.Intvl = opt.intvl_test
55 t.Mode = opt.Mode
56 return t
57}
58
59//Blocking
Matteo Scandolo88e91892018-11-06 16:29:19 -080060func (t *Tester) Start(s *Server) error {
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090061 ctx := context.Background()
62 ctx, cancel := context.WithCancel(ctx)
63 t.cancel = cancel
Matteo Scandolo88e91892018-11-06 16:29:19 -080064 defer func() {
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090065 cancel()
66 t.Initialize()
67 logger.Debug("Tester Done")
68 }()
69 logger.Info("Tester Run() start")
70 if t.Mode == DEFAULT {
71 //Empty
72 } else if t.Mode == AAA || t.Mode == BOTH {
73 eg, child := errgroup.WithContext(ctx)
74 child, cancel := context.WithCancel(child)
75 eg.Go(func() error {
76 defer func() {
77 logger.Debug("exeAAATest Done")
78 }()
79 err := t.exeAAATest(child, s, t.AAAWait)
80 return err
81 })
82
83 if t.Mode == BOTH {
84 eg.Go(func() error {
85 defer func() {
86 logger.Debug("exeDHCPTest Done")
87 }()
88
89 err := t.exeDHCPTest(ctx, s, t.DhcpWait)
90 return err
91 })
92 }
93 if err := eg.Wait(); err != nil {
94 logger.Error("Error happened in tester: %s", err)
95 cancel()
96 return err
97 } else {
98 logger.Debug("Test successfully finished")
99 }
100 }
101 return nil
102}
103
104func (t *Tester) Stop(s *Server) error {
105 if t.cancel != nil {
106 t.cancel()
107 }
108 return nil
109}
110
Matteo Scandolo88e91892018-11-06 16:29:19 -0800111func (t *Tester) Initialize() {
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900112 logger.Info("Tester Initialize () called")
113 processes := t.Processes
114 logger.Debug("Runnig Process: %s", processes)
115 KillProcesses(processes)
Matteo Scandolo88e91892018-11-06 16:29:19 -0800116 exec.Command("rm", "/var/run/dhcpd.pid").Run() //This is for DHCP server activation
117 exec.Command("touch", "/var/run/dhcpd.pid").Run() //This is for DHCP server activation
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900118}
119
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800120type UniVeth struct {
121 OnuId uint32
122 Veth string
123}
124
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900125func (t *Tester) exeAAATest(ctx context.Context, s *Server, wait int) error {
126 tick := time.NewTicker(time.Second)
127 defer tick.Stop()
128 logger.Info("exeAAATest stands by....")
129 infos, err := s.GetUniIoinfos("outside")
130 if err != nil {
131 return err
132 }
133
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800134 univeths := []UniVeth{}
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900135 for _, info := range infos {
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800136 uv := UniVeth{
137 OnuId: info.onuid,
138 Veth: info.Name,
139 }
140 univeths = append(univeths, uv)
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900141 }
142
Matteo Scandolo88e91892018-11-06 16:29:19 -0800143 for sec := 1; sec <= wait; sec++ {
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900144 select {
145 case <-ctx.Done():
146 logger.Debug("exeAAATest thread receives close ")
147 return nil
148 case <-tick.C:
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800149 logger.WithField("seconds", wait-sec).Info("exeAAATest stands by ... ", wait-sec)
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900150 if sec == wait {
151 wg := sync.WaitGroup{}
152 wg.Add(1)
Matteo Scandolo88e91892018-11-06 16:29:19 -0800153 go func() error {
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900154 defer wg.Done()
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800155 err = activateWPASups(ctx, univeths, t.Intvl, s)
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900156 if err != nil {
157 return err
158 }
159 logger.Info("WPA supplicants are successfully activated ")
160 t.Processes = append(t.Processes, "wpa_supplicant")
161 logger.Debug("Running Process:%s", t.Processes)
162 return nil
163 }()
164 wg.Wait()
165 }
166 }
167 }
168 return nil
169}
170
171func (t *Tester) exeDHCPTest(ctx context.Context, s *Server, wait int) error {
172 tick := time.NewTicker(time.Second)
173 defer tick.Stop()
174 logger.Info("exeDHCPTest stands by....")
175 info, err := s.IdentifyNniIoinfo("outside")
176 if err != nil {
177 return err
178 }
179
180 err = activateDHCPServer(info.Name, t.DhcpServerIP)
181 if err != nil {
182 return err
183 }
184 t.Processes = append(t.Processes, "dhcpd")
185 logger.Debug("Running Process:%s", t.Processes)
186
187 infos, err := s.GetUniIoinfos("outside")
188 if err != nil {
189 return err
190 }
191
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800192 univeths := []UniVeth{}
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900193 for _, info := range infos {
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800194 uv := UniVeth{
195 OnuId: info.onuid,
196 Veth: info.Name,
197 }
198 univeths = append(univeths, uv)
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900199 }
200
Matteo Scandolo88e91892018-11-06 16:29:19 -0800201 for sec := 1; sec <= wait; sec++ {
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900202 select {
Matteo Scandolo88e91892018-11-06 16:29:19 -0800203 case <-ctx.Done():
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900204 logger.Debug("exeDHCPTest thread receives close ")
205 return nil
Matteo Scandolo88e91892018-11-06 16:29:19 -0800206 case <-tick.C:
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800207 logger.WithField("seconds", wait-sec).Info("exeDHCPTest stands by ... ", wait-sec)
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900208 if sec == wait {
209 wg := sync.WaitGroup{}
210 wg.Add(1)
Matteo Scandolo88e91892018-11-06 16:29:19 -0800211 go func() error {
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900212 defer wg.Done()
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800213 err = activateDHCPClients(ctx, univeths, t.Intvl, s)
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900214 if err != nil {
215 return err
216 }
Matteo Scandolo88e91892018-11-06 16:29:19 -0800217 logger.WithFields(log.Fields{
218 "univeths": univeths,
219 }).Info("DHCP clients are successfully activated")
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900220 t.Processes = append(t.Processes, "dhclient")
Matteo Scandolo88e91892018-11-06 16:29:19 -0800221 logger.Debug("Running Process: ", t.Processes)
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900222 return nil
223 }()
224 wg.Wait()
225 }
226 }
227 }
228 return nil
229}
230
231func KillProcesses(pnames []string) error {
232 for _, pname := range pnames {
233 killProcess(pname)
234 }
235 return nil
236}
237
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800238func activateWPASups(ctx context.Context, vethnames []UniVeth, intvl int, s *Server) error {
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900239 tick := time.NewTicker(time.Duration(intvl) * time.Second)
240 defer tick.Stop()
241 i := 0
242 for {
Matteo Scandolo88e91892018-11-06 16:29:19 -0800243 select {
244 case <-tick.C:
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900245 if i < len(vethnames) {
246 vethname := vethnames[i]
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800247 if err := activateWPASupplicant(vethname, s); err != nil {
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900248 return err
249 }
Matteo Scandolo88e91892018-11-06 16:29:19 -0800250 i++
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900251 }
Matteo Scandolo88e91892018-11-06 16:29:19 -0800252 case <-ctx.Done():
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900253 logger.Debug("activateWPASups was canceled by context.")
254 return nil
255 }
256 }
257 return nil
258}
259
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800260func activateDHCPClients(ctx context.Context, vethnames []UniVeth, intvl int, s *Server) error {
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900261 tick := time.NewTicker(time.Duration(intvl) * time.Second)
262 defer tick.Stop()
263 i := 0
264 for {
Matteo Scandolo88e91892018-11-06 16:29:19 -0800265 select {
266 case <-tick.C:
267 if i < len(vethnames) {
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900268 vethname := vethnames[i]
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800269 if err := activateDHCPClient(vethname, s); err != nil {
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900270 return err
271 }
Matteo Scandolo88e91892018-11-06 16:29:19 -0800272 i++
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900273 }
Matteo Scandolo88e91892018-11-06 16:29:19 -0800274 case <-ctx.Done():
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900275 logger.Debug("activateDHCPClients was canceled by context.")
276 return nil
277 }
278 }
279 return nil
280}
281
282func killProcess(name string) error {
283 err := exec.Command("pkill", name).Run()
284 if err != nil {
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800285 logger.Error("Fail to pkill %s: %v", name, err)
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900286 return err
287 }
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800288 logger.Info("Successfully killed %s", name)
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900289 return nil
290}
291
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800292func activateWPASupplicant(univeth UniVeth, s *Server) (err error) {
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900293 cmd := "/sbin/wpa_supplicant"
294 conf := "/etc/wpa_supplicant/wpa_supplicant.conf"
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800295 err = exec.Command(cmd, "-D", "wired", "-i", univeth.Veth, "-c", conf).Start()
296 onu, _ := s.GetOnuByID(univeth.OnuId)
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900297 if err != nil {
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800298 utils.LoggerWithOnu(onu).WithFields(log.Fields{
299 "err": err,
300 "veth": univeth.Veth,
301 }).Error("Fail to activateWPASupplicant()", err)
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900302 return
303 }
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800304 logger.Info("activateWPASupplicant() for :%s", univeth.Veth)
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900305 return
306}
307
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800308func activateDHCPClient(univeth UniVeth, s *Server) (err error) {
309 onu, _ := s.GetOnuByID(univeth.OnuId)
Matteo Scandolo2a659142018-11-15 11:23:45 -0800310
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800311 cmd := exec.Command("/usr/local/bin/dhclient", univeth.Veth)
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900312 if err := cmd.Start(); err != nil {
Matteo Scandolo2a659142018-11-15 11:23:45 -0800313 logger.Error("Fail to activateDHCPClient() for: %s", univeth.Veth)
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800314 logger.Panic("activateDHCPClient %s", err)
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900315 }
Matteo Scandolo2a659142018-11-15 11:23:45 -0800316 utils.LoggerWithOnu(onu).WithFields(log.Fields{
317 "veth": univeth.Veth,
318 }).Infof("activateDHCPClient() start for: %s", univeth.Veth)
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900319 return
320}
321
322func activateDHCPServer(veth string, serverip string) error {
323 err := exec.Command("ip", "addr", "add", serverip, "dev", veth).Run()
324 if err != nil {
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800325 logger.Error("Fail to add ip to %s address: %s", veth, err)
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900326 return err
327 }
328 err = exec.Command("ip", "link", "set", veth, "up").Run()
329 if err != nil {
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800330 logger.Error("Fail to set %s up: %s", veth, err)
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900331 return err
332 }
333 cmd := "/usr/local/bin/dhcpd"
334 conf := "/etc/dhcp/dhcpd.conf"
335 err = exec.Command(cmd, "-cf", conf, veth).Run()
336 if err != nil {
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800337 logger.Error("Fail to activateDHCP Server (): %s", err)
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900338 return err
339 }
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800340 logger.Info("DHCP Server is successfully activated !")
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900341 return err
342}