github.com/Finschia/finschia-sdk@v0.48.1/server/oc_cmds_test.go (about) 1 package server 2 3 import ( 4 "bytes" 5 "context" 6 "fmt" 7 "io/ioutil" 8 "os" 9 "testing" 10 11 "github.com/stretchr/testify/require" 12 13 cfg "github.com/Finschia/ostracon/config" 14 "github.com/Finschia/ostracon/crypto" 15 tmjson "github.com/Finschia/ostracon/libs/json" 16 "github.com/Finschia/ostracon/libs/log" 17 tmos "github.com/Finschia/ostracon/libs/os" 18 tmrand "github.com/Finschia/ostracon/libs/rand" 19 "github.com/Finschia/ostracon/p2p" 20 "github.com/Finschia/ostracon/privval" 21 "github.com/Finschia/ostracon/types" 22 tmtime "github.com/Finschia/ostracon/types/time" 23 ) 24 25 var ( 26 logger = log.NewOCLogger(log.NewSyncWriter(os.Stdout)) 27 ) 28 29 func TestShowValidator(t *testing.T) { 30 testCommon := newPrecedenceCommon(t) 31 32 serverCtx := &Context{} 33 ctx := context.WithValue(context.Background(), ServerContextKey, serverCtx) 34 35 if err := testCommon.cmd.ExecuteContext(ctx); err != cancelledInPreRun { 36 t.Fatalf("function failed with [%T] %v", err, err) 37 } 38 39 // ostracon init & create the server config file 40 initFilesWithConfig(serverCtx.Config) 41 output := captureStdout(t, func() { ShowValidatorCmd().ExecuteContext(ctx) }) 42 43 // output must match the locally stored priv_validator key 44 privKey := loadFilePVKey(t, serverCtx.Config.PrivValidatorKeyFile()) 45 bz, err := tmjson.Marshal(privKey.PubKey) 46 require.NoError(t, err) 47 require.Equal(t, string(bz), output) 48 } 49 50 func TestShowValidatorWithKMS(t *testing.T) { 51 testCommon := newPrecedenceCommon(t) 52 53 serverCtx := &Context{} 54 ctx := context.WithValue(context.Background(), ServerContextKey, serverCtx) 55 56 if err := testCommon.cmd.ExecuteContext(ctx); err != cancelledInPreRun { 57 t.Fatalf("function failed with [%T] %v", err, err) 58 } 59 60 // ostracon init & create the server config file 61 serverCtx.Config.PrivValidatorRemoteAddresses = append(serverCtx.Config.PrivValidatorRemoteAddresses, "127.0.0.1") 62 initFilesWithConfig(serverCtx.Config) 63 64 chainID, err := loadChainID(serverCtx.Config) 65 require.NoError(t, err) 66 67 // remove config file 68 if tmos.FileExists(serverCtx.Config.PrivValidatorKeyFile()) { 69 err := os.Remove(serverCtx.Config.PrivValidatorKeyFile()) 70 require.NoError(t, err) 71 } 72 73 privval.WithMockKMS(t, t.TempDir(), chainID, func(addr string, privKey crypto.PrivKey) { 74 serverCtx.Config.PrivValidatorListenAddr = addr 75 require.NoFileExists(t, serverCtx.Config.PrivValidatorKeyFile()) 76 output := captureStdout(t, func() { ShowValidatorCmd().ExecuteContext(ctx) }) 77 require.NoError(t, err) 78 79 // output must contains the KMS public key 80 bz, err := tmjson.Marshal(privKey.PubKey()) 81 require.NoError(t, err) 82 expected := string(bz) 83 require.Contains(t, output, expected) 84 }) 85 } 86 87 func TestShowValidatorWithInefficientKMSAddress(t *testing.T) { 88 testCommon := newPrecedenceCommon(t) 89 90 serverCtx := &Context{} 91 ctx := context.WithValue(context.Background(), ServerContextKey, serverCtx) 92 93 if err := testCommon.cmd.ExecuteContext(ctx); err != cancelledInPreRun { 94 t.Fatalf("function failed with [%T] %v", err, err) 95 } 96 97 // ostracon init & create the server config file 98 initFilesWithConfig(serverCtx.Config) 99 100 // remove config file 101 if tmos.FileExists(serverCtx.Config.PrivValidatorKeyFile()) { 102 err := os.Remove(serverCtx.Config.PrivValidatorKeyFile()) 103 require.NoError(t, err) 104 } 105 106 serverCtx.Config.PrivValidatorListenAddr = "127.0.0.1:inefficient" 107 err := ShowValidatorCmd().ExecuteContext(ctx) 108 require.Error(t, err) 109 } 110 111 func TestLoadChainID(t *testing.T) { 112 expected := "c57861" 113 config := cfg.ResetTestRootWithChainID("TestLoadChainID", expected) 114 defer func() { 115 var _ = os.RemoveAll(config.RootDir) 116 }() 117 118 require.FileExists(t, config.GenesisFile()) 119 genDoc, err := types.GenesisDocFromFile(config.GenesisFile()) 120 require.NoError(t, err) 121 require.Equal(t, expected, genDoc.ChainID) 122 123 chainID, err := loadChainID(config) 124 require.NoError(t, err) 125 require.Equal(t, expected, chainID) 126 } 127 128 func TestLoadChainIDWithoutStateDB(t *testing.T) { 129 expected := "c34091" 130 config := cfg.ResetTestRootWithChainID("TestLoadChainID", expected) 131 defer func() { 132 var _ = os.RemoveAll(config.RootDir) 133 }() 134 135 config.DBBackend = "goleveldb" 136 config.DBPath = "/../path with containing chars that cannot be used\\/:*?\"<>|\x00" 137 138 _, err := loadChainID(config) 139 require.Error(t, err) 140 } 141 142 func initFilesWithConfig(config *cfg.Config) error { 143 // private validator 144 privValKeyFile := config.PrivValidatorKeyFile() 145 privValStateFile := config.PrivValidatorStateFile() 146 var pv *privval.FilePV 147 if tmos.FileExists(privValKeyFile) { 148 pv = privval.LoadFilePV(privValKeyFile, privValStateFile) 149 logger.Info("Found private validator", "keyFile", privValKeyFile, 150 "stateFile", privValStateFile) 151 } else { 152 pv = privval.GenFilePV(privValKeyFile, privValStateFile) 153 if pv != nil { 154 pv.Save() 155 } 156 logger.Info("Generated private validator", "keyFile", privValKeyFile, 157 "stateFile", privValStateFile) 158 } 159 160 nodeKeyFile := config.NodeKeyFile() 161 if tmos.FileExists(nodeKeyFile) { 162 logger.Info("Found node key", "path", nodeKeyFile) 163 } else { 164 if _, err := p2p.LoadOrGenNodeKey(nodeKeyFile); err != nil { 165 return err 166 } 167 logger.Info("Generated node key", "path", nodeKeyFile) 168 } 169 170 // genesis file 171 genFile := config.GenesisFile() 172 if tmos.FileExists(genFile) { 173 logger.Info("Found genesis file", "path", genFile) 174 } else { 175 genDoc := types.GenesisDoc{ 176 ChainID: fmt.Sprintf("test-chain-%v", tmrand.Str(6)), 177 GenesisTime: tmtime.Now(), 178 ConsensusParams: types.DefaultConsensusParams(), 179 } 180 pubKey, err := pv.GetPubKey() 181 if err != nil { 182 return fmt.Errorf("can't get pubkey: %w", err) 183 } 184 genDoc.Validators = []types.GenesisValidator{{ 185 Address: pubKey.Address(), 186 PubKey: pubKey, 187 Power: 10, 188 }} 189 190 if err := genDoc.SaveAs(genFile); err != nil { 191 return err 192 } 193 logger.Info("Generated genesis file", "path", genFile) 194 } 195 196 return nil 197 } 198 199 func loadFilePVKey(t *testing.T, file string) privval.FilePVKey { 200 // output must match the locally stored priv_validator key 201 keyJSONBytes, err := ioutil.ReadFile(file) 202 require.NoError(t, err) 203 privKey := privval.FilePVKey{} 204 err = tmjson.Unmarshal(keyJSONBytes, &privKey) 205 require.NoError(t, err) 206 return privKey 207 } 208 209 func captureStdout(t *testing.T, fnc func()) string { 210 t.Helper() 211 backup := os.Stdout 212 defer func() { 213 os.Stdout = backup 214 }() 215 r, w, err := os.Pipe() 216 if err != nil { 217 t.Fatalf("fail pipe: %v", err) 218 } 219 os.Stdout = w 220 fnc() 221 w.Close() 222 var buffer bytes.Buffer 223 if n, err := buffer.ReadFrom(r); err != nil { 224 t.Fatalf("fail read buf: %v - number: %v", err, n) 225 } 226 output := buffer.String() 227 return output[:len(output)-1] 228 }