diff --git a/tools/integration-tests/docker-compose.yml b/tools/integration-tests/docker-compose.yml index 6f6f1c959e37074e2c718716f65665fffc9f4687..c0bacb2e75e9f8532cbdfa19bac32e63f9aab3a1 100644 --- a/tools/integration-tests/docker-compose.yml +++ b/tools/integration-tests/docker-compose.yml @@ -9,9 +9,9 @@ services: volumes: - ./config.entry_node.json:/config.json:ro ports: - - "9000:9000/tcp" + - "9000:9000/tcp" # visualizer expose: - - "1888/tcp" + - "1888/tcp" # analysis server (within Docker network) networks: - integration-test @@ -23,8 +23,8 @@ services: volumes: - ./config.peer_master.json:/config.json:ro ports: - - "8080:8080/tcp" - - "8081:8081/tcp" + - "8080:8080/tcp" # web API + - "8081:8081/tcp" # dashboard depends_on: - entry_node networks: @@ -37,7 +37,7 @@ services: volumes: - ./config.peer_replica.json:/config.json:ro expose: - - "8080/tcp" + - "8080/tcp" # web API (within Docker network) depends_on: - entry_node networks: diff --git a/tools/integration-tests/tester/framework/framework.go b/tools/integration-tests/tester/framework/framework.go index 9edb5fa111f53d9bfb1caeba803374011809c25b..58aba94da446c5fea1f2d83512eef940dd5e6793 100644 --- a/tools/integration-tests/tester/framework/framework.go +++ b/tools/integration-tests/tester/framework/framework.go @@ -1,3 +1,7 @@ +// Package framework provides integration test functionality for GoShimmer with a Docker network. +// It effectively abstracts away all complexity with discovering peers, +// waiting for them to autopeer and offers easy access to the peers' web API +// and logs via Docker. package framework import ( @@ -8,11 +12,15 @@ import ( "github.com/docker/docker/client" ) +// Framework is a wrapper encapsulating all peers type Framework struct { peers []*Peer dockerCli *client.Client } +// New creates a new instance of Framework, gets all available peers within the Docker network and +// waits for them to autopeer. +// Panics if no peer is found. func New() *Framework { fmt.Printf("Finding available peers...\n") @@ -44,6 +52,8 @@ func New() *Framework { return f } +// waitForAutopeering waits until all peers have reached a minimum amount of neighbors. +// Panics if this minimum is not reached after autopeeringMaxTries. func (f *Framework) waitForAutopeering() { maxTries := autopeeringMaxTries for maxTries > 0 { @@ -78,10 +88,12 @@ func (f *Framework) waitForAutopeering() { panic("Peering not successful.") } +// Peers returns all available peers. func (f *Framework) Peers() []*Peer { return f.peers } +// RandomPeer returns a random peer out of the list of peers. func (f *Framework) RandomPeer() *Peer { return f.peers[rand.Intn(len(f.peers))] } diff --git a/tools/integration-tests/tester/framework/peer.go b/tools/integration-tests/tester/framework/peer.go index 3562d79d5425c9e2ab79a067238d21d0d20eb515..14f9466c69fc629285c060c1c673986e5e298e82 100644 --- a/tools/integration-tests/tester/framework/peer.go +++ b/tools/integration-tests/tester/framework/peer.go @@ -15,6 +15,7 @@ import ( "github.com/iotaledger/goshimmer/client" ) +// Peer represents a GoShimmer node inside the Docker network type Peer struct { name string ip net.IP @@ -24,6 +25,7 @@ type Peer struct { accepted []getNeighbors.Neighbor } +// NewPeer creates a new instance of Peer with the given information. func NewPeer(name string, ip net.IP, dockerCli *dockerclient.Client) *Peer { return &Peer{ name: name, @@ -37,10 +39,12 @@ func (p *Peer) String() string { return fmt.Sprintf("Peer:{%s, %s, %s, %d}", p.name, p.ip.String(), p.BaseUrl(), p.TotalNeighbors()) } +// TotalNeighbors returns the total number of neighbors the peer has. func (p *Peer) TotalNeighbors() int { return len(p.chosen) + len(p.accepted) } +// SetNeighbors sets the neighbors of the peer accordingly. func (p *Peer) SetNeighbors(chosen, accepted []getNeighbors.Neighbor) { p.chosen = make([]getNeighbors.Neighbor, len(chosen)) copy(p.chosen, chosen) @@ -49,13 +53,15 @@ func (p *Peer) SetNeighbors(chosen, accepted []getNeighbors.Neighbor) { copy(p.accepted, accepted) } +// Logs returns the logs of the peer as io.ReadCloser. +// Logs are returned via Docker and contain every log entry since start of the container/GoShimmer node. func (p *Peer) Logs() (io.ReadCloser, error) { return p.dockerCli.ContainerLogs( context.Background(), p.name, types.ContainerLogsOptions{ ShowStdout: true, - ShowStderr: false, + ShowStderr: true, Since: "", Timestamps: false, Follow: false, @@ -64,6 +70,9 @@ func (p *Peer) Logs() (io.ReadCloser, error) { }) } +// getAvailablePeers gets all available peers in the Docker network. +// It uses the expected Docker hostnames and tries to resolve them. +// If that does not work it means the host is not available in the network func getAvailablePeers(dockerCli *dockerclient.Client) (peers []*Peer) { // get peer master if addr, err := net.LookupIP(hostnamePeerMaster); err != nil { @@ -87,6 +96,7 @@ func getAvailablePeers(dockerCli *dockerclient.Client) (peers []*Peer) { return } +// getWebApiBaseUrl returns the web API base url for the given IP. func getWebApiBaseUrl(ip net.IP) string { return fmt.Sprintf("http://%s:%s", ip.String(), apiPort) } diff --git a/tools/integration-tests/tester/tests/dockerlogs_test.go b/tools/integration-tests/tester/tests/dockerlogs_test.go index b9cb6d14408a56e5c1e9f1fa9cb7ddab879b8206..49189d969b9acbfb3449e017457692c5061880a4 100644 --- a/tools/integration-tests/tester/tests/dockerlogs_test.go +++ b/tools/integration-tests/tester/tests/dockerlogs_test.go @@ -12,12 +12,12 @@ import ( // TestDockerLogs simply verifies that a peer's log message contains "GoShimmer". // Using the combination of logs and regular expressions can be useful to test a certain peer's behavior. func TestDockerLogs(t *testing.T) { + r := regexp.MustCompile("GoShimmer") + for _, p := range f.Peers() { log, err := p.Logs() require.NoError(t, err) - r := regexp.MustCompile("GoShimmer") - assert.True(t, r.MatchReader(bufio.NewReader(log))) } } diff --git a/tools/integration-tests/tester/tests/main_test.go b/tools/integration-tests/tester/tests/main_test.go index f80f520082fc09e0702b9638e4ceb7fd4eed405e..bc82c6c961871b4f798c0c5b3497fdfa5b8f9b2d 100644 --- a/tools/integration-tests/tester/tests/main_test.go +++ b/tools/integration-tests/tester/tests/main_test.go @@ -1,3 +1,8 @@ +// Package tests provides the possibility to write integration tests in regular Go style. +// The integration test framework is initialized before any test in the package runs and +// thus can readily be used to make requests to peers and read their logs. +// +// Each tested feature should reside in its own test file and define tests cases as necessary. package tests import ( @@ -9,6 +14,8 @@ import ( var f *framework.Framework +// TestMain gets called by the test utility and is executed before any other test in this package. +// It is therefore used to initialize the integration testing framework. func TestMain(m *testing.M) { f = framework.New() diff --git a/tools/integration-tests/tester/tests/relaymessage_test.go b/tools/integration-tests/tester/tests/relaymessage_test.go index 41f88ec1e6215bb59602f43fc30c7091abe675a2..d2cc24b75919ea29700ab29050bafcfd6a3da1d9 100644 --- a/tools/integration-tests/tester/tests/relaymessage_test.go +++ b/tools/integration-tests/tester/tests/relaymessage_test.go @@ -10,6 +10,8 @@ import ( "github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload" ) +// TestRelayMessages checks whether messages are actually relayed/gossiped through the network +// by checking the messages' existence on all nodes after a cool down. func TestRelayMessages(t *testing.T) { numMessages := 100 ids := make([]string, numMessages)