utils.lua 3.05 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
local lfs = require "lfs"
local assert = require "luassert"

local utils = { luabin = "" }

for i = 0, -math.huge, -1 do
  if not arg[i] then
    break
  end
  utils.luabin = arg[i]
end

utils.tmpdir = os.tmpname()
os.remove(utils.tmpdir)
lfs.mkdir(utils.tmpdir)

function utils.expectCommand(spec)
  local resultPath = utils.tmpdir.."/"..spec.name..".out"
  local cmdPath = "./"..spec.name
  local file = assert(io.open(cmdPath, "w"))
  file:write([[
#!]]..utils.luabin..[[

package.path = "]]..package.path..[["
package.cpath = "]]..package.cpath..[["

local lfs = require "lfs"
local socket = require "socket.core"

local cmd = "]]..spec.name..[["
io.output("]]..resultPath..[[")

local function fail(message, ...)
  io.write(string.format(message, ...))
  os.exit(127)
end

local function expectArg(index, expected)
  local actual = arg[index]
  if actual ~= expected then
    fail("%q argument #%d expected to be %q, but was %q",
      cmd, index, expected, tostring(actual))
  end
end

local function expectDir(path)
  if lfs.attributes(path, "mode") ~= "directory" then
    fail("%q expected directory %q to be available", cmd, path)
  end
end

local function expectFile(path, expected)
  if lfs.attributes(path, "mode") ~= "file" then
    fail("%q expected file %q to exist", cmd, path)
  elseif expected then
    local file = assert(io.open(path))
    local actual = file:read("*a")
    if actual ~= expected then
      fail("%q expected file %q to have different contents", cmd, path)
    end
  end
end
]])
  for i, value in ipairs(spec.arguments or {}) do
    assert(type(value) == "string")
    file:write(string.format('expectArg(%d, %q)\n', i, value))
  end
  for i, value in ipairs(spec.directories or {}) do
    assert(type(value) == "string")
    file:write(string.format('expectDir(%q)\n', value))
  end
  for path, contents in pairs(spec.files or {}) do
    if type(contents) == "string" then
      file:write(string.format('expectFile(%q, %q)\n', path, contents))
    else
      file:write(string.format('expectFile(%q)\n', path))
    end
  end

  if spec.code then
    file:write(spec.code)
  else
    if spec.delay then
      file:write(string.format('socket.sleep(%g)\n', spec.delay))
    end
    if spec.stdout then
      file:write(string.format('io.stdout:write(%q)\n', spec.stdout))
    end
    if spec.stderr then
      file:write(string.format('io.stderr:write(%q)\n', spec.stderr))
    end
    file:write('local pipes = {}\n')
    for i, delay in ipairs(spec.childdelays or {}) do
      file:write(string.format('table.insert(pipes, assert(io.popen("sleep %g")))\n', delay))
    end
    file:write('for _, pipe in ipairs(pipes) do\n',
               '  pipe:close()\n',
               'end\n')
  end
  file:write('io.write(table.concat(arg, " "))\n')
  file:close()

  os.execute("chmod 700 "..cmdPath)

  local expected = string.format(table.concat(spec.arguments, " "))
  return function ()
    local file = assert(io.open(resultPath))
    local args = file:read("*a")
    file:close()
    os.remove(resultPath)
    os.remove(cmdPath)
    assert.equal(expected, args)
  end
end

return utils