Bläddra i källkod

Added tests & documentation for ping.go

arianagiroux 1 vecka sedan
förälder
incheckning
b17166ed7a
2 ändrade filer med 61 tillägg och 21 borttagningar
  1. 60 20
      ping.go
  2. 1 1
      ping_test.go

+ 60 - 20
ping.go

@@ -1,6 +1,43 @@
-// Defines a wrapper around the system ping binary.
+// Pingo defines a number of high level functions and data structures to
+// interact with and represent a Ping via Go. Primarily, it defines the
+// Ping() function and Address data structure.
 //
-// NOTE(os): may fail with non-unix compliant system ping binaries.
+// NOTE this project does not provide a Go implementation of the ping protocol.
+// Instead, this project merely provides a wrapper to your system's existing
+// ping.c binary.
+//
+// NOTE(os): this project may fail with non-unix compliant system ping binaries,
+// predominantly Windows platforms. This relates to the way in which the project
+// interacts with the ping binary. (read: the project uses `ping -c1 ADDRESS`
+// and will break on systems that implement a different CLI)
+//
+// The project defines a simple top level binding for the system's ping.c:
+// Ping(). It simply reports a delay time as reported by the system ping, and
+// any errors encountered.
+//
+// Additionally, the project defines the "Address" data structure to represent
+// a series of ping results relating to the given host. Its fields are simple:
+//
+//	Address (string): the host or IP address
+//
+//	Results ([]float64): a series of ping results
+//
+//	MaxResults (int): The maximum number of results to track, as enforced by
+//		Address.Truncate()
+//
+// The Address data structure provides a series of higher level access functions
+// to prevent code repetition:
+//
+//	Example:
+//		...
+//		a := Address{Address:"google.ca", MaxResults:20}
+//		latency, err := a.Ping() 	// get a single result and return the value
+//		... 											// handle error
+//		a.Results, err = a.Poll()	// append a ping to the Results slice, then return the updated slice
+//		... 											// handle error
+//		a.Results = a.Truncate()	// return a modified slice of only the most n*a.MaxResults long
+//
+// For more, see each function's GoDoc.
 package pingo
 
 import (
@@ -21,7 +58,7 @@ func runPing(address string) (delay *[]byte, err error) {
 	return &out, err
 }
 
-// splitBytesToLines splits bytes as returned by [pingstats.runPing] into an
+// splitBytesToLines splits bytes as returned by runPing into an
 // array of strings by newline
 func splitBytesToLines(bytes *[]byte) (lines []string) {
 	return strings.Split(strings.ReplaceAll(string(*bytes), "\r\n", "\n"), "\n")
@@ -41,17 +78,17 @@ func Ping(address string) (delay float64, err error) {
 
 	lines := splitBytesToLines(out)
 
-	for i := 0; i < len(lines); i++ {
+	for i := range lines {
 		if strings.Contains(lines[i], "bytes from") {
 			position := strings.Index(lines[i], "time=")
 
 			before, _, success := strings.Cut(lines[i][position:], " ")
 			if !success {
-				return -1, errors.New("Line does not match pattern!")
+				return -1, errors.New("line does not match pattern")
 			}
 			_, after, success := strings.Cut(before, "=")
 			if !success {
-				return -1, errors.New("Line does not match pattern!")
+				return -1, errors.New("line does not match pattern")
 			}
 
 			delay, _ := strconv.ParseFloat(after, 64)
@@ -62,36 +99,39 @@ func Ping(address string) (delay float64, err error) {
 }
 
 type Address struct {
-	Address     string
-	results     []float64
-	max_results int
+	Address    string
+	Results    []float64
+	MaxResults int
 }
 
+// Enforces a Address.Result maximum length by dropping the oldest result,
+// then returns the modified slice.
 func (a Address) Truncate() []float64 {
-	if len(a.results) > a.max_results {
-		a.results = a.results[len(a.results)-a.max_results : len(a.results)] // return modified slice missing first index
+	if len(a.Results) > a.MaxResults {
+		a.Results = a.Results[len(a.Results)-a.MaxResults : len(a.Results)] // return modified slice missing first index
 	}
 
-	return a.results
+	return a.Results
 }
 
-// Wraps [Ping]
+// Wraps Ping, passing Address.Address as its argument.
 func (a Address) Ping() (delay float64, err error) {
 	return Ping(a.Address)
 }
 
-// Poll  the affiliated Address and appends it to a.results
+// Poll the affiliated Address, append it to a.Results, and report the modified
+// slice and any errors.
 func (a Address) Poll() (results []float64, err error) {
 	delay, err := a.Ping()
-	a.results = append(a.results, delay)
-	a.results = a.Truncate() // enforce max length
-	return a.results, err
+	a.Results = append(a.Results, delay)
+	a.Results = a.Truncate() // enforce max length
+	return a.Results, err
 }
 
-// Last returns the last result in [Address.results]. Returns -1 if no previous result
+// Last returns the last result in Address.Results. Returns -1 if no previous result
 func (a Address) Last() (delay float64) {
-	if len(a.results) > 0 {
-		return a.results[len(a.results)-1]
+	if len(a.Results) > 0 {
+		return a.Results[len(a.Results)-1]
 	} else {
 		return -1
 	}

+ 1 - 1
ping_test.go

@@ -101,7 +101,7 @@ func Test_Ping(t *testing.T) {
 }
 
 func spawnAddress(a string, r []float64, m int) Address {
-	return Address{Address: a, results: r, max_results: m}
+	return Address{Address: a, Results: r, MaxResults: m}
 }
 func Test_Address_Truncate(t *testing.T) {
 	testA := spawnAddress("test", make([]float64, 20), 10)