-
Notifications
You must be signed in to change notification settings - Fork 24
/
info_test.go
127 lines (117 loc) · 2.51 KB
/
info_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
// Copyright 2014 Mikio Hara. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin freebsd linux netbsd
package tcp_test
import (
"crypto/tls"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net"
"net/http"
"runtime"
"testing"
"time"
"github.com/mikioh/tcp"
"github.com/mikioh/tcpinfo"
)
var infoTests = []struct {
host, url string
}{
{
host: "golang.org",
url: "https://golang.org/robots.txt",
},
{
host: "github.com",
url: "https://github.com/robots.txt",
},
}
func TestInfo(t *testing.T) {
switch runtime.GOOS {
case "darwin":
vers := kernelVersion()
if vers == nil || vers[0] < 15 {
t.Skipf("not supported on %v, %s/%s", vers, runtime.GOOS, runtime.GOARCH)
}
case "freebsd", "linux", "netbsd":
default:
t.Skipf("not supported on %s/%s", runtime.GOOS, runtime.GOARCH)
}
var logs []chan string
for i := 0; i < len(infoTests); i++ {
logs = append(logs, make(chan string, 100))
}
for i, tt := range infoTests {
sig := make(chan struct{}, 1)
tr := &http.Transport{
Dial: func(network, address string) (net.Conn, error) {
d := net.Dialer{DualStack: true}
c, err := d.Dial(network, address)
if err != nil {
return nil, err
}
tc, err := tcp.NewConn(c)
if err != nil {
c.Close()
return nil, err
}
go monitor(tc, logs[i], sig)
return tc.Conn, nil
},
TLSClientConfig: &tls.Config{ServerName: tt.host},
}
client := http.Client{Transport: tr}
resp, err := client.Get(tt.url)
if err != nil {
t.Fatal(err)
}
if _, err := io.Copy(ioutil.Discard, resp.Body); err != nil {
t.Fatal(err)
}
sig <- struct{}{}
resp.Body.Close()
}
for _, log := range logs {
for r := range log {
t.Log(r)
}
}
}
func monitor(c *tcp.Conn, log chan<- string, sig <-chan struct{}) {
defer close(log)
log <- fmt.Sprintf("%s %v->%v", c.LocalAddr().Network(), c.LocalAddr(), c.RemoteAddr())
var o tcpinfo.Info
var b [256]byte
for {
i, err := c.Option(o.Level(), o.Name(), b[:])
if err != nil {
return
}
txt, err := json.MarshalIndent(i, "", "\t")
if err != nil {
continue
}
if runtime.GOOS == "linux" {
var oo tcpinfo.CCInfo
ci, err := c.Option(oo.Level(), oo.Name(), b[:])
if err != nil {
return
}
ctxt, err := json.MarshalIndent(ci, "", "\t")
if err != nil {
continue
}
txt = append(txt, ctxt...)
}
select {
case <-sig:
return
default:
log <- string(txt)
time.Sleep(100 * time.Millisecond)
}
}
}