Updating executor to remove old util.go

Adding new Network interaction "class"
This commit is contained in:
Philippe Caseiro 2018-09-20 16:43:31 +02:00
parent 735bc8d19e
commit b680e256b9
6 changed files with 154 additions and 42 deletions

View File

@ -5,6 +5,7 @@ import (
"fmt" "fmt"
"log" "log"
"os/exec" "os/exec"
"syscall"
) )
// Executor interface to describe command runners signature // Executor interface to describe command runners signature
@ -12,12 +13,22 @@ type Executor interface {
Run(command string, params ...string) *CommandResult Run(command string, params ...string) *CommandResult
} }
// CommandResult contain all information about a command execution, stdout, stderr
type CommandResult struct {
Stdout string
Stderr string
ReturnCode int
}
type localExecutor struct{} type localExecutor struct{}
func (e *localExecutor) Run(command string, params ...string) *CommandResult { func (e *localExecutor) Run(command string, params ...string) *CommandResult {
var out bytes.Buffer var out bytes.Buffer
var stderr bytes.Buffer var stderr bytes.Buffer
var exitCode int
defaultFailedCode := 255
exe := exec.Command(command, params...) exe := exec.Command(command, params...)
exe.Stdout = &out exe.Stdout = &out
@ -25,14 +36,32 @@ func (e *localExecutor) Run(command string, params ...string) *CommandResult {
err := exe.Run() err := exe.Run()
if err != nil { if err != nil {
if exitError, ok := err.(*exec.ExitError); ok {
ws := exitError.Sys().(syscall.WaitStatus)
exitCode = ws.ExitStatus()
} else {
// This will happen (in OSX) if `name` is not available in $PATH,
// in this situation, exit code could not be get, and stderr will be
// empty string very likely, so we use the default fail code, and format err
// to string and set to stderr
log.Printf("Could not get exit code for failed program: %v, %v", command, params)
exitCode = defaultFailedCode
}
fmt.Println(fmt.Sprint(err) + ": " + stderr.String()) fmt.Println(fmt.Sprint(err) + ": " + stderr.String())
log.Fatal(err) log.Fatal(err)
} }
if err != nil {
// try to get the exit code
} else {
// success, exitCode should be 0 if go is ok
ws := exe.ProcessState.Sys().(syscall.WaitStatus)
exitCode = ws.ExitStatus()
}
return &CommandResult{ return &CommandResult{
Stdout: out.String(), Stdout: out.String(),
Stderr: stderr.String(), Stderr: stderr.String(),
// FIXME ReturnCode: exitCode,
ReturnCode: 0,
} }
} }

18
openwrt/executor_test.go Normal file
View File

@ -0,0 +1,18 @@
package openwrt
import (
"testing"
)
func TestRun(t *testing.T) {
exec := &localExecutor{}
res := exec.Run("uname", "-a")
if g, e := res.ReturnCode, 0; g != e {
t.Errorf("Run command failed ! Got bad return code [%d], [%d} is expected\n", g, e)
}
// res = exec.Run("noCommandWithThisNameExists", "-a")
// if g, e := res.ReturnCode, 127; g != e {
// t.Errorf("Run command failed ! Got bad return code [%d], [%d} is expected\n", g, e)
// }
}

75
openwrt/network.go Normal file
View File

@ -0,0 +1,75 @@
package openwrt
import (
"fmt"
"io/ioutil"
"net"
"strings"
)
// Network provides a representation of network
type Network struct {
exec Executor
}
// NewNetwork return an UCI instance to interact with UCI
func NewNetwork() *Network {
exec := &localExecutor{}
return &Network{exec}
}
// NewNetworkWithExecutor return an UCI instance to interact with UCI
func NewNetworkWithExecutor(exe Executor) *Network {
exec := exe
return &Network{exec}
}
// ListInterfaces list all available interfaces on a system using "ip" commmand
func (n *Network) ListInterfaces() []net.Interface {
var result []net.Interface
ifaces, err := net.Interfaces()
if err != nil {
fmt.Print(fmt.Errorf("error listing network interfacess: %+v", err.Error()))
return nil
}
for _, i := range ifaces {
result = append(result, i)
}
return result
}
// ListWirelessInterfaces list all wifi cards
func (n *Network) ListWirelessInterfaces() []net.Interface {
var result []net.Interface
var ifaceNames []string
wifiFile := "/proc/net/wireless"
wifiFileContent, err := ioutil.ReadFile(wifiFile)
check(err)
index := 0
for _, line := range strings.Split(string(wifiFileContent), "\n") {
if index < 2 {
index++
continue
} else {
name := strings.Split(line, ":")[0]
ifaceNames = append(ifaceNames, name)
}
}
ifaces, err := net.Interfaces()
if err != nil {
fmt.Print(fmt.Errorf("error listing network interfaces : %+v", err.Error()))
return nil
}
for _, i := range ifaces {
for _, name := range ifaceNames {
if name == i.Name {
result = append(result, i)
}
}
}
return result
}

22
openwrt/network_test.go Normal file
View File

@ -0,0 +1,22 @@
package openwrt
import (
"fmt"
"testing"
)
func TestNetworkListInterfaces(t *testing.T) {
net := NewNetwork()
iface := net.ListInterfaces()
for _, ife := range iface {
fmt.Printf("%s\n", ife.Name)
}
}
func TestListWirelessInterfaces(t *testing.T) {
net := NewNetwork()
res := net.ListWirelessInterfaces()
for _, el := range res {
fmt.Printf("%s\n", el.Name)
}
}

View File

@ -5,6 +5,12 @@ import (
"strings" "strings"
) )
func check(e error) {
if e != nil {
panic(e)
}
}
func createMockExecutor(stdout string, stderr string, returnCode int) Executor { func createMockExecutor(stdout string, stderr string, returnCode int) Executor {
return &mockExecutor{ return &mockExecutor{
stdout: stdout, stdout: stdout,

View File

@ -1,38 +0,0 @@
package openwrt
import (
"bytes"
"fmt"
"log"
"os/exec"
)
// CommandResult contain all information about a command execution, stdout, stderr
type CommandResult struct {
Stdout string
Stderr string
ReturnCode int
}
// Run executes a system command and returns
func run(command string, params ...string) *CommandResult {
var out bytes.Buffer
var stderr bytes.Buffer
exe := exec.Command(command, params...)
exe.Stdout = &out
exe.Stderr = &stderr
err := exe.Run()
if err != nil {
fmt.Println(fmt.Sprint(err) + ": " + stderr.String())
log.Fatal(err)
}
return &CommandResult{
Stdout: out.String(),
Stderr: stderr.String(),
// FIXME
ReturnCode: 0,
}
}