From 2ac5f1138b5c4c5540479e26ca9b9755cf7b784d Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 5 Jun 2016 13:40:37 +0300 Subject: unittests: Add os_close, os_read and os_readv tests --- test/unit/os/fs_spec.lua | 218 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 200 insertions(+), 18 deletions(-) (limited to 'test') diff --git a/test/unit/os/fs_spec.lua b/test/unit/os/fs_spec.lua index 857a5001f1..54f5a99902 100644 --- a/test/unit/os/fs_spec.lua +++ b/test/unit/os/fs_spec.lua @@ -17,6 +17,10 @@ local NULL = helpers.NULL local NODE_NORMAL = 0 local NODE_WRITABLE = 1 +local function ok(expr) + assert.is_true(expr) +end + cimport('unistd.h') cimport('./src/nvim/os/shell.h') cimport('./src/nvim/option_defs.h') @@ -150,11 +154,11 @@ describe('fs function', function() local function os_can_exe(name) local buf = ffi.new('char *[1]') buf[0] = NULL - local ok = fs.os_can_exe(to_cstr(name), buf, true) + local ce_ret = fs.os_can_exe(to_cstr(name), buf, true) -- When os_can_exe returns true, it must set the path. -- When it returns false, the path must be NULL. - if ok then + if ce_ret then neq(NULL, buf[0]) return internalize(buf[0]) else @@ -368,6 +372,44 @@ describe('fs function', function() local function os_open(path, flags, mode) return fs.os_open((to_cstr(path)), flags, mode) end + local function os_close(fd) + return fs.os_close(fd) + end + local function os_read(fd, size) + local buf = nil + if size == nil then + size = 0 + else + buf = ffi.new('char[?]', size, ('\0'):rep(size)) + end + local eof = ffi.new('bool[?]', 1, {true}) + local ret2 = fs.os_read(fd, eof, buf, size) + local ret1 = eof[0] + local ret3 = '' + if buf ~= nil then + ret3 = ffi.string(buf, size) + end + return ret1, ret2, ret3 + end + local function os_readv(fd, sizes) + local bufs = {} + for i, size in ipairs(sizes) do + bufs[i] = { + iov_base=ffi.new('char[?]', size, ('\0'):rep(size)), + iov_len=size, + } + end + local iov = ffi.new('struct iovec[?]', #sizes, bufs) + local eof = ffi.new('bool[?]', 1, {true}) + local ret2 = fs.os_readv(fd, eof, iov, #sizes) + local ret1 = eof[0] + local ret3 = {} + for i = 1,#sizes do + -- Warning: iov may not be used. + ret3[i] = ffi.string(bufs[i].iov_base, bufs[i].iov_len) + end + return ret1, ret2, ret3 + end describe('os_file_exists', function() it('returns false when given a non-existing file', function() @@ -432,30 +474,34 @@ describe('fs function', function() end) describe('os_open', function() + local new_file = 'test_new_file' + local existing_file = 'unit-test-directory/test_existing.file' + before_each(function() - io.open('unit-test-directory/test_existing.file', 'w').close() + (io.open(existing_file, 'w')):close() end) after_each(function() - os.remove('unit-test-directory/test_existing.file') - os.remove('test_new_file') + os.remove(existing_file) + os.remove(new_file) end) - local new_file = 'test_new_file' - local existing_file = 'unit-test-directory/test_existing.file' - it('returns UV_ENOENT for O_RDWR on a non-existing file', function() eq(ffi.C.UV_ENOENT, (os_open('non-existing-file', ffi.C.kO_RDWR, 0))) end) - it('returns non-negative for O_CREAT on a non-existing file', function() + it('returns non-negative for O_CREAT on a non-existing file which then can be closed', function() assert_file_does_not_exist(new_file) - assert.is_true(0 <= (os_open(new_file, ffi.C.kO_CREAT, 0))) + local fd = os_open(new_file, ffi.C.kO_CREAT, 0) + assert.is_true(0 <= fd) + eq(0, os_close(fd)) end) - it('returns non-negative for O_CREAT on a existing file', function() + it('returns non-negative for O_CREAT on a existing file which then can be closed', function() assert_file_exists(existing_file) - assert.is_true(0 <= (os_open(existing_file, ffi.C.kO_CREAT, 0))) + local fd = os_open(existing_file, ffi.C.kO_CREAT, 0) + assert.is_true(0 <= fd) + eq(0, os_close(fd)) end) it('returns UV_EEXIST for O_CREAT|O_EXCL on a existing file', function() @@ -463,24 +509,160 @@ describe('fs function', function() eq(ffi.C.kUV_EEXIST, (os_open(existing_file, (bit.bor(ffi.C.kO_CREAT, ffi.C.kO_EXCL)), 0))) end) - it('sets `rwx` permissions for O_CREAT 700', function() + it('sets `rwx` permissions for O_CREAT 700 which then can be closed', function() assert_file_does_not_exist(new_file) --create the file - os_open(new_file, ffi.C.kO_CREAT, tonumber("700", 8)) + local fd = os_open(new_file, ffi.C.kO_CREAT, tonumber("700", 8)) --verify permissions eq('rwx------', lfs.attributes(new_file)['permissions']) + eq(0, os_close(fd)) end) - it('sets `rw` permissions for O_CREAT 600', function() + it('sets `rw` permissions for O_CREAT 600 which then can be closed', function() assert_file_does_not_exist(new_file) --create the file - os_open(new_file, ffi.C.kO_CREAT, tonumber("600", 8)) + local fd = os_open(new_file, ffi.C.kO_CREAT, tonumber("600", 8)) --verify permissions eq('rw-------', lfs.attributes(new_file)['permissions']) + eq(0, os_close(fd)) + end) + + it('returns a non-negative file descriptor for an existing file which then can be closed', function() + local fd = os_open(existing_file, ffi.C.kO_RDWR, 0) + assert.is_true(0 <= fd) + eq(0, os_close(fd)) + end) + end) + + describe('os_close', function() + it('returns EBADF for negative file descriptors', function() + eq(ffi.C.UV_EBADF, os_close(-1)) + eq(ffi.C.UV_EBADF, os_close(-1000)) + end) + end) + + describe('os_read', function() + local file = 'test-unit-os-fs_spec-os_read.dat' + + local s = '' + for i = 0, 255 do + s = s .. (i == 0 and '\0' or ('%c'):format(i)) + end + local fcontents = s:rep(16) + + before_each(function() + local f = io.open(file, 'w') + f:write(fcontents) + f:close() + end) + + after_each(function() + os.remove(file) + end) + + it('can read zero bytes from a file', function() + local fd = os_open(file, ffi.C.kO_RDONLY, 0) + ok(fd >= 0) + eq({false, 0, ''}, {os_read(fd, nil)}) + eq({false, 0, ''}, {os_read(fd, 0)}) + eq(0, os_close(fd)) + end) + + it('can read from a file multiple times', function() + local fd = os_open(file, ffi.C.kO_RDONLY, 0) + ok(fd >= 0) + eq({false, 2, '\000\001'}, {os_read(fd, 2)}) + eq({false, 2, '\002\003'}, {os_read(fd, 2)}) + eq(0, os_close(fd)) + end) + + it('can read the whole file at once and then report eof', function() + local fd = os_open(file, ffi.C.kO_RDONLY, 0) + ok(fd >= 0) + eq({false, #fcontents, fcontents}, {os_read(fd, #fcontents)}) + eq({true, 0, ('\0'):rep(#fcontents)}, {os_read(fd, #fcontents)}) + eq(0, os_close(fd)) + end) + + it('can read the whole file in two calls, one partially', function() + local fd = os_open(file, ffi.C.kO_RDONLY, 0) + ok(fd >= 0) + eq({false, #fcontents * 3/4, fcontents:sub(1, #fcontents * 3/4)}, + {os_read(fd, #fcontents * 3/4)}) + eq({true, + (#fcontents * 1/4), + fcontents:sub(#fcontents * 3/4 + 1) .. ('\0'):rep(#fcontents * 2/4)}, + {os_read(fd, #fcontents * 3/4)}) + eq(0, os_close(fd)) + end) + end) + + describe('os_readv', function() + -- Function may be absent + if not pcall(function() return fs.os_readv end) then + return + end + local file = 'test-unit-os-fs_spec-os_readv.dat' + + local s = '' + for i = 0, 255 do + s = s .. (i == 0 and '\0' or ('%c'):format(i)) + end + local fcontents = s:rep(16) + + before_each(function() + local f = io.open(file, 'w') + f:write(fcontents) + f:close() end) - it('returns a non-negative file descriptor for an existing file', function() - assert.is_true(0 <= (os_open(existing_file, ffi.C.kO_RDWR, 0))) + after_each(function() + os.remove(file) + end) + + it('can read zero bytes from a file', function() + local fd = os_open(file, ffi.C.kO_RDONLY, 0) + ok(fd >= 0) + eq({false, 0, {}}, {os_readv(fd, {})}) + eq({false, 0, {'', '', ''}}, {os_readv(fd, {0, 0, 0})}) + eq(0, os_close(fd)) + end) + + it('can read from a file multiple times to a differently-sized buffers', function() + local fd = os_open(file, ffi.C.kO_RDONLY, 0) + ok(fd >= 0) + eq({false, 2, {'\000\001'}}, {os_readv(fd, {2})}) + eq({false, 5, {'\002\003', '\004\005\006'}}, {os_readv(fd, {2, 3})}) + eq(0, os_close(fd)) + end) + + it('can read the whole file at once and then report eof', function() + local fd = os_open(file, ffi.C.kO_RDONLY, 0) + ok(fd >= 0) + eq({false, + #fcontents, + {fcontents:sub(1, #fcontents * 1/4), + fcontents:sub(#fcontents * 1/4 + 1, #fcontents * 3/4), + fcontents:sub(#fcontents * 3/4 + 1, #fcontents * 15/16), + fcontents:sub(#fcontents * 15/16 + 1, #fcontents)}}, + {os_readv(fd, {#fcontents * 1/4, + #fcontents * 2/4, + #fcontents * 3/16, + #fcontents * 1/16})}) + eq({true, 0, {'\0'}}, {os_readv(fd, {1})}) + eq(0, os_close(fd)) + end) + + it('can read the whole file in two calls, one partially', function() + local fd = os_open(file, ffi.C.kO_RDONLY, 0) + ok(fd >= 0) + eq({false, #fcontents * 3/4, {fcontents:sub(1, #fcontents * 3/4)}}, + {os_readv(fd, {#fcontents * 3/4})}) + eq({true, + (#fcontents * 1/4), + {fcontents:sub(#fcontents * 3/4 + 1) .. ('\0'):rep(#fcontents * 2/4)}}, + {os_readv(fd, {#fcontents * 3/4})}) + eq(0, os_close(fd)) end) end) -- cgit From 3e7c8e714915672a032eef2950b25264a3c91c58 Mon Sep 17 00:00:00 2001 From: ZyX Date: Tue, 21 Jun 2016 22:51:40 +0300 Subject: unittests: Add os_write test New os/fs.c functions are now all tested. --- test/unit/os/fs_spec.lua | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'test') diff --git a/test/unit/os/fs_spec.lua b/test/unit/os/fs_spec.lua index 54f5a99902..d7e98b43ce 100644 --- a/test/unit/os/fs_spec.lua +++ b/test/unit/os/fs_spec.lua @@ -410,6 +410,9 @@ describe('fs function', function() end return ret1, ret2, ret3 end + local function os_write(fd, data) + return fs.os_write(fd, data, data and #data or 0) + end describe('os_file_exists', function() it('returns false when given a non-existing file', function() @@ -666,6 +669,45 @@ describe('fs function', function() end) end) + describe('os_write', function() + -- Function may be absent + local file = 'test-unit-os-fs_spec-os_write.dat' + + local s = '' + for i = 0, 255 do + s = s .. (i == 0 and '\0' or ('%c'):format(i)) + end + local fcontents = s:rep(16) + + before_each(function() + local f = io.open(file, 'w') + f:write(fcontents) + f:close() + end) + + after_each(function() + os.remove(file) + end) + + it('can write zero bytes to a file', function() + local fd = os_open(file, ffi.C.kO_WRONLY, 0) + ok(fd >= 0) + eq(0, os_write(fd, '')) + eq(0, os_write(fd, nil)) + eq(fcontents, io.open(file, 'r'):read('*a')) + eq(0, os_close(fd)) + end) + + it('can write some data to a file', function() + local fd = os_open(file, ffi.C.kO_WRONLY, 0) + ok(fd >= 0) + eq(3, os_write(fd, 'abc')) + eq(4, os_write(fd, ' def')) + eq('abc def' .. fcontents:sub(8), io.open(file, 'r'):read('*a')) + eq(0, os_close(fd)) + end) + end) + describe('os_nodetype', function() before_each(function() os.remove('non-existing-file') -- cgit From fec7983ecd7ac58f4f8ad9f8b4dc8f6937b87099 Mon Sep 17 00:00:00 2001 From: ZyX Date: Wed, 22 Jun 2016 01:01:21 +0300 Subject: unittests: Add tests for file.c Also fixes some errors found. --- test/unit/file_spec.lua | 361 +++++++++++++++++++++++++++++++++++++++++++++++ test/unit/helpers.lua | 5 +- test/unit/os/fs_spec.lua | 29 +--- 3 files changed, 372 insertions(+), 23 deletions(-) create mode 100644 test/unit/file_spec.lua (limited to 'test') diff --git a/test/unit/file_spec.lua b/test/unit/file_spec.lua new file mode 100644 index 0000000000..ac78dffe6e --- /dev/null +++ b/test/unit/file_spec.lua @@ -0,0 +1,361 @@ +local lfs = require('lfs') + +local helpers = require('test.unit.helpers') + +local eq = helpers.eq +local ok = helpers.ok +local ffi = helpers.ffi +local cimport = helpers.cimport + +local m = cimport('./src/nvim/file.h') + +local s = '' +for i = 0, 255 do + s = s .. (i == 0 and '\0' or ('%c'):format(i)) +end +local fcontents = s:rep(16) + +local dir = 'Xtest-unit-file_spec.d' +local file1 = dir .. '/file1.dat' +local file2 = dir .. '/file2.dat' +local linkf = dir .. '/file.lnk' +local linkb = dir .. '/broken.lnk' +local filec = dir .. '/created-file.dat' + +before_each(function() + lfs.mkdir(dir); + + local f1 = io.open(file1, 'w') + f1:write(fcontents) + f1:close() + + local f2 = io.open(file2, 'w') + f2:write(fcontents) + f2:close() + + lfs.link('file1.dat', linkf, true) + lfs.link('broken.dat', linkb, true) +end) + +after_each(function() + os.remove(file1) + os.remove(file2) + os.remove(linkf) + os.remove(linkb) + os.remove(filec) + lfs.rmdir(dir) +end) + +local function file_open(fname, flags, mode) + local ret2 = ffi.new('FileDescriptor') + local ret1 = m.file_open(ret2, fname, flags, mode) + return ret1, ret2 +end + +local function file_open_new(fname, flags, mode) + local ret1 = ffi.new('int[?]', 1, {0}) + local ret2 = ffi.gc(m.file_open_new(ret1, fname, flags, mode), nil) + return ret1[0], ret2 +end + +local function file_write(fp, buf) + return m.file_write(fp, buf, #buf) +end + +local function file_read(fp, size) + local buf = nil + if size == nil then + size = 0 + else + buf = ffi.new('char[?]', size, ('\0'):rep(size)) + end + local ret1 = m.file_read(fp, buf, size) + local ret2 = '' + if buf ~= nil then + ret2 = ffi.string(buf, size) + end + return ret1, ret2 +end + +local function file_fsync(fp) + return m.file_fsync(fp) +end + +local function file_skip(fp, size) + return m.file_skip(fp, size) +end + +describe('file_open', function() + it('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)) + end) + + it('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)) + end) + + it('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)) + end) + + it('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)) + end) + + it('fails to open an existing file with kFileCreateOnly', function() + local err, fp = file_open(file1, m.kFileCreateOnly, 384) + eq(m.UV_EEXIST, err) + end) + + it('fails to open an symlink with kFileNoSymlink', function() + local err, fp = file_open(linkf, m.kFileNoSymlink, 384) + eq(m.UV_ELOOP, err) + end) + + it('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)) + end) + + it('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)) + end) + + it('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)) + end) + + it('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)) + end) + + it('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)) + local attrs = lfs.attributes(file1) + eq(0, attrs.size) + end) + + it('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)) + local attrs = lfs.attributes(file1) + eq(4096, attrs.size) + end) + + it('fails to create a file with just kFileWriteOnly', function() + local err, fp = 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', + function() + local err, fp = file_open(linkf, m.kFileTruncate, 384) + eq(0, err) + eq(true, fp.wr) + eq(0, m.file_close(fp)) + local attrs = lfs.attributes(file1) + eq(0, attrs.size) + end) + + it('fails to open a directory write-only', function() + local err, fp = file_open(dir, m.kFileWriteOnly, 384) + eq(m.UV_EISDIR, err) + end) + + it('fails to open a broken symbolic link write-only', function() + local err, fp = file_open(linkb, m.kFileWriteOnly, 384) + eq(m.UV_ENOENT, err) + end) + + it('fails to open a broken symbolic link read-only', function() + local err, fp = 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() + local err, fp = file_open_new(file1, 0, 384) + eq(0, err) + eq(false, fp.wr) + eq(0, m.file_free(fp)) + end) + + it('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_fsync', function() + it('can flush writes to disk', function() + local err, fp = file_open(filec, m.kFileCreateOnly, 384) + eq(0, file_fsync(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_fsync(fp)) + eq(wsize, lfs.attributes(filec).size) + eq(0, m.file_close(fp)) + end) +end) + +describe('file_read', function() + it('can read small chunks of input until eof', function() + local err, fp = file_open(file1, 0, 384) + eq(0, err) + eq(false, fp.wr) + local shift = 0 + while shift < #fcontents do + local size = 3 + local exp_err = size + local exp_s = fcontents:sub(shift + 1, shift + size) + if shift + size >= #fcontents then + exp_err = #fcontents - shift + exp_s = (fcontents:sub(shift + 1, shift + size) + .. (('\0'):rep(size - exp_err))) + end + eq({exp_err, exp_s}, {file_read(fp, size)}) + shift = shift + size + end + eq(0, m.file_close(fp)) + end) + + it('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)) + end) + + it('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)) + end) + + it('can read file by 768-byte-chunks', function() + local err, fp = file_open(file1, 0, 384) + eq(0, err) + eq(false, fp.wr) + local shift = 0 + while shift < #fcontents do + local size = 768 + local exp_err = size + local exp_s = fcontents:sub(shift + 1, shift + size) + if shift + size >= #fcontents then + exp_err = #fcontents - shift + exp_s = (fcontents:sub(shift + 1, shift + size) + .. (('\0'):rep(size - exp_err))) + end + eq({exp_err, exp_s}, {file_read(fp, size)}) + shift = shift + size + end + eq(0, m.file_close(fp)) + end) +end) + +describe('file_write', function() + it('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 err = file_write(fp, fcontents) + eq(#fcontents, err) + eq(0, m.file_close(fp)) + eq(err, lfs.attributes(filec).size) + eq(fcontents, io.open(filec):read('*a')) + end) + + it('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) + local shift = 0 + while shift < #fcontents do + local size = 3 + local s = fcontents:sub(shift + 1, shift + size) + local err = file_write(fp, s) + eq(err, #s) + shift = shift + size + end + eq(0, m.file_close(fp)) + 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() + local err, fp = file_open(filec, m.kFileCreateOnly, 384) + eq(0, err) + eq(true, fp.wr) + local shift = 0 + while shift < #fcontents do + local size = 768 + local s = fcontents:sub(shift + 1, shift + size) + local err = file_write(fp, s) + eq(err, #s) + shift = shift + size + end + eq(0, m.file_close(fp)) + eq(#fcontents, lfs.attributes(filec).size) + eq(fcontents, io.open(filec):read('*a')) + end) +end) + +describe('file_skip', function() + it('can skip 3 bytes', function() + local err, fp = file_open(file1, 0, 384) + eq(0, err) + eq(false, fp.wr) + eq(3, file_skip(fp, 3)) + local err, s = file_read(fp, 3) + eq(3, err) + eq(fcontents:sub(4, 6), s) + eq(0, m.file_close(fp)) + end) +end) diff --git a/test/unit/helpers.lua b/test/unit/helpers.lua index f0c193884e..91da459393 100644 --- a/test/unit/helpers.lua +++ b/test/unit/helpers.lua @@ -7,6 +7,7 @@ local global_helpers = require('test.helpers') local neq = global_helpers.neq local eq = global_helpers.eq +local ok = global_helpers.ok -- add some standard header locations for _, p in ipairs(Paths.include_paths) do @@ -34,7 +35,8 @@ local function filter_complex_blocks(body) if not (string.find(line, "(^)", 1, true) ~= nil or string.find(line, "_ISwupper", 1, true) or string.find(line, "msgpack_zone_push_finalizer") - or string.find(line, "msgpack_unpacker_reserve_buffer")) then + or string.find(line, "msgpack_unpacker_reserve_buffer") + or string.find(line, "inline _Bool")) then result[#result + 1] = line end end @@ -156,6 +158,7 @@ return { cimport = cimport, cppimport = cppimport, internalize = internalize, + ok = ok, eq = eq, neq = neq, ffi = ffi, diff --git a/test/unit/os/fs_spec.lua b/test/unit/os/fs_spec.lua index d7e98b43ce..1f7f6fb791 100644 --- a/test/unit/os/fs_spec.lua +++ b/test/unit/os/fs_spec.lua @@ -6,6 +6,7 @@ local helpers = require('test.unit.helpers') local cimport = helpers.cimport local cppimport = helpers.cppimport local internalize = helpers.internalize +local ok = helpers.ok local eq = helpers.eq local neq = helpers.neq local ffi = helpers.ffi @@ -17,10 +18,6 @@ local NULL = helpers.NULL local NODE_NORMAL = 0 local NODE_WRITABLE = 1 -local function ok(expr) - assert.is_true(expr) -end - cimport('unistd.h') cimport('./src/nvim/os/shell.h') cimport('./src/nvim/option_defs.h') @@ -31,6 +28,12 @@ cppimport('sys/stat.h') cppimport('fcntl.h') cppimport('uv-errno.h') +local s = '' +for i = 0, 255 do + s = s .. (i == 0 and '\0' or ('%c'):format(i)) +end +local fcontents = s:rep(16) + local buffer = "" local directory = nil local absolute_executable = nil @@ -547,12 +550,6 @@ describe('fs function', function() describe('os_read', function() local file = 'test-unit-os-fs_spec-os_read.dat' - local s = '' - for i = 0, 255 do - s = s .. (i == 0 and '\0' or ('%c'):format(i)) - end - local fcontents = s:rep(16) - before_each(function() local f = io.open(file, 'w') f:write(fcontents) @@ -607,12 +604,6 @@ describe('fs function', function() end local file = 'test-unit-os-fs_spec-os_readv.dat' - local s = '' - for i = 0, 255 do - s = s .. (i == 0 and '\0' or ('%c'):format(i)) - end - local fcontents = s:rep(16) - before_each(function() local f = io.open(file, 'w') f:write(fcontents) @@ -673,12 +664,6 @@ describe('fs function', function() -- Function may be absent local file = 'test-unit-os-fs_spec-os_write.dat' - local s = '' - for i = 0, 255 do - s = s .. (i == 0 and '\0' or ('%c'):format(i)) - end - local fcontents = s:rep(16) - before_each(function() local f = io.open(file, 'w') f:write(fcontents) -- cgit From 2dd154457ceb4bbc122b9e1ad34bf693ee3dd510 Mon Sep 17 00:00:00 2001 From: ZyX Date: Thu, 23 Jun 2016 21:17:24 +0300 Subject: file: Move src/nvim/file.* to src/nvim/os/fileio.* --- test/unit/file_spec.lua | 361 ------------------------------------------- test/unit/os/fileio_spec.lua | 361 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 361 insertions(+), 361 deletions(-) delete mode 100644 test/unit/file_spec.lua create mode 100644 test/unit/os/fileio_spec.lua (limited to 'test') diff --git a/test/unit/file_spec.lua b/test/unit/file_spec.lua deleted file mode 100644 index ac78dffe6e..0000000000 --- a/test/unit/file_spec.lua +++ /dev/null @@ -1,361 +0,0 @@ -local lfs = require('lfs') - -local helpers = require('test.unit.helpers') - -local eq = helpers.eq -local ok = helpers.ok -local ffi = helpers.ffi -local cimport = helpers.cimport - -local m = cimport('./src/nvim/file.h') - -local s = '' -for i = 0, 255 do - s = s .. (i == 0 and '\0' or ('%c'):format(i)) -end -local fcontents = s:rep(16) - -local dir = 'Xtest-unit-file_spec.d' -local file1 = dir .. '/file1.dat' -local file2 = dir .. '/file2.dat' -local linkf = dir .. '/file.lnk' -local linkb = dir .. '/broken.lnk' -local filec = dir .. '/created-file.dat' - -before_each(function() - lfs.mkdir(dir); - - local f1 = io.open(file1, 'w') - f1:write(fcontents) - f1:close() - - local f2 = io.open(file2, 'w') - f2:write(fcontents) - f2:close() - - lfs.link('file1.dat', linkf, true) - lfs.link('broken.dat', linkb, true) -end) - -after_each(function() - os.remove(file1) - os.remove(file2) - os.remove(linkf) - os.remove(linkb) - os.remove(filec) - lfs.rmdir(dir) -end) - -local function file_open(fname, flags, mode) - local ret2 = ffi.new('FileDescriptor') - local ret1 = m.file_open(ret2, fname, flags, mode) - return ret1, ret2 -end - -local function file_open_new(fname, flags, mode) - local ret1 = ffi.new('int[?]', 1, {0}) - local ret2 = ffi.gc(m.file_open_new(ret1, fname, flags, mode), nil) - return ret1[0], ret2 -end - -local function file_write(fp, buf) - return m.file_write(fp, buf, #buf) -end - -local function file_read(fp, size) - local buf = nil - if size == nil then - size = 0 - else - buf = ffi.new('char[?]', size, ('\0'):rep(size)) - end - local ret1 = m.file_read(fp, buf, size) - local ret2 = '' - if buf ~= nil then - ret2 = ffi.string(buf, size) - end - return ret1, ret2 -end - -local function file_fsync(fp) - return m.file_fsync(fp) -end - -local function file_skip(fp, size) - return m.file_skip(fp, size) -end - -describe('file_open', function() - it('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)) - end) - - it('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)) - end) - - it('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)) - end) - - it('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)) - end) - - it('fails to open an existing file with kFileCreateOnly', function() - local err, fp = file_open(file1, m.kFileCreateOnly, 384) - eq(m.UV_EEXIST, err) - end) - - it('fails to open an symlink with kFileNoSymlink', function() - local err, fp = file_open(linkf, m.kFileNoSymlink, 384) - eq(m.UV_ELOOP, err) - end) - - it('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)) - end) - - it('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)) - end) - - it('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)) - end) - - it('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)) - end) - - it('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)) - local attrs = lfs.attributes(file1) - eq(0, attrs.size) - end) - - it('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)) - local attrs = lfs.attributes(file1) - eq(4096, attrs.size) - end) - - it('fails to create a file with just kFileWriteOnly', function() - local err, fp = 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', - function() - local err, fp = file_open(linkf, m.kFileTruncate, 384) - eq(0, err) - eq(true, fp.wr) - eq(0, m.file_close(fp)) - local attrs = lfs.attributes(file1) - eq(0, attrs.size) - end) - - it('fails to open a directory write-only', function() - local err, fp = file_open(dir, m.kFileWriteOnly, 384) - eq(m.UV_EISDIR, err) - end) - - it('fails to open a broken symbolic link write-only', function() - local err, fp = file_open(linkb, m.kFileWriteOnly, 384) - eq(m.UV_ENOENT, err) - end) - - it('fails to open a broken symbolic link read-only', function() - local err, fp = 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() - local err, fp = file_open_new(file1, 0, 384) - eq(0, err) - eq(false, fp.wr) - eq(0, m.file_free(fp)) - end) - - it('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_fsync', function() - it('can flush writes to disk', function() - local err, fp = file_open(filec, m.kFileCreateOnly, 384) - eq(0, file_fsync(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_fsync(fp)) - eq(wsize, lfs.attributes(filec).size) - eq(0, m.file_close(fp)) - end) -end) - -describe('file_read', function() - it('can read small chunks of input until eof', function() - local err, fp = file_open(file1, 0, 384) - eq(0, err) - eq(false, fp.wr) - local shift = 0 - while shift < #fcontents do - local size = 3 - local exp_err = size - local exp_s = fcontents:sub(shift + 1, shift + size) - if shift + size >= #fcontents then - exp_err = #fcontents - shift - exp_s = (fcontents:sub(shift + 1, shift + size) - .. (('\0'):rep(size - exp_err))) - end - eq({exp_err, exp_s}, {file_read(fp, size)}) - shift = shift + size - end - eq(0, m.file_close(fp)) - end) - - it('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)) - end) - - it('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)) - end) - - it('can read file by 768-byte-chunks', function() - local err, fp = file_open(file1, 0, 384) - eq(0, err) - eq(false, fp.wr) - local shift = 0 - while shift < #fcontents do - local size = 768 - local exp_err = size - local exp_s = fcontents:sub(shift + 1, shift + size) - if shift + size >= #fcontents then - exp_err = #fcontents - shift - exp_s = (fcontents:sub(shift + 1, shift + size) - .. (('\0'):rep(size - exp_err))) - end - eq({exp_err, exp_s}, {file_read(fp, size)}) - shift = shift + size - end - eq(0, m.file_close(fp)) - end) -end) - -describe('file_write', function() - it('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 err = file_write(fp, fcontents) - eq(#fcontents, err) - eq(0, m.file_close(fp)) - eq(err, lfs.attributes(filec).size) - eq(fcontents, io.open(filec):read('*a')) - end) - - it('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) - local shift = 0 - while shift < #fcontents do - local size = 3 - local s = fcontents:sub(shift + 1, shift + size) - local err = file_write(fp, s) - eq(err, #s) - shift = shift + size - end - eq(0, m.file_close(fp)) - 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() - local err, fp = file_open(filec, m.kFileCreateOnly, 384) - eq(0, err) - eq(true, fp.wr) - local shift = 0 - while shift < #fcontents do - local size = 768 - local s = fcontents:sub(shift + 1, shift + size) - local err = file_write(fp, s) - eq(err, #s) - shift = shift + size - end - eq(0, m.file_close(fp)) - eq(#fcontents, lfs.attributes(filec).size) - eq(fcontents, io.open(filec):read('*a')) - end) -end) - -describe('file_skip', function() - it('can skip 3 bytes', function() - local err, fp = file_open(file1, 0, 384) - eq(0, err) - eq(false, fp.wr) - eq(3, file_skip(fp, 3)) - local err, s = file_read(fp, 3) - eq(3, err) - eq(fcontents:sub(4, 6), s) - eq(0, m.file_close(fp)) - end) -end) diff --git a/test/unit/os/fileio_spec.lua b/test/unit/os/fileio_spec.lua new file mode 100644 index 0000000000..22b61786c0 --- /dev/null +++ b/test/unit/os/fileio_spec.lua @@ -0,0 +1,361 @@ +local lfs = require('lfs') + +local helpers = require('test.unit.helpers') + +local eq = helpers.eq +local ok = helpers.ok +local ffi = helpers.ffi +local cimport = helpers.cimport + +local m = cimport('./src/nvim/os/fileio.h') + +local s = '' +for i = 0, 255 do + s = s .. (i == 0 and '\0' or ('%c'):format(i)) +end +local fcontents = s:rep(16) + +local dir = 'Xtest-unit-file_spec.d' +local file1 = dir .. '/file1.dat' +local file2 = dir .. '/file2.dat' +local linkf = dir .. '/file.lnk' +local linkb = dir .. '/broken.lnk' +local filec = dir .. '/created-file.dat' + +before_each(function() + lfs.mkdir(dir); + + local f1 = io.open(file1, 'w') + f1:write(fcontents) + f1:close() + + local f2 = io.open(file2, 'w') + f2:write(fcontents) + f2:close() + + lfs.link('file1.dat', linkf, true) + lfs.link('broken.dat', linkb, true) +end) + +after_each(function() + os.remove(file1) + os.remove(file2) + os.remove(linkf) + os.remove(linkb) + os.remove(filec) + lfs.rmdir(dir) +end) + +local function file_open(fname, flags, mode) + local ret2 = ffi.new('FileDescriptor') + local ret1 = m.file_open(ret2, fname, flags, mode) + return ret1, ret2 +end + +local function file_open_new(fname, flags, mode) + local ret1 = ffi.new('int[?]', 1, {0}) + local ret2 = ffi.gc(m.file_open_new(ret1, fname, flags, mode), nil) + return ret1[0], ret2 +end + +local function file_write(fp, buf) + return m.file_write(fp, buf, #buf) +end + +local function file_read(fp, size) + local buf = nil + if size == nil then + size = 0 + else + buf = ffi.new('char[?]', size, ('\0'):rep(size)) + end + local ret1 = m.file_read(fp, buf, size) + local ret2 = '' + if buf ~= nil then + ret2 = ffi.string(buf, size) + end + return ret1, ret2 +end + +local function file_fsync(fp) + return m.file_fsync(fp) +end + +local function file_skip(fp, size) + return m.file_skip(fp, size) +end + +describe('file_open', function() + it('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)) + end) + + it('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)) + end) + + it('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)) + end) + + it('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)) + end) + + it('fails to open an existing file with kFileCreateOnly', function() + local err, fp = file_open(file1, m.kFileCreateOnly, 384) + eq(m.UV_EEXIST, err) + end) + + it('fails to open an symlink with kFileNoSymlink', function() + local err, fp = file_open(linkf, m.kFileNoSymlink, 384) + eq(m.UV_ELOOP, err) + end) + + it('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)) + end) + + it('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)) + end) + + it('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)) + end) + + it('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)) + end) + + it('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)) + local attrs = lfs.attributes(file1) + eq(0, attrs.size) + end) + + it('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)) + local attrs = lfs.attributes(file1) + eq(4096, attrs.size) + end) + + it('fails to create a file with just kFileWriteOnly', function() + local err, fp = 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', + function() + local err, fp = file_open(linkf, m.kFileTruncate, 384) + eq(0, err) + eq(true, fp.wr) + eq(0, m.file_close(fp)) + local attrs = lfs.attributes(file1) + eq(0, attrs.size) + end) + + it('fails to open a directory write-only', function() + local err, fp = file_open(dir, m.kFileWriteOnly, 384) + eq(m.UV_EISDIR, err) + end) + + it('fails to open a broken symbolic link write-only', function() + local err, fp = file_open(linkb, m.kFileWriteOnly, 384) + eq(m.UV_ENOENT, err) + end) + + it('fails to open a broken symbolic link read-only', function() + local err, fp = 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() + local err, fp = file_open_new(file1, 0, 384) + eq(0, err) + eq(false, fp.wr) + eq(0, m.file_free(fp)) + end) + + it('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_fsync', function() + it('can flush writes to disk', function() + local err, fp = file_open(filec, m.kFileCreateOnly, 384) + eq(0, file_fsync(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_fsync(fp)) + eq(wsize, lfs.attributes(filec).size) + eq(0, m.file_close(fp)) + end) +end) + +describe('file_read', function() + it('can read small chunks of input until eof', function() + local err, fp = file_open(file1, 0, 384) + eq(0, err) + eq(false, fp.wr) + local shift = 0 + while shift < #fcontents do + local size = 3 + local exp_err = size + local exp_s = fcontents:sub(shift + 1, shift + size) + if shift + size >= #fcontents then + exp_err = #fcontents - shift + exp_s = (fcontents:sub(shift + 1, shift + size) + .. (('\0'):rep(size - exp_err))) + end + eq({exp_err, exp_s}, {file_read(fp, size)}) + shift = shift + size + end + eq(0, m.file_close(fp)) + end) + + it('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)) + end) + + it('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)) + end) + + it('can read file by 768-byte-chunks', function() + local err, fp = file_open(file1, 0, 384) + eq(0, err) + eq(false, fp.wr) + local shift = 0 + while shift < #fcontents do + local size = 768 + local exp_err = size + local exp_s = fcontents:sub(shift + 1, shift + size) + if shift + size >= #fcontents then + exp_err = #fcontents - shift + exp_s = (fcontents:sub(shift + 1, shift + size) + .. (('\0'):rep(size - exp_err))) + end + eq({exp_err, exp_s}, {file_read(fp, size)}) + shift = shift + size + end + eq(0, m.file_close(fp)) + end) +end) + +describe('file_write', function() + it('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 err = file_write(fp, fcontents) + eq(#fcontents, err) + eq(0, m.file_close(fp)) + eq(err, lfs.attributes(filec).size) + eq(fcontents, io.open(filec):read('*a')) + end) + + it('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) + local shift = 0 + while shift < #fcontents do + local size = 3 + local s = fcontents:sub(shift + 1, shift + size) + local err = file_write(fp, s) + eq(err, #s) + shift = shift + size + end + eq(0, m.file_close(fp)) + 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() + local err, fp = file_open(filec, m.kFileCreateOnly, 384) + eq(0, err) + eq(true, fp.wr) + local shift = 0 + while shift < #fcontents do + local size = 768 + local s = fcontents:sub(shift + 1, shift + size) + local err = file_write(fp, s) + eq(err, #s) + shift = shift + size + end + eq(0, m.file_close(fp)) + eq(#fcontents, lfs.attributes(filec).size) + eq(fcontents, io.open(filec):read('*a')) + end) +end) + +describe('file_skip', function() + it('can skip 3 bytes', function() + local err, fp = file_open(file1, 0, 384) + eq(0, err) + eq(false, fp.wr) + eq(3, file_skip(fp, 3)) + local err, s = file_read(fp, 3) + eq(3, err) + eq(fcontents:sub(4, 6), s) + eq(0, m.file_close(fp)) + end) +end) -- cgit From a3b05a03b62b2c5be92a63ba3890b0359a335ba7 Mon Sep 17 00:00:00 2001 From: ZyX Date: Thu, 23 Jun 2016 22:25:35 +0300 Subject: unittests: Fix bug somewhere that makes file_read tests SEGV --- test/unit/os/fileio_spec.lua | 5 ++++- test/unit/os/fs_spec.lua | 8 ++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) (limited to 'test') diff --git a/test/unit/os/fileio_spec.lua b/test/unit/os/fileio_spec.lua index 22b61786c0..3f0bd16e6c 100644 --- a/test/unit/os/fileio_spec.lua +++ b/test/unit/os/fileio_spec.lua @@ -67,7 +67,10 @@ local function file_read(fp, size) if size == nil then size = 0 else - buf = ffi.new('char[?]', size, ('\0'):rep(size)) + -- For some reason if length of NUL-bytes-string is the same as `char[?]` + -- size luajit garbage collector crashes. But it does not do so in + -- os_read[v] tests in os/fs_spec.lua. + buf = ffi.new('char[?]', size + 1, ('\0'):rep(size)) end local ret1 = m.file_read(fp, buf, size) local ret2 = '' diff --git a/test/unit/os/fs_spec.lua b/test/unit/os/fs_spec.lua index 1f7f6fb791..cc10b0cfa4 100644 --- a/test/unit/os/fs_spec.lua +++ b/test/unit/os/fs_spec.lua @@ -378,12 +378,16 @@ describe('fs function', function() local function os_close(fd) return fs.os_close(fd) end + -- For some reason if length of NUL-bytes-string is the same as `char[?]` + -- size luajit crashes. Though it does not do so in this test suite, better + -- be cautios and allocate more elements then needed. I only did this to + -- strings. local function os_read(fd, size) local buf = nil if size == nil then size = 0 else - buf = ffi.new('char[?]', size, ('\0'):rep(size)) + buf = ffi.new('char[?]', size + 1, ('\0'):rep(size)) end local eof = ffi.new('bool[?]', 1, {true}) local ret2 = fs.os_read(fd, eof, buf, size) @@ -398,7 +402,7 @@ describe('fs function', function() local bufs = {} for i, size in ipairs(sizes) do bufs[i] = { - iov_base=ffi.new('char[?]', size, ('\0'):rep(size)), + iov_base=ffi.new('char[?]', size + 1, ('\0'):rep(size)), iov_len=size, } end -- cgit From 6580dfeddd9693b778f59ca5c333d05200d67687 Mon Sep 17 00:00:00 2001 From: ZyX Date: Fri, 24 Jun 2016 00:06:46 +0300 Subject: unittests: Fix kFileNoSymlink test on FreeBSD MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Actual value on FreeBSD is -31, UV_EMLINK was obtained from /usr/include/asm-generic/errno-base.h (there EMLINK is defined as 31 there). This may actually be something else, but I do not think so as “Too many links” description also fits in. [Man page][1] agrees with me, search for `[EMLINK]` ([linux man page][2] also specifies ELOOP explicitly in a similar section). [1]: https://www.freebsd.org/cgi/man.cgi?query=open&sektion=2 [2]: http://man7.org/linux/man-pages/man3/open.3p.html --- test/unit/os/fileio_spec.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/unit/os/fileio_spec.lua b/test/unit/os/fileio_spec.lua index 3f0bd16e6c..59d85926d9 100644 --- a/test/unit/os/fileio_spec.lua +++ b/test/unit/os/fileio_spec.lua @@ -128,7 +128,9 @@ describe('file_open', function() it('fails to open an symlink with kFileNoSymlink', function() local err, fp = file_open(linkf, m.kFileNoSymlink, 384) - eq(m.UV_ELOOP, err) + -- 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() -- cgit From 4741c8b234eeaeac839b689d6316528ecc78a934 Mon Sep 17 00:00:00 2001 From: ZyX Date: Fri, 24 Jun 2016 01:12:30 +0300 Subject: unittests: Fix testlint errors --- test/unit/os/fileio_spec.lua | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) (limited to 'test') diff --git a/test/unit/os/fileio_spec.lua b/test/unit/os/fileio_spec.lua index 59d85926d9..5358022422 100644 --- a/test/unit/os/fileio_spec.lua +++ b/test/unit/os/fileio_spec.lua @@ -3,17 +3,16 @@ local lfs = require('lfs') local helpers = require('test.unit.helpers') local eq = helpers.eq -local ok = helpers.ok local ffi = helpers.ffi local cimport = helpers.cimport local m = cimport('./src/nvim/os/fileio.h') -local s = '' +local fcontents = '' for i = 0, 255 do - s = s .. (i == 0 and '\0' or ('%c'):format(i)) + fcontents = fcontents .. (i == 0 and '\0' or ('%c'):format(i)) end -local fcontents = s:rep(16) +fcontents = fcontents:rep(16) local dir = 'Xtest-unit-file_spec.d' local file1 = dir .. '/file1.dat' @@ -122,12 +121,12 @@ describe('file_open', function() end) it('fails to open an existing file with kFileCreateOnly', function() - local err, fp = file_open(file1, m.kFileCreateOnly, 384) + local err, _ = file_open(file1, m.kFileCreateOnly, 384) eq(m.UV_EEXIST, err) end) it('fails to open an symlink with kFileNoSymlink', function() - local err, fp = file_open(linkf, m.kFileNoSymlink, 384) + 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 @@ -180,7 +179,7 @@ describe('file_open', function() end) it('fails to create a file with just kFileWriteOnly', function() - local err, fp = file_open(filec, m.kFileWriteOnly, 384) + local err, _ = file_open(filec, m.kFileWriteOnly, 384) eq(m.UV_ENOENT, err) local attrs = lfs.attributes(filec) eq(nil, attrs) @@ -197,17 +196,17 @@ describe('file_open', function() end) it('fails to open a directory write-only', function() - local err, fp = file_open(dir, m.kFileWriteOnly, 384) + 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() - local err, fp = file_open(linkb, m.kFileWriteOnly, 384) + 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() - local err, fp = file_open(linkb, m.kFileReadOnly, 384) + local err, _ = file_open(linkb, m.kFileReadOnly, 384) eq(m.UV_ENOENT, err) end) end) @@ -310,10 +309,10 @@ describe('file_write', function() local err, fp = file_open(filec, m.kFileCreateOnly, 384) eq(0, err) eq(true, fp.wr) - local err = file_write(fp, fcontents) - eq(#fcontents, err) + local wr = file_write(fp, fcontents) + eq(#fcontents, wr) eq(0, m.file_close(fp)) - eq(err, lfs.attributes(filec).size) + eq(wr, lfs.attributes(filec).size) eq(fcontents, io.open(filec):read('*a')) end) @@ -325,8 +324,8 @@ describe('file_write', function() while shift < #fcontents do local size = 3 local s = fcontents:sub(shift + 1, shift + size) - local err = file_write(fp, s) - eq(err, #s) + local wr = file_write(fp, s) + eq(wr, #s) shift = shift + size end eq(0, m.file_close(fp)) @@ -342,8 +341,8 @@ describe('file_write', function() while shift < #fcontents do local size = 768 local s = fcontents:sub(shift + 1, shift + size) - local err = file_write(fp, s) - eq(err, #s) + local wr = file_write(fp, s) + eq(wr, #s) shift = shift + size end eq(0, m.file_close(fp)) @@ -358,8 +357,8 @@ describe('file_skip', function() eq(0, err) eq(false, fp.wr) eq(3, file_skip(fp, 3)) - local err, s = file_read(fp, 3) - eq(3, err) + local rd, s = file_read(fp, 3) + eq(3, rd) eq(fcontents:sub(4, 6), s) eq(0, m.file_close(fp)) end) -- cgit