aboutsummaryrefslogtreecommitdiff
path: root/test/unit/os/fileio_spec.lua
diff options
context:
space:
mode:
Diffstat (limited to 'test/unit/os/fileio_spec.lua')
-rw-r--r--test/unit/os/fileio_spec.lua216
1 files changed, 164 insertions, 52 deletions
diff --git a/test/unit/os/fileio_spec.lua b/test/unit/os/fileio_spec.lua
index 5358022422..4d58a8934e 100644
--- a/test/unit/os/fileio_spec.lua
+++ b/test/unit/os/fileio_spec.lua
@@ -1,12 +1,15 @@
local lfs = require('lfs')
-local helpers = require('test.unit.helpers')
+local helpers = require('test.unit.helpers')(after_each)
+local itp = helpers.gen_itp(it)
local eq = helpers.eq
local ffi = helpers.ffi
local cimport = helpers.cimport
+local cppimport = helpers.cppimport
-local m = cimport('./src/nvim/os/fileio.h')
+local m = cimport('./src/nvim/os/os.h', './src/nvim/os/fileio.h')
+cppimport('fcntl.h')
local fcontents = ''
for i = 0, 255 do
@@ -57,10 +60,26 @@ local function file_open_new(fname, flags, mode)
return ret1[0], ret2
end
+local function file_open_fd(fd, flags)
+ local ret2 = ffi.new('FileDescriptor')
+ local ret1 = m.file_open_fd(ret2, fd, flags)
+ return ret1, ret2
+end
+
+local function file_open_fd_new(fd, flags)
+ local ret1 = ffi.new('int[?]', 1, {0})
+ local ret2 = ffi.gc(m.file_open_fd_new(ret1, fd, flags), nil)
+ return ret1[0], ret2
+end
+
local function file_write(fp, buf)
return m.file_write(fp, buf, #buf)
end
+local function msgpack_file_write(fp, buf)
+ return m.msgpack_file_write(fp, buf, #buf)
+end
+
local function file_read(fp, size)
local buf = nil
if size == nil then
@@ -79,6 +98,10 @@ local function file_read(fp, size)
return ret1, ret2
end
+local function file_flush(fp)
+ return m.file_flush(fp)
+end
+
local function file_fsync(fp)
return m.file_fsync(fp)
end
@@ -87,149 +110,211 @@ local function file_skip(fp, size)
return m.file_skip(fp, size)
end
+describe('file_open_fd', function()
+ itp('can use file descriptor returned by os_open for reading', function()
+ local fd = m.os_open(file1, m.kO_RDONLY, 0)
+ local err, fp = file_open_fd(fd, m.kFileReadOnly)
+ eq(0, err)
+ eq({#fcontents, fcontents}, {file_read(fp, #fcontents)})
+ eq(0, m.file_close(fp, false))
+ end)
+ itp('can use file descriptor returned by os_open for writing', function()
+ eq(nil, lfs.attributes(filec))
+ local fd = m.os_open(filec, m.kO_WRONLY + m.kO_CREAT, 384)
+ local err, fp = file_open_fd(fd, m.kFileWriteOnly)
+ eq(0, err)
+ eq(4, file_write(fp, 'test'))
+ eq(0, m.file_close(fp, false))
+ eq(4, lfs.attributes(filec).size)
+ eq('test', io.open(filec):read('*a'))
+ end)
+end)
+
+describe('file_open_fd_new', function()
+ itp('can use file descriptor returned by os_open for reading', function()
+ local fd = m.os_open(file1, m.kO_RDONLY, 0)
+ local err, fp = file_open_fd_new(fd, m.kFileReadOnly)
+ eq(0, err)
+ eq({#fcontents, fcontents}, {file_read(fp, #fcontents)})
+ eq(0, m.file_free(fp, false))
+ end)
+ itp('can use file descriptor returned by os_open for writing', function()
+ eq(nil, lfs.attributes(filec))
+ local fd = m.os_open(filec, m.kO_WRONLY + m.kO_CREAT, 384)
+ local err, fp = file_open_fd_new(fd, m.kFileWriteOnly)
+ eq(0, err)
+ eq(4, file_write(fp, 'test'))
+ eq(0, m.file_free(fp, false))
+ eq(4, lfs.attributes(filec).size)
+ eq('test', io.open(filec):read('*a'))
+ end)
+end)
+
describe('file_open', function()
- it('can create a rwx------ file with kFileCreate', function()
+ itp('can create a rwx------ file with kFileCreate', function()
local err, fp = file_open(filec, m.kFileCreate, 448)
eq(0, err)
local attrs = lfs.attributes(filec)
eq('rwx------', attrs.permissions)
- eq(0, m.file_close(fp))
+ eq(0, m.file_close(fp, false))
end)
- it('can create a rw------- file with kFileCreate', function()
+ itp('can create a rw------- file with kFileCreate', function()
local err, fp = file_open(filec, m.kFileCreate, 384)
eq(0, err)
local attrs = lfs.attributes(filec)
eq('rw-------', attrs.permissions)
- eq(0, m.file_close(fp))
+ eq(0, m.file_close(fp, false))
end)
- it('can create a rwx------ file with kFileCreateOnly', function()
+ itp('can create a rwx------ file with kFileCreateOnly', function()
local err, fp = file_open(filec, m.kFileCreateOnly, 448)
eq(0, err)
local attrs = lfs.attributes(filec)
eq('rwx------', attrs.permissions)
- eq(0, m.file_close(fp))
+ eq(0, m.file_close(fp, false))
end)
- it('can create a rw------- file with kFileCreateOnly', function()
+ itp('can create a rw------- file with kFileCreateOnly', function()
local err, fp = file_open(filec, m.kFileCreateOnly, 384)
eq(0, err)
local attrs = lfs.attributes(filec)
eq('rw-------', attrs.permissions)
- eq(0, m.file_close(fp))
+ eq(0, m.file_close(fp, false))
end)
- it('fails to open an existing file with kFileCreateOnly', function()
+ itp('fails to open an existing file with kFileCreateOnly', function()
local err, _ = file_open(file1, m.kFileCreateOnly, 384)
eq(m.UV_EEXIST, err)
end)
- it('fails to open an symlink with kFileNoSymlink', function()
+ itp('fails to open an symlink with kFileNoSymlink', function()
local err, _ = file_open(linkf, m.kFileNoSymlink, 384)
-- err is UV_EMLINK in FreeBSD, but if I use `ok(err == m.UV_ELOOP or err ==
-- m.UV_EMLINK)`, then I loose the ability to see actual `err` value.
if err ~= m.UV_ELOOP then eq(m.UV_EMLINK, err) end
end)
- it('can open an existing file write-only with kFileCreate', function()
+ itp('can open an existing file write-only with kFileCreate', function()
local err, fp = file_open(file1, m.kFileCreate, 384)
eq(0, err)
eq(true, fp.wr)
- eq(0, m.file_close(fp))
+ eq(0, m.file_close(fp, false))
end)
- it('can open an existing file read-only with zero', function()
+ itp('can open an existing file read-only with zero', function()
local err, fp = file_open(file1, 0, 384)
eq(0, err)
eq(false, fp.wr)
- eq(0, m.file_close(fp))
+ eq(0, m.file_close(fp, false))
end)
- it('can open an existing file read-only with kFileReadOnly', function()
+ itp('can open an existing file read-only with kFileReadOnly', function()
local err, fp = file_open(file1, m.kFileReadOnly, 384)
eq(0, err)
eq(false, fp.wr)
- eq(0, m.file_close(fp))
+ eq(0, m.file_close(fp, false))
end)
- it('can open an existing file read-only with kFileNoSymlink', function()
+ itp('can open an existing file read-only with kFileNoSymlink', function()
local err, fp = file_open(file1, m.kFileNoSymlink, 384)
eq(0, err)
eq(false, fp.wr)
- eq(0, m.file_close(fp))
+ eq(0, m.file_close(fp, false))
end)
- it('can truncate an existing file with kFileTruncate', function()
+ itp('can truncate an existing file with kFileTruncate', function()
local err, fp = file_open(file1, m.kFileTruncate, 384)
eq(0, err)
eq(true, fp.wr)
- eq(0, m.file_close(fp))
+ eq(0, m.file_close(fp, false))
local attrs = lfs.attributes(file1)
eq(0, attrs.size)
end)
- it('can open an existing file write-only with kFileWriteOnly', function()
+ itp('can open an existing file write-only with kFileWriteOnly', function()
local err, fp = file_open(file1, m.kFileWriteOnly, 384)
eq(0, err)
eq(true, fp.wr)
- eq(0, m.file_close(fp))
+ eq(0, m.file_close(fp, false))
local attrs = lfs.attributes(file1)
eq(4096, attrs.size)
end)
- it('fails to create a file with just kFileWriteOnly', function()
+ itp('fails to create a file with just kFileWriteOnly', function()
local err, _ = file_open(filec, m.kFileWriteOnly, 384)
eq(m.UV_ENOENT, err)
local attrs = lfs.attributes(filec)
eq(nil, attrs)
end)
- it('can truncate an existing file with kFileTruncate when opening a symlink',
+ itp('can truncate an existing file with kFileTruncate when opening a symlink',
function()
local err, fp = file_open(linkf, m.kFileTruncate, 384)
eq(0, err)
eq(true, fp.wr)
- eq(0, m.file_close(fp))
+ eq(0, m.file_close(fp, false))
local attrs = lfs.attributes(file1)
eq(0, attrs.size)
end)
- it('fails to open a directory write-only', function()
+ itp('fails to open a directory write-only', function()
local err, _ = file_open(dir, m.kFileWriteOnly, 384)
eq(m.UV_EISDIR, err)
end)
- it('fails to open a broken symbolic link write-only', function()
+ itp('fails to open a broken symbolic link write-only', function()
local err, _ = file_open(linkb, m.kFileWriteOnly, 384)
eq(m.UV_ENOENT, err)
end)
- it('fails to open a broken symbolic link read-only', function()
+ itp('fails to open a broken symbolic link read-only', function()
local err, _ = file_open(linkb, m.kFileReadOnly, 384)
eq(m.UV_ENOENT, err)
end)
end)
describe('file_open_new', function()
- it('can open a file read-only', function()
+ itp('can open a file read-only', function()
local err, fp = file_open_new(file1, 0, 384)
eq(0, err)
eq(false, fp.wr)
- eq(0, m.file_free(fp))
+ eq(0, m.file_free(fp, false))
end)
- it('fails to open an existing file with kFileCreateOnly', function()
+ itp('fails to open an existing file with kFileCreateOnly', function()
local err, fp = file_open_new(file1, m.kFileCreateOnly, 384)
eq(m.UV_EEXIST, err)
eq(nil, fp)
end)
end)
--- file_close is called above, so it is not tested directly
+describe('file_close', function()
+ itp('can flush writes to disk also with true argument', function()
+ local err, fp = file_open(filec, m.kFileCreateOnly, 384)
+ eq(0, err)
+ local wsize = file_write(fp, 'test')
+ eq(4, wsize)
+ eq(0, lfs.attributes(filec).size)
+ eq(0, m.file_close(fp, true))
+ eq(wsize, lfs.attributes(filec).size)
+ end)
+end)
+
+describe('file_free', function()
+ itp('can flush writes to disk also with true argument', function()
+ local err, fp = file_open_new(filec, m.kFileCreateOnly, 384)
+ eq(0, err)
+ local wsize = file_write(fp, 'test')
+ eq(4, wsize)
+ eq(0, lfs.attributes(filec).size)
+ eq(0, m.file_free(fp, true))
+ eq(wsize, lfs.attributes(filec).size)
+ end)
+end)
describe('file_fsync', function()
- it('can flush writes to disk', function()
+ itp('can flush writes to disk', function()
local err, fp = file_open(filec, m.kFileCreateOnly, 384)
eq(0, file_fsync(fp))
eq(0, err)
@@ -239,12 +324,27 @@ describe('file_fsync', function()
eq(0, lfs.attributes(filec).size)
eq(0, file_fsync(fp))
eq(wsize, lfs.attributes(filec).size)
- eq(0, m.file_close(fp))
+ eq(0, m.file_close(fp, false))
+ end)
+end)
+
+describe('file_flush', function()
+ itp('can flush writes to disk', function()
+ local err, fp = file_open(filec, m.kFileCreateOnly, 384)
+ eq(0, file_flush(fp))
+ eq(0, err)
+ eq(0, lfs.attributes(filec).size)
+ local wsize = file_write(fp, 'test')
+ eq(4, wsize)
+ eq(0, lfs.attributes(filec).size)
+ eq(0, file_flush(fp))
+ eq(wsize, lfs.attributes(filec).size)
+ eq(0, m.file_close(fp, false))
end)
end)
describe('file_read', function()
- it('can read small chunks of input until eof', function()
+ itp('can read small chunks of input until eof', function()
local err, fp = file_open(file1, 0, 384)
eq(0, err)
eq(false, fp.wr)
@@ -261,29 +361,29 @@ describe('file_read', function()
eq({exp_err, exp_s}, {file_read(fp, size)})
shift = shift + size
end
- eq(0, m.file_close(fp))
+ eq(0, m.file_close(fp, false))
end)
- it('can read the whole file at once', function()
+ itp('can read the whole file at once', function()
local err, fp = file_open(file1, 0, 384)
eq(0, err)
eq(false, fp.wr)
eq({#fcontents, fcontents}, {file_read(fp, #fcontents)})
eq({0, ('\0'):rep(#fcontents)}, {file_read(fp, #fcontents)})
- eq(0, m.file_close(fp))
+ eq(0, m.file_close(fp, false))
end)
- it('can read more then 1024 bytes after reading a small chunk', function()
+ itp('can read more then 1024 bytes after reading a small chunk', function()
local err, fp = file_open(file1, 0, 384)
eq(0, err)
eq(false, fp.wr)
eq({5, fcontents:sub(1, 5)}, {file_read(fp, 5)})
eq({#fcontents - 5, fcontents:sub(6) .. (('\0'):rep(5))},
{file_read(fp, #fcontents)})
- eq(0, m.file_close(fp))
+ eq(0, m.file_close(fp, false))
end)
- it('can read file by 768-byte-chunks', function()
+ itp('can read file by 768-byte-chunks', function()
local err, fp = file_open(file1, 0, 384)
eq(0, err)
eq(false, fp.wr)
@@ -300,23 +400,23 @@ describe('file_read', function()
eq({exp_err, exp_s}, {file_read(fp, size)})
shift = shift + size
end
- eq(0, m.file_close(fp))
+ eq(0, m.file_close(fp, false))
end)
end)
describe('file_write', function()
- it('can write the whole file at once', function()
+ itp('can write the whole file at once', function()
local err, fp = file_open(filec, m.kFileCreateOnly, 384)
eq(0, err)
eq(true, fp.wr)
local wr = file_write(fp, fcontents)
eq(#fcontents, wr)
- eq(0, m.file_close(fp))
+ eq(0, m.file_close(fp, false))
eq(wr, lfs.attributes(filec).size)
eq(fcontents, io.open(filec):read('*a'))
end)
- it('can write the whole file by small chunks', function()
+ itp('can write the whole file by small chunks', function()
local err, fp = file_open(filec, m.kFileCreateOnly, 384)
eq(0, err)
eq(true, fp.wr)
@@ -328,12 +428,12 @@ describe('file_write', function()
eq(wr, #s)
shift = shift + size
end
- eq(0, m.file_close(fp))
+ eq(0, m.file_close(fp, false))
eq(#fcontents, lfs.attributes(filec).size)
eq(fcontents, io.open(filec):read('*a'))
end)
- it('can write the whole file by 768-byte-chunks', function()
+ itp('can write the whole file by 768-byte-chunks', function()
local err, fp = file_open(filec, m.kFileCreateOnly, 384)
eq(0, err)
eq(true, fp.wr)
@@ -345,14 +445,26 @@ describe('file_write', function()
eq(wr, #s)
shift = shift + size
end
- eq(0, m.file_close(fp))
+ eq(0, m.file_close(fp, false))
eq(#fcontents, lfs.attributes(filec).size)
eq(fcontents, io.open(filec):read('*a'))
end)
end)
+describe('msgpack_file_write', function()
+ itp('can write the whole file at once', function()
+ local err, fp = file_open(filec, m.kFileCreateOnly, 384)
+ eq(0, err)
+ eq(true, fp.wr)
+ local wr = msgpack_file_write(fp, fcontents)
+ eq(0, wr)
+ eq(0, m.file_close(fp, false))
+ eq(fcontents, io.open(filec):read('*a'))
+ end)
+end)
+
describe('file_skip', function()
- it('can skip 3 bytes', function()
+ itp('can skip 3 bytes', function()
local err, fp = file_open(file1, 0, 384)
eq(0, err)
eq(false, fp.wr)
@@ -360,6 +472,6 @@ describe('file_skip', function()
local rd, s = file_read(fp, 3)
eq(3, rd)
eq(fcontents:sub(4, 6), s)
- eq(0, m.file_close(fp))
+ eq(0, m.file_close(fp, false))
end)
end)