mirror of
https://github.com/pgsty/minio.git
synced 2026-09-15 23:14:04 +03:00
7a060cab1e
Keep NVMe/HDD pool pairs useful without remote tiering: promote objects that are read often, demote previously moved objects once they go idle, and leave the feature off until operators set a two-pool topology. Signed-off-by: mr javad seydi <seydi.birjand@gmail.com>
110 lines
3.2 KiB
Go
110 lines
3.2 KiB
Go
// Copyright (c) 2015-2026 MinIO, Inc.
|
|
|
|
package ilm
|
|
|
|
import (
|
|
"errors"
|
|
"reflect"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/minio/minio/internal/config"
|
|
)
|
|
|
|
func clearAccessEnv(t *testing.T) {
|
|
t.Helper()
|
|
for _, name := range []string{
|
|
EnvILMAccessTiering, EnvILMAccessPools, EnvILMAccessMaxSize,
|
|
EnvILMAccessPromoteWatermark, EnvILMAccessBinWidth, EnvILMAccessBins,
|
|
EnvILMAccessFlush, EnvILMAccessMinResidency, EnvILMAccessWorkers,
|
|
EnvILMAccessMaxTracked,
|
|
} {
|
|
// The env helper treats an empty value as unset. t.Setenv restores the
|
|
// caller's exact value automatically when the test finishes.
|
|
t.Setenv(name, "")
|
|
}
|
|
}
|
|
|
|
func TestLookupAccessDefaults(t *testing.T) {
|
|
clearAccessEnv(t)
|
|
cfg, err := LookupConfig(DefaultKVS.Clone())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if cfg.AccessTiering {
|
|
t.Fatal("access tiering must default off")
|
|
}
|
|
if cfg.AccessBinWidth != time.Minute || cfg.AccessBins != 12 || cfg.AccessFlush != time.Minute {
|
|
t.Fatalf("unexpected counter defaults: width=%s bins=%d flush=%s", cfg.AccessBinWidth, cfg.AccessBins, cfg.AccessFlush)
|
|
}
|
|
if cfg.AccessWorkers != 10 || cfg.AccessMaxTracked != 1000000 {
|
|
t.Fatalf("unexpected worker/map defaults: %d/%d", cfg.AccessWorkers, cfg.AccessMaxTracked)
|
|
}
|
|
}
|
|
|
|
func TestLookupAccessEnabled(t *testing.T) {
|
|
clearAccessEnv(t)
|
|
kvs := DefaultKVS.Clone()
|
|
kvs.Set(accessTiering, config.EnableOn)
|
|
kvs.Set(accessPools, "2, 0, 1")
|
|
kvs.Set(accessMaxSize, "2GiB")
|
|
kvs.Set(accessPromoteWatermark, "90")
|
|
kvs.Set(accessBinWidth, "30s")
|
|
kvs.Set(accessBins, "20")
|
|
kvs.Set(accessFlush, "15s")
|
|
kvs.Set(accessMinResidency, "2h")
|
|
kvs.Set(accessWorkers, "7")
|
|
kvs.Set(accessMaxTracked, "1234")
|
|
|
|
cfg, err := LookupConfig(kvs)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !cfg.AccessTiering || !reflect.DeepEqual(cfg.AccessPools, []int{2, 0, 1}) {
|
|
t.Fatalf("unexpected topology: enabled=%v pools=%v", cfg.AccessTiering, cfg.AccessPools)
|
|
}
|
|
if cfg.AccessMaxSize != 2<<30 || cfg.HistoryWindow() != 10*time.Minute {
|
|
t.Fatalf("unexpected size/history: %d/%s", cfg.AccessMaxSize, cfg.HistoryWindow())
|
|
}
|
|
if hot, ok := cfg.HotPool(); !ok || hot != 2 {
|
|
t.Fatalf("HotPool = %d/%v", hot, ok)
|
|
}
|
|
if cold, ok := cfg.ColdPool(); !ok || cold != 1 {
|
|
t.Fatalf("ColdPool = %d/%v", cold, ok)
|
|
}
|
|
}
|
|
|
|
func TestLookupAccessRejectsInvalidValues(t *testing.T) {
|
|
clearAccessEnv(t)
|
|
tests := []struct {
|
|
key, value string
|
|
want error
|
|
}{
|
|
{accessPools, "0,0", ErrAccessPoolsInvalid},
|
|
{accessPromoteWatermark, "0", ErrAccessWatermarkInvalid},
|
|
{accessBinWidth, "500ms", ErrAccessBinWidthInvalid},
|
|
{accessBins, "1", ErrAccessBinsInvalid},
|
|
{accessFlush, "0s", ErrAccessFlushInvalid},
|
|
{accessMinResidency, "-1s", ErrAccessResidencyInvalid},
|
|
{accessWorkers, "0", ErrAccessWorkersInvalid},
|
|
{accessMaxTracked, "0", ErrAccessTrackedInvalid},
|
|
}
|
|
for _, tc := range tests {
|
|
t.Run(tc.key, func(t *testing.T) {
|
|
kvs := DefaultKVS.Clone()
|
|
kvs.Set(tc.key, tc.value)
|
|
_, err := LookupConfig(kvs)
|
|
if !errors.Is(err, tc.want) {
|
|
t.Fatalf("error = %v, want %v", err, tc.want)
|
|
}
|
|
})
|
|
}
|
|
|
|
kvs := DefaultKVS.Clone()
|
|
kvs.Set(accessTiering, config.EnableOn)
|
|
kvs.Set(accessPools, "0")
|
|
if _, err := LookupConfig(kvs); !errors.Is(err, ErrAccessPoolsTooFew) {
|
|
t.Fatalf("error = %v, want %v", err, ErrAccessPoolsTooFew)
|
|
}
|
|
}
|