Sign in

Search issue titles and bodies, change requests and comments. Private repositories you cannot read are not included.

vole
Clone

Read only, no credentials:

https://rodent.software/vole.git

Write over SSH with a registered key:

git clone ssh://git@rodent.software:2222/vole.git

A free and open-source forge that lives in your Git repo.

Code

395 commit(s) on main

update readme Keenan Nemetz · 28m ago 32290114
history blame raw 1.2 KiB
1package ssh
2
3import (
4 "testing"
5 "time"
6)
7
8// A closed server has nothing running. The test harness removes its temporary
9// directory as the last cleanup step, and a handler that is still finishing a
10// disconnect — writing the last row, dropping the session — would race that removal
11// and leave the directory non-empty. So Close ends the connections it is serving and
12// waits, and this is the contract that makes it worth doing.
13func TestClosingTheServerEndsItsConnections(t *testing.T) {
14 t.Parallel()
15 h := newHarness(t)
16 c := h.runner(t, h.keyPath)
17 if rep := c.call(runnerRequest{Op: "ping"}); rep.Error != "" {
18 t.Fatal(rep.Error)
19 }
20
21 if err := h.srv.Close(); err != nil {
22 t.Fatalf("close: %v", err)
23 }
24
25 // The session ends because the server ended the connection under it. Waiting for
26 // it is the assertion: a server that let a handler outlive Close would leave this
27 // hanging, and that handler would be free to write into the directory the caller
28 // is about to remove. The error itself is not interesting — EOF is the answer.
29 waited := make(chan error, 1)
30 go func() { waited <- c.sess.Wait() }()
31 select {
32 case <-waited:
33 case <-time.After(5 * time.Second):
34 t.Fatal("the session stayed open after the server closed")
35 }
36}
37