mirror of
				https://github.com/etcd-io/etcd.git
				synced 2024-09-27 06:25:44 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			213 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			213 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Copyright 2015 The etcd Authors
 | |
| //
 | |
| // 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.
 | |
| 
 | |
| package flags
 | |
| 
 | |
| import (
 | |
| 	"flag"
 | |
| 	"net/url"
 | |
| 	"os"
 | |
| 	"reflect"
 | |
| 	"testing"
 | |
| 
 | |
| 	"github.com/coreos/etcd/pkg/transport"
 | |
| )
 | |
| 
 | |
| func TestSetFlagsFromEnv(t *testing.T) {
 | |
| 	fs := flag.NewFlagSet("testing", flag.ExitOnError)
 | |
| 	fs.String("a", "", "")
 | |
| 	fs.String("b", "", "")
 | |
| 	fs.String("c", "", "")
 | |
| 	fs.Parse([]string{})
 | |
| 
 | |
| 	os.Clearenv()
 | |
| 	// flags should be settable using env vars
 | |
| 	os.Setenv("ETCD_A", "foo")
 | |
| 	// and command-line flags
 | |
| 	if err := fs.Set("b", "bar"); err != nil {
 | |
| 		t.Fatal(err)
 | |
| 	}
 | |
| 	// command-line flags take precedence over env vars
 | |
| 	os.Setenv("ETCD_C", "woof")
 | |
| 	if err := fs.Set("c", "quack"); err != nil {
 | |
| 		t.Fatal(err)
 | |
| 	}
 | |
| 
 | |
| 	// first verify that flags are as expected before reading the env
 | |
| 	for f, want := range map[string]string{
 | |
| 		"a": "",
 | |
| 		"b": "bar",
 | |
| 		"c": "quack",
 | |
| 	} {
 | |
| 		if got := fs.Lookup(f).Value.String(); got != want {
 | |
| 			t.Fatalf("flag %q=%q, want %q", f, got, want)
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	// now read the env and verify flags were updated as expected
 | |
| 	err := SetFlagsFromEnv("ETCD", fs)
 | |
| 	if err != nil {
 | |
| 		t.Errorf("err=%v, want nil", err)
 | |
| 	}
 | |
| 	for f, want := range map[string]string{
 | |
| 		"a": "foo",
 | |
| 		"b": "bar",
 | |
| 		"c": "quack",
 | |
| 	} {
 | |
| 		if got := fs.Lookup(f).Value.String(); got != want {
 | |
| 			t.Errorf("flag %q=%q, want %q", f, got, want)
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func TestSetFlagsFromEnvBad(t *testing.T) {
 | |
| 	// now verify that an error is propagated
 | |
| 	fs := flag.NewFlagSet("testing", flag.ExitOnError)
 | |
| 	fs.Int("x", 0, "")
 | |
| 	os.Setenv("ETCD_X", "not_a_number")
 | |
| 	if err := SetFlagsFromEnv("ETCD", fs); err == nil {
 | |
| 		t.Errorf("err=nil, want != nil")
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func TestSetBindAddrFromAddr(t *testing.T) {
 | |
| 	tests := []struct {
 | |
| 		args  []string
 | |
| 		waddr *IPAddressPort
 | |
| 	}{
 | |
| 		// no flags set
 | |
| 		{
 | |
| 			args:  []string{},
 | |
| 			waddr: &IPAddressPort{},
 | |
| 		},
 | |
| 		// addr flag set
 | |
| 		{
 | |
| 			args:  []string{"-addr=192.0.3.17:2379"},
 | |
| 			waddr: &IPAddressPort{IP: "::", Port: 2379},
 | |
| 		},
 | |
| 		// bindAddr flag set
 | |
| 		{
 | |
| 			args:  []string{"-bind-addr=127.0.0.1:2379"},
 | |
| 			waddr: &IPAddressPort{IP: "127.0.0.1", Port: 2379},
 | |
| 		},
 | |
| 		// both addr flags set
 | |
| 		{
 | |
| 			args:  []string{"-bind-addr=127.0.0.1:2379", "-addr=192.0.3.17:2379"},
 | |
| 			waddr: &IPAddressPort{IP: "127.0.0.1", Port: 2379},
 | |
| 		},
 | |
| 		// both addr flags set, IPv6
 | |
| 		{
 | |
| 			args:  []string{"-bind-addr=[2001:db8::4:9]:2379", "-addr=[2001:db8::4:f0]:2379"},
 | |
| 			waddr: &IPAddressPort{IP: "2001:db8::4:9", Port: 2379},
 | |
| 		},
 | |
| 	}
 | |
| 	for i, tt := range tests {
 | |
| 		fs := flag.NewFlagSet("test", flag.PanicOnError)
 | |
| 		fs.Var(&IPAddressPort{}, "addr", "")
 | |
| 		bindAddr := &IPAddressPort{}
 | |
| 		fs.Var(bindAddr, "bind-addr", "")
 | |
| 		if err := fs.Parse(tt.args); err != nil {
 | |
| 			t.Errorf("#%d: failed to parse flags: %v", i, err)
 | |
| 			continue
 | |
| 		}
 | |
| 		SetBindAddrFromAddr(fs, "bind-addr", "addr")
 | |
| 
 | |
| 		if !reflect.DeepEqual(bindAddr, tt.waddr) {
 | |
| 			t.Errorf("#%d: bindAddr = %+v, want %+v", i, bindAddr, tt.waddr)
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func TestURLsFromFlags(t *testing.T) {
 | |
| 	tests := []struct {
 | |
| 		args     []string
 | |
| 		tlsInfo  transport.TLSInfo
 | |
| 		wantURLs []url.URL
 | |
| 		wantFail bool
 | |
| 	}{
 | |
| 		// use -urls default when no flags defined
 | |
| 		{
 | |
| 			args:    []string{},
 | |
| 			tlsInfo: transport.TLSInfo{},
 | |
| 			wantURLs: []url.URL{
 | |
| 				{Scheme: "http", Host: "127.0.0.1:2379"},
 | |
| 			},
 | |
| 			wantFail: false,
 | |
| 		},
 | |
| 
 | |
| 		// explicitly setting -urls should carry through
 | |
| 		{
 | |
| 			args:    []string{"-urls=https://192.0.3.17:2930,http://127.0.0.1:1024"},
 | |
| 			tlsInfo: transport.TLSInfo{},
 | |
| 			wantURLs: []url.URL{
 | |
| 				{Scheme: "http", Host: "127.0.0.1:1024"},
 | |
| 				{Scheme: "https", Host: "192.0.3.17:2930"},
 | |
| 			},
 | |
| 			wantFail: false,
 | |
| 		},
 | |
| 
 | |
| 		// explicitly setting -addr should carry through
 | |
| 		{
 | |
| 			args:    []string{"-addr=192.0.2.3:1024"},
 | |
| 			tlsInfo: transport.TLSInfo{},
 | |
| 			wantURLs: []url.URL{
 | |
| 				{Scheme: "http", Host: "192.0.2.3:1024"},
 | |
| 			},
 | |
| 			wantFail: false,
 | |
| 		},
 | |
| 
 | |
| 		// scheme prepended to -addr should be https if TLSInfo non-empty
 | |
| 		{
 | |
| 			args: []string{"-addr=192.0.2.3:1024"},
 | |
| 			tlsInfo: transport.TLSInfo{
 | |
| 				CertFile: "/tmp/foo",
 | |
| 				KeyFile:  "/tmp/bar",
 | |
| 			},
 | |
| 			wantURLs: []url.URL{
 | |
| 				{Scheme: "https", Host: "192.0.2.3:1024"},
 | |
| 			},
 | |
| 			wantFail: false,
 | |
| 		},
 | |
| 
 | |
| 		// explicitly setting both -urls and -addr should fail
 | |
| 		{
 | |
| 			args:     []string{"-urls=https://127.0.0.1:1024", "-addr=192.0.2.3:1024"},
 | |
| 			tlsInfo:  transport.TLSInfo{},
 | |
| 			wantURLs: nil,
 | |
| 			wantFail: true,
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	for i, tt := range tests {
 | |
| 		fs := flag.NewFlagSet("test", flag.PanicOnError)
 | |
| 		fs.Var(NewURLsValue("http://127.0.0.1:2379"), "urls", "")
 | |
| 		fs.Var(&IPAddressPort{}, "addr", "")
 | |
| 
 | |
| 		if err := fs.Parse(tt.args); err != nil {
 | |
| 			t.Errorf("#%d: failed to parse flags: %v", i, err)
 | |
| 			continue
 | |
| 		}
 | |
| 
 | |
| 		gotURLs, err := URLsFromFlags(fs, "urls", "addr", tt.tlsInfo)
 | |
| 		if tt.wantFail != (err != nil) {
 | |
| 			t.Errorf("#%d: wantFail=%t, got err=%v", i, tt.wantFail, err)
 | |
| 			continue
 | |
| 		}
 | |
| 
 | |
| 		if !reflect.DeepEqual(tt.wantURLs, gotURLs) {
 | |
| 			t.Errorf("#%d: incorrect URLs\nwant=%#v\ngot=%#v", i, tt.wantURLs, gotURLs)
 | |
| 		}
 | |
| 	}
 | |
| }
 | 
