github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/internal/peer/common/peerclient_test.go (about) 1 /* 2 Copyright hechain. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 package common_test 7 8 import ( 9 "crypto/tls" 10 "fmt" 11 "io/ioutil" 12 "net" 13 "os" 14 "path" 15 "path/filepath" 16 "testing" 17 "time" 18 19 "github.com/hechain20/hechain/common/crypto/tlsgen" 20 "github.com/hechain20/hechain/internal/peer/common" 21 "github.com/hechain20/hechain/internal/pkg/comm" 22 "github.com/spf13/viper" 23 "github.com/stretchr/testify/require" 24 ) 25 26 func initPeerTestEnv(t *testing.T) (cfgPath string, cleanup func()) { 27 t.Helper() 28 cfgPath, err := ioutil.TempDir("", "peerTestEnv") 29 require.NoError(t, err) 30 certsDir := filepath.Join(cfgPath, "certs") 31 err = os.Mkdir(certsDir, 0o755) 32 require.NoError(t, err) 33 34 configFile, err := os.Create(filepath.Join(cfgPath, "test.yaml")) 35 require.NoError(t, err) 36 defer configFile.Close() 37 38 configStr := ` 39 peer: 40 tls: 41 rootcert: 42 file: "certs/ca.crt" 43 clientKey: 44 file: "certs/client.key" 45 clientCert: 46 file: "certs/client.crt" 47 client: 48 connTimeout: 1s 49 50 orderer: 51 tls: 52 rootcert: 53 file: "certs/ca.crt" 54 clientKey: 55 file: "certs/client.key" 56 clientCert: 57 file: "certs/client.crt" 58 client: 59 connTimeout: 1s 60 ` 61 _, err = configFile.WriteString(configStr) 62 require.NoError(t, err) 63 64 os.Setenv("FABRIC_CFG_PATH", cfgPath) 65 viper.Reset() 66 _ = common.InitConfig("test") 67 ca, err := tlsgen.NewCA() 68 require.NoError(t, err) 69 70 caCrtFile := path.Join(certsDir, "ca.crt") 71 err = ioutil.WriteFile(caCrtFile, ca.CertBytes(), 0o644) 72 require.NoError(t, err) 73 74 kp, err := ca.NewClientCertKeyPair() 75 require.NoError(t, err) 76 77 key := path.Join(certsDir, "client.key") 78 err = ioutil.WriteFile(key, kp.Key, 0o644) 79 require.NoError(t, err) 80 81 crt := path.Join(certsDir, "client.crt") 82 err = ioutil.WriteFile(crt, kp.Cert, 0o644) 83 require.NoError(t, err) 84 85 ekey := path.Join(certsDir, "empty.key") 86 err = ioutil.WriteFile(ekey, []byte{}, 0o644) 87 require.NoError(t, err) 88 89 ecrt := path.Join(certsDir, "empty.crt") 90 err = ioutil.WriteFile(ecrt, []byte{}, 0o644) 91 require.NoError(t, err) 92 93 configFile, err = os.Create(filepath.Join(certsDir, "bad.key")) 94 require.NoError(t, err) 95 defer configFile.Close() 96 97 _, err = configFile.WriteString(` 98 -----BEGIN PRIVATE KEY----- 99 MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgg6BAaCpwlmg/hEP4 100 QjUeWEu3crkxMvjq4vYh3LaDREuhRANCAAR+FujNKcGQW/CEpMU6Yp45ye2cbOwJ 101 -----END PRIVATE KEY----- 102 `) 103 require.NoError(t, err) 104 105 return cfgPath, func() { 106 err := os.Unsetenv("FABRIC_CFG_PATH") 107 require.NoError(t, err) 108 defer os.RemoveAll(cfgPath) 109 viper.Reset() 110 } 111 } 112 113 func TestNewPeerClientFromEnv(t *testing.T) { 114 _, cleanup := initPeerTestEnv(t) 115 defer cleanup() 116 117 pClient, err := common.NewPeerClientFromEnv() 118 require.NoError(t, err) 119 require.NotNil(t, pClient) 120 121 viper.Set("peer.tls.enabled", true) 122 pClient, err = common.NewPeerClientFromEnv() 123 require.NoError(t, err) 124 require.NotNil(t, pClient) 125 126 viper.Set("peer.tls.enabled", true) 127 viper.Set("peer.tls.clientAuthRequired", true) 128 pClient, err = common.NewPeerClientFromEnv() 129 require.NoError(t, err) 130 require.NotNil(t, pClient) 131 132 // bad key file 133 // This used to be detected when creating the client instead 134 // of when the client connects. 135 badKeyFile := filepath.Join("certs", "bad.key") 136 viper.Set("peer.tls.clientKey.file", badKeyFile) 137 pClient, err = common.NewPeerClientFromEnv() 138 require.NoError(t, err) 139 _, err = pClient.Dial("127.0.0.1:0") 140 require.ErrorContains(t, err, "failed to load client certificate:") 141 require.ErrorContains(t, err, "tls: failed to parse private key") 142 143 // bad cert file path 144 viper.Set("peer.tls.clientCert.file", "./nocert.crt") 145 pClient, err = common.NewPeerClientFromEnv() 146 require.ErrorContains(t, err, "unable to load peer.tls.clientCert.file") 147 require.Nil(t, pClient) 148 149 // bad key file path 150 viper.Set("peer.tls.clientKey.file", "./nokey.key") 151 pClient, err = common.NewPeerClientFromEnv() 152 require.ErrorContains(t, err, "unable to load peer.tls.clientKey.file") 153 require.Nil(t, pClient) 154 155 // bad ca path 156 viper.Set("peer.tls.rootcert.file", "noroot.crt") 157 pClient, err = common.NewPeerClientFromEnv() 158 require.ErrorContains(t, err, "unable to load peer.tls.rootcert.file") 159 require.Nil(t, pClient) 160 } 161 162 func TestPeerClient(t *testing.T) { 163 _, cleanup := initPeerTestEnv(t) 164 defer cleanup() 165 166 lis, err := net.Listen("tcp", "localhost:0") 167 if err != nil { 168 t.Fatalf("error creating server for test: %v", err) 169 } 170 defer lis.Close() 171 srv, err := comm.NewGRPCServerFromListener(lis, comm.ServerConfig{}) 172 if err != nil { 173 t.Fatalf("error creating gRPC server for test: %v", err) 174 } 175 go srv.Start() 176 defer srv.Stop() 177 viper.Set("peer.address", lis.Addr().String()) 178 pClient1, err := common.NewPeerClientFromEnv() 179 if err != nil { 180 t.Fatalf("failed to create PeerClient for test: %v", err) 181 } 182 eClient, err := pClient1.Endorser() 183 require.NoError(t, err) 184 require.NotNil(t, eClient) 185 eClient, err = common.GetEndorserClient("", "") 186 require.NoError(t, err) 187 require.NotNil(t, eClient) 188 189 dClient, err := pClient1.Deliver() 190 require.NoError(t, err) 191 require.NotNil(t, dClient) 192 dClient, err = common.GetDeliverClient("", "") 193 require.NoError(t, err) 194 require.NotNil(t, dClient) 195 } 196 197 func TestPeerClientTimeout(t *testing.T) { 198 t.Run("PeerClient.GetEndorser() timeout", func(t *testing.T) { 199 _, cleanup := initPeerTestEnv(t) 200 viper.Set("peer.client.connTimeout", 10*time.Millisecond) 201 defer cleanup() 202 pClient, err := common.NewPeerClientFromEnv() 203 if err != nil { 204 t.Fatalf("failed to create PeerClient for test: %v", err) 205 } 206 _, err = pClient.Endorser() 207 require.Contains(t, err.Error(), "endorser client failed to connect") 208 }) 209 t.Run("GetEndorserClient() timeout", func(t *testing.T) { 210 _, cleanup := initPeerTestEnv(t) 211 viper.Set("peer.client.connTimeout", 10*time.Millisecond) 212 defer cleanup() 213 _, err := common.GetEndorserClient("", "") 214 require.Contains(t, err.Error(), "endorser client failed to connect") 215 }) 216 t.Run("PeerClient.Deliver() timeout", func(t *testing.T) { 217 _, cleanup := initPeerTestEnv(t) 218 viper.Set("peer.client.connTimeout", 10*time.Millisecond) 219 defer cleanup() 220 pClient, err := common.NewPeerClientFromEnv() 221 if err != nil { 222 t.Fatalf("failed to create PeerClient for test: %v", err) 223 } 224 _, err = pClient.Deliver() 225 require.Contains(t, err.Error(), "deliver client failed to connect") 226 }) 227 t.Run("GetDeliverClient() timeout", func(t *testing.T) { 228 _, cleanup := initPeerTestEnv(t) 229 viper.Set("peer.client.connTimeout", 10*time.Millisecond) 230 defer cleanup() 231 _, err := common.GetDeliverClient("", "") 232 require.Contains(t, err.Error(), "deliver client failed to connect") 233 }) 234 t.Run("PeerClient.Certificate()", func(t *testing.T) { 235 _, cleanup := initPeerTestEnv(t) 236 defer cleanup() 237 pClient, err := common.NewPeerClientFromEnv() 238 if err != nil { 239 t.Fatalf("failed to create PeerClient for test: %v", err) 240 } 241 cert := pClient.Certificate() 242 require.NotNil(t, cert) 243 }) 244 } 245 246 func TestGetClientCertificate(t *testing.T) { 247 t.Run("GetClientCertificate_clientAuthRequired_disabled", func(t *testing.T) { 248 _, cleanup := initPeerTestEnv(t) 249 defer cleanup() 250 cert, err := common.GetClientCertificate() 251 require.NotEqual(t, cert, &tls.Certificate{}) 252 require.NoError(t, err) 253 }) 254 255 t.Run("GetClientCertificate_clientAuthRequired_enabled", func(t *testing.T) { 256 _, cleanup := initPeerTestEnv(t) 257 defer cleanup() 258 viper.Set("peer.tls.clientAuthRequired", true) 259 viper.Set("peer.tls.clientKey.file", filepath.Join("./certs", "client.key")) 260 viper.Set("peer.tls.clientCert.file", filepath.Join("./certs", "client.crt")) 261 defer viper.Reset() 262 263 cert, err := common.GetClientCertificate() 264 require.NoError(t, err) 265 require.NotEqual(t, cert, tls.Certificate{}) 266 }) 267 268 t.Run("GetClientCertificate_empty_keyfile", func(t *testing.T) { 269 _, cleanup := initPeerTestEnv(t) 270 defer cleanup() 271 viper.Set("peer.tls.clientAuthRequired", true) 272 viper.Set("peer.tls.clientKey.file", filepath.Join("./certs", "empty.key")) 273 viper.Set("peer.tls.clientCert.file", filepath.Join("./certs", "client.crt")) 274 defer viper.Reset() 275 276 cert, err := common.GetClientCertificate() 277 require.EqualError(t, err, "failed to load client certificate: tls: failed to find any PEM data in key input") 278 require.Equal(t, cert, tls.Certificate{}) 279 }) 280 281 t.Run("GetClientCertificate_empty_certfile", func(t *testing.T) { 282 _, cleanup := initPeerTestEnv(t) 283 defer cleanup() 284 viper.Set("peer.tls.clientAuthRequired", true) 285 viper.Set("peer.tls.clientKey.file", filepath.Join("./certs", "client.key")) 286 viper.Set("peer.tls.clientCert.file", filepath.Join("./certs", "empty.crt")) 287 defer viper.Reset() 288 289 cert, err := common.GetClientCertificate() 290 require.EqualError(t, err, "failed to load client certificate: tls: failed to find any PEM data in certificate input") 291 require.Equal(t, cert, tls.Certificate{}) 292 }) 293 294 t.Run("GetClientCertificate_bad_keyfilepath", func(t *testing.T) { 295 cfgPath, cleanup := initPeerTestEnv(t) 296 defer cleanup() 297 // bad key file path 298 viper.Set("peer.tls.clientAuthRequired", true) 299 viper.Set("peer.tls.clientKey.file", filepath.Join("./certs", "nokey.key")) 300 viper.Set("peer.tls.clientCert.file", filepath.Join("./certs", "client.crt")) 301 defer viper.Reset() 302 303 cert, err := common.GetClientCertificate() 304 require.EqualError(t, err, fmt.Sprintf("unable to load peer.tls.clientKey.file: open %s/certs/nokey.key: no such file or directory", cfgPath)) 305 require.Equal(t, cert, tls.Certificate{}) 306 }) 307 308 t.Run("GetClientCertificate_missing_certfilepath", func(t *testing.T) { 309 // missing cert file path 310 viper.Set("peer.tls.clientAuthRequired", true) 311 viper.Set("peer.tls.clientKey.file", filepath.Join("./testdata/certs", "client.key")) 312 defer viper.Reset() 313 314 cert, err := common.GetClientCertificate() 315 require.EqualError(t, err, "unable to load peer.tls.clientKey.file: open testdata/certs/client.key: no such file or directory") 316 require.Equal(t, cert, tls.Certificate{}) 317 }) 318 } 319 320 func TestNewPeerClientForAddress(t *testing.T) { 321 cfgPath, cleanup := initPeerTestEnv(t) 322 defer cleanup() 323 324 // TLS disabled 325 viper.Set("peer.tls.enabled", false) 326 327 // success case 328 pClient, err := common.NewPeerClientForAddress("testPeer", "") 329 require.NoError(t, err) 330 require.NotNil(t, pClient) 331 332 // failure - no peer address supplied 333 pClient, err = common.NewPeerClientForAddress("", "") 334 require.Contains(t, err.Error(), "peer address must be set") 335 require.Nil(t, pClient) 336 337 // TLS enabled 338 viper.Set("peer.tls.enabled", true) 339 340 // Enable clientAuthRequired 341 viper.Set("peer.tls.clientAuthRequired", true) 342 343 // success case 344 pClient, err = common.NewPeerClientForAddress("tlsPeer", path.Join(cfgPath, "certs", "ca.crt")) 345 require.NoError(t, err) 346 require.NotNil(t, pClient) 347 348 // failure - bad tls root cert file 349 pClient, err = common.NewPeerClientForAddress("badPeer", "bad.crt") 350 require.Contains(t, err.Error(), "unable to load TLS root cert file from bad.crt") 351 require.Nil(t, pClient) 352 353 // failure - empty tls root cert file 354 pClient, err = common.NewPeerClientForAddress("badPeer", "") 355 require.Contains(t, err.Error(), "tls root cert file must be set") 356 require.Nil(t, pClient) 357 358 // failure - empty tls root cert file 359 viper.Set("peer.tls.clientCert.file", "./nocert.crt") 360 pClient, err = common.NewPeerClientForAddress("badPeer", "") 361 require.Contains(t, err.Error(), "unable to load peer.tls.clientCert.file") 362 require.Nil(t, pClient) 363 364 // bad key file 365 viper.Set("peer.tls.clientKey.file", "./nokey.key") 366 viper.Set("peer.client.connTimeout", time.Duration(0)) 367 pClient, err = common.NewPeerClientForAddress("badPeer", "") 368 require.Contains(t, err.Error(), "unable to load peer.tls.clientKey.file") 369 require.Nil(t, pClient) 370 } 371 372 func TestGetClients_AddressError(t *testing.T) { 373 _, cleanup := initPeerTestEnv(t) 374 defer cleanup() 375 376 viper.Set("peer.tls.enabled", true) 377 378 // failure 379 eClient, err := common.GetEndorserClient("peer0", "") 380 require.Contains(t, err.Error(), "tls root cert file must be set") 381 require.Nil(t, eClient) 382 383 dClient, err := common.GetDeliverClient("peer0", "") 384 require.Contains(t, err.Error(), "tls root cert file must be set") 385 require.Nil(t, dClient) 386 }