2016-05-13 06:48:53 +03:00
// Copyright 2015 The etcd Authors
2015-01-25 06:19:16 +03:00
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
2014-12-24 11:29:28 +03:00
package netutil
import (
2017-04-21 19:59:34 +03:00
"context"
2014-12-24 11:29:28 +03:00
"errors"
"net"
"net/url"
"reflect"
"strconv"
"testing"
2016-12-15 01:07:33 +03:00
"time"
2018-04-27 21:40:13 +03:00
"go.uber.org/zap"
2014-12-24 11:29:28 +03:00
)
func TestResolveTCPAddrs ( t * testing . T ) {
2017-04-21 19:59:34 +03:00
defer func ( ) { resolveTCPAddr = resolveTCPAddrDefault } ( )
2014-12-24 11:29:28 +03:00
tests := [ ] struct {
urls [ ] [ ] url . URL
expected [ ] [ ] url . URL
hostMap map [ string ] string
hasError bool
} {
{
urls : [ ] [ ] url . URL {
2015-08-22 04:52:16 +03:00
{
{ Scheme : "http" , Host : "127.0.0.1:4001" } ,
{ Scheme : "http" , Host : "127.0.0.1:2379" } ,
2014-12-24 11:29:28 +03:00
} ,
2015-08-22 04:52:16 +03:00
{
{ Scheme : "http" , Host : "127.0.0.1:7001" } ,
{ Scheme : "http" , Host : "127.0.0.1:2380" } ,
2014-12-24 11:29:28 +03:00
} ,
} ,
expected : [ ] [ ] url . URL {
2015-08-22 04:52:16 +03:00
{
{ Scheme : "http" , Host : "127.0.0.1:4001" } ,
{ Scheme : "http" , Host : "127.0.0.1:2379" } ,
2014-12-24 11:29:28 +03:00
} ,
2015-08-22 04:52:16 +03:00
{
{ Scheme : "http" , Host : "127.0.0.1:7001" } ,
{ Scheme : "http" , Host : "127.0.0.1:2380" } ,
2014-12-24 11:29:28 +03:00
} ,
} ,
} ,
{
urls : [ ] [ ] url . URL {
2015-08-22 04:52:16 +03:00
{
{ Scheme : "http" , Host : "infra0.example.com:4001" } ,
{ Scheme : "http" , Host : "infra0.example.com:2379" } ,
2014-12-24 11:29:28 +03:00
} ,
2015-08-22 04:52:16 +03:00
{
{ Scheme : "http" , Host : "infra0.example.com:7001" } ,
{ Scheme : "http" , Host : "infra0.example.com:2380" } ,
2014-12-24 11:29:28 +03:00
} ,
} ,
expected : [ ] [ ] url . URL {
2015-08-22 04:52:16 +03:00
{
{ Scheme : "http" , Host : "10.0.1.10:4001" } ,
{ Scheme : "http" , Host : "10.0.1.10:2379" } ,
2014-12-24 11:29:28 +03:00
} ,
2015-08-22 04:52:16 +03:00
{
{ Scheme : "http" , Host : "10.0.1.10:7001" } ,
{ Scheme : "http" , Host : "10.0.1.10:2380" } ,
2014-12-24 11:29:28 +03:00
} ,
} ,
hostMap : map [ string ] string {
"infra0.example.com" : "10.0.1.10" ,
} ,
hasError : false ,
} ,
{
urls : [ ] [ ] url . URL {
2015-08-22 04:52:16 +03:00
{
{ Scheme : "http" , Host : "infra0.example.com:4001" } ,
{ Scheme : "http" , Host : "infra0.example.com:2379" } ,
2014-12-24 11:29:28 +03:00
} ,
2015-08-22 04:52:16 +03:00
{
{ Scheme : "http" , Host : "infra0.example.com:7001" } ,
{ Scheme : "http" , Host : "infra0.example.com:2380" } ,
2014-12-24 11:29:28 +03:00
} ,
} ,
hostMap : map [ string ] string {
"infra0.example.com" : "" ,
} ,
hasError : true ,
} ,
{
urls : [ ] [ ] url . URL {
2015-08-22 04:52:16 +03:00
{
{ Scheme : "http" , Host : "ssh://infra0.example.com:4001" } ,
{ Scheme : "http" , Host : "ssh://infra0.example.com:2379" } ,
2014-12-24 11:29:28 +03:00
} ,
2015-08-22 04:52:16 +03:00
{
{ Scheme : "http" , Host : "ssh://infra0.example.com:7001" } ,
{ Scheme : "http" , Host : "ssh://infra0.example.com:2380" } ,
2014-12-24 11:29:28 +03:00
} ,
} ,
hasError : true ,
} ,
}
for _ , tt := range tests {
2017-04-21 19:59:34 +03:00
resolveTCPAddr = func ( ctx context . Context , addr string ) ( * net . TCPAddr , error ) {
2014-12-24 11:29:28 +03:00
host , port , err := net . SplitHostPort ( addr )
if err != nil {
return nil , err
}
if tt . hostMap [ host ] == "" {
2018-04-27 21:40:13 +03:00
return nil , errors . New ( "cannot resolve host" )
2014-12-24 11:29:28 +03:00
}
i , err := strconv . Atoi ( port )
if err != nil {
return nil , err
}
return & net . TCPAddr { IP : net . ParseIP ( tt . hostMap [ host ] ) , Port : i , Zone : "" } , nil
}
2016-12-15 01:07:33 +03:00
ctx , cancel := context . WithTimeout ( context . TODO ( ) , time . Second )
2018-04-27 21:40:13 +03:00
urls , err := resolveTCPAddrs ( ctx , zap . NewExample ( ) , tt . urls )
2016-12-15 01:07:33 +03:00
cancel ( )
2014-12-24 11:29:28 +03:00
if tt . hasError {
if err == nil {
t . Errorf ( "expected error" )
}
continue
}
2015-08-21 22:09:17 +03:00
if ! reflect . DeepEqual ( urls , tt . expected ) {
t . Errorf ( "expected: %v, got %v" , tt . expected , urls )
2014-12-24 11:29:28 +03:00
}
}
}
2015-08-21 19:41:13 +03:00
func TestURLsEqual ( t * testing . T ) {
2017-04-21 19:59:34 +03:00
defer func ( ) { resolveTCPAddr = resolveTCPAddrDefault } ( )
2015-08-21 20:15:08 +03:00
hostm := map [ string ] string {
"example.com" : "10.0.10.1" ,
"first.com" : "10.0.11.1" ,
"second.com" : "10.0.11.2" ,
}
2017-04-21 19:59:34 +03:00
resolveTCPAddr = func ( ctx context . Context , addr string ) ( * net . TCPAddr , error ) {
2017-04-07 20:43:05 +03:00
host , port , herr := net . SplitHostPort ( addr )
if herr != nil {
return nil , herr
}
2015-08-21 20:15:08 +03:00
if _ , ok := hostm [ host ] ; ! ok {
2015-08-21 19:41:13 +03:00
return nil , errors . New ( "cannot resolve host." )
}
i , err := strconv . Atoi ( port )
if err != nil {
return nil , err
}
2015-08-21 20:15:08 +03:00
return & net . TCPAddr { IP : net . ParseIP ( hostm [ host ] ) , Port : i , Zone : "" } , nil
2015-08-21 19:41:13 +03:00
}
tests := [ ] struct {
a [ ] url . URL
b [ ] url . URL
expect bool
2018-01-25 21:31:59 +03:00
err error
2015-08-21 19:41:13 +03:00
} {
{
a : [ ] url . URL { { Scheme : "http" , Host : "127.0.0.1:2379" } } ,
b : [ ] url . URL { { Scheme : "http" , Host : "127.0.0.1:2379" } } ,
expect : true ,
} ,
{
a : [ ] url . URL { { Scheme : "http" , Host : "example.com:2379" } } ,
b : [ ] url . URL { { Scheme : "http" , Host : "10.0.10.1:2379" } } ,
expect : true ,
} ,
2017-08-31 22:41:05 +03:00
{
a : [ ] url . URL { { Scheme : "http" , Host : "example.com:2379" } } ,
b : [ ] url . URL { { Scheme : "https" , Host : "10.0.10.1:2379" } } ,
expect : false ,
2018-01-25 21:31:59 +03:00
err : errors . New ( ` "http://10.0.10.1:2379"(resolved from "http://example.com:2379") != "https://10.0.10.1:2379"(resolved from "https://10.0.10.1:2379") ` ) ,
2017-08-31 22:41:05 +03:00
} ,
{
a : [ ] url . URL { { Scheme : "https" , Host : "example.com:2379" } } ,
b : [ ] url . URL { { Scheme : "http" , Host : "10.0.10.1:2379" } } ,
expect : false ,
2018-01-25 21:31:59 +03:00
err : errors . New ( ` "https://10.0.10.1:2379"(resolved from "https://example.com:2379") != "http://10.0.10.1:2379"(resolved from "http://10.0.10.1:2379") ` ) ,
2017-08-31 22:41:05 +03:00
} ,
{
a : [ ] url . URL { { Scheme : "unix" , Host : "abc:2379" } } ,
b : [ ] url . URL { { Scheme : "unix" , Host : "abc:2379" } } ,
expect : true ,
} ,
2015-08-21 19:41:13 +03:00
{
a : [ ] url . URL { { Scheme : "http" , Host : "127.0.0.1:2379" } , { Scheme : "http" , Host : "127.0.0.1:2380" } } ,
b : [ ] url . URL { { Scheme : "http" , Host : "127.0.0.1:2379" } , { Scheme : "http" , Host : "127.0.0.1:2380" } } ,
expect : true ,
} ,
{
a : [ ] url . URL { { Scheme : "http" , Host : "example.com:2379" } , { Scheme : "http" , Host : "127.0.0.1:2380" } } ,
b : [ ] url . URL { { Scheme : "http" , Host : "example.com:2379" } , { Scheme : "http" , Host : "127.0.0.1:2380" } } ,
expect : true ,
} ,
{
a : [ ] url . URL { { Scheme : "http" , Host : "10.0.10.1:2379" } , { Scheme : "http" , Host : "127.0.0.1:2380" } } ,
b : [ ] url . URL { { Scheme : "http" , Host : "example.com:2379" } , { Scheme : "http" , Host : "127.0.0.1:2380" } } ,
expect : true ,
} ,
{
a : [ ] url . URL { { Scheme : "http" , Host : "127.0.0.1:2379" } } ,
b : [ ] url . URL { { Scheme : "http" , Host : "127.0.0.1:2380" } } ,
expect : false ,
2018-01-25 21:31:59 +03:00
err : errors . New ( ` "http://127.0.0.1:2379"(resolved from "http://127.0.0.1:2379") != "http://127.0.0.1:2380"(resolved from "http://127.0.0.1:2380") ` ) ,
2015-08-21 19:41:13 +03:00
} ,
{
a : [ ] url . URL { { Scheme : "http" , Host : "example.com:2380" } } ,
b : [ ] url . URL { { Scheme : "http" , Host : "10.0.10.1:2379" } } ,
expect : false ,
2018-01-25 21:31:59 +03:00
err : errors . New ( ` "http://10.0.10.1:2380"(resolved from "http://example.com:2380") != "http://10.0.10.1:2379"(resolved from "http://10.0.10.1:2379") ` ) ,
2015-08-21 19:41:13 +03:00
} ,
{
a : [ ] url . URL { { Scheme : "http" , Host : "127.0.0.1:2379" } } ,
b : [ ] url . URL { { Scheme : "http" , Host : "10.0.0.1:2379" } } ,
expect : false ,
2018-01-25 21:31:59 +03:00
err : errors . New ( ` "http://127.0.0.1:2379"(resolved from "http://127.0.0.1:2379") != "http://10.0.0.1:2379"(resolved from "http://10.0.0.1:2379") ` ) ,
2015-08-21 19:41:13 +03:00
} ,
{
a : [ ] url . URL { { Scheme : "http" , Host : "example.com:2379" } } ,
b : [ ] url . URL { { Scheme : "http" , Host : "10.0.0.1:2379" } } ,
expect : false ,
2018-01-25 21:31:59 +03:00
err : errors . New ( ` "http://10.0.10.1:2379"(resolved from "http://example.com:2379") != "http://10.0.0.1:2379"(resolved from "http://10.0.0.1:2379") ` ) ,
2015-08-21 19:41:13 +03:00
} ,
{
a : [ ] url . URL { { Scheme : "http" , Host : "127.0.0.1:2379" } , { Scheme : "http" , Host : "127.0.0.1:2380" } } ,
b : [ ] url . URL { { Scheme : "http" , Host : "127.0.0.1:2380" } , { Scheme : "http" , Host : "127.0.0.1:2380" } } ,
expect : false ,
2018-01-25 21:31:59 +03:00
err : errors . New ( ` "http://127.0.0.1:2379"(resolved from "http://127.0.0.1:2379") != "http://127.0.0.1:2380"(resolved from "http://127.0.0.1:2380") ` ) ,
2015-08-21 19:41:13 +03:00
} ,
{
a : [ ] url . URL { { Scheme : "http" , Host : "example.com:2379" } , { Scheme : "http" , Host : "127.0.0.1:2380" } } ,
b : [ ] url . URL { { Scheme : "http" , Host : "127.0.0.1:2380" } , { Scheme : "http" , Host : "127.0.0.1:2380" } } ,
expect : false ,
2018-01-25 21:31:59 +03:00
err : errors . New ( ` "http://10.0.10.1:2379"(resolved from "http://example.com:2379") != "http://127.0.0.1:2380"(resolved from "http://127.0.0.1:2380") ` ) ,
2015-08-21 19:41:13 +03:00
} ,
{
a : [ ] url . URL { { Scheme : "http" , Host : "127.0.0.1:2379" } , { Scheme : "http" , Host : "127.0.0.1:2380" } } ,
b : [ ] url . URL { { Scheme : "http" , Host : "10.0.0.1:2379" } , { Scheme : "http" , Host : "127.0.0.1:2380" } } ,
expect : false ,
2018-01-25 21:31:59 +03:00
err : errors . New ( ` "http://127.0.0.1:2379"(resolved from "http://127.0.0.1:2379") != "http://10.0.0.1:2379"(resolved from "http://10.0.0.1:2379") ` ) ,
2015-08-21 19:41:13 +03:00
} ,
{
a : [ ] url . URL { { Scheme : "http" , Host : "example.com:2379" } , { Scheme : "http" , Host : "127.0.0.1:2380" } } ,
b : [ ] url . URL { { Scheme : "http" , Host : "10.0.0.1:2379" } , { Scheme : "http" , Host : "127.0.0.1:2380" } } ,
expect : false ,
2018-01-25 21:31:59 +03:00
err : errors . New ( ` "http://10.0.10.1:2379"(resolved from "http://example.com:2379") != "http://10.0.0.1:2379"(resolved from "http://10.0.0.1:2379") ` ) ,
2015-08-21 19:41:13 +03:00
} ,
{
a : [ ] url . URL { { Scheme : "http" , Host : "10.0.0.1:2379" } } ,
b : [ ] url . URL { { Scheme : "http" , Host : "10.0.0.1:2379" } , { Scheme : "http" , Host : "127.0.0.1:2380" } } ,
expect : false ,
2018-01-25 21:31:59 +03:00
err : errors . New ( ` len(["http://10.0.0.1:2379"]) != len(["http://10.0.0.1:2379" "http://127.0.0.1:2380"]) ` ) ,
2015-08-21 19:41:13 +03:00
} ,
2015-08-21 20:15:08 +03:00
{
a : [ ] url . URL { { Scheme : "http" , Host : "first.com:2379" } , { Scheme : "http" , Host : "second.com:2380" } } ,
b : [ ] url . URL { { Scheme : "http" , Host : "10.0.11.1:2379" } , { Scheme : "http" , Host : "10.0.11.2:2380" } } ,
expect : true ,
} ,
{
a : [ ] url . URL { { Scheme : "http" , Host : "second.com:2380" } , { Scheme : "http" , Host : "first.com:2379" } } ,
b : [ ] url . URL { { Scheme : "http" , Host : "10.0.11.1:2379" } , { Scheme : "http" , Host : "10.0.11.2:2380" } } ,
expect : true ,
} ,
2015-08-21 19:41:13 +03:00
}
2018-01-25 21:31:59 +03:00
for i , test := range tests {
2018-04-27 21:40:13 +03:00
result , err := urlsEqual ( context . TODO ( ) , zap . NewExample ( ) , test . a , test . b )
2015-08-21 19:41:13 +03:00
if result != test . expect {
2018-01-25 21:31:59 +03:00
t . Errorf ( "#%d: a:%v b:%v, expected %v but %v" , i , test . a , test . b , test . expect , result )
}
if test . err != nil {
if err . Error ( ) != test . err . Error ( ) {
t . Errorf ( "#%d: err expected %v but %v" , i , test . err , err )
}
2015-08-21 19:41:13 +03:00
}
}
}
func TestURLStringsEqual ( t * testing . T ) {
2018-04-27 21:40:13 +03:00
result , err := URLStringsEqual ( context . TODO ( ) , zap . NewExample ( ) , [ ] string { "http://127.0.0.1:8080" } , [ ] string { "http://127.0.0.1:8080" } )
2015-08-21 19:41:13 +03:00
if ! result {
t . Errorf ( "unexpected result %v" , result )
}
2018-01-25 21:31:59 +03:00
if err != nil {
t . Errorf ( "unexpected error %v" , err )
}
2015-08-21 19:41:13 +03:00
}