Skip to content

Commit

Permalink
πŸš€ Running TCP test via CLI
Browse files Browse the repository at this point in the history
πŸ”₯ tcp test working with CLI
  • Loading branch information
thibaultleouay authored Nov 7, 2024
2 parents bb0872d + 4f71575 commit 5331c89
Show file tree
Hide file tree
Showing 17 changed files with 522 additions and 56 deletions.
1 change: 0 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
name: goreleaser

on:
pull_request:
push:
# run only against tags
tags:
Expand Down
24 changes: 24 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Tests

on:
push:
branches:
- master
tags:
- '*.*.*'
pull_request:
branches:
- '**'

jobs:
ci:
name: Continuous Integration
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: '>=1.22.0'
- name: Run test
run: go test -timeout 30s -race -count=1 ./...
3 changes: 1 addition & 2 deletions .goreleaser.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,8 @@ brews:
# Repository name.
#
# Templates: allowed.
name: homebrew-tap
name: homebrew-cli


branch: main
token: "{{ .Env.TAP_GITHUB_TOKEN }}"

9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
# OpenStatus CLI

OpenStatus CLI is a command line interface for OpenStatus.
OpenStatus CLI is a command line interface for OpenStatus.

## Installation

```bash
brew tap openstatus/cli
brew install openstatus
```
5 changes: 2 additions & 3 deletions config.openstatus.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
tests:
ids:
- 2260
- 2264

- 1
- 2
4 changes: 2 additions & 2 deletions internal/monitors/monitor_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
"github.com/urfave/cli/v3"
)

func getMonitorInfo(httpClient *http.Client, apiKey string, monitorId string) error {
func GetMonitorInfo(httpClient *http.Client, apiKey string, monitorId string) error {

if monitorId == "" {
return fmt.Errorf("Monitor ID is required")
Expand Down Expand Up @@ -50,7 +50,7 @@ func GetMonitorInfoCmd() *cli.Command {
Action: func(ctx context.Context, cmd *cli.Command) error {
fmt.Println("Monitor information")
monitorId := cmd.Args().Get(0)
err := getMonitorInfo(http.DefaultClient, cmd.String("access-token"), monitorId)
err := GetMonitorInfo(http.DefaultClient, cmd.String("access-token"), monitorId)
if err != nil {
return cli.Exit("Failed to get monitor information", 1)
}
Expand Down
62 changes: 41 additions & 21 deletions internal/monitors/monitor_info_test.go
Original file line number Diff line number Diff line change
@@ -1,26 +1,15 @@
package monitors
package monitors_test

import (
"bytes"
"io"
"log"
"net/http"
"os"
"testing"
)

type interceptorHTTPClient struct {
f func(req *http.Request) (*http.Response, error)
}

func (i *interceptorHTTPClient) RoundTrip(req *http.Request) (*http.Response, error) {
return i.f(req)
}

func (i *interceptorHTTPClient) GetHTTPClient() *http.Client {
return &http.Client{
Transport: i,
}
}
"github.com/openstatusHQ/cli/internal/monitors"
)

func Test_getMonitorInfo(t *testing.T) {
t.Parallel()
Expand All @@ -30,7 +19,7 @@ func Test_getMonitorInfo(t *testing.T) {
interceptor := &interceptorHTTPClient{
f: func(req *http.Request) (*http.Response, error) {
return &http.Response{
StatusCode: http.StatusAccepted,
StatusCode: http.StatusOK,
}, nil
},
}
Expand All @@ -40,18 +29,49 @@ func Test_getMonitorInfo(t *testing.T) {
t.Cleanup(func() {
log.SetOutput(os.Stdout)
})
err := getMonitorInfo(interceptor.GetHTTPClient(), "", "")
err := monitors.GetMonitorInfo(interceptor.GetHTTPClient(), "", "")
if err == nil {
t.Errorf("Expected log output, got nothing")
}
})

t.Run("Monitor ID is required", func(t *testing.T) {
t.Run("Should work", func(t *testing.T) {

body := `{
"id": 2260,
"periodicity": "10m",
"url": "https://www.openstatus.dev",
"regions": [
"iad",
"hkg",
"jnb",
"syd",
"gru"
],
"name": "Vercel Checker Edge",
"description": "",
"method": "GET",
"body": "",
"headers": [
{
"key": "",
"value": ""
}
],
"assertions": [],
"active": false,
"public": false,
"degradedAfter": null,
"timeout": 45000,
"jobType": "http"
}`
r := io.NopCloser(bytes.NewReader([]byte(body)))

interceptor := &interceptorHTTPClient{
f: func(req *http.Request) (*http.Response, error) {
return &http.Response{
StatusCode: http.StatusAccepted,
StatusCode: http.StatusOK,
Body: r,
}, nil
},
}
Expand All @@ -61,8 +81,8 @@ func Test_getMonitorInfo(t *testing.T) {
t.Cleanup(func() {
log.SetOutput(os.Stdout)
})
err := getMonitorInfo(interceptor.GetHTTPClient(), "", "")
if err == nil {
err := monitors.GetMonitorInfo(interceptor.GetHTTPClient(), "test", "1")
if err != nil {
t.Errorf("Expected log output, got nothing")
}
})
Expand Down
32 changes: 25 additions & 7 deletions internal/monitors/monitor_trigger.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ var (
noResult bool
)

func monitorTrigger(httpClient *http.Client, apiKey string, monitorId string) error {
func MonitorTrigger(httpClient *http.Client, apiKey string, monitorId string) error {

if monitorId == "" {
return fmt.Errorf("Monitor ID is required")
Expand Down Expand Up @@ -57,12 +57,30 @@ func monitorTrigger(httpClient *http.Client, apiKey string, monitorId string) er

var inError bool
for _, r := range result {
if r.Error != "" {
inError = true
tbl.AddRow(r.Region, r.Latency, color.RedString("❌"))
} else {
tbl.AddRow(r.Region, r.Latency, color.GreenString("βœ”"))
if r.JobType == "tcp" {
var result TCPRunResult
if err := json.Unmarshal(r.Message, &result); err != nil {
return fmt.Errorf("unable to unmarshal : %w", err)
}
if result.ErrorMessge != "" {
inError = true
tbl.AddRow(r.Region, r.Latency, color.RedString("❌"))
continue
}

}
if r.JobType == "http" {
var result HTTPRunResult
if err := json.Unmarshal(r.Message, &result); err != nil {
return fmt.Errorf("unable to unmarshal : %w", err)
}
if result.Error != "" {
inError = true
tbl.AddRow(r.Region, r.Latency, color.RedString("❌"))
continue
}
}
tbl.AddRow(r.Region, r.Latency, color.GreenString("βœ”"))

}
tbl.Print()
Expand Down Expand Up @@ -98,7 +116,7 @@ func GetMonitorsTriggerCmd() *cli.Command {
},
Action: func(ctx context.Context, cmd *cli.Command) error {
monitorId := cmd.Args().Get(0)
err := monitorTrigger(http.DefaultClient, cmd.String("access-token"), monitorId)
err := MonitorTrigger(http.DefaultClient, cmd.String("access-token"), monitorId)
if err != nil {
return cli.Exit("Failed to trigger monitor", 1)
}
Expand Down
81 changes: 81 additions & 0 deletions internal/monitors/monitor_trigger_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package monitors_test

import (
"bytes"
"io"
"log"
"net/http"
"os"
"testing"

"github.com/openstatusHQ/cli/internal/monitors"
)

func Test_getMonitorTrigger(t *testing.T) {
t.Parallel()

t.Run("Monitor ID is required", func(t *testing.T) {

interceptor := &interceptorHTTPClient{
f: func(req *http.Request) (*http.Response, error) {
return &http.Response{
StatusCode: http.StatusOK,
}, nil
},
}

var bf bytes.Buffer
log.SetOutput(&bf)
t.Cleanup(func() {
log.SetOutput(os.Stdout)
})
err := monitors.MonitorTrigger(interceptor.GetHTTPClient(), "", "")
if err == nil {
t.Errorf("Expected log output, got nothing")
}
})

t.Run("Successfully return", func(t *testing.T) {
body := `{"resultId": 1}`
r := io.NopCloser(bytes.NewReader([]byte(body)))

interceptor := &interceptorHTTPClient{
f: func(req *http.Request) (*http.Response, error) {
return &http.Response{
StatusCode: http.StatusOK,
Body: r,
}, nil
},
}

var bf bytes.Buffer
log.SetOutput(&bf)
t.Cleanup(func() {
log.SetOutput(os.Stdout)
})
err := monitors.MonitorTrigger(interceptor.GetHTTPClient(), "", "")
if err == nil {
t.Errorf("Expected log output, got nothing")
}
})
t.Run("No 200 throw error", func(t *testing.T) {

interceptor := &interceptorHTTPClient{
f: func(req *http.Request) (*http.Response, error) {
return &http.Response{
StatusCode: http.StatusInternalServerError,
}, nil
},
}

var bf bytes.Buffer
log.SetOutput(&bf)
t.Cleanup(func() {
log.SetOutput(os.Stdout)
})
err := monitors.MonitorTrigger(interceptor.GetHTTPClient(), "1", "1")
if err == nil {
t.Errorf("Expected log output, got nothing")
}
})
}
31 changes: 23 additions & 8 deletions internal/monitors/monitors.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package monitors

import (
"encoding/json"

"github.com/urfave/cli/v3"
)

Expand Down Expand Up @@ -46,14 +48,27 @@ type TriggerResultResponse struct {
}

type RunResult struct {
Headers map[string]string `json:"headers,omitempty"`
Body string `json:"body,omitempty"`
Error string `json:"error,omitempty"`
Region string `json:"region"`
Latency int64 `json:"latency"`
Timestamp int64 `json:"timestamp"`
Status int `json:"status,omitempty"`
Timing Timing `json:"timing"`
JobType string `json:"jobType"`
Region string `json:"region"`
Message json.RawMessage
Timestamp int64 `json:"timestamp"`
Latency int64 `json:"latency"`
}

type HTTPRunResult struct {
Headers map[string]string `json:"headers,omitempty"`
Body string `json:"body,omitempty"`
Error string `json:"error,omitempty"`
Status int `json:"status,omitempty"`
Timing Timing `json:"timing"`
}

type TCPRunResult struct {
ErrorMessge string `json:"errorMessage"`
Timing struct {
TCPStart int64 `json:"tcpStart"`
TCPDone int64 `json:"tcpDone"`
} `json:"timing"`
}

func MonitorsCmd() *cli.Command {
Expand Down
4 changes: 2 additions & 2 deletions internal/monitors/monitors_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (

var allMonitor bool

func listMonitors(httpClient *http.Client, apiKey string) error {
func ListMonitors(httpClient *http.Client, apiKey string) error {
url := "https://api.openstatus.dev/v1/monitor"

req, _ := http.NewRequest("GET", url, nil)
Expand Down Expand Up @@ -72,7 +72,7 @@ func GetMonitorsListCmd() *cli.Command {
},
Action: func(ctx context.Context, cmd *cli.Command) error {
fmt.Println("List of all monitors")
err := listMonitors(http.DefaultClient, cmd.String("access-token"))
err := ListMonitors(http.DefaultClient, cmd.String("access-token"))
if err != nil {
return cli.Exit("Failed to list monitors", 1)
}
Expand Down
Loading

0 comments on commit 5331c89

Please sign in to comment.