From 15cba86ca6af666b942c3ea7a780e6c73c443191 Mon Sep 17 00:00:00 2001 From: Philip-21 Date: Fri, 15 Dec 2023 09:01:47 +0100 Subject: [PATCH 01/10] ethereum besu unit test created Signed-off-by: Philip-21 --- go.mod | 3 +- go.sum | 6 + .../blockchain/ethereum/besu/genesis_test.go | 145 ++++++++++++++++++ .../besu/testdata/genesis1_output.json | 21 +++ .../besu/testdata/genesis2_output.json | 21 +++ 5 files changed, 195 insertions(+), 1 deletion(-) create mode 100644 internal/blockchain/ethereum/besu/genesis_test.go create mode 100644 internal/blockchain/ethereum/besu/testdata/genesis1_output.json create mode 100644 internal/blockchain/ethereum/besu/testdata/genesis2_output.json diff --git a/go.mod b/go.mod index 11945eb8..7d95c922 100644 --- a/go.mod +++ b/go.mod @@ -31,7 +31,8 @@ require ( github.com/otiai10/copy v1.7.0 github.com/spf13/cobra v1.5.0 github.com/spf13/viper v1.12.1-0.20220712161005-5247643f0235 - github.com/stretchr/testify v1.8.0 + github.com/stretchr/objx v0.5.1 // indirect + github.com/stretchr/testify v1.8.4 golang.org/x/crypto v0.10.0 gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v3 v3.0.1 diff --git a/go.sum b/go.sum index 8d849ed8..97926f5d 100644 --- a/go.sum +++ b/go.sum @@ -865,6 +865,9 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.1 h1:4VhoImhV/Bm0ToFkXFi8hXNXwpDRZ/ynw3amt82mzq0= +github.com/stretchr/objx v0.5.1/go.mod h1:/iHQpkQwBD6DLUmQ4pE+s1TXdob1mORJ4/UFdrifcy0= github.com/stretchr/testify v0.0.0-20180303142811-b89eecf5ca5d/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= @@ -876,6 +879,9 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/subosito/gotenv v1.3.0/go.mod h1:YzJjq/33h7nrwdY+iHMhEOEEbW0ovIz0tB6t6PwAXzs= github.com/subosito/gotenv v1.4.0 h1:yAzM1+SmVcz5R4tXGsNMu1jUl2aOJXoiWUCEwwnGrvs= diff --git a/internal/blockchain/ethereum/besu/genesis_test.go b/internal/blockchain/ethereum/besu/genesis_test.go new file mode 100644 index 00000000..ed227305 --- /dev/null +++ b/internal/blockchain/ethereum/besu/genesis_test.go @@ -0,0 +1,145 @@ +package besu + +import ( + "encoding/json" + "fmt" + "os" + "strings" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestCreateGenesis(t *testing.T) { + //test diferent parameter cases for the CreateGenesis() + testCases := []struct { + Name string + addresses []string + blockPeriod int + chainID int64 + }{ + { + Name: "testcase1", + addresses: []string{"0xAddress1", "0xAddress2"}, + blockPeriod: 10, + chainID: int64(123), + }, + { + Name: "testcase2", + addresses: []string{"0xAddress3", "0xAddress4"}, + blockPeriod: 7, + chainID: int64(456), + }, + { + Name: "testcase3", + addresses: []string{"0xAddress14", "0xAddress29"}, + blockPeriod: 22, + chainID: 345, + }, + } + for _, tc := range testCases { + t.Run(tc.Name, func(t *testing.T) { + genesis := CreateGenesis(tc.addresses, tc.blockPeriod, tc.chainID) + extraData := "0x0000000000000000000000000000000000000000000000000000000000000000" + alloc := make(map[string]*Alloc) + for _, address := range tc.addresses { + alloc[address] = &Alloc{ + Balance: "0x200000000000000000000000000000000000000000000000000000000000000", + } + extraData += address + } + extraData = strings.ReplaceAll(fmt.Sprintf("%-236s", extraData), " ", "0") + expectedGenesis := &Genesis{ + Config: &GenesisConfig{ + ChainId: tc.chainID, + ConstantinopleFixBlock: 0, + Clique: &CliqueConfig{ + Blockperiodseconds: tc.blockPeriod, + EpochLength: 30000, + }, + }, + Coinbase: "0x0000000000000000000000000000000000000000", + Difficulty: "0x1", + ExtraData: extraData, + GasLimit: "0xffffffff", + MixHash: "0x0000000000000000000000000000000000000000000000000000000000000000", + Nonce: "0x0", + Timestamp: "0x5c51a607", + Alloc: alloc, + Number: "0x0", + GasUsed: "0x0", + ParentHash: "0x0000000000000000000000000000000000000000000000000000000000000000", + } + // Assert that the generated Genesis is equal to the expected Genesis + assert.Equal(t, expectedGenesis, genesis, "Generated Genesis does not match the expected Genesis") + }) + } + +} + +func TestWriteGenesisJSON(t *testing.T) { + filepath := "testdata" + + testCases := []struct { + Name string + SampleGenesis Genesis + filename string + }{ + { + Name: "TestCase1", + SampleGenesis: Genesis{ + Config: &GenesisConfig{ + ChainId: int64(456), + ConstantinopleFixBlock: 0, + Clique: &CliqueConfig{ + Blockperiodseconds: 20, + EpochLength: 2000, + }, + }, + }, + filename: filepath + "/genesis1_output.json", + }, + { + Name: "TestCase2", + SampleGenesis: Genesis{ + Config: &GenesisConfig{ + ChainId: int64(338), + ConstantinopleFixBlock: 0, + Clique: &CliqueConfig{ + Blockperiodseconds: 40, + EpochLength: 4000, + }, + }, + }, + filename: filepath + "/genesis2_output.json", + }, + } + for _, tc := range testCases { + t.Run(tc.Name, func(t *testing.T) { + err := tc.SampleGenesis.WriteGenesisJson(tc.filename) + if err != nil { + t.Log("unable to write Genesis JSON", err) + } + // Assert that there is no error + assert.NoError(t, err) + + writtenJSONBytes, err := os.ReadFile(tc.filename) + if err != nil { + t.Log("Unable to write JSON Bytes", err) + } + assert.NoError(t, err) + var writtenGenesis Genesis + + err = json.Unmarshal(writtenJSONBytes, &writtenGenesis) + if err != nil { + t.Log("unable to unmarshal JSON", err) + } + assert.NoError(t, err) + + // Assert that the written Genesis matches the original Genesis + assert.Equal(t, tc.SampleGenesis, writtenGenesis) + }) + + } + +} diff --git a/internal/blockchain/ethereum/besu/testdata/genesis1_output.json b/internal/blockchain/ethereum/besu/testdata/genesis1_output.json new file mode 100644 index 00000000..6a047ed1 --- /dev/null +++ b/internal/blockchain/ethereum/besu/testdata/genesis1_output.json @@ -0,0 +1,21 @@ +{ + "config": { + "chainId": 456, + "constantinoplefixblock": 0, + "clique": { + "epochlength": 2000, + "blockperiodseconds": 20 + } + }, + "nonce": "", + "timestamp": "", + "extraData": "", + "gasLimit": "", + "difficulty": "", + "mixHash": "", + "coinbase": "", + "alloc": null, + "number": "", + "gasUsed": "", + "parentHash": "" +} \ No newline at end of file diff --git a/internal/blockchain/ethereum/besu/testdata/genesis2_output.json b/internal/blockchain/ethereum/besu/testdata/genesis2_output.json new file mode 100644 index 00000000..f3314549 --- /dev/null +++ b/internal/blockchain/ethereum/besu/testdata/genesis2_output.json @@ -0,0 +1,21 @@ +{ + "config": { + "chainId": 338, + "constantinoplefixblock": 0, + "clique": { + "epochlength": 4000, + "blockperiodseconds": 40 + } + }, + "nonce": "", + "timestamp": "", + "extraData": "", + "gasLimit": "", + "difficulty": "", + "mixHash": "", + "coinbase": "", + "alloc": null, + "number": "", + "gasUsed": "", + "parentHash": "" +} \ No newline at end of file From 0b4d49d7b88af89437429ecf2eb43d44d9a0c172 Mon Sep 17 00:00:00 2001 From: Philip-21 Date: Sat, 16 Dec 2023 19:20:17 +0100 Subject: [PATCH 02/10] new tests created Signed-off-by: Philip-21 --- .../ethereum/besu/besu_provider_test.go | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 internal/blockchain/ethereum/besu/besu_provider_test.go diff --git a/internal/blockchain/ethereum/besu/besu_provider_test.go b/internal/blockchain/ethereum/besu/besu_provider_test.go new file mode 100644 index 00000000..79e34b7b --- /dev/null +++ b/internal/blockchain/ethereum/besu/besu_provider_test.go @@ -0,0 +1,46 @@ +package besu + +import ( + "context" + "testing" + + "github.com/hyperledger/firefly-cli/pkg/types" + "github.com/hyperledger/firefly-common/pkg/fftypes" + "github.com/stretchr/testify/assert" +) + +func TestNewBesuProvider(t *testing.T) { + var ctx context.Context + testCases := []struct { + Name string + Ctx context.Context + Stack *types.Stack + }{ + { + Name: "testcase1", + Ctx: ctx, + Stack: &types.Stack{ + Name: "TestBesuProviderWithEthconnect", + Members: []*types.Organization{{OrgName: "Org1"}}, + BlockchainProvider: fftypes.FFEnumValue("BlockchainProvider", "EthConnect"), + BlockchainConnector: fftypes.FFEnumValue("BlockchainConnector", "EthConnect"), + BlockchainNodeProvider: fftypes.FFEnumValue("BlockchainNodeProvider", "EthConnect"), + }, + }, + { + Name: "TestBesuProviderWithEvmconnect", + Stack: &types.Stack{ + BlockchainProvider: fftypes.FFEnumValue("BlockchainProvider", "Geth"), + BlockchainConnector: fftypes.FFEnumValue("BlockchainConnector", "EvmConnect"), + BlockchainNodeProvider: fftypes.FFEnumValue("BlockchainNodeProvider", "Geth"), + }, + }, + } + for _, tc := range testCases { + t.Run(tc.Name, func(t *testing.T) { + besuProvider := NewBesuProvider(tc.Ctx, tc.Stack) + assert.NotNil(t, besuProvider) + }) + } +} + From 01fa58e7c77222bdb5f0a6470c2450d17d53ffc5 Mon Sep 17 00:00:00 2001 From: Philip-21 Date: Sat, 16 Dec 2023 20:53:17 +0100 Subject: [PATCH 03/10] adjustments Signed-off-by: Philip-21 --- internal/blockchain/ethereum/besu/besu_provider_test.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/internal/blockchain/ethereum/besu/besu_provider_test.go b/internal/blockchain/ethereum/besu/besu_provider_test.go index 79e34b7b..6ed98ab9 100644 --- a/internal/blockchain/ethereum/besu/besu_provider_test.go +++ b/internal/blockchain/ethereum/besu/besu_provider_test.go @@ -28,8 +28,11 @@ func TestNewBesuProvider(t *testing.T) { }, }, { - Name: "TestBesuProviderWithEvmconnect", + Name: "testcase2", + Ctx: ctx, Stack: &types.Stack{ + Members: []*types.Organization{{OrgName: "Org2"}, {OrgName: "org4"}}, + Name: "TestBesuProviderWithEvmconnect", BlockchainProvider: fftypes.FFEnumValue("BlockchainProvider", "Geth"), BlockchainConnector: fftypes.FFEnumValue("BlockchainConnector", "EvmConnect"), BlockchainNodeProvider: fftypes.FFEnumValue("BlockchainNodeProvider", "Geth"), @@ -43,4 +46,3 @@ func TestNewBesuProvider(t *testing.T) { }) } } - From 13659be40f6b335dfe3d740b7420a54f689f8def Mon Sep 17 00:00:00 2001 From: Philip-21 Date: Wed, 20 Dec 2023 22:17:05 +0100 Subject: [PATCH 04/10] adjusting tests Signed-off-by: Philip-21 --- internal/blockchain/ethereum/besu/besu_provider_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/internal/blockchain/ethereum/besu/besu_provider_test.go b/internal/blockchain/ethereum/besu/besu_provider_test.go index 6ed98ab9..41654482 100644 --- a/internal/blockchain/ethereum/besu/besu_provider_test.go +++ b/internal/blockchain/ethereum/besu/besu_provider_test.go @@ -22,9 +22,9 @@ func TestNewBesuProvider(t *testing.T) { Stack: &types.Stack{ Name: "TestBesuProviderWithEthconnect", Members: []*types.Organization{{OrgName: "Org1"}}, - BlockchainProvider: fftypes.FFEnumValue("BlockchainProvider", "EthConnect"), + BlockchainProvider: fftypes.FFEnumValue("BlockchainProvider", "Ethereum"), BlockchainConnector: fftypes.FFEnumValue("BlockchainConnector", "EthConnect"), - BlockchainNodeProvider: fftypes.FFEnumValue("BlockchainNodeProvider", "EthConnect"), + BlockchainNodeProvider: fftypes.FFEnumValue("BlockchainNodeProvider", "besu"), }, }, { @@ -33,9 +33,9 @@ func TestNewBesuProvider(t *testing.T) { Stack: &types.Stack{ Members: []*types.Organization{{OrgName: "Org2"}, {OrgName: "org4"}}, Name: "TestBesuProviderWithEvmconnect", - BlockchainProvider: fftypes.FFEnumValue("BlockchainProvider", "Geth"), + BlockchainProvider: fftypes.FFEnumValue("BlockchainProvider", "Ethereum"), BlockchainConnector: fftypes.FFEnumValue("BlockchainConnector", "EvmConnect"), - BlockchainNodeProvider: fftypes.FFEnumValue("BlockchainNodeProvider", "Geth"), + BlockchainNodeProvider: fftypes.FFEnumValue("BlockchainNodeProvider", "besu"), }, }, } From 4df584d2e31e0821c45a72396622b96594e803b0 Mon Sep 17 00:00:00 2001 From: Philip-21 Date: Wed, 27 Dec 2023 15:54:07 +0100 Subject: [PATCH 05/10] unit test for geth provider Signed-off-by: Philip-21 --- .../blockchain/ethereum/geth/genesis_test.go | 92 +++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 internal/blockchain/ethereum/geth/genesis_test.go diff --git a/internal/blockchain/ethereum/geth/genesis_test.go b/internal/blockchain/ethereum/geth/genesis_test.go new file mode 100644 index 00000000..11e77817 --- /dev/null +++ b/internal/blockchain/ethereum/geth/genesis_test.go @@ -0,0 +1,92 @@ +package geth + +import ( + "fmt" + "strings" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestCreateGenesis(t *testing.T) { + testCases := []struct { + Name string + addresses []string + blockPeriod int + chainID int64 + }{ + { + Name: "testcase1", + addresses: []string{"0xAddress20", "0xAddress27"}, + blockPeriod: 28, + chainID: int64(21), + }, + { + Name: "testcase2", + addresses: []string{"0xAddress36", "0xAddress45"}, + blockPeriod: 26, + chainID: int64(98), + }, + { + Name: "testcase3", + addresses: []string{"0xAddress19", "0xAddress38", "0xAddress64", "0xAddress74"}, + blockPeriod: 40, + chainID: int64(93), + }, + { + Name: "testcase4", + addresses: []string{"0xAddress96", "0xAddress25", "0xAddress49", "0xAddress24", "0xAddress37", "0xAddress12"}, + blockPeriod: 12, + chainID: int64(5000), + }, + { + Name: "testcase5", + addresses: []string{"0xAddress62536", "0xAddress3261", "0xAddress82721"}, + blockPeriod: 14, + chainID: int64(900000), + }, + } + for _, tc := range testCases { + t.Run(tc.Name, func(t *testing.T) { + genesis := CreateGenesis(tc.addresses, tc.blockPeriod, tc.chainID) + extraData := "0x0000000000000000000000000000000000000000000000000000000000000000" + alloc := make(map[string]*Alloc) + for _, address := range tc.addresses { + alloc[address] = &Alloc{ + "0x200000000000000000000000000000000000000000000000000000000000000", + } + extraData += address + } + extraData = strings.ReplaceAll(fmt.Sprintf("%-236s", extraData), " ", "0") + expectedGenesis := &Genesis{ + Config: &GenesisConfig{ + ChainId: tc.chainID, + HomesteadBlock: 0, + Eip150Hash: "0x0000000000000000000000000000000000000000000000000000000000000000", + Eip155Block: 0, + Eip158Block: 0, + ByzantiumBlock: 0, + ConstantinopleBlock: 0, + Clique: &CliqueConfig{ + Period: tc.blockPeriod, + Epoch: 30000, + }, + }, + Nonce: "0x0", + Timestamp: "0x60edb1c7", + ExtraData: extraData, + GasLimit: "0xffffff", + Difficulty: "0x1", + MixHash: "0x0000000000000000000000000000000000000000000000000000000000000000", + Coinbase: "0x0000000000000000000000000000000000000000", + Alloc: alloc, + Number: "0x0", + GasUsed: "0x0", + ParentHash: "0x0000000000000000000000000000000000000000000000000000000000000000", + } + // Assert that the generated Genesis is equal to the expected Genesis + assert.Equal(t, expectedGenesis, genesis, "Generated Genesis does not match the expected Genesis") + + }) + } +} From 3de27fc275bf7b90c18996085a251ca56ed2fce5 Mon Sep 17 00:00:00 2001 From: Philip-21 Date: Wed, 27 Dec 2023 23:28:19 +0100 Subject: [PATCH 06/10] new unit tests for besu provider functions Signed-off-by: Philip-21 --- .../ethereum/besu/besu_provider_test.go | 75 +++++++++++++++++++ .../besu/testdata/test_contracts.json | 14 ++++ 2 files changed, 89 insertions(+) create mode 100644 internal/blockchain/ethereum/besu/testdata/test_contracts.json diff --git a/internal/blockchain/ethereum/besu/besu_provider_test.go b/internal/blockchain/ethereum/besu/besu_provider_test.go index 41654482..42c2d946 100644 --- a/internal/blockchain/ethereum/besu/besu_provider_test.go +++ b/internal/blockchain/ethereum/besu/besu_provider_test.go @@ -2,8 +2,12 @@ package besu import ( "context" + "os" + "path/filepath" "testing" + "github.com/hyperledger/firefly-cli/internal/blockchain/ethereum" + "github.com/hyperledger/firefly-cli/pkg/types" "github.com/hyperledger/firefly-common/pkg/fftypes" "github.com/stretchr/testify/assert" @@ -46,3 +50,74 @@ func TestNewBesuProvider(t *testing.T) { }) } } + +func TestParseAccount(t *testing.T) { + input := map[string]interface{}{ + "address": "0xAddress1", + "privateKey": "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff", + } + + besuProvider := &BesuProvider{} + result := besuProvider.ParseAccount(input) + + // Assert that the result is of type *ethereum.Account + if _, ok := result.(*ethereum.Account); !ok { + t.Errorf("Expected result to be of type *ethereum.Account, but got %T", result) + } + expectedAccount := ðereum.Account{ + Address: "0xAddress1", + PrivateKey: "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff", + } + assert.Equal(t, expectedAccount, result, "Generated result unmatched") + +} + +func TestGetContracts(t *testing.T) { + // Create a temporary contract JSON file for testing (replace with your actual test file) + FilePath := "testdata" + testContractFile := filepath.Join(FilePath, "/test_contracts.json") + // Sample contract JSON content for testing + const testContractJSON = `{ + "contracts": { + "Contract1": { + "name": "sample_1", + "abi": "sample_abi_1", + "bin": "sample_bin_1" + }, + "Contract2": { + "name": "sample_2", + "abi": "sample_abi_2", + "bin": "sample_bin_2" + } + } + }` + p := &BesuProvider{} + + err := os.WriteFile(testContractFile, []byte(testContractJSON), 0755) + if err != nil { + t.Log("unable to write file:", err) + } + contracts, err := p.GetContracts(testContractFile, nil) + if err != nil { + t.Log("unable to get contract", err) + } + // Assert that the returned contracts match the expected contract names + expectedContracts := []string{"Contract1", "Contract2"} + if !CompareStringSlices(contracts, expectedContracts) { + t.Errorf("Expected contracts: %v, Got: %v", expectedContracts, contracts) + } +} + +func CompareStringSlices(a, b []string) bool { + //compare string lengths + if len(a) != len(b) { + return false + } + //compare values + for i, v := range a { + if v != b[i] { + return false + } + } + return true +} diff --git a/internal/blockchain/ethereum/besu/testdata/test_contracts.json b/internal/blockchain/ethereum/besu/testdata/test_contracts.json new file mode 100644 index 00000000..7fd46002 --- /dev/null +++ b/internal/blockchain/ethereum/besu/testdata/test_contracts.json @@ -0,0 +1,14 @@ +{ + "contracts": { + "Contract1": { + "name": "sample_1", + "abi": "sample_abi_1", + "bin": "sample_bin_1" + }, + "Contract2": { + "name": "sample_2", + "abi": "sample_abi_2", + "bin": "sample_bin_2" + } + } + } \ No newline at end of file From f41da6dfc0ae38a2450668b29cca6f02e0feb3d9 Mon Sep 17 00:00:00 2001 From: Philip-21 Date: Fri, 29 Dec 2023 08:54:42 +0100 Subject: [PATCH 07/10] tests for geth provider Signed-off-by: Philip-21 --- .../ethereum/besu/besu_provider_test.go | 1 - .../ethereum/geth/geth_provider_test.go | 119 ++++++++++++++++++ 2 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 internal/blockchain/ethereum/geth/geth_provider_test.go diff --git a/internal/blockchain/ethereum/besu/besu_provider_test.go b/internal/blockchain/ethereum/besu/besu_provider_test.go index 42c2d946..c8a8a405 100644 --- a/internal/blockchain/ethereum/besu/besu_provider_test.go +++ b/internal/blockchain/ethereum/besu/besu_provider_test.go @@ -73,7 +73,6 @@ func TestParseAccount(t *testing.T) { } func TestGetContracts(t *testing.T) { - // Create a temporary contract JSON file for testing (replace with your actual test file) FilePath := "testdata" testContractFile := filepath.Join(FilePath, "/test_contracts.json") // Sample contract JSON content for testing diff --git a/internal/blockchain/ethereum/geth/geth_provider_test.go b/internal/blockchain/ethereum/geth/geth_provider_test.go new file mode 100644 index 00000000..a74b3eff --- /dev/null +++ b/internal/blockchain/ethereum/geth/geth_provider_test.go @@ -0,0 +1,119 @@ +package geth + +import ( + "context" + "testing" + + "github.com/hyperledger/firefly-cli/internal/blockchain/ethereum" + "github.com/hyperledger/firefly-cli/pkg/types" + "github.com/hyperledger/firefly-common/pkg/fftypes" + "github.com/stretchr/testify/assert" +) + +func TestNewGethProvider(t *testing.T) { + var ctx context.Context + + testcases := []struct { + Name string + Ctx context.Context + Stack *types.Stack + }{ + { + Name: "testcase1", + Ctx: ctx, + Stack: &types.Stack{ + Name: "TestGethWithEvmConnect", + Members: []*types.Organization{ + { + OrgName: "Org1", + NodeName: "geth", + Account: ðereum.Account{ + Address: "0x1234567890abcdef0123456789abcdef6789abcd", + PrivateKey: "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff", + }, + }, + { + OrgName: "Org2", + NodeName: "geth", + Account: ðereum.Account{ + Address: "0x1234567890abcdef012345670000000000000000", + PrivateKey: "9876543210987654321098765432109876543210987654321098765432109876", + }, + }, + }, + BlockchainProvider: fftypes.FFEnumValue("BlockchainProvider", "Ethereum"), + BlockchainConnector: fftypes.FFEnumValue("BlockchainConnector", "Evmconnect"), + BlockchainNodeProvider: fftypes.FFEnumValue("BlockchainNodeProvider", "geth"), + }, + }, + { + Name: "testcase2", + Ctx: ctx, + Stack: &types.Stack{ + Name: "TestGethWithEthConnect", + Members: []*types.Organization{ + { + OrgName: "Org55", + NodeName: "geth", + Account: ðereum.Account{ + Address: "0x1f2a000000000000000000000000000000000000", + PrivateKey: "aabbccddeeff0011223344556677889900112233445566778899aabbccddeeff", + }, + }, + }, + BlockchainProvider: fftypes.FFEnumValue("BlockchainProvider", "Ethereum"), + BlockchainConnector: fftypes.FFEnumValue("BlockchainConnector", "Ethconnect"), + BlockchainNodeProvider: fftypes.FFEnumValue("BlockchainNodeProvider", "geth"), + }, + }, + } + for _, tc := range testcases { + t.Run(tc.Name, func(t *testing.T) { + gethProvider := NewGethProvider(tc.Ctx, tc.Stack) + assert.NotNil(t, gethProvider) + }) + } +} + +func TestParseAccount(t *testing.T) { + testcases := []struct { + Name string + Address map[string]interface{} + ExpectedAccount *ethereum.Account + }{ + { + Name: "Account 1", + Address: map[string]interface{}{ + "address": "0x1234567890abcdef0123456789abcdef6789abcd", + "privateKey": "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff", + }, + ExpectedAccount: ðereum.Account{ + Address: "0x1234567890abcdef0123456789abcdef6789abcd", + PrivateKey: "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff", + }, + }, + { + Name: "Account 2", + Address: map[string]interface{}{ + "address": "0x549b5f43a40e1a0522864a004cfff2b0ca473a65", + "privateKey": "112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00", + }, + ExpectedAccount: ðereum.Account{ + Address: "0x549b5f43a40e1a0522864a004cfff2b0ca473a65", + PrivateKey: "112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00", + }, + }, + } + for _, tc := range testcases { + t.Run(tc.Name, func(t *testing.T) { + gethProvider := &GethProvider{} + result := gethProvider.ParseAccount(tc.Address) + + _, ok := result.(*ethereum.Account) + if !ok { + t.Errorf("Expected result to be of type *ethereum.Account, but got %T", result) + } + assert.Equal(t, tc.ExpectedAccount, result, "Generated result unmatched") + }) + } +} From 849e1646bd3cf9a0874f9d523a8bf6d495d2150d Mon Sep 17 00:00:00 2001 From: Philip-21 Date: Fri, 29 Dec 2023 19:20:19 +0100 Subject: [PATCH 08/10] more geth unit tests Signed-off-by: Philip-21 --- .../ethereum/geth/geth_provider_test.go | 125 ++++++++++++++++++ .../geth/testdata/test_contracts.json | 14 ++ 2 files changed, 139 insertions(+) create mode 100644 internal/blockchain/ethereum/geth/testdata/test_contracts.json diff --git a/internal/blockchain/ethereum/geth/geth_provider_test.go b/internal/blockchain/ethereum/geth/geth_provider_test.go index a74b3eff..ecf78993 100644 --- a/internal/blockchain/ethereum/geth/geth_provider_test.go +++ b/internal/blockchain/ethereum/geth/geth_provider_test.go @@ -2,6 +2,9 @@ package geth import ( "context" + "os" + "path/filepath" + "testing" "github.com/hyperledger/firefly-cli/internal/blockchain/ethereum" @@ -117,3 +120,125 @@ func TestParseAccount(t *testing.T) { }) } } + +func TestGetOrgConfig(t *testing.T) { + testCases := []struct { + Name string + Org *types.Organization + Stack *types.Stack + OrgConfig *types.OrgConfig + }{ + { + Name: "Testcase1", + Stack: &types.Stack{ + Name: "Org-1", + }, + Org: &types.Organization{ + OrgName: "Org-1", + NodeName: "geth", + Account: ðereum.Account{ + Address: "0x1234567890abcdef0123456789abcdef6789abcd", + PrivateKey: "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff", + }, + }, + OrgConfig: &types.OrgConfig{ + Name: "Org-1", + Key: "0x1234567890abcdef0123456789abcdef6789abcd", + }, + }, + { + Name: "Testcase2", + Stack: &types.Stack{ + Name: "Org-2", + }, + Org: &types.Organization{ + OrgName: "Org-2", + NodeName: "geth", + Account: ðereum.Account{ + Address: "0x1f2a000000000000000000000000000000000000", + PrivateKey: "9876543210987654321098765432109876543210987654321098765432109876", + }, + }, + OrgConfig: &types.OrgConfig{ + Name: "Org-2", + Key: "0x1f2a000000000000000000000000000000000000", + }, + }, + { + Name: "Testcase3", + Stack: &types.Stack{ + Name: "Org-3", + }, + Org: &types.Organization{ + OrgName: "Org-3", + NodeName: "geth", + Account: ðereum.Account{ + Address: "0xabcdeffedcba9876543210abcdeffedc00000000", + PrivateKey: "aabbccddeeff0011223344556677889900112233445566778899aabbccddeeff", + }, + }, + OrgConfig: &types.OrgConfig{ + Name: "Org-3", + Key: "0xabcdeffedcba9876543210abcdeffedc00000000", + }, + }, + } + for _, tc := range testCases { + t.Run(tc.Name, func(t *testing.T) { + p := &GethProvider{} + + Orgconfig := p.GetOrgConfig(tc.Stack, tc.Org) + assert.NotNil(t, Orgconfig) + assert.Equal(t, tc.OrgConfig, Orgconfig) + }) + } +} + +func TestGetContracts(t *testing.T) { + FilePath := "testdata" + testContractFile := filepath.Join(FilePath, "/test_contracts.json") + // Sample contract JSON content for testing + const testContractJSON = `{ + "contracts": { + "Contract1": { + "name": "sample_1", + "abi": "sample_abi_1", + "bin": "sample_bin_1" + }, + "Contract2": { + "name": "sample_2", + "abi": "sample_abi_2", + "bin": "sample_bin_2" + } + } + }` + p := &GethProvider{} + + err := os.WriteFile(testContractFile, []byte(testContractJSON), 0755) + if err != nil { + t.Log("unable to write file:", err) + } + contracts, err := p.GetContracts(testContractFile, nil) + if err != nil { + t.Log("unable to get contract", err) + } + // Assert that the returned contracts match the expected contract names + expectedContracts := []string{"Contract1", "Contract2"} + if !CompareStringSlices(contracts, expectedContracts) { + t.Errorf("Expected contracts: %v, Got: %v", expectedContracts, contracts) + } +} + +func CompareStringSlices(a, b []string) bool { + //compare string lengths + if len(a) != len(b) { + return false + } + //compare values + for i, v := range a { + if v != b[i] { + return false + } + } + return true +} diff --git a/internal/blockchain/ethereum/geth/testdata/test_contracts.json b/internal/blockchain/ethereum/geth/testdata/test_contracts.json new file mode 100644 index 00000000..7fd46002 --- /dev/null +++ b/internal/blockchain/ethereum/geth/testdata/test_contracts.json @@ -0,0 +1,14 @@ +{ + "contracts": { + "Contract1": { + "name": "sample_1", + "abi": "sample_abi_1", + "bin": "sample_bin_1" + }, + "Contract2": { + "name": "sample_2", + "abi": "sample_abi_2", + "bin": "sample_bin_2" + } + } + } \ No newline at end of file From 375c811ff5ae463420d2078a9388d2ffe022a7a2 Mon Sep 17 00:00:00 2001 From: Philip-21 Date: Fri, 29 Dec 2023 21:05:51 +0100 Subject: [PATCH 09/10] more geth and besu unit tests Signed-off-by: Philip-21 --- .../ethereum/besu/besu_provider_test.go | 55 +++++++++++++ .../blockchain/ethereum/geth/genesis_test.go | 77 +++++++++++++++++++ .../geth/testdata/genesis1_output.json | 29 +++++++ .../geth/testdata/genesis2_output.json | 29 +++++++ 4 files changed, 190 insertions(+) create mode 100644 internal/blockchain/ethereum/geth/testdata/genesis1_output.json create mode 100644 internal/blockchain/ethereum/geth/testdata/genesis2_output.json diff --git a/internal/blockchain/ethereum/besu/besu_provider_test.go b/internal/blockchain/ethereum/besu/besu_provider_test.go index c8a8a405..f06ebfc7 100644 --- a/internal/blockchain/ethereum/besu/besu_provider_test.go +++ b/internal/blockchain/ethereum/besu/besu_provider_test.go @@ -120,3 +120,58 @@ func CompareStringSlices(a, b []string) bool { } return true } + +func TestGetOrgConfig(t *testing.T) { + testCases := []struct { + Name string + Org *types.Organization + Stack *types.Stack + OrgConfig *types.OrgConfig + }{ + { + Name: "Testcase1", + Stack: &types.Stack{ + Name: "Org-1", + }, + Org: &types.Organization{ + OrgName: "Org-1", + NodeName: "besu", + Account: ðereum.Account{ + Address: "0x1234567890abcdef0123456789abcdef6789abcd", + PrivateKey: "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff", + }, + }, + OrgConfig: &types.OrgConfig{ + Name: "Org-1", + Key: "0x1234567890abcdef0123456789abcdef6789abcd", + }, + }, + { + Name: "Testcase2", + Stack: &types.Stack{ + Name: "Org-2", + }, + Org: &types.Organization{ + OrgName: "Org-2", + NodeName: "besu", + Account: ðereum.Account{ + Address: "0x1f2a000000000000000000000000000000000000", + PrivateKey: "9876543210987654321098765432109876543210987654321098765432109876", + }, + }, + OrgConfig: &types.OrgConfig{ + Name: "Org-2", + Key: "0x1f2a000000000000000000000000000000000000", + }, + }, + } + for _, tc := range testCases { + t.Run(tc.Name, func(t *testing.T) { + p := &BesuProvider{} + + Orgconfig := p.GetOrgConfig(tc.Stack, tc.Org) + assert.NotNil(t, Orgconfig) + assert.Equal(t, tc.OrgConfig, Orgconfig) + }) + } +} diff --git a/internal/blockchain/ethereum/geth/genesis_test.go b/internal/blockchain/ethereum/geth/genesis_test.go index 11e77817..27a2d2d5 100644 --- a/internal/blockchain/ethereum/geth/genesis_test.go +++ b/internal/blockchain/ethereum/geth/genesis_test.go @@ -1,7 +1,9 @@ package geth import ( + "encoding/json" "fmt" + "os" "strings" "testing" @@ -90,3 +92,78 @@ func TestCreateGenesis(t *testing.T) { }) } } + +func TestWriteGenesisJSON(t *testing.T) { + filepath := "testdata" + + testCases := []struct { + Name string + SampleGenesis Genesis + filename string + }{ + { + Name: "TestCase1", + SampleGenesis: Genesis{ + Config: &GenesisConfig{ + ChainId: int64(456), + Eip155Block: 0, + Eip158Block: 0, + ByzantiumBlock: 0, + ConstantinopleBlock: 0, + IstanbulBlock: 0, + Clique: &CliqueConfig{ + Period: 20, + Epoch: 2000, + }, + }, + }, + filename: filepath + "/genesis1_output.json", + }, + { + Name: "TestCase2", + SampleGenesis: Genesis{ + Config: &GenesisConfig{ + ChainId: int64(338), + ConstantinopleBlock: 0, + Eip155Block: 0, + Eip158Block: 0, + ByzantiumBlock: 0, + IstanbulBlock: 0, + Clique: &CliqueConfig{ + Period: 40, + Epoch: 4000, + }, + }, + }, + filename: filepath + "/genesis2_output.json", + }, + } + for _, tc := range testCases { + t.Run(tc.Name, func(t *testing.T) { + err := tc.SampleGenesis.WriteGenesisJson(tc.filename) + if err != nil { + t.Log("unable to write Genesis JSON", err) + } + // Assert that there is no error + assert.NoError(t, err) + + writtenJSONBytes, err := os.ReadFile(tc.filename) + if err != nil { + t.Log("Unable to write JSON Bytes", err) + } + assert.NoError(t, err) + var writtenGenesis Genesis + + err = json.Unmarshal(writtenJSONBytes, &writtenGenesis) + if err != nil { + t.Log("unable to unmarshal JSON", err) + } + assert.NoError(t, err) + + // Assert that the written Genesis matches the original Genesis + assert.Equal(t, tc.SampleGenesis, writtenGenesis) + }) + + } + +} diff --git a/internal/blockchain/ethereum/geth/testdata/genesis1_output.json b/internal/blockchain/ethereum/geth/testdata/genesis1_output.json new file mode 100644 index 00000000..d82c4210 --- /dev/null +++ b/internal/blockchain/ethereum/geth/testdata/genesis1_output.json @@ -0,0 +1,29 @@ +{ + "config": { + "chainId": 456, + "homesteadBlock": 0, + "eip150Block": 0, + "eip150Hash": "", + "eip155Block": 0, + "eip158Block": 0, + "byzantiumBlock": 0, + "constantinopleBlock": 0, + "petersburgBlock": 0, + "istanbulBlock": 0, + "clique": { + "period": 20, + "epoch": 2000 + } + }, + "nonce": "", + "timestamp": "", + "extraData": "", + "gasLimit": "", + "difficulty": "", + "mixHash": "", + "coinbase": "", + "alloc": null, + "number": "", + "gasUsed": "", + "parentHash": "" +} \ No newline at end of file diff --git a/internal/blockchain/ethereum/geth/testdata/genesis2_output.json b/internal/blockchain/ethereum/geth/testdata/genesis2_output.json new file mode 100644 index 00000000..7159a9f9 --- /dev/null +++ b/internal/blockchain/ethereum/geth/testdata/genesis2_output.json @@ -0,0 +1,29 @@ +{ + "config": { + "chainId": 338, + "homesteadBlock": 0, + "eip150Block": 0, + "eip150Hash": "", + "eip155Block": 0, + "eip158Block": 0, + "byzantiumBlock": 0, + "constantinopleBlock": 0, + "petersburgBlock": 0, + "istanbulBlock": 0, + "clique": { + "period": 40, + "epoch": 4000 + } + }, + "nonce": "", + "timestamp": "", + "extraData": "", + "gasLimit": "", + "difficulty": "", + "mixHash": "", + "coinbase": "", + "alloc": null, + "number": "", + "gasUsed": "", + "parentHash": "" +} \ No newline at end of file From 4abec60a536591012584b47b1d08152c2e890456 Mon Sep 17 00:00:00 2001 From: Philip-21 Date: Sun, 31 Dec 2023 08:03:58 +0100 Subject: [PATCH 10/10] more geth and besu unit tests Signed-off-by: Philip-21 --- .../blockchain/ethereum/besu/genesis_test.go | 42 +++++++++ .../ethereum/geth/geth_provider_test.go | 92 +++++++++++++++++++ 2 files changed, 134 insertions(+) diff --git a/internal/blockchain/ethereum/besu/genesis_test.go b/internal/blockchain/ethereum/besu/genesis_test.go index ed227305..fe6f8b4e 100644 --- a/internal/blockchain/ethereum/besu/genesis_test.go +++ b/internal/blockchain/ethereum/besu/genesis_test.go @@ -7,6 +7,8 @@ import ( "strings" "testing" + "github.com/hyperledger/firefly-cli/internal/blockchain/ethereum" + "github.com/hyperledger/firefly-cli/pkg/types" "github.com/stretchr/testify/assert" ) @@ -143,3 +145,43 @@ func TestWriteGenesisJSON(t *testing.T) { } } + +func TestGetConnectorExternal(t *testing.T) { + testcase := []struct { + Name string + Org *types.Organization + ExpectedPort string + }{ + { + Name: "testcase1", + Org: &types.Organization{ + OrgName: "Org-1", + NodeName: "besu", + Account: ðereum.Account{ + Address: "0x1f2a000000000000000000000000000000000000", + PrivateKey: "9876543210987654321098765432109876543210987654321098765432109876", + }, + ExposedConnectorPort: 8584, + }, + ExpectedPort: "http://127.0.0.1:8584", + }, + { + Name: "testcase2", + Org: &types.Organization{ + OrgName: "Org-2", + NodeName: "besu", + Account: ðereum.Account{ + Address: "0xabcdeffedcba9876543210abcdeffedc00000000", + PrivateKey: "aabbccddeeff0011223344556677889900112233445566778899aabbccddeeff", + }, + ExposedConnectorPort: 8000, + }, + ExpectedPort: "http://127.0.0.1:8000", + }, + } + for _, tc := range testcase { + p := &BesuProvider{} + result := p.GetConnectorExternalURL(tc.Org) + assert.Equal(t, tc.ExpectedPort, result) + } +} \ No newline at end of file diff --git a/internal/blockchain/ethereum/geth/geth_provider_test.go b/internal/blockchain/ethereum/geth/geth_provider_test.go index ecf78993..34cce6b6 100644 --- a/internal/blockchain/ethereum/geth/geth_provider_test.go +++ b/internal/blockchain/ethereum/geth/geth_provider_test.go @@ -2,6 +2,7 @@ package geth import ( "context" + "encoding/hex" "os" "path/filepath" @@ -242,3 +243,94 @@ func CompareStringSlices(a, b []string) bool { } return true } + +func TestGetConnectorExternal(t *testing.T) { + testcase := []struct { + Name string + Org *types.Organization + ExpectedPort string + }{ + { + Name: "testcase1", + Org: &types.Organization{ + OrgName: "Org-1", + NodeName: "geth", + Account: ðereum.Account{ + Address: "0x1f2a000000000000000000000000000000000000", + PrivateKey: "9876543210987654321098765432109876543210987654321098765432109876", + }, + ExposedConnectorPort: 8584, + }, + ExpectedPort: "http://127.0.0.1:8584", + }, + { + Name: "testcase2", + Org: &types.Organization{ + OrgName: "Org-2", + NodeName: "geth", + Account: ðereum.Account{ + Address: "0xabcdeffedcba9876543210abcdeffedc00000000", + PrivateKey: "aabbccddeeff0011223344556677889900112233445566778899aabbccddeeff", + }, + ExposedConnectorPort: 8000, + }, + ExpectedPort: "http://127.0.0.1:8000", + }, + } + for _, tc := range testcase { + p := &GethProvider{} + result := p.GetConnectorExternalURL(tc.Org) + assert.Equal(t, tc.ExpectedPort, result) + } +} + +func TestCreateAccount(t *testing.T) { + testcases := []struct { + Name string + Stack *types.Stack + Args []string + }{ + { + Name: "testcase1", + Stack: &types.Stack{ + Name: "Org-1_geth", + BlockchainProvider: fftypes.FFEnumValue("BlockchainProvider", "Ethereum"), + BlockchainConnector: fftypes.FFEnumValue("BlockChainConnector", "Ethconnect"), + BlockchainNodeProvider: fftypes.FFEnumValue("BlockchainNodeProvider", "geth"), + }, + Args: []string{}, + }, + { + Name: "testcase1", + Stack: &types.Stack{ + Name: "Org-2_geth", + BlockchainProvider: fftypes.FFEnumValue("BlockchainProvider", "Ethereum"), + BlockchainConnector: fftypes.FFEnumValue("BlockChainConnector", "Ethconnect"), + BlockchainNodeProvider: fftypes.FFEnumValue("BlockchainNodeProvider", "geth"), + }, + Args: []string{}, + }, + } + for _, tc := range testcases { + t.Run(tc.Name, func(t *testing.T) { + p := &GethProvider{ + stack: tc.Stack, + } + Account, err := p.CreateAccount(tc.Args) + if err != nil { + t.Log("unable to create account", err) + } + //validate properties of account + assert.NotNil(t, Account) + account, ok := Account.(*ethereum.Account) + assert.True(t, ok, "unexpected Type for account") + + //check if Ethereum Addresss is valid + assert.NotEmpty(t, account.Address) + // Check if the private key is a non-empty hex string + assert.NotEmpty(t, account.PrivateKey) + _, err = hex.DecodeString(account.PrivateKey) + assert.NoError(t, err, "invalid private key format") + }) + } +}