mirror of
				https://github.com/tailscale/tailscale.git
				synced 2025-11-04 00:55:11 +00:00 
			
		
		
		
	The //go:build syntax was introduced in Go 1.17: https://go.dev/doc/go1.17#build-lines gofmt has kept the +build and go:build lines in sync since then, but enough time has passed. Time to remove them. Done with: perl -i -npe 's,^// \+build.*\n,,' $(git grep -l -F '+build') Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
		
			
				
	
	
		
			129 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			129 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
//go:build glidertests
 | 
						|
 | 
						|
package ssh
 | 
						|
 | 
						|
import (
 | 
						|
	"bytes"
 | 
						|
	"context"
 | 
						|
	"io"
 | 
						|
	"testing"
 | 
						|
	"time"
 | 
						|
)
 | 
						|
 | 
						|
func TestAddHostKey(t *testing.T) {
 | 
						|
	s := Server{}
 | 
						|
	signer, err := generateSigner()
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	s.AddHostKey(signer)
 | 
						|
	if len(s.HostSigners) != 1 {
 | 
						|
		t.Fatal("Key was not properly added")
 | 
						|
	}
 | 
						|
	signer, err = generateSigner()
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	s.AddHostKey(signer)
 | 
						|
	if len(s.HostSigners) != 1 {
 | 
						|
		t.Fatal("Key was not properly replaced")
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestServerShutdown(t *testing.T) {
 | 
						|
	l := newLocalListener()
 | 
						|
	testBytes := []byte("Hello world\n")
 | 
						|
	s := &Server{
 | 
						|
		Handler: func(s Session) {
 | 
						|
			s.Write(testBytes)
 | 
						|
			time.Sleep(50 * time.Millisecond)
 | 
						|
		},
 | 
						|
	}
 | 
						|
	go func() {
 | 
						|
		err := s.Serve(l)
 | 
						|
		if err != nil && err != ErrServerClosed {
 | 
						|
			t.Fatal(err)
 | 
						|
		}
 | 
						|
	}()
 | 
						|
	sessDone := make(chan struct{})
 | 
						|
	sess, _, cleanup := newClientSession(t, l.Addr().String(), nil)
 | 
						|
	go func() {
 | 
						|
		defer cleanup()
 | 
						|
		defer close(sessDone)
 | 
						|
		var stdout bytes.Buffer
 | 
						|
		sess.Stdout = &stdout
 | 
						|
		if err := sess.Run(""); err != nil {
 | 
						|
			t.Fatal(err)
 | 
						|
		}
 | 
						|
		if !bytes.Equal(stdout.Bytes(), testBytes) {
 | 
						|
			t.Fatalf("expected = %s; got %s", testBytes, stdout.Bytes())
 | 
						|
		}
 | 
						|
	}()
 | 
						|
 | 
						|
	srvDone := make(chan struct{})
 | 
						|
	go func() {
 | 
						|
		defer close(srvDone)
 | 
						|
		err := s.Shutdown(context.Background())
 | 
						|
		if err != nil {
 | 
						|
			t.Fatal(err)
 | 
						|
		}
 | 
						|
	}()
 | 
						|
 | 
						|
	timeout := time.After(2 * time.Second)
 | 
						|
	select {
 | 
						|
	case <-timeout:
 | 
						|
		t.Fatal("timeout")
 | 
						|
		return
 | 
						|
	case <-srvDone:
 | 
						|
		// TODO: add timeout for sessDone
 | 
						|
		<-sessDone
 | 
						|
		return
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestServerClose(t *testing.T) {
 | 
						|
	l := newLocalListener()
 | 
						|
	s := &Server{
 | 
						|
		Handler: func(s Session) {
 | 
						|
			time.Sleep(5 * time.Second)
 | 
						|
		},
 | 
						|
	}
 | 
						|
	go func() {
 | 
						|
		err := s.Serve(l)
 | 
						|
		if err != nil && err != ErrServerClosed {
 | 
						|
			t.Fatal(err)
 | 
						|
		}
 | 
						|
	}()
 | 
						|
 | 
						|
	clientDoneChan := make(chan struct{})
 | 
						|
	closeDoneChan := make(chan struct{})
 | 
						|
 | 
						|
	sess, _, cleanup := newClientSession(t, l.Addr().String(), nil)
 | 
						|
	go func() {
 | 
						|
		defer cleanup()
 | 
						|
		defer close(clientDoneChan)
 | 
						|
		<-closeDoneChan
 | 
						|
		if err := sess.Run(""); err != nil && err != io.EOF {
 | 
						|
			t.Fatal(err)
 | 
						|
		}
 | 
						|
	}()
 | 
						|
 | 
						|
	go func() {
 | 
						|
		err := s.Close()
 | 
						|
		if err != nil {
 | 
						|
			t.Fatal(err)
 | 
						|
		}
 | 
						|
		close(closeDoneChan)
 | 
						|
	}()
 | 
						|
 | 
						|
	timeout := time.After(100 * time.Millisecond)
 | 
						|
	select {
 | 
						|
	case <-timeout:
 | 
						|
		t.Error("timeout")
 | 
						|
		return
 | 
						|
	case <-s.getDoneChan():
 | 
						|
		<-clientDoneChan
 | 
						|
		return
 | 
						|
	}
 | 
						|
}
 |