106 lines
2.9 KiB
Go
106 lines
2.9 KiB
Go
package grdp
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"git.zeroonesoft.cn/golib/rdplib/plugin/rdpgfx"
|
|
"git.zeroonesoft.cn/golib/rdplib/protocol/pdu"
|
|
)
|
|
|
|
// fakeBmpStore 记录 Persist 调用并提供 Get/Keys,用于验证
|
|
// CacheBitmapV2 持久键的跨会话存取(6.4b M2)。
|
|
type fakeBmpStore struct {
|
|
persisted map[uint64]rdpgfx.GfxCacheEntry
|
|
}
|
|
|
|
func newFakeBmpStore() *fakeBmpStore {
|
|
return &fakeBmpStore{persisted: map[uint64]rdpgfx.GfxCacheEntry{}}
|
|
}
|
|
|
|
func (f *fakeBmpStore) Persist(key uint64, w, h int, bpp uint16, data []byte) {
|
|
f.persisted[key] = rdpgfx.GfxCacheEntry{Key: key, Width: w, Height: h, Bpp: bpp, Data: data}
|
|
}
|
|
func (f *fakeBmpStore) Export() []rdpgfx.GfxCacheEntry {
|
|
out := make([]rdpgfx.GfxCacheEntry, 0, len(f.persisted))
|
|
for _, e := range f.persisted {
|
|
out = append(out, e)
|
|
}
|
|
return out
|
|
}
|
|
func (f *fakeBmpStore) Get(key uint64) (rdpgfx.GfxCacheEntry, bool) {
|
|
e, ok := f.persisted[key]
|
|
return e, ok
|
|
}
|
|
func (f *fakeBmpStore) Keys() []uint64 {
|
|
out := make([]uint64, 0, len(f.persisted))
|
|
for k := range f.persisted {
|
|
out = append(out, k)
|
|
}
|
|
return out
|
|
}
|
|
|
|
// TestStoreBitmapCacheV2PersistentKey:带持久键的 CacheBitmapV2 应把
|
|
// 位图以 key2<<32|key1 持久化;零数据+持久键应从持久库回填会话内单元。
|
|
func TestStoreBitmapCacheV2PersistentKey(t *testing.T) {
|
|
store := newFakeBmpStore()
|
|
g := &RdpClient{
|
|
bitmapCache: make(map[uint32]*Bitmap),
|
|
bitmapCacheFIFO: []uint32{},
|
|
gfxCacheStore: store,
|
|
}
|
|
|
|
// 1) 带键+数据:进会话缓存并持久化
|
|
cb := &pdu.CacheBitmapV2Order{
|
|
CacheId: 1,
|
|
Flags: pdu.CBR2_PERSISTENT_KEY_PRESENT,
|
|
Key1: 0xDEAD,
|
|
Key2: 0xBEEF,
|
|
BitmapBpp: 32,
|
|
BitmapWidth: 4,
|
|
BitmapHeight: 4,
|
|
BitmapLength: 64,
|
|
CacheIndex: 7,
|
|
BitmapDataStream: make([]byte, 4*4*4),
|
|
}
|
|
g.storeBitmapCacheV2(cb)
|
|
pk := uint64(0xBEEF)<<32 | 0xDEAD
|
|
if _, ok := store.persisted[pk]; !ok {
|
|
t.Fatalf("entry not persisted under %x; got %v", pk, store.persisted)
|
|
}
|
|
if _, ok := g.bitmapCache[1<<16|7]; !ok {
|
|
t.Fatal("entry missing from in-session cache")
|
|
}
|
|
|
|
// 2) 零数据+同键(另一单元):从持久库回填
|
|
cb2 := &pdu.CacheBitmapV2Order{
|
|
CacheId: 2,
|
|
Flags: pdu.CBR2_PERSISTENT_KEY_PRESENT,
|
|
Key1: 0xDEAD,
|
|
Key2: 0xBEEF,
|
|
BitmapBpp: 32,
|
|
BitmapWidth: 4,
|
|
BitmapHeight: 4,
|
|
CacheIndex: 9,
|
|
}
|
|
g.storeBitmapCacheV2(cb2)
|
|
b, ok := g.bitmapCache[2<<16|9]
|
|
if !ok || b == nil || len(b.Data) != 4*4*4 {
|
|
t.Fatalf("persistent backfill failed: ok=%v len=%v", ok, b)
|
|
}
|
|
|
|
// 3) 零数据但持久库未命中:不放入缓存
|
|
cb3 := &pdu.CacheBitmapV2Order{
|
|
CacheId: 3,
|
|
Flags: pdu.CBR2_PERSISTENT_KEY_PRESENT,
|
|
Key1: 0x1111,
|
|
Key2: 0x2222,
|
|
BitmapBpp: 32,
|
|
BitmapWidth: 4, BitmapHeight: 4,
|
|
CacheIndex: 5,
|
|
}
|
|
g.storeBitmapCacheV2(cb3)
|
|
if _, ok := g.bitmapCache[3<<16|5]; ok {
|
|
t.Fatal("missed backfill must not populate cache")
|
|
}
|
|
}
|