forked from TrueCloudLab/neoneo-go
Merge pull request #551 from nspcc-dev/feature/performance_test
performance: add performance test
This commit is contained in:
commit
16d9ba2297
2 changed files with 138 additions and 0 deletions
20
integration/README.md
Normal file
20
integration/README.md
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
# Integration package
|
||||||
|
The main goal is to have integration tests here.
|
||||||
|
|
||||||
|
### Performance test
|
||||||
|
Right now we have `performance_test.go` to measure number of processed TX per second.
|
||||||
|
In order to run it:
|
||||||
|
```
|
||||||
|
$ cd integration
|
||||||
|
$ go test -bench=. -benchmem
|
||||||
|
```
|
||||||
|
|
||||||
|
Result:
|
||||||
|
```
|
||||||
|
10000 402421 ns/op 177370 B/op 90 allocs/op
|
||||||
|
PASS
|
||||||
|
ok github.com/CityOfZion/neo-go/integration 4.360s
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
Which means that in 4.360 seconds neo-go processes 10 000 transactions.
|
118
integration/performance_test.go
Normal file
118
integration/performance_test.go
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
package integration
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/rand"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/CityOfZion/neo-go/config"
|
||||||
|
"github.com/CityOfZion/neo-go/pkg/core"
|
||||||
|
"github.com/CityOfZion/neo-go/pkg/core/storage"
|
||||||
|
"github.com/CityOfZion/neo-go/pkg/core/transaction"
|
||||||
|
"github.com/CityOfZion/neo-go/pkg/crypto"
|
||||||
|
"github.com/CityOfZion/neo-go/pkg/crypto/keys"
|
||||||
|
"github.com/CityOfZion/neo-go/pkg/network"
|
||||||
|
"github.com/CityOfZion/neo-go/pkg/rpc"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Benchmark test to measure number of processed TX.
|
||||||
|
// Same benchmark made on reference C# node https://github.com/neo-project/neo/issues/1321.
|
||||||
|
func BenchmarkTXPerformanceTest(t *testing.B) {
|
||||||
|
net := config.ModeUnitTestNet
|
||||||
|
configPath := "../config"
|
||||||
|
cfg, err := config.Load(configPath, net)
|
||||||
|
require.NoError(t, err, "could not load config")
|
||||||
|
|
||||||
|
memoryStore := storage.NewMemoryStore()
|
||||||
|
chain, err := core.NewBlockchain(memoryStore, cfg.ProtocolConfiguration)
|
||||||
|
require.NoError(t, err, "could not create chain")
|
||||||
|
|
||||||
|
go chain.Run()
|
||||||
|
|
||||||
|
serverConfig := network.NewServerConfig(cfg)
|
||||||
|
server := network.NewServer(serverConfig, chain)
|
||||||
|
data := prepareData(t)
|
||||||
|
t.ResetTimer()
|
||||||
|
|
||||||
|
for n := 0; n < t.N; n++ {
|
||||||
|
if server.RelayTxn(data[n]) != network.RelaySucceed {
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
if server.RelayTxn(data[n]) != network.RelayAlreadyExists {
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
chain.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
func prepareData(t *testing.B) []*transaction.Transaction {
|
||||||
|
var data []*transaction.Transaction
|
||||||
|
|
||||||
|
wif := getWif(t)
|
||||||
|
|
||||||
|
for n := 0; n < t.N; n++ {
|
||||||
|
tx := getTX(t, wif)
|
||||||
|
require.NoError(t, rpc.SignTx(tx, wif))
|
||||||
|
data = append(data, tx)
|
||||||
|
}
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
// getWif returns Wif.
|
||||||
|
func getWif(t *testing.B) *keys.WIF {
|
||||||
|
var (
|
||||||
|
wifEncoded = "KxhEDBQyyEFymvfJD96q8stMbJMbZUb6D1PmXqBWZDU2WvbvVs9o"
|
||||||
|
version = byte(0x00)
|
||||||
|
)
|
||||||
|
wif, err := keys.WIFDecode(wifEncoded, version)
|
||||||
|
require.NoError(t, err)
|
||||||
|
return wif
|
||||||
|
}
|
||||||
|
|
||||||
|
// getTX returns Invocation transaction with some random attributes in order to have different hashes.
|
||||||
|
func getTX(t *testing.B, wif *keys.WIF) *transaction.Transaction {
|
||||||
|
fromAddress := wif.PrivateKey.Address()
|
||||||
|
fromAddressHash, err := crypto.Uint160DecodeAddress(fromAddress)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
tx := &transaction.Transaction{
|
||||||
|
Type: transaction.InvocationType,
|
||||||
|
Version: 0,
|
||||||
|
Data: &transaction.InvocationTX{
|
||||||
|
Script: []byte{0x51},
|
||||||
|
Gas: 1,
|
||||||
|
Version: 1,
|
||||||
|
},
|
||||||
|
Attributes: []transaction.Attribute{},
|
||||||
|
Inputs: []transaction.Input{},
|
||||||
|
Outputs: []transaction.Output{},
|
||||||
|
Scripts: []transaction.Witness{},
|
||||||
|
Trimmed: false,
|
||||||
|
}
|
||||||
|
tx.Attributes = append(tx.Attributes,
|
||||||
|
transaction.Attribute{
|
||||||
|
Usage: transaction.Description,
|
||||||
|
Data: []byte(randString(10)),
|
||||||
|
})
|
||||||
|
tx.Attributes = append(tx.Attributes,
|
||||||
|
transaction.Attribute{
|
||||||
|
Usage: transaction.Script,
|
||||||
|
Data: fromAddressHash.BytesBE(),
|
||||||
|
})
|
||||||
|
return tx
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns a random string with the n as its length.
|
||||||
|
func randString(n int) string {
|
||||||
|
b := make([]byte, n)
|
||||||
|
for i := range b {
|
||||||
|
b[i] = byte(Int(65, 90))
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int returns a random integer in [min,max).
|
||||||
|
func Int(min, max int) int {
|
||||||
|
return min + rand.Intn(max-min)
|
||||||
|
}
|
Loading…
Reference in a new issue