mirror of
https://github.com/prashantgupta24/automatic-mouse-mover.git
synced 2024-12-22 16:34:11 +00:00
Merge pull request #13 from prashantgupta24/test_update
adding tests + godoc
This commit is contained in:
commit
ced87f1d96
6
.gitignore
vendored
6
.gitignore
vendored
@ -1,3 +1,7 @@
|
|||||||
vendor/
|
vendor/
|
||||||
bin/
|
bin/
|
||||||
log/
|
log/
|
||||||
|
|
||||||
|
# coverage
|
||||||
|
*.html
|
||||||
|
*.out
|
18
Makefile
18
Makefile
@ -1,3 +1,8 @@
|
|||||||
|
COVER_PROFILE=cover.out
|
||||||
|
COVER_HTML=cover.html
|
||||||
|
|
||||||
|
.PHONY: $(COVER_PROFILE) $(COVER_HTML)
|
||||||
|
|
||||||
all: open
|
all: open
|
||||||
|
|
||||||
build: clean
|
build: clean
|
||||||
@ -16,14 +21,21 @@ clean:
|
|||||||
start:
|
start:
|
||||||
go run cmd/main.go
|
go run cmd/main.go
|
||||||
|
|
||||||
test:
|
test:coverage
|
||||||
go test -v -race -failfast ./...
|
|
||||||
|
coverage: $(COVER_HTML)
|
||||||
|
|
||||||
|
$(COVER_HTML): $(COVER_PROFILE)
|
||||||
|
go tool cover -html=$(COVER_PROFILE) -o $(COVER_HTML)
|
||||||
|
|
||||||
|
$(COVER_PROFILE):
|
||||||
|
go test -v -failfast -race -coverprofile=$(COVER_PROFILE) ./...
|
||||||
|
|
||||||
vet:
|
vet:
|
||||||
go vet $(shell glide nv)
|
go vet $(shell glide nv)
|
||||||
|
|
||||||
lint:
|
lint:
|
||||||
go list ./... | grep -v vendor | xargs -L1 golint -set_exit_status
|
go list ./... | grep -v vendor | grep -v /assets/ |xargs -L1 golint -set_exit_status
|
||||||
|
|
||||||
.PHONY: build
|
.PHONY: build
|
||||||
.PHONY: clean
|
.PHONY: clean
|
24
pkg/mousemover/doc.go
Normal file
24
pkg/mousemover/doc.go
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
Ever felt the need to keep your machine awake without having to resort to the age-old
|
||||||
|
methods of installing an app that you don't trust or playing a video? Well, not anymore!
|
||||||
|
|
||||||
|
Introducing the simplest app on the market that has the sole purpose of moving your mouse
|
||||||
|
pointer at regular intervals so that your machine never sleeps! And best of all, it works
|
||||||
|
ONLY when you are not working, so be rest assured that the mouse won't start moving on its
|
||||||
|
own without the machine actually being idle.
|
||||||
|
|
||||||
|
|
||||||
|
Installation
|
||||||
|
|
||||||
|
The libary can be installed using:
|
||||||
|
go get -u github.com/automatic-mouse-mover/pkg/mousemover
|
||||||
|
|
||||||
|
Usage
|
||||||
|
|
||||||
|
Clone this repo and run Make, it should create the amm.app and open the folder where
|
||||||
|
it was built for you. You just have to drag and drop it to the Applications folder on your mac.
|
||||||
|
|
||||||
|
Refer to the README for more details.
|
||||||
|
|
||||||
|
*/
|
||||||
|
package mousemover
|
@ -2,13 +2,8 @@ package mousemover
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
"sync"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
|
|
||||||
"github.com/go-vgo/robotgo"
|
"github.com/go-vgo/robotgo"
|
||||||
"github.com/prashantgupta24/activity-tracker/pkg/activity"
|
"github.com/prashantgupta24/activity-tracker/pkg/activity"
|
||||||
"github.com/prashantgupta24/activity-tracker/pkg/tracker"
|
"github.com/prashantgupta24/activity-tracker/pkg/tracker"
|
||||||
@ -16,25 +11,18 @@ import (
|
|||||||
|
|
||||||
var instance *MouseMover
|
var instance *MouseMover
|
||||||
|
|
||||||
//MouseMover is the main struct for the app
|
|
||||||
type MouseMover struct {
|
|
||||||
quit chan struct{}
|
|
||||||
mutex sync.RWMutex
|
|
||||||
runningStatus bool
|
|
||||||
logFile *os.File
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
timeout = 100 //ms
|
timeout = 100 //ms
|
||||||
logDir = "log"
|
logDir = "log"
|
||||||
logFileName = "logFile-amm-1"
|
logFileName = "logFile-amm-2"
|
||||||
)
|
)
|
||||||
|
|
||||||
//Start the main app
|
//Start the main app
|
||||||
func (m *MouseMover) Start() {
|
func (m *MouseMover) Start() {
|
||||||
if m.isRunning() {
|
if m.state.isRunning() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
m.state = &state{}
|
||||||
m.quit = make(chan struct{})
|
m.quit = make(chan struct{})
|
||||||
|
|
||||||
heartbeatInterval := 60 //value always in seconds
|
heartbeatInterval := 60 //value always in seconds
|
||||||
@ -47,37 +35,43 @@ func (m *MouseMover) Start() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
heartbeatCh := activityTracker.Start()
|
heartbeatCh := activityTracker.Start()
|
||||||
|
m.run(heartbeatCh, activityTracker)
|
||||||
|
}
|
||||||
|
|
||||||
go func(m *MouseMover) {
|
func (m *MouseMover) run(heartbeatCh chan *tracker.Heartbeat, activityTracker *tracker.Instance) {
|
||||||
logger := getLogger(m, false) //set writeToFile=true only for debugging
|
go func() {
|
||||||
m.updateRunningStatus(true)
|
state := m.state
|
||||||
|
if state != nil && state.isRunning() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
state.updateRunningStatus(true)
|
||||||
|
|
||||||
|
logger := getLogger(m, false, logFileName) //set writeToFile=true only for debugging
|
||||||
movePixel := 10
|
movePixel := 10
|
||||||
var lastMoved time.Time
|
|
||||||
isSystemSleeping := false
|
|
||||||
didNotMoveTimes := 0
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case heartbeat := <-heartbeatCh:
|
case heartbeat := <-heartbeatCh:
|
||||||
if !heartbeat.WasAnyActivity {
|
if !heartbeat.WasAnyActivity {
|
||||||
if isSystemSleeping {
|
if state.isSystemSleeping() {
|
||||||
logger.Infof("system sleeping")
|
logger.Infof("system sleeping")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
mouseMoveSuccessCh := make(chan bool)
|
mouseMoveSuccessCh := make(chan bool)
|
||||||
go moveAndCheck(movePixel, mouseMoveSuccessCh)
|
go moveAndCheck(state, movePixel, mouseMoveSuccessCh)
|
||||||
select {
|
select {
|
||||||
case wasMouseMoveSuccess := <-mouseMoveSuccessCh:
|
case wasMouseMoveSuccess := <-mouseMoveSuccessCh:
|
||||||
if wasMouseMoveSuccess {
|
if wasMouseMoveSuccess {
|
||||||
lastMoved = time.Now()
|
state.updateLastMouseMovedTime(time.Now())
|
||||||
logger.Infof("moved mouse at : %v\n\n", lastMoved)
|
logger.Infof("moved mouse at : %v\n\n", state.getLastMouseMovedTime())
|
||||||
movePixel *= -1
|
movePixel *= -1
|
||||||
didNotMoveTimes = 0
|
state.updateDidNotMoveCount(0)
|
||||||
} else {
|
} else {
|
||||||
didNotMoveTimes++
|
didNotMoveCount := state.getDidNotMoveCount()
|
||||||
|
state.updateDidNotMoveCount(didNotMoveCount + 1)
|
||||||
msg := fmt.Sprintf("Mouse pointer cannot be moved at %v. Last moved at %v. Happened %v times. See README for details.",
|
msg := fmt.Sprintf("Mouse pointer cannot be moved at %v. Last moved at %v. Happened %v times. See README for details.",
|
||||||
time.Now(), lastMoved, didNotMoveTimes)
|
time.Now(), state.getLastMouseMovedTime(), state.getDidNotMoveCount())
|
||||||
logger.Errorf(msg)
|
logger.Errorf(msg)
|
||||||
if didNotMoveTimes >= 3 {
|
if state.getDidNotMoveCount() >= 3 {
|
||||||
go func() {
|
go func() {
|
||||||
robotgo.ShowAlert("Error with Automatic Mouse Mover", msg)
|
robotgo.ShowAlert("Error with Automatic Mouse Mover", msg)
|
||||||
}()
|
}()
|
||||||
@ -88,59 +82,32 @@ func (m *MouseMover) Start() {
|
|||||||
logger.Errorf("timeout happened after %vms while trying to move mouse", timeout)
|
logger.Errorf("timeout happened after %vms while trying to move mouse", timeout)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
logger.Infof("activity detected in the last %v seconds.", int(heartbeatInterval))
|
logger.Infof("activity detected in the last %v seconds.", int(activityTracker.HeartbeatInterval))
|
||||||
logger.Infof("Activity type:\n")
|
logger.Infof("Activity type:\n")
|
||||||
for activityType, times := range heartbeat.ActivityMap {
|
for activityType, times := range heartbeat.ActivityMap {
|
||||||
logger.Infof("activityType : %v times: %v\n", activityType, len(times))
|
logger.Infof("activityType : %v times: %v\n", activityType, len(times))
|
||||||
if activityType == activity.MachineSleep {
|
if activityType == activity.MachineSleep {
|
||||||
isSystemSleeping = true
|
state.updateMachineSleepStatus(true)
|
||||||
} else if activityType == activity.MachineWake {
|
} else if activityType == activity.MachineWake {
|
||||||
isSystemSleeping = false
|
state.updateMachineSleepStatus(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
logger.Infof("\n\n\n")
|
logger.Infof("\n\n\n")
|
||||||
}
|
}
|
||||||
case <-m.quit:
|
case <-m.quit:
|
||||||
logger.Infof("stopping mouse mover")
|
logger.Infof("stopping mouse mover")
|
||||||
m.updateRunningStatus(false)
|
state.updateRunningStatus(false)
|
||||||
activityTracker.Quit()
|
activityTracker.Quit()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}(m)
|
}()
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MouseMover) isRunning() bool {
|
|
||||||
m.mutex.RLock()
|
|
||||||
defer m.mutex.RUnlock()
|
|
||||||
return m.runningStatus
|
|
||||||
}
|
|
||||||
func (m *MouseMover) updateRunningStatus(isRunning bool) {
|
|
||||||
m.mutex.Lock()
|
|
||||||
defer m.mutex.Unlock()
|
|
||||||
m.runningStatus = isRunning
|
|
||||||
}
|
|
||||||
|
|
||||||
func moveAndCheck(movePixel int, mouseMoveSuccessCh chan bool) {
|
|
||||||
currentX, currentY := robotgo.GetMousePos()
|
|
||||||
moveToX := currentX + movePixel
|
|
||||||
moveToY := currentY + movePixel
|
|
||||||
robotgo.MoveMouse(moveToX, moveToY)
|
|
||||||
|
|
||||||
//check if mouse moved. Sometimes mac users need to give
|
|
||||||
//extra permission for controlling the mouse
|
|
||||||
movedX, movedY := robotgo.GetMousePos()
|
|
||||||
if movedX == currentX && movedY == currentY {
|
|
||||||
mouseMoveSuccessCh <- false
|
|
||||||
} else {
|
|
||||||
mouseMoveSuccessCh <- true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Quit the app
|
//Quit the app
|
||||||
func (m *MouseMover) Quit() {
|
func (m *MouseMover) Quit() {
|
||||||
//making it idempotent
|
//making it idempotent
|
||||||
if m != nil && m.isRunning() {
|
if m != nil && m.state.isRunning() {
|
||||||
m.quit <- struct{}{}
|
m.quit <- struct{}{}
|
||||||
}
|
}
|
||||||
if m.logFile != nil {
|
if m.logFile != nil {
|
||||||
@ -151,35 +118,9 @@ func (m *MouseMover) Quit() {
|
|||||||
//GetInstance gets the singleton instance for mouse mover app
|
//GetInstance gets the singleton instance for mouse mover app
|
||||||
func GetInstance() *MouseMover {
|
func GetInstance() *MouseMover {
|
||||||
if instance == nil {
|
if instance == nil {
|
||||||
instance = &MouseMover{}
|
instance = &MouseMover{
|
||||||
|
state: &state{},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return instance
|
return instance
|
||||||
}
|
}
|
||||||
|
|
||||||
func getLogger(m *MouseMover, doWriteToFile bool) *log.Logger {
|
|
||||||
logger := log.New()
|
|
||||||
logger.Formatter = &logrus.TextFormatter{
|
|
||||||
FullTimestamp: true,
|
|
||||||
}
|
|
||||||
|
|
||||||
if doWriteToFile {
|
|
||||||
_, err := os.Stat(logDir)
|
|
||||||
if err != nil {
|
|
||||||
if os.IsNotExist(err) {
|
|
||||||
err = os.Mkdir(logDir, os.ModePerm)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("error creating dir: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
logFile, err := os.OpenFile(logDir+"/"+logFileName, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("error opening file: %v", err)
|
|
||||||
}
|
|
||||||
logger.SetOutput(logFile)
|
|
||||||
m.logFile = logFile
|
|
||||||
}
|
|
||||||
|
|
||||||
return logger
|
|
||||||
}
|
|
||||||
|
107
pkg/mousemover/mouseMoverUtil.go
Normal file
107
pkg/mousemover/mouseMoverUtil.go
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
package mousemover
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/go-vgo/robotgo"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
func getLogger(m *MouseMover, doWriteToFile bool, filename string) *log.Logger {
|
||||||
|
logger := log.New()
|
||||||
|
logger.Formatter = &logrus.TextFormatter{
|
||||||
|
FullTimestamp: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
if doWriteToFile {
|
||||||
|
_, err := os.Stat(logDir)
|
||||||
|
if err != nil {
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
err = os.Mkdir(logDir, os.ModePerm)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("error creating dir: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
logFile, err := os.OpenFile(logDir+"/"+filename, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("error opening file: %v", err)
|
||||||
|
}
|
||||||
|
logger.SetOutput(logFile)
|
||||||
|
m.logFile = logFile
|
||||||
|
}
|
||||||
|
|
||||||
|
return logger
|
||||||
|
}
|
||||||
|
|
||||||
|
func moveAndCheck(state *state, movePixel int, mouseMoveSuccessCh chan bool) {
|
||||||
|
if state.override != nil { //we don't want to move mouse for tests
|
||||||
|
mouseMoveSuccessCh <- state.override.valueToReturn
|
||||||
|
return
|
||||||
|
}
|
||||||
|
currentX, currentY := robotgo.GetMousePos()
|
||||||
|
moveToX := currentX + movePixel
|
||||||
|
moveToY := currentY + movePixel
|
||||||
|
robotgo.MoveMouse(moveToX, moveToY)
|
||||||
|
|
||||||
|
//check if mouse moved. Sometimes mac users need to give
|
||||||
|
//extra permission for controlling the mouse
|
||||||
|
movedX, movedY := robotgo.GetMousePos()
|
||||||
|
if movedX == currentX && movedY == currentY {
|
||||||
|
mouseMoveSuccessCh <- false
|
||||||
|
} else {
|
||||||
|
mouseMoveSuccessCh <- true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//getters and setters for state variable
|
||||||
|
func (s *state) isRunning() bool {
|
||||||
|
s.mutex.RLock()
|
||||||
|
defer s.mutex.RUnlock()
|
||||||
|
return s.isAppRunning
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state) updateRunningStatus(isRunning bool) {
|
||||||
|
s.mutex.Lock()
|
||||||
|
defer s.mutex.Unlock()
|
||||||
|
s.isAppRunning = isRunning
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state) isSystemSleeping() bool {
|
||||||
|
s.mutex.RLock()
|
||||||
|
defer s.mutex.RUnlock()
|
||||||
|
return s.isSysSleeping
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state) updateMachineSleepStatus(isSleeping bool) {
|
||||||
|
s.mutex.Lock()
|
||||||
|
defer s.mutex.Unlock()
|
||||||
|
s.isSysSleeping = isSleeping
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state) getLastMouseMovedTime() time.Time {
|
||||||
|
s.mutex.RLock()
|
||||||
|
defer s.mutex.RUnlock()
|
||||||
|
return s.lastMouseMovedTime
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state) updateLastMouseMovedTime(time time.Time) {
|
||||||
|
s.mutex.Lock()
|
||||||
|
defer s.mutex.Unlock()
|
||||||
|
s.lastMouseMovedTime = time
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state) getDidNotMoveCount() int {
|
||||||
|
s.mutex.RLock()
|
||||||
|
defer s.mutex.RUnlock()
|
||||||
|
return s.didNotMoveCount
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state) updateDidNotMoveCount(count int) {
|
||||||
|
s.mutex.Lock()
|
||||||
|
defer s.mutex.Unlock()
|
||||||
|
s.didNotMoveCount = count
|
||||||
|
}
|
@ -1,44 +1,177 @@
|
|||||||
package mousemover
|
package mousemover
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/suite"
|
"github.com/stretchr/testify/suite"
|
||||||
|
|
||||||
|
"github.com/prashantgupta24/activity-tracker/pkg/activity"
|
||||||
|
"github.com/prashantgupta24/activity-tracker/pkg/tracker"
|
||||||
)
|
)
|
||||||
|
|
||||||
type TestMover struct {
|
type TestMover struct {
|
||||||
suite.Suite
|
suite.Suite
|
||||||
|
activityTracker *tracker.Instance
|
||||||
|
heartbeatCh chan *tracker.Heartbeat
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSuite(t *testing.T) {
|
func TestSuite(t *testing.T) {
|
||||||
suite.Run(t, new(TestMover))
|
suite.Run(t, new(TestMover))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Run once before all tests
|
||||||
|
func (suite *TestMover) SetupSuite() {
|
||||||
|
heartbeatInterval := 60
|
||||||
|
workerInterval := 10
|
||||||
|
|
||||||
|
suite.activityTracker = &tracker.Instance{
|
||||||
|
HeartbeatInterval: heartbeatInterval,
|
||||||
|
WorkerInterval: workerInterval,
|
||||||
|
}
|
||||||
|
|
||||||
|
suite.heartbeatCh = make(chan *tracker.Heartbeat)
|
||||||
|
}
|
||||||
|
|
||||||
//Run once before each test
|
//Run once before each test
|
||||||
func (suite *TestMover) SetupTest() {
|
func (suite *TestMover) SetupTest() {
|
||||||
instance = nil
|
instance = nil
|
||||||
}
|
}
|
||||||
|
func (suite *TestMover) TestAppStart() {
|
||||||
|
t := suite.T()
|
||||||
|
mouseMover := GetInstance()
|
||||||
|
mouseMover.run(suite.heartbeatCh, suite.activityTracker)
|
||||||
|
time.Sleep(time.Millisecond * 500) //wait for app to start
|
||||||
|
assert.True(t, mouseMover.state.isRunning(), "app should have started")
|
||||||
|
}
|
||||||
func (suite *TestMover) TestSingleton() {
|
func (suite *TestMover) TestSingleton() {
|
||||||
t := suite.T()
|
t := suite.T()
|
||||||
|
|
||||||
mouseMover1 := GetInstance()
|
mouseMover1 := GetInstance()
|
||||||
mouseMover1.Start()
|
mouseMover1.run(suite.heartbeatCh, suite.activityTracker)
|
||||||
|
|
||||||
time.Sleep(time.Millisecond * 500)
|
time.Sleep(time.Millisecond * 500)
|
||||||
|
|
||||||
mouseMover2 := GetInstance()
|
mouseMover2 := GetInstance()
|
||||||
assert.True(t, mouseMover2.isRunning(), "instance should not have started")
|
assert.True(t, mouseMover2.state.isRunning(), "instance should have started")
|
||||||
}
|
}
|
||||||
func (suite *TestMover) TestAppStartAndStop() {
|
|
||||||
|
func (suite *TestMover) TestLogFile() {
|
||||||
t := suite.T()
|
t := suite.T()
|
||||||
mouseMover := GetInstance()
|
mouseMover := GetInstance()
|
||||||
mouseMover.Start()
|
logFileName := "test1"
|
||||||
time.Sleep(time.Millisecond * 500) //wait for app to start
|
|
||||||
assert.True(t, mouseMover.isRunning(), "app should have started")
|
|
||||||
|
|
||||||
mouseMover.Quit()
|
getLogger(mouseMover, true, logFileName)
|
||||||
time.Sleep(time.Millisecond * 500) //wait for app to stop
|
|
||||||
assert.False(t, mouseMover.isRunning(), "app should have stopped")
|
filePath := logDir + "/" + logFileName
|
||||||
|
assert.FileExists(t, filePath, "log file should exist")
|
||||||
|
os.RemoveAll(filePath)
|
||||||
|
}
|
||||||
|
func (suite *TestMover) TestSystemSleepAndWake() {
|
||||||
|
t := suite.T()
|
||||||
|
mouseMover := GetInstance()
|
||||||
|
|
||||||
|
state := &state{
|
||||||
|
override: &override{
|
||||||
|
valueToReturn: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
mouseMover.state = state
|
||||||
|
heartbeatCh := make(chan *tracker.Heartbeat)
|
||||||
|
|
||||||
|
mouseMover.run(heartbeatCh, suite.activityTracker)
|
||||||
|
time.Sleep(time.Millisecond * 500) //wait for app to start
|
||||||
|
assert.True(t, mouseMover.state.isRunning(), "instance should have started")
|
||||||
|
assert.False(t, mouseMover.state.isSystemSleeping(), "machine should not be sleeping")
|
||||||
|
|
||||||
|
//fake a machine-sleep activity
|
||||||
|
machineSleepActivityMap := make(map[activity.Type][]time.Time)
|
||||||
|
var sleepTimeArray []time.Time
|
||||||
|
sleepTimeArray = append(sleepTimeArray, time.Now())
|
||||||
|
machineSleepActivityMap[activity.MachineSleep] = sleepTimeArray
|
||||||
|
heartbeatCh <- &tracker.Heartbeat{
|
||||||
|
WasAnyActivity: true,
|
||||||
|
ActivityMap: machineSleepActivityMap,
|
||||||
|
}
|
||||||
|
time.Sleep(time.Millisecond * 500) //wait for it to be registered
|
||||||
|
assert.True(t, mouseMover.state.isSystemSleeping(), "machine should be sleeping now")
|
||||||
|
|
||||||
|
//assert app is sleeping
|
||||||
|
heartbeatCh <- &tracker.Heartbeat{
|
||||||
|
WasAnyActivity: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
time.Sleep(time.Millisecond * 500) //wait for it to be registered
|
||||||
|
assert.True(t, time.Time.IsZero(state.getLastMouseMovedTime()), "should be default but is ", state.getLastMouseMovedTime())
|
||||||
|
assert.Equal(t, state.getDidNotMoveCount(), 0, "should be 0")
|
||||||
|
|
||||||
|
//fake a machine-wake activity
|
||||||
|
machineWakeActivityMap := make(map[activity.Type][]time.Time)
|
||||||
|
var wakeTimeArray []time.Time
|
||||||
|
wakeTimeArray = append(wakeTimeArray, time.Now())
|
||||||
|
machineWakeActivityMap[activity.MachineWake] = wakeTimeArray
|
||||||
|
heartbeatCh <- &tracker.Heartbeat{
|
||||||
|
WasAnyActivity: true,
|
||||||
|
ActivityMap: machineWakeActivityMap,
|
||||||
|
}
|
||||||
|
|
||||||
|
time.Sleep(time.Millisecond * 500) //wait for it to be registered
|
||||||
|
assert.False(t, mouseMover.state.isSystemSleeping(), "machine should be awake now")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (suite *TestMover) TestMouseMoveSuccess() {
|
||||||
|
t := suite.T()
|
||||||
|
mouseMover := GetInstance()
|
||||||
|
|
||||||
|
state := &state{
|
||||||
|
override: &override{
|
||||||
|
valueToReturn: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
mouseMover.state = state
|
||||||
|
heartbeatCh := make(chan *tracker.Heartbeat)
|
||||||
|
|
||||||
|
mouseMover.run(heartbeatCh, suite.activityTracker)
|
||||||
|
time.Sleep(time.Millisecond * 500) //wait for app to start
|
||||||
|
assert.True(t, state.isRunning(), "instance should have started")
|
||||||
|
assert.False(t, state.isSystemSleeping(), "machine should not be sleeping")
|
||||||
|
assert.True(t, time.Time.IsZero(state.getLastMouseMovedTime()), "should be default")
|
||||||
|
assert.Equal(t, state.getDidNotMoveCount(), 0, "should be 0")
|
||||||
|
|
||||||
|
heartbeatCh <- &tracker.Heartbeat{
|
||||||
|
WasAnyActivity: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
time.Sleep(time.Millisecond * 500) //wait for it to be registered
|
||||||
|
assert.False(t, time.Time.IsZero(state.getLastMouseMovedTime()), "should be default but is ", state.getLastMouseMovedTime())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (suite *TestMover) TestMouseMoveFailure() {
|
||||||
|
t := suite.T()
|
||||||
|
mouseMover := GetInstance()
|
||||||
|
|
||||||
|
state := &state{
|
||||||
|
override: &override{
|
||||||
|
valueToReturn: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
mouseMover.state = state
|
||||||
|
heartbeatCh := make(chan *tracker.Heartbeat)
|
||||||
|
|
||||||
|
mouseMover.run(heartbeatCh, suite.activityTracker)
|
||||||
|
time.Sleep(time.Millisecond * 500) //wait for app to start
|
||||||
|
assert.True(t, state.isRunning(), "instance should have started")
|
||||||
|
assert.False(t, state.isSystemSleeping(), "machine should not be sleeping")
|
||||||
|
assert.True(t, time.Time.IsZero(state.getLastMouseMovedTime()), "should be default")
|
||||||
|
assert.Equal(t, state.getDidNotMoveCount(), 0, "should be 0")
|
||||||
|
|
||||||
|
heartbeatCh <- &tracker.Heartbeat{
|
||||||
|
WasAnyActivity: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
time.Sleep(time.Millisecond * 500) //wait for it to be registered
|
||||||
|
assert.True(t, time.Time.IsZero(state.getLastMouseMovedTime()), "should be default but is ", state.getLastMouseMovedTime())
|
||||||
|
assert.NotEqual(t, state.getDidNotMoveCount(), 0, "should not be 0")
|
||||||
}
|
}
|
||||||
|
29
pkg/mousemover/types.go
Normal file
29
pkg/mousemover/types.go
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package mousemover
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
//MouseMover is the main struct for the app
|
||||||
|
type MouseMover struct {
|
||||||
|
quit chan struct{}
|
||||||
|
logFile *os.File
|
||||||
|
state *state
|
||||||
|
}
|
||||||
|
|
||||||
|
//state manages the internal working of the app
|
||||||
|
type state struct {
|
||||||
|
mutex sync.RWMutex
|
||||||
|
isAppRunning bool
|
||||||
|
isSysSleeping bool
|
||||||
|
lastMouseMovedTime time.Time
|
||||||
|
didNotMoveCount int
|
||||||
|
override *override
|
||||||
|
}
|
||||||
|
|
||||||
|
//only needed for tests
|
||||||
|
type override struct {
|
||||||
|
valueToReturn bool
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user