mirror of
				https://github.com/tailscale/tailscale.git
				synced 2025-10-31 08:11:32 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			70 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			70 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Copyright (c) 2020 Tailscale Inc & AUTHORS All rights reserved.
 | |
| // Use of this source code is governed by a BSD-style
 | |
| // license that can be found in the LICENSE file.
 | |
| 
 | |
| package wgengine
 | |
| 
 | |
| import (
 | |
| 	"bytes"
 | |
| 	"fmt"
 | |
| 	"strings"
 | |
| 	"testing"
 | |
| 	"time"
 | |
| )
 | |
| 
 | |
| func TestWatchdog(t *testing.T) {
 | |
| 	t.Parallel()
 | |
| 
 | |
| 	t.Run("default watchdog does not fire", func(t *testing.T) {
 | |
| 		t.Parallel()
 | |
| 		e, err := NewFakeUserspaceEngine(t.Logf, 0)
 | |
| 		if err != nil {
 | |
| 			t.Fatal(err)
 | |
| 		}
 | |
| 
 | |
| 		e = NewWatchdog(e)
 | |
| 		e.(*watchdogEngine).maxWait = 150 * time.Millisecond
 | |
| 
 | |
| 		e.RequestStatus()
 | |
| 		e.RequestStatus()
 | |
| 		e.RequestStatus()
 | |
| 		e.Close()
 | |
| 	})
 | |
| 
 | |
| 	t.Run("watchdog fires on blocked getStatus", func(t *testing.T) {
 | |
| 		t.Parallel()
 | |
| 		e, err := NewFakeUserspaceEngine(t.Logf, 0)
 | |
| 		if err != nil {
 | |
| 			t.Fatal(err)
 | |
| 		}
 | |
| 		usEngine := e.(*userspaceEngine)
 | |
| 		e = NewWatchdog(e)
 | |
| 		wdEngine := e.(*watchdogEngine)
 | |
| 		wdEngine.maxWait = 100 * time.Millisecond
 | |
| 
 | |
| 		logBuf := new(bytes.Buffer)
 | |
| 		fatalCalled := make(chan struct{})
 | |
| 		wdEngine.logf = func(format string, args ...interface{}) {
 | |
| 			fmt.Fprintf(logBuf, format+"\n", args...)
 | |
| 		}
 | |
| 		wdEngine.fatalf = func(format string, args ...interface{}) {
 | |
| 			t.Logf("FATAL: %s", fmt.Sprintf(format, args...))
 | |
| 			fatalCalled <- struct{}{}
 | |
| 		}
 | |
| 
 | |
| 		usEngine.wgLock.Lock() // blocks getStatus so the watchdog will fire
 | |
| 
 | |
| 		go e.RequestStatus()
 | |
| 
 | |
| 		select {
 | |
| 		case <-fatalCalled:
 | |
| 			if !strings.Contains(logBuf.String(), "goroutine profile: total ") {
 | |
| 				t.Errorf("fatal called without watchdog stacks, got: %s", logBuf.String())
 | |
| 			}
 | |
| 			// expected
 | |
| 		case <-time.After(3 * time.Second):
 | |
| 			t.Fatalf("watchdog failed to fire")
 | |
| 		}
 | |
| 	})
 | |
| }
 |