Implement initial go test for network.Create
This commit is contained in:
parent
168b65ea1d
commit
71bc182ab4
@ -6,8 +6,8 @@ import (
|
||||
"io"
|
||||
"isle/bootstrap"
|
||||
"isle/toolkit"
|
||||
"isle/yamlutil"
|
||||
"net"
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
_ "embed"
|
||||
@ -71,7 +71,7 @@ type NetworkConfig struct {
|
||||
Tun ConfigTun `yaml:"tun"`
|
||||
} `yaml:"vpn"`
|
||||
Storage struct {
|
||||
Allocations []ConfigStorageAllocation
|
||||
Allocations []ConfigStorageAllocation `yaml:"allocations"`
|
||||
} `yaml:"storage"`
|
||||
}
|
||||
|
||||
@ -145,6 +145,18 @@ func (c *NetworkConfig) fillDefaults() {
|
||||
)
|
||||
}
|
||||
|
||||
// UnmarshalYAML implements the yaml.Unmarshaler interface. It will attempt to
|
||||
// fill in default values where it can.
|
||||
func (c *NetworkConfig) UnmarshalYAML(n *yaml.Node) error {
|
||||
type wrap NetworkConfig
|
||||
if err := n.Decode((*wrap)(c)); err != nil {
|
||||
return fmt.Errorf("decoding into %T: %w", c, err)
|
||||
}
|
||||
|
||||
c.fillDefaults()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Config describes the structure of the daemon config file.
|
||||
type Config struct {
|
||||
Networks map[string]NetworkConfig `yaml:"networks"`
|
||||
@ -186,6 +198,30 @@ func CopyDefaultConfig(into io.Writer) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// UnmarshalYAML implements the yaml.Unmarshaler interface. It will attempt to
|
||||
// fill in default values where it can.
|
||||
func (c *Config) UnmarshalYAML(n *yaml.Node) error {
|
||||
{ // DEPRECATED
|
||||
var networkConfig NetworkConfig
|
||||
_ = n.Decode(&networkConfig)
|
||||
if !toolkit.IsZero(networkConfig) {
|
||||
*c = Config{
|
||||
Networks: map[string]NetworkConfig{
|
||||
DeprecatedNetworkID: networkConfig,
|
||||
},
|
||||
}
|
||||
return c.Validate()
|
||||
}
|
||||
}
|
||||
|
||||
type wrap Config
|
||||
if err := n.Decode((*wrap)(c)); err != nil {
|
||||
return fmt.Errorf("yaml unmarshaling back into Config struct: %w", err)
|
||||
}
|
||||
|
||||
return c.Validate()
|
||||
}
|
||||
|
||||
// LoadConfig loads the daemon config from userConfigPath.
|
||||
//
|
||||
// If userConfigPath is not given then the default is loaded and returned.
|
||||
@ -194,37 +230,9 @@ func LoadConfig(userConfigPath string) (Config, error) {
|
||||
return Config{}, nil
|
||||
}
|
||||
|
||||
userConfigB, err := os.ReadFile(userConfigPath)
|
||||
if err != nil {
|
||||
return Config{}, fmt.Errorf("reading from file: %w", err)
|
||||
}
|
||||
|
||||
{ // DEPRECATED
|
||||
var networkConfig NetworkConfig
|
||||
_ = yaml.Unmarshal(userConfigB, &networkConfig)
|
||||
if !toolkit.IsZero(networkConfig) {
|
||||
networkConfig.fillDefaults()
|
||||
config := Config{
|
||||
Networks: map[string]NetworkConfig{
|
||||
DeprecatedNetworkID: networkConfig,
|
||||
},
|
||||
}
|
||||
return config, config.Validate()
|
||||
}
|
||||
}
|
||||
|
||||
var config Config
|
||||
if err := yaml.Unmarshal(userConfigB, &config); err != nil {
|
||||
return Config{}, fmt.Errorf("yaml unmarshaling back into Config struct: %w", err)
|
||||
}
|
||||
|
||||
for id := range config.Networks {
|
||||
network := config.Networks[id]
|
||||
network.fillDefaults()
|
||||
config.Networks[id] = network
|
||||
}
|
||||
|
||||
return config, config.Validate()
|
||||
err := yamlutil.LoadYamlFile(&config, userConfigPath)
|
||||
return config, err
|
||||
}
|
||||
|
||||
// BootstrapGarageHostForAlloc returns the bootstrap.GarageHostInstance which
|
||||
|
150
go/daemon/network/network_test.go
Normal file
150
go/daemon/network/network_test.go
Normal file
@ -0,0 +1,150 @@
|
||||
package network
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
|
||||
"isle/bootstrap"
|
||||
"isle/daemon/daecommon"
|
||||
"isle/nebula"
|
||||
"isle/toolkit"
|
||||
|
||||
"dev.mediocregopher.com/mediocre-go-lib.git/mlog"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
var (
|
||||
envBinDirPath = func() string {
|
||||
appDirPath := os.Getenv("APPDIR")
|
||||
if appDirPath == "" {
|
||||
panic("APPDIR not set")
|
||||
}
|
||||
return filepath.Join(appDirPath, "bin")
|
||||
}()
|
||||
|
||||
ipNetCounter uint64
|
||||
)
|
||||
|
||||
func newIPNet(t *testing.T) nebula.IPNet {
|
||||
var (
|
||||
ipNet nebula.IPNet
|
||||
ipNetStr = fmt.Sprintf(
|
||||
"172.16.%d.0/24", atomic.AddUint64(&ipNetCounter, 1),
|
||||
)
|
||||
)
|
||||
|
||||
if err := ipNet.UnmarshalText([]byte(ipNetStr)); err != nil {
|
||||
t.Fatalf("parsing IPNet from %q: %v", ipNetStr, err)
|
||||
}
|
||||
|
||||
return ipNet
|
||||
}
|
||||
|
||||
func mustParseNetworkConfigf(str string, args ...any) daecommon.NetworkConfig {
|
||||
str = fmt.Sprintf(str, args...)
|
||||
|
||||
var networkConfig daecommon.NetworkConfig
|
||||
if err := yaml.Unmarshal([]byte(str), &networkConfig); err != nil {
|
||||
panic(fmt.Sprintf("parsing network config: %v", err))
|
||||
}
|
||||
return networkConfig
|
||||
}
|
||||
|
||||
type harness struct {
|
||||
ctx context.Context
|
||||
logger *mlog.Logger
|
||||
rootDir toolkit.Dir
|
||||
dirCounter uint64
|
||||
}
|
||||
|
||||
func newHarness(t *testing.T) *harness {
|
||||
return &harness{
|
||||
ctx: context.Background(),
|
||||
logger: mlog.NewLogger(nil),
|
||||
rootDir: toolkit.Dir{Path: t.TempDir()},
|
||||
}
|
||||
}
|
||||
|
||||
func (h *harness) mkDir(t *testing.T, name string) toolkit.Dir {
|
||||
fullName := fmt.Sprintf("%s-%d", name, atomic.AddUint64(&h.dirCounter, 1))
|
||||
|
||||
t.Logf("Creating directory %q", fullName)
|
||||
d, err := h.rootDir.MkChildDir(fullName, false)
|
||||
if err != nil {
|
||||
t.Fatalf("creating %q: %v", fullName, err)
|
||||
}
|
||||
|
||||
return d
|
||||
}
|
||||
|
||||
func TestCreate(t *testing.T) {
|
||||
var (
|
||||
h = newHarness(t)
|
||||
creationParams = bootstrap.NewCreationParams("test", "test.localnet")
|
||||
networkConfig = mustParseNetworkConfigf(`
|
||||
vpn:
|
||||
public_addr: "127.0.0.1:10000"
|
||||
tun:
|
||||
device: isle-test
|
||||
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
|
||||
`,
|
||||
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,
|
||||
)
|
||||
stateDir = h.mkDir(t, "state")
|
||||
runtimeDir = h.mkDir(t, "runtime")
|
||||
ipNet = newIPNet(t)
|
||||
hostName = nebula.HostName("primus")
|
||||
)
|
||||
|
||||
network, err := Create(
|
||||
h.ctx,
|
||||
h.logger.WithNamespace("network"),
|
||||
networkConfig,
|
||||
envBinDirPath,
|
||||
stateDir,
|
||||
runtimeDir,
|
||||
creationParams,
|
||||
ipNet,
|
||||
hostName,
|
||||
nil,
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("creating Network: %v", err)
|
||||
}
|
||||
t.Cleanup(func() {
|
||||
t.Log("Shutting down Network")
|
||||
if err := network.Shutdown(); err != nil {
|
||||
t.Logf("Shutting down Network failed: %v", err)
|
||||
}
|
||||
})
|
||||
|
||||
gotCreationParams, err := network.GetNetworkCreationParams(h.ctx)
|
||||
if err != nil {
|
||||
t.Fatalf("calling GetNetworkCreationParams: %v", err)
|
||||
} else if creationParams != gotCreationParams {
|
||||
t.Fatalf(
|
||||
"expected CreationParams %+v, got %+v",
|
||||
creationParams,
|
||||
gotCreationParams,
|
||||
)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user