mirror of
https://github.com/juanfont/headscale.git
synced 2026-11-03 04:04:12 +09:00
mapper: retain the logtail instruction across client restarts
Updates #3522 (cherry picked from commit52a7f8c89c) (cherry picked from commit0c9186d4a3)
This commit is contained in:
1 parent
940260cfdc
commit
d03d3a0231
10 files changed
+274
-12
No files matched your search
@@ -2,6 +2,7 @@ package mapper
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -130,3 +131,93 @@ func TestSyncInitialMapNoPhantomPeersOnTimeout(t *testing.T) {
|
||||
len(phantom), phantom)
|
||||
}
|
||||
}
|
||||
|
||||
// TestInitialMapCarriesDebugConfigOnEveryStream pins that the logtail
|
||||
// instruction reaches every client stream. A client applies
|
||||
// [tailcfg.Debug.DisableLogTail] only while the process lives, so every
|
||||
// AddNode's first frame (a fresh process or a second connection alike) has to
|
||||
// carry it; a later non-full frame must not.
|
||||
func TestInitialMapCarriesDebugConfigOnEveryStream(t *testing.T) {
|
||||
for _, tt := range []struct {
|
||||
name string
|
||||
logTail bool
|
||||
want *tailcfg.Debug
|
||||
}{
|
||||
{"logtail_disabled", false, &tailcfg.Debug{DisableLogTail: true}},
|
||||
{"logtail_enabled", true, nil},
|
||||
} {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
testData, cleanup := setupBatcherWithTestData(t, NewBatcherAndMapper, 1, 3, normalBufferSize)
|
||||
defer cleanup()
|
||||
|
||||
// Set before any AddNode queues work, so no worker reads it concurrently.
|
||||
testData.Config.LogTail.Enabled = tt.logTail
|
||||
|
||||
batcher := testData.Batcher.Batcher
|
||||
capVer := tailcfg.CapabilityVersion(100)
|
||||
|
||||
firstFrame := func(t *testing.T, ch chan *tailcfg.MapResponse) *tailcfg.MapResponse {
|
||||
t.Helper()
|
||||
|
||||
select {
|
||||
case resp := <-ch:
|
||||
return resp
|
||||
case <-time.After(5 * time.Second):
|
||||
t.Fatal("no initial map")
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
for i := range testData.Nodes {
|
||||
n := &testData.Nodes[i]
|
||||
testData.State.Connect(n.n.ID)
|
||||
|
||||
err := batcher.AddNode(n.n.ID, n.ch, capVer, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("AddNode(%d): %v", n.n.ID, err)
|
||||
}
|
||||
|
||||
resp := firstFrame(t, n.ch)
|
||||
if resp.Node == nil {
|
||||
t.Fatalf("node %d: first frame lacks self node", n.n.ID)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(tt.want, resp.Debug) {
|
||||
t.Errorf("node %d initial map Debug = %+v, want %+v", n.n.ID, resp.Debug, tt.want)
|
||||
}
|
||||
}
|
||||
|
||||
// A second stream for an already-connected node gets its own full map.
|
||||
second := make(chan *tailcfg.MapResponse, normalBufferSize)
|
||||
|
||||
err := batcher.AddNode(testData.Nodes[0].n.ID, second, capVer, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("AddNode second stream: %v", err)
|
||||
}
|
||||
|
||||
if resp := firstFrame(t, second); !reflect.DeepEqual(tt.want, resp.Debug) {
|
||||
t.Errorf("second stream initial map Debug = %+v, want %+v", resp.Debug, tt.want)
|
||||
}
|
||||
|
||||
batcher.AddWork(change.DERPMap())
|
||||
|
||||
for i := range testData.Nodes {
|
||||
n := &testData.Nodes[i]
|
||||
|
||||
for {
|
||||
resp := firstFrame(t, n.ch)
|
||||
if resp.DERPMap == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if resp.Debug != nil {
|
||||
t.Errorf("node %d DERP frame carries Debug %+v", n.n.ID, resp.Debug)
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user