diff options
Diffstat (limited to 'test/unit/os/fileio_spec.lua')
-rw-r--r-- | test/unit/os/fileio_spec.lua | 216 |
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) |