Blame specs/posix_spec.yaml

Packit 437b5e
# Specl specifications for APIs in lposix.c
Packit 437b5e
#
Packit 437b5e
# Specifications are topographically sorted, with fundamental calls specified
Packit 437b5e
# at the top of the file, and calls with dependencies on correct functioning
Packit 437b5e
# of earlier specifications further down.
Packit 437b5e
#
Packit 437b5e
# If you get a series of failed expectations, fixing the earliest failures
Packit 437b5e
# first will often clear up later failures automatically!
Packit 437b5e
Packit 437b5e
specify posix:
Packit 437b5e
- describe euidaccess:
Packit 437b5e
  - before: f = posix.euidaccess
Packit 437b5e
  - context with bad arguments:
Packit 437b5e
      badargs.diagnose (f, "euidaccess (string, string)")
Packit 437b5e
Packit 437b5e
Packit 437b5e
- describe errno:
Packit 437b5e
  - context with bad arguments:
Packit 437b5e
      badargs.diagnose (posix.errno, "(?int)")
Packit 437b5e
Packit 437b5e
Packit 437b5e
- describe set_errno:
Packit 437b5e
  - context with bad arguments:
Packit 437b5e
      badargs.diagnose (posix.set_errno, "(int)")
Packit 437b5e
Packit 437b5e
Packit 437b5e
- describe getopt:
Packit 437b5e
  - context with bad arguments:
Packit 437b5e
      badargs.diagnose (posix.getopt, "(list, string, ?table, ?int, ?int)")
Packit 437b5e
Packit 437b5e
Packit 437b5e
- describe openpty:
Packit 437b5e
  - context with bad arguments:
Packit 437b5e
      badargs.diagnose (posix.openpty, "openpty ()")
Packit 437b5e
Packit 437b5e
Packit 437b5e
# spawn's tests also cover execx
Packit 437b5e
- describe spawn:
Packit 437b5e
  - before: f = posix.spawn
Packit 437b5e
Packit 437b5e
  - context with bad arguments:
Packit 437b5e
      badargs.diagnose (f, "spawn (table|function, ?any*)")
Packit 437b5e
Packit 437b5e
  - it spawns a command and can detect success:
Packit 437b5e
      expect (f ({"true"})).to_equal (0)
Packit 437b5e
  - it can detect failure:
Packit 437b5e
      expect (f ({"false"})).to_equal (1)
Packit 437b5e
  - it can pass a table of arguments:
Packit 437b5e
      expect (f ({"echo", "foo"})).to_equal(0)
Packit 437b5e
  - it can pass a function:
Packit 437b5e
      # FIXME: If the function body contains:
Packit 437b5e
      # io.stdout.write ("hello")
Packit 437b5e
      # then the specl results are printed twice; "hello" is not printed
Packit 437b5e
      expect (f (function () end)).to_equal(0)
Packit 437b5e
Packit 437b5e
- describe popen:
Packit 437b5e
  - before:
Packit 437b5e
      popen, pclose = posix.popen, posix.pclose
Packit 437b5e
      read, write, BUFSIZE = posix.read, posix.write, posix.BUFSIZ
Packit 437b5e
  - context with bad arguments:
Packit 437b5e
      badargs.diagnose (popen, "popen (table|function, string, ?function)")
Packit 437b5e
Packit 437b5e
  - it spawns a command and reads its output:
Packit 437b5e
      p = popen ({"echo", "foo"}, "r")
Packit 437b5e
      s = posix.read (p.fd, posix.BUFSIZ)
Packit 437b5e
      pclose (p)
Packit 437b5e
      expect (s).to_equal "foo\n"
Packit 437b5e
Packit 437b5e
  - it spawns a command and writes its input:
Packit 437b5e
      p = popen ({"wc"}, "w")
Packit 437b5e
      s = "foo bar baz"
Packit 437b5e
      expect (write (p.fd, s)).to_equal (#s)
Packit 437b5e
      pclose (p)
Packit 437b5e
Packit 437b5e
- describe popen_pipeline:
Packit 437b5e
  - before:
Packit 437b5e
      popen_pipeline, pclose = posix.popen_pipeline, posix.pclose
Packit 437b5e
      read, write, BUFSIZE = posix.read, posix.write, posix.BUFSIZ
Packit 437b5e
  - context with bad arguments:
Packit 437b5e
      badargs.diagnose (popen_pipeline, "popen_pipeline (table, string, ?function)")
Packit 437b5e
Packit 437b5e
  - it spawns a pipeline and reads its output:
Packit 437b5e
      p = popen_pipeline ({{"echo", "foo", "bar", "baz"}, {"wc"}, {"wc", "-l"}}, "r")
Packit 437b5e
      expect (read (p.fd, posix.BUFSIZ)).to_match ("^%s*1\n")
Packit 437b5e
      pclose (p)
Packit 437b5e
Packit 437b5e
  - it spawns a pipeline and writes its input:
Packit 437b5e
      s = "foo bar baz"
Packit 437b5e
      p = popen_pipeline ({{"cat"}, {"wc"}}, "w")
Packit 437b5e
      expect (write (p.fd, s)).to_equal (#s)
Packit 437b5e
      pclose (p)
Packit 437b5e
Packit 437b5e
Packit 437b5e
- describe timeradd:
Packit 437b5e
  - before:
Packit 437b5e
      tv1 = { sec = 2, usec = 123456 }
Packit 437b5e
      tv2 = { sec = 1, usec = 876543 }
Packit 437b5e
      f = posix.timeradd
Packit 437b5e
Packit 437b5e
  - context with bad arguments:
Packit 437b5e
      badargs.diagnose (f, "timeradd (table, table)")
Packit 437b5e
Packit 437b5e
  - it adds both fields of a timerval:
Packit 437b5e
      expect (f (tv1, tv2)).to_equal { sec = 3, usec = 999999 }
Packit 437b5e
  - it carries overflow second:
Packit 437b5e
      expect (f (tv2, tv2)).to_equal { sec = 3, usec = 753086 }
Packit 437b5e
  - it does not require 'sec' field:
Packit 437b5e
      expect (f (tv1, {usec = 876543})).to_equal { sec = 2, usec = 999999 }
Packit 437b5e
      expect (f ({usec = 123456}, {usec = 876543})).to_equal { sec = 0, usec = 999999}
Packit 437b5e
  - it does not require 'usec' field:
Packit 437b5e
      expect (f (tv1, {sec = 1})).to_equal { sec = 3, usec = 123456 }
Packit 437b5e
      expect (f ({sec = 2}, {sec = 1})).to_equal { sec = 3, usec = 0 }
Packit 437b5e
Packit 437b5e
Packit 437b5e
- describe timercmp:
Packit 437b5e
  - before:
Packit 437b5e
      tv1 = { sec = 2, usec = 123456 }
Packit 437b5e
      tv2 = { sec = 1, usec = 876543 }
Packit 437b5e
      f = posix.timercmp
Packit 437b5e
Packit 437b5e
  - context with bad arguments:
Packit 437b5e
      badargs.diagnose (f, "timercmp (table, table)")
Packit 437b5e
Packit 437b5e
  - it returns 0 if timers are equal:
Packit 437b5e
      expect (f (tv1, tv1)).to_equal (0)
Packit 437b5e
  - it returns positive integer if second timer is greater than first:
Packit 437b5e
      expect (f (tv1, tv2) > 0).to_be (true)
Packit 437b5e
  - it returns negative integer if first timer is greater than the second:
Packit 437b5e
      expect (f (tv2, tv1) < 0).to_be (true)
Packit 437b5e
Packit 437b5e
Packit 437b5e
- describe timersub:
Packit 437b5e
  - before:
Packit 437b5e
      tv1 = { sec = 2, usec = 876543 }
Packit 437b5e
      tv2 = { sec = 1, usec = 123456 }
Packit 437b5e
      f = posix.timersub
Packit 437b5e
Packit 437b5e
  - context with bad arguments:
Packit 437b5e
      badargs.diagnose (f, "timersub (table, table)")
Packit 437b5e
Packit 437b5e
  - it subtracts both fields of a timerval:
Packit 437b5e
      expect (f (tv1, tv2)).to_equal { sec = 1, usec = 753087 }
Packit 437b5e
  - it carries overflow second:
Packit 437b5e
      expect (f (tv2, tv1)).to_equal { sec = -2, usec = 246913 }
Packit 437b5e
  - it does not require 'sec' field:
Packit 437b5e
      expect (f (tv1, {usec = 123456})).to_equal { sec = 2, usec = 753087 }
Packit 437b5e
      expect (f ({usec = 876543}, {usec = 123456})).
Packit 437b5e
        to_equal { sec = 0, usec = 753087}
Packit 437b5e
  - it does not require 'usec' field:
Packit 437b5e
      expect (f (tv1, {sec = 1})).to_equal { sec = 1, usec = 876543 }
Packit 437b5e
      expect (f ({sec = 2}, {sec = 1})).to_equal { sec = 1, usec = 0 }
Packit 437b5e
Packit 437b5e
Packit 437b5e
- specify file descriptors:
Packit 437b5e
  - describe fileno:
Packit 437b5e
    - context with bad arguments:
Packit 437b5e
        badargs.diagnose (posix.fileno, "(file)")
Packit 437b5e
Packit 437b5e
Packit 437b5e
  - describe rpoll:
Packit 437b5e
    - context with bad arguments:
Packit 437b5e
        badargs.diagnose (posix.rpoll, "(int, int)")
Packit 437b5e
Packit 437b5e
Packit 437b5e
  - describe poll:
Packit 437b5e
    - context with bad arguments:
Packit 437b5e
        badargs.diagnose (posix.poll, "(table, ?int)")
Packit 437b5e
Packit 437b5e
Packit 437b5e
  - describe close:
Packit 437b5e
    - context with bad arguments:
Packit 437b5e
        badargs.diagnose (posix.close, "(int)")
Packit 437b5e
Packit 437b5e
Packit 437b5e
  - describe dup:
Packit 437b5e
    - context with bad arguments:
Packit 437b5e
        badargs.diagnose (posix.dup, "(int)")
Packit 437b5e
Packit 437b5e
Packit 437b5e
  - describe dup2:
Packit 437b5e
    - context with bad arguments:
Packit 437b5e
        badargs.diagnose (posix.dup2, "(int, int)")
Packit 437b5e
Packit 437b5e
Packit 437b5e
  - describe pipe:
Packit 437b5e
    - before:
Packit 437b5e
        pipe, read, write = posix.pipe, posix.read, posix.write
Packit 437b5e
Packit 437b5e
    - context with bad arguments:
Packit 437b5e
        badargs.diagnose (pipe, "()")
Packit 437b5e
Packit 437b5e
    - it creates a pipe:
Packit 437b5e
        pout, pin = pipe ()
Packit 437b5e
        expect (pout > 0).to_be (true)
Packit 437b5e
        expect (pin > 0).to_be (true)
Packit 437b5e
    - it can buffer characters:
Packit 437b5e
        pout, pin = pipe ()
Packit 437b5e
        data = "test characters"
Packit 437b5e
        write (pin, data)
Packit 437b5e
        expect (read (pout, data:len ())).to_be (data)
Packit 437b5e
Packit 437b5e
Packit 437b5e
  - describe read:
Packit 437b5e
    - context with bad arguments:
Packit 437b5e
        badargs.diagnose (posix.read, "(int, int)")
Packit 437b5e
Packit 437b5e
Packit 437b5e
  - describe write:
Packit 437b5e
    - context with bad arguments:
Packit 437b5e
        badargs.diagnose (posix.write, "(int, string)")
Packit 437b5e
Packit 437b5e
Packit 437b5e
  - describe fcntl:
Packit 437b5e
    - before:
Packit 437b5e
        F_GETLK, F_SETLK, F_SETLKW = posix.F_GETLK, posix.F_SETLK, posix.F_SETLKW
Packit 437b5e
        F_RDLCK, F_WRLCK, F_UNLCK = posix.F_RDLCK, posix.F_WRLCK, posix.F_UNLCK
Packit 437b5e
        SEEK_SET, SEEK_CUR, SEEK_END = posix.SEEK_SET, posix.SEEK_CUR, posix.SEEK_END
Packit 437b5e
Packit 437b5e
        fcntl, typeerrors = init (posix, "fcntl")
Packit 437b5e
Packit 437b5e
    # posix.fcntl diagnoses the third arg differently depending on
Packit 437b5e
    # the value of `cmd`, which `diagnose.badargs` can't express; ergo
Packit 437b5e
    # manual checks here...
Packit 437b5e
    - context with bad arguments:
Packit 437b5e
      - 'it diagnoses missing argument #1':
Packit 437b5e
          expect (fcntl ()).to_raise.any_of (typeerrors (1, "int"))
Packit 437b5e
      - 'it diagnoses argument #1 type not int':
Packit 437b5e
          expect (fcntl (false)).to_raise.any_of (typeerrors (1, "int", "boolean"))
Packit 437b5e
      - 'it diagnoses missing argument #2':
Packit 437b5e
          expect (fcntl (-1)).to_raise.any_of (typeerrors (2, "int"))
Packit 437b5e
      - 'it diagnoses argument #2 type not int':
Packit 437b5e
          expect (fcntl (-1, false)).to_raise.any_of (typeerrors (2, "int", "boolean"))
Packit 437b5e
      - 'it diagnoses missing argument #3 to F_GETLK':
Packit 437b5e
          expect (fcntl (-1, F_GETLK)).to_raise.any_of (typeerrors (3, "table"))
Packit 437b5e
      - 'it diagnoses argument #3 type to F_GETLK not table':
Packit 437b5e
          expect (fcntl (-1, F_GETLK, false)).
Packit 437b5e
            to_raise.any_of (typeerrors (3, "table", "boolean"))
Packit 437b5e
      - 'it diagnoses argument #3 type to non-F_GETLK not int':
Packit 437b5e
          expect (fcntl (-1, 0, false)).
Packit 437b5e
            to_raise.any_of (typeerrors (3, "?int", "boolean"))
Packit 437b5e
      - 'it diagnoses too many arguments':
Packit 437b5e
          expect (fcntl (-1, F_GETLK, {}, false)).to_raise.any_of (typeerrors (4))
Packit 437b5e
          expect (fcntl (-1, 0, -1, false)).to_raise.any_of (typeerrors (4))
Packit 437b5e
Packit 437b5e
    - it has all needed constants:
Packit 437b5e
        expect (type (F_GETLK)).to_be "number"
Packit 437b5e
        expect (type (F_SETLK)).to_be "number"
Packit 437b5e
        expect (type (F_SETLKW)).to_be "number"
Packit 437b5e
        expect (type (F_RDLCK)).to_be "number"
Packit 437b5e
        expect (type (F_WRLCK)).to_be "number"
Packit 437b5e
        expect (type (F_UNLCK)).to_be "number"
Packit 437b5e
        expect (type (SEEK_SET)).to_be "number"
Packit 437b5e
        expect (type (SEEK_CUR)).to_be "number"
Packit 437b5e
        expect (type (SEEK_END)).to_be "number"
Packit 437b5e
Packit 437b5e
    - context when file locking:
Packit 437b5e
      - before:
Packit 437b5e
          mkstemp, open, close = posix.mkstemp, posix.open, posix.close
Packit 437b5e
          fork, wait, errno = posix.fork, posix.wait, posix.errno
Packit 437b5e
          O_RDWR, EAGAIN, EACCES = posix.O_RDWR, posix.EAGAIN, posix.EACCES
Packit 437b5e
          P_CHILD = 0
Packit 437b5e
          SUCCESS = 0
Packit 437b5e
          fd, path = mkstemp "tmpXXXXXX"
Packit 437b5e
          close (fd)
Packit 437b5e
          parent_pid = posix.getpid "pid"
Packit 437b5e
Packit 437b5e
          query_lock = {
Packit 437b5e
            l_type = F_RDLCK, l_whence = SEEK_SET, l_start = 0, l_len = 0,
Packit 437b5e
          }
Packit 437b5e
          write_lock = {
Packit 437b5e
            l_type = F_WRLCK, l_whence = SEEK_SET, l_start = 0, l_len = 0,
Packit 437b5e
          }
Packit 437b5e
      - after:
Packit 437b5e
          os.remove (path)
Packit 437b5e
Packit 437b5e
      - it checks whether lock is possible with F_GETLK:
Packit 437b5e
          fd = open (path, O_RDWR)
Packit 437b5e
          result = fcntl (fd, F_GETLK, query_lock)
Packit 437b5e
          expect (result).to_be (SUCCESS)
Packit 437b5e
          expect (query_lock.l_type).to_be (F_UNLCK)
Packit 437b5e
          close (fd)
Packit 437b5e
      - it can lock file with F_SETLK: |
Packit 437b5e
          parent_fd = open (path, O_RDWR)
Packit 437b5e
          result = fcntl (parent_fd, F_SETLK, write_lock)
Packit 437b5e
          expect (result).to_be (SUCCESS)
Packit 437b5e
          process = fork ()
Packit 437b5e
          if process == P_CHILD then
Packit 437b5e
            child_fd = open (path, O_RDWR)
Packit 437b5e
            result = fcntl (child_fd, F_GETLK, query_lock)
Packit 437b5e
            close (child_fd)
Packit 437b5e
            -- (not sure how to expect () in subprocess)
Packit 437b5e
            if result ~= SUCCESS then
Packit 437b5e
              os.exit (10)
Packit 437b5e
            elseif query_lock.l_pid ~= parent_pid then
Packit 437b5e
              os.exit (11)
Packit 437b5e
            else
Packit 437b5e
              os.exit (12)
Packit 437b5e
            end
Packit 437b5e
          else
Packit 437b5e
            _, _, exit_code = wait (process)
Packit 437b5e
            expect (exit_code).to_be (12)
Packit 437b5e
          end
Packit 437b5e
          close (parent_fd)
Packit 437b5e
      - it returns error if cannot lock file with F_SETLK: |
Packit 437b5e
          parent_fd = open (path, O_RDWR)
Packit 437b5e
          result = fcntl (parent_fd, F_SETLK, write_lock)
Packit 437b5e
          expect (result).to_be (0)
Packit 437b5e
          process = fork ()
Packit 437b5e
          if process == P_CHILD then
Packit 437b5e
            child_fd = open (path, O_RDWR)
Packit 437b5e
            result = fcntl (child_fd, F_SETLK, write_lock)
Packit 437b5e
            close (child_fd)
Packit 437b5e
            -- (not sure how to expect () in subprocess)
Packit 437b5e
            if result == SUCCESS then
Packit 437b5e
              os.exit (10)
Packit 437b5e
            elseif errno () ~= errno (EACCES) and errno () ~= errno (EAGAIN) then
Packit 437b5e
              os.exit (11)
Packit 437b5e
            else
Packit 437b5e
              os.exit (12)
Packit 437b5e
            end
Packit 437b5e
          else
Packit 437b5e
            _, _, exit_code = wait (process)
Packit 437b5e
            expect (exit_code).to_be (12)
Packit 437b5e
          end
Packit 437b5e
          close (parent_fd)
Packit 437b5e
Packit 437b5e
Packit 437b5e
  - describe lseek:
Packit 437b5e
    - before:
Packit 437b5e
        close, lseek, open, read, write =
Packit 437b5e
          posix.close, posix.lseek, posix.open, posix.read, posix.write
Packit 437b5e
        SEEK_SET, SEEK_CUR, SEEK_END =
Packit 437b5e
          posix.SEEK_SET, posix.SEEK_CUR, posix.SEEK_END
Packit 437b5e
Packit 437b5e
    - context with bad arguments:
Packit 437b5e
        badargs.diagnose (lseek, "(int, int, int)")
Packit 437b5e
Packit 437b5e
    - it changes the current position of a file descriptor:
Packit 437b5e
        _, path = posix.mkstemp (template)
Packit 437b5e
        fd = open (path, posix.O_RDWR)
Packit 437b5e
        expect (fd).not_to_be (nil)
Packit 437b5e
        write (fd, "0123456789")
Packit 437b5e
        lseek (fd, 3, SEEK_SET)
Packit 437b5e
        expect (read (fd, 3)).to_be "345"
Packit 437b5e
        lseek (fd, -2, SEEK_CUR)
Packit 437b5e
        expect (read (fd, 3)).to_be "456"
Packit 437b5e
        lseek (fd, -5, SEEK_END)
Packit 437b5e
        expect (read (fd, 3)).to_be "567"
Packit 437b5e
        close (fd)
Packit 437b5e
        os.remove (path)
Packit 437b5e
Packit 437b5e
Packit 437b5e
Packit 437b5e
- specify file system:
Packit 437b5e
  - before:
Packit 437b5e
      # Make and change into a temporary subdirectory where we can
Packit 437b5e
      # control all the contents for self-contained examples.
Packit 437b5e
      link, mkdir, mkdtemp = posix.link, posix.mkdir, posix.mkdtemp
Packit 437b5e
      origwd = posix.getcwd ()
Packit 437b5e
      dir, errmsg = mkdtemp (template)
Packit 437b5e
      mkdir (dir .. "/subdir")
Packit 437b5e
      link ("subdir", dir .. "/soft", true)
Packit 437b5e
      touch (dir .. "/file")
Packit 437b5e
      link (dir .. "/file", dir .. "/hard")
Packit 437b5e
      link ("no such destination", dir .. "/dangling", true)
Packit 437b5e
  - after:
Packit 437b5e
      posix.chdir (origwd)
Packit 437b5e
      rmtmp (dir)
Packit 437b5e
Packit 437b5e
Packit 437b5e
  - describe sync:
Packit 437b5e
    - context with bad arguments:
Packit 437b5e
        badargs.diagnose (posix.sync, "()")
Packit 437b5e
Packit 437b5e
Packit 437b5e
  - describe fsync:
Packit 437b5e
    - context with bad arguments:
Packit 437b5e
        badargs.diagnose (posix.fsync, "(int)")
Packit 437b5e
Packit 437b5e
Packit 437b5e
  - describe fdatasync:
Packit 437b5e
    - context with bad arguments:
Packit 437b5e
        if posix.fdatasync then
Packit 437b5e
          badargs.diagnose (posix.fdatasync, "(int)")
Packit 437b5e
        end
Packit 437b5e
Packit 437b5e
Packit 437b5e
  - describe basename:
Packit 437b5e
    - before:
Packit 437b5e
        basename = posix.basename
Packit 437b5e
Packit 437b5e
    - context with bad arguments:
Packit 437b5e
        badargs.diagnose (basename, "(string)")
Packit 437b5e
Packit 437b5e
    - it returns a path without leading directories:
Packit 437b5e
        expect (basename "/foo/bar").to_be "bar"
Packit 437b5e
Packit 437b5e
Packit 437b5e
  - describe dirname:
Packit 437b5e
    - before:
Packit 437b5e
        dirname = posix.dirname
Packit 437b5e
Packit 437b5e
    - context with bad arguments:
Packit 437b5e
        badargs.diagnose (dirname, "(string)")
Packit 437b5e
Packit 437b5e
    - it return a path without final element:
Packit 437b5e
        expect (dirname "/foo/bar").to_be "/foo"
Packit 437b5e
Packit 437b5e
Packit 437b5e
  - describe dir:
Packit 437b5e
    - context with bad arguments:
Packit 437b5e
        badargs.diagnose (posix.dir, "(?string)")
Packit 437b5e
Packit 437b5e
Packit 437b5e
  - describe glob:
Packit 437b5e
    - before:
Packit 437b5e
        chdir, glob, mkdtemp = posix.chdir, posix.glob, posix.mkdtemp
Packit 437b5e
Packit 437b5e
    - context with bad arguments:
Packit 437b5e
        badargs.diagnose (glob, "(?string)")
Packit 437b5e
Packit 437b5e
    - it matches files in the given directory:
Packit 437b5e
        dir = mkdtemp (template)
Packit 437b5e
        touch (dir .. "/test.1")
Packit 437b5e
        touch (dir .. "/test.2")
Packit 437b5e
        touch (dir .. "/extra_file")
Packit 437b5e
        chdir (dir)
Packit 437b5e
        globlist, errmsg = glob "test.*"
Packit 437b5e
        expect (errmsg).to_be (nil)
Packit 437b5e
        expect (type (globlist)).to_be "table"
Packit 437b5e
        rmtmp (dir)
Packit 437b5e
Packit 437b5e
Packit 437b5e
  - describe files:
Packit 437b5e
    - before:
Packit 437b5e
        files = posix.files
Packit 437b5e
Packit 437b5e
    - context with bad arguments:
Packit 437b5e
        badargs.diagnose (files, "(?string)")
Packit 437b5e
Packit 437b5e
    - it returns a table of files in the given directory:
Packit 437b5e
        t = {}
Packit 437b5e
        for f in files (dir) do
Packit 437b5e
          table.insert (t, f)
Packit 437b5e
        end
Packit 437b5e
        table.sort (t)
Packit 437b5e
        expect (t).to_equal {".", "..", "dangling", "file", "hard", "soft", "subdir"}
Packit 437b5e
Packit 437b5e
Packit 437b5e
  - describe getcwd:
Packit 437b5e
    - context with bad arguments:
Packit 437b5e
        badargs.diagnose (posix.getcwd, "()")
Packit 437b5e
Packit 437b5e
Packit 437b5e
  - describe chdir:
Packit 437b5e
    - before:
Packit 437b5e
        chdir, chmod, getcwd, mkdir, rmdir =
Packit 437b5e
          posix.chdir, posix.chmod, posix.getcwd, posix.mkdir, posix.rmdir
Packit 437b5e
        cwd = getcwd ()
Packit 437b5e
    - after:
Packit 437b5e
        chdir (cwd)
Packit 437b5e
        pcall (rmdir, "x")
Packit 437b5e
Packit 437b5e
    - context with bad arguments:
Packit 437b5e
        badargs.diagnose (chdir, "(string)")
Packit 437b5e
Packit 437b5e
    - it changes to a relative directory:
Packit 437b5e
        thisdir = posix.basename (getcwd ())
Packit 437b5e
        expect (Emsg (chdir ("../" .. thisdir))).
Packit 437b5e
          not_to_contain "No such file or directory"
Packit 437b5e
        expect (Emsg (chdir "..")).not_to_contain "No such file or directory"
Packit 437b5e
    - it changes to an absolute directory:
Packit 437b5e
        expect (Emsg (chdir "/var/tmp/")).
Packit 437b5e
          not_to_contain "No such file or directory"
Packit 437b5e
    - it diagnoses missing directory:
Packit 437b5e
        expect (Emsg (chdir "very_unlikely_to_exist")).
Packit 437b5e
          to_contain "No such file or directory"
Packit 437b5e
    - it diagnoses insufficient permissions:
Packit 437b5e
        mkdir "x"
Packit 437b5e
        chmod ("x", "a-rwx")
Packit 437b5e
        expect (Emsg (chdir "x")).
Packit 437b5e
          to_contain "Permission denied"
Packit 437b5e
        rmdir "x"
Packit 437b5e
Packit 437b5e
Packit 437b5e
  - describe rmdir:
Packit 437b5e
    - before:
Packit 437b5e
        mkdir, rmdir = posix.mkdir, posix.rmdir
Packit 437b5e
Packit 437b5e
    - context with bad arguments:
Packit 437b5e
        badargs.diagnose (rmdir, "(string)")
Packit 437b5e
Packit 437b5e
    - it removes the named directory:
Packit 437b5e
        mkdir "x"
Packit 437b5e
        expect (Emsg (rmdir "x")).not_to_contain "No such file or directory"
Packit 437b5e
    - it diagnoses missing directory:
Packit 437b5e
        expect (Emsg (rmdir ".")).to_contain "Invalid argument"
Packit 437b5e
Packit 437b5e
Packit 437b5e
  - describe unlink:
Packit 437b5e
    - context with bad arguments:
Packit 437b5e
        badargs.diagnose (posix.unlink, "(string)")
Packit 437b5e
Packit 437b5e
Packit 437b5e
  - describe link:
Packit 437b5e
    - before:
Packit 437b5e
        link, stat = posix.link, posix.stat
Packit 437b5e
        touch "xxx"
Packit 437b5e
    - after:
Packit 437b5e
        os.remove "xxx"
Packit 437b5e
Packit 437b5e
    - context with bad arguments:
Packit 437b5e
        badargs.diagnose (link, "(string, string, ?boolean)")
Packit 437b5e
Packit 437b5e
    - it creates hard links:
Packit 437b5e
        expect (Emsg (link ("xxx", "xxx-hard"))).to_be ""
Packit 437b5e
        expect (stat ("xxx-hard", "ino")).to_be (stat ("xxx", "ino"))
Packit 437b5e
        os.remove "xxx-hard"
Packit 437b5e
    - it creates soft links:
Packit 437b5e
        expect (Emsg (link ("xxx", "xxx-soft", true))).to_be ""
Packit 437b5e
        expect (stat ("xxx-soft", "type")).to_be "link"
Packit 437b5e
        os.remove "xxx-soft"
Packit 437b5e
Packit 437b5e
  - describe readlink:
Packit 437b5e
    - before:
Packit 437b5e
        readlink = posix.readlink
Packit 437b5e
Packit 437b5e
    - context with bad arguments:
Packit 437b5e
        badargs.diagnose (readlink, "(string)")
Packit 437b5e
Packit 437b5e
    - it diagnoses missing file: |
Packit 437b5e
        _, err, code = readlink "does not exist!"
Packit 437b5e
        expect (err).to_match "^does not exist!: "
Packit 437b5e
        expect (code).to_be (posix.ENOENT)
Packit 437b5e
    - it diagnoses non-symbolic link: |
Packit 437b5e
        _, err, code = readlink (dir .. "/file")
Packit 437b5e
        expect (err).to_be (dir .. "/file: not a symbolic link")
Packit 437b5e
        expect (code).to_be (posix.EINVAL)
Packit 437b5e
    - it reads the contents of a symbolic link:
Packit 437b5e
        expect (readlink (dir .. "/soft")).to_be "subdir"
Packit 437b5e
    - it reads the contents of a dangling symbolic link:
Packit 437b5e
        expect (readlink (dir .. "/dangling")).to_be "no such destination"
Packit 437b5e
Packit 437b5e
Packit 437b5e
  - describe access:
Packit 437b5e
    - before:
Packit 437b5e
        access = posix.access
Packit 437b5e
        touch "xxx"
Packit 437b5e
    - after:
Packit 437b5e
        os.remove "xxx"
Packit 437b5e
Packit 437b5e
    - context with bad arguments:
Packit 437b5e
        badargs.diagnose (posix.access, "(string, ?string)")
Packit 437b5e
Packit 437b5e
    - it checks whether a file is visible to the real user:
Packit 437b5e
        expect (Emsg (access ("xxx", "f"))).to_be ""
Packit 437b5e
    - it checks whether a file is readable by the real user:
Packit 437b5e
        expect (Emsg (access ("xxx", "r"))).to_be ""
Packit 437b5e
    - it checks whether a file is writable by the real user:
Packit 437b5e
        expect (Emsg (access ("xxx", "w"))).to_be ""
Packit 437b5e
    - "it defaults to 'f' with no mode argument":
Packit 437b5e
        expect (access ("xxx")).to_be (access ("xxx", "f"))
Packit 437b5e
    - it diagnoses missing files:
Packit 437b5e
        os.remove "xxx"
Packit 437b5e
        expect (Emsg (access "xxx")).to_contain "No such file or directory"
Packit 437b5e
Packit 437b5e
Packit 437b5e
  - describe chown:
Packit 437b5e
    - context with bad arguments:
Packit 437b5e
        badargs.diagnose (posix.chown, "(string, ?string|int, ?string|int)")
Packit 437b5e
Packit 437b5e
Packit 437b5e
  - describe utime:
Packit 437b5e
    - before:
Packit 437b5e
        stat, utime = posix.stat, posix.utime
Packit 437b5e
        touch "xxx"
Packit 437b5e
    - after:
Packit 437b5e
        os.remove "xxx"
Packit 437b5e
Packit 437b5e
    - context with bad arguments:
Packit 437b5e
        badargs.diagnose (posix.utime, "(string, ?int, ?int)")
Packit 437b5e
Packit 437b5e
    - it sets the last file modification time:
Packit 437b5e
        mtime = stat ("/etc", "mtime")
Packit 437b5e
        expect (stat ("xxx", "mtime")).not_to_equal (mtime)
Packit 437b5e
        expect (Emsg (utime ("xxx", mtime))).to_be ""
Packit 437b5e
        expect (stat ("xxx", "mtime")).to_equal (mtime)
Packit 437b5e
    - it sets the last file access time:
Packit 437b5e
        atime = stat ("/etc", "atime")
Packit 437b5e
        expect (stat ("xxx", "atime")).not_to_equal (atime)
Packit 437b5e
        expect (Emsg (utime ("xxx", nil, atime))).to_be ""
Packit 437b5e
        expect (stat ("xxx", "atime")).to_equal (atime)
Packit 437b5e
Packit 437b5e
Packit 437b5e
- specify process management:
Packit 437b5e
  - describe nice:
Packit 437b5e
    - before:
Packit 437b5e
        nice = posix.nice
Packit 437b5e
Packit 437b5e
    - context with bad arguments:
Packit 437b5e
        badargs.diagnose (nice, "(int)")
Packit 437b5e
Packit 437b5e
    - it adjusts the process priority:
Packit 437b5e
        old = nice (1)
Packit 437b5e
        expect (old).not_to_be (nil)
Packit 437b5e
        new = nice (2)
Packit 437b5e
        expect (new).to_be (old + 2)
Packit 437b5e
Packit 437b5e
Packit 437b5e
  - describe fork:
Packit 437b5e
    # NOTE: Calling expect in a child process does not report results
Packit 437b5e
    #       back to parent, so we send test data over a pipe.
Packit 437b5e
    - before:
Packit 437b5e
        nice, execp, fork, getpid, getppid, wait =
Packit 437b5e
          posix.nice, posix.execp, posix.fork, posix.getpid, posix.getppid, posix.wait
Packit 437b5e
        _exit, close, pipe, read, write =
Packit 437b5e
          posix._exit, posix.close, posix.pipe, posix.read, posix.write
Packit 437b5e
        P_CHILD = 0
Packit 437b5e
Packit 437b5e
    - context with bad arguments:
Packit 437b5e
        badargs.diagnose (fork, "()")
Packit 437b5e
Packit 437b5e
    - it copies itself to a new child process: |
Packit 437b5e
        r, w = pipe ()
Packit 437b5e
        process, status = fork (), 67
Packit 437b5e
        if process == P_CHILD then
Packit 437b5e
          close (r) -- close unused read end
Packit 437b5e
          -- write parent pid and child pid to shared pipe.
Packit 437b5e
          write (w, tostring (getppid ()).."\n")
Packit 437b5e
          write (w, tostring (getpid "pid").."\n")
Packit 437b5e
          close (w)
Packit 437b5e
          _exit (status)
Packit 437b5e
        else
Packit 437b5e
          posix.close (w) -- close unused write end
Packit 437b5e
          p, msg, ret = wait (process)
Packit 437b5e
          expect (p).to_be (process)
Packit 437b5e
          expect (msg).to_be "exited"
Packit 437b5e
          expect (ret).to_be (status)
Packit 437b5e
          -- check pids from child process.
Packit 437b5e
          buf = posix.read (r, 1024)
Packit 437b5e
          cppid, cpid = string.match (buf, "(%d+)\n(%d+)\n")
Packit 437b5e
          close (r)
Packit 437b5e
          expect (cppid).to_be (tostring (getpid "pid"))
Packit 437b5e
          expect (cpid).to_be (tostring (process))
Packit 437b5e
        end
Packit 437b5e
Packit 437b5e
Packit 437b5e
  - describe _exit:
Packit 437b5e
    - context with bad arguments:
Packit 437b5e
        badargs.diagnose (posix. _exit, "(int)")
Packit 437b5e
Packit 437b5e
Packit 437b5e
  - describe wait:
Packit 437b5e
    - context with bad arguments:
Packit 437b5e
        badargs.diagnose (posix.wait, "(?int, ?int)")
Packit 437b5e
Packit 437b5e
Packit 437b5e
  - describe setpid:
Packit 437b5e
    - before:
Packit 437b5e
        setpid, typeerrors = init (posix, "setpid")
Packit 437b5e
Packit 437b5e
    - context with bad arguments:
Packit 437b5e
      - 'it diagnoses missing argument #1':
Packit 437b5e
          expect (setpid ()).to_raise.any_of (typeerrors (1, "string"))
Packit 437b5e
      - 'it diagnoses argument #1 type not string':
Packit 437b5e
          expect (setpid (false)).to_raise.any_of (typeerrors (1, "string", "boolean"))
Packit 437b5e
      - 'it diagnoses argument #1 invalid option': |
Packit 437b5e
          expect (setpid "fubar").to_raise.any_of {
Packit 437b5e
            "bad argument #1 to '?' (invalid id option 'f')",
Packit 437b5e
            "bad argument #1 to 'setpid' (invalid id option 'f')",
Packit 437b5e
          }
Packit 437b5e
      - 'it diagnoses missing argument #2':
Packit 437b5e
          expect (setpid "p").to_raise.any_of (typeerrors (2, "int"))
Packit 437b5e
      - 'it diagnoses argument #2 type not int':
Packit 437b5e
          expect (setpid ("p", false)).
Packit 437b5e
            to_raise.any_of (typeerrors (2, "int", "boolean"))
Packit 437b5e
      - 'it diagnoses missing argument #3':
Packit 437b5e
          expect (setpid ("p", 0)).to_raise.any_of (typeerrors (3, "int"))
Packit 437b5e
      - 'it diagnoses argument #3 type not int':
Packit 437b5e
          expect (setpid ("p", 0, false)).
Packit 437b5e
            to_raise.any_of (typeerrors (3, "int", "boolean"))
Packit 437b5e
      - it diagnoses too many arguments:
Packit 437b5e
          expect (setpid ("p", 0, 0, false)).to_raise.any_of (typeerrors (4))
Packit 437b5e
          expect (setpid ("u", 0, false)).to_raise.any_of (typeerrors (3))
Packit 437b5e
Packit 437b5e
Packit 437b5e
  - describe sleep:
Packit 437b5e
    - context with bad arguments:
Packit 437b5e
        badargs.diagnose (posix.sleep, "(int)")
Packit 437b5e
Packit 437b5e
Packit 437b5e
  - describe sched_setscheduler:
Packit 437b5e
    - context with bad arguments:
Packit 437b5e
        if posix.sched_setscheduler then
Packit 437b5e
          badargs.diagnose (posix.sched_setscheduler, "(?int, ?int, ?int)")
Packit 437b5e
        end
Packit 437b5e
Packit 437b5e
Packit 437b5e
  - describe sched_getscheduler:
Packit 437b5e
    - context with bad arguments:
Packit 437b5e
        if posix.sched_getscheduler then
Packit 437b5e
          badargs.diagnose (posix.sched_getscheduler, "(?int)")
Packit 437b5e
        end
Packit 437b5e
Packit 437b5e
Packit 437b5e
Packit 437b5e
- specify terminal handling:
Packit 437b5e
  - describe ttyname:
Packit 437b5e
    - before:
Packit 437b5e
        ttyname = posix.ttyname
Packit 437b5e
Packit 437b5e
    - context with bad arguments:
Packit 437b5e
        badargs.diagnose (posix.ttyname, "(?int)")
Packit 437b5e
Packit 437b5e
    - it takes a file descriptor argument:
Packit 437b5e
        expect (ttyname (2)).to_contain.any_of {"console", "pts", "tty"}
Packit 437b5e
    - it returns a string:
Packit 437b5e
        expect (type (ttyname (1))).to_be "string"
Packit 437b5e
    - it defaults the first argument to 0:
Packit 437b5e
        expect (ttyname ()).to_be (ttyname (0))
Packit 437b5e
Packit 437b5e
Packit 437b5e
  - describe ctermid:
Packit 437b5e
    - before:
Packit 437b5e
        ctermid = posix.ctermid
Packit 437b5e
Packit 437b5e
    - context with bad arguments:
Packit 437b5e
        badargs.diagnose (posix.ctermid, "()")
Packit 437b5e
Packit 437b5e
    - it returns the pathname of the controlling terminal:
Packit 437b5e
        expect (ctermid ()).to_match.any_of {"/.*pts.*", "/.*tty.*"}
Packit 437b5e
Packit 437b5e
Packit 437b5e
  - describe isatty:
Packit 437b5e
    - context with bad arguments:
Packit 437b5e
        badargs.diagnose (posix.isatty, "(int)")
Packit 437b5e
Packit 437b5e
Packit 437b5e
  - describe tcsetattr:
Packit 437b5e
    - context with bad arguments:
Packit 437b5e
        badargs.diagnose (posix.tcsetattr, "(int, int, table)")
Packit 437b5e
Packit 437b5e
Packit 437b5e
  - describe tcgetattr:
Packit 437b5e
    - context with bad arguments:
Packit 437b5e
        badargs.diagnose (posix.tcgetattr, "(int)")
Packit 437b5e
Packit 437b5e
Packit 437b5e
  - describe tcsendbreak:
Packit 437b5e
    - context with bad arguments:
Packit 437b5e
        badargs.diagnose (posix.tcsendbreak, "(int, int)")
Packit 437b5e
Packit 437b5e
Packit 437b5e
  - describe tcdrain:
Packit 437b5e
    - context with bad arguments:
Packit 437b5e
        badargs.diagnose (posix.tcdrain, "(int)")
Packit 437b5e
Packit 437b5e
Packit 437b5e
  - describe tcflush:
Packit 437b5e
    - context with bad arguments:
Packit 437b5e
        badargs.diagnose (posix.tcflush, "(int, int)")
Packit 437b5e
Packit 437b5e
Packit 437b5e
  - describe tcflow:
Packit 437b5e
    - context with bad arguments:
Packit 437b5e
        badargs.diagnose (posix.tcflow, "(int, int)")
Packit 437b5e
Packit 437b5e
Packit 437b5e
Packit 437b5e
- specify user management:
Packit 437b5e
  - describe getlogin:
Packit 437b5e
    - context with bad arguments:
Packit 437b5e
        badargs.diagnose (posix.getlogin, "()")
Packit 437b5e
Packit 437b5e
Packit 437b5e
  - describe getgroups:
Packit 437b5e
    - context with bad arguments:
Packit 437b5e
        if posix.getgroups then
Packit 437b5e
          badargs.diagnose (posix.getgroups, "()")
Packit 437b5e
        end
Packit 437b5e
Packit 437b5e
Packit 437b5e
  - describe crypt:
Packit 437b5e
    - before:
Packit 437b5e
        crypt = posix.crypt
Packit 437b5e
        key, salt = "hello", "pl"
Packit 437b5e
Packit 437b5e
    - context with bad arguments:
Packit 437b5e
        if posix.crypt then
Packit 437b5e
          badargs.diagnose (posix.crypt, "(string, string)")
Packit 437b5e
        end
Packit 437b5e
Packit 437b5e
    - it can perform repeatable one-way hashing:
Packit 437b5e
        hash = crypt (key, salt)
Packit 437b5e
        expect (crypt (key, salt)).to_be (hash)
Packit 437b5e
    - it encrypts differently for a different salt:
Packit 437b5e
        expect (crypt (key, salt)).not_to_equal (crypt (key, "/."))