Skip to content
Snippets Groups Projects
Unverified Commit 5673ae79 authored by jonastheis's avatar jonastheis
Browse files

Add comments/doc to the code

parent 8b4d2734
Branches
No related tags found
No related merge requests found
...@@ -9,9 +9,9 @@ services: ...@@ -9,9 +9,9 @@ services:
volumes: volumes:
- ./config.entry_node.json:/config.json:ro - ./config.entry_node.json:/config.json:ro
ports: ports:
- "9000:9000/tcp" - "9000:9000/tcp" # visualizer
expose: expose:
- "1888/tcp" - "1888/tcp" # analysis server (within Docker network)
networks: networks:
- integration-test - integration-test
...@@ -23,8 +23,8 @@ services: ...@@ -23,8 +23,8 @@ services:
volumes: volumes:
- ./config.peer_master.json:/config.json:ro - ./config.peer_master.json:/config.json:ro
ports: ports:
- "8080:8080/tcp" - "8080:8080/tcp" # web API
- "8081:8081/tcp" - "8081:8081/tcp" # dashboard
depends_on: depends_on:
- entry_node - entry_node
networks: networks:
...@@ -37,7 +37,7 @@ services: ...@@ -37,7 +37,7 @@ services:
volumes: volumes:
- ./config.peer_replica.json:/config.json:ro - ./config.peer_replica.json:/config.json:ro
expose: expose:
- "8080/tcp" - "8080/tcp" # web API (within Docker network)
depends_on: depends_on:
- entry_node - entry_node
networks: networks:
......
// 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 package framework
import ( import (
...@@ -8,11 +12,15 @@ import ( ...@@ -8,11 +12,15 @@ import (
"github.com/docker/docker/client" "github.com/docker/docker/client"
) )
// Framework is a wrapper encapsulating all peers
type Framework struct { type Framework struct {
peers []*Peer peers []*Peer
dockerCli *client.Client 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 { func New() *Framework {
fmt.Printf("Finding available peers...\n") fmt.Printf("Finding available peers...\n")
...@@ -44,6 +52,8 @@ func New() *Framework { ...@@ -44,6 +52,8 @@ func New() *Framework {
return f 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() { func (f *Framework) waitForAutopeering() {
maxTries := autopeeringMaxTries maxTries := autopeeringMaxTries
for maxTries > 0 { for maxTries > 0 {
...@@ -78,10 +88,12 @@ func (f *Framework) waitForAutopeering() { ...@@ -78,10 +88,12 @@ func (f *Framework) waitForAutopeering() {
panic("Peering not successful.") panic("Peering not successful.")
} }
// Peers returns all available peers.
func (f *Framework) Peers() []*Peer { func (f *Framework) Peers() []*Peer {
return f.peers return f.peers
} }
// RandomPeer returns a random peer out of the list of peers.
func (f *Framework) RandomPeer() *Peer { func (f *Framework) RandomPeer() *Peer {
return f.peers[rand.Intn(len(f.peers))] return f.peers[rand.Intn(len(f.peers))]
} }
...@@ -15,6 +15,7 @@ import ( ...@@ -15,6 +15,7 @@ import (
"github.com/iotaledger/goshimmer/client" "github.com/iotaledger/goshimmer/client"
) )
// Peer represents a GoShimmer node inside the Docker network
type Peer struct { type Peer struct {
name string name string
ip net.IP ip net.IP
...@@ -24,6 +25,7 @@ type Peer struct { ...@@ -24,6 +25,7 @@ type Peer struct {
accepted []getNeighbors.Neighbor 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 { func NewPeer(name string, ip net.IP, dockerCli *dockerclient.Client) *Peer {
return &Peer{ return &Peer{
name: name, name: name,
...@@ -37,10 +39,12 @@ func (p *Peer) String() string { ...@@ -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()) 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 { func (p *Peer) TotalNeighbors() int {
return len(p.chosen) + len(p.accepted) return len(p.chosen) + len(p.accepted)
} }
// SetNeighbors sets the neighbors of the peer accordingly.
func (p *Peer) SetNeighbors(chosen, accepted []getNeighbors.Neighbor) { func (p *Peer) SetNeighbors(chosen, accepted []getNeighbors.Neighbor) {
p.chosen = make([]getNeighbors.Neighbor, len(chosen)) p.chosen = make([]getNeighbors.Neighbor, len(chosen))
copy(p.chosen, chosen) copy(p.chosen, chosen)
...@@ -49,13 +53,15 @@ func (p *Peer) SetNeighbors(chosen, accepted []getNeighbors.Neighbor) { ...@@ -49,13 +53,15 @@ func (p *Peer) SetNeighbors(chosen, accepted []getNeighbors.Neighbor) {
copy(p.accepted, accepted) 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) { func (p *Peer) Logs() (io.ReadCloser, error) {
return p.dockerCli.ContainerLogs( return p.dockerCli.ContainerLogs(
context.Background(), context.Background(),
p.name, p.name,
types.ContainerLogsOptions{ types.ContainerLogsOptions{
ShowStdout: true, ShowStdout: true,
ShowStderr: false, ShowStderr: true,
Since: "", Since: "",
Timestamps: false, Timestamps: false,
Follow: false, Follow: false,
...@@ -64,6 +70,9 @@ func (p *Peer) Logs() (io.ReadCloser, error) { ...@@ -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) { func getAvailablePeers(dockerCli *dockerclient.Client) (peers []*Peer) {
// get peer master // get peer master
if addr, err := net.LookupIP(hostnamePeerMaster); err != nil { if addr, err := net.LookupIP(hostnamePeerMaster); err != nil {
...@@ -87,6 +96,7 @@ func getAvailablePeers(dockerCli *dockerclient.Client) (peers []*Peer) { ...@@ -87,6 +96,7 @@ func getAvailablePeers(dockerCli *dockerclient.Client) (peers []*Peer) {
return return
} }
// getWebApiBaseUrl returns the web API base url for the given IP.
func getWebApiBaseUrl(ip net.IP) string { func getWebApiBaseUrl(ip net.IP) string {
return fmt.Sprintf("http://%s:%s", ip.String(), apiPort) return fmt.Sprintf("http://%s:%s", ip.String(), apiPort)
} }
...@@ -12,12 +12,12 @@ import ( ...@@ -12,12 +12,12 @@ import (
// TestDockerLogs simply verifies that a peer's log message contains "GoShimmer". // 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. // Using the combination of logs and regular expressions can be useful to test a certain peer's behavior.
func TestDockerLogs(t *testing.T) { func TestDockerLogs(t *testing.T) {
r := regexp.MustCompile("GoShimmer")
for _, p := range f.Peers() { for _, p := range f.Peers() {
log, err := p.Logs() log, err := p.Logs()
require.NoError(t, err) require.NoError(t, err)
r := regexp.MustCompile("GoShimmer")
assert.True(t, r.MatchReader(bufio.NewReader(log))) assert.True(t, r.MatchReader(bufio.NewReader(log)))
} }
} }
// 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 package tests
import ( import (
...@@ -9,6 +14,8 @@ import ( ...@@ -9,6 +14,8 @@ import (
var f *framework.Framework 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) { func TestMain(m *testing.M) {
f = framework.New() f = framework.New()
......
...@@ -10,6 +10,8 @@ import ( ...@@ -10,6 +10,8 @@ import (
"github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload" "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) { func TestRelayMessages(t *testing.T) {
numMessages := 100 numMessages := 100
ids := make([]string, numMessages) ids := make([]string, numMessages)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment