[WIP] Fix unit tests
This commit is contained in:
@@ -21,7 +21,7 @@ type testInstance struct {
|
||||
|
||||
var _ instance = &testInstance{}
|
||||
|
||||
func (stub *testInstance) Updates() *updates.Updates {
|
||||
func (stub *testInstance) IntelUpdates() *updates.Updates {
|
||||
return stub.updates
|
||||
}
|
||||
|
||||
@@ -54,6 +54,15 @@ func runTest(m *testing.M) error {
|
||||
return fmt.Errorf("failed to initialize dataroot: %w", err)
|
||||
}
|
||||
defer func() { _ = os.RemoveAll(ds) }()
|
||||
installDir, err := os.MkdirTemp("", "geoip_installdir")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create tmp install dir: %w", err)
|
||||
}
|
||||
defer func() { _ = os.RemoveAll(installDir) }()
|
||||
err = updates.GenerateMockFolder(installDir, "Test Intel", "1.0.0")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to generate mock installation: %w", err)
|
||||
}
|
||||
|
||||
stub := &testInstance{}
|
||||
stub.db, err = dbmodule.New(stub)
|
||||
@@ -68,7 +77,10 @@ func runTest(m *testing.M) error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create api: %w", err)
|
||||
}
|
||||
stub.updates, err = updates.New(stub)
|
||||
stub.updates, err = updates.New(stub, "Test Intel", updates.UpdateIndex{
|
||||
Directory: installDir,
|
||||
IndexFile: "index.json",
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create updates: %w", err)
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ type testInstance struct {
|
||||
|
||||
var _ instance = &testInstance{}
|
||||
|
||||
func (stub *testInstance) Updates() *updates.Updates {
|
||||
func (stub *testInstance) IntelUpdates() *updates.Updates {
|
||||
return stub.updates
|
||||
}
|
||||
|
||||
@@ -54,6 +54,15 @@ func runTest(m *testing.M) error {
|
||||
return fmt.Errorf("failed to initialize dataroot: %w", err)
|
||||
}
|
||||
defer func() { _ = os.RemoveAll(ds) }()
|
||||
installDir, err := os.MkdirTemp("", "netenv_installdir")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create tmp install dir: %w", err)
|
||||
}
|
||||
defer func() { _ = os.RemoveAll(installDir) }()
|
||||
err = updates.GenerateMockFolder(installDir, "Test Intel", "1.0.0")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to generate mock installation: %w", err)
|
||||
}
|
||||
|
||||
stub := &testInstance{}
|
||||
stub.db, err = dbmodule.New(stub)
|
||||
@@ -68,7 +77,10 @@ func runTest(m *testing.M) error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create api: %w", err)
|
||||
}
|
||||
stub.updates, err = updates.New(stub)
|
||||
stub.updates, err = updates.New(stub, "Test Intel", updates.UpdateIndex{
|
||||
Directory: installDir,
|
||||
IndexFile: "index.json",
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create updates: %w", err)
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ type testInstance struct {
|
||||
geoip *geoip.GeoIP
|
||||
}
|
||||
|
||||
func (stub *testInstance) Updates() *updates.Updates {
|
||||
func (stub *testInstance) IntelUpdates() *updates.Updates {
|
||||
return stub.updates
|
||||
}
|
||||
|
||||
@@ -61,6 +61,16 @@ func runTest(m *testing.M) error {
|
||||
}
|
||||
defer func() { _ = os.RemoveAll(ds) }()
|
||||
|
||||
installDir, err := os.MkdirTemp("", "endpoints_installdir")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create tmp install dir: %w", err)
|
||||
}
|
||||
defer func() { _ = os.RemoveAll(installDir) }()
|
||||
err = updates.GenerateMockFolder(installDir, "Test Intel", "1.0.0")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to generate mock installation: %w", err)
|
||||
}
|
||||
|
||||
stub := &testInstance{}
|
||||
stub.db, err = dbmodule.New(stub)
|
||||
if err != nil {
|
||||
@@ -74,7 +84,10 @@ func runTest(m *testing.M) error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create api: %w", err)
|
||||
}
|
||||
stub.updates, err = updates.New(stub)
|
||||
stub.updates, err = updates.New(stub, "Test Intel", updates.UpdateIndex{
|
||||
Directory: installDir,
|
||||
IndexFile: "index.json",
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create updates: %w", err)
|
||||
}
|
||||
|
||||
@@ -26,9 +26,7 @@ type testInstance struct {
|
||||
netenv *netenv.NetEnv
|
||||
}
|
||||
|
||||
// var _ instance = &testInstance{}
|
||||
|
||||
func (stub *testInstance) Updates() *updates.Updates {
|
||||
func (stub *testInstance) IntelUpdates() *updates.Updates {
|
||||
return stub.updates
|
||||
}
|
||||
|
||||
@@ -70,6 +68,16 @@ func runTest(m *testing.M) error {
|
||||
}
|
||||
defer func() { _ = os.RemoveAll(ds) }()
|
||||
|
||||
installDir, err := os.MkdirTemp("", "resolver_installdir")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create tmp install dir: %w", err)
|
||||
}
|
||||
defer func() { _ = os.RemoveAll(installDir) }()
|
||||
err = updates.GenerateMockFolder(installDir, "Test Intel", "1.0.0")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to generate mock installation: %w", err)
|
||||
}
|
||||
|
||||
stub := &testInstance{}
|
||||
stub.db, err = dbmodule.New(stub)
|
||||
if err != nil {
|
||||
@@ -91,7 +99,10 @@ func runTest(m *testing.M) error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create netenv: %w", err)
|
||||
}
|
||||
stub.updates, err = updates.New(stub)
|
||||
stub.updates, err = updates.New(stub, "Test Intel", updates.UpdateIndex{
|
||||
Directory: installDir,
|
||||
IndexFile: "index.json",
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create updates: %w", err)
|
||||
}
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
[Unit]
|
||||
Description=Portmaster by Safing
|
||||
Documentation=https://safing.io
|
||||
Documentation=https://docs.safing.io
|
||||
Before=nss-lookup.target network.target shutdown.target
|
||||
After=systemd-networkd.service
|
||||
Conflicts=shutdown.target
|
||||
Conflicts=firewalld.service
|
||||
Wants=nss-lookup.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
Restart=on-failure
|
||||
RestartSec=10
|
||||
LockPersonality=yes
|
||||
MemoryDenyWriteExecute=yes
|
||||
NoNewPrivileges=yes
|
||||
PrivateTmp=yes
|
||||
PIDFile=/opt/safing/portmaster/core-lock.pid
|
||||
Environment=LOGLEVEL=info
|
||||
Environment=PORTMASTER_ARGS=
|
||||
EnvironmentFile=-/etc/default/portmaster
|
||||
ProtectSystem=true
|
||||
#ReadWritePaths=/var/lib/portmaster
|
||||
#ReadWritePaths=/run/xtables.lock
|
||||
RestrictAddressFamilies=AF_UNIX AF_NETLINK AF_INET AF_INET6
|
||||
RestrictNamespaces=yes
|
||||
# In future version portmaster will require access to user home
|
||||
# directories to verify application permissions.
|
||||
ProtectHome=read-only
|
||||
ProtectKernelTunables=yes
|
||||
ProtectKernelLogs=yes
|
||||
ProtectControlGroups=yes
|
||||
PrivateDevices=yes
|
||||
AmbientCapabilities=cap_chown cap_kill cap_net_admin cap_net_bind_service cap_net_broadcast cap_net_raw cap_sys_module cap_sys_ptrace cap_dac_override cap_fowner cap_fsetid cap_sys_resource cap_bpf cap_perfmon
|
||||
CapabilityBoundingSet=cap_chown cap_kill cap_net_admin cap_net_bind_service cap_net_broadcast cap_net_raw cap_sys_module cap_sys_ptrace cap_dac_override cap_fowner cap_fsetid cap_sys_resource cap_bpf cap_perfmon
|
||||
# SystemCallArchitectures=native
|
||||
# SystemCallFilter=@system-service @module
|
||||
# SystemCallErrorNumber=EPERM
|
||||
ExecStart=/opt/safing/portmaster/portmaster-start --data /opt/safing/portmaster core -- $PORTMASTER_ARGS
|
||||
ExecStopPost=-/opt/safing/portmaster/portmaster-start recover-iptables
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -3,6 +3,7 @@ package updates
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
@@ -179,3 +180,50 @@ func getIdentifierAndVersion(versionedPath string) (identifier, version string,
|
||||
// `dirPath + filename` is guaranteed by path.Split()
|
||||
return dirPath + filename, version, true
|
||||
}
|
||||
|
||||
// GenerateMockFolder generates mock bundle folder for testing.
|
||||
func GenerateMockFolder(dir, name, version string) error {
|
||||
// Make sure dir exists
|
||||
_ = os.MkdirAll(dir, defaultDirMode)
|
||||
|
||||
// Create empty files
|
||||
file, err := os.Create(filepath.Join(dir, "portmaster"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_ = file.Close()
|
||||
file, err = os.Create(filepath.Join(dir, "portmaster-core"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_ = file.Close()
|
||||
file, err = os.Create(filepath.Join(dir, "portmaster.zip"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_ = file.Close()
|
||||
file, err = os.Create(filepath.Join(dir, "assets.zip"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_ = file.Close()
|
||||
|
||||
bundle, err := GenerateBundleFromDir(dir, BundleFileSettings{
|
||||
Name: name,
|
||||
Version: version,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
bundleStr, err := json.MarshalIndent(bundle, "", " ")
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "failed to marshal bundle: %s\n", err)
|
||||
}
|
||||
|
||||
err = os.WriteFile(filepath.Join(dir, "index.json"), bundleStr, defaultFileMode)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -40,8 +40,10 @@ func CreateDownloader(index UpdateIndex) Downloader {
|
||||
|
||||
func (d *Downloader) downloadIndexFile(ctx context.Context) error {
|
||||
// Make sure dir exists
|
||||
_ = os.MkdirAll(d.dir, defaultDirMode)
|
||||
var err error
|
||||
err := os.MkdirAll(d.dir, defaultDirMode)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create directory for updates: %s", d.dir)
|
||||
}
|
||||
var content string
|
||||
for _, url := range d.indexURLs {
|
||||
content, err = d.downloadIndexFileFromURL(ctx, url)
|
||||
@@ -50,15 +52,15 @@ func (d *Downloader) downloadIndexFile(ctx context.Context) error {
|
||||
continue
|
||||
}
|
||||
// Downloading was successful.
|
||||
|
||||
bundle, err := ParseBundle(content)
|
||||
var bundle *Bundle
|
||||
bundle, err = ParseBundle(content)
|
||||
if err != nil {
|
||||
log.Warningf("updates: %s", err)
|
||||
continue
|
||||
}
|
||||
// Parsing was successful
|
||||
|
||||
version, err := semver.NewVersion(d.bundle.Version)
|
||||
var version *semver.Version
|
||||
version, err = semver.NewVersion(d.bundle.Version)
|
||||
if err != nil {
|
||||
log.Warningf("updates: failed to parse bundle version: %s", err)
|
||||
continue
|
||||
@@ -79,7 +81,7 @@ func (d *Downloader) downloadIndexFile(ctx context.Context) error {
|
||||
indexFilepath := filepath.Join(d.dir, d.indexFile)
|
||||
err = os.WriteFile(indexFilepath, []byte(content), defaultFileMode)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to write index file: %s", err)
|
||||
return fmt.Errorf("failed to write index file: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -6,8 +6,6 @@ import (
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
"github.com/safing/portmaster/base/api"
|
||||
"github.com/safing/portmaster/base/config"
|
||||
"github.com/safing/portmaster/base/log"
|
||||
"github.com/safing/portmaster/base/notifications"
|
||||
"github.com/safing/portmaster/service/mgr"
|
||||
@@ -215,8 +213,6 @@ func (u *Updates) Stop() error {
|
||||
}
|
||||
|
||||
type instance interface {
|
||||
API() *api.API
|
||||
Config() *config.Config
|
||||
Restart()
|
||||
Shutdown()
|
||||
Notifications() *notifications.Notifications
|
||||
|
||||
89
service/updates/updates_test.go
Normal file
89
service/updates/updates_test.go
Normal file
@@ -0,0 +1,89 @@
|
||||
package updates
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/safing/portmaster/base/notifications"
|
||||
)
|
||||
|
||||
type testInstance struct{}
|
||||
|
||||
func (i *testInstance) Restart() {}
|
||||
func (i *testInstance) Shutdown() {}
|
||||
|
||||
func (i *testInstance) Notifications() *notifications.Notifications {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *testInstance) Ready() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (i *testInstance) SetCmdLineOperation(f func() error) {}
|
||||
|
||||
func TestPreformUpdate(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// Initialize mock instance
|
||||
stub := &testInstance{}
|
||||
|
||||
// Make tmp dirs
|
||||
installedDir, err := os.MkdirTemp("", "updates_current")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer func() { _ = os.RemoveAll(installedDir) }()
|
||||
updateDir, err := os.MkdirTemp("", "updates_new")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer func() { _ = os.RemoveAll(updateDir) }()
|
||||
purgeDir, err := os.MkdirTemp("", "updates_purge")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer func() { _ = os.RemoveAll(purgeDir) }()
|
||||
|
||||
// Generate mock files
|
||||
if err := GenerateMockFolder(installedDir, "Test", "1.0.0"); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := GenerateMockFolder(updateDir, "Test", "1.0.1"); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Create updater
|
||||
updates, err := New(stub, "Test", UpdateIndex{
|
||||
Directory: installedDir,
|
||||
DownloadDirectory: updateDir,
|
||||
PurgeDirectory: purgeDir,
|
||||
IndexFile: "index.json",
|
||||
AutoApply: false,
|
||||
NeedsRestart: false,
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// Read and parse the index file
|
||||
if err := updates.downloader.Verify(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// Try to apply the updates
|
||||
err = updates.applyUpdates(nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// CHeck if the current version is now the new.
|
||||
bundle, err := LoadBundle(filepath.Join(installedDir, "index.json"))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if bundle.Version != "1.0.1" {
|
||||
panic(fmt.Errorf("expected version 1.0.1 found %s", bundle.Version))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user