Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Infinite ping #86

Merged
merged 27 commits into from
Feb 15, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
f577a85
Add --infinite flag
radulucut Jan 15, 2024
3bbc717
Add infinite output view & refactoring
radulucut Jan 17, 2024
ca86281
Fix Sent count
radulucut Jan 17, 2024
b5da380
More docs
jimaek Jan 17, 2024
b9e9d4e
Add tests + refactoring
radulucut Jan 18, 2024
20c83e7
Update formating, fix test
radulucut Jan 18, 2024
0c774f7
Fix test
radulucut Jan 18, 2024
1ae9a0f
Update Go version and dependencies
radulucut Jan 19, 2024
f527b86
Update table format
radulucut Jan 19, 2024
a99d83d
Add table truncation
radulucut Jan 23, 2024
2e3e18d
Fix limit flag
radulucut Jan 23, 2024
a291e5f
Parse and handle in-progress measurement
radulucut Jan 25, 2024
225d384
Add more tests
radulucut Jan 26, 2024
45d9151
Add support for share & summary + fixes & tests
radulucut Jan 30, 2024
8542e5a
Add combined mdev, change --infinite + --latency
radulucut Jan 31, 2024
180a8ba
Update ping.go
MartinKolarik Feb 2, 2024
3ca1801
Update mdev logic & term padding, fix history
radulucut Feb 5, 2024
940e0a4
Fix tests
radulucut Feb 5, 2024
416ea8f
Refactor code structure to improve testability
radulucut Feb 6, 2024
c741fd5
Add printer
radulucut Feb 7, 2024
7881888
Refactoring, ping tests & fixes
radulucut Feb 7, 2024
ea5c2b8
Skip test on windows
radulucut Feb 7, 2024
96a19a8
Update actions
MartinKolarik Feb 12, 2024
877c51a
Handle failed measurements
radulucut Feb 12, 2024
5d3121e
Add time for in progress measurements
radulucut Feb 13, 2024
b80540d
Replace github.com/golang/mock with go.uber.org/mock
radulucut Feb 13, 2024
9be6fae
Update sleep durations in ping_test.go
radulucut Feb 13, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 34 additions & 8 deletions cmd/ping.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ package cmd

radulucut marked this conversation as resolved.
Show resolved Hide resolved
import (
"fmt"
"os"
"os/signal"
"syscall"

"github.com/jsdelivr/globalping-cli/client"
"github.com/jsdelivr/globalping-cli/model"
Expand Down Expand Up @@ -49,20 +52,41 @@ Examples:
return err
}
if ctx.Infinite {
ctx.Limit = min(ctx.Limit, 5) // Limit to 5 probes
ctx.Packets = 16 // Default to 16 packets
for {
ctx.From, err = ping(cmd)
if err != nil {
return err
}
}
return infinitePing(cmd)
}
_, err = ping(cmd)
return err
},
}

func infinitePing(cmd *cobra.Command) error {
radulucut marked this conversation as resolved.
Show resolved Hide resolved
var err error
if ctx.Limit > 5 {
return fmt.Errorf("continous mode is currently limited to 5 probes")
}
ctx.Packets = 16 // Default to 16 packets

// Trap sigterm or interupt to display info on exit
sig := make(chan os.Signal, 1)
signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)

go func() {
for {
ctx.From, err = ping(cmd)
radulucut marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
sig <- syscall.SIGINT
return
}
}
}()

<-sig
if err == nil {
view.OutputSummary(&ctx)
}
return err
}

func ping(cmd *cobra.Command) (string, error) {
opts = model.PostMeasurement{
Type: "ping",
Expand All @@ -88,6 +112,8 @@ func ping(cmd *cobra.Command) (string, error) {
return "", err
}

ctx.CallCount++

// Save measurement ID to history
if !isPreviousMeasurementId {
err := saveMeasurementID(res.ID)
Expand Down
1 change: 1 addition & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ var (
opts = model.PostMeasurement{}
ctx = model.Context{
APIMinInterval: 500 * time.Millisecond,
MaxHistory: 10,
}
)

Expand Down
1 change: 1 addition & 0 deletions model/get.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ type PingStats struct {
Rcv int `json:"rcv"` // The number of received packets.
Drop int `json:"drop"` // The number of dropped packets (total - rcv).
Loss float64 `json:"loss"` // The percentage of dropped packets.
Mdev float64 `json:"mdev"` // The mean deviation of the rtt values.
}

type PingTiming struct {
Expand Down
56 changes: 54 additions & 2 deletions model/root.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package model

import (
"math"
"time"

"github.com/pterm/pterm"
Expand All @@ -24,16 +25,67 @@ type Context struct {
Infinite bool // Infinite flag

APIMinInterval time.Duration // Minimum interval between API calls
Area *pterm.AreaPrinter
Stats []MeasurementStats

Area *pterm.AreaPrinter
Hostname string
CompletedStats []MeasurementStats
InProgressStats []MeasurementStats
CallCount int // Number of measurements created
MaxHistory int // Maximum number of measurements to keep in history
History *Rbuffer // History of measurements
}

type MeasurementStats struct {
Sent int // Number of packets sent
Rcv int // Number of packets received
Lost int // Number of packets lost
Loss float64 // Percentage of packets lost
Last float64 // Last RTT
Min float64 // Minimum RTT
Avg float64 // Average RTT
Max float64 // Maximum RTT
Mdev float64 // Mean deviation of RTT
Time float64 // Total time
}

func NewMeasurementStats() MeasurementStats {
return MeasurementStats{Last: -1, Min: math.MaxFloat64, Avg: -1, Max: -1}
}

type Rbuffer struct {
Index int
Slice []string
}

func (q *Rbuffer) Push(id string) {
q.Slice[q.Index] = id
q.Index = (q.Index + 1) % len(q.Slice)
}

func (q *Rbuffer) ToString(sep string) string {
s := ""
i := q.Index
isFirst := true
for {
if q.Slice[i] != "" {
if isFirst {
isFirst = false
s += q.Slice[i]
} else {
s += sep + q.Slice[i]
}
}
i = (i + 1) % len(q.Slice)
if i == q.Index {
break
}
}
return s
}

func NewRbuffer(size int) *Rbuffer {
return &Rbuffer{
Index: 0,
Slice: make([]string, size),
}
}
40 changes: 40 additions & 0 deletions model/root_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package model

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestRBuffer(t *testing.T) {
t.Run("Push", func(t *testing.T) {
b := NewRbuffer(3)
assert.Equal(t, 0, b.Index)
assert.Equal(t, []string{"", "", ""}, b.Slice)
b.Push("a")
assert.Equal(t, 1, b.Index)
assert.Equal(t, []string{"a", "", ""}, b.Slice)
b.Push("b")
assert.Equal(t, 2, b.Index)
assert.Equal(t, []string{"a", "b", ""}, b.Slice)
b.Push("c")
assert.Equal(t, 0, b.Index)
assert.Equal(t, []string{"a", "b", "c"}, b.Slice)
b.Push("d")
assert.Equal(t, 1, b.Index)
assert.Equal(t, []string{"d", "b", "c"}, b.Slice)
})

t.Run("ToString", func(t *testing.T) {
b := NewRbuffer(3)
assert.Equal(t, "", b.ToString("+"))
b.Push("a")
assert.Equal(t, "a", b.ToString("+"))
b.Push("b")
assert.Equal(t, "a+b", b.ToString("+"))
b.Push("c")
assert.Equal(t, "a+b+c", b.ToString("+"))
b.Push("d")
assert.Equal(t, "b+c+d", b.ToString("+"))
})
}
Loading
Loading