diff --git a/auditd/1.0.0/cmodule/exec.lua b/auditd/1.0.0/cmodule/exec.lua index 7690cd7..7328899 100644 --- a/auditd/1.0.0/cmodule/exec.lua +++ b/auditd/1.0.0/cmodule/exec.lua @@ -10,8 +10,8 @@ local function trim_end(s) end -- Executes the given command in a shell. --- NOTE: stderr is redirected to stdout. ---:: string -> ok::boolean, output|err::string +-- NOTE: stderr is redirecting to stdout. +--:: string -> string?, err::string local function exec(cmd) local f = io.popen("exec 2>&1;" .. cmd) if not f then @@ -23,7 +23,7 @@ local function exec(cmd) return false, string.format( "exec(%s): %s=%d: %s", cmd, status, code, show_output(output)) end - return true, trim_end(output) + return trim_end(output) end return exec diff --git a/auditd/1.0.0/cmodule/exec_spec.lua b/auditd/1.0.0/cmodule/exec_spec.lua index 0d872aa..b73e578 100644 --- a/auditd/1.0.0/cmodule/exec_spec.lua +++ b/auditd/1.0.0/cmodule/exec_spec.lua @@ -9,7 +9,7 @@ describe("exec", function() assert(exec("true")) end) - it("must fail unless the exit code is 0", function() + it("must fail if exit code != 0", function() local ok, err = exec("echo ERROR; false") assert(not ok) assert(string_contains(err, 'exit=1: ERROR'), diff --git a/auditd/1.0.0/cmodule/managed.lua b/auditd/1.0.0/cmodule/managed.lua index e1fc28f..bde6b40 100644 --- a/auditd/1.0.0/cmodule/managed.lua +++ b/auditd/1.0.0/cmodule/managed.lua @@ -4,8 +4,11 @@ local File = {}; File.__index = File local MODIFIED = {} --- Introduces a managed file. --- NOTE: `mode` is a string of format of `chmod` command, see: man chmod(1). +-- Introduces a "managed" file. +-- 1. Set the required access `mode` to the file. +-- 2. Set the required content of the file with `set`. +-- 3. Then use `ensure` to adjust the file on disk to required state. +-- NOTE: `mode` is a string in `chmod` format, see: chmod(1). --:: string, string -> File function File.new(path, mode) return setmetatable({ @@ -15,16 +18,16 @@ function File.new(path, mode) }, File) end --- Sets target content of the managed file. +-- Sets target content of the file. --:: string -> () function File:set(data) self._data = data end --- Adjust the managed file state on disk. --- Does nothing if the file content equals to the target data. +-- Adjust the file on disk to required state. +-- Does nothing if the file on disk matches the required state. --:: () -> true|MODIFIED, err::string? -function File:adjust() +function File:ensure() if self:compare() == MODIFIED then local ok, err = self:write() return ok and MODIFIED, @@ -33,7 +36,7 @@ function File:adjust() return true end --- Overwrite the managed file with the target data. +-- Entirely overwrites the file on disk with the required content. --:: () -> ok::boolean, err::string? function File:write() local ok, err = exec( @@ -53,7 +56,7 @@ function File:write() string.format("chmod %q %q", self._mode, self._path)) end --- Compares content of the managed file with the target value. +-- Compares the required content with the file's content on disk. --:: () -> true|MODIFIED function File:compare() local data diff --git a/auditd/1.0.0/cmodule/managed_spec.lua b/auditd/1.0.0/cmodule/managed_spec.lua index d601a73..8d25c74 100644 --- a/auditd/1.0.0/cmodule/managed_spec.lua +++ b/auditd/1.0.0/cmodule/managed_spec.lua @@ -1,61 +1,58 @@ local managed = require "managed" local exec = require "exec" -local function temp_dir() - local filename = assert(os.tmpname()) - assert(os.remove(filename)) - return filename .. ".dir" -end - local function rm(path) - local cmd = string.format("rm -rf %q", path) + local cmd = string.format("rm -r %q", path) assert(exec(cmd)) end -local function read_all(filename) +local function read_file(filename) local f = assert(io.open(filename, "rb"), string.format("failed to open: %s", filename)) return assert(f:read("a")), f:close() end local function read_mode(filename) - local cmd = string.format("ls -l %q | cut -f1 -d' '", filename) - local ok, mode = assert(exec(cmd)) - return mode + local cmd = string.format("ls -l %q | cut -f1 -d\\ ", filename) + return assert(exec(cmd)) end -describe("Managed file", function() +describe("Managed file #write", function() setup(function() - tmp = temp_dir() + tmp = assert(exec("mktemp -d")) + f_name = tmp .. "/sub/file" end) teardown(function() rm(tmp) end) - describe("adjust()", function() + describe("ensure()", function() it("should create a file unless it exists", function() - local f = managed.File.new(tmp.."/file", "ug=rw,o=r") + local f = managed.File.new(f_name, "ug=rw,o=r") f:set("CREATE") - local result = assert(f:adjust()) - assert.equals(result, managed.MODIFIED) - assert.equals(read_all(tmp.."/file"), "CREATE") - assert.equals(read_mode(tmp.."/file"), "-rw-rw-r--") + + local result = assert(f:ensure()) + assert.equals(managed.MODIFIED, result) + assert.equals("CREATE", read_file(f_name)) + assert.equals("-rw-rw-r--", read_mode(f_name)) end) - it("should return `true` while file's content == target data", function() - local f = managed.File.new(tmp.."/file", "TEST") + it("should return `true` while file's content == required content", function() + local f = managed.File.new(f_name, "INVALID") f:set("CREATE") - local result = assert(f:adjust()) - assert.equals(result, true) + + local result = assert(f:ensure()) + assert.is_true(result) end) - it("should overwrite if file's content != target data", function() - local f = managed.File.new(tmp.."/file", "400") + it("should overwrite if file's content != required content", function() + local f = managed.File.new(f_name, "0400") f:set("UPDATE") - local result = assert(f:adjust()) - assert.equals(result, managed.MODIFIED) - assert.equals(read_all(tmp.."/file"), "UPDATE") - assert.equals(read_mode(tmp.."/file"), "-r--------") + + local result = assert(f:ensure()) + assert.equals(managed.MODIFIED, result) + assert.equals("UPDATE", read_file(f_name)) + assert.equals("-r--------", read_mode(f_name)) end) end) end)