ping added
This commit is contained in:
		
							parent
							
								
									fae2846a85
								
							
						
					
					
						commit
						4b9311adb7
					
				
							
								
								
									
										389
									
								
								net/ping/ping.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										389
									
								
								net/ping/ping.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,389 @@ | ||||
| package ping | ||||
| 
 | ||||
| import ( | ||||
| 	"log" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| ) | ||||
| 
 | ||||
| type PingOptions struct { | ||||
| 	Retry    int | ||||
| 	Interval int | ||||
| 	Deadline int | ||||
| } | ||||
| 
 | ||||
| type Response struct { | ||||
| 	TTL  int | ||||
| 	Time float32 | ||||
| } | ||||
| 
 | ||||
| type Summary struct { | ||||
| 	SendCount    int | ||||
| 	ReceiveCount int | ||||
| 	LossPercent  float32 | ||||
| 	MinTime      float32 | ||||
| 	MaxTime      float32 | ||||
| 	AvgTime      float32 | ||||
| } | ||||
| 
 | ||||
| type PingResult struct { | ||||
| 	Responses map[int]*Response | ||||
| 	Summary   *Summary | ||||
| } | ||||
| 
 | ||||
| func (o *PingOptions) Validate() { | ||||
| 	if 0 >= o.Retry { | ||||
| 		o.Retry = 1 | ||||
| 	} | ||||
| 	if 0 >= o.Interval { | ||||
| 		o.Interval = 1 | ||||
| 	} | ||||
| 	if 0 >= o.Deadline { | ||||
| 		o.Deadline = 0 | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // $ ping 192.168.1.1 -c 7 -i 1 -w 0.3 | ||||
| // PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data. | ||||
| // 64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=0.325 ms | ||||
| // 64 bytes from 192.168.1.1: icmp_seq=2 ttl=64 time=0.344 ms | ||||
| // 64 bytes from 192.168.1.1: icmp_seq=3 ttl=64 time=0.163 ms | ||||
| // 64 bytes from 192.168.1.1: icmp_seq=7 ttl=64 time=0.180 ms | ||||
| 
 | ||||
| // --- 192.168.1.1 ping statistics --- | ||||
| // 7 packets transmitted, 4 received, 42% packet loss, time 6010ms | ||||
| // rtt min/avg/max/mdev = 0.163/0.253/0.344/0.082 ms | ||||
| func parseLinuxPing(output []byte) (*PingResult, error) { | ||||
| 	result := &PingResult{ | ||||
| 		Responses: make(map[int]*Response, 0), | ||||
| 		Summary:   &Summary{}, | ||||
| 	} | ||||
| 	lines := strings.Split(string(output), "\n") | ||||
| 
 | ||||
| LOOP: | ||||
| 	for _, line := range lines { | ||||
| 		log.Print(line) | ||||
| 		fields := strings.Fields(line) | ||||
| 		switch len(fields) { | ||||
| 		case 5: | ||||
| 			if "rtt" != fields[0] { | ||||
| 				continue LOOP | ||||
| 			} | ||||
| 
 | ||||
| 			times := strings.Split(fields[3], "/") | ||||
| 
 | ||||
| 			minTime, err := strconv.ParseFloat(times[0], 32) | ||||
| 			if nil != err { | ||||
| 				log.Print(err) | ||||
| 				continue LOOP | ||||
| 			} | ||||
| 			result.Summary.MinTime = float32(minTime) | ||||
| 
 | ||||
| 			maxTime, err := strconv.ParseFloat(times[2], 32) | ||||
| 			if nil != err { | ||||
| 				log.Print(err) | ||||
| 				continue LOOP | ||||
| 			} | ||||
| 			result.Summary.MaxTime = float32(maxTime) | ||||
| 
 | ||||
| 			avgTime, err := strconv.ParseFloat(times[1], 32) | ||||
| 			if nil != err { | ||||
| 				log.Print(err) | ||||
| 				continue LOOP | ||||
| 			} | ||||
| 			result.Summary.AvgTime = float32(avgTime) | ||||
| 
 | ||||
| 		case 8: | ||||
| 			seqs := strings.Split(fields[4], "=") | ||||
| 			ttls := strings.Split(fields[5], "=") | ||||
| 			times := strings.Split(fields[6], "=") | ||||
| 			seq, err := strconv.Atoi(seqs[1]) | ||||
| 			if nil != err { | ||||
| 				log.Print(err) | ||||
| 				continue LOOP | ||||
| 			} | ||||
| 			ttl, err := strconv.Atoi(ttls[1]) | ||||
| 			if nil != err { | ||||
| 				log.Print(err) | ||||
| 				continue LOOP | ||||
| 			} | ||||
| 			_time, err := strconv.ParseFloat(times[1], 32) | ||||
| 			if nil != err { | ||||
| 				log.Print(err) | ||||
| 				continue LOOP | ||||
| 			} | ||||
| 
 | ||||
| 			result.Responses[seq] = &Response{ | ||||
| 				TTL:  ttl, | ||||
| 				Time: float32(_time), | ||||
| 			} | ||||
| 
 | ||||
| 		case 10: | ||||
| 			sendCount, err := strconv.Atoi(fields[0]) | ||||
| 			if nil != err { | ||||
| 				log.Print(err) | ||||
| 				continue LOOP | ||||
| 			} | ||||
| 			result.Summary.SendCount = sendCount | ||||
| 
 | ||||
| 			receiveCount, err := strconv.Atoi(fields[3]) | ||||
| 			if nil != err { | ||||
| 				log.Print(err) | ||||
| 				continue LOOP | ||||
| 			} | ||||
| 			result.Summary.ReceiveCount = receiveCount | ||||
| 
 | ||||
| 			lossPercent, err := strconv.ParseFloat(strings.Replace(fields[5], "%", "", -1), 32) | ||||
| 			if nil != err { | ||||
| 				log.Print(err) | ||||
| 				continue LOOP | ||||
| 			} | ||||
| 			result.Summary.LossPercent = float32(lossPercent) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return result, nil | ||||
| } | ||||
| 
 | ||||
| // Windows 10 | ||||
| // Active code page: 437 | ||||
| 
 | ||||
| // Pinging 192.168.1.1 with 32 bytes of data: | ||||
| // Reply from 192.168.1.1: bytes=32 time<1ms TTL=64 | ||||
| // Reply from 192.168.1.1: bytes=32 time<1ms TTL=64 | ||||
| // Reply from 192.168.1.1: bytes=32 time<1ms TTL=64 | ||||
| // Reply from 192.168.1.1: bytes=32 time<1ms TTL=64 | ||||
| // Reply from 192.168.1.1: bytes=32 time<1ms TTL=64 | ||||
| 
 | ||||
| // Ping statistics for 192.168.1.1: | ||||
| //     Packets: Sent = 5, Received = 5, Lost = 0 (0% loss), | ||||
| // Approximate round trip times in milli-seconds: | ||||
| //     Minimum = 0ms, Maximum = 0ms, Average = 0ms | ||||
| 
 | ||||
| // Active code page: 437 | ||||
| 
 | ||||
| // Pinging www.google.com [216.58.221.164] with 32 bytes of data: | ||||
| // Reply from 216.58.221.164: bytes=32 time=37ms TTL=51 | ||||
| // Request timed out. | ||||
| // Reply from 216.58.221.164: bytes=32 time=38ms TTL=51 | ||||
| // Reply from 216.58.221.164: bytes=32 time=37ms TTL=51 | ||||
| // Reply from 216.58.221.164: bytes=32 time=37ms TTL=51 | ||||
| 
 | ||||
| // Ping statistics for 216.58.221.164: | ||||
| //     Packets: Sent = 5, Received = 4, Lost = 1 (20% loss), | ||||
| // Approximate round trip times in milli-seconds: | ||||
| //     Minimum = 37ms, Maximum = 38ms, Average = 37ms | ||||
| 
 | ||||
| func parseWindowsPing(output []byte) (*PingResult, error) { | ||||
| 	result := &PingResult{ | ||||
| 		Responses: make(map[int]*Response, 0), | ||||
| 		Summary:   &Summary{}, | ||||
| 	} | ||||
| 	lines := strings.Split(string(output), "\n") | ||||
| 
 | ||||
| 	seq := 1 | ||||
| LOOP: | ||||
| 	for _, line := range lines { | ||||
| 		log.Print(line) | ||||
| 		fields := strings.Fields(line) | ||||
| 		switch len(fields) { | ||||
| 		case 3: | ||||
| 			log.Print(fields) | ||||
| 			if "Request timed out." != line { | ||||
| 				continue LOOP | ||||
| 			} | ||||
| 			result.Responses[seq] = nil | ||||
| 			seq = seq + 1 | ||||
| 		case 6: | ||||
| 			if "Reply" != fields[0] || "from" != fields[1] { | ||||
| 				continue LOOP | ||||
| 			} | ||||
| 			times := strings.Replace(fields[4], "time", "", -1) | ||||
| 			times = strings.Replace(times, "<", "", -1) | ||||
| 			times = strings.Replace(times, "=", "", -1) | ||||
| 			times = strings.Replace(times, "ms", "", -1) | ||||
| 
 | ||||
| 			ttls := strings.Split(fields[5], "=") | ||||
| 
 | ||||
| 			ttl, err := strconv.Atoi(ttls[1]) | ||||
| 			if nil != err { | ||||
| 				log.Print(err) | ||||
| 				continue LOOP | ||||
| 			} | ||||
| 			_time, err := strconv.ParseFloat(times, 32) | ||||
| 			if nil != err { | ||||
| 				log.Print(err) | ||||
| 				continue LOOP | ||||
| 			} | ||||
| 
 | ||||
| 			result.Responses[seq] = &Response{ | ||||
| 				TTL:  ttl, | ||||
| 				Time: float32(_time), | ||||
| 			} | ||||
| 			seq = seq + 1 | ||||
| 		case 9: | ||||
| 			log.Print(fields) | ||||
| 			if "Minimum" != fields[0] { | ||||
| 				continue LOOP | ||||
| 			} | ||||
| 
 | ||||
| 			minTimes := strings.Replace(fields[2], "ms", "", -1) | ||||
| 			minTimes = strings.Replace(minTimes, ",", "", -1) | ||||
| 			minTime, err := strconv.ParseFloat(minTimes, 32) | ||||
| 			if nil != err { | ||||
| 				log.Print(err) | ||||
| 				continue LOOP | ||||
| 			} | ||||
| 			result.Summary.MinTime = float32(minTime) | ||||
| 
 | ||||
| 			maxTimes := strings.Replace(fields[5], "ms", "", -1) | ||||
| 			maxTimes = strings.Replace(maxTimes, ",", "", -1) | ||||
| 			maxTime, err := strconv.ParseFloat(maxTimes, 32) | ||||
| 			if nil != err { | ||||
| 				log.Print(err) | ||||
| 				continue LOOP | ||||
| 			} | ||||
| 			result.Summary.MaxTime = float32(maxTime) | ||||
| 
 | ||||
| 			avgTimes := strings.Replace(fields[8], "ms", "", -1) | ||||
| 			avgTime, err := strconv.ParseFloat(avgTimes, 32) | ||||
| 			if nil != err { | ||||
| 				log.Print(err) | ||||
| 				continue LOOP | ||||
| 			} | ||||
| 			result.Summary.AvgTime = float32(avgTime) | ||||
| 
 | ||||
| 		case 12: | ||||
| 			if "Packets:" != fields[0] { | ||||
| 				continue LOOP | ||||
| 			} | ||||
| 			sendCount, err := strconv.Atoi(strings.Replace(fields[3], ",", "", -1)) | ||||
| 			if nil != err { | ||||
| 				log.Print(err) | ||||
| 				continue LOOP | ||||
| 			} | ||||
| 			result.Summary.SendCount = sendCount | ||||
| 
 | ||||
| 			receiveCount, err := strconv.Atoi(strings.Replace(fields[6], ",", "", -1)) | ||||
| 			if nil != err { | ||||
| 				log.Print(err) | ||||
| 				continue LOOP | ||||
| 			} | ||||
| 			result.Summary.ReceiveCount = receiveCount | ||||
| 
 | ||||
| 			lossPercents := strings.Replace(fields[10], "(", "", -1) | ||||
| 			lossPercents = strings.Replace(lossPercents, "%", "", -1) | ||||
| 			lossPercent, err := strconv.ParseFloat(lossPercents, 32) | ||||
| 			if nil != err { | ||||
| 				log.Print(err) | ||||
| 				continue LOOP | ||||
| 			} | ||||
| 			result.Summary.LossPercent = float32(lossPercent) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return result, nil | ||||
| } | ||||
| 
 | ||||
| // $ ping 192.168.1.1 -c 5 -i 1 | ||||
| // PING 192.168.1.1 (192.168.1.1): 56 data bytes | ||||
| // 64 bytes from 192.168.1.1: icmp_seq=0 ttl=64 time=1.664 ms | ||||
| // 64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=0.971 ms | ||||
| // 64 bytes from 192.168.1.1: icmp_seq=2 ttl=64 time=3.934 ms | ||||
| // 64 bytes from 192.168.1.1: icmp_seq=3 ttl=64 time=3.539 ms | ||||
| // 64 bytes from 192.168.1.1: icmp_seq=4 ttl=64 time=3.690 ms | ||||
| 
 | ||||
| // --- 192.168.1.1 ping statistics --- | ||||
| // 5 packets transmitted, 5 packets received, 0.0% packet loss | ||||
| // round-trip min/avg/max/stddev = 0.971/2.760/3.934/1.204 ms | ||||
| func parseDarwinPing(output []byte) (*PingResult, error) { | ||||
| 	result := &PingResult{ | ||||
| 		Responses: make(map[int]*Response, 0), | ||||
| 		Summary:   &Summary{}, | ||||
| 	} | ||||
| 	lines := strings.Split(string(output), "\n") | ||||
| 
 | ||||
| LOOP: | ||||
| 	for _, line := range lines { | ||||
| 		log.Print(line) | ||||
| 		fields := strings.Fields(line) | ||||
| 		switch len(fields) { | ||||
| 		case 5: | ||||
| 			if "round-trip" != fields[0] { | ||||
| 				continue LOOP | ||||
| 			} | ||||
| 
 | ||||
| 			times := strings.Split(fields[3], "/") | ||||
| 
 | ||||
| 			minTime, err := strconv.ParseFloat(times[0], 32) | ||||
| 			if nil != err { | ||||
| 				log.Print(err) | ||||
| 				continue LOOP | ||||
| 			} | ||||
| 			result.Summary.MinTime = float32(minTime) | ||||
| 
 | ||||
| 			maxTime, err := strconv.ParseFloat(times[2], 32) | ||||
| 			if nil != err { | ||||
| 				log.Print(err) | ||||
| 				continue LOOP | ||||
| 			} | ||||
| 			result.Summary.MaxTime = float32(maxTime) | ||||
| 
 | ||||
| 			avgTime, err := strconv.ParseFloat(times[1], 32) | ||||
| 			if nil != err { | ||||
| 				log.Print(err) | ||||
| 				continue LOOP | ||||
| 			} | ||||
| 			result.Summary.AvgTime = float32(avgTime) | ||||
| 
 | ||||
| 		case 8: | ||||
| 			seqs := strings.Split(fields[4], "=") | ||||
| 			ttls := strings.Split(fields[5], "=") | ||||
| 			times := strings.Split(fields[6], "=") | ||||
| 			seq, err := strconv.Atoi(seqs[1]) | ||||
| 			if nil != err { | ||||
| 				log.Print(err) | ||||
| 				continue LOOP | ||||
| 			} | ||||
| 			ttl, err := strconv.Atoi(ttls[1]) | ||||
| 			if nil != err { | ||||
| 				log.Print(err) | ||||
| 				continue LOOP | ||||
| 			} | ||||
| 			_time, err := strconv.ParseFloat(times[1], 32) | ||||
| 			if nil != err { | ||||
| 				log.Print(err) | ||||
| 				continue LOOP | ||||
| 			} | ||||
| 
 | ||||
| 			result.Responses[seq] = &Response{ | ||||
| 				TTL:  ttl, | ||||
| 				Time: float32(_time), | ||||
| 			} | ||||
| 
 | ||||
| 		case 9: | ||||
| 			sendCount, err := strconv.Atoi(fields[0]) | ||||
| 			if nil != err { | ||||
| 				log.Print(err) | ||||
| 				continue LOOP | ||||
| 			} | ||||
| 			result.Summary.SendCount = sendCount | ||||
| 
 | ||||
| 			receiveCount, err := strconv.Atoi(fields[3]) | ||||
| 			if nil != err { | ||||
| 				log.Print(err) | ||||
| 				continue LOOP | ||||
| 			} | ||||
| 			result.Summary.ReceiveCount = receiveCount | ||||
| 
 | ||||
| 			lossPercent, err := strconv.ParseFloat(strings.Replace(fields[6], "%", "", -1), 32) | ||||
| 			if nil != err { | ||||
| 				log.Print(err) | ||||
| 				continue LOOP | ||||
| 			} | ||||
| 			result.Summary.LossPercent = float32(lossPercent) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return result, nil | ||||
| } | ||||
							
								
								
									
										1
									
								
								net/ping/ping_darwin.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								net/ping/ping_darwin.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | ||||
| package ping | ||||
							
								
								
									
										24
									
								
								net/ping/ping_linux.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								net/ping/ping_linux.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,24 @@ | ||||
| package ping | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"os/exec" | ||||
| ) | ||||
| 
 | ||||
| func Ping(destination string, options *PingOptions) (*PingResult, error) { | ||||
| 	options.Validate() | ||||
| 
 | ||||
| 	params := make([]string, 0) | ||||
| 	params = append(params, destination) | ||||
| 	params = append(params, fmt.Sprintf("-c %d", options.Retry)) | ||||
| 	params = append(params, fmt.Sprintf("-i %d", options.Interval)) | ||||
| 	params = append(params, fmt.Sprintf("-w %d", options.Deadline)) | ||||
| 
 | ||||
| 	pCmd := exec.Command("ping", params...) | ||||
| 	output, err := pCmd.CombinedOutput() | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	return parseLinuxPing(output) | ||||
| } | ||||
							
								
								
									
										38
									
								
								net/ping/ping_linux_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								net/ping/ping_linux_test.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,38 @@ | ||||
| package ping | ||||
| 
 | ||||
| import "testing" | ||||
| 
 | ||||
| func TestPing(t *testing.T) { | ||||
| 	type args struct { | ||||
| 		destination string | ||||
| 		options     *PingOptions | ||||
| 	} | ||||
| 	tests := []struct { | ||||
| 		name    string | ||||
| 		args    args | ||||
| 		want    *PingResult | ||||
| 		wantErr bool | ||||
| 	}{ | ||||
| 		{ | ||||
| 			name: "192.168.1.1", | ||||
| 			args: args{ | ||||
| 				destination: "192.168.1.1", | ||||
| 				options: &PingOptions{ | ||||
| 					Retry: 4, | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 	for _, tt := range tests { | ||||
| 		t.Run(tt.name, func(t *testing.T) { | ||||
| 			got, err := Ping(tt.args.destination, tt.args.options) | ||||
| 			if (err != nil) != tt.wantErr { | ||||
| 				t.Errorf("Ping() error = %v, wantErr %v", err, tt.wantErr) | ||||
| 				return | ||||
| 			} | ||||
| 			if got != tt.want { | ||||
| 				t.Errorf("Ping() = %v, want %v", got, tt.want) | ||||
| 			} | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										145
									
								
								net/ping/ping_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								net/ping/ping_test.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,145 @@ | ||||
| package ping | ||||
| 
 | ||||
| import ( | ||||
| 	"reflect" | ||||
| 	"testing" | ||||
| ) | ||||
| 
 | ||||
| func TestPingOptions_Validate(t *testing.T) { | ||||
| 	type fields struct { | ||||
| 		Retry    int | ||||
| 		Interval int | ||||
| 		Deadline int | ||||
| 	} | ||||
| 	tests := []struct { | ||||
| 		name   string | ||||
| 		fields fields | ||||
| 	}{ | ||||
| 		// TODO: Add test cases. | ||||
| 	} | ||||
| 	for _, tt := range tests { | ||||
| 		t.Run(tt.name, func(t *testing.T) { | ||||
| 			o := &PingOptions{ | ||||
| 				Retry:    tt.fields.Retry, | ||||
| 				Interval: tt.fields.Interval, | ||||
| 				Deadline: tt.fields.Deadline, | ||||
| 			} | ||||
| 			o.Validate() | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func Test_parseLinuxPing(t *testing.T) { | ||||
| 	type args struct { | ||||
| 		output []byte | ||||
| 	} | ||||
| 	tests := []struct { | ||||
| 		name    string | ||||
| 		args    args | ||||
| 		want    *PingResult | ||||
| 		wantErr bool | ||||
| 	}{ | ||||
| 		// TODO: Add test cases. | ||||
| 	} | ||||
| 	for _, tt := range tests { | ||||
| 		t.Run(tt.name, func(t *testing.T) { | ||||
| 			got, err := parseLinuxPing(tt.args.output) | ||||
| 			if (err != nil) != tt.wantErr { | ||||
| 				t.Errorf("parseLinuxPing() error = %v, wantErr %v", err, tt.wantErr) | ||||
| 				return | ||||
| 			} | ||||
| 			if !reflect.DeepEqual(got, tt.want) { | ||||
| 				t.Errorf("parseLinuxPing() = %v, want %v", got, tt.want) | ||||
| 			} | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func Test_parseWindowsPing(t *testing.T) { | ||||
| 	type args struct { | ||||
| 		output []byte | ||||
| 	} | ||||
| 	tests := []struct { | ||||
| 		name    string | ||||
| 		args    args | ||||
| 		want    *PingResult | ||||
| 		wantErr bool | ||||
| 	}{ | ||||
| 		{ | ||||
| 			name: "test", | ||||
| 			args: args{ | ||||
| 				output: []byte(` | ||||
| Active code page: 437 | ||||
| 
 | ||||
| Pinging www.google.com [216.58.221.164] with 32 bytes of data: | ||||
| Reply from 216.58.221.164: bytes=32 time=37ms TTL=51 | ||||
| Request timed out. | ||||
| Reply from 216.58.221.164: bytes=32 time=38ms TTL=51 | ||||
| Reply from 216.58.221.164: bytes=32 time=37ms TTL=51 | ||||
| Reply from 216.58.221.164: bytes=32 time=37ms TTL=51 | ||||
| 
 | ||||
| Ping statistics for 216.58.221.164: | ||||
|     Packets: Sent = 5, Received = 4, Lost = 1 (20% loss), | ||||
| Approximate round trip times in milli-seconds: | ||||
|     Minimum = 37ms, Maximum = 38ms, Average = 37ms | ||||
| 
 | ||||
| 				`), | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 	for _, tt := range tests { | ||||
| 		t.Run(tt.name, func(t *testing.T) { | ||||
| 			got, err := parseWindowsPing(tt.args.output) | ||||
| 			if (err != nil) != tt.wantErr { | ||||
| 				t.Errorf("parseWindowsPing() error = %v, wantErr %v", err, tt.wantErr) | ||||
| 				return | ||||
| 			} | ||||
| 			if !reflect.DeepEqual(got, tt.want) { | ||||
| 				t.Errorf("parseWindowsPing() = %v, want %v", got, tt.want) | ||||
| 			} | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func Test_parseDarwinPing(t *testing.T) { | ||||
| 	type args struct { | ||||
| 		output []byte | ||||
| 	} | ||||
| 	tests := []struct { | ||||
| 		name    string | ||||
| 		args    args | ||||
| 		want    *PingResult | ||||
| 		wantErr bool | ||||
| 	}{ | ||||
| 		{ | ||||
| 			name: "test", | ||||
| 			args: args{ | ||||
| 				output: []byte(` | ||||
| PING 192.168.1.1 (192.168.1.1): 56 data bytes | ||||
| 64 bytes from 192.168.1.1: icmp_seq=0 ttl=64 time=1.664 ms | ||||
| 64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=0.971 ms | ||||
| 64 bytes from 192.168.1.1: icmp_seq=2 ttl=64 time=3.934 ms | ||||
| 64 bytes from 192.168.1.1: icmp_seq=3 ttl=64 time=3.539 ms | ||||
| 64 bytes from 192.168.1.1: icmp_seq=4 ttl=64 time=3.690 ms | ||||
| 
 | ||||
| --- 192.168.1.1 ping statistics --- | ||||
| 5 packets transmitted, 5 packets received, 0.0% packet loss | ||||
| round-trip min/avg/max/stddev = 0.971/2.760/3.934/1.204 ms | ||||
| 
 | ||||
| 				`), | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 	for _, tt := range tests { | ||||
| 		t.Run(tt.name, func(t *testing.T) { | ||||
| 			got, err := parseDarwinPing(tt.args.output) | ||||
| 			if (err != nil) != tt.wantErr { | ||||
| 				t.Errorf("parseDarwinPing() error = %v, wantErr %v", err, tt.wantErr) | ||||
| 				return | ||||
| 			} | ||||
| 			if !reflect.DeepEqual(got, tt.want) { | ||||
| 				t.Errorf("parseDarwinPing() = %v, want %v", got, tt.want) | ||||
| 			} | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										23
									
								
								net/ping/ping_windows.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								net/ping/ping_windows.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,23 @@ | ||||
| package ping | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"os/exec" | ||||
| ) | ||||
| 
 | ||||
| func Ping(destination string, options *PingOptions) (string, error) { | ||||
| 	options.Validate() | ||||
| 
 | ||||
| 	params := make([]string, 0) | ||||
| 	params = append(params, destination) | ||||
| 	params = append(params, fmt.Sprintf("-n %d", options.Retry)) | ||||
| 	params = append(params, fmt.Sprintf("-w %d", options.Deadline*1000)) | ||||
| 
 | ||||
| 	pCmd := exec.Command("cmd.exe", "/C", "chcp 437", "&&", "ping", params...) | ||||
| 	output, err := pCmd.CombinedOutput() | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
| 
 | ||||
| 	return parseLinuxPing(output) | ||||
| } | ||||
							
								
								
									
										38
									
								
								net/ping/ping_windows_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								net/ping/ping_windows_test.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,38 @@ | ||||
| package ping | ||||
| 
 | ||||
| import "testing" | ||||
| 
 | ||||
| func TestPing(t *testing.T) { | ||||
| 	type args struct { | ||||
| 		destination string | ||||
| 		options     *PingOptions | ||||
| 	} | ||||
| 	tests := []struct { | ||||
| 		name    string | ||||
| 		args    args | ||||
| 		want    string | ||||
| 		wantErr bool | ||||
| 	}{ | ||||
| 		{ | ||||
| 			name: "192.168.1.1", | ||||
| 			args: args{ | ||||
| 				destination: "192.168.1.1", | ||||
| 				options: &PingOptions{ | ||||
| 					Retry: 4, | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 	for _, tt := range tests { | ||||
| 		t.Run(tt.name, func(t *testing.T) { | ||||
| 			got, err := Ping(tt.args.destination, tt.args.options) | ||||
| 			if (err != nil) != tt.wantErr { | ||||
| 				t.Errorf("Ping() error = %v, wantErr %v", err, tt.wantErr) | ||||
| 				return | ||||
| 			} | ||||
| 			if got != tt.want { | ||||
| 				t.Errorf("Ping() = %v, want %v", got, tt.want) | ||||
| 			} | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user