1// Copyright 2015 The etcd Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package etcdserver
16
17import (
18	"net/url"
19	"testing"
20
21	"github.com/coreos/etcd/pkg/types"
22)
23
24func mustNewURLs(t *testing.T, urls []string) []url.URL {
25	if len(urls) == 0 {
26		return nil
27	}
28	u, err := types.NewURLs(urls)
29	if err != nil {
30		t.Fatalf("error creating new URLs from %q: %v", urls, err)
31	}
32	return u
33}
34
35func TestConfigVerifyBootstrapWithoutClusterAndDiscoveryURLFail(t *testing.T) {
36	c := &ServerConfig{
37		Name:               "node1",
38		DiscoveryURL:       "",
39		InitialPeerURLsMap: types.URLsMap{},
40	}
41	if err := c.VerifyBootstrap(); err == nil {
42		t.Errorf("err = nil, want not nil")
43	}
44}
45
46func TestConfigVerifyExistingWithDiscoveryURLFail(t *testing.T) {
47	cluster, err := types.NewURLsMap("node1=http://127.0.0.1:2380")
48	if err != nil {
49		t.Fatalf("NewCluster error: %v", err)
50	}
51	c := &ServerConfig{
52		Name:               "node1",
53		DiscoveryURL:       "http://127.0.0.1:2379/abcdefg",
54		PeerURLs:           mustNewURLs(t, []string{"http://127.0.0.1:2380"}),
55		InitialPeerURLsMap: cluster,
56		NewCluster:         false,
57	}
58	if err := c.VerifyJoinExisting(); err == nil {
59		t.Errorf("err = nil, want not nil")
60	}
61}
62
63func TestConfigVerifyLocalMember(t *testing.T) {
64	tests := []struct {
65		clusterSetting string
66		apurls         []string
67		strict         bool
68		shouldError    bool
69	}{
70		{
71			// Node must exist in cluster
72			"",
73			nil,
74			true,
75
76			true,
77		},
78		{
79			// Initial cluster set
80			"node1=http://localhost:7001,node2=http://localhost:7002",
81			[]string{"http://localhost:7001"},
82			true,
83
84			false,
85		},
86		{
87			// Default initial cluster
88			"node1=http://localhost:2380,node1=http://localhost:7001",
89			[]string{"http://localhost:2380", "http://localhost:7001"},
90			true,
91
92			false,
93		},
94		{
95			// Advertised peer URLs must match those in cluster-state
96			"node1=http://localhost:7001",
97			[]string{"http://localhost:12345"},
98			true,
99
100			true,
101		},
102		{
103			// Advertised peer URLs must match those in cluster-state
104			"node1=http://localhost:2380,node1=http://localhost:12345",
105			[]string{"http://localhost:12345"},
106			true,
107
108			true,
109		},
110		{
111			// Advertised peer URLs must match those in cluster-state
112			"node1=http://localhost:2380",
113			[]string{},
114			true,
115
116			true,
117		},
118		{
119			// do not care about the urls if strict is not set
120			"node1=http://localhost:2380",
121			[]string{},
122			false,
123
124			false,
125		},
126	}
127
128	for i, tt := range tests {
129		cluster, err := types.NewURLsMap(tt.clusterSetting)
130		if err != nil {
131			t.Fatalf("#%d: Got unexpected error: %v", i, err)
132		}
133		cfg := ServerConfig{
134			Name:               "node1",
135			InitialPeerURLsMap: cluster,
136		}
137		if tt.apurls != nil {
138			cfg.PeerURLs = mustNewURLs(t, tt.apurls)
139		}
140		if err = cfg.hasLocalMember(); err == nil && tt.strict {
141			err = cfg.advertiseMatchesCluster()
142		}
143		if (err == nil) && tt.shouldError {
144			t.Errorf("#%d: Got no error where one was expected", i)
145		}
146		if (err != nil) && !tt.shouldError {
147			t.Errorf("#%d: Got unexpected error: %v", i, err)
148		}
149	}
150}
151
152func TestSnapDir(t *testing.T) {
153	tests := map[string]string{
154		"/":            "/member/snap",
155		"/var/lib/etc": "/var/lib/etc/member/snap",
156	}
157	for dd, w := range tests {
158		cfg := ServerConfig{
159			DataDir: dd,
160		}
161		if g := cfg.SnapDir(); g != w {
162			t.Errorf("DataDir=%q: SnapDir()=%q, want=%q", dd, g, w)
163		}
164	}
165}
166
167func TestWALDir(t *testing.T) {
168	tests := map[string]string{
169		"/":            "/member/wal",
170		"/var/lib/etc": "/var/lib/etc/member/wal",
171	}
172	for dd, w := range tests {
173		cfg := ServerConfig{
174			DataDir: dd,
175		}
176		if g := cfg.WALDir(); g != w {
177			t.Errorf("DataDir=%q: WALDir()=%q, want=%q", dd, g, w)
178		}
179	}
180}
181
182func TestShouldDiscover(t *testing.T) {
183	tests := map[string]bool{
184		"":    false,
185		"foo": true,
186		"http://discovery.etcd.io/asdf": true,
187	}
188	for durl, w := range tests {
189		cfg := ServerConfig{
190			DiscoveryURL: durl,
191		}
192		if g := cfg.ShouldDiscover(); g != w {
193			t.Errorf("durl=%q: ShouldDiscover()=%t, want=%t", durl, g, w)
194		}
195	}
196}
197