fixing moved from/into deleted directories

This commit is contained in:
Axel Kittenberger 2012-02-16 00:28:03 +01:00
parent 80baea16e0
commit f172c69dee
6 changed files with 115 additions and 113 deletions

View File

@ -10,6 +10,8 @@
fix: in case of HUP-reset imply insist=true, since startup is known to be fix: in case of HUP-reset imply insist=true, since startup is known to be
configured correctly. configured correctly.
fix: a series of typos in comments, manpage etc. fix: a series of typos in comments, manpage etc.
fix: moves to and from deleted directories (deleted when Lsyncd gets notified)
were not correctly translated
change: complain if any "rsyncOps" is given change: complain if any "rsyncOps" is given
change: splitted the default configurations in their own files. change: splitted the default configurations in their own files.
more cleanly seperated from the Lsyncd runner, and highlights it are just more cleanly seperated from the Lsyncd runner, and highlights it are just

View File

@ -34,7 +34,7 @@ default.direct = {
spawn( spawn(
event, event,
'/bin/mkdir', '/bin/mkdir',
'-p', -- '-p',
event.targetPath event.targetPath
) )
else else

View File

@ -1942,13 +1942,13 @@ local Inotify = (function()
local etyped = etype local etyped = etype
if etyped == 'Move' then if etyped == 'Move' then
if not relative2 then if not relative2 then
log('Normal', 'Transformed Move to Create for ', sync.config.name) log('Normal', 'Transformed Move to Delete for ', sync.config.name)
etyped = 'Create' etyped = 'Delete'
elseif not relative then elseif not relative then
relative = relative2 relative = relative2
relative2 = nil relative2 = nil
log('Normal', 'Transformed Move to Delete for ', sync.config.name) log('Normal', 'Transformed Move to Create for ', sync.config.name)
etyped = 'Delete' etyped = 'Create'
end end
end end
sync:delay(etyped, time, relative, relative2) sync:delay(etyped, time, relative, relative2)
@ -2042,13 +2042,13 @@ local Fsevents = (function()
local etyped = etype local etyped = etype
if etyped == 'Move' then if etyped == 'Move' then
if not relative2 then if not relative2 then
log('Normal', 'Transformed Move to Create for ', sync.config.name) log('Normal', 'Transformed Move to Delete for ', sync.config.name)
etyped = 'Create' etyped = 'Delete'
elseif not relative then elseif not relative then
relative = relative2 relative = relative2
relative2 = nil relative2 = nil
log('Normal', 'Transformed Move to Delete for ', sync.config.name) log('Normal', 'Transformed Move to Create for ', sync.config.name)
etyped = 'Delete' etyped = 'Create'
end end
end end
sync:delay(etyped, time, relative, relative2) sync:delay(etyped, time, relative, relative2)

View File

@ -11,13 +11,13 @@ cwriteln('****************************************************************')
local tdir, srcdir, trgdir = mktemps() local tdir, srcdir, trgdir = mktemps()
-- makes some startup data -- makes some startup data
churn(srcdir, 10) churn(srcdir, 10)
local logs = {'-log', 'Exec'} local logs = {'-log', 'Exec' }
local pid = spawn( local pid = spawn(
'./lsyncd', './lsyncd',
'-nodaemon', '-nodaemon',
'-direct', srcdir, trgdir, '-direct', srcdir, trgdir,
unpack(logs) unpack(logs)
) )

View File

@ -1,109 +1,109 @@
#!/usr/bin/lua #!/usr/bin/lua
require("posix") require('posix')
dofile("tests/testlib.lua") dofile('tests/testlib.lua')
cwriteln("****************************************************************") cwriteln('****************************************************************')
cwriteln(" Testing excludes ") cwriteln(' Testing excludes')
cwriteln("****************************************************************") cwriteln('****************************************************************')
local tdir, srcdir, trgdir = mktemps() local tdir, srcdir, trgdir = mktemps()
local logfile = tdir .. "log" local logfile = tdir .. 'log'
local cfgfile = tdir .. "config.lua" local cfgfile = tdir .. 'config.lua'
local range = 5 local range = 5
local log = {"-log", "all"} local log = {'-log', 'all'}
writefile(cfgfile, [[ writefile(cfgfile, [[
settings = { settings = {
logfile = "]]..logfile..[[", logfile = ']]..logfile..[[',
nodaemon = true, nodaemon = true,
delay = 3, delay = 3,
} }
sync { sync {
default.rsync, default.rsync,
source = "]]..srcdir..[[", source = ']]..srcdir..[[',
target = "]]..trgdir..[[", target = ']]..trgdir..[[',
exclude = { exclude = {
"erf", 'erf',
"/eaf", '/eaf',
"erd/", 'erd/',
"/ead", '/ead',
}, },
}]]); }]]);
-- writes all files -- writes all files
local function writefiles() local function writefiles()
posix.mkdir(srcdir .. "d"); posix.mkdir(srcdir .. 'd');
writefile(srcdir .. "erf", "erf"); writefile(srcdir .. 'erf', 'erf');
writefile(srcdir .. "eaf", "erf"); writefile(srcdir .. 'eaf', 'erf');
writefile(srcdir .. "erd", "erd"); writefile(srcdir .. 'erd', 'erd');
writefile(srcdir .. "ead", "ead"); writefile(srcdir .. 'ead', 'ead');
writefile(srcdir .. "d/erf", "erf"); writefile(srcdir .. 'd/erf', 'erf');
writefile(srcdir .. "d/eaf", "erf"); writefile(srcdir .. 'd/eaf', 'erf');
writefile(srcdir .. "d/erd", "erd"); writefile(srcdir .. 'd/erd', 'erd');
writefile(srcdir .. "d/ead", "ead"); writefile(srcdir .. 'd/ead', 'ead');
end end
-- test if the filename exists, fails if this is different to expect -- test if the filename exists, fails if this is different to expect
local function testfile(filename, expect) local function testfile(filename, expect)
local stat, err = posix.stat(filename) local stat, err = posix.stat(filename)
if stat and not expect then if stat and not expect then
cwriteln("failure: ",filename," should be excluded"); cwriteln('failure: ',filename,' should be excluded');
os.exit(1); os.exit(1);
end end
if not stat and expect then if not stat and expect then
cwriteln("failure: ",filename," should not be excluded"); cwriteln('failure: ',filename,' should not be excluded');
os.exit(1); os.exit(1);
end end
end end
-- test all files -- test all files
local function testfiles() local function testfiles()
testfile(srcdir .. "erf", false); testfile(srcdir .. 'erf', false);
testfile(srcdir .. "eaf", false); testfile(srcdir .. 'eaf', false);
testfile(srcdir .. "erd", true); testfile(srcdir .. 'erd', true);
testfile(srcdir .. "ead", true); testfile(srcdir .. 'ead', true);
testfile(srcdir .. "d/erf", false); testfile(srcdir .. 'd/erf', false);
testfile(srcdir .. "d/eaf", true); testfile(srcdir .. 'd/eaf', true);
testfile(srcdir .. "d/erd", true); testfile(srcdir .. 'd/erd', true);
testfile(srcdir .. "d/ead", true); testfile(srcdir .. 'd/ead', true);
end end
cwriteln("testing startup excludes"); cwriteln('testing startup excludes');
writefiles(); writefiles();
cwriteln("starting Lsyncd"); cwriteln('starting Lsyncd');
local pid = spawn("./lsyncd", cfgfile); local pid = spawn('./lsyncd', cfgfile);
cwriteln("waiting for Lsyncd to start"); cwriteln('waiting for Lsyncd to start');
posix.sleep(3) posix.sleep(3)
cwriteln("testing excludes after startup"); cwriteln('testing excludes after startup');
testfiles(); testfiles();
cwriteln("ok, removing sources"); cwriteln('ok, removing sources');
if srcdir:sub(1,4) ~= "/tmp" then if srcdir:sub(1,4) ~= '/tmp' then
-- just to make sure before rm -rf -- just to make sure before rm -rf
cwriteln("exist before drama, srcdir is '", srcdir, "'"); cwriteln('exist before drama, srcdir is '', srcdir, ''');
os.exit(1); os.exit(1);
end end
os.execute("rm -rf "..srcdir.."/*"); os.execute('rm -rf '..srcdir..'/*');
writeln("waiting for Lsyncd to remove destination"); writeln('waiting for Lsyncd to remove destination');
if os.execute("diff -urN "..srcdir.." "..trgdir) ~= 0 then if os.execute('diff -urN '..srcdir..' '..trgdir) ~= 0 then
os.exit(1); os.exit(1);
end end
posix.sleep(5); posix.sleep(5);
writeln("writing files after startup"); writeln('writing files after startup');
writefiles(); writefiles();
writeln("waiting for Lsyncd to transmit changes"); writeln('waiting for Lsyncd to transmit changes');
posix.sleep(5); posix.sleep(5);
testfiles(); testfiles();
writeln("killing started Lsyncd"); writeln('killing started Lsyncd');
posix.kill(pid); posix.kill(pid);
local _, exitmsg, lexitcode = posix.wait(lpid); local _, exitmsg, lexitcode = posix.wait(lpid);
cwriteln("Exitcode of Lsyncd = ", exitmsg, " ", lexitcode); cwriteln('Exitcode of Lsyncd = ', exitmsg, ' ', lexitcode);
posix.sleep(1); posix.sleep(1);
if lexitcode == 0 then if lexitcode == 0 then
cwriteln("OK"); cwriteln('OK');
end end
os.exit(lexitcode); os.exit(lexitcode);

View File

@ -1,28 +1,28 @@
-- common testing environment -- common testing environment
require("posix") require('posix')
-- escape codes to colorize output on terminal -- escape codes to colorize output on terminal
local c1="\027[47;34m" local c1='\027[47;34m'
local c0="\027[0m" local c0='\027[0m'
--- ---
-- writes colorized -- writes colorized
-- --
function cwriteln(...) function cwriteln(...)
io.write(c1, ...) io.write(c1, ...)
io.write(c0, "\n") io.write(c0, '\n')
end end
----- -----
-- initializes the pseudo random generator -- initializes the pseudo random generator
-- if environemnt "SEED" is set, use that as seed. -- if environemnt 'SEED' is set, use that as seed.
local seed = os.getenv("SEED") or os.time() local seed = os.getenv('SEED') or os.time()
math.randomseed(seed) math.randomseed(seed)
cwriteln("random seed: ", seed) cwriteln('random seed: ', seed)
----- -----
-- creates a tmp directory -- creates a tmp directory
-- --
-- @returns the name of the directory -- @returns the name of the directory
-- --
function mktempd() function mktempd()
@ -30,24 +30,24 @@ function mktempd()
local s = f:read('*a') local s = f:read('*a')
f:close() f:close()
s = s:gsub('[\n\r]+', ' ') s = s:gsub('[\n\r]+', ' ')
s = s:match("^%s*(.-)%s*$") s = s:match('^%s*(.-)%s*$')
return s return s
end end
----- -----
-- creates a tmp directory with the -- creates a tmp directory with the
-- typical lsyncd test architecture -- typical lsyncd test architecture
-- --
-- @returns path of tmpdir -- @returns path of tmpdir
-- path of srcdir -- path of srcdir
-- path of trgdir -- path of trgdir
-- --
function mktemps() function mktemps()
local tdir = mktempd().."/" local tdir = mktempd()..'/'
cwriteln("using ", tdir, " as test root") cwriteln('using ', tdir, ' as test root')
local srcdir = tdir.."src/" local srcdir = tdir..'src/'
local trgdir = tdir.."trg/" local trgdir = tdir..'trg/'
posix.mkdir(srcdir) posix.mkdir(srcdir)
posix.mkdir(trgdir) posix.mkdir(trgdir)
return tdir, srcdir, trgdir return tdir, srcdir, trgdir
@ -58,9 +58,9 @@ end
-- and adds a newline. -- and adds a newline.
-- --
function writefile(filename, text) function writefile(filename, text)
local f = io.open(filename, "w") local f = io.open(filename, 'w')
if not f then if not f then
cwriteln("Cannot open '"..filename.."' for writing.") cwriteln('Cannot open "'..filename..'" for writing.')
return false return false
end end
f:write(text) f:write(text)
@ -76,16 +76,16 @@ end
-- --
function spawn(...) function spawn(...)
args = {...} args = {...}
cwriteln("spawning: ", table.concat(args, " ")) cwriteln('spawning: ', table.concat(args, ' '))
local pid = posix.fork() local pid = posix.fork()
if pid < 0 then if pid < 0 then
cwriteln("Error, failed fork!") cwriteln('Error, failed fork!')
os.exit(-1) os.exit(-1)
end end
if pid == 0 then if pid == 0 then
posix.exec(...) posix.exec(...)
-- should not return -- should not return
cwriteln("Error, failed to spawn: ", ...) cwriteln('Error, failed to spawn: ', ...)
os.exit(-1); os.exit(-1);
end end
return pid return pid
@ -97,9 +97,9 @@ end
-- @param rootdir ... the directory to make data in -- @param rootdir ... the directory to make data in
-- @param n ... roughly how much data action will done -- @param n ... roughly how much data action will done
-- --
function churn(rootdir, n) function churn(rootdir, n)
-- all dirs created, indexed by integer and path -- all dirs created, indexed by integer and path
root = {name=""} root = {name=''}
alldirs = {root} alldirs = {root}
dirsWithFileI = {} dirsWithFileI = {}
dirsWithFileD = {} dirsWithFileD = {}
@ -110,11 +110,11 @@ function churn(rootdir, n)
-- name is internal recursive paramter, keep it nil. -- name is internal recursive paramter, keep it nil.
-- --
local function dirname(dir, name) local function dirname(dir, name)
name = name or "" name = name or ''
if not dir then if not dir then
return name return name
end end
return dirname(dir.parent, dir.name .. "/" .. name) return dirname(dir.parent, dir.name .. '/' .. name)
end end
----- -----
@ -133,7 +133,7 @@ function churn(rootdir, n)
---- ----
-- Picks a random file. -- Picks a random file.
-- --
-- Returns 3 values: -- Returns 3 values:
-- * the directory -- * the directory
-- * the filename -- * the filename
-- * number of files in directory -- * number of files in directory
@ -158,7 +158,7 @@ function churn(rootdir, n)
-- picks one file at random -- picks one file at random
local cr = math.random(1, c) local cr = math.random(1, c)
local fn local fn
for name, _ in pairs(rdir) do for name, _ in pairs(rdir) do
if #name == 2 then if #name == 2 then
-- filenames are 2 chars wide. -- filenames are 2 chars wide.
@ -184,7 +184,7 @@ function churn(rootdir, n)
if c == 1 then if c == 1 then
-- if last file from origin dir, it has no files anymore -- if last file from origin dir, it has no files anymore
for i, v in ipairs(dirsWithFileI) do for i, v in ipairs(dirsWithFileI) do
if v == dir then if v == dir then
table.remove(dirsWithFileI, i) table.remove(dirsWithFileI, i)
break break
end end
@ -194,16 +194,16 @@ function churn(rootdir, n)
end end
---- ----
-- possible randomized behaviour. -- possible randomized behaviour.
-- just gives it a pause -- just gives it a pause
-- --
local function sleep() local function sleep()
cwriteln("..zzz..") cwriteln('..zzz..')
posix.sleep(1) posix.sleep(1)
end end
---- ----
-- possible randomized behaviour. -- possible randomized behaviour.
-- creates a directory -- creates a directory
-- --
local function mkdir() local function mkdir()
@ -214,19 +214,19 @@ function churn(rootdir, n)
if not rdir[nn] then if not rdir[nn] then
local ndir = { local ndir = {
name = nn, name = nn,
parent = rdir, parent = rdir,
} }
local dn = dirname(ndir) local dn = dirname(ndir)
rdir[nn] = dn rdir[nn] = dn
table.insert(alldirs, ndir) table.insert(alldirs, ndir)
cwriteln("mkdir "..rootdir..dn) cwriteln('mkdir '..rootdir..dn)
posix.mkdir(rootdir..dn) posix.mkdir(rootdir..dn)
end end
end end
---- ----
-- possible randomized behaviour. -- possible randomized behaviour.
-- creates a directory -- Creates a file.
-- --
local function mkfile() local function mkfile()
-- chooses a random directory to create it into -- chooses a random directory to create it into
@ -234,8 +234,8 @@ function churn(rootdir, n)
-- creates a new random one letter name -- creates a new random one letter name
local nn = 'f'..string.char(96 + math.random(26)) local nn = 'f'..string.char(96 + math.random(26))
local fn = dirname(rdir) .. nn local fn = dirname(rdir) .. nn
cwriteln("mkfile "..rootdir..fn) cwriteln('mkfile '..rootdir..fn)
local f = io.open(rootdir..fn, "w") local f = io.open(rootdir..fn, 'w')
if f then if f then
for i=1,10 do for i=1,10 do
f:write(string.char(96 + math.random(26))) f:write(string.char(96 + math.random(26)))
@ -251,14 +251,14 @@ function churn(rootdir, n)
end end
---- ----
-- possible randomized behaviour. -- possible randomized behaviour,
-- moves a directory -- moves a directory.
-- --
local function mvdir() local function mvdir()
if #alldirs <= 2 then if #alldirs <= 2 then
return return
end end
-- chooses a random directory to move -- chooses a random directory to move
local odir = pickDir(true) local odir = pickDir(true)
-- chooses a random directory to move to -- chooses a random directory to move to
local tdir = pickDir() local tdir = pickDir()
@ -277,7 +277,7 @@ function churn(rootdir, n)
end end
local on = dirname(odir) local on = dirname(odir)
local tn = dirname(tdir) local tn = dirname(tdir)
cwriteln("mvdir ",rootdir,on," -> ",rootdir,tn,odir.name) cwriteln('mvdir ',rootdir,on,' -> ',rootdir,tn,odir.name)
os.rename(rootdir..on, rootdir..tn..odir.name) os.rename(rootdir..on, rootdir..tn..odir.name)
odir.parent[odir.name] = nil odir.parent[odir.name] = nil
odir.parent = tdir odir.parent = tdir
@ -285,8 +285,8 @@ function churn(rootdir, n)
end end
---- ----
-- possible randomized behaviour. -- possible randomized behaviour,
-- moves a directory -- moves a file.
-- --
local function mvfile() local function mvfile()
local odir, fn, c = pickFile() local odir, fn, c = pickFile()
@ -298,7 +298,7 @@ function churn(rootdir, n)
local tdir = pickDir() local tdir = pickDir()
local on = dirname(odir) local on = dirname(odir)
local tn = dirname(tdir) local tn = dirname(tdir)
cwriteln("mvfile ",rootdir,on,fn," -> ",rootdir,tn,fn) cwriteln('mvfile ',rootdir,on,fn,' -> ',rootdir,tn,fn)
os.rename(rootdir..on..fn, rootdir..tn..fn) os.rename(rootdir..on..fn, rootdir..tn..fn)
rmFileReference(odir, fn, c) rmFileReference(odir, fn, c)
@ -310,14 +310,14 @@ function churn(rootdir, n)
end end
---- ----
-- possible randomized behaviour. -- possible randomized behaviour,
-- moves a directory. -- removes a file.
-- --
local function rmfile() local function rmfile()
local dir, fn, c = pickFile() local dir, fn, c = pickFile()
if dir then if dir then
local dn = dirname(dir) local dn = dirname(dir)
cwriteln("rmfile ",rootdir,dn,fn) cwriteln('rmfile ',rootdir,dn,fn)
posix.unlink(rootdir..dn..fn) posix.unlink(rootdir..dn..fn)
rmFileReference(dir, fn, c) rmFileReference(dir, fn, c)
end end
@ -331,7 +331,7 @@ function churn(rootdir, n)
{ 20, rmfile }, { 20, rmfile },
} }
cwriteln("making random data") cwriteln('making random data')
local ndice = 0 local ndice = 0
for i, d in ipairs(dice) do for i, d in ipairs(dice) do
ndice = ndice + d[1] ndice = ndice + d[1]
@ -339,7 +339,7 @@ function churn(rootdir, n)
end end
for ai=1,n do for ai=1,n do
-- throw a die what to do -- throws a die what to do
local acn = math.random(ndice) local acn = math.random(ndice)
for i, d in ipairs(dice) do for i, d in ipairs(dice) do
if acn <= d[1] then if acn <= d[1] then