363 lines
12 KiB
Go
363 lines
12 KiB
Go
// +build windows
|
|
|
|
package ping
|
|
|
|
import (
|
|
"errors"
|
|
"reflect"
|
|
"testing"
|
|
|
|
"github.com/influxdata/telegraf/testutil"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
// Windows ping format ( should support multilanguage ?)
|
|
var winPLPingOutput = `
|
|
Badanie 8.8.8.8 z 32 bajtami danych:
|
|
Odpowiedz z 8.8.8.8: bajtow=32 czas=49ms TTL=43
|
|
Odpowiedz z 8.8.8.8: bajtow=32 czas=46ms TTL=43
|
|
Odpowiedz z 8.8.8.8: bajtow=32 czas=48ms TTL=43
|
|
Odpowiedz z 8.8.8.8: bajtow=32 czas=57ms TTL=43
|
|
|
|
Statystyka badania ping dla 8.8.8.8:
|
|
Pakiety: Wyslane = 4, Odebrane = 4, Utracone = 0
|
|
(0% straty),
|
|
Szacunkowy czas bladzenia pakietww w millisekundach:
|
|
Minimum = 46 ms, Maksimum = 57 ms, Czas sredni = 50 ms
|
|
`
|
|
|
|
// Windows ping format ( should support multilanguage ?)
|
|
var winENPingOutput = `
|
|
Pinging 8.8.8.8 with 32 bytes of data:
|
|
Reply from 8.8.8.8: bytes=32 time=52ms TTL=43
|
|
Reply from 8.8.8.8: bytes=32 time=50ms TTL=43
|
|
Reply from 8.8.8.8: bytes=32 time=50ms TTL=43
|
|
Reply from 8.8.8.8: bytes=32 time=51ms TTL=43
|
|
|
|
Ping statistics for 8.8.8.8:
|
|
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
|
|
Approximate round trip times in milli-seconds:
|
|
Minimum = 50ms, Maximum = 52ms, Average = 50ms
|
|
`
|
|
|
|
func TestHost(t *testing.T) {
|
|
trans, recReply, recPacket, avg, min, max, err := processPingOutput(winPLPingOutput)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, 4, trans, "4 packets were transmitted")
|
|
assert.Equal(t, 4, recReply, "4 packets were reply")
|
|
assert.Equal(t, 4, recPacket, "4 packets were received")
|
|
assert.Equal(t, 50, avg, "Average 50")
|
|
assert.Equal(t, 46, min, "Min 46")
|
|
assert.Equal(t, 57, max, "max 57")
|
|
|
|
trans, recReply, recPacket, avg, min, max, err = processPingOutput(winENPingOutput)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, 4, trans, "4 packets were transmitted")
|
|
assert.Equal(t, 4, recReply, "4 packets were reply")
|
|
assert.Equal(t, 4, recPacket, "4 packets were received")
|
|
assert.Equal(t, 50, avg, "Average 50")
|
|
assert.Equal(t, 50, min, "Min 50")
|
|
assert.Equal(t, 52, max, "Max 52")
|
|
}
|
|
|
|
func mockHostPinger(binary string, timeout float64, args ...string) (string, error) {
|
|
return winENPingOutput, nil
|
|
}
|
|
|
|
// Test that Gather function works on a normal ping
|
|
func TestPingGather(t *testing.T) {
|
|
var acc testutil.Accumulator
|
|
p := Ping{
|
|
Urls: []string{"www.google.com", "www.reddit.com"},
|
|
pingHost: mockHostPinger,
|
|
}
|
|
|
|
acc.GatherError(p.Gather)
|
|
tags := map[string]string{"url": "www.google.com"}
|
|
fields := map[string]interface{}{
|
|
"packets_transmitted": 4,
|
|
"packets_received": 4,
|
|
"reply_received": 4,
|
|
"percent_packet_loss": 0.0,
|
|
"percent_reply_loss": 0.0,
|
|
"average_response_ms": 50.0,
|
|
"minimum_response_ms": 50.0,
|
|
"maximum_response_ms": 52.0,
|
|
"result_code": 0,
|
|
}
|
|
acc.AssertContainsTaggedFields(t, "ping", fields, tags)
|
|
|
|
tags = map[string]string{"url": "www.reddit.com"}
|
|
acc.AssertContainsTaggedFields(t, "ping", fields, tags)
|
|
}
|
|
|
|
var errorPingOutput = `
|
|
Badanie nask.pl [195.187.242.157] z 32 bajtami danych:
|
|
Upłynął limit czasu żądania.
|
|
Upłynął limit czasu żądania.
|
|
Upłynął limit czasu żądania.
|
|
Upłynął limit czasu żądania.
|
|
|
|
Statystyka badania ping dla 195.187.242.157:
|
|
Pakiety: Wysłane = 4, Odebrane = 0, Utracone = 4
|
|
(100% straty),
|
|
`
|
|
|
|
func mockErrorHostPinger(binary string, timeout float64, args ...string) (string, error) {
|
|
return errorPingOutput, errors.New("No packets received")
|
|
}
|
|
|
|
// Test that Gather works on a ping with no transmitted packets, even though the
|
|
// command returns an error
|
|
func TestBadPingGather(t *testing.T) {
|
|
var acc testutil.Accumulator
|
|
p := Ping{
|
|
Urls: []string{"www.amazon.com"},
|
|
pingHost: mockErrorHostPinger,
|
|
}
|
|
|
|
acc.GatherError(p.Gather)
|
|
tags := map[string]string{"url": "www.amazon.com"}
|
|
fields := map[string]interface{}{
|
|
"packets_transmitted": 4,
|
|
"packets_received": 0,
|
|
"reply_received": 0,
|
|
"percent_packet_loss": 100.0,
|
|
"percent_reply_loss": 100.0,
|
|
"result_code": 0,
|
|
}
|
|
acc.AssertContainsTaggedFields(t, "ping", fields, tags)
|
|
}
|
|
|
|
func TestArguments(t *testing.T) {
|
|
arguments := []string{"-c", "3"}
|
|
p := Ping{
|
|
Count: 2,
|
|
Timeout: 12.0,
|
|
Arguments: arguments,
|
|
}
|
|
|
|
actual := p.args("www.google.com")
|
|
require.True(t, reflect.DeepEqual(actual, arguments), "Expected : %s Actual: %s", arguments, actual)
|
|
}
|
|
|
|
var lossyPingOutput = `
|
|
Badanie thecodinglove.com [66.6.44.4] z 9800 bajtami danych:
|
|
Upłynął limit czasu żądania.
|
|
Odpowiedź z 66.6.44.4: bajtów=9800 czas=114ms TTL=48
|
|
Odpowiedź z 66.6.44.4: bajtów=9800 czas=114ms TTL=48
|
|
Odpowiedź z 66.6.44.4: bajtów=9800 czas=118ms TTL=48
|
|
Odpowiedź z 66.6.44.4: bajtów=9800 czas=114ms TTL=48
|
|
Odpowiedź z 66.6.44.4: bajtów=9800 czas=114ms TTL=48
|
|
Upłynął limit czasu żądania.
|
|
Odpowiedź z 66.6.44.4: bajtów=9800 czas=119ms TTL=48
|
|
Odpowiedź z 66.6.44.4: bajtów=9800 czas=116ms TTL=48
|
|
|
|
Statystyka badania ping dla 66.6.44.4:
|
|
Pakiety: Wysłane = 9, Odebrane = 7, Utracone = 2
|
|
(22% straty),
|
|
Szacunkowy czas błądzenia pakietów w millisekundach:
|
|
Minimum = 114 ms, Maksimum = 119 ms, Czas średni = 115 ms
|
|
`
|
|
|
|
func mockLossyHostPinger(binary string, timeout float64, args ...string) (string, error) {
|
|
return lossyPingOutput, nil
|
|
}
|
|
|
|
// Test that Gather works on a ping with lossy packets
|
|
func TestLossyPingGather(t *testing.T) {
|
|
var acc testutil.Accumulator
|
|
p := Ping{
|
|
Urls: []string{"www.google.com"},
|
|
pingHost: mockLossyHostPinger,
|
|
}
|
|
|
|
acc.GatherError(p.Gather)
|
|
tags := map[string]string{"url": "www.google.com"}
|
|
fields := map[string]interface{}{
|
|
"packets_transmitted": 9,
|
|
"packets_received": 7,
|
|
"reply_received": 7,
|
|
"percent_packet_loss": 22.22222222222222,
|
|
"percent_reply_loss": 22.22222222222222,
|
|
"average_response_ms": 115.0,
|
|
"minimum_response_ms": 114.0,
|
|
"maximum_response_ms": 119.0,
|
|
"result_code": 0,
|
|
}
|
|
acc.AssertContainsTaggedFields(t, "ping", fields, tags)
|
|
}
|
|
|
|
// Fatal ping output (invalid argument)
|
|
var fatalPingOutput = `
|
|
Bad option -d.
|
|
|
|
|
|
Usage: ping [-t] [-a] [-n count] [-l size] [-f] [-i TTL] [-v TOS]
|
|
[-r count] [-s count] [[-j host-list] | [-k host-list]]
|
|
[-w timeout] [-R] [-S srcaddr] [-4] [-6] target_name
|
|
|
|
Options:
|
|
-t Ping the specified host until stopped.
|
|
To see statistics and continue - type Control-Break;
|
|
To stop - type Control-C.
|
|
-a Resolve addresses to hostnames.
|
|
-n count Number of echo requests to send.
|
|
-l size Send buffer size.
|
|
-f Set Don't Fragment flag in packet (IPv4-only).
|
|
-i TTL Time To Live.
|
|
-v TOS Type Of Service (IPv4-only. This setting has been deprecated
|
|
and has no effect on the type of service field in the IP Header).
|
|
-r count Record route for count hops (IPv4-only).
|
|
-s count Timestamp for count hops (IPv4-only).
|
|
-j host-list Loose source route along host-list (IPv4-only).
|
|
-k host-list Strict source route along host-list (IPv4-only).
|
|
-w timeout Timeout in milliseconds to wait for each reply.
|
|
-R Use routing header to test reverse route also (IPv6-only).
|
|
-S srcaddr Source address to use.
|
|
-4 Force using IPv4.
|
|
-6 Force using IPv6.
|
|
|
|
`
|
|
|
|
func mockFatalHostPinger(binary string, timeout float64, args ...string) (string, error) {
|
|
return fatalPingOutput, errors.New("So very bad")
|
|
}
|
|
|
|
// Test that a fatal ping command does not gather any statistics.
|
|
func TestFatalPingGather(t *testing.T) {
|
|
var acc testutil.Accumulator
|
|
p := Ping{
|
|
Urls: []string{"www.amazon.com"},
|
|
pingHost: mockFatalHostPinger,
|
|
}
|
|
|
|
acc.GatherError(p.Gather)
|
|
assert.True(t, acc.HasFloatField("ping", "errors"),
|
|
"Fatal ping should have packet measurements")
|
|
assert.False(t, acc.HasInt64Field("ping", "packets_transmitted"),
|
|
"Fatal ping should not have packet measurements")
|
|
assert.False(t, acc.HasInt64Field("ping", "packets_received"),
|
|
"Fatal ping should not have packet measurements")
|
|
assert.False(t, acc.HasFloatField("ping", "percent_packet_loss"),
|
|
"Fatal ping should not have packet measurements")
|
|
assert.False(t, acc.HasFloatField("ping", "percent_reply_loss"),
|
|
"Fatal ping should not have packet measurements")
|
|
assert.False(t, acc.HasInt64Field("ping", "average_response_ms"),
|
|
"Fatal ping should not have packet measurements")
|
|
assert.False(t, acc.HasInt64Field("ping", "maximum_response_ms"),
|
|
"Fatal ping should not have packet measurements")
|
|
assert.False(t, acc.HasInt64Field("ping", "minimum_response_ms"),
|
|
"Fatal ping should not have packet measurements")
|
|
}
|
|
|
|
var UnreachablePingOutput = `
|
|
Pinging www.google.pl [8.8.8.8] with 32 bytes of data:
|
|
Request timed out.
|
|
Request timed out.
|
|
Reply from 194.204.175.50: Destination net unreachable.
|
|
Request timed out.
|
|
|
|
Ping statistics for 8.8.8.8:
|
|
Packets: Sent = 4, Received = 1, Lost = 3 (75% loss),
|
|
`
|
|
|
|
func mockUnreachableHostPinger(binary string, timeout float64, args ...string) (string, error) {
|
|
return UnreachablePingOutput, errors.New("So very bad")
|
|
}
|
|
|
|
//Reply from 185.28.251.217: TTL expired in transit.
|
|
|
|
// in case 'Destination net unreachable' ping app return receive packet which is not what we need
|
|
// it's not contain valid metric so treat it as lost one
|
|
func TestUnreachablePingGather(t *testing.T) {
|
|
var acc testutil.Accumulator
|
|
p := Ping{
|
|
Urls: []string{"www.google.com"},
|
|
pingHost: mockUnreachableHostPinger,
|
|
}
|
|
|
|
acc.GatherError(p.Gather)
|
|
|
|
tags := map[string]string{"url": "www.google.com"}
|
|
fields := map[string]interface{}{
|
|
"packets_transmitted": 4,
|
|
"packets_received": 1,
|
|
"reply_received": 0,
|
|
"percent_packet_loss": 75.0,
|
|
"percent_reply_loss": 100.0,
|
|
"result_code": 0,
|
|
}
|
|
acc.AssertContainsTaggedFields(t, "ping", fields, tags)
|
|
|
|
assert.False(t, acc.HasFloatField("ping", "errors"),
|
|
"Fatal ping should not have packet measurements")
|
|
assert.False(t, acc.HasInt64Field("ping", "average_response_ms"),
|
|
"Fatal ping should not have packet measurements")
|
|
assert.False(t, acc.HasInt64Field("ping", "maximum_response_ms"),
|
|
"Fatal ping should not have packet measurements")
|
|
assert.False(t, acc.HasInt64Field("ping", "minimum_response_ms"),
|
|
"Fatal ping should not have packet measurements")
|
|
}
|
|
|
|
var TTLExpiredPingOutput = `
|
|
Pinging www.google.pl [8.8.8.8] with 32 bytes of data:
|
|
Request timed out.
|
|
Request timed out.
|
|
Reply from 185.28.251.217: TTL expired in transit.
|
|
Request timed out.
|
|
|
|
Ping statistics for 8.8.8.8:
|
|
Packets: Sent = 4, Received = 1, Lost = 3 (75% loss),
|
|
`
|
|
|
|
func mockTTLExpiredPinger(binary string, timeout float64, args ...string) (string, error) {
|
|
return TTLExpiredPingOutput, errors.New("So very bad")
|
|
}
|
|
|
|
// in case 'Destination net unreachable' ping app return receive packet which is not what we need
|
|
// it's not contain valid metric so treat it as lost one
|
|
func TestTTLExpiredPingGather(t *testing.T) {
|
|
var acc testutil.Accumulator
|
|
p := Ping{
|
|
Urls: []string{"www.google.com"},
|
|
pingHost: mockTTLExpiredPinger,
|
|
}
|
|
|
|
acc.GatherError(p.Gather)
|
|
|
|
tags := map[string]string{"url": "www.google.com"}
|
|
fields := map[string]interface{}{
|
|
"packets_transmitted": 4,
|
|
"packets_received": 1,
|
|
"reply_received": 0,
|
|
"percent_packet_loss": 75.0,
|
|
"percent_reply_loss": 100.0,
|
|
"result_code": 0,
|
|
}
|
|
acc.AssertContainsTaggedFields(t, "ping", fields, tags)
|
|
|
|
assert.False(t, acc.HasFloatField("ping", "errors"),
|
|
"Fatal ping should not have packet measurements")
|
|
assert.False(t, acc.HasInt64Field("ping", "average_response_ms"),
|
|
"Fatal ping should not have packet measurements")
|
|
assert.False(t, acc.HasInt64Field("ping", "maximum_response_ms"),
|
|
"Fatal ping should not have packet measurements")
|
|
assert.False(t, acc.HasInt64Field("ping", "minimum_response_ms"),
|
|
"Fatal ping should not have packet measurements")
|
|
}
|
|
|
|
func TestPingBinary(t *testing.T) {
|
|
var acc testutil.Accumulator
|
|
p := Ping{
|
|
Urls: []string{"www.google.com"},
|
|
Binary: "ping6",
|
|
pingHost: func(binary string, timeout float64, args ...string) (string, error) {
|
|
assert.True(t, binary == "ping6")
|
|
return "", nil
|
|
},
|
|
}
|
|
acc.GatherError(p.Gather)
|
|
}
|