1// Copyright 2016 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 e2e 16 17import ( 18 "fmt" 19 "io/ioutil" 20 "os" 21 "strings" 22 "testing" 23 24 "github.com/coreos/etcd/pkg/expect" 25) 26 27const exampleConfigFile = "../etcd.conf.yml.sample" 28 29func TestEtcdExampleConfig(t *testing.T) { 30 proc, err := spawnCmd([]string{binDir + "/etcd", "--config-file", exampleConfigFile}) 31 if err != nil { 32 t.Fatal(err) 33 } 34 if err = waitReadyExpectProc(proc, etcdServerReadyLines); err != nil { 35 t.Fatal(err) 36 } 37 if err = proc.Stop(); err != nil { 38 t.Fatal(err) 39 } 40} 41 42func TestEtcdMultiPeer(t *testing.T) { 43 peers, tmpdirs := make([]string, 3), make([]string, 3) 44 for i := range peers { 45 peers[i] = fmt.Sprintf("e%d=http://127.0.0.1:%d", i, etcdProcessBasePort+i) 46 d, err := ioutil.TempDir("", fmt.Sprintf("e%d.etcd", i)) 47 if err != nil { 48 t.Fatal(err) 49 } 50 tmpdirs[i] = d 51 } 52 ic := strings.Join(peers, ",") 53 54 procs := make([]*expect.ExpectProcess, len(peers)) 55 defer func() { 56 for i := range procs { 57 if procs[i] != nil { 58 procs[i].Stop() 59 } 60 os.RemoveAll(tmpdirs[i]) 61 } 62 }() 63 for i := range procs { 64 args := []string{ 65 binDir + "/etcd", 66 "--name", fmt.Sprintf("e%d", i), 67 "--listen-client-urls", "http://0.0.0.0:0", 68 "--data-dir", tmpdirs[i], 69 "--advertise-client-urls", "http://0.0.0.0:0", 70 "--listen-peer-urls", fmt.Sprintf("http://127.0.0.1:%d,http://127.0.0.1:%d", etcdProcessBasePort+i, etcdProcessBasePort+len(peers)+i), 71 "--initial-advertise-peer-urls", fmt.Sprintf("http://127.0.0.1:%d", etcdProcessBasePort+i), 72 "--initial-cluster", ic, 73 } 74 p, err := spawnCmd(args) 75 if err != nil { 76 t.Fatal(err) 77 } 78 procs[i] = p 79 } 80 81 for _, p := range procs { 82 if err := waitReadyExpectProc(p, etcdServerReadyLines); err != nil { 83 t.Fatal(err) 84 } 85 } 86} 87 88// TestEtcdUnixPeers checks that etcd will boot with unix socket peers. 89func TestEtcdUnixPeers(t *testing.T) { 90 d, err := ioutil.TempDir("", "e1.etcd") 91 if err != nil { 92 t.Fatal(err) 93 } 94 defer os.RemoveAll(d) 95 proc, err := spawnCmd( 96 []string{ 97 binDir + "/etcd", 98 "--data-dir", d, 99 "--name", "e1", 100 "--listen-peer-urls", "unix://etcd.unix:1", 101 "--initial-advertise-peer-urls", "unix://etcd.unix:1", 102 "--initial-cluster", "e1=unix://etcd.unix:1", 103 }, 104 ) 105 defer os.Remove("etcd.unix:1") 106 if err != nil { 107 t.Fatal(err) 108 } 109 if err = waitReadyExpectProc(proc, etcdServerReadyLines); err != nil { 110 t.Fatal(err) 111 } 112 if err = proc.Stop(); err != nil { 113 t.Fatal(err) 114 } 115} 116 117// TestEtcdPeerCNAuth checks that the inter peer auth based on CN of cert is working correctly. 118func TestEtcdPeerCNAuth(t *testing.T) { 119 peers, tmpdirs := make([]string, 3), make([]string, 3) 120 for i := range peers { 121 peers[i] = fmt.Sprintf("e%d=https://127.0.0.1:%d", i, etcdProcessBasePort+i) 122 d, err := ioutil.TempDir("", fmt.Sprintf("e%d.etcd", i)) 123 if err != nil { 124 t.Fatal(err) 125 } 126 tmpdirs[i] = d 127 } 128 ic := strings.Join(peers, ",") 129 130 procs := make([]*expect.ExpectProcess, len(peers)) 131 defer func() { 132 for i := range procs { 133 if procs[i] != nil { 134 procs[i].Stop() 135 } 136 os.RemoveAll(tmpdirs[i]) 137 } 138 }() 139 140 // node 0 and 1 have a cert with the correct CN, node 2 doesn't 141 for i := range procs { 142 commonArgs := []string{ 143 binDir + "/etcd", 144 "--name", fmt.Sprintf("e%d", i), 145 "--listen-client-urls", "http://0.0.0.0:0", 146 "--data-dir", tmpdirs[i], 147 "--advertise-client-urls", "http://0.0.0.0:0", 148 "--listen-peer-urls", fmt.Sprintf("https://127.0.0.1:%d,https://127.0.0.1:%d", etcdProcessBasePort+i, etcdProcessBasePort+len(peers)+i), 149 "--initial-advertise-peer-urls", fmt.Sprintf("https://127.0.0.1:%d", etcdProcessBasePort+i), 150 "--initial-cluster", ic, 151 } 152 153 var args []string 154 if i <= 1 { 155 args = []string{ 156 "--peer-cert-file", certPath, 157 "--peer-key-file", privateKeyPath, 158 "--peer-trusted-ca-file", caPath, 159 "--peer-client-cert-auth", 160 "--peer-cert-allowed-cn", "example.com", 161 } 162 } else { 163 args = []string{ 164 "--peer-cert-file", certPath2, 165 "--peer-key-file", privateKeyPath2, 166 "--peer-trusted-ca-file", caPath, 167 "--peer-client-cert-auth", 168 "--peer-cert-allowed-cn", "example2.com", 169 } 170 } 171 172 commonArgs = append(commonArgs, args...) 173 174 p, err := spawnCmd(commonArgs) 175 if err != nil { 176 t.Fatal(err) 177 } 178 procs[i] = p 179 } 180 181 for i, p := range procs { 182 var expect []string 183 if i <= 1 { 184 expect = etcdServerReadyLines 185 } else { 186 expect = []string{"remote error: tls: bad certificate"} 187 } 188 if err := waitReadyExpectProc(p, expect); err != nil { 189 t.Fatal(err) 190 } 191 } 192} 193