Rename module from template
This commit is contained in:
parent
221afdb9b2
commit
e75a4d4607
8 changed files with 480 additions and 0 deletions
109
polyculeconnect/config/config.go
Normal file
109
polyculeconnect/config/config.go
Normal file
|
@ -0,0 +1,109 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"os"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type ListeningMode int64
|
||||
|
||||
func (lm ListeningMode) String() string {
|
||||
mapping := map[ListeningMode]string{
|
||||
ModeNet: "net",
|
||||
ModeUnix: "unix",
|
||||
}
|
||||
val := mapping[lm]
|
||||
return val
|
||||
}
|
||||
|
||||
func listeningModeFromString(rawVal string) (ListeningMode, error) {
|
||||
mapping := map[string]ListeningMode{
|
||||
"unix": ModeUnix,
|
||||
"net": ModeNet,
|
||||
}
|
||||
if typedVal, ok := mapping[rawVal]; !ok {
|
||||
return ModeNet, fmt.Errorf("invalid listening mode %s", rawVal)
|
||||
} else {
|
||||
return typedVal, nil
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
ModeUnix ListeningMode = iota
|
||||
ModeNet
|
||||
)
|
||||
|
||||
type jsonConf struct {
|
||||
Log struct {
|
||||
Level string `json:"level"`
|
||||
} `json:"log"`
|
||||
Server struct {
|
||||
Host string `json:"host"`
|
||||
Port int `json:"port"`
|
||||
Mode string `json:"mode"`
|
||||
SockPath string `json:"sock"`
|
||||
} `json:"server"`
|
||||
}
|
||||
|
||||
type AppConfig struct {
|
||||
LogLevel logrus.Level
|
||||
ServerMode ListeningMode
|
||||
Host string
|
||||
Port int
|
||||
SockPath string
|
||||
}
|
||||
|
||||
func parseLevel(lvlStr string) logrus.Level {
|
||||
for _, lvl := range logrus.AllLevels {
|
||||
if lvl.String() == lvlStr {
|
||||
return lvl
|
||||
}
|
||||
}
|
||||
return logrus.InfoLevel
|
||||
}
|
||||
|
||||
func (ac *AppConfig) UnmarshalJSON(data []byte) error {
|
||||
var jsonConf jsonConf
|
||||
if err := json.Unmarshal(data, &jsonConf); err != nil {
|
||||
return fmt.Errorf("failed to read JSON: %w", err)
|
||||
}
|
||||
ac.LogLevel = parseLevel(jsonConf.Log.Level)
|
||||
|
||||
lm, err := listeningModeFromString(jsonConf.Server.Mode)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to parse server listening mode: %w", err)
|
||||
}
|
||||
ac.ServerMode = lm
|
||||
ac.SockPath = jsonConf.Server.SockPath
|
||||
ac.Host = jsonConf.Server.Host
|
||||
ac.Port = jsonConf.Server.Port
|
||||
return nil
|
||||
}
|
||||
|
||||
var defaultConfig AppConfig = AppConfig{
|
||||
LogLevel: logrus.InfoLevel,
|
||||
ServerMode: ModeNet,
|
||||
Host: "0.0.0.0",
|
||||
Port: 5000,
|
||||
}
|
||||
|
||||
func New(filepath string) (*AppConfig, error) {
|
||||
content, err := os.ReadFile(filepath)
|
||||
if err != nil {
|
||||
if errors.Is(err, fs.ErrNotExist) {
|
||||
conf := defaultConfig
|
||||
return &conf, nil
|
||||
}
|
||||
return nil, fmt.Errorf("failed to read config file %q: %w", filepath, err)
|
||||
}
|
||||
var conf AppConfig
|
||||
if err := json.Unmarshal(content, &conf); err != nil {
|
||||
return nil, fmt.Errorf("failed to parse config file: %w", err)
|
||||
}
|
||||
return &conf, nil
|
||||
}
|
137
polyculeconnect/config/config_test.go
Normal file
137
polyculeconnect/config/config_test.go
Normal file
|
@ -0,0 +1,137 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path"
|
||||
"testing"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestListeningModeString(t *testing.T) {
|
||||
assert.Equal(t, "net", ModeNet.String(), "Unexpected string value")
|
||||
assert.Equal(t, "unix", ModeUnix.String(), "Unexpected string value")
|
||||
}
|
||||
|
||||
// Test returning a default config when providing a path that does not exist
|
||||
func TestDefault(t *testing.T) {
|
||||
conf, err := New("/this/path/does/not/exist")
|
||||
if assert.Nil(t, err, "Unexpected error") {
|
||||
assert.Equal(t, defaultConfig, *conf, "Unexpected config")
|
||||
}
|
||||
}
|
||||
|
||||
// Test creating a valid config (net mode)
|
||||
func TestOKNet(t *testing.T) {
|
||||
tmpPath := t.TempDir()
|
||||
content := `{
|
||||
"log": {
|
||||
"level": "error"
|
||||
},
|
||||
"server": {
|
||||
"mode": "net",
|
||||
"host": "127.0.0.1",
|
||||
"port": 8888
|
||||
}
|
||||
}`
|
||||
confPath := path.Join(tmpPath, "config.json")
|
||||
require.Nil(t, os.WriteFile(confPath, []byte(content), 0o644), "Failed to write config")
|
||||
|
||||
expectedConf := AppConfig{
|
||||
LogLevel: logrus.ErrorLevel,
|
||||
ServerMode: ModeNet,
|
||||
Host: "127.0.0.1",
|
||||
Port: 8888,
|
||||
}
|
||||
conf, err := New(confPath)
|
||||
if assert.Nil(t, err, "Unexpected error") {
|
||||
assert.Equal(t, expectedConf, *conf, "Unexpected config")
|
||||
}
|
||||
}
|
||||
|
||||
// Test creating a valid config (unix mode)
|
||||
func TestOKUnix(t *testing.T) {
|
||||
tmpPath := t.TempDir()
|
||||
content := `{
|
||||
"log": {
|
||||
"level": "error"
|
||||
},
|
||||
"server": {
|
||||
"mode": "unix",
|
||||
"sock": "/run/toto.sock"
|
||||
}
|
||||
}`
|
||||
confPath := path.Join(tmpPath, "config.json")
|
||||
require.Nil(t, os.WriteFile(confPath, []byte(content), 0o644), "Failed to write config")
|
||||
|
||||
expectedConf := AppConfig{
|
||||
LogLevel: logrus.ErrorLevel,
|
||||
ServerMode: ModeUnix,
|
||||
SockPath: "/run/toto.sock",
|
||||
}
|
||||
conf, err := New(confPath)
|
||||
if assert.Nil(t, err, "Unexpected error") {
|
||||
assert.Equal(t, expectedConf, *conf, "Unexpected config")
|
||||
}
|
||||
}
|
||||
|
||||
// Test creating a valid config, no log level provided, should be info
|
||||
func TestOKNoLogLevel(t *testing.T) {
|
||||
tmpPath := t.TempDir()
|
||||
content := `{
|
||||
"server": {
|
||||
"mode": "net",
|
||||
"host": "127.0.0.1",
|
||||
"port": 8888
|
||||
}
|
||||
}`
|
||||
confPath := path.Join(tmpPath, "config.json")
|
||||
require.Nil(t, os.WriteFile(confPath, []byte(content), 0o644), "Failed to write config")
|
||||
|
||||
expectedConf := AppConfig{
|
||||
LogLevel: logrus.InfoLevel,
|
||||
ServerMode: ModeNet,
|
||||
Host: "127.0.0.1",
|
||||
Port: 8888,
|
||||
}
|
||||
conf, err := New(confPath)
|
||||
if assert.Nil(t, err, "Unexpected error") {
|
||||
assert.Equal(t, expectedConf, *conf, "Unexpected config")
|
||||
}
|
||||
}
|
||||
|
||||
// Test giving an invalid server mode
|
||||
func TestErrMode(t *testing.T) {
|
||||
tmpPath := t.TempDir()
|
||||
content := `{
|
||||
"log": {
|
||||
"level": "error"
|
||||
},
|
||||
"server": {
|
||||
"mode": "toto",
|
||||
"sock": "/run/toto.sock"
|
||||
}
|
||||
}`
|
||||
confPath := path.Join(tmpPath, "config.json")
|
||||
require.Nil(t, os.WriteFile(confPath, []byte(content), 0o644), "Failed to write config")
|
||||
|
||||
_, err := New(confPath)
|
||||
if assert.Error(t, err, "Unexpected nil error") {
|
||||
errMsg := "failed to parse config file: failed to parse server listening mode: invalid listening mode toto"
|
||||
assert.Equal(t, errMsg, err.Error(), "Unexpected error message")
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvalidJSON(t *testing.T) {
|
||||
tmpPath := t.TempDir()
|
||||
content := "toto"
|
||||
confPath := path.Join(tmpPath, "config.json")
|
||||
require.Nil(t, os.WriteFile(confPath, []byte(content), 0o644), "Failed to write config")
|
||||
_, err := New(confPath)
|
||||
if assert.Error(t, err, "Unexpected nil error") {
|
||||
errMsg := "failed to parse config file: invalid character 'o' in literal true (expecting 'r')"
|
||||
assert.Equal(t, errMsg, err.Error(), "Unexpected error message")
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue