Added suggestions from @SwampDragons to the parsers from the vmware builders, included unit-tests and sample file for fusion's networking file, and fixed a few situations where the channel wasn't being closed.
This commit is contained in:
parent
0609909f1a
commit
898321bcfe
|
@ -704,6 +704,7 @@ func parseParameter(val tkParameter) (pParameter, error) {
|
|||
}
|
||||
|
||||
address := net.ParseIP(cidr[0])
|
||||
|
||||
bits, err := strconv.Atoi(cidr[1])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -1038,10 +1039,12 @@ func (e *configDeclaration) IP4() (net.IP, error) {
|
|||
return nil, fmt.Errorf("No IP4 addresses found")
|
||||
}
|
||||
|
||||
// Try and parse it as an IP4. If so, then it's good to return it as-is.
|
||||
if res := net.ParseIP(result[0]); res != nil {
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// Otherwise make an attempt to resolve it to an address.
|
||||
res, err := net.ResolveIPAddr("ip4", result[0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -1069,10 +1072,12 @@ func (e *configDeclaration) IP6() (net.IP, error) {
|
|||
return nil, fmt.Errorf("No IP6 addresses found")
|
||||
}
|
||||
|
||||
// If we were able to parse it into an IP, then we can just return it.
|
||||
if res := net.ParseIP(result[0]); res != nil {
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// Otherwise, try to resolve it into an address.
|
||||
res, err := net.ResolveIPAddr("ip6", result[0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -1277,8 +1282,6 @@ func tokenizeNetworkingConfig(in chan byte) chan string {
|
|||
}
|
||||
|
||||
switch by {
|
||||
case '\r':
|
||||
fallthrough
|
||||
case '\t':
|
||||
fallthrough
|
||||
case ' ':
|
||||
|
@ -1290,16 +1293,20 @@ func tokenizeNetworkingConfig(in chan byte) chan string {
|
|||
out <- state
|
||||
state = ""
|
||||
|
||||
case '\r':
|
||||
// If windows has tampered with our newlines, then we normalize
|
||||
// things by converting its value from 0x0d to 0x0a.
|
||||
fallthrough
|
||||
case '\n':
|
||||
// Newlines can repeat, so this case is responsible for writing
|
||||
// to the chan, and consolidating multiple newlines into singles.
|
||||
// to the chan, and consolidating multiple newlines into a single.
|
||||
if repeat_newline {
|
||||
continue
|
||||
}
|
||||
if len(state) > 0 {
|
||||
out <- state
|
||||
}
|
||||
out <- string(by)
|
||||
out <- "\n"
|
||||
state = ""
|
||||
repeat_newline = true
|
||||
continue
|
||||
|
@ -1317,6 +1324,7 @@ func tokenizeNetworkingConfig(in chan byte) chan string {
|
|||
if len(state) > 0 {
|
||||
out <- state
|
||||
}
|
||||
close(out)
|
||||
}(out)
|
||||
return out
|
||||
}
|
||||
|
@ -1355,6 +1363,7 @@ func splitNetworkingConfig(in chan string) chan []string {
|
|||
if len(row) > 0 {
|
||||
out <- row
|
||||
}
|
||||
close(out)
|
||||
}(out)
|
||||
return out
|
||||
}
|
||||
|
@ -1698,7 +1707,7 @@ func parseNetworkingCommand_add_dhcp_mac_to_ip(row []string) (*networkingCommand
|
|||
}
|
||||
|
||||
ip := net.ParseIP(row[2])
|
||||
if ip != nil {
|
||||
if ip == nil {
|
||||
return nil, fmt.Errorf("Unable to parse third argument as ipv4. : %v", row[2])
|
||||
}
|
||||
|
||||
|
@ -1850,6 +1859,7 @@ func parseNetworkingConfig(rows chan []string) chan networkingCommandEntry {
|
|||
out <- *entry
|
||||
}
|
||||
}
|
||||
close(out)
|
||||
}(rows, out)
|
||||
return out
|
||||
}
|
||||
|
@ -2197,7 +2207,7 @@ This consumes bytes within a pair of some bytes, like parentheses, brackets, bra
|
|||
|
||||
We start by reading bytes until we encounter openByte. These will be returned as
|
||||
the first parameter. Then we can enter a goro and consume bytes until we get to
|
||||
closeByte. At that point we're done, and suicide.
|
||||
closeByte. At that point we're done, and we can exit.
|
||||
**/
|
||||
func consumeOpenClosePair(openByte, closeByte byte, in chan byte) ([]byte, chan byte) {
|
||||
result := make([]byte, 0)
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"encoding/hex"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func consumeString(s string) (out chan byte) {
|
||||
|
@ -20,6 +21,13 @@ func consumeString(s string) (out chan byte) {
|
|||
return
|
||||
}
|
||||
|
||||
func collectIntoStringList(in chan string) (result []string) {
|
||||
for item := range in {
|
||||
result = append(result, item)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func uncommentFromString(s string) string {
|
||||
inCh := consumeString(s)
|
||||
out := uncomment(inCh)
|
||||
|
@ -856,3 +864,223 @@ func TestParserReadDhcpdLeases(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestParserTokenizeNetworkingConfig(t *testing.T) {
|
||||
tests := []string{
|
||||
"words words words",
|
||||
"newlines\n\n\n\n\n\n\n\nnewlines\r\r\r\r\r\r\r\rnewlines\n\n\n\n",
|
||||
" newline-less",
|
||||
}
|
||||
expects := [][]string{
|
||||
[]string{"words", "words", "words"},
|
||||
[]string{"newlines", "\n", "newlines", "\n", "newlines", "\n"},
|
||||
[]string{"newline-less"},
|
||||
}
|
||||
|
||||
for testnum := 0; testnum < len(tests); testnum += 1 {
|
||||
inCh := consumeString(tests[testnum])
|
||||
outCh := tokenizeNetworkingConfig(inCh)
|
||||
result := collectIntoStringList(outCh)
|
||||
|
||||
expected := expects[testnum]
|
||||
if len(result) != len(expected) {
|
||||
t.Errorf("test %d expected %d items, got %d instead", 1+testnum, len(expected), len(result))
|
||||
continue
|
||||
}
|
||||
|
||||
ok := true
|
||||
for index := 0; index < len(expected); index += 1 {
|
||||
if result[index] != expected[index] {
|
||||
ok = false
|
||||
}
|
||||
}
|
||||
if !ok {
|
||||
t.Errorf("test %d expected %#v, got %#v", 1+testnum, expects[testnum], result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestParserSplitNetworkingConfig(t *testing.T) {
|
||||
tests := []string{
|
||||
"this is a story\n\n\nabout some newlines",
|
||||
"\n\n\nthat can begin and end with newlines\n\n\n",
|
||||
" in\n\n\nsome\ncases\nit\ncan\nend\nwith\nan\nempty\nstring\n\n\n\n",
|
||||
"\n\n\nand\nbegin\nwith\nan\nempty\nstring ",
|
||||
}
|
||||
expects := [][]string{
|
||||
[]string{"this is a story", "about some newlines"},
|
||||
[]string{"that can begin and end with newlines"},
|
||||
[]string{"in", "some", "cases", "it", "can", "end", "with", "an", "empty", "string"},
|
||||
[]string{"and", "begin", "with", "an", "empty", "string"},
|
||||
}
|
||||
|
||||
for testnum := 0; testnum < len(tests); testnum += 1 {
|
||||
inCh := consumeString(tests[testnum])
|
||||
stringCh := tokenizeNetworkingConfig(inCh)
|
||||
outCh := splitNetworkingConfig(stringCh)
|
||||
|
||||
result := make([]string, 0)
|
||||
for item := range outCh {
|
||||
result = append(result, strings.Join(item, " "))
|
||||
}
|
||||
|
||||
expected := expects[testnum]
|
||||
if len(result) != len(expected) {
|
||||
t.Errorf("test %d expected %d items, got %d instead", 1+testnum, len(expected), len(result))
|
||||
continue
|
||||
}
|
||||
|
||||
ok := true
|
||||
for index := 0; index < len(expected); index += 1 {
|
||||
if result[index] != expected[index] {
|
||||
ok = false
|
||||
}
|
||||
}
|
||||
if !ok {
|
||||
t.Errorf("test %d expected %#v, got %#v", 1+testnum, expects[testnum], result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestParserParseNetworkingConfigVersion(t *testing.T) {
|
||||
success_tests := []string{"VERSION=4,2"}
|
||||
failure_tests := []string{
|
||||
"VERSION=1=2",
|
||||
"VERSION=3,4,5",
|
||||
"VERSION=a,b",
|
||||
}
|
||||
|
||||
for testnum := 0; testnum < len(success_tests); testnum += 1 {
|
||||
test := []string{success_tests[testnum]}
|
||||
if _, err := networkingReadVersion(test); err != nil {
|
||||
t.Errorf("success-test %d parsing failed: %v", 1+testnum, err)
|
||||
}
|
||||
}
|
||||
|
||||
for testnum := 0; testnum < len(success_tests); testnum += 1 {
|
||||
test := []string{failure_tests[testnum]}
|
||||
if _, err := networkingReadVersion(test); err == nil {
|
||||
t.Errorf("failure-test %d should have failed", 1+testnum)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestParserParseNetworkingConfigEntries(t *testing.T) {
|
||||
tests := []string{
|
||||
"answer VNET_999_ANYTHING option",
|
||||
"remove_answer VNET_123_ALSOANYTHING",
|
||||
"add_nat_portfwd 24 udp 42 127.0.0.1 24",
|
||||
"remove_nat_portfwd 42 tcp 2502",
|
||||
"add_dhcp_mac_to_ip 57005 00:0d:0e:0a:0d:00 127.0.0.2",
|
||||
"remove_dhcp_mac_to_ip 57005 00:0d:0e:0a:0d:00",
|
||||
"add_bridge_mapping string 51",
|
||||
"remove_bridge_mapping string",
|
||||
"add_nat_prefix 57005 /24",
|
||||
"remove_nat_prefix 57005 /31",
|
||||
}
|
||||
|
||||
for testnum := 0; testnum < len(tests); testnum += 1 {
|
||||
test := strings.Split(tests[testnum], " ")
|
||||
parser := NetworkingParserByCommand(test[0])
|
||||
if parser == nil {
|
||||
t.Errorf("test %d unable to parse command: %#v", 1+testnum, test)
|
||||
continue
|
||||
}
|
||||
operand_parser := *parser
|
||||
|
||||
_, err := operand_parser(test[1:])
|
||||
if err != nil {
|
||||
t.Errorf("test %d unable to parse command parameters %#v: %v", 1+testnum, test, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestParserReadNetworingConfig(t *testing.T) {
|
||||
expected_answer_vnet_1 := map[string]string{
|
||||
"DHCP": "yes",
|
||||
"DHCP_CFG_HASH": "01F4CE0D79A1599698B6E5814CCB68058BB0ED5E",
|
||||
"HOSTONLY_NETMASK": "255.255.255.0",
|
||||
"HOSTONLY_SUBNET": "192.168.70.0",
|
||||
"NAT": "no",
|
||||
"VIRTUAL_ADAPTER": "yes",
|
||||
}
|
||||
|
||||
f, err := os.Open(filepath.Join("testdata", "networking-example"))
|
||||
if err != nil {
|
||||
t.Fatalf("Unable to open networking-example sample: %v", err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
config, err := ReadNetworkingConfig(f)
|
||||
if err != nil {
|
||||
t.Fatalf("error parsing networking-example: %v", err)
|
||||
}
|
||||
|
||||
if vnet, ok := config.answer[1]; ok {
|
||||
for ans_key := range expected_answer_vnet_1 {
|
||||
result, ok := vnet[ans_key]
|
||||
if !ok {
|
||||
t.Errorf("unable to find key %s in VNET_%d answer", ans_key, 1)
|
||||
continue
|
||||
}
|
||||
|
||||
if result != expected_answer_vnet_1[ans_key] {
|
||||
t.Errorf("expected key %s for VNET_%d to be %v, got %v", ans_key, 1, expected_answer_vnet_1[ans_key], result)
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
t.Errorf("unable to find VNET_%d answer", 1)
|
||||
}
|
||||
|
||||
expected_answer_vnet_8 := map[string]string{
|
||||
"DHCP": "yes",
|
||||
"DHCP_CFG_HASH": "C30F14F65A0FE4B5DCC6C67497D7A8A33E5E538C",
|
||||
"HOSTONLY_NETMASK": "255.255.255.0",
|
||||
"HOSTONLY_SUBNET": "172.16.41.0",
|
||||
"NAT": "yes",
|
||||
"VIRTUAL_ADAPTER": "yes",
|
||||
}
|
||||
|
||||
if vnet, ok := config.answer[8]; ok {
|
||||
for ans_key := range expected_answer_vnet_8 {
|
||||
result, ok := vnet[ans_key]
|
||||
if !ok {
|
||||
t.Errorf("unable to find key %s in VNET_%d answer", ans_key, 8)
|
||||
continue
|
||||
}
|
||||
|
||||
if result != expected_answer_vnet_8[ans_key] {
|
||||
t.Errorf("expected key %s for VNET_%d to be %v, got %v", ans_key, 8, expected_answer_vnet_8[ans_key], result)
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
t.Errorf("unable to find VNET_%d answer", 8)
|
||||
}
|
||||
|
||||
expected_nat_portfwd_8 := map[string]string{
|
||||
"tcp/2200": "172.16.41.129:3389",
|
||||
"tcp/2201": "172.16.41.129:3389",
|
||||
"tcp/2222": "172.16.41.129:22",
|
||||
"tcp/3389": "172.16.41.131:3389",
|
||||
"tcp/55985": "172.16.41.129:5985",
|
||||
"tcp/55986": "172.16.41.129:5986",
|
||||
}
|
||||
|
||||
if vnet, ok := config.nat_portfwd[8-1]; ok {
|
||||
for nat_key := range expected_nat_portfwd_8 {
|
||||
result, ok := vnet[nat_key]
|
||||
if !ok {
|
||||
t.Errorf("unable to find key %s in VNET_%d nat_portfwd", nat_key, 8)
|
||||
continue
|
||||
}
|
||||
|
||||
if result != expected_nat_portfwd_8[nat_key] {
|
||||
t.Errorf("expected key %s for VNET_%d to be %v, got %v", nat_key, 8, expected_nat_portfwd_8[nat_key], result)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
t.Errorf("unable to find VNET_%d answer", 8-1)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
VERSION=1,0
|
||||
answer VNET_1_DHCP yes
|
||||
answer VNET_1_DHCP_CFG_HASH 01F4CE0D79A1599698B6E5814CCB68058BB0ED5E
|
||||
answer VNET_1_HOSTONLY_NETMASK 255.255.255.0
|
||||
answer VNET_1_HOSTONLY_SUBNET 192.168.70.0
|
||||
answer VNET_1_NAT no
|
||||
answer VNET_1_VIRTUAL_ADAPTER yes
|
||||
answer VNET_8_DHCP yes
|
||||
answer VNET_8_DHCP_CFG_HASH C30F14F65A0FE4B5DCC6C67497D7A8A33E5E538C
|
||||
answer VNET_8_HOSTONLY_NETMASK 255.255.255.0
|
||||
answer VNET_8_HOSTONLY_SUBNET 172.16.41.0
|
||||
answer VNET_8_NAT yes
|
||||
answer VNET_8_VIRTUAL_ADAPTER yes
|
||||
add_nat_portfwd 8 tcp 2200 172.16.41.129 3389
|
||||
add_nat_portfwd 8 tcp 2201 172.16.41.129 3389
|
||||
add_nat_portfwd 8 tcp 2222 172.16.41.129 22
|
||||
add_nat_portfwd 8 tcp 3389 172.16.41.131 3389
|
||||
add_nat_portfwd 8 tcp 55985 172.16.41.129 5985
|
||||
add_nat_portfwd 8 tcp 55986 172.16.41.129 5986
|
Loading…
Reference in New Issue