Implement basic test for network.Join

This commit is contained in:
Brian Picciano 2024-10-14 12:12:43 +02:00
parent cb6c11acef
commit f639d460cf
2 changed files with 185 additions and 59 deletions

View File

@ -1,6 +1,7 @@
package network
import (
"reflect"
"testing"
)
@ -55,3 +56,29 @@ func TestLoad(t *testing.T) {
}
})
}
func TestJoin(t *testing.T) {
var (
h = newIntegrationHarness(t)
primus = h.createNetwork(t, "primus", nil)
secondus = h.joinNetwork(t, primus, "secondus", nil)
)
primusHosts, err := primus.GetHosts(h.ctx)
if err != nil {
t.Fatalf("getting hosts from primus: %v", err)
}
secondusHosts, err := secondus.GetHosts(h.ctx)
if err != nil {
t.Fatalf("getting hosts from secondus: %v", err)
}
if !reflect.DeepEqual(primusHosts, secondusHosts) {
t.Fatalf(
"expected primusHosts %+v to equal secondusHosts %+v",
primusHosts,
secondusHosts,
)
}
}

View File

@ -2,6 +2,7 @@ package network
import (
"context"
"encoding/json"
"fmt"
"io"
"isle/bootstrap"
@ -118,6 +119,85 @@ func (h *integrationHarness) mkDir(t *testing.T, name string) toolkit.Dir {
return d
}
type networkConfigOpts struct {
hasPublicAddr bool
numStorageAllocs int
}
func (h *integrationHarness) mkNetworkConfig(
t *testing.T,
opts *networkConfigOpts,
) daecommon.NetworkConfig {
if opts == nil {
opts = new(networkConfigOpts)
}
publicAddr := ""
if opts.hasPublicAddr {
publicAddr = newPublicAddr()
}
allocs := make([]map[string]any, opts.numStorageAllocs)
for i := range allocs {
allocs[i] = map[string]any{
"data_path": h.mkDir(t, "data").Path,
"meta_path": h.mkDir(t, "meta").Path,
"capacity": 1,
}
}
allocsJSON, err := json.Marshal(allocs)
if err != nil {
t.Fatalf("marshaling allocs: %v", err)
}
return mustParseNetworkConfigf(`
vpn:
public_addr: %q
tun:
device: %q
storage:
allocations: %s
`,
publicAddr,
newTunDevice(),
allocsJSON,
)
}
func (h *integrationHarness) mkChildrenOpts(
t *testing.T, runtimeDir toolkit.Dir,
) *children.Opts {
var (
childrenLogFilePath = filepath.Join(runtimeDir.Path, "children.log")
childrenOpts children.Opts
)
childrenLogFile, err := os.Create(childrenLogFilePath)
if err != nil {
t.Fatalf("creating %q: %v", childrenLogFilePath, err)
}
t.Cleanup(func() {
if err := childrenLogFile.Close(); err != nil {
t.Errorf("closing %q: %v", childrenLogFilePath, err)
}
})
if os.Getenv("ISLE_INTEGRATION_TEST_CHILDREN_LOG_STDOUT") == "" {
childrenOpts = children.Opts{
Stdout: childrenLogFile,
Stderr: childrenLogFile,
}
} else {
childrenOpts = children.Opts{
Stdout: io.MultiWriter(os.Stdout, childrenLogFile),
Stderr: io.MultiWriter(os.Stdout, childrenLogFile),
}
}
return &childrenOpts
}
type createNetworkOpts struct {
creationParams bootstrap.CreationParams
manualShutdown bool
@ -149,75 +229,29 @@ func (h *integrationHarness) createNetwork(
hostNameStr string,
opts *createNetworkOpts,
) integrationHarnessNetwork {
t.Logf("Creating as %q", hostNameStr)
opts = opts.withDefaults()
var (
networkConfig = mustParseNetworkConfigf(`
vpn:
public_addr: %q
tun:
device: %q
storage:
allocations:
- data_path: %s
meta_path: %s
capacity: 1
- data_path: %s
meta_path: %s
capacity: 1
- data_path: %s
meta_path: %s
capacity: 1
`,
newPublicAddr(),
newTunDevice(),
h.mkDir(t, "data").Path,
h.mkDir(t, "meta").Path,
h.mkDir(t, "data").Path,
h.mkDir(t, "meta").Path,
h.mkDir(t, "data").Path,
h.mkDir(t, "meta").Path,
)
networkConfig = h.mkNetworkConfig(t, &networkConfigOpts{
hasPublicAddr: true,
numStorageAllocs: 3,
})
stateDir = h.mkDir(t, "state")
runtimeDir = h.mkDir(t, "runtime")
childrenLogFilePath = filepath.Join(runtimeDir.Path, "children.log")
ipNet = newIPNet()
hostName = nebula.HostName(hostNameStr)
childrenOpts *children.Opts
networkOpts = &Opts{
ChildrenOpts: h.mkChildrenOpts(t, runtimeDir),
}
)
childrenLogFile, err := os.Create(childrenLogFilePath)
if err != nil {
t.Fatalf("creating %q: %v", childrenLogFilePath, err)
}
t.Cleanup(func() {
if err := childrenLogFile.Close(); err != nil {
t.Errorf("closing %q: %v", childrenLogFilePath, err)
}
})
if os.Getenv("ISLE_INTEGRATION_TEST_CHILDREN_LOG_STDOUT") == "" {
childrenOpts = &children.Opts{
Stdout: childrenLogFile,
Stderr: childrenLogFile,
}
} else {
childrenOpts = &children.Opts{
Stdout: io.MultiWriter(os.Stdout, childrenLogFile),
Stderr: io.MultiWriter(os.Stdout, childrenLogFile),
}
}
networkOpts := &Opts{
ChildrenOpts: childrenOpts,
}
network, err := Create(
h.ctx,
h.logger.WithNamespace("network"),
h.logger.WithNamespace("network").WithNamespace(hostNameStr),
networkConfig,
getEnvBinDirPath(),
stateDir,
@ -233,9 +267,9 @@ func (h *integrationHarness) createNetwork(
if !opts.manualShutdown {
t.Cleanup(func() {
t.Log("Shutting down Network")
t.Logf("Shutting down Network %q", hostNameStr)
if err := network.Shutdown(); err != nil {
t.Logf("Shutting down Network failed: %v", err)
t.Logf("Shutting down Network %q failed: %v", hostNameStr, err)
}
})
}
@ -249,3 +283,68 @@ func (h *integrationHarness) createNetwork(
networkOpts,
}
}
type joinNetworkOpts struct {
networkConfigOpts
canCreateHosts bool
manualShutdown bool
}
func (h *integrationHarness) joinNetwork(
t *testing.T,
network integrationHarnessNetwork,
hostNameStr string,
opts *joinNetworkOpts,
) integrationHarnessNetwork {
t.Logf("Joining as %q", hostNameStr)
opts = new(joinNetworkOpts)
var (
networkConfig = h.mkNetworkConfig(t, &opts.networkConfigOpts)
stateDir = h.mkDir(t, "state")
runtimeDir = h.mkDir(t, "runtime")
hostName = nebula.HostName(hostNameStr)
networkOpts = &Opts{
ChildrenOpts: h.mkChildrenOpts(t, runtimeDir),
}
)
joiningBootstrap, err := network.CreateHost(h.ctx, hostName, CreateHostOpts{
CanCreateHosts: opts.canCreateHosts,
})
if err != nil {
t.Fatalf("creating host joining bootstrap: %v", err)
}
joinedNetwork, err := Join(
h.ctx,
h.logger.WithNamespace("network").WithNamespace(hostNameStr),
networkConfig,
joiningBootstrap,
getEnvBinDirPath(),
stateDir,
runtimeDir,
networkOpts,
)
if err != nil {
t.Fatalf("joining network: %v", err)
}
if !opts.manualShutdown {
t.Cleanup(func() {
t.Logf("Shutting down Network %q", hostNameStr)
if err := joinedNetwork.Shutdown(); err != nil {
t.Logf("Shutting down Network %q failed: %v", hostNameStr, err)
}
})
}
return integrationHarnessNetwork{
joinedNetwork,
network.creationParams,
networkConfig,
stateDir,
runtimeDir,
networkOpts,
}
}