Skip to content

Commit

Permalink
Mikrotik tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
udhos committed Dec 9, 2016
1 parent d89fc4a commit 7d4dc67
Show file tree
Hide file tree
Showing 2 changed files with 265 additions and 1 deletion.
2 changes: 1 addition & 1 deletion dev/model_junos_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ func handleConnectionJuniperJunOS(t *testing.T, c net.Conn, options optionsJunos
}

if _, err := c.Write([]byte("\n--- JUNOS 11.2R1.2 built 2011-06-22 02:55:58 UTC")); err != nil {
t.Logf("handleConnectionJuniperJunOS: send username prompt error: %v", err)
t.Logf("handleConnectionJuniperJunOS: send banner error: %v", err)
return
}

Expand Down
264 changes: 264 additions & 0 deletions dev/model_mikrotik_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,264 @@
package dev

import (
"io"
"net"
"path/filepath"
"strings"
"testing"

"github.com/udhos/jazigo/conf"
"github.com/udhos/jazigo/temp"
)

type optionsMikrotik struct {
breakConn bool
}

func TestMikrotik1(t *testing.T) {

// launch bogus test server
addr := ":2011"
s, listenErr := spawnServerMikrotik(t, addr, optionsMikrotik{})
if listenErr != nil {
t.Errorf("could not spawn bogus Mikrotik server: %v", listenErr)
}

// run client test
logger := &testLogger{t}
tab := NewDeviceTable()
opt := conf.NewOptions()
opt.Set(&conf.AppConfig{MaxConcurrency: 3, MaxConfigFiles: 10})
RegisterModels(logger, tab)
CreateDevice(tab, logger, "mikrotik", "lab1", "localhost"+addr, "telnet", "lab", "pass", "en", false, nil)

repo := temp.MakeTempRepo()
defer temp.CleanupTempRepo()

requestCh := make(chan FetchRequest)
errlogPrefix := filepath.Join(repo, "errlog_test.")
go Spawner(tab, logger, requestCh, repo, errlogPrefix, opt, NewFilterTable(logger))
good, bad, skip := Scan(tab, tab.ListDevices(), logger, opt.Get(), requestCh)
if good != 1 || bad != 0 || skip != 0 {
t.Errorf("good=%d bad=%d skip=%d", good, bad, skip)
}

close(requestCh) // shutdown Spawner - we might exit first though

s.close() // shutdown server

<-s.done // wait termination of accept loop goroutine
}

func TestMikrotik2(t *testing.T) {

// launch bogus test server
addr := ":2012"
s, listenErr := spawnServerMikrotik(t, addr, optionsMikrotik{breakConn: true})
if listenErr != nil {
t.Errorf("could not spawn bogus Mikrotik server: %v", listenErr)
}

// run client test
logger := &testLogger{t}
tab := NewDeviceTable()
opt := conf.NewOptions()
opt.Set(&conf.AppConfig{MaxConcurrency: 3, MaxConfigFiles: 10})
RegisterModels(logger, tab)
CreateDevice(tab, logger, "mikrotik", "lab1", "localhost"+addr, "telnet", "lab", "pass", "en", false, nil)

repo := temp.MakeTempRepo()
defer temp.CleanupTempRepo()

requestCh := make(chan FetchRequest)
errlogPrefix := filepath.Join(repo, "errlog_test.")
go Spawner(tab, logger, requestCh, repo, errlogPrefix, opt, NewFilterTable(logger))
good, bad, skip := Scan(tab, tab.ListDevices(), logger, opt.Get(), requestCh)
if good != 0 || bad != 1 || skip != 0 {
t.Errorf("good=%d bad=%d skip=%d", good, bad, skip)
}

close(requestCh) // shutdown Spawner - we might exit first though

s.close() // shutdown server

<-s.done // wait termination of accept loop goroutine
}

func spawnServerMikrotik(t *testing.T, addr string, options optionsMikrotik) (*testServer, error) {

ln, err := net.Listen("tcp", addr)
if err != nil {
return nil, err
}

s := &testServer{listener: ln, done: make(chan int)}

go acceptLoopMikrotik(t, s, handleConnectionMikrotik, options)

return s, nil
}

func acceptLoopMikrotik(t *testing.T, s *testServer, handler func(*testing.T, net.Conn, optionsMikrotik), options optionsMikrotik) {
for {
conn, err := s.listener.Accept()
if err != nil {
t.Logf("acceptLoopMikrotik: accept failure, exiting: %v", err)
break
}
go handler(t, conn, options)
}

close(s.done)
}

func handleConnectionMikrotik(t *testing.T, c net.Conn, options optionsMikrotik) {
defer c.Close()

buf := make([]byte, 1000)

// send username prompt
if _, err := c.Write([]byte("Login: ")); err != nil {
t.Logf("handleConnectionMikrotik: send username prompt error: %v", err)
return
}

// consume username
if _, err := c.Read(buf); err != nil {
t.Logf("handleConnectionMikrotik: read username error: %v", err)
return
}

// send password prompt
if _, err := c.Write([]byte("\nPassword: ")); err != nil {
t.Logf("handleConnectionMikrotik: send password prompt error: %v", err)
return
}

// consume password
if _, err := c.Read(buf); err != nil {
t.Logf("handleConnectionMikrotik: read password error: %v", err)
return
}

// send post login prompt

banner := `
MMM MMM KKK TTTTTTTTTTT KKK
MMMM MMMM KKK TTTTTTTTTTT KKK
MMM MMMM MMM III KKK KKK RRRRRR OOOOOO TTT III KKK KKK
MMM MM MMM III KKKKK RRR RRR OOO OOO TTT III KKKKK
MMM MMM III KKK KKK RRRRRR OOO OOO TTT III KKK KKK
MMM MMM III KKK KKK RRR RRR OOOOOO TTT III KKK KKK
MikroTik RouterOS 6.37.3 (c) 1999-2016 http://www.mikrotik.com/
ROUTER HAS NO SOFTWARE KEY
----------------------------
You have 20h19m to configure the router to be remotely accessible,
and to enter the key by pasting it in a Telnet window or in Winbox.
Turn off the device to stop the timer.
See www.mikrotik.com/key for more details.
Current installation "software ID": 6ZDH-HYFR
Please press "Enter" to continue!
`

if _, err := c.Write([]byte("\r\n" + banner)); err != nil {
t.Logf("handleConnectionMikrotik: send banner error: %v", err)
return
}

// consume response
if _, err := c.Read(buf); err != nil {
t.Logf("handleConnectionMikrotik: read response error: %v", err)
return
}

LOOP:
for {
// send command prompt
if _, err := c.Write([]byte("\r\n[admin@MikroTik] > ")); err != nil {
t.Logf("handleConnectionMikrotik: send command prompt error: %v", err)
return
}

// consume command
n, readErr := c.Read(buf)
if readErr != nil {
if readErr == io.EOF {
t.Logf("handleConnectionMikrotik: peer EOF")
return // peer closed connection
}
t.Logf("handleConnectionMikrotik: read command error: %v", readErr)
return
}

str := strings.TrimSpace(string(buf[:n]))

t.Logf("handleConnectionMikrotik: command: [%s]", str)

if strings.HasPrefix(str, "/") {
str = str[1:]
}

switch {
case strings.HasPrefix(str, "quit"):
break LOOP
case strings.HasPrefix(str, "export"):
if options.breakConn {
t.Logf("handleConnectionMikrotik: export command: will BREAK conn")
return // break connection (defer/close)
}

config := `# jan/08/2015 22:37:22 by RouterOS 6.37.3
# software id = PSRQ-KACL
#
/ip address
add address=192.168.56.100/24 interface=ether1 network=192.168.56.0
`
if _, err := c.Write([]byte("\r\n" + config)); err != nil {
t.Logf("handleConnectionMikrotik: send config error: %v", err)
return
}

case strings.HasPrefix(str, "system resource print"):

system :=
` uptime: 10h9m21s
version: 6.37.3 (stable)
build-time: Jan/28/2014 11:11:46
free-memory: 231.7MiB
total-memory: 249.8MiB
cpu: Intel(R)
cpu-count: 1
cpu-frequency: 0MHz
cpu-load: 100%
free-hdd-space: 3950.3MiB
total-hdd-space: 4032.5MiB
write-sect-since-reboot: 5896
write-sect-total: 5896
architecture-name: x86
board-name: x86
platform: MikroTik
`
if _, err := c.Write([]byte("\r\n" + system)); err != nil {
t.Logf("handleConnectionMikrotik: send system error: %v", err)
return
}
default:
if _, err := c.Write([]byte("\r\nbad command name")); err != nil {
t.Logf("handleConnectionMikrotik: send unknown command error: %v", err)
return
}
}

}

// send bye
if _, err := c.Write([]byte("\r\ninterrupted\r\n")); err != nil {
t.Logf("handleConnectionMikrotik: send bye error: %v", err)
return
}
}

0 comments on commit 7d4dc67

Please sign in to comment.