@@ -292,6 +292,93 @@ func TestSealerBothGasParametersConfig(t *testing.T) {
292292 })
293293}
294294
295+ // TestParseByteSize tests the parseByteSize helper function for parsing
296+ // human-readable byte size strings (e.g., "500KB", "5MB", "1GB").
297+ func TestParseByteSize (t * testing.T ) {
298+ tests := []struct {
299+ name string
300+ input string
301+ expected int64
302+ wantErr bool
303+ }{
304+ // Valid inputs with different suffixes
305+ {"bytes" , "1024B" , 1024 , false },
306+ {"kilobytes" , "500KB" , 500 * 1024 , false },
307+ {"megabytes" , "5MB" , 5 * 1024 * 1024 , false },
308+ {"gigabytes" , "1GB" , 1 * 1024 * 1024 * 1024 , false },
309+
310+ // Case insensitivity
311+ {"lowercase kb" , "500kb" , 500 * 1024 , false },
312+ {"lowercase mb" , "5mb" , 5 * 1024 * 1024 , false },
313+ {"mixed case" , "5Mb" , 5 * 1024 * 1024 , false },
314+
315+ // No suffix (assumes bytes)
316+ {"no suffix" , "1024" , 1024 , false },
317+
318+ // Zero and empty
319+ {"zero string" , "0" , 0 , false },
320+ {"empty string" , "" , 0 , false },
321+
322+ // Whitespace handling
323+ {"leading space" , " 500KB" , 500 * 1024 , false },
324+ {"trailing space" , "500KB " , 500 * 1024 , false },
325+ {"space before suffix" , "500 KB" , 500 * 1024 , false },
326+
327+ // Invalid inputs
328+ {"invalid suffix" , "500XB" , 0 , true },
329+ {"non-numeric" , "abcMB" , 0 , true },
330+ {"float" , "5.5MB" , 0 , true },
331+
332+ // Note: negative values are technically parsed by ParseInt,
333+ // but produce negative results which are invalid for byte sizes.
334+ // The calling code should validate the result is non-negative.
335+ }
336+
337+ for _ , tt := range tests {
338+ t .Run (tt .name , func (t * testing.T ) {
339+ result , err := parseByteSize (tt .input )
340+ if tt .wantErr {
341+ assert .Error (t , err , "expected error for input: %s" , tt .input )
342+ } else {
343+ assert .NoError (t , err , "unexpected error for input: %s" , tt .input )
344+ assert .Equal (t , tt .expected , result , "unexpected result for input: %s" , tt .input )
345+ }
346+ })
347+ }
348+ }
349+
350+ // TestPreloadRateLimitConfig tests the preload rate limit configuration parsing.
351+ func TestPreloadRateLimitConfig (t * testing.T ) {
352+ tests := []struct {
353+ name string
354+ input string
355+ expected int64
356+ }{
357+ {"empty string defaults to 1MB/s" , "" , 1024 * 1024 },
358+ {"explicit 1MB" , "1MB" , 1024 * 1024 },
359+ {"unlimited (0)" , "0" , 0 },
360+ {"invalid falls back to 1MB/s" , "invalid" , 1024 * 1024 },
361+ {"500KB" , "500KB" , 500 * 1024 },
362+ {"2MB" , "2MB" , 2 * 1024 * 1024 },
363+ {"lowercase 100kb" , "100kb" , 100 * 1024 },
364+ {"lowercase 10mb" , "10mb" , 10 * 1024 * 1024 },
365+ }
366+
367+ for _ , tt := range tests {
368+ t .Run (tt .name , func (t * testing.T ) {
369+ config := DefaultConfig ()
370+ config .Cache .PreloadRateLimit = tt .input
371+
372+ assert .NoError (t , config .loadChain ())
373+
374+ ethConfig , err := config .buildEth (nil , nil )
375+ assert .NoError (t , err )
376+
377+ assert .Equal (t , tt .expected , ethConfig .PreloadRateLimit , "input: %s" , tt .input )
378+ })
379+ }
380+ }
381+
295382// TestDeveloperModeGasParameters tests the developer mode specific code path
296383// for setting TargetGasPercentage and BaseFeeChangeDenominator (lines 1293-1304 in config.go).
297384// The default config uses mainnet which has Bor config, so these tests actually execute lines 1293-1304.
0 commit comments