diff --git a/cmd/objectstore/objectstore_show.go b/cmd/objectstore/objectstore_show.go index 080159b1..77ad1fb9 100644 --- a/cmd/objectstore/objectstore_show.go +++ b/cmd/objectstore/objectstore_show.go @@ -66,7 +66,14 @@ var objectStoreShowCmd = &cobra.Command{ ow.AppendDataWithLabel("region", client.Region, "Region") ow.AppendDataWithLabel("accesskey", creds.AccessKeyID, "Access Key") ow.AppendDataWithLabel("status", objectStore.Status, "Status") - ow.AppendDataWithLabel("stats", fmt.Sprintf("Objects: %d, Size: %s MB, Size Used: %d", stats.NumObjects, strconv.Itoa(objectStore.MaxSize), stats.SizeKBUtilised), "Stats") + sizeUsedBytes := int64(stats.SizeKBUtilised) * 1024 + humanSizeUsed := humanSize(sizeUsedBytes) + + ow.AppendDataWithLabel( + "stats", + fmt.Sprintf("Size: %d GB, Used: %s, Objects: %d", objectStore.MaxSize, humanSizeUsed, stats.NumObjects), + "Stats", + ) switch common.OutputFormat { case "json": @@ -79,3 +86,30 @@ var objectStoreShowCmd = &cobra.Command{ } }, } + +func humanSize(bytes int64) string { + const ( + _ = iota + KB float64 = 1 << (10 * iota) + MB + GB + TB + PB + ) + value := float64(bytes) + + switch { + case value >= PB: + return fmt.Sprintf("%.2f PB", value/PB) + case value >= TB: + return fmt.Sprintf("%.2f TB", value/TB) + case value >= GB: + return fmt.Sprintf("%.2f GB", value/GB) + case value >= MB: + return fmt.Sprintf("%.2f MB", value/MB) + case value >= KB: + return fmt.Sprintf("%.2f KB", value/KB) + default: + return fmt.Sprintf("%d B", bytes) + } +} diff --git a/cmd/objectstore/objectstore_show_test.go b/cmd/objectstore/objectstore_show_test.go new file mode 100644 index 00000000..6267b924 --- /dev/null +++ b/cmd/objectstore/objectstore_show_test.go @@ -0,0 +1,128 @@ +package objectstore + +import ( + "testing" +) + +func TestHumanSize(t *testing.T) { + tests := []struct { + name string + bytes int64 + expected string + }{ + { + name: "Zero bytes", + bytes: 0, + expected: "0 B", + }, + { + name: "Bytes only", + bytes: 512, + expected: "512 B", + }, + { + name: "Exactly 1 KB", + bytes: 1024, + expected: "1.00 KB", + }, + { + name: "Kilobytes", + bytes: 1536, + expected: "1.50 KB", + }, + { + name: "Exactly 1 MB", + bytes: 1024 * 1024, + expected: "1.00 MB", + }, + { + name: "Megabytes", + bytes: 1572864, + expected: "1.50 MB", + }, + { + name: "Exactly 1 GB", + bytes: 1024 * 1024 * 1024, + expected: "1.00 GB", + }, + { + name: "Gigabytes", + bytes: 1610612736, + expected: "1.50 GB", + }, + { + name: "Exactly 1 TB", + bytes: 1024 * 1024 * 1024 * 1024, + expected: "1.00 TB", + }, + { + name: "Terabytes", + bytes: 1649267441664, + expected: "1.50 TB", + }, + { + name: "Exactly 1 PB", + bytes: 1024 * 1024 * 1024 * 1024 * 1024, + expected: "1.00 PB", + }, + { + name: "Petabytes", + bytes: 1688849860263936, + expected: "1.50 PB", + }, + { + name: "Large number with decimals", + bytes: 12356 * 1024, + expected: "12.07 MB", + }, + { + name: "Small KB value", + bytes: 2048, + expected: "2.00 KB", + }, + { + name: "Fractional MB", + bytes: 2621440, + expected: "2.50 MB", + }, + { + name: "Maximum int64 value", + bytes: 9223372036854775807, + expected: "8192.00 PB", + }, + { + name: "Negative value (edge case)", + bytes: -1024, + expected: "-1024 B", + }, + { + name: "Just under 1 KB", + bytes: 1023, + expected: "1023 B", + }, + { + name: "Just over 1 KB", + bytes: 1025, + expected: "1.00 KB", + }, + { + name: "Just under 1 MB", + bytes: 1048575, + expected: "1024.00 KB", + }, + { + name: "Just over 1 MB", + bytes: 1048577, + expected: "1.00 MB", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := humanSize(tt.bytes) + if result != tt.expected { + t.Errorf("humanSize(%d) = %s, want %s", tt.bytes, result, tt.expected) + } + }) + } +} diff --git a/doc/DEVELOPER.md b/doc/DEVELOPER.md index 41e21d64..01c5bb9c 100644 --- a/doc/DEVELOPER.md +++ b/doc/DEVELOPER.md @@ -20,7 +20,6 @@ Currently, all the components are integrated using [Cobra](https://github.com/sp * [Go-homedir](https://github.com/mitchellh/go-homedir) (to get the home of the system user) * [Tablewriter](https://github.com/olekukonko/tablewriter) (the utility to create and generate text based tables in the terminal) * [Go-update](https://github.com/tj/go-update) (it is to be able to auto-update the binary) -* [Go-pluralize](https://github.com/alejandrojnm/go-pluralize) (to pluralize any string based on the number of elements of the slice passed to it) ## Release