Name the setting and value when a size does not parse (closes #429)
check / check (push) Successful in 12m50s
check / check (push) Successful in 12m50s
A size setting such as chunk_size: banana failed with "invalid size
format: strconv.ParseFloat: parsing "": invalid syntax", naming neither
the setting nor the value. The size decoder now quotes the value, and
Parse checks every size setting after ${...} references are filled in,
so the error reads chunk_size: "banana" is not a size; use a number of
bytes or a unit such as 10MB. This covers chunk_size, blob_size_limit
and s3.part_size, and config set. A value too large for a size, such as
100EB or 99999999999999999999, fails as too large, naming the setting.
Model: opus-5-5
This commit is contained in:
1 parent
f6df500ba2
commit
c9f3667757
5 files changed
+214
-20
No files matched your search
@@ -0,0 +1,120 @@
|
||||
package config //nolint:testpackage // checks errNotASize and errSizeTooLarge
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// TestParseRefusesValueThatIsNotASize checks that a size setting whose
|
||||
// value is not a size fails the parse with an error naming the setting and
|
||||
// quoting the value, also when a ${...} reference fills the value in.
|
||||
func TestParseRefusesValueThatIsNotASize(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
sizePath := filepath.Join(t.TempDir(), "size")
|
||||
|
||||
err := os.WriteFile(sizePath, []byte("lots"), 0o600)
|
||||
if err != nil {
|
||||
t.Fatalf("write size: %v", err)
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
yaml string
|
||||
want string
|
||||
}{
|
||||
{"chunk_size", keysTestConfig + "chunk_size: banana\n",
|
||||
`chunk_size: "banana" is not a size; ` +
|
||||
"use a number of bytes or a unit such as 10MB"},
|
||||
{"blob_size_limit", keysTestConfig + "blob_size_limit: 10XB\n",
|
||||
`blob_size_limit: "10XB" is not a size; ` +
|
||||
"use a number of bytes or a unit such as 10MB"},
|
||||
{"s3.part_size", strings.Replace(keysTestConfig, " region:",
|
||||
" part_size: big\n region:", 1),
|
||||
`s3.part_size: "big" is not a size; ` +
|
||||
"use a number of bytes or a unit such as 10MB"},
|
||||
{"from a reference",
|
||||
keysTestConfig + "chunk_size: ${FILE:" + sizePath + "}\n",
|
||||
`chunk_size: "lots" is not a size; ` +
|
||||
"use a number of bytes or a unit such as 10MB"},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
_, err := Parse([]byte(tt.yaml))
|
||||
if !errors.Is(err, errNotASize) {
|
||||
t.Fatalf("Parse() error = %v, want errNotASize", err)
|
||||
}
|
||||
|
||||
if err.Error() != tt.want {
|
||||
t.Errorf("Parse() error = %q, want %q", err.Error(), tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestParseRefusesSizeTooLarge checks that a size setting whose value is
|
||||
// too large for a size fails the parse with an error naming the setting.
|
||||
// YAML reads the second value as a float.
|
||||
func TestParseRefusesSizeTooLarge(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
value string
|
||||
want string
|
||||
}{
|
||||
{"100EB", "chunk_size: size exceeds maximum supported value: 100EB"},
|
||||
{"99999999999999999999",
|
||||
"chunk_size: size exceeds maximum supported value"},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.value, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
_, err := Parse([]byte(keysTestConfig + "chunk_size: " + tt.value + "\n"))
|
||||
if !errors.Is(err, errSizeTooLarge) {
|
||||
t.Fatalf("Parse() error = %v, want errSizeTooLarge", err)
|
||||
}
|
||||
|
||||
if err.Error() != tt.want {
|
||||
t.Errorf("Parse() error = %q, want %q", err.Error(), tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestParseAcceptsSizes checks that size settings given as a number of
|
||||
// bytes, as a unit, and through a ${...} reference still parse.
|
||||
func TestParseAcceptsSizes(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
sizePath := filepath.Join(t.TempDir(), "size")
|
||||
|
||||
err := os.WriteFile(sizePath, []byte("20MB"), 0o600)
|
||||
if err != nil {
|
||||
t.Fatalf("write size: %v", err)
|
||||
}
|
||||
|
||||
data := strings.Replace(keysTestConfig, " region:",
|
||||
" part_size: 6000000\n region:", 1) +
|
||||
"chunk_size: ${FILE:" + sizePath + "}\n" +
|
||||
"blob_size_limit: 1GB\n"
|
||||
|
||||
cfg, err := Parse([]byte(data))
|
||||
if err != nil {
|
||||
t.Fatalf("Parse() unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if cfg.ChunkSize != 20_000_000 || cfg.BlobSizeLimit != 1_000_000_000 ||
|
||||
cfg.S3.PartSize != 6_000_000 {
|
||||
t.Errorf("chunk_size, blob_size_limit, s3.part_size = %d, %d, %d, "+
|
||||
"want 20000000, 1000000000, 6000000",
|
||||
cfg.ChunkSize, cfg.BlobSizeLimit, cfg.S3.PartSize)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user