-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
650abca
commit 392332c
Showing
2 changed files
with
151 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
package config | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"io/ioutil" | ||
"log" | ||
"os" | ||
) | ||
|
||
// Config represents the configuration of the K-V database. | ||
type Config struct { | ||
Addr string `json:"addr"` | ||
LogLevel string `json:"log_level"` | ||
StoreCapacity int `json:"store_capacity"` | ||
StoreEngine string `json:"store_engine"` | ||
StorePath string `json:"store_path"` | ||
} | ||
|
||
// DefaultConfig returns the default configuration. | ||
func DefaultConfig() *Config { | ||
return &Config{ | ||
Addr: ":8080", | ||
LogLevel: "info", | ||
StoreCapacity: 1000000, | ||
StoreEngine: "memory", | ||
StorePath: "./store", | ||
} | ||
} | ||
|
||
// LoadConfig loads the configuration from a file. | ||
func LoadConfig(filename string) (*Config, error) { | ||
data, err := ioutil.ReadFile(filename) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
var config Config | ||
if err := json.Unmarshal(data, &config); err != nil { | ||
return nil, err | ||
} | ||
|
||
return &config, nil | ||
} | ||
|
||
// SaveConfig saves the configuration to a file. | ||
func SaveConfig(filename string, config *Config) error { | ||
data, err := json.MarshalIndent(config, "", " ") | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return ioutil.WriteFile(filename, data, 0644) | ||
} | ||
|
||
// ValidateConfig validates the configuration. | ||
func ValidateConfig(config *Config) error { | ||
if config.Addr == "" { | ||
return fmt.Errorf("addr is required") | ||
} | ||
|
||
if config.LogLevel != "debug" && config.LogLevel != "info" && config.LogLevel != "warn" && config.LogLevel != "error" { | ||
return fmt.Errorf("invalid log level: %s", config.LogLevel) | ||
} | ||
|
||
if config.StoreCapacity <= 0 { | ||
return fmt.Errorf("store capacity must be greater than 0") | ||
} | ||
|
||
if config.StoreEngine != "memory" && config.StoreEngine != "disk" { | ||
return fmt.Errorf("invalid store engine: %s", config.StoreEngine) | ||
} | ||
|
||
if config.StorePath == "" { | ||
return fmt.Errorf("store path is required") | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
package config | ||
|
||
import ( | ||
"testing" | ||
) | ||
|
||
func TestDefaultConfig(t *testing.T) { | ||
config := DefaultConfig() | ||
if config.Addr != ":8080" { | ||
t.Errorf("expected addr to be :8080, but got %s", config.Addr) | ||
} | ||
if config.LogLevel != "info" { | ||
t.Errorf("expected log level to be info, but got %s", config.LogLevel) | ||
} | ||
if config.StoreCapacity != 1000000 { | ||
t.Errorf("expected store capacity to be 1000000, but got %d", config.StoreCapacity) | ||
} | ||
if config.StoreEngine != "memory" { | ||
t.Errorf("expected store engine to be memory, but got %s", config.StoreEngine) | ||
} | ||
if config.StorePath != "./store" { | ||
t.Errorf("expected store path to be ./store, but got %s", config.StorePath) | ||
} | ||
} | ||
|
||
func TestLoadConfig(t *testing.T) { | ||
filename := "test_config.json" | ||
config := &Config{ | ||
Addr: ":8081", | ||
LogLevel: "debug", | ||
StoreCapacity: 500000, | ||
StoreEngine: "disk", | ||
StorePath: "./test_store", | ||
} | ||
if err := SaveConfig(filename, config); err != nil { | ||
t.Fatal(err) | ||
} | ||
defer os.Remove(filename) | ||
|
||
loadedConfig, err := LoadConfig(filename) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
if loadedConfig.Addr != config.Addr { | ||
t.Errorf("expected addr to be %s, but got %s", config.Addr, loadedConfig.Addr) | ||
} | ||
if loadedConfig.LogLevel != config.LogLevel { | ||
t.Errorf("expected log level to be %s, but got %s", config.LogLevel, loadedConfig.LogLevel) | ||
} | ||
if loadedConfig.StoreCapacity != config.StoreCapacity { | ||
t.Errorf("expected store capacity to be %d, but got %d", config.StoreCapacity, loadedConfig.StoreCapacity) | ||
} | ||
if loadedConfig.StoreEngine != config.StoreEngine { | ||
t.Errorf("expected store engine to be %s, but got %s", config.StoreEngine, loadedConfig.StoreEngine) | ||
} | ||
if loadedConfig.StorePath != config.StorePath { | ||
t.Errorf("expected store path to be %s, but got %s", config.StorePath, loadedConfig.StorePath) | ||
} | ||
} | ||
|
||
func TestValidateConfig(t *testing.T) { | ||
config := &Config{ | ||
Addr: "", | ||
LogLevel: "invalid", | ||
StoreCapacity: 0, | ||
StoreEngine: "invalid", | ||
StorePath: "", | ||
} | ||
if err := ValidateConfig(config); err == nil { | ||
t.Errorf("expected validation to fail, but got no error") | ||
} | ||
} |