lntest: wait for valid tls cert and macaroon files

This changes the wait during node connection to check both for the
existance as well as for the validity of the tls cert and macaroon
files.

This ensures that nodes in the process of starting up don't inadvertedly
cause a connection error due to not yet having written the entire file.
This commit is contained in:
Matheus Degiovani 2020-04-20 12:09:05 -03:00
parent 9f036b4310
commit 91538884da

@ -689,28 +689,26 @@ func (hn *HarnessNode) writePidFile() error {
func (hn *HarnessNode) ReadMacaroon(macPath string, timeout time.Duration) ( func (hn *HarnessNode) ReadMacaroon(macPath string, timeout time.Duration) (
*macaroon.Macaroon, error) { *macaroon.Macaroon, error) {
// Wait until macaroon file is created before using it. // Wait until macaroon file is created and has valid content before
macTimeout := time.After(timeout) // using it.
for !fileExists(macPath) { var mac *macaroon.Macaroon
select { err := wait.NoError(func() error {
case <-macTimeout: macBytes, err := ioutil.ReadFile(macPath)
return nil, fmt.Errorf("timeout waiting for macaroon "+ if err != nil {
"file %s to be created after %d seconds", return fmt.Errorf("error reading macaroon file: %v", err)
macPath, timeout/time.Second)
case <-time.After(100 * time.Millisecond):
} }
}
// Now that we know the file exists, read it and return the macaroon. newMac := &macaroon.Macaroon{}
macBytes, err := ioutil.ReadFile(macPath) if err = newMac.UnmarshalBinary(macBytes); err != nil {
if err != nil { return fmt.Errorf("error unmarshalling macaroon "+
return nil, err "file: %v", err)
} }
mac := &macaroon.Macaroon{} mac = newMac
if err = mac.UnmarshalBinary(macBytes); err != nil {
return nil, err return nil
} }, timeout)
return mac, nil
return mac, err
} }
// ConnectRPCWithMacaroon uses the TLS certificate and given macaroon to // ConnectRPCWithMacaroon uses the TLS certificate and given macaroon to
@ -718,25 +716,24 @@ func (hn *HarnessNode) ReadMacaroon(macPath string, timeout time.Duration) (
func (hn *HarnessNode) ConnectRPCWithMacaroon(mac *macaroon.Macaroon) ( func (hn *HarnessNode) ConnectRPCWithMacaroon(mac *macaroon.Macaroon) (
*grpc.ClientConn, error) { *grpc.ClientConn, error) {
// Wait until TLS certificate is created before using it, up to 30 sec. // Wait until TLS certificate is created and has valid content before
tlsTimeout := time.After(DefaultTimeout) // using it, up to 30 sec.
for !fileExists(hn.Cfg.TLSCertPath) { var tlsCreds credentials.TransportCredentials
select { err := wait.NoError(func() error {
case <-tlsTimeout: var err error
return nil, fmt.Errorf("timeout waiting for TLS cert " + tlsCreds, err = credentials.NewClientTLSFromFile(
"file to be created") hn.Cfg.TLSCertPath, "",
case <-time.After(100 * time.Millisecond): )
} return err
}, DefaultTimeout)
if err != nil {
return nil, fmt.Errorf("error reading TLS cert: %v", err)
} }
opts := []grpc.DialOption{grpc.WithBlock()} opts := []grpc.DialOption{
tlsCreds, err := credentials.NewClientTLSFromFile( grpc.WithBlock(),
hn.Cfg.TLSCertPath, "", grpc.WithTransportCredentials(tlsCreds),
)
if err != nil {
return nil, err
} }
opts = append(opts, grpc.WithTransportCredentials(tlsCreds))
ctx, cancel := context.WithTimeout(context.Background(), DefaultTimeout) ctx, cancel := context.WithTimeout(context.Background(), DefaultTimeout)
defer cancel() defer cancel()
@ -1159,14 +1156,3 @@ func (hn *HarnessNode) WaitForBalance(expectedBalance btcutil.Amount, confirmed
return nil return nil
} }
// fileExists reports whether the named file or directory exists.
// This function is taken from https://github.com/btcsuite/btcd
func fileExists(name string) bool {
if _, err := os.Stat(name); err != nil {
if os.IsNotExist(err) {
return false
}
}
return true
}