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) } }