Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
18 changes: 9 additions & 9 deletions cmd/dataset.go
Original file line number Diff line number Diff line change
Expand Up @@ -363,9 +363,9 @@ var StatDatasetCmd = &cobra.Command{
ingestionCount := stats.Ingestion.Count
ingestionSize := stats.Ingestion.Size
storageSize := stats.Storage.Size
var compressionRatio float64
if ingestionSize > 0 {
compressionRatio = 100 - (float64(storageSize) / float64(ingestionSize) * 100)
compressionRatio := "n/a"
if ingestionSize > 0 && storageSize > 0 {
compressionRatio = fmt.Sprintf("%.2f%%", 100-(float64(storageSize)/float64(ingestionSize)*100))
}

// Fetch retention data
Expand Down Expand Up @@ -394,9 +394,9 @@ var StatDatasetCmd = &cobra.Command{
data := map[string]interface{}{
"info": map[string]interface{}{
"event_count": ingestionCount,
"ingestion_size": humanize.Bytes(uint64(ingestionSize)),
"storage_size": humanize.Bytes(uint64(storageSize)),
"compression_ratio": fmt.Sprintf("%.2f%%", compressionRatio),
"ingestion_size": humanize.IBytes(uint64(ingestionSize)),
"storage_size": humanize.IBytes(uint64(storageSize)),
"compression_ratio": compressionRatio,
},
"retention": retention,
"alerts": nonNilSlice(alertsData.Alerts),
Expand All @@ -415,9 +415,9 @@ var StatDatasetCmd = &cobra.Command{
// Render the info section with consistent alignment
fmt.Println(SelectedStyle.Render("\nInfo:"))
fmt.Printf(" %-18s %d\n", "Event Count:", ingestionCount)
fmt.Printf(" %-18s %s\n", "Ingestion Size:", humanize.Bytes(uint64(ingestionSize)))
fmt.Printf(" %-18s %s\n", "Storage Size:", humanize.Bytes(uint64(storageSize)))
fmt.Printf(" %-18s %.2f%s\n", "Compression Ratio:", compressionRatio, "%")
fmt.Printf(" %-18s %s\n", "Ingestion Size:", humanize.IBytes(uint64(ingestionSize)))
fmt.Printf(" %-18s %s\n", "Storage Size:", humanize.IBytes(uint64(storageSize)))
fmt.Printf(" %-18s %s\n", "Compression Ratio:", compressionRatio)
fmt.Printf(" %-18s %s\n", "Dataset Type:", SelectedStyle.Render(datasetType))
fmt.Println()

Expand Down
96 changes: 96 additions & 0 deletions cmd/dataset_test.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package cmd

import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"net/http/httptest"
"os"
"strings"
"testing"

"github.com/parseablehq/pb/pkg/config"
Expand Down Expand Up @@ -69,3 +74,94 @@ func TestFetchInfoReturnsNotFoundError(t *testing.T) {
t.Fatal("expected not found error")
}
}

func TestDatasetInfoCompressionRatioJSON(t *testing.T) {
for _, test := range []struct {
name string
ingestionSize uint64
storageSize uint64
wantIngestion string
wantStorage string
want string
}{
{name: "storage not reported", ingestionSize: 1400000, wantIngestion: "1.3 MiB", wantStorage: "0 B", want: "n/a"},
{name: "empty dataset", wantIngestion: "0 B", wantStorage: "0 B", want: "n/a"},
{name: "stored data available", ingestionSize: 1000, storageSize: 250, wantIngestion: "1000 B", wantStorage: "250 B", want: "75.00%"},
{name: "GiB sizes", ingestionSize: 2684354560, storageSize: 1610612736, wantIngestion: "2.5 GiB", wantStorage: "1.5 GiB", want: "40.00%"},
} {
t.Run(test.name, func(t *testing.T) {
useDatasetInfoStatsResponse(t, test.ingestionSize, test.storageSize)
if err := StatDatasetCmd.Flags().Set("output", "json"); err != nil {
t.Fatal(err)
}
t.Cleanup(func() { _ = StatDatasetCmd.Flags().Set("output", "") })

var output bytes.Buffer
StatDatasetCmd.SetOut(&output)
t.Cleanup(func() { StatDatasetCmd.SetOut(nil) })
if err := StatDatasetCmd.RunE(StatDatasetCmd, []string{"events"}); err != nil {
t.Fatal(err)
}
var result struct {
Info struct {
CompressionRatio string `json:"compression_ratio"`
IngestionSize string `json:"ingestion_size"`
StorageSize string `json:"storage_size"`
} `json:"info"`
}
if err := json.Unmarshal(output.Bytes(), &result); err != nil {
t.Fatalf("invalid JSON %q: %v", output.String(), err)
}
if result.Info.CompressionRatio != test.want {
t.Fatalf("compression ratio = %q, want %q", result.Info.CompressionRatio, test.want)
}
if result.Info.IngestionSize != test.wantIngestion || result.Info.StorageSize != test.wantStorage {
t.Fatalf("unexpected size display: ingestion=%q, storage=%q", result.Info.IngestionSize, result.Info.StorageSize)
}
})
}
}

func TestDatasetInfoCompressionRatioText(t *testing.T) {
useDatasetInfoStatsResponse(t, 1400000, 0)
reader, writer, err := os.Pipe()
if err != nil {
t.Fatal(err)
}
originalStdout := os.Stdout
os.Stdout = writer
t.Cleanup(func() { os.Stdout = originalStdout })

commandErr := StatDatasetCmd.RunE(StatDatasetCmd, []string{"events"})
_ = writer.Close()
os.Stdout = originalStdout
output, readErr := io.ReadAll(reader)
_ = reader.Close()
if commandErr != nil {
t.Fatal(commandErr)
}
if readErr != nil {
t.Fatal(readErr)
}
if !strings.Contains(string(output), "Compression Ratio: n/a") || !strings.Contains(string(output), "1.3 MiB") {
t.Fatalf("unexpected text output: %q", output)
}
}

func useDatasetInfoStatsResponse(t *testing.T, ingestionSize, storageSize uint64) {
t.Helper()
useCommandTransport(t, func(req *http.Request) (*http.Response, error) {
switch req.URL.Path {
case "/api/v1/logstream/events/info":
return commandHTTPResponse(http.StatusOK, "200 OK", `{"telemetryType":"logs"}`), nil
case "/api/v1/logstream/events/stats":
body := fmt.Sprintf(`{"ingestion":{"count":3740,"size":%d},"storage":{"size":%d}}`, ingestionSize, storageSize)
return commandHTTPResponse(http.StatusOK, "200 OK", body), nil
case "/api/v1/logstream/events/retention", "/api/v1/logstream/events/alert":
return commandHTTPResponse(http.StatusNotFound, "404 Not Found", ""), nil
default:
t.Fatalf("unexpected request path: %s", req.URL.Path)
return nil, nil
}
})
}
Loading