mirror of https://github.com/qwc/backive.git
A bunch of tests and mocking
This commit is contained in:
parent
8ca9615541
commit
9c5feeb672
14
backup.go
14
backup.go
|
@ -13,8 +13,8 @@ import (
|
|||
)
|
||||
|
||||
// Mockings
|
||||
var mock_exec_Command = exec.Command
|
||||
var mock_cmd_Run = func(c *exec.Cmd) error {
|
||||
var mockExecCommand = exec.Command
|
||||
var mockCmdRun = func(c *exec.Cmd) error {
|
||||
return c.Run()
|
||||
}
|
||||
|
||||
|
@ -81,8 +81,8 @@ func (b *Backup) PrepareRun() error {
|
|||
}
|
||||
writer := io.MultiWriter(logfile)
|
||||
b.logger = log.New(writer, b.Name, log.LstdFlags)
|
||||
cmd := mock_exec_Command("chown", "-R", b.ExeUser, backupPath)
|
||||
err = mock_cmd_Run(cmd)
|
||||
cmd := mockExecCommand("chown", "-R", b.ExeUser, backupPath)
|
||||
err = mockCmdRun(cmd)
|
||||
if err != nil {
|
||||
b.logger.Printf("chown for backup directory failed: %s", err)
|
||||
return err
|
||||
|
@ -107,10 +107,10 @@ func (b *Backup) Run() error {
|
|||
log.Printf("ERROR: Script path is relative, aborting.")
|
||||
return fmt.Errorf("script path is relative, aborting")
|
||||
}
|
||||
cmd := mock_exec_Command("/usr/bin/sh", b.ScriptPath)
|
||||
cmd := mockExecCommand("/usr/bin/sh", b.ScriptPath)
|
||||
if b.ExeUser != "" {
|
||||
// setup script environment including user to use
|
||||
cmd = mock_exec_Command("sudo", "-E", "-u", b.ExeUser, "/usr/bin/sh", b.ScriptPath)
|
||||
cmd = mockExecCommand("sudo", "-E", "-u", b.ExeUser, "/usr/bin/sh", b.ScriptPath)
|
||||
}
|
||||
b.logger.Printf("Running backup script of '%s'", b.Name)
|
||||
b.logger.Printf("Script is: %s", b.ScriptPath)
|
||||
|
@ -129,7 +129,7 @@ func (b *Backup) Run() error {
|
|||
|
||||
log.Printf("About to run: %s", cmd.String())
|
||||
// run script
|
||||
err := mock_cmd_Run(cmd)
|
||||
err := mockCmdRun(cmd)
|
||||
if err != nil {
|
||||
log.Printf("Backup '%s' run failed", b.Name)
|
||||
return err
|
||||
|
|
|
@ -14,12 +14,6 @@ func getCurrentFilePath() string {
|
|||
return file
|
||||
}
|
||||
|
||||
type MockCmd struct{}
|
||||
|
||||
func (c *MockCmd) Run() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestFindBackupsForDevice(t *testing.T) {
|
||||
var testBackups = Backups{}
|
||||
|
||||
|
@ -119,7 +113,7 @@ func setupNewTestEnv(subdir string) {
|
|||
func TestPrepareRun(t *testing.T) {
|
||||
setupNewTestEnv("preparerun")
|
||||
|
||||
mock_cmd_Run = func(c *exec.Cmd) error {
|
||||
mockCmdRun = func(c *exec.Cmd) error {
|
||||
return nil
|
||||
}
|
||||
var testBkp = Backup{
|
||||
|
@ -142,7 +136,7 @@ func TestRun(t *testing.T) {
|
|||
config.Devices["mytarget"].Name = "mytarget"
|
||||
config.Devices["mytarget"].UUID = "123-456-789-abc-def"
|
||||
|
||||
mock_cmd_Run = func(c *exec.Cmd) error {
|
||||
mockCmdRun = func(c *exec.Cmd) error {
|
||||
return nil
|
||||
}
|
||||
var testBkp = Backup{
|
||||
|
@ -167,7 +161,7 @@ func TestRun(t *testing.T) {
|
|||
t.Logf("Error which should not occur: %s", err)
|
||||
t.Fail()
|
||||
}
|
||||
mock_cmd_Run = func(c *exec.Cmd) error {
|
||||
mockCmdRun = func(c *exec.Cmd) error {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,9 @@ import (
|
|||
"path"
|
||||
)
|
||||
|
||||
var mockOsWriteFile = os.WriteFile
|
||||
var mockOsReadFile = os.ReadFile
|
||||
|
||||
// Database is a simple string to string mapping, where arbitrary strings can be stored and safed to disk or loaded
|
||||
type Database struct {
|
||||
data map[string]string
|
||||
|
@ -23,7 +26,7 @@ func (d *Database) Save() {
|
|||
log.Printf("Writing database output to file: %s", jsonstr)
|
||||
saveDir, _ := path.Split(dbPath)
|
||||
CreateDirectoryIfNotExists(saveDir)
|
||||
err := os.WriteFile(dbPath, []byte(jsonstr), 0644)
|
||||
err := mockOsWriteFile(dbPath, []byte(jsonstr), 0644)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
@ -32,7 +35,7 @@ func (d *Database) Save() {
|
|||
// Load loads the database
|
||||
func (d *Database) Load() {
|
||||
if _, err := os.Stat(dbPath); err == nil {
|
||||
data, rferr := os.ReadFile(dbPath)
|
||||
data, rferr := mockOsReadFile(dbPath)
|
||||
if rferr != nil {
|
||||
panic(rferr)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
package backive
|
||||
|
||||
import (
|
||||
"io/fs"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestDatabase(t *testing.T) {
|
||||
mockOsStat = func(p string) (fs.FileInfo, error) {
|
||||
return nil, nil
|
||||
}
|
||||
db := new(Database)
|
||||
mockOsReadFile = func(p string) ([]byte, error) {
|
||||
return []byte("{}"), nil
|
||||
}
|
||||
db.Load()
|
||||
|
||||
mockOsWriteFile = func(p string, data []byte, rights fs.FileMode) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
db.Save()
|
||||
}
|
|
@ -35,7 +35,7 @@ func (d *Device) Mount() error {
|
|||
cmd.Stdout = log.Writer()
|
||||
cmd.Stderr = log.Writer()
|
||||
log.Printf("Command to execute: %s", cmd.String())
|
||||
err := mock_cmd_Run(cmd)
|
||||
err := mockCmdRun(cmd)
|
||||
if err != nil {
|
||||
log.Printf("Mounting failed with error %v", err)
|
||||
return err
|
||||
|
@ -49,7 +49,7 @@ func (d *Device) Unmount() error {
|
|||
if d.isMounted {
|
||||
log.Printf("Unmounting %s", d.Name)
|
||||
sync := exec.Command("sync")
|
||||
syncErr := mock_cmd_Run(sync)
|
||||
syncErr := mockCmdRun(sync)
|
||||
if syncErr != nil {
|
||||
log.Println(syncErr)
|
||||
return syncErr
|
||||
|
@ -59,7 +59,7 @@ func (d *Device) Unmount() error {
|
|||
path.Join(config.Settings.SystemMountPoint, d.Name),
|
||||
)
|
||||
log.Printf("About to run: %s", cmd.String())
|
||||
err := mock_cmd_Run(cmd)
|
||||
err := mockCmdRun(cmd)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return err
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
package backive
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestDevice(t *testing.T) {
|
||||
testDevice := new(Device)
|
||||
testDevice.Name = "Testdevice"
|
||||
testDevice.UUID = "123-456-789-abc-def"
|
||||
mockCmdRun = func(c *exec.Cmd) error {
|
||||
return nil
|
||||
}
|
||||
err := testDevice.Mount()
|
||||
if err != nil {
|
||||
t.Log("Should not fail, is mocked.")
|
||||
t.Fail()
|
||||
}
|
||||
if !testDevice.IsMounted() {
|
||||
t.Log("Should return true.")
|
||||
t.Fail()
|
||||
}
|
||||
err = testDevice.Unmount()
|
||||
if err != nil {
|
||||
t.Log("Should not fail, is mocked.")
|
||||
t.Fail()
|
||||
}
|
||||
if testDevice.IsMounted() {
|
||||
t.Log("Should return false.")
|
||||
t.Fail()
|
||||
}
|
||||
}
|
29
events.go
29
events.go
|
@ -14,10 +14,12 @@ type EventHandler struct {
|
|||
ls net.Listener
|
||||
//done <-chan struct{}
|
||||
callbacks []func(map[string]string)
|
||||
stop chan bool
|
||||
}
|
||||
|
||||
// Init initializes the unix socket.
|
||||
func (eh *EventHandler) Init(socketPath string) {
|
||||
eh.stop = make(chan bool)
|
||||
log.Println("Initializing EventHandler...")
|
||||
var err error
|
||||
dir, _ := path.Split(socketPath)
|
||||
|
@ -29,13 +31,28 @@ func (eh *EventHandler) Init(socketPath string) {
|
|||
eh.callbacks = make([]func(map[string]string), 3)
|
||||
}
|
||||
|
||||
func (eh *EventHandler) Stop() {
|
||||
log.Println("Closing EventHandler")
|
||||
eh.stop <- true
|
||||
err := eh.ls.Close()
|
||||
if err != nil {
|
||||
log.Println("Error closing the listener")
|
||||
}
|
||||
log.Println("Closed EventHandler")
|
||||
}
|
||||
|
||||
// Listen starts the event loop.
|
||||
func (eh *EventHandler) Listen() {
|
||||
log.Println("Running eventloop")
|
||||
func() {
|
||||
for {
|
||||
select {
|
||||
case <-eh.stop:
|
||||
return
|
||||
default:
|
||||
eh.process()
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
|
@ -49,8 +66,14 @@ func (eh *EventHandler) process() {
|
|||
client, err := eh.ls.Accept()
|
||||
log.Println("Accepted client")
|
||||
if err != nil {
|
||||
select {
|
||||
case <-eh.stop:
|
||||
return
|
||||
default:
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
defer client.Close()
|
||||
data := make([]byte, 2048)
|
||||
for {
|
||||
buf := make([]byte, 512)
|
||||
|
@ -67,15 +90,15 @@ func (eh *EventHandler) process() {
|
|||
//log.Println(sdata)
|
||||
var message map[string]interface{}
|
||||
errjson := json.Unmarshal([]byte(sdata), &message)
|
||||
if errjson != nil {
|
||||
log.Fatal(errjson)
|
||||
}
|
||||
var env = map[string]string{}
|
||||
if message["request"] == "udev" {
|
||||
for k, v := range message["data"].(map[string]interface{}) {
|
||||
env[k] = v.(string)
|
||||
}
|
||||
}
|
||||
if errjson != nil {
|
||||
log.Fatal(errjson)
|
||||
}
|
||||
for _, v := range eh.callbacks {
|
||||
if v != nil {
|
||||
v(env)
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
package backive
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestEventhandler(t *testing.T) {
|
||||
t.Skip("Do not get it to work...")
|
||||
eh := new(EventHandler)
|
||||
eh.Init("./backive.socket")
|
||||
defer func() {
|
||||
eh.Stop()
|
||||
err := os.Remove("./backive.socket")
|
||||
if err != nil {
|
||||
t.Log(err)
|
||||
}
|
||||
}()
|
||||
t.Log("Initialized test")
|
||||
go eh.Listen()
|
||||
t.Log("eh is listening")
|
||||
var hasBeenCalled = make(chan bool)
|
||||
eh.RegisterCallback(
|
||||
func(m map[string]string) {
|
||||
hasBeenCalled <- true
|
||||
},
|
||||
)
|
||||
t.Log("registered callback")
|
||||
beenCalled := false
|
||||
var counter = 0
|
||||
env := map[string]string{}
|
||||
env["test"] = "test"
|
||||
message := map[string]interface{}{}
|
||||
message["request"] = "udev"
|
||||
message["data"] = env
|
||||
for {
|
||||
select {
|
||||
case data := <-hasBeenCalled:
|
||||
t.Log("receiving message")
|
||||
beenCalled = data
|
||||
if !beenCalled {
|
||||
t.Fail()
|
||||
}
|
||||
t.Log("received message")
|
||||
eh.Stop()
|
||||
return
|
||||
default:
|
||||
t.Logf("Waiting for callback %d", counter)
|
||||
time.Sleep(time.Millisecond)
|
||||
if counter == 2 {
|
||||
sendDataToSocket("./backive.socket", message)
|
||||
t.Log("sent message")
|
||||
}
|
||||
if counter < 10 {
|
||||
counter++
|
||||
} else {
|
||||
t.Log("Stopping with Fail")
|
||||
eh.Stop()
|
||||
t.Fail()
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func sendDataToSocket(socket string, message map[string]interface{}) {
|
||||
c, err := net.Dial("unix", socket)
|
||||
if err != nil {
|
||||
log.Fatalln("Could not instantiate unix socket. Aborting")
|
||||
}
|
||||
jsonstr, err := json.Marshal(message)
|
||||
if err != nil {
|
||||
log.Fatalln("Could not convert to json. Aborting")
|
||||
}
|
||||
c.Write(jsonstr)
|
||||
defer c.Close()
|
||||
}
|
7
utils.go
7
utils.go
|
@ -5,12 +5,15 @@ import (
|
|||
"os"
|
||||
)
|
||||
|
||||
var mockOsStat = os.Stat
|
||||
var mockOsMkdirAll = os.MkdirAll
|
||||
|
||||
// CreateDirectoryIfNotExists Checks for a directory string and creates the directory if it does not exist, must be a absolute path.
|
||||
func CreateDirectoryIfNotExists(dir string) {
|
||||
if _, err := os.Stat(dir); err == nil {
|
||||
if _, err := mockOsStat(dir); err == nil {
|
||||
//ignore
|
||||
} else if os.IsNotExist(err) {
|
||||
os.MkdirAll(dir, 0755)
|
||||
mockOsMkdirAll(dir, 0755)
|
||||
} else {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue