@@ -4,6 +4,9 @@ package caddy_remote_host
4
4
// public API see package caddy_remote_host_test.
5
5
6
6
import (
7
+ "context"
8
+ "errors"
9
+ "net"
7
10
"testing"
8
11
9
12
"github.com/caddyserver/caddy/v2"
@@ -19,5 +22,92 @@ func TestMatchRemoteHost_Provision(t *testing.T) {
19
22
require .NoError (t , err )
20
23
assert .NotNil (t , subject .logger )
21
24
assert .NotNil (t , subject .cache )
25
+ assert .Nil (t , subject .resolver )
22
26
assert .NotNil (t , hostRegex )
23
27
}
28
+
29
+ type lookupResult struct {
30
+ ips []net.IPAddr
31
+ err error
32
+ }
33
+
34
+ func resolvesTo (ips ... string ) lookupResult {
35
+ r := lookupResult {ips : make ([]net.IPAddr , len (ips ))}
36
+ for i , ip := range ips {
37
+ r .ips [i ] = net.IPAddr {IP : net .ParseIP (ip )}
38
+ }
39
+ return r
40
+ }
41
+
42
+ type mockResolver struct {
43
+ addrs map [string ]lookupResult
44
+ }
45
+
46
+ func (m * mockResolver ) LookupIPAddr (_ context.Context , h string ) ([]net.IPAddr , error ) {
47
+ if result , ok := m .addrs [h ]; ok {
48
+ return result .ips , result .err
49
+ }
50
+ return nil , errors .New ("no suitable address found" )
51
+ }
52
+
53
+ func TestMatchRemoteHost_resolveIPs (t * testing.T ) {
54
+ require := require .New (t )
55
+ assert := assert .New (t )
56
+
57
+ mock := & mockResolver {
58
+ addrs : map [string ]lookupResult {
59
+ "example.com" : resolvesTo ("127.0.0.1" , "127.0.0.2" ),
60
+ "example.org" : resolvesTo ("::1" , "fe80::1" ),
61
+ "nil.records.example" : {},
62
+ "no.records.example" : {ips : make ([]net.IPAddr , 0 )},
63
+ },
64
+ }
65
+
66
+ subject := MatchRemoteHost {resolver : mock }
67
+ for host := range mock .addrs {
68
+ subject .Hosts = append (subject .Hosts , host )
69
+ }
70
+
71
+ require .NoError (subject .Provision (caddy.Context {}))
72
+ ips , err := subject .resolveIPs ()
73
+ require .NoError (err )
74
+
75
+ var haveIPs []string
76
+ for _ , result := range mock .addrs {
77
+ for _ , ip := range result .ips {
78
+ haveIPs = append (haveIPs , ip .String ())
79
+ }
80
+ }
81
+
82
+ toStrings := func (ips []net.IP ) []string {
83
+ s := make ([]string , len (ips ))
84
+ for i , ip := range ips {
85
+ s [i ] = ip .String ()
86
+ }
87
+ return s
88
+ }
89
+
90
+ assert .ElementsMatch (haveIPs , toStrings (ips ))
91
+
92
+ cachedIPs , ok := subject .cache .Get (cacheKey )
93
+ require .True (ok )
94
+ require .NotNil (cachedIPs )
95
+ assert .ElementsMatch (haveIPs , toStrings (cachedIPs .([]net.IP )))
96
+ }
97
+
98
+ func TestMatchRemoteHost_resolveIPs_failure (t * testing.T ) {
99
+ subject := MatchRemoteHost {
100
+ Hosts : []string {"example.com" },
101
+ resolver : & mockResolver {map [string ]lookupResult {
102
+ "example.com" : {err : & net.DNSError {Err : "no suitable host found" }},
103
+ }},
104
+ }
105
+
106
+ require .NoError (t , subject .Provision (caddy.Context {}))
107
+
108
+ ips , err := subject .resolveIPs ()
109
+ // XXX: the expected message is constructed within package net
110
+ // and might change with future Go versions
111
+ assert .EqualError (t , err , "lookup : no suitable host found" )
112
+ assert .Empty (t , ips )
113
+ }
0 commit comments