diff --git a/internal/client/config/config.go b/internal/client/config/config.go index 5abf7bf..106cad3 100644 --- a/internal/client/config/config.go +++ b/internal/client/config/config.go @@ -4,6 +4,7 @@ import ( "fmt" "os" "path/filepath" + "sync" "gopkg.in/yaml.v3" ) @@ -15,21 +16,32 @@ const ( defaultServerAddress = "127.0.0.1:50051" ) +var flags Flags +var once sync.Once + func GetConfig() (Config, error) { var fileCfg Config + once.Do(func() { + flags = parseFlags() + }) - flags := parseFlags() configPath := flags.ConfigPath if configPath == "" { configPath = defaultConfigPath } - if _, err := os.Stat(configPath); !os.IsNotExist(err) { - if err = parseConfig(configPath, &fileCfg); err != nil { - fmt.Print("failed read yaml config file: ", err.Error()) + if _, err := os.Stat(configPath); os.IsNotExist(err) { + // Возвращаем ошибку, если файл конфигурации не существует + return Config{}, fmt.Errorf("config file not found: %s", configPath) + } else if err != nil { + // Возвращаем ошибку, если есть другая ошибка при проверке файла + return Config{}, fmt.Errorf("failed to check config file: %w", err) + } - return Config{}, err - } + // Попытка парсинга файла конфигурации + if err := parseConfig(configPath, &fileCfg); err != nil { + fmt.Printf("failed to read yaml config file: %v\n", err) + return Config{}, err } return setConfig(fileCfg, flags), nil diff --git a/internal/client/config/config_internal_test.go b/internal/client/config/config_internal_test.go new file mode 100644 index 0000000..0f85909 --- /dev/null +++ b/internal/client/config/config_internal_test.go @@ -0,0 +1,73 @@ +package config + +import ( + "os" + "path/filepath" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestParseConfig(t *testing.T) { + tempDir := t.TempDir() + configPath := filepath.Join(tempDir, "config.yaml") + validYAMLContent := []byte(` +storage_path: "./data" +upload_path: "./upload" +server_address: "127.0.0.1:50051" +`) + invalidYAMLContent := []byte(` +storage_path: ["./data"] +`) + //nolint:gosec + require.NoError(t, os.WriteFile(configPath, validYAMLContent, 0644)) + + tests := []struct { + name string + filePath string + expectedCfg Config + expectError bool + }{ + { + name: "Valid config file", + filePath: configPath, + expectedCfg: Config{StoragePath: "./data", UploadPath: "./upload", ServerAddress: "127.0.0.1:50051"}, + expectError: false, + }, + { + name: "Invalid path", + filePath: string([]byte{0x7f}), + expectedCfg: Config{}, + expectError: true, + }, + { + name: "Non-existing file", + filePath: filepath.Join(tempDir, "non-existing.yaml"), + expectedCfg: Config{}, + expectError: true, + }, + { + name: "Invalid YAML content", + filePath: "", + expectedCfg: Config{}, + expectError: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var cfg Config + err := parseConfig(tt.filePath, &cfg) + + if tt.expectError { + require.Error(t, err) + } else { + require.NoError(t, err) + require.Equal(t, tt.expectedCfg, cfg) + } + }) + } + + //nolint:gosec + require.NoError(t, os.WriteFile(configPath, invalidYAMLContent, 0644)) +} diff --git a/internal/client/config/config_test.go b/internal/client/config/config_test.go index 747a3e7..a31dfb6 100644 --- a/internal/client/config/config_test.go +++ b/internal/client/config/config_test.go @@ -6,43 +6,101 @@ import ( "testing" "github.com/kripsy/GophKeeper/internal/client/config" + "github.com/stretchr/testify/assert" ) -func TestGetConfig1(t *testing.T) { +func TestGetConfig(t *testing.T) { + // Предыдущая часть с созданием временного файла остается без изменений oldArgs := os.Args + defer func() { os.Args = oldArgs }() // Восстанавливаем исходное значение после теста + + // Создаем временный файл конфигурации + tempConfigFile, err := os.CreateTemp("", "config.yaml") + if err != nil { + t.Fatalf("Cannot create temp config file: %v", err) + } + defer os.Remove(tempConfigFile.Name()) // Удаляем временный файл после теста + + // Записываем валидный YAML в файл + yamlContent := []byte(` +storage_path: "./1keeper/Data" +upload_path: "./1keeper/Upload" +server_address: "127.0.0.1:50051" +`) + if _, err := tempConfigFile.Write(yamlContent); err != nil { + t.Fatalf("Cannot write to temp config file: %v", err) + } + tempConfigFile.Close() // Закрываем файл после записи + tests := []struct { - name string - args []string - want config.Config - wantErr bool + name string + configFile string // Добавляем поле для конфигурации пути файла + configFileData []byte // Данные для записи в файл конфигурации + args []string + want config.Config + wantErr bool }{ { - name: "ok with flag", - args: append(oldArgs, - "", - "-cfg-path", "/config.yaml", - "-storage-path", "/path/to/storage", - "-upload-path", "/path/to/uploads", - "-server-addr", "127.0.0.1:8080"), + name: "ok with valid yaml", + configFile: tempConfigFile.Name(), + configFileData: []byte(` +storage_path: "./path/to/storage" +upload_path: "./path/to/uploads" +server_address: "127.0.0.1:8080" +`), + args: append([]string{os.Args[0]}, + "-cfg-path", tempConfigFile.Name()), want: config.Config{ - StoragePath: "./1keeper/Data", - UploadPath: "./1keeper/Upload", - ServerAddress: "127.0.0.1:50051", + StoragePath: "./path/to/storage", + UploadPath: "./path/to/uploads", + ServerAddress: "127.0.0.1:8080", }, wantErr: false, }, + { + name: "error with invalid yaml", + configFile: tempConfigFile.Name(), + configFileData: []byte(`invalid_yaml`), + args: append([]string{os.Args[0]}, "-cfg-path", tempConfigFile.Name()), + want: config.Config{}, + wantErr: true, + }, + { + name: "error with non-existing config path", + configFile: "non-existing-path.yaml", + configFileData: []byte(` +storage_path: "./path/to/storage" +upload_path: "./path/to/uploads" +server_address: "127.0.0.1:8080" +`), + args: append([]string{os.Args[0]}, "-cfg-path", "non-existing-path.yaml"), + want: config.Config{}, + wantErr: true, + }, } + for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { + // Если указаны данные конфигурации, записываем их в файл + if len(tt.configFileData) > 0 { + if err := os.WriteFile(tt.configFile, tt.configFileData, 0644); err != nil { + t.Fatalf("Failed to write to config file: %v", err) + } + } + os.Args = tt.args got, err := config.GetConfig() - if (err != nil) != tt.wantErr { - t.Errorf("GetConfig() error = %v, wantErr %v", err, tt.wantErr) - return + if !tt.wantErr { + assert.Equal(t, true, reflect.DeepEqual(tt.want, got)) + assert.NoError(t, err) + } else { + assert.Error(t, err) } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("GetConfig() got = %v, want %v", got, tt.want) + + // Очищаем файл конфигурации после каждого теста + if len(tt.configFileData) > 0 { + os.Remove(tt.configFile) } }) }