86 lines
2.8 KiB
Go
86 lines
2.8 KiB
Go
package rpc
|
||
|
||
import (
|
||
"context"
|
||
"sync"
|
||
"testing"
|
||
|
||
"go.uber.org/zap/zaptest"
|
||
|
||
"github.com/iamxvbaba/td/bin"
|
||
"github.com/iamxvbaba/td/clock"
|
||
"github.com/iamxvbaba/td/tg"
|
||
)
|
||
|
||
type layerBinderCall struct {
|
||
rawAuthKeyID [8]byte
|
||
sessionID int64
|
||
layer int
|
||
}
|
||
|
||
// layerCaptureSessions 在 captureSessions 基础上实现可选的 ClientLayerBinder。
|
||
type layerCaptureSessions struct {
|
||
captureSessions
|
||
layerMu sync.Mutex
|
||
layerCalls []layerBinderCall
|
||
}
|
||
|
||
func (s *layerCaptureSessions) SetClientLayerForAuthKey(rawAuthKeyID [8]byte, sessionID int64, layer int) {
|
||
s.layerMu.Lock()
|
||
defer s.layerMu.Unlock()
|
||
s.layerCalls = append(s.layerCalls, layerBinderCall{rawAuthKeyID: rawAuthKeyID, sessionID: sessionID, layer: layer})
|
||
}
|
||
|
||
func (s *layerCaptureSessions) layerCallsSnapshot() []layerBinderCall {
|
||
s.layerMu.Lock()
|
||
defer s.layerMu.Unlock()
|
||
return append([]layerBinderCall(nil), s.layerCalls...)
|
||
}
|
||
|
||
// TestLegacyDispatchInvokeWithLayerAppliesOrderedSessionCorrection verifies the
|
||
// legacy facade follows the same explicit correction semantics as generated
|
||
// admission. A repeated selector is idempotent; a new selector updates exactly
|
||
// this session and notifies the connection once.
|
||
func TestLegacyDispatchInvokeWithLayerAppliesOrderedSessionCorrection(t *testing.T) {
|
||
sessions := &layerCaptureSessions{}
|
||
r := New(Config{DC: 2, IP: "127.0.0.1", Port: 2398}, Deps{Sessions: sessions}, zaptest.NewLogger(t), clock.System)
|
||
rawAuthKeyID := [8]byte{1, 2, 3, 4, 5, 6, 7, 8}
|
||
const sessionID = int64(42)
|
||
|
||
dispatchWithLayer := func(layer int) {
|
||
t.Helper()
|
||
var in bin.Buffer
|
||
req := &tg.InvokeWithLayerRequest{Layer: layer, Query: &tg.HelpGetConfigRequest{}}
|
||
if err := req.Encode(&in); err != nil {
|
||
t.Fatalf("encode: %v", err)
|
||
}
|
||
if _, err := r.Dispatch(context.Background(), rawAuthKeyID, sessionID, &in); err != nil {
|
||
t.Fatalf("dispatch layer %d: %v", layer, err)
|
||
}
|
||
}
|
||
|
||
dispatchWithLayer(225)
|
||
calls := sessions.layerCallsSnapshot()
|
||
if len(calls) != 1 {
|
||
t.Fatalf("layer binder calls = %d, want 1", len(calls))
|
||
}
|
||
if calls[0] != (layerBinderCall{rawAuthKeyID: rawAuthKeyID, sessionID: sessionID, layer: 225}) {
|
||
t.Fatalf("layer binder call = %+v", calls[0])
|
||
}
|
||
|
||
// 同 layer 重复 wrapper:不再下推。
|
||
dispatchWithLayer(225)
|
||
if calls := sessions.layerCallsSnapshot(); len(calls) != 1 {
|
||
t.Fatalf("layer binder calls after repeat = %d, want 1", len(calls))
|
||
}
|
||
|
||
// A later explicit selector is a valid ordered correction.
|
||
dispatchWithLayer(226)
|
||
calls = sessions.layerCallsSnapshot()
|
||
if len(calls) != 2 || calls[1] != (layerBinderCall{rawAuthKeyID: rawAuthKeyID, sessionID: sessionID, layer: 226}) {
|
||
t.Fatalf("layer binder calls after correction = %+v", calls)
|
||
}
|
||
if layer, ok := r.NegotiatedSessionLayer(rawAuthKeyID, sessionID); !ok || layer != 226 {
|
||
t.Fatalf("corrected exact session profile = (%d,%v), want (226,true)", layer, ok)
|
||
}
|
||
}
|