1package resolver 2 3import ( 4 "context" 5 "io" 6 "net" 7 "time" 8 9 "github.com/ooni/probe-cli/v3/internal/engine/atomicx" 10) 11 12type FakeDialer struct { 13 Conn net.Conn 14 Err error 15} 16 17func (d FakeDialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) { 18 time.Sleep(10 * time.Microsecond) 19 return d.Conn, d.Err 20} 21 22type FakeConn struct { 23 ReadError error 24 ReadData []byte 25 SetDeadlineError error 26 SetReadDeadlineError error 27 SetWriteDeadlineError error 28 WriteError error 29} 30 31func (c *FakeConn) Read(b []byte) (int, error) { 32 if len(c.ReadData) > 0 { 33 n := copy(b, c.ReadData) 34 c.ReadData = c.ReadData[n:] 35 return n, nil 36 } 37 if c.ReadError != nil { 38 return 0, c.ReadError 39 } 40 return 0, io.EOF 41} 42 43func (c *FakeConn) Write(b []byte) (n int, err error) { 44 if c.WriteError != nil { 45 return 0, c.WriteError 46 } 47 n = len(b) 48 return 49} 50 51func (*FakeConn) Close() (err error) { 52 return 53} 54 55func (*FakeConn) LocalAddr() net.Addr { 56 return &net.TCPAddr{} 57} 58 59func (*FakeConn) RemoteAddr() net.Addr { 60 return &net.TCPAddr{} 61} 62 63func (c *FakeConn) SetDeadline(t time.Time) (err error) { 64 return c.SetDeadlineError 65} 66 67func (c *FakeConn) SetReadDeadline(t time.Time) (err error) { 68 return c.SetReadDeadlineError 69} 70 71func (c *FakeConn) SetWriteDeadline(t time.Time) (err error) { 72 return c.SetWriteDeadlineError 73} 74 75type FakeTransport struct { 76 Data []byte 77 Err error 78} 79 80func (ft FakeTransport) RoundTrip(ctx context.Context, query []byte) ([]byte, error) { 81 return ft.Data, ft.Err 82} 83 84func (ft FakeTransport) RequiresPadding() bool { 85 return false 86} 87 88func (ft FakeTransport) Address() string { 89 return "" 90} 91 92func (ft FakeTransport) Network() string { 93 return "fake" 94} 95 96type FakeEncoder struct { 97 Data []byte 98 Err error 99} 100 101func (fe FakeEncoder) Encode(domain string, qtype uint16, padding bool) ([]byte, error) { 102 return fe.Data, fe.Err 103} 104 105type FakeResolver struct { 106 NumFailures *atomicx.Int64 107 Err error 108 Result []string 109} 110 111func NewFakeResolverThatFails() FakeResolver { 112 return FakeResolver{NumFailures: atomicx.NewInt64(), Err: errNotFound} 113} 114 115func NewFakeResolverWithResult(r []string) FakeResolver { 116 return FakeResolver{NumFailures: atomicx.NewInt64(), Result: r} 117} 118 119var errNotFound = &net.DNSError{ 120 Err: "no such host", 121} 122 123func (c FakeResolver) LookupHost(ctx context.Context, hostname string) ([]string, error) { 124 time.Sleep(10 * time.Microsecond) 125 if c.Err != nil { 126 if c.NumFailures != nil { 127 c.NumFailures.Add(1) 128 } 129 return nil, c.Err 130 } 131 return c.Result, nil 132} 133 134func (c FakeResolver) Network() string { 135 return "fake" 136} 137 138func (c FakeResolver) Address() string { 139 return "" 140} 141 142var _ Resolver = FakeResolver{} 143