chore: 初始开源发布
iotlcm-sms:独立短信 HTTP/gRPC 服务,支持阿里云与腾讯云。 - Go module 迁移至 git.5iot.com/iotlcm-public/iotlcm-sms - 补 Apache-2.0 LICENSE,重写 README(特性/配置/接口/部署/目录/测试) - 配置改为 config.example.yaml + SMS_* 环境变量注入,仓库不含真实凭证 - 清理内部标识(私有镜像仓库 / 公司名 / 客户签名 / 真实模板ID / 真实手机号) - 统一 LF 行尾并加 .gitattributes
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
package sms
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestLoadDefaultConfig_FileThenEnvOverride(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
path := filepath.Join(dir, "config.yaml")
|
||||
content := "serviceType: \"1\"\nregionId: cn-qingdao\naccessKeyId: file-ak\naccessKeySecret: file-sk\nsignName: 示例签名\n"
|
||||
if err := os.WriteFile(path, []byte(content), 0o600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
t.Setenv("SMS_CONFIG_FILE", path)
|
||||
t.Setenv("SMS_ACCESS_KEY_SECRET", "env-sk")
|
||||
t.Setenv("SMS_ACCESS_KEY_ID", "")
|
||||
t.Setenv("SMS_TEMPLATE_ID", "")
|
||||
|
||||
cfg, source, err := LoadDefaultConfig()
|
||||
if err != nil {
|
||||
t.Fatalf("LoadDefaultConfig: %v", err)
|
||||
}
|
||||
if source.File != path {
|
||||
t.Errorf("source.File = %q, want %q", source.File, path)
|
||||
}
|
||||
if len(source.Env) != 1 || source.Env[0] != "SMS_ACCESS_KEY_SECRET" {
|
||||
t.Errorf("source.Env = %v, want [SMS_ACCESS_KEY_SECRET]", source.Env)
|
||||
}
|
||||
if cfg.AccessKeyID != "file-ak" {
|
||||
t.Errorf("AccessKeyID = %q, want file-ak (文件值应保留)", cfg.AccessKeyID)
|
||||
}
|
||||
if cfg.AccessKeySecret != "env-sk" {
|
||||
t.Errorf("AccessKeySecret = %q, want env-sk (环境变量应覆盖文件值)", cfg.AccessKeySecret)
|
||||
}
|
||||
if cfg.RegionID != "cn-qingdao" {
|
||||
t.Errorf("RegionID = %q, want cn-qingdao", cfg.RegionID)
|
||||
}
|
||||
if cfg.SignName != "示例签名" {
|
||||
t.Errorf("SignName = %q, want 示例签名", cfg.SignName)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadDefaultConfig_NoFile(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
t.Setenv("SMS_CONFIG_FILE", filepath.Join(dir, "missing.yaml"))
|
||||
if _, _, err := LoadDefaultConfig(); err == nil {
|
||||
t.Fatal("显式指定配置文件但缺失时应返回错误")
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadDefaultConfig_RegionDefault(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
path := filepath.Join(dir, "config.yaml")
|
||||
if err := os.WriteFile(path, []byte("signName: 示例签名\n"), 0o600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Setenv("SMS_CONFIG_FILE", path)
|
||||
t.Setenv("SMS_REGION_ID", "")
|
||||
|
||||
cfg, _, err := LoadDefaultConfig()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if cfg.RegionID != "cn-hangzhou" {
|
||||
t.Errorf("RegionID = %q, want cn-hangzhou", cfg.RegionID)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMergeConfig_CallerWinsThenDefault(t *testing.T) {
|
||||
def := Config{ServiceType: "1", RegionID: "cn-hangzhou", AccessKeyID: "ak", SignName: "示例签名"}
|
||||
got := mergeConfig(def, Config{TemplateID: "SMS_298990049"})
|
||||
if got.TemplateID != "SMS_298990049" {
|
||||
t.Errorf("TemplateID = %q, want SMS_298990049", got.TemplateID)
|
||||
}
|
||||
if got.AccessKeyID != "ak" || got.SignName != "示例签名" {
|
||||
t.Errorf("凭证/签名未从默认配置回退: %+v", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadDefaultConfig_RejectsDirectory(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
// 模拟 Docker 在挂载源缺失时自动创建的目录
|
||||
bad := filepath.Join(dir, "config.yaml")
|
||||
if err := os.Mkdir(bad, 0o755); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Setenv("SMS_CONFIG_FILE", bad)
|
||||
if _, _, err := LoadDefaultConfig(); err == nil {
|
||||
t.Fatal("配置文件是目录时应返回错误,避免静默使用空凭证")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user