package iot import ( "context" _ "github.com/gogf/gf/contrib/drivers/mysql/v2" _ "github.com/gogf/gf/contrib/drivers/sqlite/v2" "github.com/gogf/gf/v2/database/gdb" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/os/gcfg" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/consts" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/library/contexts" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/model" "os" "testing" "time" ) func TestLegacyDiagnoseFallback(t *testing.T) { ctx := context.Background() previous := gdb.GetConfig("default") previousLegacy := gdb.GetConfig("legacyCard") adapter := g.Cfg().GetAdapter() cfg, err := gcfg.NewAdapterContent(`{"database":{"legacyCard":{"link":"sqlite::@file(:memory:)"}}}`) if err != nil { t.Fatal(err) } g.Cfg().SetAdapter(cfg) for _, group := range []string{"default", "legacyCard"} { if err := gdb.SetConfigGroup(group, gdb.ConfigGroup{{Type: "sqlite", Link: "sqlite::@file(:memory:)", MaxOpenConnCount: 1}}); err != nil { t.Fatal(err) } } t.Cleanup(func() { _ = g.DB().Close(ctx) _ = g.DB("legacyCard").Close(ctx) _ = gdb.SetConfigGroup("default", previous) _ = gdb.SetConfigGroup("legacyCard", previousLegacy) g.Cfg().SetAdapter(adapter) }) for _, sql := range []string{ "CREATE TABLE yz_card_info(iccid TEXT, imsi TEXT, msisdn TEXT, channel_id TEXT)", "CREATE TABLE yz_card_route(cd_id TEXT)", "INSERT INTO yz_card_route VALUES ('77')", "INSERT INTO yz_card_info VALUES ('898607B91923C0327236','imsi','phone','77')", } { if _, err := g.DB("legacyCard").Exec(ctx, sql); err != nil { t.Fatal(err) } } for _, sql := range []string{ "CREATE TABLE t_sim_card_info(iccid TEXT, imsi TEXT, msisdn TEXT, tenant_id TEXT)", "CREATE TABLE t_sim_channels(chan_key TEXT,temp_key TEXT,chan_status INTEGER,tenant_id TEXT,created_by INTEGER,created_dept INTEGER)", "INSERT INTO t_sim_channels VALUES ('77','sim_yunda_v1',0,'A',7,10)", } { if _, err := g.DB().Exec(ctx, sql); err != nil { t.Fatal(err) } } principal := &model.Identity{BaseClaims: model.BaseClaims{ID: 7, TenantId: "A", DeptId: 10, Roles: []model.Role{{RoleId: 9, DataScope: consts.SysRoleDataScopePersonal}}}} scopeCtx := contexts.Set(ctx, &model.Context{User: principal}) for _, code := range []string{"898607B91923C0327236", "imsi", "phone"} { card, err := resolveLegacyDiagnoseCardInfo(scopeCtx, code) if err != nil || card == nil || card.ChanKey != "77" || card.HasLocalCard { t.Fatalf("card=%+v err=%v", card, err) } } if _, err := resolveLegacyDiagnoseCardInfo(ctx, "phone"); err == nil { t.Fatal("guest allowed") } principal.TenantId = "B" if _, err := resolveLegacyDiagnoseCardInfo(scopeCtx, "phone"); err == nil { t.Fatal("cross tenant channel allowed") } principal.TenantId = "A" principal.ID = 8 if _, err := resolveLegacyDiagnoseCardInfo(scopeCtx, "phone"); err == nil { t.Fatal("foreign channel allowed") } principal.ID = 7 if _, err := g.DB().Exec(ctx, "UPDATE t_sim_channels SET chan_status=1"); err != nil { t.Fatal(err) } if _, err := resolveLegacyDiagnoseCardInfo(scopeCtx, "phone"); err == nil { t.Fatal("disabled channel allowed") } if _, err := g.DB().Exec(ctx, "INSERT INTO t_sim_card_info VALUES ('898607B91923C0327236','imsi','phone','A')"); err != nil { t.Fatal(err) } if _, err := resolveLegacyDiagnoseCardInfo(scopeCtx, "phone"); err == nil { t.Fatal("local visibility bypassed") } if _, err := g.DB("legacyCard").Exec(ctx, "INSERT INTO yz_card_info VALUES ('duplicate','','phone','77')"); err != nil { t.Fatal(err) } if _, err := queryLegacyDiagnoseCard(ctx, "phone"); err == nil { t.Fatal("ambiguous card accepted") } missing, err := queryLegacyDiagnoseCard(ctx, "missing") if err != nil || missing != nil { t.Fatalf("missing=%+v err=%v", missing, err) } } func TestLegacyDiagnoseReadOnlyIntegration(t *testing.T) { configPath := os.Getenv("IOTLCM_LEGACY_DIAGNOSIS_CONFIG") if configPath == "" { t.Skip("未启用真实旧库只读测试") } content, err := os.ReadFile(configPath) if err != nil { t.Fatal("无法读取测试环境配置") } adapter, err := gcfg.NewAdapterContent(string(content)) if err != nil { t.Fatal("环境配置格式无效") } previous := g.Cfg().GetAdapter() g.Cfg().SetAdapter(adapter) t.Cleanup(func() { g.Cfg().SetAdapter(previous) }) ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second) defer cancel() card, err := queryLegacyDiagnoseCard(ctx, "898607B91923C0327236") if err != nil { t.Fatal(err) } if card == nil { t.Fatal("真实旧库未查到卡及路由映射") } t.Logf("旧库实际命中 ICCID=%s channelKey=%s IMSI存在=%t MSISDN存在=%t", card.ICCID, card.ChannelKey, card.IMSI != "", card.MSISDN != "") }