118 lines
4.6 KiB
Go
118 lines
4.6 KiB
Go
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)
|
||
}
|
||
}
|