func setup_diff() (*ripTestApp, *ripTestClient) { app := &ripTestApp{ cmdRoot: &command.CmdNode{MinLevel: command.EXEC}, confRootCandidate: &command.ConfNode{}, confRootActive: &command.ConfNode{}, } hardware := fwd.NewDataplaneBogus() listInterfaces := func() ([]string, []string) { ifaces, vrfs, err := hardware.Interfaces() if err != nil { log.Printf("Example_diff: hardware.Interfaces(): error: %v", err) } return ifaces, vrfs } listCommitId := func() []string { return []string{"BOGUS:rip.Example_diff:listCommitId"} } command.LoadKeywordTable(listInterfaces, listCommitId) root := app.cmdRoot cmdNone := command.CMD_NONE cmdConf := command.CMD_CONF command.CmdInstall(root, cmdNone, "commit", command.CONF, command.HelperCommit, nil, "Apply current candidate configuration") command.CmdInstall(root, cmdNone, "show configuration", command.EXEC, command.HelperShowConf, nil, "Show candidate configuration") command.CmdInstall(root, cmdNone, "show configuration compare", command.EXEC, command.HelperShowCompare, nil, "Show differences between active and candidate configurations") command.CmdInstall(root, cmdNone, "no {ANY}", command.CONF, command.HelperNo, nil, "Remove a configuration item") command.CmdInstall(root, cmdConf, "username {USERNAME} password (PASSWORD)", command.EXEC, cmdUsername, command.ApplyBogus, "User clear-text password") command.CmdInstall(root, cmdConf, "hostname (HOSTNAME)", command.CONF, command.HelperHostname, command.ApplyBogus, "Hostname") command.CmdInstall(root, cmdNone, "show version", command.EXEC, cmdVersion, nil, "Show version") command.CmdInstall(root, cmdConf, "router rip", command.CONF, cmdRip, applyRip, "Enable RIP protocol") command.CmdInstall(root, cmdConf, "router rip network {NETWORK}", command.CONF, cmdRipNetwork, applyRipNet, "Insert network into RIP protocol") command.CmdInstall(root, cmdConf, "router rip network {NETWORK} cost (RIPMETRIC)", command.CONF, cmdRipNetCost, applyRipNetCost, "RIP network metric") command.CmdInstall(root, cmdConf, "router rip vrf {VRFNAME} network {NETWORK}", command.CONF, cmdRipNetwork, applyRipNet, "Insert network into RIP protocol") command.CmdInstall(root, cmdConf, "router rip vrf {VRFNAME} network {NETWORK} cost (RIPMETRIC)", command.CONF, cmdRipNetCost, applyRipNetCost, "RIP network metric") outputSinkFunc := func(m string) { } c := NewRipTestClient(outputSinkFunc) return app, c }
func setup_diff() (*bgpTestApp, *bgpTestClient) { app := &bgpTestApp{ cmdRoot: &command.CmdNode{MinLevel: command.EXEC}, confRootCandidate: &command.ConfNode{}, confRootActive: &command.ConfNode{}, } hardware := fwd.NewDataplaneBogus() listInterfaces := func() ([]string, []string) { ifaces, vrfs, err := hardware.Interfaces() if err != nil { log.Printf("Example_diff: hardware.Interfaces(): error: %v", err) } return ifaces, vrfs } listCommitId := func() []string { return []string{"BOGUS:bgp.Example_diff:listCommitId"} } command.LoadKeywordTable(listInterfaces, listCommitId) root := app.cmdRoot cmdNone := command.CMD_NONE cmdConf := command.CMD_CONF command.CmdInstall(root, cmdNone, "commit", command.CONF, command.HelperCommit, nil, "Apply current candidate configuration") command.CmdInstall(root, cmdNone, "show configuration", command.EXEC, command.HelperShowConf, nil, "Show candidate configuration") command.CmdInstall(root, cmdNone, "show configuration compare", command.EXEC, command.HelperShowCompare, nil, "Show differences between active and candidate configurations") command.CmdInstall(root, cmdNone, "no {ANY}", command.CONF, command.HelperNo, nil, "Remove a configuration item") command.CmdInstall(root, cmdConf, "hostname (HOSTNAME)", command.CONF, command.HelperHostname, command.ApplyBogus, "Hostname") command.CmdInstall(root, cmdNone, "show version", command.EXEC, cmdVersion, nil, "Show version") command.CmdInstall(root, cmdConf, "router bgp {ASN} neighbor {IPADDR} description {ANY}", command.CONF, cmdNeighDesc, command.ApplyBogus, "BGP neighbor description") command.CmdInstall(root, cmdConf, "router bgp {ASN} neighbor {IPADDR} remote-as (ASN)", command.CONF, cmdNeighAsn, applyNeighAsn, "BGP neighbor ASN") outputSinkFunc := func(m string) { } c := NewBgpTestClient(outputSinkFunc) return app, c }
func main() { daemonName := "rip" log.Printf("%s daemon starting", daemonName) rip := &Rip{ cmdRoot: &command.CmdNode{Path: "", MinLevel: command.EXEC, Handler: nil}, confRootCandidate: &command.ConfNode{}, confRootActive: &command.ConfNode{}, daemonName: daemonName, hardware: fwd.NewDataplaneBogus(), } var dataplaneName string configPrefix := command.ConfigPathRoot + "/" + daemonName + ".conf." flag.StringVar(&rip.configPathPrefix, "configPathPrefix", configPrefix, "configuration path prefix") flag.IntVar(&rip.maxConfigFiles, "maxConfigFiles", command.DefaultMaxConfigFiles, "limit number of configuration files (negative value means unlimited)") flag.StringVar(&dataplaneName, "dataplane", "native", "select forwarding engine") flag.Parse() rip.hardware = fwd.NewDataplane(dataplaneName) listInterfaces := func() ([]string, []string) { ifaces, vrfs, err := rip.hardware.Interfaces() if err != nil { log.Printf("%s main: Interfaces(): error: %v", rip.daemonName, err) } return ifaces, vrfs } listCommitId := func() []string { _, matches, err := command.ListConfig(rip.ConfigPathPrefix(), true) if err != nil { log.Printf("%s main: error listing commit id's: %v", rip.daemonName, err) } var idList []string for _, m := range matches { id, err1 := command.ExtractCommitIdFromFilename(m) if err1 != nil { log.Printf("%s main: error extracting commit id's: %v", rip.daemonName, err1) continue } idList = append(idList, strconv.Itoa(id)) } return idList } command.LoadKeywordTable(listInterfaces, listCommitId) installCommands(rip.CmdRoot()) loadConf(rip) cliServer := cli.NewServer() go cli.ListenTelnet(":2002", cliServer) tick := time.Duration(10) ticker := time.NewTicker(time.Second * tick) for { select { case <-ticker.C: log.Printf("%s main: %ds tick", rip.daemonName, tick) case comm := <-cliServer.CommandChannel: log.Printf("%s main: command: isLine=%v len=%d [%s]", rip.daemonName, comm.IsLine, len(comm.Cmd), comm.Cmd) cli.Execute(rip, comm.Cmd, comm.IsLine, !comm.HideFromHistory, comm.Client) case c := <-cliServer.InputClosed: // inputLoop hit closed connection. it's finished. // we should discard pending output (if any). log.Printf("%s main: inputLoop hit closed connection", rip.daemonName) c.DiscardOutputQueue() } } }
func TestCmdInstall(t *testing.T) { hardware := fwd.NewDataplaneBogus() listInterfaces := func() ([]string, []string) { ifaces, vrfs, err := hardware.Interfaces() if err != nil { t.Errorf("hardware.Interfaces(): error: %v", err) } return ifaces, vrfs } listCommitId := func() []string { return []string{"BOGUS:TestCmdInstall:listCommitId"} } LoadKeywordTable(listInterfaces, listCommitId) cmdNone := CMD_NONE cmdConf := CMD_CONF root := &CmdNode{Path: "", MinLevel: EXEC, Handler: nil} cmdBogus := func(ctx ConfContext, node *CmdNode, line string, c CmdClient) { } if _, err := cmdAdd(root, cmdNone, "configure", ENAB, cmdBogus, nil, "Enter configuration mode"); err != nil { t.Errorf("error: %v", err) } if _, err := cmdAdd(root, cmdNone, "enable", EXEC, cmdBogus, nil, "Enter privileged mode"); err != nil { t.Errorf("error: %v", err) } descUnreach := "interface {IFNAME} description {ANY} unreachable" if _, err := cmdAdd(root, cmdConf, descUnreach, CONF, cmdBogus, ApplyBogus, "Interface description"); err == nil { t.Errorf("error: silently installed unreachable command location: [%s]", descUnreach) } if _, err := cmdAdd(root, cmdConf, "interface {IFNAME} ipv4 address {IFADDR}", CONF, cmdBogus, ApplyBogus, "Assign IPv4 address to interface"); err != nil { t.Errorf("error: %v", err) } if _, err := cmdAdd(root, cmdConf, "interface {IFNAME} ipv6 address {IFADDR6}", CONF, cmdBogus, ApplyBogus, "Assign IPv6 address to interface"); err != nil { t.Errorf("error: %v", err) } c := "interface {IFNAME} ip address {IFADDR}" if _, err := cmdAdd(root, cmdConf, c, CONF, cmdBogus, ApplyBogus, "Assign address to interface"); err == nil { t.Errorf("error: silently installed ambiguous command location: [%s]", c) } if _, err := cmdAdd(root, cmdConf, "ip routing", CONF, cmdBogus, ApplyBogus, "Enable IP routing"); err != nil { t.Errorf("error: %v", err) } if _, err := cmdAdd(root, cmdConf, "hostname HOSTNAME", CONF, cmdBogus, ApplyBogus, "Assign hostname"); err != nil { t.Errorf("error: %v", err) } if _, err := cmdAdd(root, cmdNone, "list", EXEC, cmdBogus, nil, "List command tree"); err != nil { t.Errorf("error: %v", err) } if _, err := cmdAdd(root, cmdNone, "quit", EXEC, cmdBogus, nil, "Quit session"); err != nil { t.Errorf("error: %v", err) } if _, err := cmdAdd(root, cmdNone, "reload", ENAB, cmdBogus, nil, "Reload"); err != nil { t.Errorf("error: %v", err) } if _, err := cmdAdd(root, cmdNone, "reload", ENAB, cmdBogus, nil, "Ugh"); err == nil { t.Errorf("error: silently reinstalled 'reload' command") } if _, err := cmdAdd(root, cmdNone, "rollback", CONF, cmdBogus, nil, "Reset candidate configuration from active configuration"); err != nil { t.Errorf("error: %v", err) } if _, err := cmdAdd(root, cmdNone, "rollback {ID}", CONF, cmdBogus, nil, "Reset candidate configuration from rollback configuration"); err != nil { t.Errorf("error: %v", err) } if _, err := cmdAdd(root, cmdNone, "show interface", EXEC, cmdBogus, nil, "Show interfaces"); err != nil { t.Errorf("error: %v", err) } if _, err := cmdAdd(root, cmdNone, "show", EXEC, cmdBogus, nil, "Ugh"); err == nil { t.Errorf("error: silently reinstalled 'show' command") } if _, err := cmdAdd(root, cmdNone, "show configuration", EXEC, cmdBogus, nil, "Show candidate configuration"); err != nil { t.Errorf("error: %v", err) } if _, err := cmdAdd(root, cmdNone, "show ip address", EXEC, cmdBogus, nil, "Show addresses"); err != nil { t.Errorf("error: %v", err) } if _, err := cmdAdd(root, cmdNone, "show ip interface", EXEC, cmdBogus, nil, "Show interfaces"); err != nil { t.Errorf("error: %v", err) } if _, err := cmdAdd(root, cmdNone, "show ip interface detail", EXEC, cmdBogus, nil, "Show interface detail"); err != nil { t.Errorf("error: %v", err) } if _, err := cmdAdd(root, cmdNone, "show ip route", EXEC, cmdBogus, nil, "Show routing table"); err != nil { t.Errorf("error: %v", err) } if _, err := cmdAdd(root, cmdNone, "show running-configuration", EXEC, cmdBogus, nil, "Show active configuration"); err != nil { t.Errorf("error: %v", err) } if _, err := cmdAdd(root, cmdNone, "show version", EXEC, cmdBogus, nil, "Show version"); err != nil { t.Errorf("error: %v", err) } }
func TestConf(t *testing.T) { app := &testApp{ cmdRoot: &command.CmdNode{MinLevel: command.EXEC}, confRootCandidate: &command.ConfNode{}, confRootActive: &command.ConfNode{}, } hardware := fwd.NewDataplaneBogus() listInterfaces := func() ([]string, []string) { ifaces, vrfs, err := hardware.Interfaces() if err != nil { t.Errorf("hardware.Interfaces(): error: %v", err) } return ifaces, vrfs } listCommitId := func() []string { return []string{"BOGUS:TestConf:listCommitId"} } command.LoadKeywordTable(listInterfaces, listCommitId) root := app.cmdRoot cmdNone := command.CMD_NONE cmdConf := command.CMD_CONF cmdBogus := func(ctx command.ConfContext, node *command.CmdNode, line string, c command.CmdClient) { } command.CmdInstall(root, cmdConf, "interface {IFNAME} description {ANY}", command.CONF, command.HelperIfaceDescr, command.ApplyBogus, "Set interface description") command.CmdInstall(root, cmdConf, "interface {IFNAME} ipv4 address {IFADDR}", command.CONF, command.HelperIfaceAddr, command.ApplyBogus, "Assign IPv4 address to interface") command.CmdInstall(root, cmdConf, "interface {IFNAME} ipv6 address {IFADDR6}", command.CONF, cmdBogus, command.ApplyBogus, "Assign IPv6 address to interface") command.CmdInstall(root, cmdConf, "interface {IFNAME} shutdown", command.CONF, cmdBogus, command.ApplyBogus, "Disable interface") command.CmdInstall(root, cmdConf, "ip routing", command.CONF, cmdBogus, command.ApplyBogus, "Enable IP routing") command.CmdInstall(root, cmdConf, "hostname (HOSTNAME)", command.CONF, command.HelperHostname, command.ApplyBogus, "Assign hostname") command.CmdInstall(root, cmdNone, "no {ANY}", command.CONF, command.HelperNo, nil, "Remove a configuration item") c := &testClient{outputChannel: make(chan string)} close(c.outputChannel) // closed channel will break writers if err := command.Dispatch(app, "", c, command.CONF, false); err != nil { t.Errorf("empty command rejected: %v", err) } if err := command.Dispatch(app, " ", c, command.CONF, false); err != nil { t.Errorf("blank command rejected: %v", err) } if err := command.Dispatch(app, " !xxx ", c, command.CONF, false); err != nil { t.Errorf("comment command ! rejected: %v", err) } if err := command.Dispatch(app, " #xxx ", c, command.CONF, false); err != nil { t.Errorf("comment command # rejected: %v", err) } if err := command.Dispatch(app, "xxxxxx", c, command.CONF, false); err == nil { t.Errorf("bad command accepted") } command.Dispatch(app, "hostname nexthop-router", c, command.CONF, false) if host := getHostname(app.ConfRootCandidate()); host != "nexthop-router" { t.Errorf("bad hostname: %s", host) } command.Dispatch(app, "int eth0 desc aa bb ccc", c, command.CONF, false) node, err := app.confRootCandidate.Get("interface eth0 description") if err != nil || node == nil { t.Errorf("bad description: %v", err) return } if node.Path != "interface eth0 description" { t.Errorf("bad description path: [%s]", node.Path) } if len(node.Children) != 1 { t.Errorf("bad description value count: %d", len(node.Children)) } if v := command.DescriptionDecode(command.LastToken(node.Children[0].Path)); v != " aa bb ccc" { t.Errorf("bad description value: [%s]", v) } command.Dispatch(app, "no int eth0 desc xxxxxxx", c, command.CONF, false) node, err = app.confRootCandidate.Get("interface eth0 description") if node != nil || err == nil { t.Errorf("eth0 description should not be present: node=[%v] error=[%v]", node, err) } command.Dispatch(app, "int eth1 desc ddd eee fff ", c, command.CONF, false) node, err = app.confRootCandidate.Get("interface eth1 description") if err != nil { t.Errorf("bad description: %v", err) } if node.Path != "interface eth1 description" { t.Errorf("bad description path: [%s]", node.Path) } if len(node.Children) != 1 { t.Errorf("bad description value count: %d", len(node.Children)) } if v := command.DescriptionDecode(command.LastToken(node.Children[0].Path)); v != "ddd eee fff " { t.Errorf("bad description value: [%s]", v) } command.Dispatch(app, "no int eth1 desc", c, command.CONF, false) node, err = app.confRootCandidate.Get("interface eth1 description") if node != nil || err == nil { t.Errorf("eth1 description should not be present: node=[%v] error=[%v]", node, err) } command.Dispatch(app, "int eth2 ipv4 addr 1.1.1.1/1", c, command.CONF, false) node, err = app.confRootCandidate.Get("interface eth2 ipv4 address") if err != nil { t.Errorf("bad eth2 address 1: %v", err) return } if len(node.Children) != 1 { t.Errorf("wrong number of eth2 addresses (expected=1): %d", len(node.Children)) } command.Dispatch(app, "int eth2 ipv4 addr 2.2.2.2/2", c, command.CONF, false) if err != nil { t.Errorf("bad eth2 address 2: %v", err) return } if len(node.Children) != 2 { t.Errorf("wrong number of eth2 addresses (expected=2): %d", len(node.Children)) } command.Dispatch(app, "int eth2 ipv4 addr 3.3.3.3/3", c, command.CONF, false) node, err = app.confRootCandidate.Get("interface eth2 ipv4 address") if err != nil { t.Errorf("bad eth2 address 3: %v", err) return } if len(node.Children) != 3 { t.Errorf("wrong number of eth2 addresses (expected=3): %d", len(node.Children)) } command.Dispatch(app, "no int eth2 ipv4 addr 3.3.3.3/3", c, command.CONF, false) if len(node.Children) != 2 { t.Errorf("wrong number of eth2 addresses (expected=2): %d", len(node.Children)) } command.Dispatch(app, "no int eth2 ipv4 addr", c, command.CONF, false) node, err = app.confRootCandidate.Get("interface eth2 ipv4 address") if node != nil || err == nil { t.Errorf("eth2 should not have address: node=[%v] error=[%v]", node, err) } command.Dispatch(app, "int eth3 ipv4 addr 1.1.1.1/1", c, command.CONF, false) command.Dispatch(app, "int eth3 ipv4 addr 2.2.2.2/2", c, command.CONF, false) command.Dispatch(app, "int eth3 ipv4 addr 3.3.3.3/3", c, command.CONF, false) command.Dispatch(app, "int eth3 ipv4 addr 4.4.4.4/4", c, command.CONF, false) node, err = app.confRootCandidate.Get("interface eth3 ipv4 address") if err != nil { t.Errorf("bad eth3 address: %v", err) return } if len(node.Children) != 4 { t.Errorf("wrong number of eth3 addresses (expected=4): %d", len(node.Children)) } node, err = app.confRootCandidate.Get("interface eth3 ipv4") if err != nil { t.Errorf("eth3 should have ipv4: node=[%v] error=[%v]", node, err) } command.Dispatch(app, "no int eth3 ipv4", c, command.CONF, false) node, err = app.confRootCandidate.Get("interface eth3") if node != nil || err == nil { t.Errorf("eth3 should not exist: node=[%v] error=[%v]", node, err) } command.Dispatch(app, "int eth4 ipv4 addr 1.1.1.1/1", c, command.CONF, false) command.Dispatch(app, "int eth4 desc abc", c, command.CONF, false) node, err = app.confRootCandidate.Get("interface eth4 ipv4 address") if err != nil { t.Errorf("bad eth4 address: %v", err) return } if len(node.Children) != 1 { t.Errorf("wrong number of eth4 addresses (expected=1): %d", len(node.Children)) } node, err = app.confRootCandidate.Get("interface eth4 description") if err != nil { t.Errorf("bad eth4 description: %v", err) return } command.Dispatch(app, "no int eth4 ipv4 addr", c, command.CONF, false) node, err = app.confRootCandidate.Get("interface eth4 ipv4") if node != nil || err == nil { t.Errorf("eth4 should not have ipv4: node=[%v] error=[%v]", node, err) return } node, err = app.confRootCandidate.Get("interface eth4") if node == nil || err != nil { t.Errorf("eth4 should exist: node=[%v] error=[%v]", node, err) return } f := func() { command.Dispatch(app, "interface eth5 ipv4 address 1.1.1.1/24", c, command.CONF, false) } noCmd, err := command.CmdFind(root, "no X", command.CONF, true) if err != nil { t.Errorf("could not find 'no' command: %v", err) } f() cmd := "no interface eth5 ipv4 address 1.1.1.1/24" if err := command.CmdNo(app, noCmd, cmd, c); err != nil { t.Errorf("cmd failed: [%s] error=[%v]", cmd, err) } f() cmd = "no interface eth5 ipv4 address" if err := command.CmdNo(app, noCmd, cmd, c); err != nil { t.Errorf("cmd failed: [%s] error=[%v]", cmd, err) } f() cmd = "no interface eth5 ipv4" if err := command.CmdNo(app, noCmd, cmd, c); err != nil { t.Errorf("cmd failed: [%s] error=[%v]", cmd, err) } f() cmd = "no interface eth5" if err := command.CmdNo(app, noCmd, cmd, c); err != nil { t.Errorf("cmd failed: [%s] error=[%v]", cmd, err) } f() cmd = "no interface" if err := command.CmdNo(app, noCmd, cmd, c); err != nil { t.Errorf("cmd failed: [%s] error=[%v]", cmd, err) } f() cmd = "no" if err := command.CmdNo(app, noCmd, cmd, c); err == nil { t.Errorf("bad cmd silently accepted: [%s]", cmd) } }
func TestPrune(t *testing.T) { app := &testApp{ cmdRoot: &command.CmdNode{MinLevel: command.EXEC}, confRootCandidate: &command.ConfNode{}, confRootActive: &command.ConfNode{}, } hardware := fwd.NewDataplaneBogus() listInterfaces := func() ([]string, []string) { ifaces, vrfs, err := hardware.Interfaces() if err != nil { t.Errorf("hardware.Interfaces(): error: %v", err) } return ifaces, vrfs } listCommitId := func() []string { return []string{"BOGUS:TestPrune:listCommitId"} } command.LoadKeywordTable(listInterfaces, listCommitId) root := app.cmdRoot cmdNone := command.CMD_NONE cmdConf := command.CMD_CONF /* cmdBogus := func(ctx command.ConfContext, node *command.CmdNode, line string, c command.CmdClient) { } */ cmdSimpleSet := func(ctx command.ConfContext, node *command.CmdNode, line string, c command.CmdClient) { ctx.ConfRootCandidate().Set(node.Path, line) } path := "a b c d e f g h i j" jPath := "b c d e f g h i j" hPath := "b c d e f g h" gPath := "b c d e f g" fPath := "b c d e f" command.CmdInstall(root, cmdConf, path, command.CONF, cmdSimpleSet, command.ApplyBogus, "Teste prune A") command.CmdInstall(root, cmdConf, fPath, command.CONF, cmdSimpleSet, command.ApplyBogus, "Teste prune F") command.CmdInstall(root, cmdConf, jPath, command.CONF, cmdSimpleSet, command.ApplyBogus, "Teste prune J") command.CmdInstall(root, cmdNone, "no {ANY}", command.CONF, command.HelperNo, nil, "Remove a configuration item") c := &testClient{outputChannel: make(chan string)} close(c.outputChannel) // closed channel will break writers noCmd, err := command.CmdFind(root, "no X", command.CONF, true) if noCmd == nil || err != nil { t.Errorf("could not find 'no' command: %v", err) return } command.Dispatch(app, path, c, command.CONF, false) { node, err := app.confRootCandidate.Get(path) if node == nil || err != nil { t.Errorf("missing config node=[%s] error: %v", path, err) return } if node.Path != path { t.Errorf("config node mismatch want=[%s] got=[%s]", path, node.Path) return } } noPath := fmt.Sprintf("no %s", path) if err := command.CmdNo(app, noCmd, noPath, c); err != nil { t.Errorf("cmd failed: [%s] error=[%v]", noPath, err) return } { node, err := app.confRootCandidate.Get(path) if node != nil || err == nil { t.Errorf("unexpected config node=[%s] error: %v", path, err) return } } { p := "a" node, err := app.confRootCandidate.Get(p) if node != nil || err == nil { t.Errorf("unexpected config node=[%s] error: %v", p, err) return } } command.Dispatch(app, jPath, c, command.CONF, false) { node, err := app.confRootCandidate.Get(jPath) if node == nil || err != nil { t.Errorf("missing config node=[%s] error: %v", jPath, err) return } if node.Path != jPath { t.Errorf("config node mismatch want=[%s] got=[%s]", jPath, node.Path) return } } noH := fmt.Sprintf("no %s", hPath) if err := command.CmdNo(app, noCmd, noH, c); err != nil { t.Errorf("cmd failed: [%s] error=[%v]", noH, err) return } { node, err := app.confRootCandidate.Get(hPath) if node != nil || err == nil { t.Errorf("unexpected config node=[%s] error: %v", hPath, err) return } } { node, err := app.confRootCandidate.Get(gPath) if node != nil || err == nil { t.Errorf("unexpected config node=[%s] error: %v", gPath, err) return } } { node, err := app.confRootCandidate.Get(fPath) if node == nil || err != nil { t.Errorf("missing config node=[%s] error: %v", fPath, err) return } if node.Path != fPath { t.Errorf("config node mismatch want=[%s] got=[%s]", fPath, node.Path) return } } }
func TestConf(t *testing.T) { app := &ripTestApp{ cmdRoot: &command.CmdNode{MinLevel: command.EXEC}, confRootCandidate: &command.ConfNode{}, confRootActive: &command.ConfNode{}, } hardware := fwd.NewDataplaneBogus() listInterfaces := func() ([]string, []string) { ifaces, vrfs, err := hardware.Interfaces() if err != nil { t.Errorf("hardware.Interfaces(): error: %v", err) } return ifaces, vrfs } listCommitId := func() []string { return []string{"BOGUS:rip.TestConf:listCommitId"} } command.LoadKeywordTable(listInterfaces, listCommitId) root := app.cmdRoot cmdNone := command.CMD_NONE cmdConf := command.CMD_CONF command.CmdInstall(root, cmdConf, "router rip", command.CONF, cmdRip, applyRip, "Enable RIP protocol") command.CmdInstall(root, cmdConf, "router rip network {NETWORK}", command.CONF, cmdRipNetwork, applyRipNet, "Insert network into RIP protocol") command.CmdInstall(root, cmdNone, "no {ANY}", command.CONF, command.HelperNo, nil, "Remove a configuration item") c := NewRipTestClient(func(string) {}) r := "router rip" net := fmt.Sprintf("%s network", r) n1 := "1.1.1.0/24" n2 := "2.2.2.0/24" net1 := fmt.Sprintf("%s %s", net, n1) net2 := fmt.Sprintf("%s %s", net, n2) command.Dispatch(app, net1, c, command.CONF, false) command.Dispatch(app, net2, c, command.CONF, false) { node, err := app.confRootCandidate.Get(net) if node == nil || err != nil { t.Errorf("missing config node=[%s] error: %v", net, err) return } if node.Path != net { t.Errorf("config node mismatch want=[%s] got=[%s]", net, node.Path) } if len(node.Children) != 2 { t.Errorf("bad number of values want=2 got=%d", len(node.Children)) } if v := command.LastToken(node.Children[0].Path); v != n1 { t.Errorf("unexpected 1st network want=%s got=%s", n1, v) } if v := command.LastToken(node.Children[1].Path); v != n2 { t.Errorf("unexpected 2nd network want=%s got=%s", n2, v) } } nonet1 := fmt.Sprintf("no %s", net1) nonet2 := fmt.Sprintf("no %s", net2) /* noCmd, err := command.CmdFind(root, "no X", command.CONF, true) if err != nil { t.Errorf("could not find 'no' command: %v", err) return } */ dumpConf(app.confRootCandidate, "conf1:") fmt.Printf("trying: [%s]\n", nonet1) if err := command.CmdNo(app, nil, nonet1, c); err != nil { t.Errorf("cmd failed: [%s] error=[%v]", nonet1, err) return } dumpConf(app.confRootCandidate, "conf2:") fmt.Printf("trying: [%s]\n", nonet2) if err := command.CmdNo(app, nil, nonet2, c); err != nil { t.Errorf("cmd failed: [%s] error=[%v]", nonet2, err) return } dumpConf(app.confRootCandidate, "conf3:") { node, err := app.confRootCandidate.Get(net) if node != nil || err == nil { t.Errorf("unexpected config node=[%s] error: %v", net, err) } } { node, err := app.confRootCandidate.Get(r) if node == nil || err != nil { t.Errorf("missing config node=[%s] error: %v", r, err) } } }