๐Ÿ’พ Archived View for source.community โ€บ ckaznocha โ€บ gemini โ€บ blob โ€บ main โ€บ server_test.go captured on 2023-04-26 at 13:23:24. Gemini links have been rewritten to link to archived content

View Raw

More Information

โฌ…๏ธ Previous capture (2023-01-29)

โžก๏ธ Next capture (2024-02-05)

-=-=-=-=-=-=-

                                                         .
,-. ,-. . . ,-. ,-. ,-.    ,-. ,-. ,-,-. ,-,-. . . ,-. . |- . .
`-. | | | | |   |   |-'    |   | | | | | | | | | | | | | |  | |
`-' `-' `-^ '   `-' `-' :: `-' `-' ' ' ' ' ' ' `-^ ' ' ' `' `-|
                                                             /|
                                                            `-'

Profile for ckaznocha

ckaznocha / gemini

git clone https://source.community/ckaznocha/gemini.git

Branches

Log

Tree

/server_test.go (main)

โ†‘ /

blob

View raw contents of /server_test.go (main)

โ”€โ”€โ”€โ”€โ•ฎ
   1โ”‚ package gemini_test
   2โ”‚ 
   3โ”‚ import (
   4โ”‚ 	"bufio"
   5โ”‚ 	"context"
   6โ”‚ 	"crypto/tls"
   7โ”‚ 	"errors"
   8โ”‚ 	"fmt"
   9โ”‚ 	"net"
  10โ”‚ 	"strings"
  11โ”‚ 	"sync"
  12โ”‚ 	"testing"
  13โ”‚ 	"time"
  14โ”‚ 
  15โ”‚ 	"source.community/ckaznocha/gemini"
  16โ”‚ )
  17โ”‚ 
  18โ”‚ func failOnErrIfServerRunning(t *testing.T, done <-chan struct{}, err error, msg string) bool {
  19โ”‚ 	t.Helper()
  20โ”‚ 
  21โ”‚ 	select {
  22โ”‚ 	case <-done:
  23โ”‚ 		return true
  24โ”‚ 	default:
  25โ”‚ 		if err != nil {
  26โ”‚ 			t.Error(msg)
  27โ”‚ 
  28โ”‚ 			return true
  29โ”‚ 		}
  30โ”‚ 
  31โ”‚ 		return false
  32โ”‚ 	}
  33โ”‚ }
  34โ”‚ 
  35โ”‚ func TestServer_ListenAndServeTLS(t *testing.T) {
  36โ”‚ 	t.Parallel()
  37โ”‚ 
  38โ”‚ 	type fields struct {
  39โ”‚ 		Handler     gemini.Handler
  40โ”‚ 		LogHandler  func(message string, isError bool)
  41โ”‚ 		BaseContext func(net.Listener) context.Context
  42โ”‚ 		ConnContext func(ctx context.Context, c net.Conn) context.Context
  43โ”‚ 		TLSConfig   *tls.Config
  44โ”‚ 	}
  45โ”‚ 
  46โ”‚ 	type args struct {
  47โ”‚ 		addr     string
  48โ”‚ 		certFile string
  49โ”‚ 		keyFile  string
  50โ”‚ 	}
  51โ”‚ 
  52โ”‚ 	tests := []struct {
  53โ”‚ 		name          string
  54โ”‚ 		fields        fields
  55โ”‚ 		args          args
  56โ”‚ 		wantErr       bool
  57โ”‚ 		shutdownFirst bool
  58โ”‚ 	}{
  59โ”‚ 		{
  60โ”‚ 			name: "Starts a server on the given address",
  61โ”‚ 			fields: fields{
  62โ”‚ 				Handler: gemini.NewServeMux(),
  63โ”‚ 			},
  64โ”‚ 			args: args{
  65โ”‚ 				addr:     "localhost:8049",
  66โ”‚ 				certFile: "testdata/cert.pem",
  67โ”‚ 				keyFile:  "testdata/key.pem",
  68โ”‚ 			},
  69โ”‚ 		},
  70โ”‚ 		{
  71โ”‚ 			name:          "Exits if the server has already been shutdown",
  72โ”‚ 			shutdownFirst: true,
  73โ”‚ 		},
  74โ”‚ 	}
  75โ”‚ 
  76โ”‚ 	for _, tt := range tests {
  77โ”‚ 		tt := tt
  78โ”‚ 		t.Run(tt.name, func(t *testing.T) {
  79โ”‚ 			t.Parallel()
  80โ”‚ 			s := &gemini.Server{
  81โ”‚ 				Handler:     tt.fields.Handler,
  82โ”‚ 				LogHandler:  tt.fields.LogHandler,
  83โ”‚ 				BaseContext: tt.fields.BaseContext,
  84โ”‚ 				ConnContext: tt.fields.ConnContext,
  85โ”‚ 				TLSConfig:   tt.fields.TLSConfig,
  86โ”‚ 			}
  87โ”‚ 
  88โ”‚ 			if tt.shutdownFirst {
  89โ”‚ 				s.Shutdown(context.Background())
  90โ”‚ 			}
  91โ”‚ 
  92โ”‚ 			clientDone := make(chan struct{}, 1)
  93โ”‚ 			serverDone := make(chan struct{}, 1)
  94โ”‚ 
  95โ”‚ 			go func() {
  96โ”‚ 				defer func() {
  97โ”‚ 					if err := s.Shutdown(context.Background()); err != nil {
  98โ”‚ 						t.Errorf("Server.ListenAndServeTLS(%v, %v) Unable to shutdown: error = %v", tt.args.certFile, tt.args.keyFile, err)
  99โ”‚ 					}
 100โ”‚ 
 101โ”‚ 					clientDone <- struct{}{}
 102โ”‚ 				}()
 103โ”‚ 
 104โ”‚ 				conn, err := tls.DialWithDialer(
 105โ”‚ 					&net.Dialer{Timeout: 1 * time.Second},
 106โ”‚ 					"tcp",
 107โ”‚ 					tt.args.addr,
 108โ”‚ 					&tls.Config{
 109โ”‚ 						InsecureSkipVerify: true,
 110โ”‚ 					},
 111โ”‚ 				)
 112โ”‚ 				if failOnErrIfServerRunning(
 113โ”‚ 					t,
 114โ”‚ 					serverDone,
 115โ”‚ 					err,
 116โ”‚ 					fmt.Sprintf("Server.ListenAndServeTLS(%v, %v) Unable to dial: error = %v", tt.args.certFile, tt.args.keyFile, err),
 117โ”‚ 				) {
 118โ”‚ 					return
 119โ”‚ 				}
 120โ”‚ 
 121โ”‚ 				if _, err = fmt.Fprint(conn, "gemini://localhost.com/\r\n"); failOnErrIfServerRunning(
 122โ”‚ 					t,
 123โ”‚ 					serverDone,
 124โ”‚ 					err,
 125โ”‚ 					fmt.Sprintf("Server.ListenAndServeTLS(%v, %v) Unable to write request: error = %v", tt.args.certFile, tt.args.keyFile, err),
 126โ”‚ 				) {
 127โ”‚ 					return
 128โ”‚ 				}
 129โ”‚ 
 130โ”‚ 				b := bufio.NewReader(conn)
 131โ”‚ 				got, err := b.ReadBytes('\n')
 132โ”‚ 				if failOnErrIfServerRunning(
 133โ”‚ 					t,
 134โ”‚ 					serverDone,
 135โ”‚ 					err,
 136โ”‚ 					fmt.Sprintf("Server.ListenAndServeTLS(%v, %v) Unable to read response: error = %v", tt.args.certFile, tt.args.keyFile, err),
 137โ”‚ 				) {
 138โ”‚ 					return
 139โ”‚ 				}
 140โ”‚ 
 141โ”‚ 				if string(got) != "51 The requested resource could not be found but may be available in the future.\r\n" {
 142โ”‚ 					t.Errorf("Server.ListenAndServeTLS(%v, %v) Incorrect response: got = %v", tt.args.certFile, tt.args.keyFile, string(got))
 143โ”‚ 
 144โ”‚ 					return
 145โ”‚ 				}
 146โ”‚ 
 147โ”‚ 				if err = conn.Close(); failOnErrIfServerRunning(
 148โ”‚ 					t,
 149โ”‚ 					serverDone,
 150โ”‚ 					err,
 151โ”‚ 					fmt.Sprintf("Server.ListenAndServeTLS(%v, %v) Unable to close connection: error = %v", tt.args.certFile, tt.args.keyFile, err),
 152โ”‚ 				) {
 153โ”‚ 					return
 154โ”‚ 				}
 155โ”‚ 			}()
 156โ”‚ 
 157โ”‚ 			if err := s.ListenAndServeTLS(
 158โ”‚ 				tt.args.addr,
 159โ”‚ 				tt.args.certFile,
 160โ”‚ 				tt.args.keyFile,
 161โ”‚ 			); !errors.Is(err, gemini.ErrServerShutdown) != tt.wantErr {
 162โ”‚ 				t.Errorf("Server.ListenAndServeTLS(%v, %v) error = %v, wantErr %v", tt.args.certFile, tt.args.keyFile, err, tt.wantErr)
 163โ”‚ 			}
 164โ”‚ 
 165โ”‚ 			serverDone <- struct{}{}
 166โ”‚ 			<-clientDone
 167โ”‚ 		})
 168โ”‚ 	}
 169โ”‚ }
 170โ”‚ 
 171โ”‚ func TestServer_ServeTLS(t *testing.T) {
 172โ”‚ 	t.Parallel()
 173โ”‚ 
 174โ”‚ 	type fields struct {
 175โ”‚ 		Handler     gemini.Handler
 176โ”‚ 		LogHandler  func(message string, isError bool)
 177โ”‚ 		BaseContext func(net.Listener) context.Context
 178โ”‚ 		ConnContext func(ctx context.Context, c net.Conn) context.Context
 179โ”‚ 		TLSConfig   *tls.Config
 180โ”‚ 	}
 181โ”‚ 
 182โ”‚ 	type args struct {
 183โ”‚ 		certFile string
 184โ”‚ 		keyFile  string
 185โ”‚ 	}
 186โ”‚ 
 187โ”‚ 	tests := []struct {
 188โ”‚ 		name          string
 189โ”‚ 		fields        fields
 190โ”‚ 		args          args
 191โ”‚ 		wantErr       bool
 192โ”‚ 		shutdownFirst bool
 193โ”‚ 	}{
 194โ”‚ 		{
 195โ”‚ 			name: "",
 196โ”‚ 			fields: fields{
 197โ”‚ 				Handler: gemini.NewServeMux(),
 198โ”‚ 			},
 199โ”‚ 			args: args{
 200โ”‚ 				certFile: "",
 201โ”‚ 				keyFile:  "",
 202โ”‚ 			},
 203โ”‚ 			wantErr: true,
 204โ”‚ 		},
 205โ”‚ 		{
 206โ”‚ 			name: "",
 207โ”‚ 			args: args{
 208โ”‚ 				certFile: "testdata/cert.pem",
 209โ”‚ 				keyFile:  "testdata/key.pem",
 210โ”‚ 			},
 211โ”‚ 		},
 212โ”‚ 		{
 213โ”‚ 			name: "",
 214โ”‚ 			fields: fields{
 215โ”‚ 				TLSConfig: &tls.Config{MinVersion: tls.VersionTLS11},
 216โ”‚ 			},
 217โ”‚ 			args: args{
 218โ”‚ 				certFile: "testdata/cert.pem",
 219โ”‚ 				keyFile:  "testdata/key.pem",
 220โ”‚ 			},
 221โ”‚ 			wantErr: true,
 222โ”‚ 		},
 223โ”‚ 		{
 224โ”‚ 			name:   "",
 225โ”‚ 			fields: fields{},
 226โ”‚ 			args: args{
 227โ”‚ 				certFile: "testdata/cert.pem",
 228โ”‚ 				keyFile:  "testdata/key.pem",
 229โ”‚ 			},
 230โ”‚ 			shutdownFirst: true,
 231โ”‚ 		},
 232โ”‚ 	}
 233โ”‚ 
 234โ”‚ 	for _, tt := range tests {
 235โ”‚ 		tt := tt
 236โ”‚ 		t.Run(tt.name, func(t *testing.T) {
 237โ”‚ 			t.Parallel()
 238โ”‚ 			s := &gemini.Server{
 239โ”‚ 				Handler:     tt.fields.Handler,
 240โ”‚ 				LogHandler:  tt.fields.LogHandler,
 241โ”‚ 				BaseContext: tt.fields.BaseContext,
 242โ”‚ 				ConnContext: tt.fields.ConnContext,
 243โ”‚ 				TLSConfig:   tt.fields.TLSConfig,
 244โ”‚ 			}
 245โ”‚ 
 246โ”‚ 			l, err := net.Listen("tcp", "localhost:0")
 247โ”‚ 			if err != nil {
 248โ”‚ 				t.Fatalf("unable to open listener: %s", err)
 249โ”‚ 			}
 250โ”‚ 
 251โ”‚ 			if tt.shutdownFirst {
 252โ”‚ 				s.Shutdown(context.Background())
 253โ”‚ 			}
 254โ”‚ 
 255โ”‚ 			clientDone := make(chan struct{}, 1)
 256โ”‚ 			serverDone := make(chan struct{}, 1)
 257โ”‚ 
 258โ”‚ 			go func() {
 259โ”‚ 				defer func() {
 260โ”‚ 					if err := s.Shutdown(context.Background()); err != nil {
 261โ”‚ 						t.Errorf("Server.ListenAndServeTLS(%v, %v) Unable to shutdown: error = %v", tt.args.certFile, tt.args.keyFile, err)
 262โ”‚ 					}
 263โ”‚ 
 264โ”‚ 					clientDone <- struct{}{}
 265โ”‚ 				}()
 266โ”‚ 
 267โ”‚ 				conn, err := tls.DialWithDialer(
 268โ”‚ 					&net.Dialer{Timeout: 1 * time.Second},
 269โ”‚ 					"tcp",
 270โ”‚ 					l.Addr().String(),
 271โ”‚ 					&tls.Config{
 272โ”‚ 						InsecureSkipVerify: true,
 273โ”‚ 					},
 274โ”‚ 				)
 275โ”‚ 				if failOnErrIfServerRunning(
 276โ”‚ 					t,
 277โ”‚ 					serverDone,
 278โ”‚ 					err,
 279โ”‚ 					fmt.Sprintf("Server.ListenAndServeTLS(%v, %v) Unable to dial: error = %v", tt.args.certFile, tt.args.keyFile, err),
 280โ”‚ 				) {
 281โ”‚ 					return
 282โ”‚ 				}
 283โ”‚ 
 284โ”‚ 				if _, err = fmt.Fprint(conn, "gemini://localhost.com/\r\n"); failOnErrIfServerRunning(
 285โ”‚ 					t,
 286โ”‚ 					serverDone,
 287โ”‚ 					err,
 288โ”‚ 					fmt.Sprintf("Server.ListenAndServeTLS(%v, %v) Unable to write request: error = %v", tt.args.certFile, tt.args.keyFile, err),
 289โ”‚ 				) {
 290โ”‚ 					return
 291โ”‚ 				}
 292โ”‚ 
 293โ”‚ 				b := bufio.NewReader(conn)
 294โ”‚ 				got, err := b.ReadBytes('\n')
 295โ”‚ 				if failOnErrIfServerRunning(
 296โ”‚ 					t,
 297โ”‚ 					serverDone,
 298โ”‚ 					err,
 299โ”‚ 					fmt.Sprintf("Server.ListenAndServeTLS(%v, %v) Unable to read response: error = %v", tt.args.certFile, tt.args.keyFile, err),
 300โ”‚ 				) {
 301โ”‚ 					return
 302โ”‚ 				}
 303โ”‚ 
 304โ”‚ 				if string(got) != "51 The requested resource could not be found but may be available in the future.\r\n" {
 305โ”‚ 					t.Errorf("Server.ListenAndServeTLS(%v, %v) Incorrect response: got = %v", tt.args.certFile, tt.args.keyFile, string(got))
 306โ”‚ 
 307โ”‚ 					return
 308โ”‚ 				}
 309โ”‚ 
 310โ”‚ 				if err = conn.Close(); failOnErrIfServerRunning(
 311โ”‚ 					t,
 312โ”‚ 					serverDone,
 313โ”‚ 					err,
 314โ”‚ 					fmt.Sprintf("Server.ListenAndServeTLS(%v, %v) Unable to close connection: error = %v", tt.args.certFile, tt.args.keyFile, err),
 315โ”‚ 				) {
 316โ”‚ 					return
 317โ”‚ 				}
 318โ”‚ 			}()
 319โ”‚ 
 320โ”‚ 			if err := s.ServeTLS(l, tt.args.certFile, tt.args.keyFile); !errors.Is(err, gemini.ErrServerShutdown) != tt.wantErr {
 321โ”‚ 				t.Errorf("Server.ServeTLS(%v, %v, %v) error = %v, wantErr %v", l, tt.args.certFile, tt.args.keyFile, err, tt.wantErr)
 322โ”‚ 			}
 323โ”‚ 
 324โ”‚ 			serverDone <- struct{}{}
 325โ”‚ 			<-clientDone
 326โ”‚ 		})
 327โ”‚ 	}
 328โ”‚ }
 329โ”‚ 
 330โ”‚ func TestServer_Serve(t *testing.T) {
 331โ”‚ 	t.Parallel()
 332โ”‚ 
 333โ”‚ 	type fields struct {
 334โ”‚ 		Handler     gemini.Handler
 335โ”‚ 		LogHandler  func(message string, isError bool)
 336โ”‚ 		BaseContext func(net.Listener) context.Context
 337โ”‚ 		ConnContext func(ctx context.Context, c net.Conn) context.Context
 338โ”‚ 		TLSConfig   *tls.Config
 339โ”‚ 	}
 340โ”‚ 
 341โ”‚ 	tests := []struct {
 342โ”‚ 		fields        fields
 343โ”‚ 		name          string
 344โ”‚ 		reqBody       string
 345โ”‚ 		wantResponse  string
 346โ”‚ 		wantErr       bool
 347โ”‚ 		shutdownFirst bool
 348โ”‚ 		wantNonTLS    bool
 349โ”‚ 	}{
 350โ”‚ 		{
 351โ”‚ 			name: "works",
 352โ”‚ 			fields: fields{
 353โ”‚ 				Handler: gemini.NewServeMux(),
 354โ”‚ 			},
 355โ”‚ 			wantResponse: "51 The requested resource could not be found but may be available in the future.\r\n",
 356โ”‚ 		},
 357โ”‚ 		{
 358โ”‚ 			name: "errors when its not a TLS connection",
 359โ”‚ 			fields: fields{
 360โ”‚ 				Handler: gemini.NewServeMux(),
 361โ”‚ 			},
 362โ”‚ 			wantErr:    true,
 363โ”‚ 			wantNonTLS: true,
 364โ”‚ 		},
 365โ”‚ 		{
 366โ”‚ 			name: "errors when the server has already been shutdown",
 367โ”‚ 			fields: fields{
 368โ”‚ 				Handler: gemini.NewServeMux(),
 369โ”‚ 			},
 370โ”‚ 			shutdownFirst: true,
 371โ”‚ 		},
 372โ”‚ 		{
 373โ”‚ 			name: "errors base context is nil",
 374โ”‚ 			fields: fields{
 375โ”‚ 				Handler:     gemini.NewServeMux(),
 376โ”‚ 				BaseContext: func(l net.Listener) context.Context { return nil },
 377โ”‚ 			},
 378โ”‚ 			wantErr: true,
 379โ”‚ 		},
 380โ”‚ 		{
 381โ”‚ 			name: "errors conn context is nil",
 382โ”‚ 			fields: fields{
 383โ”‚ 				Handler:     gemini.NewServeMux(),
 384โ”‚ 				ConnContext: func(ctx context.Context, c net.Conn) context.Context { return nil },
 385โ”‚ 			},
 386โ”‚ 			wantErr: true,
 387โ”‚ 		},
 388โ”‚ 		{
 389โ”‚ 			name: "handles a too large request",
 390โ”‚ 			fields: fields{
 391โ”‚ 				Handler: gemini.NewServeMux(),
 392โ”‚ 			},
 393โ”‚ 			wantResponse: "59 the request length exceeded the max size of 1024 bytes\r\n",
 394โ”‚ 			reqBody:      "gemini://localhost/" + strings.Repeat("n", 1028-len("gemini://localhost/\r\n")) + "\r\n",
 395โ”‚ 		},
 396โ”‚ 	}
 397โ”‚ 
 398โ”‚ 	for _, tt := range tests {
 399โ”‚ 		tt := tt
 400โ”‚ 		t.Run(tt.name, func(t *testing.T) {
 401โ”‚ 			t.Parallel()
 402โ”‚ 			s := &gemini.Server{
 403โ”‚ 				Handler:     tt.fields.Handler,
 404โ”‚ 				LogHandler:  tt.fields.LogHandler,
 405โ”‚ 				BaseContext: tt.fields.BaseContext,
 406โ”‚ 				ConnContext: tt.fields.ConnContext,
 407โ”‚ 				TLSConfig:   tt.fields.TLSConfig,
 408โ”‚ 			}
 409โ”‚ 
 410โ”‚ 			l, err := net.Listen("tcp", "localhost:0")
 411โ”‚ 			if err != nil {
 412โ”‚ 				t.Fatalf("unable to open listener: %s", err)
 413โ”‚ 			}
 414โ”‚ 
 415โ”‚ 			if !tt.wantNonTLS {
 416โ”‚ 				var cert tls.Certificate
 417โ”‚ 				cert, err = tls.LoadX509KeyPair("testdata/cert.pem", "testdata/key.pem")
 418โ”‚ 				if err != nil {
 419โ”‚ 					t.Fatalf("unable to open listener: %s", err)
 420โ”‚ 				}
 421โ”‚ 
 422โ”‚ 				config := &tls.Config{
 423โ”‚ 					Certificates: []tls.Certificate{cert},
 424โ”‚ 				}
 425โ”‚ 				l = tls.NewListener(l, config)
 426โ”‚ 			}
 427โ”‚ 
 428โ”‚ 			if tt.shutdownFirst {
 429โ”‚ 				s.Shutdown(context.Background())
 430โ”‚ 			}
 431โ”‚ 
 432โ”‚ 			clientDone := make(chan struct{}, 1)
 433โ”‚ 			serverDone := make(chan struct{}, 1)
 434โ”‚ 
 435โ”‚ 			go func() {
 436โ”‚ 				defer func() {
 437โ”‚ 					if err = s.Shutdown(context.Background()); err != nil {
 438โ”‚ 						t.Errorf("Server.Serve(%v) Unable to shutdown: error = %v", l, err)
 439โ”‚ 					}
 440โ”‚ 
 441โ”‚ 					clientDone <- struct{}{}
 442โ”‚ 				}()
 443โ”‚ 
 444โ”‚ 				var conn *tls.Conn
 445โ”‚ 				conn, err = tls.DialWithDialer(
 446โ”‚ 					&net.Dialer{Timeout: 1 * time.Second},
 447โ”‚ 					"tcp",
 448โ”‚ 					l.Addr().String(),
 449โ”‚ 					&tls.Config{
 450โ”‚ 						InsecureSkipVerify: true,
 451โ”‚ 					},
 452โ”‚ 				)
 453โ”‚ 				if failOnErrIfServerRunning(
 454โ”‚ 					t,
 455โ”‚ 					serverDone,
 456โ”‚ 					err,
 457โ”‚ 					fmt.Sprintf("Server.Serve(%v) Unable to dial: error = %v", l, err),
 458โ”‚ 				) {
 459โ”‚ 					return
 460โ”‚ 				}
 461โ”‚ 
 462โ”‚ 				body := "gemini://localhost.com/\r\n"
 463โ”‚ 				if tt.reqBody != "" {
 464โ”‚ 					body = tt.reqBody
 465โ”‚ 				}
 466โ”‚ 
 467โ”‚ 				if _, err = fmt.Fprint(conn, body); failOnErrIfServerRunning(
 468โ”‚ 					t,
 469โ”‚ 					serverDone,
 470โ”‚ 					err,
 471โ”‚ 					fmt.Sprintf("Server.Serve(%v) Unable to write request: error = %v", l, err),
 472โ”‚ 				) {
 473โ”‚ 					return
 474โ”‚ 				}
 475โ”‚ 
 476โ”‚ 				b := bufio.NewReader(conn)
 477โ”‚ 				var got []byte
 478โ”‚ 				got, err = b.ReadBytes('\n')
 479โ”‚ 				if failOnErrIfServerRunning(
 480โ”‚ 					t,
 481โ”‚ 					serverDone,
 482โ”‚ 					err,
 483โ”‚ 					fmt.Sprintf("Server.Serve(%v) Unable to read response: error = %v", l, err),
 484โ”‚ 				) {
 485โ”‚ 					return
 486โ”‚ 				}
 487โ”‚ 
 488โ”‚ 				if string(got) != tt.wantResponse { //!= "51 The requested resource could not be found but may be available in the future.\r\n" {
 489โ”‚ 					t.Errorf("Server.Serve(%v) Incorrect response: got = %v, want %s", l, string(got), tt.wantResponse)
 490โ”‚ 
 491โ”‚ 					return
 492โ”‚ 				}
 493โ”‚ 
 494โ”‚ 				if err = conn.Close(); failOnErrIfServerRunning(
 495โ”‚ 					t,
 496โ”‚ 					serverDone,
 497โ”‚ 					err,
 498โ”‚ 					fmt.Sprintf("Server.Serve(%v) Unable to close connection: error = %v", l, err),
 499โ”‚ 				) {
 500โ”‚ 					return
 501โ”‚ 				}
 502โ”‚ 			}()
 503โ”‚ 
 504โ”‚ 			err = s.Serve(l)
 505โ”‚ 			if !errors.Is(err, gemini.ErrServerShutdown) != tt.wantErr {
 506โ”‚ 				t.Errorf("Server.Serve(%v) error = %v, wantErr %v", l, err, tt.wantErr)
 507โ”‚ 			}
 508โ”‚ 
 509โ”‚ 			serverDone <- struct{}{}
 510โ”‚ 			<-clientDone
 511โ”‚ 		})
 512โ”‚ 	}
 513โ”‚ }
 514โ”‚ 
 515โ”‚ func TestServer_RegisterOnShutdown(t *testing.T) {
 516โ”‚ 	t.Parallel()
 517โ”‚ 
 518โ”‚ 	type args struct {
 519โ”‚ 		i int
 520โ”‚ 	}
 521โ”‚ 
 522โ”‚ 	tests := []struct {
 523โ”‚ 		name string
 524โ”‚ 		args args
 525โ”‚ 	}{
 526โ”‚ 		{
 527โ”‚ 			name: "",
 528โ”‚ 			args: args{i: 0},
 529โ”‚ 		},
 530โ”‚ 		{
 531โ”‚ 			name: "",
 532โ”‚ 			args: args{i: 1},
 533โ”‚ 		},
 534โ”‚ 		{
 535โ”‚ 			name: "",
 536โ”‚ 			args: args{i: 2},
 537โ”‚ 		},
 538โ”‚ 	}
 539โ”‚ 
 540โ”‚ 	for _, tt := range tests {
 541โ”‚ 		tt := tt
 542โ”‚ 		t.Run(tt.name, func(t *testing.T) {
 543โ”‚ 			t.Parallel()
 544โ”‚ 			s := &gemini.Server{}
 545โ”‚ 			var wg sync.WaitGroup
 546โ”‚ 			wg.Add(tt.args.i)
 547โ”‚ 
 548โ”‚ 			for i := 0; i < tt.args.i; i++ {
 549โ”‚ 				s.RegisterOnShutdown(func() { wg.Done() })
 550โ”‚ 			}
 551โ”‚ 
 552โ”‚ 			l, err := net.Listen("tcp", "localhost:0")
 553โ”‚ 			if err != nil {
 554โ”‚ 				t.Fatalf("unable to open listener: %s", err)
 555โ”‚ 			}
 556โ”‚ 
 557โ”‚ 			cert, err := tls.LoadX509KeyPair("testdata/cert.pem", "testdata/key.pem")
 558โ”‚ 			if err != nil {
 559โ”‚ 				t.Fatalf("unable to open listener: %s", err)
 560โ”‚ 			}
 561โ”‚ 
 562โ”‚ 			config := &tls.Config{
 563โ”‚ 				Certificates: []tls.Certificate{cert},
 564โ”‚ 			}
 565โ”‚ 
 566โ”‚ 			l = tls.NewListener(l, config)
 567โ”‚ 
 568โ”‚ 			go func() {
 569โ”‚ 				defer s.Shutdown(context.Background())
 570โ”‚ 				time.Sleep(5 * time.Millisecond)
 571โ”‚ 			}()
 572โ”‚ 
 573โ”‚ 			if err := s.Serve(l); err != nil && !errors.Is(err, gemini.ErrServerShutdown) {
 574โ”‚ 				t.Errorf("Server.Serve(%v) error = %v", l, err)
 575โ”‚ 			}
 576โ”‚ 
 577โ”‚ 			wg.Wait()
 578โ”‚ 		})
 579โ”‚ 	}
 580โ”‚ }
 581โ”‚ 
 582โ”‚ func TestServer_Shutdown(t *testing.T) {
 583โ”‚ 	t.Parallel()
 584โ”‚ 
 585โ”‚ 	type fields struct {
 586โ”‚ 		Handler     gemini.Handler
 587โ”‚ 		LogHandler  func(message string, isError bool)
 588โ”‚ 		BaseContext func(net.Listener) context.Context
 589โ”‚ 		ConnContext func(ctx context.Context, c net.Conn) context.Context
 590โ”‚ 		TLSConfig   *tls.Config
 591โ”‚ 		Addr        string
 592โ”‚ 	}
 593โ”‚ 
 594โ”‚ 	type args struct {
 595โ”‚ 		ctx context.Context
 596โ”‚ 	}
 597โ”‚ 
 598โ”‚ 	tests := []struct {
 599โ”‚ 		args    args
 600โ”‚ 		fields  fields
 601โ”‚ 		name    string
 602โ”‚ 		wantErr bool
 603โ”‚ 	}{
 604โ”‚ 		// TODO: Add test cases.
 605โ”‚ 	}
 606โ”‚ 
 607โ”‚ 	for _, tt := range tests {
 608โ”‚ 		tt := tt
 609โ”‚ 		t.Run(tt.name, func(t *testing.T) {
 610โ”‚ 			t.Parallel()
 611โ”‚ 			s := &gemini.Server{
 612โ”‚ 				Handler:     tt.fields.Handler,
 613โ”‚ 				LogHandler:  tt.fields.LogHandler,
 614โ”‚ 				BaseContext: tt.fields.BaseContext,
 615โ”‚ 				ConnContext: tt.fields.ConnContext,
 616โ”‚ 				TLSConfig:   tt.fields.TLSConfig,
 617โ”‚ 			}
 618โ”‚ 			if err := s.Shutdown(tt.args.ctx); (err != nil) != tt.wantErr {
 619โ”‚ 				t.Errorf("Server.Shutdown(%v) error = %v, wantErr %v", tt.args.ctx, err, tt.wantErr)
 620โ”‚ 			}
 621โ”‚ 		})
 622โ”‚ 	}
 623โ”‚ }
โ”€โ”€โ”€โ”€โ•ฏ

ยท ยท ยท

๐Ÿก Home

FAQs

Privacy Policy

Terms & Conditions

Official Gemlog

info@source.community

ยฉ 2023 source.community