Files
iotlcm/upstream-proxy/internal/logic/upstreamimpl/apn_http_test.go
T

118 lines
4.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package upstreamimpl
import (
"bytes"
"encoding/json"
"net/http"
"net/http/httptest"
"strings"
"testing"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
"github.com/gogf/gf/v2/os/gcfg"
"git.5iot.com/iotlcm-public/iotlcm-upstream-proxy/internal/logic/upstreamapi"
"git.5iot.com/iotlcm-public/iotlcm-upstream-proxy/internal/model"
)
func TestAPNProxyHTTPFailureIsUncertainOnlyOnAPNRoute(t *testing.T) {
oldAdapter := g.Cfg().GetAdapter()
defer g.Cfg().SetAdapter(oldAdapter)
for _, tc := range []struct {
name, path, body string
disconnect, uncertain bool
}{
{"HTTP200顶层9999", "/sim/change/sim-apn", `{"code":9999,"message":"模拟网关未确认"}`, false, true},
{"通道连接断开", "/sim/change/sim-apn", "", true, true},
{"非APN同名字段", "/sim/change/sim-status", `{"code":9999,"message":"模拟非APN网关错误"}`, false, false},
} {
t.Run(tc.name, func(t *testing.T) {
chanServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if tc.disconnect {
conn, _, err := w.(http.Hijacker).Hijack()
if err != nil {
t.Error(err)
return
}
_ = conn.Close()
return
}
_, _ = w.Write([]byte(tc.body))
}))
defer chanServer.Close()
adapter, err := gcfg.NewAdapterContent(`{"gateway":{"address":"` + strings.TrimPrefix(chanServer.URL, "http://") + `","timeout":"1s"}}`)
if err != nil {
t.Fatal(err)
}
g.Cfg().SetAdapter(adapter)
api := upstreamapi.NewUpstreamAPI()
api.RegisterChan("fake-channel", "test", &model.SimCardChannelCache{Instance: &sSimYD{}})
proxy := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
var input model.SimBaseReqJson
if err := json.NewDecoder(r.Body).Decode(&input); err != nil {
t.Error(err)
return
}
ctx := (&ghttp.Request{Request: r}).Context()
items, err := api.SimBase(ctx, &input)
if err != nil {
t.Error(err)
return
}
_ = json.NewEncoder(w).Encode(map[string]any{"code": 0, "data": items})
}))
defer proxy.Close()
body := []byte(`{"simKeys":[{"chanKey":"fake-channel","iccid":"fake-card"}],"reqData":{"operationId":"fake-operation","submitOnly":true}}`)
response, err := http.Post(proxy.URL+tc.path, "application/json", bytes.NewReader(body))
if err != nil {
t.Fatal(err)
}
defer response.Body.Close()
var output struct {
Code int `json:"code"`
Data model.SimBaseResJson `json:"data"`
}
if err := json.NewDecoder(response.Body).Decode(&output); err != nil {
t.Fatal(err)
}
if response.StatusCode != 200 || output.Code != 0 || len(output.Data) != 1 || output.Data[0].Code != 9999 || output.Data[0].Message == "" {
t.Fatalf("代理异常响应无效:HTTP=%d result=%+v", response.StatusCode, output)
}
isUncertain := strings.Contains(string(output.Data[0].ResData), `"uncertain":true`)
if isUncertain != tc.uncertain {
t.Fatalf("APN路由隔离失效:%s", output.Data[0].ResData)
}
})
}
}
func TestAPNProxyHTTPKeepsDurableJobAndFrozenRequest(t *testing.T) {
oldAdapter := g.Cfg().GetAdapter()
defer g.Cfg().SetAdapter(oldAdapter)
var captured model.SimBaseReqJson
chanServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if err := json.NewDecoder(r.Body).Decode(&captured); err != nil {
t.Error(err)
return
}
_, _ = w.Write([]byte(`{"code":0,"data":[{"code":0,"simKey":{"chanKey":"fake-channel","iccid":"fake-card","msisdn":"frozen-number"},"resData":{"orderNum":"saved-job","pending":true}}]}`))
}))
defer chanServer.Close()
adapter, err := gcfg.NewAdapterContent(`{"gateway":{"address":"` + strings.TrimPrefix(chanServer.URL, "http://") + `","timeout":"1s"}}`)
if err != nil {
t.Fatal(err)
}
g.Cfg().SetAdapter(adapter)
api := upstreamapi.NewUpstreamAPI()
api.RegisterChan("fake-channel", "test", &model.SimCardChannelCache{Instance: &sSimYD{}})
input := &model.SimBaseReqJson{SimKeys: []*model.SimKey{{ChanKey: "fake-channel", ICCID: "fake-card", MSISDN: "frozen-number"}}, ReqData: json.RawMessage(`{"operationId":"stable-operation","recoverOnly":true}`)}
ctx := (&ghttp.Request{Request: httptest.NewRequest("POST", "/sim/change/sim-apn", nil)}).Context()
items, err := api.SimBase(ctx, input)
if err != nil || len(items) != 1 || !strings.Contains(string(items[0].ResData), `"orderNum":"saved-job"`) || !strings.Contains(string(items[0].ResData), `"pending":true`) {
t.Fatalf("HTTP转发丢失jobId:%+v %v", items, err)
}
if string(captured.ReqData) != string(input.ReqData) || captured.SimKeys[0].MSISDN != "frozen-number" {
t.Fatalf("恢复请求被改写:%+v", captured)
}
}