Merge pull request #1633 from calmh/errorstate
Move folder errors to state
This commit is contained in:
commit
ba4a6fc0c5
|
@ -354,7 +354,12 @@ func folderSummary(m *model.Model, folder string) map[string]interface{} {
|
||||||
|
|
||||||
res["inSyncFiles"], res["inSyncBytes"] = globalFiles-needFiles, globalBytes-needBytes
|
res["inSyncFiles"], res["inSyncBytes"] = globalFiles-needFiles, globalBytes-needBytes
|
||||||
|
|
||||||
res["state"], res["stateChanged"] = m.State(folder)
|
var err error
|
||||||
|
res["state"], res["stateChanged"], err = m.State(folder)
|
||||||
|
if err != nil {
|
||||||
|
res["error"] = err.Error()
|
||||||
|
}
|
||||||
|
|
||||||
res["version"] = m.CurrentLocalVersion(folder) + m.RemoteLocalVersion(folder)
|
res["version"] = m.CurrentLocalVersion(folder) + m.RemoteLocalVersion(folder)
|
||||||
|
|
||||||
ignorePatterns, _, _ := m.GetIgnores(folder)
|
ignorePatterns, _, _ := m.GetIgnores(folder)
|
||||||
|
|
|
@ -42,6 +42,7 @@ func TestFolderErrors(t *testing.T) {
|
||||||
|
|
||||||
m := model.NewModel(cfg, protocol.LocalDeviceID, "device", "syncthing", "dev", ldb)
|
m := model.NewModel(cfg, protocol.LocalDeviceID, "device", "syncthing", "dev", ldb)
|
||||||
m.AddFolder(fcfg)
|
m.AddFolder(fcfg)
|
||||||
|
m.StartFolderRW("folder")
|
||||||
|
|
||||||
if err := m.CheckFolderHealth("folder"); err != nil {
|
if err := m.CheckFolderHealth("folder"); err != nil {
|
||||||
t.Error("Unexpected error", cfg.Folders()["folder"].Invalid)
|
t.Error("Unexpected error", cfg.Folders()["folder"].Invalid)
|
||||||
|
@ -69,6 +70,7 @@ func TestFolderErrors(t *testing.T) {
|
||||||
|
|
||||||
m = model.NewModel(cfg, protocol.LocalDeviceID, "device", "syncthing", "dev", ldb)
|
m = model.NewModel(cfg, protocol.LocalDeviceID, "device", "syncthing", "dev", ldb)
|
||||||
m.AddFolder(fcfg)
|
m.AddFolder(fcfg)
|
||||||
|
m.StartFolderRW("folder")
|
||||||
|
|
||||||
if err := m.CheckFolderHealth("folder"); err != nil {
|
if err := m.CheckFolderHealth("folder"); err != nil {
|
||||||
t.Error("Unexpected error", cfg.Folders()["folder"].Invalid)
|
t.Error("Unexpected error", cfg.Folders()["folder"].Invalid)
|
||||||
|
@ -90,8 +92,9 @@ func TestFolderErrors(t *testing.T) {
|
||||||
|
|
||||||
m = model.NewModel(cfg, protocol.LocalDeviceID, "device", "syncthing", "dev", ldb)
|
m = model.NewModel(cfg, protocol.LocalDeviceID, "device", "syncthing", "dev", ldb)
|
||||||
m.AddFolder(fcfg)
|
m.AddFolder(fcfg)
|
||||||
|
m.StartFolderRW("folder")
|
||||||
|
|
||||||
if err := m.CheckFolderHealth("folder"); err == nil || err.Error() != "Folder marker missing" {
|
if err := m.CheckFolderHealth("folder"); err == nil || err.Error() != "folder marker missing" {
|
||||||
t.Error("Incorrect error: Folder marker missing !=", m.CheckFolderHealth("folder"))
|
t.Error("Incorrect error: Folder marker missing !=", m.CheckFolderHealth("folder"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,8 +120,9 @@ func TestFolderErrors(t *testing.T) {
|
||||||
|
|
||||||
m = model.NewModel(cfg, protocol.LocalDeviceID, "device", "syncthing", "dev", ldb)
|
m = model.NewModel(cfg, protocol.LocalDeviceID, "device", "syncthing", "dev", ldb)
|
||||||
m.AddFolder(fcfg)
|
m.AddFolder(fcfg)
|
||||||
|
m.StartFolderRW("folder")
|
||||||
|
|
||||||
if err := m.CheckFolderHealth("folder"); err == nil || err.Error() != "Folder path missing" {
|
if err := m.CheckFolderHealth("folder"); err == nil || err.Error() != "folder path missing" {
|
||||||
t.Error("Incorrect error: Folder path missing !=", m.CheckFolderHealth("folder"))
|
t.Error("Incorrect error: Folder path missing !=", m.CheckFolderHealth("folder"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,7 +130,7 @@ func TestFolderErrors(t *testing.T) {
|
||||||
|
|
||||||
os.Mkdir("testdata/testfolder", 0700)
|
os.Mkdir("testdata/testfolder", 0700)
|
||||||
|
|
||||||
if err := m.CheckFolderHealth("folder"); err == nil || err.Error() != "Folder marker missing" {
|
if err := m.CheckFolderHealth("folder"); err == nil || err.Error() != "folder marker missing" {
|
||||||
t.Error("Incorrect error: Folder marker missing !=", m.CheckFolderHealth("folder"))
|
t.Error("Incorrect error: Folder marker missing !=", m.CheckFolderHealth("folder"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -193,9 +193,9 @@
|
||||||
<th><span class="glyphicon glyphicon-folder-open"></span> <span translate>Folder Path</span></th>
|
<th><span class="glyphicon glyphicon-folder-open"></span> <span translate>Folder Path</span></th>
|
||||||
<td class="text-right">{{folder.path}}</td>
|
<td class="text-right">{{folder.path}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr ng-if="model[folder.id].invalid">
|
<tr ng-if="model[folder.id].invalid || model[folder.id].error">
|
||||||
<th><span class="glyphicon glyphicon-warning-sign"></span> <span translate>Error</span></th>
|
<th><span class="glyphicon glyphicon-warning-sign"></span> <span translate>Error</span></th>
|
||||||
<td class="text-right">{{model[folder.id].invalid}}</td>
|
<td class="text-right">{{model[folder.id].invalid || model[folder.id].error}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th><span class="glyphicon glyphicon-globe"></span> <span translate>Global State</span></th>
|
<th><span class="glyphicon glyphicon-globe"></span> <span translate>Global State</span></th>
|
||||||
|
|
|
@ -461,10 +461,14 @@ angular.module('syncthing.core')
|
||||||
return 'unshared';
|
return 'unshared';
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($scope.model[folderCfg.id].invalid !== '') {
|
if ($scope.model[folderCfg.id].invalid) {
|
||||||
return 'stopped';
|
return 'stopped';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($scope.model[folderCfg.id].state == 'error') {
|
||||||
|
return 'stopped'; // legacy, the state is called "stopped" in the GUI
|
||||||
|
}
|
||||||
|
|
||||||
return '' + $scope.model[folderCfg.id].state;
|
return '' + $scope.model[folderCfg.id].state;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -494,6 +498,9 @@ angular.module('syncthing.core')
|
||||||
if (state == 'scanning') {
|
if (state == 'scanning') {
|
||||||
return 'primary';
|
return 'primary';
|
||||||
}
|
}
|
||||||
|
if (state == 'error') {
|
||||||
|
return 'danger';
|
||||||
|
}
|
||||||
return 'info';
|
return 'info';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -215,29 +215,6 @@ func (w *Wrapper) SetGUI(gui GUIConfiguration) {
|
||||||
w.replaces <- w.cfg.Copy()
|
w.replaces <- w.cfg.Copy()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sets the folder error state. Emits ConfigSaved to cause a GUI refresh.
|
|
||||||
func (w *Wrapper) SetFolderError(id string, err error) {
|
|
||||||
w.mut.Lock()
|
|
||||||
defer w.mut.Unlock()
|
|
||||||
|
|
||||||
w.folderMap = nil
|
|
||||||
|
|
||||||
for i := range w.cfg.Folders {
|
|
||||||
if w.cfg.Folders[i].ID == id {
|
|
||||||
errstr := ""
|
|
||||||
if err != nil {
|
|
||||||
errstr = err.Error()
|
|
||||||
}
|
|
||||||
if errstr != w.cfg.Folders[i].Invalid {
|
|
||||||
w.cfg.Folders[i].Invalid = errstr
|
|
||||||
events.Default.Log(events.ConfigSaved, w.cfg)
|
|
||||||
w.replaces <- w.cfg.Copy()
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns whether or not connection attempts from the given device should be
|
// Returns whether or not connection attempts from the given device should be
|
||||||
// silently ignored.
|
// silently ignored.
|
||||||
func (w *Wrapper) IgnoredDevice(id protocol.DeviceID) bool {
|
func (w *Wrapper) IgnoredDevice(id protocol.DeviceID) bool {
|
||||||
|
|
|
@ -1,17 +1,8 @@
|
||||||
// Copyright (C) 2015 The Syncthing Authors.
|
// Copyright (C) 2015 The Syncthing Authors.
|
||||||
//
|
//
|
||||||
// This program is free software: you can redistribute it and/or modify it
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
// under the terms of the GNU General Public License as published by the Free
|
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
// Software Foundation, either version 3 of the License, or (at your option)
|
// You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
// any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
// more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License along
|
|
||||||
// with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
package model
|
package model
|
||||||
|
|
||||||
|
@ -28,7 +19,7 @@ const (
|
||||||
FolderIdle folderState = iota
|
FolderIdle folderState = iota
|
||||||
FolderScanning
|
FolderScanning
|
||||||
FolderSyncing
|
FolderSyncing
|
||||||
FolderCleaning
|
FolderError
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s folderState) String() string {
|
func (s folderState) String() string {
|
||||||
|
@ -37,10 +28,10 @@ func (s folderState) String() string {
|
||||||
return "idle"
|
return "idle"
|
||||||
case FolderScanning:
|
case FolderScanning:
|
||||||
return "scanning"
|
return "scanning"
|
||||||
case FolderCleaning:
|
|
||||||
return "cleaning"
|
|
||||||
case FolderSyncing:
|
case FolderSyncing:
|
||||||
return "syncing"
|
return "syncing"
|
||||||
|
case FolderError:
|
||||||
|
return "error"
|
||||||
default:
|
default:
|
||||||
return "unknown"
|
return "unknown"
|
||||||
}
|
}
|
||||||
|
@ -51,10 +42,16 @@ type stateTracker struct {
|
||||||
|
|
||||||
mut sync.Mutex
|
mut sync.Mutex
|
||||||
current folderState
|
current folderState
|
||||||
|
err error
|
||||||
changed time.Time
|
changed time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// setState sets the new folder state, for states other than FolderError.
|
||||||
func (s *stateTracker) setState(newState folderState) {
|
func (s *stateTracker) setState(newState folderState) {
|
||||||
|
if newState == FolderError {
|
||||||
|
panic("must use setError")
|
||||||
|
}
|
||||||
|
|
||||||
s.mut.Lock()
|
s.mut.Lock()
|
||||||
if newState != s.current {
|
if newState != s.current {
|
||||||
/* This should hold later...
|
/* This should hold later...
|
||||||
|
@ -74,6 +71,7 @@ func (s *stateTracker) setState(newState folderState) {
|
||||||
}
|
}
|
||||||
|
|
||||||
s.current = newState
|
s.current = newState
|
||||||
|
s.err = nil
|
||||||
s.changed = time.Now()
|
s.changed = time.Now()
|
||||||
|
|
||||||
events.Default.Log(events.StateChanged, eventData)
|
events.Default.Log(events.StateChanged, eventData)
|
||||||
|
@ -81,9 +79,35 @@ func (s *stateTracker) setState(newState folderState) {
|
||||||
s.mut.Unlock()
|
s.mut.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *stateTracker) getState() (current folderState, changed time.Time) {
|
// getState returns the current state, the time when it last changed, and the
|
||||||
|
// current error or nil.
|
||||||
|
func (s *stateTracker) getState() (current folderState, changed time.Time, err error) {
|
||||||
s.mut.Lock()
|
s.mut.Lock()
|
||||||
current, changed = s.current, s.changed
|
current, changed, err = s.current, s.changed, s.err
|
||||||
s.mut.Unlock()
|
s.mut.Unlock()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// setError sets the folder state to FolderError with the specified error.
|
||||||
|
func (s *stateTracker) setError(err error) {
|
||||||
|
s.mut.Lock()
|
||||||
|
if s.current != FolderError || s.err.Error() != err.Error() {
|
||||||
|
eventData := map[string]interface{}{
|
||||||
|
"folder": s.folder,
|
||||||
|
"to": FolderError.String(),
|
||||||
|
"from": s.current.String(),
|
||||||
|
"error": err.Error(),
|
||||||
|
}
|
||||||
|
|
||||||
|
if !s.changed.IsZero() {
|
||||||
|
eventData["duration"] = time.Since(s.changed).Seconds()
|
||||||
|
}
|
||||||
|
|
||||||
|
s.current = FolderError
|
||||||
|
s.err = err
|
||||||
|
s.changed = time.Now()
|
||||||
|
|
||||||
|
events.Default.Log(events.StateChanged, eventData)
|
||||||
|
}
|
||||||
|
s.mut.Unlock()
|
||||||
|
}
|
||||||
|
|
|
@ -48,8 +48,9 @@ type service interface {
|
||||||
Jobs() ([]string, []string) // In progress, Queued
|
Jobs() ([]string, []string) // In progress, Queued
|
||||||
BringToFront(string)
|
BringToFront(string)
|
||||||
|
|
||||||
setState(folderState)
|
setState(state folderState)
|
||||||
getState() (folderState, time.Time)
|
setError(err error)
|
||||||
|
getState() (folderState, time.Time, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Model struct {
|
type Model struct {
|
||||||
|
@ -1083,13 +1084,13 @@ func (m *Model) AddFolder(cfg config.FolderConfiguration) {
|
||||||
|
|
||||||
func (m *Model) ScanFolders() map[string]error {
|
func (m *Model) ScanFolders() map[string]error {
|
||||||
m.fmut.RLock()
|
m.fmut.RLock()
|
||||||
var folders = make([]string, 0, len(m.folderCfgs))
|
folders := make([]string, 0, len(m.folderCfgs))
|
||||||
for folder := range m.folderCfgs {
|
for folder := range m.folderCfgs {
|
||||||
folders = append(folders, folder)
|
folders = append(folders, folder)
|
||||||
}
|
}
|
||||||
m.fmut.RUnlock()
|
m.fmut.RUnlock()
|
||||||
|
|
||||||
var errors = make(map[string]error, len(m.folderCfgs))
|
errors := make(map[string]error, len(m.folderCfgs))
|
||||||
var errorsMut sync.Mutex
|
var errorsMut sync.Mutex
|
||||||
|
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
|
@ -1102,11 +1103,15 @@ func (m *Model) ScanFolders() map[string]error {
|
||||||
errorsMut.Lock()
|
errorsMut.Lock()
|
||||||
errors[folder] = err
|
errors[folder] = err
|
||||||
errorsMut.Unlock()
|
errorsMut.Unlock()
|
||||||
|
|
||||||
// Potentially sets the error twice, once in the scanner just
|
// Potentially sets the error twice, once in the scanner just
|
||||||
// by doing a check, and once here, if the error returned is
|
// by doing a check, and once here, if the error returned is
|
||||||
// the same one as returned by CheckFolderHealth, though
|
// the same one as returned by CheckFolderHealth, though
|
||||||
// duplicate set is handled by SetFolderError
|
// duplicate set is handled by setError.
|
||||||
m.cfg.SetFolderError(folder, err)
|
m.fmut.RLock()
|
||||||
|
srv := m.folderRunners[folder]
|
||||||
|
m.fmut.RUnlock()
|
||||||
|
srv.setError(err)
|
||||||
}
|
}
|
||||||
wg.Done()
|
wg.Done()
|
||||||
}()
|
}()
|
||||||
|
@ -1182,13 +1187,13 @@ nextSub:
|
||||||
}
|
}
|
||||||
|
|
||||||
runner.setState(FolderScanning)
|
runner.setState(FolderScanning)
|
||||||
defer runner.setState(FolderIdle)
|
|
||||||
fchan, err := w.Walk()
|
|
||||||
|
|
||||||
|
fchan, err := w.Walk()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
m.cfg.SetFolderError(folder, err)
|
runner.setError(err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
batchSize := 100
|
batchSize := 100
|
||||||
batch := make([]protocol.FileInfo, 0, batchSize)
|
batch := make([]protocol.FileInfo, 0, batchSize)
|
||||||
for f := range fchan {
|
for f := range fchan {
|
||||||
|
@ -1298,6 +1303,7 @@ nextSub:
|
||||||
fs.Update(protocol.LocalDeviceID, batch)
|
fs.Update(protocol.LocalDeviceID, batch)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
runner.setState(FolderIdle)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1340,15 +1346,18 @@ func (m *Model) clusterConfig(device protocol.DeviceID) protocol.ClusterConfigMe
|
||||||
return cm
|
return cm
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Model) State(folder string) (string, time.Time) {
|
func (m *Model) State(folder string) (string, time.Time, error) {
|
||||||
m.fmut.RLock()
|
m.fmut.RLock()
|
||||||
runner, ok := m.folderRunners[folder]
|
runner, ok := m.folderRunners[folder]
|
||||||
m.fmut.RUnlock()
|
m.fmut.RUnlock()
|
||||||
if !ok {
|
if !ok {
|
||||||
return "", time.Time{}
|
// The returned error should be an actual folder error, so returning
|
||||||
|
// errors.New("does not exist") or similar here would be
|
||||||
|
// inappropriate.
|
||||||
|
return "", time.Time{}, nil
|
||||||
}
|
}
|
||||||
state, changed := runner.getState()
|
state, changed, err := runner.getState()
|
||||||
return state.String(), changed
|
return state.String(), changed, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Model) Override(folder string) {
|
func (m *Model) Override(folder string) {
|
||||||
|
@ -1528,7 +1537,7 @@ func (m *Model) BringToFront(folder, file string) {
|
||||||
func (m *Model) CheckFolderHealth(id string) error {
|
func (m *Model) CheckFolderHealth(id string) error {
|
||||||
folder, ok := m.cfg.Folders()[id]
|
folder, ok := m.cfg.Folders()[id]
|
||||||
if !ok {
|
if !ok {
|
||||||
return errors.New("Folder does not exist")
|
return errors.New("folder does not exist")
|
||||||
}
|
}
|
||||||
|
|
||||||
fi, err := os.Stat(folder.Path())
|
fi, err := os.Stat(folder.Path())
|
||||||
|
@ -1538,9 +1547,9 @@ func (m *Model) CheckFolderHealth(id string) error {
|
||||||
// that all files have been deleted which might not be the case,
|
// that all files have been deleted which might not be the case,
|
||||||
// so mark it as invalid instead.
|
// so mark it as invalid instead.
|
||||||
if err != nil || !fi.IsDir() {
|
if err != nil || !fi.IsDir() {
|
||||||
err = errors.New("Folder path missing")
|
err = errors.New("folder path missing")
|
||||||
} else if !folder.HasMarker() {
|
} else if !folder.HasMarker() {
|
||||||
err = errors.New("Folder marker missing")
|
err = errors.New("folder marker missing")
|
||||||
}
|
}
|
||||||
} else if os.IsNotExist(err) {
|
} else if os.IsNotExist(err) {
|
||||||
// If we don't have any files in the index, and the directory
|
// If we don't have any files in the index, and the directory
|
||||||
|
@ -1555,35 +1564,21 @@ func (m *Model) CheckFolderHealth(id string) error {
|
||||||
err = folder.CreateMarker()
|
err = folder.CreateMarker()
|
||||||
}
|
}
|
||||||
|
|
||||||
if err == nil {
|
m.fmut.RLock()
|
||||||
if folder.Invalid != "" {
|
runner := m.folderRunners[folder.ID]
|
||||||
l.Infof("Starting folder %q after error %q", folder.ID, folder.Invalid)
|
m.fmut.RUnlock()
|
||||||
m.cfg.SetFolderError(id, nil)
|
_, _, oldErr := runner.getState()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
if oldErr != nil && oldErr.Error() != err.Error() {
|
||||||
|
l.Infof("Folder %q error changed: %q -> %q", folder.ID, oldErr, err)
|
||||||
|
} else if oldErr == nil {
|
||||||
|
l.Warnf("Stopping folder %q - %v", folder.ID, err)
|
||||||
}
|
}
|
||||||
|
runner.setError(err)
|
||||||
if folder, ok := m.cfg.Folders()[id]; !ok || folder.Invalid != "" {
|
} else if oldErr != nil {
|
||||||
panic("Unable to unset folder \"" + id + "\" error.")
|
l.Infof("Folder %q error is cleared, restarting", folder.ID)
|
||||||
}
|
runner.setState(FolderIdle)
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if folder.Invalid == err.Error() {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// folder is a copy of the original struct, hence Invalid value is
|
|
||||||
// preserved after the set.
|
|
||||||
m.cfg.SetFolderError(id, err)
|
|
||||||
|
|
||||||
if folder.Invalid == "" {
|
|
||||||
l.Warnf("Stopping folder %q - %v", folder.ID, err)
|
|
||||||
} else {
|
|
||||||
l.Infof("Folder %q error changed: %q -> %q", folder.ID, folder.Invalid, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if folder, ok := m.cfg.Folders()[id]; !ok || folder.Invalid != err.Error() {
|
|
||||||
panic("Unable to set folder \"" + id + "\" error.")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -621,21 +621,25 @@ func TestROScanRecovery(t *testing.T) {
|
||||||
if time.Now().After(timeout) {
|
if time.Now().After(timeout) {
|
||||||
return fmt.Errorf("Timed out waiting for status: %s, current status: %s", status, m.cfg.Folders()["default"].Invalid)
|
return fmt.Errorf("Timed out waiting for status: %s, current status: %s", status, m.cfg.Folders()["default"].Invalid)
|
||||||
}
|
}
|
||||||
if m.cfg.Folders()["default"].Invalid == status {
|
_, _, err := m.State("default")
|
||||||
|
if err == nil && status == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if err != nil && err.Error() == status {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
time.Sleep(10 * time.Millisecond)
|
time.Sleep(10 * time.Millisecond)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := waitFor("Folder path missing"); err != nil {
|
if err := waitFor("folder path missing"); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
os.Mkdir(fcfg.RawPath, 0700)
|
os.Mkdir(fcfg.RawPath, 0700)
|
||||||
|
|
||||||
if err := waitFor("Folder marker missing"); err != nil {
|
if err := waitFor("folder marker missing"); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -654,14 +658,14 @@ func TestROScanRecovery(t *testing.T) {
|
||||||
|
|
||||||
os.Remove(filepath.Join(fcfg.RawPath, ".stfolder"))
|
os.Remove(filepath.Join(fcfg.RawPath, ".stfolder"))
|
||||||
|
|
||||||
if err := waitFor("Folder marker missing"); err != nil {
|
if err := waitFor("folder marker missing"); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
os.Remove(fcfg.RawPath)
|
os.Remove(fcfg.RawPath)
|
||||||
|
|
||||||
if err := waitFor("Folder path missing"); err != nil {
|
if err := waitFor("folder path missing"); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -701,21 +705,25 @@ func TestRWScanRecovery(t *testing.T) {
|
||||||
if time.Now().After(timeout) {
|
if time.Now().After(timeout) {
|
||||||
return fmt.Errorf("Timed out waiting for status: %s, current status: %s", status, m.cfg.Folders()["default"].Invalid)
|
return fmt.Errorf("Timed out waiting for status: %s, current status: %s", status, m.cfg.Folders()["default"].Invalid)
|
||||||
}
|
}
|
||||||
if m.cfg.Folders()["default"].Invalid == status {
|
_, _, err := m.State("default")
|
||||||
|
if err == nil && status == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if err != nil && err.Error() == status {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
time.Sleep(10 * time.Millisecond)
|
time.Sleep(10 * time.Millisecond)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := waitFor("Folder path missing"); err != nil {
|
if err := waitFor("folder path missing"); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
os.Mkdir(fcfg.RawPath, 0700)
|
os.Mkdir(fcfg.RawPath, 0700)
|
||||||
|
|
||||||
if err := waitFor("Folder marker missing"); err != nil {
|
if err := waitFor("folder marker missing"); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -734,14 +742,14 @@ func TestRWScanRecovery(t *testing.T) {
|
||||||
|
|
||||||
os.Remove(filepath.Join(fcfg.RawPath, ".stfolder"))
|
os.Remove(filepath.Join(fcfg.RawPath, ".stfolder"))
|
||||||
|
|
||||||
if err := waitFor("Folder marker missing"); err != nil {
|
if err := waitFor("folder marker missing"); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
os.Remove(fcfg.RawPath)
|
os.Remove(fcfg.RawPath)
|
||||||
|
|
||||||
if err := waitFor("Folder path missing"); err != nil {
|
if err := waitFor("folder path missing"); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,8 +67,8 @@ func (s *roFolder) Serve() {
|
||||||
// Potentially sets the error twice, once in the scanner just
|
// Potentially sets the error twice, once in the scanner just
|
||||||
// by doing a check, and once here, if the error returned is
|
// by doing a check, and once here, if the error returned is
|
||||||
// the same one as returned by CheckFolderHealth, though
|
// the same one as returned by CheckFolderHealth, though
|
||||||
// duplicate set is handled by SetFolderError
|
// duplicate set is handled by setError.
|
||||||
s.model.cfg.SetFolderError(s.folder, err)
|
s.setError(err)
|
||||||
reschedule()
|
reschedule()
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
|
@ -245,8 +245,8 @@ func (p *rwFolder) Serve() {
|
||||||
// Potentially sets the error twice, once in the scanner just
|
// Potentially sets the error twice, once in the scanner just
|
||||||
// by doing a check, and once here, if the error returned is
|
// by doing a check, and once here, if the error returned is
|
||||||
// the same one as returned by CheckFolderHealth, though
|
// the same one as returned by CheckFolderHealth, though
|
||||||
// duplicate set is handled by SetFolderError
|
// duplicate set is handled by setError.
|
||||||
p.model.cfg.SetFolderError(p.folder, err)
|
p.setError(err)
|
||||||
rescheduleScan()
|
rescheduleScan()
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue