blob: 623447db5904eead5dfc9efdb38307c88f33da8f [file] [log] [blame]
/*
* Copyright 2018-present Open Networking Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package core
import (
"bytes"
"context"
"fmt"
"os/exec"
"strconv"
"time"
"github.com/opencord/voltha-bbsim/common/logger"
"github.com/opencord/voltha-bbsim/device"
)
// TestManager is the structure for test manager
type TestManager struct {
DhcpServerIP string
Pid []int
testers map[string]map[device.Devkey]*Tester
ctx context.Context
cancel context.CancelFunc
}
// Tester is the structure for Test
type Tester struct {
Type string
Key device.Devkey
Testfunc func(device.Devkey) error
Waitsec int
ctx context.Context
cancel context.CancelFunc
}
// NewTestManager returns new TestManager
func NewTestManager(opt *option) *TestManager {
t := new(TestManager)
t.DhcpServerIP = opt.dhcpservip
return t
}
// CreateTester creates instance of Tester
func (*TestManager) CreateTester(testtype string, opt *option, key device.Devkey, fn func(device.Devkey) error, waitsec int) *Tester {
logger.Debug("CreateTester() called")
t := new(Tester)
t.Type = testtype
t.Key = key
t.Testfunc = fn
t.Waitsec = waitsec
return t
}
// Start does starting action - Blocking Call
func (tm *TestManager) Start() error {
ctx, cancel := context.WithCancel(context.Background())
tm.ctx = ctx
tm.cancel = cancel
tm.testers = make(map[string]map[device.Devkey]*Tester)
tm.testers["AAA"] = map[device.Devkey]*Tester{}
tm.testers["DHCP"] = map[device.Devkey]*Tester{}
logger.Info("TestManager start")
return nil
}
// Stop does stopping action
func (tm *TestManager) Stop() error {
if tm.cancel != nil {
tm.cancel()
}
tm.Initialize()
logger.Debug("TestManager Done")
return nil
}
func (tm *TestManager) StartTester(t *Tester) error {
testtype := t.Type
key := t.Key
waitsec := t.Waitsec
// TODO use timers instead of this crazy loop: https://gobyexample.com/timers
logger.Debug("StartTester type:%s called with key:%v", testtype, key)
child, cancel := context.WithCancel(tm.ctx)
t.ctx = child
t.cancel = cancel
go func() error {
tick := time.NewTicker(time.Second)
counter := 0
defer func() {
tick.Stop()
logger.Debug("Tester type:%s with key %v Done", testtype, key)
}()
L:
for counter < waitsec {
select {
case <-tick.C:
counter++
if counter == waitsec { // TODO: This should be fixed
break L
}
case <-child.Done():
return nil
}
}
err := t.Testfunc(key)
if err != nil {
return err
}
return nil
}()
tm.testers[testtype][key] = t
return nil
}
// StopTester stops the test
func (tm *TestManager) StopTester(testtype string, key device.Devkey) error {
ts := tm.testers[testtype][key]
ts.cancel()
delete(tm.testers[testtype], key)
return nil
}
// Initialize test manager
func (tm *TestManager) Initialize() {
logger.Info("TestManager Initialize () called")
pids := tm.Pid
logger.Debug("Runnig Process: %v", pids)
KillProcesses(pids)
exec.Command("rm", "/var/run/dhcpd.pid").Run() // This is for DHCP server activation
exec.Command("touch", "/var/run/dhcpd.pid").Run() // This is for DHCP server activation
}
// KillProcesses kill process by specified pid
func KillProcesses(pids []int) error {
for _, pname := range pids {
killProcess(pname)
}
return nil
}
func killProcess(pid int) error {
err := exec.Command("kill", strconv.Itoa(pid)).Run()
if err != nil {
logger.Error("Fail to kill %d: %v", pid, err)
return err
}
logger.Info("Successfully killed %d", pid)
return nil
}
func activateWPASupplicant(key device.Devkey) (err error) {
if err = startEAPClient(key.Intfid, key.ID); err != nil {
errmsg := fmt.Sprintf("Failed to activate WPA Supplicant intfid: %d onuid: %d", key.Intfid, key.ID)
logger.Error(errmsg)
}
logger.Info("Successfuly activateWPASupplicant() for intfid:%d onuid:%d", key.Intfid, key.ID)
return nil
}
func activateDHCPClient(key device.Devkey) (err error) {
if err = startDHCPClient(key.Intfid, key.ID); err != nil {
errmsg := fmt.Sprintf("Failed to activate DHCP client intfid: %d onuid: %d", key.Intfid, key.ID)
logger.Error(errmsg)
}
return nil
}
func activateDHCPServer(veth string, serverip string) error {
err := exec.Command("ip", "addr", "add", serverip, "dev", veth).Run()
if err != nil {
logger.Error("Fail to add ip to %s address: %s", veth, err)
return err
}
err = exec.Command("ip", "link", "set", veth, "up").Run()
if err != nil {
logger.Error("Fail to set %s up: %s", veth, err)
return err
}
dhcp := "/usr/local/bin/dhcpd"
conf := "/etc/dhcp/dhcpd.conf"
logfile := "/tmp/dhcplog"
var stderr bytes.Buffer
cmd := exec.Command(dhcp, "-cf", conf, veth, "-tf", logfile)
cmd.Stderr = &stderr
err = cmd.Run()
if err != nil {
logger.Error("Fail to activateDHCP Server (): %s, %s", err, stderr.String())
return err
}
logger.Info("DHCP Server is successfully activated !")
return err
}