Skip to content

Commit

Permalink
Adds two fields to general (strategy and detail)
Browse files Browse the repository at this point in the history
  • Loading branch information
tjayrush committed Jan 23, 2025
1 parent ec27c42 commit bf3d716
Show file tree
Hide file tree
Showing 10 changed files with 105 additions and 34 deletions.
14 changes: 7 additions & 7 deletions app/action_init_general.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,16 +90,16 @@ var generalQ1 = wizard.Question{
// --------------------------------------------------------
var generalQ2 = wizard.Question{
//.....question-|---------|---------|---------|---------|---------|----|65
Question: `Do you want to download only bloom filters or the entire index?`,
Question: `Do you want to download only bloomFilters or the entireIndex?`,
Hint: `Downloading blooms takes less time and is smaller (4gb), but is
|slower when searching. Downloading the entire index takes longer
|and is larger (180gb), but is much faster during search.`,
Value: "entire index",
Value: "entireIndex",
Validate: func(input string, q *wizard.Question) (string, error) {
switch input {
case "bloom filters":
case "bloomFilters":
return input, validOk(q.Messages[0], input)
case "entire index":
case "entireIndex":
return input, validOk(q.Messages[1], input)
default:
return input, fmt.Errorf(q.Messages[2]+"%w", wizard.ErrValidate)
Expand All @@ -108,10 +108,10 @@ var generalQ2 = wizard.Question{
Messages: []string{
`only bloom filters will be downloaded`,
`both bloom filters and index chunks will be downloaded`,
`value must be either "bloom filters" or "entire index"`,
`value must be either "bloomFilters" or "entireIndex"`,
},
Replacements: []wizard.Replacement{
{Color: colors.BrightBlue, Values: []string{"bloom filters", "entire index"}},
{Color: colors.BrightBlue, Values: []string{"bloomFilters", "entireIndex"}},
},
PrepareFn: func(input string, q *wizard.Question) (string, error) {
if q.Screen.Questions[0].Value == "scratch" {
Expand Down Expand Up @@ -146,7 +146,7 @@ var generalQ3 = wizard.Question{
"unable to create folder: %s",
},
PrepareFn: func(input string, q *wizard.Question) (string, error) {
if q.Screen.Questions[2].Value == "bloom filters" {
if q.Screen.Questions[2].Value == "bloomFilters" {
q.Hint = `The bloom filters take up about 5-10gb and the caches may get
|quite large depending on your usage, so choose a folder where you
|can store up to 100gb.`
Expand Down
8 changes: 8 additions & 0 deletions app/config_helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ func TestValidateConfig(t *testing.T) {
cfg := types.NewConfig()
cfg.General = types.General{
DataFolder: "",
Strategy: "download",
Detail: "entireIndex",
}
err := validateConfig(cfg)
assert.Error(t, err)
Expand All @@ -127,6 +129,8 @@ func TestInitializeFolders(t *testing.T) {
},
General: types.General{
DataFolder: "/tmp/test-data-folder",
Strategy: "download",
Detail: "entireIndex",
},
}

Expand All @@ -147,6 +151,8 @@ func TestInitializeFolders(t *testing.T) {
},
General: types.General{
DataFolder: "/tmp/test-missing-data-folder",
Strategy: "download",
Detail: "entireIndex",
},
}

Expand All @@ -171,6 +177,8 @@ func TestInitializeFolders(t *testing.T) {
},
General: types.General{
DataFolder: "/tmp/test-data-folder",
Strategy: "download",
Detail: "entireIndex",
},
}

Expand Down
8 changes: 8 additions & 0 deletions app/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ func TestLoadConfig_ValidConfig(t *testing.T) {
Logging: types.NewLogging(),
General: types.General{
DataFolder: "/tmp/test-data-folder",
Strategy: "scratch",
Detail: "entireIndex",
},
}

Expand Down Expand Up @@ -67,6 +69,7 @@ func TestLoadConfig_EnvOverrides(t *testing.T) {
"TB_KHEDRA_CHAINS_MAINNET_RPCS=http://env.rpc1.mainnet,http://env.rpc2.mainnet",
"TB_KHEDRA_SERVICES_API_PORT=9090",
"TB_KHEDRA_GENERAL_DATAFOLDER=/tmp/env-data-folder",
"TB_KHEDRA_GENERAL_DETAIL=entireIndex",
})()

cfg := types.Config{
Expand All @@ -92,6 +95,8 @@ func TestLoadConfig_EnvOverrides(t *testing.T) {
},
General: types.General{
DataFolder: "/tmp/test-data-folder",
Strategy: "download",
Detail: "bloomFilters",
},
}

Expand All @@ -103,6 +108,7 @@ func TestLoadConfig_EnvOverrides(t *testing.T) {
assert.Equal(t, []string{"http://env.rpc1.mainnet", "http://env.rpc2.mainnet"}, result.Chains["mainnet"].RPCs)
assert.Equal(t, 9090, result.Services["api"].Port)
assert.Equal(t, "/tmp/env-data-folder", result.General.DataFolder)
assert.Equal(t, "entireIndex", result.General.Detail)

os.RemoveAll(cfg.Logging.Folder)
os.RemoveAll(result.General.DataFolder)
Expand Down Expand Up @@ -133,6 +139,8 @@ func TestLoadConfig_ValidationFailure(t *testing.T) {
},
General: types.General{
DataFolder: "",
Strategy: "download",
Detail: "entireIndex",
},
}

Expand Down
14 changes: 7 additions & 7 deletions pkg/types/apply_env.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ const (
PrefixServices = "TB_KHEDRA_SERVICES_"

// General Keys
KeyDataFolder = "TB_KHEDRA_GENERAL_DATAFOLDER"
KeyDownloadStrategy = "TB_KHEDRA_GENERAL_DOWNLOADSTRATEGY"
KeyDownloadDetail = "TB_KHEDRA_GENERAL_DOWNLOADDETAIL"
KeyDataFolder = "TB_KHEDRA_GENERAL_DATAFOLDER"
KeyStrategy = "TB_KHEDRA_GENERAL_STRATEGY"
KeyDetail = "TB_KHEDRA_GENERAL_DETAIL"

// Logging Keys
KeyLoggingFolder = "TB_KHEDRA_LOGGING_FOLDER"
Expand Down Expand Up @@ -146,10 +146,10 @@ func applyEnv(keys []string, receiver *Config) error {
// General settings
case key == KeyDataFolder:
receiver.General.DataFolder = envValue
case key == KeyDownloadStrategy:
receiver.General.DownloadStrategy = envValue
case key == KeyDownloadDetail:
receiver.General.DownloadDetail = envValue
case key == KeyStrategy:
receiver.General.Strategy = envValue
case key == KeyDetail:
receiver.General.Detail = envValue

// Logging settings
case key == KeyLoggingFolder:
Expand Down
6 changes: 6 additions & 0 deletions pkg/types/apply_env_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ func TestApplyEnv(t *testing.T) {
cfg := Config{
General: General{
DataFolder: "/default/data",
Strategy: "download",
Detail: "entireIndex",
},
Chains: map[string]Chain{
"mainnet": {
Expand All @@ -42,6 +44,8 @@ func TestApplyEnv(t *testing.T) {
expected := Config{
General: General{
DataFolder: "/env/data",
Strategy: "download",
Detail: "entireIndex",
},
Chains: map[string]Chain{
"mainnet": {
Expand Down Expand Up @@ -179,6 +183,8 @@ func TestApplyEnv(t *testing.T) {
cfg := Config{
General: General{
DataFolder: "/default/data",
Strategy: "download",
Detail: "entireIndex",
},
Chains: map[string]Chain{
"mainnet": {
Expand Down
2 changes: 2 additions & 0 deletions pkg/types/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ func TestConfigNew(t *testing.T) {

assert.NotNil(t, cfg.General)
assert.Equal(t, expectedDataFolder, cfg.General.DataFolder)
assert.Equal(t, "download", cfg.General.Strategy)
assert.Equal(t, "entireIndex", cfg.General.Detail)

assert.NotNil(t, cfg.Chains)
assert.Equal(t, 1, len(cfg.Chains))
Expand Down
18 changes: 9 additions & 9 deletions pkg/types/general.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@ import (
// General represents configuration for data storage, ensuring the data folder is specified,
// validated for existence, and serialized for YAML-based configuration management.
type General struct {
DataFolder string `koanf:"dataFolder" yaml:"dataFolder" validate:"required,folder_exists"`
DownloadStrategy string `koanf:"downloadStrategy" yaml:"downloadStrategy"`
DownloadDetail string `koanf:"downloadDetail" yaml:"downloadDetail"`
DataFolder string `koanf:"dataFolder" yaml:"dataFolder" validate:"required,folder_exists"`
Strategy string `koanf:"strategy" yaml:"strategy" validate:"oneof=download scratch"`
Detail string `koanf:"detail" yaml:"detail" validate:"oneof=entireIndex bloomFilters"`
}

func NewGeneral() General {
return General{
DataFolder: getDefaultDataFolder(),
DownloadStrategy: getDefaultDownloadStrategy(),
DownloadDetail: getDefaultDownloadDetail(),
DataFolder: getDefaultDataFolder(),
Strategy: getDefaultStrategy(),
Detail: getDefaultDetail(),
}
}

Expand All @@ -29,10 +29,10 @@ func getDefaultDataFolder() string {
return filepath.Join(homeDir, ".khedra", "data")
}

func getDefaultDownloadStrategy() string {
func getDefaultStrategy() string {
return "download"
}

func getDefaultDownloadDetail() string {
return "entire index"
func getDefaultDetail() string {
return "entireIndex"
}
54 changes: 49 additions & 5 deletions pkg/types/general_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func TestNewGeneral(t *testing.T) {
expectedPath := filepath.Join(homeDir, ".khedra", "data")
g := NewGeneral()
assert.Equal(t, expectedPath, g.DataFolder)
}
}

// TestGeneralValidation validates the functionality of the General type to ensure
// that invalid data is caught and proper validation rules are applied.
Expand All @@ -33,30 +33,74 @@ func TestGeneralValidation(t *testing.T) {
wantErr bool
}{
{
name: "Valid General struct",
name: "Valid General struct with all fields",
general: General{
DataFolder: createTempDir(t, true),
Strategy: "scratch",
Detail: "bloomFilters",
},
wantErr: false,
},
{
name: "Non-existent DataFolder",
name: "Non-existent DataFolder with valid strategy and detail",
general: General{
DataFolder: "/non/existent/path",
Strategy: "download",
Detail: "entireIndex",
},
wantErr: false,
},
{
name: "Non-writable DataFolder",
name: "Non-writable DataFolder with valid strategy and detail",
general: General{
DataFolder: createTempDir(t, false),
Strategy: "scratch",
Detail: "bloomFilters",
},
wantErr: false,
},
{
name: "Empty DataFolder",
name: "Empty DataFolder with valid strategy and detail",
general: General{
DataFolder: "",
Strategy: "download",
Detail: "entireIndex",
},
wantErr: true,
},
{
name: "Invalid Strategy",
general: General{
DataFolder: createTempDir(t, true),
Strategy: "invalid_strategy",
Detail: "bloomFilters",
},
wantErr: true,
},
{
name: "Invalid Detail",
general: General{
DataFolder: createTempDir(t, true),
Strategy: "scratch",
Detail: "invalid_detail",
},
wantErr: true,
},
{
name: "Empty Strategy",
general: General{
DataFolder: createTempDir(t, true),
Strategy: "",
Detail: "bloomFilters",
},
wantErr: true,
},
{
name: "Empty Detail",
general: General{
DataFolder: createTempDir(t, true),
Strategy: "scratch",
Detail: "",
},
wantErr: true,
},
Expand Down
12 changes: 6 additions & 6 deletions pkg/types/get_env_keys_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ func TestGetEnvironmentKeys(t *testing.T) {
"TB_KHEDRA_CHAINS_MAINNET_ENABLED",
"TB_KHEDRA_CHAINS_MAINNET_RPCS",
"TB_KHEDRA_GENERAL_DATAFOLDER",
"TB_KHEDRA_GENERAL_DOWNLOADSTRATEGY",
"TB_KHEDRA_GENERAL_DOWNLOADDETAIL",
"TB_KHEDRA_GENERAL_STRATEGY",
"TB_KHEDRA_GENERAL_DETAIL",
"TB_KHEDRA_LOGGING_COMPRESS",
"TB_KHEDRA_LOGGING_FILENAME",
"TB_KHEDRA_LOGGING_FOLDER",
Expand All @@ -43,17 +43,17 @@ func TestGetEnvironmentKeys(t *testing.T) {

testGetEnvKeysInEnv := func(t *testing.T) {
defer setEnv(map[string]string{
"TB_KHEDRA_CHAINS_MAINNET_ENABLED": "false",
"TB_KHEDRA_LOGGING_FILENAME": "\"A filename\"",
"TB_KHEDRA_GENERAL_DOWNLOADSTRATEGY": "scratch",
"TB_KHEDRA_CHAINS_MAINNET_ENABLED": "false",
"TB_KHEDRA_LOGGING_FILENAME": "\"A filename\"",
"TB_KHEDRA_GENERAL_STRATEGY": "scratch",
})()
cfg := NewConfig()
keys := getEnvironmentKeys(cfg, InEnv)
sort.Strings(keys)
assert.ElementsMatch(t, []string{
"TB_KHEDRA_CHAINS_MAINNET_ENABLED",
"TB_KHEDRA_LOGGING_FILENAME",
"TB_KHEDRA_GENERAL_DOWNLOADSTRATEGY",
"TB_KHEDRA_GENERAL_STRATEGY",
}, keys)
}
t.Run("Test getEnv", testGetEnvKeysInEnv)
Expand Down
3 changes: 3 additions & 0 deletions pkg/validate/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package validate
import (
"fmt"
"reflect"

"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/colors"
)

func Validate(input interface{}) error {
Expand All @@ -29,6 +31,7 @@ func Validate(input interface{}) error {
fv.validatorName, fv.tagArg = splitDirective(directive)
fn, ok := validatorRegistry[fv.validatorName]
if !ok {
fmt.Println(colors.Red, "unknown validator", fv.validatorName, colors.Off)
continue
}
if err := fn(fv); err != nil {
Expand Down

0 comments on commit bf3d716

Please sign in to comment.