Sfoglia il codice sorgente

Replace the testcases script with a Vagrant VM

See the README section for more details. Basically, with this way, we can store a bunch of existing valid exa outputs, change a VM's environment to match our values, then check that exa still works by comparing outputs.
Benjamin Sago 9 anni fa
parent
commit
54067bf765

+ 1 - 0
.gitignore

@@ -1,3 +1,4 @@
 *~
 target
 testcases
+.vagrant

+ 0 - 8
.travis.yml

@@ -8,12 +8,4 @@ rust:
   - stable
 script:
     - cargo build --verbose
-    - yes | sudo ./generate-testcases.sh
     - cargo test --verbose
-    - cargo run
-    - cargo run -- --long
-    - cargo run -- --long --grid
-    - cargo run -- --tree
-    - cargo run -- --tree --long
-    - cargo run -- --recurse
-    - cargo run -- --recurse --long --extended

+ 33 - 5
README.md

@@ -66,8 +66,7 @@ If you’re unable to compile libgit2, you can opt out of Git support by running
 
 ### Cargo Install
 
-If you're using a recent version of Cargo (0.5.0 or higher), you can
-use the `cargo install` command:
+If you’re using a recent version of Cargo (0.5.0 or higher), you can use the `cargo install` command:
 
     cargo install --git https://github.com/ogham/exa
 
@@ -75,6 +74,35 @@ or:
 
     cargo install --no-default-features --git https://github.com/ogham/exa
 
-Cargo will clone the repository to a temporary directory, build it
-there and place the `exa` binary to: `$HOME/.cargo` (and can be
-overridden by setting the `--root` option).
+Cargo will clone the repository to a temporary directory, build it there and place the `exa` binary to: `$HOME/.cargo` (and can be overridden by setting the `--root` option).
+
+
+## Testing with Vagrant
+
+exa uses [Vagrant][] to configure virtual machines for testing.
+
+Programs such as exa that are basically interfaces to the system are [notoriously difficult to test][testing]. Although the internal components have unit tests, it’s impossible to do a complete end-to-end test without mandating the current user’s name, the time zone, the locale, and directory structure to test. (And yes, these tests are worth doing. I have missed an edge case on more than one occasion.)
+
+The initial attempt to solve the problem was just to create a directory of “awkward” test cases, run exa on it, and make sure it produced the correct output. But even this output would change if, say, the user’s locale formats dates in a different way. These can be mocked inside the code, but at the cost of making that code more complicated to read and understand.
+
+An alternative solution is to fake *everything*: create a virtual machine with a known state and run the tests on *that*. This is what Vagrant does. Although it takes a while to download and set up, it gives everyone the same development environment to test for any obvious regressions.
+
+[Vagrant]: https://www.vagrantup.com/docs/why-vagrant/
+[testing]: https://eev.ee/blog/2016/08/22/testing-for-people-who-hate-testing/#troublesome-cases
+
+First, initialise the VM:
+
+    host$ vagrant up
+
+The first command downloads the virtual machine image, and then runs our provisioning script, which installs Rust, exa’s dependencies, configures the environment, and generates some awkward files and folders to use as test cases. This takes some time, but it does write to output occasionally. Once this is done, you can SSH in, and build and test:
+
+    host$ vagrant ssh
+    vm$ cd /vagrant
+    vm$ cargo build
+    vm$ ./xtests/run
+    All the tests passed!
+
+
+### Running without Vagrant
+
+Of course, the drawback of having a standard development environment is that you stop noticing bugs that occur outside of it. For this reason, Vagrant isn’t a *necessary* development step — it’s there if you’d like to use it, but exa still gets used and tested on other platforms. It can still be built and compiled on any target triple that it supports, VM or no VM, with `cargo build` and `cargo test`.

+ 146 - 0
Vagrantfile

@@ -0,0 +1,146 @@
+Vagrant.configure("2") do |config|
+    config.vm.provider "virtualbox" do |v|
+        v.memory = 1024
+        v.cpus = 1
+    end
+
+    config.vm.box = "debian/contrib-jessie64"
+    config.vm.hostname = "exa"
+
+    # Install the dependencies needed for exa to build.
+    config.vm.provision :shell, privileged: true, inline:
+        %[apt-get install -y git cmake libgit2-dev libssh2-1-dev curl attr]
+
+    # Guarantee that the timezone is UTC -- some of the tests
+    # depend on this (for now).
+    config.vm.provision :shell, privileged: true, inline:
+        %[timedatectl set-timezone UTC]
+
+    # Install Rust.
+    # This is done as vagrant, not root, because it’s vagrant
+    # who actually uses it. Sent to /dev/null because the progress
+    # bar produces a lot of output.
+    config.vm.provision :shell, privileged: false, inline:
+        %[hash rustc &>/dev/null || curl -sSf https://static.rust-lang.org/rustup.sh | sh &> /dev/null]
+
+    # Use a different ‘target’ directory on the VM than on the host.
+    # By default it just uses the one in /vagrant/target, which can
+    # cause problems if it has different permissions than the other
+    # directories, or contains object files compiled for the host.
+    config.vm.provision :shell, privileged: false, inline:
+        %[echo "export CARGO_TARGET_DIR=/home/vagrant/target" >> ~/.bashrc]
+
+    # Test that wide columns work with a really long username.
+    # The benefit of Vagrant is that we don’t need to set this up
+    # on the *actual* system!
+    longuser = "antidisestablishmentarienism"
+    config.vm.provision :shell, privileged: true, inline:
+        %[id -u #{longuser} &>/dev/null || useradd #{longuser}]
+
+    test_dir = "/home/vagrant/testcases"
+    invalid_uid = 666
+    invalid_gid = 616
+    some_date = "201601011234.56"  # 1st January 2016, 12:34:56
+
+    # Delete old testcases if they exist already.
+    # This needs root because the generator does some sudo-ing.
+    config.vm.provision :shell, privileged: true, inline:
+        %[rm -rfv #{test_dir}]
+
+    # Generate our awkward testcases.
+    config.vm.provision :shell, privileged: false, inline:
+        %[mkdir #{test_dir}]
+
+    # Awkward file size testcases.
+    config.vm.provision :shell, privileged: false, inline: <<-EOF
+        set -xe
+        mkdir "#{test_dir}/files"
+        for i in {1..13}; do
+            fallocate -l "$i" "#{test_dir}/files/$i"_bytes
+            fallocate -l "$i"KiB "#{test_dir}/files/$i"_KiB
+            fallocate -l "$i"MiB "#{test_dir}/files/$i"_MiB
+        done
+        touch -t #{some_date} "#{test_dir}/files/"*
+    EOF
+
+    # Awkward symlink testcases.
+    config.vm.provision :shell, privileged: false, inline: <<-EOF
+        set -xe
+        mkdir "#{test_dir}/links"
+        ln -s / "#{test_dir}/links/root"
+        ln -s /usr "#{test_dir}/links/usr"
+        ln -s nowhere "#{test_dir}/links/broken"
+    EOF
+
+    # Awkward passwd testcases.
+    # sudo is needed for these because we technically aren’t a member
+    # of the groups (because they don’t exist), and chown and chgrp
+    # are smart enough to disallow it!
+    config.vm.provision :shell, privileged: false, inline: <<-EOF
+        set -xe
+        mkdir "#{test_dir}/passwd"
+
+        touch -t #{some_date} "#{test_dir}/passwd/unknown-uid"
+        sudo chown #{invalid_uid} "#{test_dir}/passwd/unknown-uid"
+
+        touch -t #{some_date} "#{test_dir}/passwd/unknown-gid"
+        sudo chgrp #{invalid_gid} "#{test_dir}/passwd/unknown-gid"
+    EOF
+
+    # Awkward permission testcases.
+    config.vm.provision :shell, privileged: false, inline: <<-EOF
+        set -xe
+        mkdir "#{test_dir}/permissions"
+
+        touch "#{test_dir}/permissions/all-permissions"
+        chmod 777 "#{test_dir}/permissions/all-permissions"
+
+        touch "#{test_dir}/permissions/no-permissions"
+        chmod 000 "#{test_dir}/permissions/no-permissions"
+
+        mkdir "#{test_dir}/permissions/forbidden-directory"
+        chmod 000 "#{test_dir}/permissions/forbidden-directory"
+
+        touch -t #{some_date} "#{test_dir}/permissions/"*
+    EOF
+
+
+    # Awkward extended attribute testcases.
+    config.vm.provision :shell, privileged: false, inline: <<-EOF
+        set -xe
+        mkdir "#{test_dir}/attributes"
+
+        touch "#{test_dir}/attributes/none"
+
+        touch "#{test_dir}/attributes/one"
+        setfattr -n user.greeting -v hello "#{test_dir}/attributes/one"
+
+        touch "#{test_dir}/attributes/two"
+        setfattr -n user.greeting -v hello "#{test_dir}/attributes/two"
+        setfattr -n user.another_greeting -v hi "#{test_dir}/attributes/two"
+
+        #touch "#{test_dir}/attributes/forbidden"
+        #setfattr -n user.greeting -v hello "#{test_dir}/attributes/forbidden"
+        #chmod +a "$YOU deny readextattr" "#{test_dir}/attributes/forbidden"
+
+        mkdir "#{test_dir}/attributes/dirs"
+
+        mkdir "#{test_dir}/attributes/dirs/empty-with-attribute"
+        setfattr -n user.greeting -v hello "#{test_dir}/attributes/dirs/empty-with-attribute"
+
+        mkdir "#{test_dir}/attributes/dirs/full-with-attribute"
+        touch "#{test_dir}/attributes/dirs/full-with-attribute/file"
+        setfattr -n user.greeting -v hello "#{test_dir}/attributes/dirs/full-with-attribute"
+
+        mkdir "#{test_dir}/attributes/dirs/full-but-forbidden"
+        touch "#{test_dir}/attributes/dirs/full-but-forbidden/file"
+        #setfattr -n user.greeting -v hello "#{test_dir}/attributes/dirs/full-but-forbidden"
+        #chmod 000 "#{test_dir}/attributes/dirs/full-but-forbidden"
+        #chmod +a "$YOU deny readextattr" "#{test_dir}/attributes/dirs/full-but-forbidden"
+
+		touch -t #{some_date} "#{test_dir}/attributes"
+        touch -t #{some_date} "#{test_dir}/attributes/"*
+        touch -t #{some_date} "#{test_dir}/attributes/dirs/"*
+        touch -t #{some_date} "#{test_dir}/attributes/dirs/"*/*
+    EOF
+end

+ 0 - 138
generate-testcases.sh

@@ -1,138 +0,0 @@
-#!/bin/bash
-
-# This is a script to generate “awkward” files and directories that the
-# testing scripts use as integration test cases.
-#
-# Tests like these verify that exa is doing the right thing at every step,
-# from command-line parsing to colourising the output properly -- especially
-# on multiple or weird platforms!
-#
-# Examples of the things it generates are:
-# - files with newlines in their name
-# - files with invalid UTF-8 in their name
-# - directories you aren’t allowed to open
-# - files with users and groups that don’t exist
-# - directories you aren’t allowed to read the xattrs for
-
-
-## -- configuration --
-
-# Directory that the files should be generated in.
-DIR=testcases
-
-# You! Yes, you, the name of the user running this script.
-YOU=`whoami`
-
-# Someone with *higher* privileges than yourself, such as root.
-ROOT=root
-
-# A UID that doesn’t map to any user on the system.
-INVALID_UID=666
-
-# A GID that doesn’t map to any group on the system.
-INVALID_GID=616
-
-# Get confirmation from the user before running.
-echo "This script will generate files into the $DIR directory."
-echo "It requires sudo for the '$ROOT' user."
-echo "You may want to edit this file before running it."
-read -r -p "Continue? [y/N] " response
-if [[ ! $response =~ ^([yY][eE][sS]|[yY])$ ]]
-then
-    exit 2
-fi
-
-# First things first, don’t try to overwrite the testcases if they already
-# exist. It’s safer to just start again from scratch.
-if [[ -e "$DIR" ]]
-then
-    echo "'$DIR' already exists - aborting" >&2
-    echo "(you'll probably have to sudo rm it.)" >&2
-    exit 2
-fi
-
-# Abort if anything goes wrong past this point!
-abort() { echo 'Hit an error - aborting' >&2; exit 1; }
-trap 'abort' ERR
-
-# List commands as they are run
-set -x
-
-# Let’s go!
-mkdir "$DIR"
-
-
-## -- links --
-
-mkdir "$DIR/links"
-ln -s / "$DIR/links/root"
-ln -s /usr "$DIR/links/usr"
-ln -s nowhere "$DIR/links/broken"
-
-
-## -- users and groups --
-
-mkdir "$DIR/passwd"
-
-# sudo is needed for these because we technically aren’t a member of the
-# groups (because they don’t exist), and chown and chgrp are smart enough to
-# disallow it!
-
-touch "$DIR/passwd/unknown-uid"
-sudo -u "$ROOT" chown $INVALID_UID "$DIR/passwd/unknown-uid"
-
-touch "$DIR/passwd/unknown-gid"
-sudo -u "$ROOT" chgrp $INVALID_GID "$DIR/passwd/unknown-gid"
-
-
-## -- permissions --
-
-mkdir "$DIR/permissions"
-
-touch "$DIR/permissions/all-permissions"
-chmod 777 "$DIR/permissions/all-permissions"
-
-touch "$DIR/permissions/no-permissions"
-chmod 000 "$DIR/permissions/no-permissions"
-
-mkdir "$DIR/permissions/forbidden-directory"
-chmod 000 "$DIR/permissions/forbidden-directory"
-
-
-## -- extended attributes --
-
-# These tests are optional but the presence of the *directory* is used
-# elsewhere! Yes I know this is a bad practice.
-mkdir "$DIR/attributes"
-
-if hash xattr; then
-    touch "$DIR/attributes/none"
-
-    touch "$DIR/attributes/one"
-    xattr -w greeting hello "$DIR/attributes/one"
-
-    touch "$DIR/attributes/two"
-    xattr -w greeting hello "$DIR/attributes/two"
-    xattr -w another_greeting hi "$DIR/attributes/two"
-
-    touch "$DIR/attributes/forbidden"
-    xattr -w greeting hello "$DIR/attributes/forbidden"
-    chmod +a "$YOU deny readextattr" "$DIR/attributes/forbidden"
-
-    mkdir "$DIR/attributes/dirs"
-
-    mkdir "$DIR/attributes/dirs/empty-with-attribute"
-    xattr -w greeting hello "$DIR/attributes/dirs/empty-with-attribute"
-
-    mkdir "$DIR/attributes/dirs/full-with-attribute"
-    touch "$DIR/attributes/dirs/full-with-attribute/file"
-    xattr -w greeting hello "$DIR/attributes/dirs/full-with-attribute"
-
-    mkdir "$DIR/attributes/dirs/full-but-forbidden"
-    touch "$DIR/attributes/dirs/full-but-forbidden/file"
-    xattr -w greeting hello "$DIR/attributes/dirs/full-but-forbidden"
-    chmod 000 "$DIR/attributes/dirs/full-but-forbidden"
-    chmod +a "$YOU deny readextattr" "$DIR/attributes/dirs/full-but-forbidden"
-else
-    echo "Skipping xattr tests"
-fi

+ 0 - 24
tests/directories.rs

@@ -1,24 +0,0 @@
-extern crate exa;
-use exa::Exa;
-
-/// --------------------------------------------------------------------------
-/// These tests assume that the ‘generate annoying testcases’ script has been
-/// run first. Otherwise, they will break!
-/// --------------------------------------------------------------------------
-
-
-static DIRECTORIES: &'static str = concat!(
-    "\x1B[1;34m", "attributes",  "\x1B[0m", '\n',
-    //"\x1B[1;34m", "filenames",   "\x1B[0m", '\n',
-    "\x1B[1;34m", "links",       "\x1B[0m", '\n',
-    "\x1B[1;34m", "passwd",      "\x1B[0m", '\n',
-    "\x1B[1;34m", "permissions", "\x1B[0m", '\n',
-);
-
-#[test]
-fn directories() {
-    let mut output = Vec::<u8>::new();
-    Exa::new( &[ "-1", "testcases" ], &mut output).unwrap().run().unwrap();
-    assert_eq!(output, DIRECTORIES.as_bytes());
-}
-

+ 0 - 21
tests/links.rs

@@ -1,21 +0,0 @@
-extern crate exa;
-use exa::Exa;
-
-/// --------------------------------------------------------------------------
-/// These tests assume that the ‘generate annoying testcases’ script has been
-/// run first. Otherwise, they will break!
-/// --------------------------------------------------------------------------
-
-
-static LINKS: &'static str = concat!(
-    "\x1B[36m", "broken",  "\x1B[0m", " ", "\x1B[31m",       "->", "\x1B[0m", " ", "\x1B[4;31m", "testcases/links/nowhere", "\x1B[0m", '\n',
-    "\x1B[36m", "root",    "\x1B[0m", " ", "\x1B[38;5;244m", "->", "\x1B[0m", " ", "\x1B[36m",   "/",                       "\x1B[0m", '\n',
-    "\x1B[36m", "usr",     "\x1B[0m", " ", "\x1B[38;5;244m", "->", "\x1B[0m", " ", "\x1B[36m",   "/", "\x1B[1;34m", "usr",  "\x1B[0m", '\n',
-);
-
-#[test]
-fn links() {
-    let mut output = Vec::<u8>::new();
-    Exa::new( &[ "-1", "testcases/links" ], &mut output).unwrap().run().unwrap();
-    assert_eq!(output, LINKS.as_bytes());
-}

+ 0 - 21
tests/permissions.rs

@@ -1,21 +0,0 @@
-extern crate exa;
-use exa::Exa;
-
-/// --------------------------------------------------------------------------
-/// These tests assume that the ‘generate annoying testcases’ script has been
-/// run first. Otherwise, they will break!
-/// --------------------------------------------------------------------------
-
-
-static PERMISSIONS: &'static str = concat!(
-    "\x1B[1;32m", "all-permissions",     "\x1B[0m", '\n',
-    "\x1B[1;34m", "forbidden-directory", "\x1B[0m", '\n',
-                  "no-permissions",                 '\n',
-);
-
-#[test]
-fn permissions() {
-    let mut output = Vec::<u8>::new();
-    Exa::new( &[ "-1", "testcases/permissions" ], &mut output).unwrap().run().unwrap();
-    assert_eq!(output, PERMISSIONS.as_bytes());
-}

+ 4 - 0
xtests/README.md

@@ -0,0 +1,4 @@
+## Extra tests
+
+These extra tests are intended to be run from a Vagrant VM that has already had its environment set up -- see the section in the README for more details.
+

+ 15 - 0
xtests/attributes

@@ -0,0 +1,15 @@
+drwxr-xr-x  - vagrant  1 Jan 12:34 /home/vagrant/testcases/attributes
+drwxr-xr-x  - vagrant  1 Jan 12:34 ├── dirs
+drwxr-xr-x@ - vagrant  1 Jan 12:34 │  ├── empty-with-attribute
+                                   │  │  └── user.greeting (len 5)
+drwxr-xr-x  - vagrant  1 Jan 12:34 │  ├── full-but-forbidden
+.rw-r--r--  0 vagrant  1 Jan 12:34 │  │  └── file
+drwxr-xr-x@ - vagrant  1 Jan 12:34 │  └── full-with-attribute
+                                   │     ├── user.greeting (len 5)
+.rw-r--r--  0 vagrant  1 Jan 12:34 │     └── file
+.rw-r--r--  0 vagrant  1 Jan 12:34 ├── none
+.rw-r--r--@ 0 vagrant  1 Jan 12:34 ├── one
+                                   │  └── user.greeting (len 5)
+.rw-r--r--@ 0 vagrant  1 Jan 12:34 └── two
+                                      ├── user.greeting (len 5)
+                                      └── user.another_greeting (len 2)

+ 3 - 0
xtests/files

@@ -0,0 +1,3 @@
+1_KiB    2_KiB    3_KiB    4_KiB    5_KiB    6_KiB    7_KiB    8_KiB    9_KiB    10_KiB    11_KiB    12_KiB    13_KiB
+1_MiB    2_MiB    3_MiB    4_MiB    5_MiB    6_MiB    7_MiB    8_MiB    9_MiB    10_MiB    11_MiB    12_MiB    13_MiB
+1_bytes  2_bytes  3_bytes  4_bytes  5_bytes  6_bytes  7_bytes  8_bytes  9_bytes  10_bytes  11_bytes  12_bytes  13_bytes

+ 3 - 0
xtests/files_120

@@ -0,0 +1,3 @@
+1_KiB    2_KiB    3_KiB    4_KiB    5_KiB    6_KiB    7_KiB    8_KiB    9_KiB    10_KiB    11_KiB    12_KiB    13_KiB
+1_MiB    2_MiB    3_MiB    4_MiB    5_MiB    6_MiB    7_MiB    8_MiB    9_MiB    10_MiB    11_MiB    12_MiB    13_MiB
+1_bytes  2_bytes  3_bytes  4_bytes  5_bytes  6_bytes  7_bytes  8_bytes  9_bytes  10_bytes  11_bytes  12_bytes  13_bytes

+ 3 - 0
xtests/files_160

@@ -0,0 +1,3 @@
+1_KiB    2_KiB    3_KiB    4_KiB    5_KiB    6_KiB    7_KiB    8_KiB    9_KiB    10_KiB    11_KiB    12_KiB    13_KiB
+1_MiB    2_MiB    3_MiB    4_MiB    5_MiB    6_MiB    7_MiB    8_MiB    9_MiB    10_MiB    11_MiB    12_MiB    13_MiB
+1_bytes  2_bytes  3_bytes  4_bytes  5_bytes  6_bytes  7_bytes  8_bytes  9_bytes  10_bytes  11_bytes  12_bytes  13_bytes

+ 2 - 0
xtests/files_200

@@ -0,0 +1,2 @@
+1_KiB  1_bytes  2_MiB    3_KiB  3_bytes  4_MiB    5_KiB  5_bytes  6_MiB    7_KiB  7_bytes  8_MiB    9_KiB  9_bytes  10_MiB    11_KiB  11_bytes  12_MiB    13_KiB  13_bytes
+1_MiB  2_KiB    2_bytes  3_MiB  4_KiB    4_bytes  5_MiB  6_KiB    6_bytes  7_MiB  8_KiB    8_bytes  9_MiB  10_KiB   10_bytes  11_MiB  12_KiB    12_bytes  13_MiB  

+ 10 - 0
xtests/files_40

@@ -0,0 +1,10 @@
+1_KiB    4_MiB    7_bytes   11_KiB
+1_MiB    4_bytes  8_KiB     11_MiB
+1_bytes  5_KiB    8_MiB     11_bytes
+2_KiB    5_MiB    8_bytes   12_KiB
+2_MiB    5_bytes  9_KiB     12_MiB
+2_bytes  6_KiB    9_MiB     12_bytes
+3_KiB    6_MiB    9_bytes   13_KiB
+3_MiB    6_bytes  10_KiB    13_MiB
+3_bytes  7_KiB    10_MiB    13_bytes
+4_KiB    7_MiB    10_bytes  

+ 5 - 0
xtests/files_80

@@ -0,0 +1,5 @@
+1_KiB    2_bytes  4_MiB    6_KiB    7_bytes  9_MiB     11_KiB    12_bytes
+1_MiB    3_KiB    4_bytes  6_MiB    8_KiB    9_bytes   11_MiB    13_KiB
+1_bytes  3_MiB    5_KiB    6_bytes  8_MiB    10_KiB    11_bytes  13_MiB
+2_KiB    3_bytes  5_MiB    7_KiB    8_bytes  10_MiB    12_KiB    13_bytes
+2_MiB    4_KiB    5_bytes  7_MiB    9_KiB    10_bytes  12_MiB    

+ 39 - 0
xtests/files_l

@@ -0,0 +1,39 @@
+.rw-r--r-- 1.0k vagrant  1 Jan 12:34 1_KiB
+.rw-r--r-- 1.0M vagrant  1 Jan 12:34 1_MiB
+.rw-r--r--    1 vagrant  1 Jan 12:34 1_bytes
+.rw-r--r-- 2.0k vagrant  1 Jan 12:34 2_KiB
+.rw-r--r-- 2.1M vagrant  1 Jan 12:34 2_MiB
+.rw-r--r--    2 vagrant  1 Jan 12:34 2_bytes
+.rw-r--r-- 3.1k vagrant  1 Jan 12:34 3_KiB
+.rw-r--r-- 3.1M vagrant  1 Jan 12:34 3_MiB
+.rw-r--r--    3 vagrant  1 Jan 12:34 3_bytes
+.rw-r--r-- 4.1k vagrant  1 Jan 12:34 4_KiB
+.rw-r--r-- 4.2M vagrant  1 Jan 12:34 4_MiB
+.rw-r--r--    4 vagrant  1 Jan 12:34 4_bytes
+.rw-r--r-- 5.1k vagrant  1 Jan 12:34 5_KiB
+.rw-r--r-- 5.2M vagrant  1 Jan 12:34 5_MiB
+.rw-r--r--    5 vagrant  1 Jan 12:34 5_bytes
+.rw-r--r-- 6.1k vagrant  1 Jan 12:34 6_KiB
+.rw-r--r-- 6.3M vagrant  1 Jan 12:34 6_MiB
+.rw-r--r--    6 vagrant  1 Jan 12:34 6_bytes
+.rw-r--r-- 7.2k vagrant  1 Jan 12:34 7_KiB
+.rw-r--r-- 7.3M vagrant  1 Jan 12:34 7_MiB
+.rw-r--r--    7 vagrant  1 Jan 12:34 7_bytes
+.rw-r--r-- 8.2k vagrant  1 Jan 12:34 8_KiB
+.rw-r--r-- 8.4M vagrant  1 Jan 12:34 8_MiB
+.rw-r--r--    8 vagrant  1 Jan 12:34 8_bytes
+.rw-r--r-- 9.2k vagrant  1 Jan 12:34 9_KiB
+.rw-r--r-- 9.4M vagrant  1 Jan 12:34 9_MiB
+.rw-r--r--    9 vagrant  1 Jan 12:34 9_bytes
+.rw-r--r--  10k vagrant  1 Jan 12:34 10_KiB
+.rw-r--r--  10M vagrant  1 Jan 12:34 10_MiB
+.rw-r--r--   10 vagrant  1 Jan 12:34 10_bytes
+.rw-r--r--  11k vagrant  1 Jan 12:34 11_KiB
+.rw-r--r--  11M vagrant  1 Jan 12:34 11_MiB
+.rw-r--r--   11 vagrant  1 Jan 12:34 11_bytes
+.rw-r--r--  12k vagrant  1 Jan 12:34 12_KiB
+.rw-r--r--  12M vagrant  1 Jan 12:34 12_MiB
+.rw-r--r--   12 vagrant  1 Jan 12:34 12_bytes
+.rw-r--r--  13k vagrant  1 Jan 12:34 13_KiB
+.rw-r--r--  13M vagrant  1 Jan 12:34 13_MiB
+.rw-r--r--   13 vagrant  1 Jan 12:34 13_bytes

+ 20 - 0
xtests/files_lG_120

@@ -0,0 +1,20 @@
+.rw-r--r-- 1.0k vagrant  1 Jan 12:34 1_KiB      .rw-r--r--    7 vagrant  1 Jan 12:34 7_bytes
+.rw-r--r-- 1.0M vagrant  1 Jan 12:34 1_MiB      .rw-r--r-- 8.2k vagrant  1 Jan 12:34 8_KiB
+.rw-r--r--    1 vagrant  1 Jan 12:34 1_bytes    .rw-r--r-- 8.4M vagrant  1 Jan 12:34 8_MiB
+.rw-r--r-- 2.0k vagrant  1 Jan 12:34 2_KiB      .rw-r--r--    8 vagrant  1 Jan 12:34 8_bytes
+.rw-r--r-- 2.1M vagrant  1 Jan 12:34 2_MiB      .rw-r--r-- 9.2k vagrant  1 Jan 12:34 9_KiB
+.rw-r--r--    2 vagrant  1 Jan 12:34 2_bytes    .rw-r--r-- 9.4M vagrant  1 Jan 12:34 9_MiB
+.rw-r--r-- 3.1k vagrant  1 Jan 12:34 3_KiB      .rw-r--r--    9 vagrant  1 Jan 12:34 9_bytes
+.rw-r--r-- 3.1M vagrant  1 Jan 12:34 3_MiB      .rw-r--r--  10k vagrant  1 Jan 12:34 10_KiB
+.rw-r--r--    3 vagrant  1 Jan 12:34 3_bytes    .rw-r--r--  10M vagrant  1 Jan 12:34 10_MiB
+.rw-r--r-- 4.1k vagrant  1 Jan 12:34 4_KiB      .rw-r--r--   10 vagrant  1 Jan 12:34 10_bytes
+.rw-r--r-- 4.2M vagrant  1 Jan 12:34 4_MiB      .rw-r--r--  11k vagrant  1 Jan 12:34 11_KiB
+.rw-r--r--    4 vagrant  1 Jan 12:34 4_bytes    .rw-r--r--  11M vagrant  1 Jan 12:34 11_MiB
+.rw-r--r-- 5.1k vagrant  1 Jan 12:34 5_KiB      .rw-r--r--   11 vagrant  1 Jan 12:34 11_bytes
+.rw-r--r-- 5.2M vagrant  1 Jan 12:34 5_MiB      .rw-r--r--  12k vagrant  1 Jan 12:34 12_KiB
+.rw-r--r--    5 vagrant  1 Jan 12:34 5_bytes    .rw-r--r--  12M vagrant  1 Jan 12:34 12_MiB
+.rw-r--r-- 6.1k vagrant  1 Jan 12:34 6_KiB      .rw-r--r--   12 vagrant  1 Jan 12:34 12_bytes
+.rw-r--r-- 6.3M vagrant  1 Jan 12:34 6_MiB      .rw-r--r--  13k vagrant  1 Jan 12:34 13_KiB
+.rw-r--r--    6 vagrant  1 Jan 12:34 6_bytes    .rw-r--r--  13M vagrant  1 Jan 12:34 13_MiB
+.rw-r--r-- 7.2k vagrant  1 Jan 12:34 7_KiB      .rw-r--r--   13 vagrant  1 Jan 12:34 13_bytes
+.rw-r--r-- 7.3M vagrant  1 Jan 12:34 7_MiB      

+ 13 - 0
xtests/files_lG_160

@@ -0,0 +1,13 @@
+.rw-r--r-- 1.0k vagrant  1 Jan 12:34 1_KiB      .rw-r--r-- 5.2M vagrant  1 Jan 12:34 5_MiB      .rw-r--r--   9 vagrant  1 Jan 12:34 9_bytes
+.rw-r--r-- 1.0M vagrant  1 Jan 12:34 1_MiB      .rw-r--r--    5 vagrant  1 Jan 12:34 5_bytes    .rw-r--r-- 10k vagrant  1 Jan 12:34 10_KiB
+.rw-r--r--    1 vagrant  1 Jan 12:34 1_bytes    .rw-r--r-- 6.1k vagrant  1 Jan 12:34 6_KiB      .rw-r--r-- 10M vagrant  1 Jan 12:34 10_MiB
+.rw-r--r-- 2.0k vagrant  1 Jan 12:34 2_KiB      .rw-r--r-- 6.3M vagrant  1 Jan 12:34 6_MiB      .rw-r--r--  10 vagrant  1 Jan 12:34 10_bytes
+.rw-r--r-- 2.1M vagrant  1 Jan 12:34 2_MiB      .rw-r--r--    6 vagrant  1 Jan 12:34 6_bytes    .rw-r--r-- 11k vagrant  1 Jan 12:34 11_KiB
+.rw-r--r--    2 vagrant  1 Jan 12:34 2_bytes    .rw-r--r-- 7.2k vagrant  1 Jan 12:34 7_KiB      .rw-r--r-- 11M vagrant  1 Jan 12:34 11_MiB
+.rw-r--r-- 3.1k vagrant  1 Jan 12:34 3_KiB      .rw-r--r-- 7.3M vagrant  1 Jan 12:34 7_MiB      .rw-r--r--  11 vagrant  1 Jan 12:34 11_bytes
+.rw-r--r-- 3.1M vagrant  1 Jan 12:34 3_MiB      .rw-r--r--    7 vagrant  1 Jan 12:34 7_bytes    .rw-r--r-- 12k vagrant  1 Jan 12:34 12_KiB
+.rw-r--r--    3 vagrant  1 Jan 12:34 3_bytes    .rw-r--r-- 8.2k vagrant  1 Jan 12:34 8_KiB      .rw-r--r-- 12M vagrant  1 Jan 12:34 12_MiB
+.rw-r--r-- 4.1k vagrant  1 Jan 12:34 4_KiB      .rw-r--r-- 8.4M vagrant  1 Jan 12:34 8_MiB      .rw-r--r--  12 vagrant  1 Jan 12:34 12_bytes
+.rw-r--r-- 4.2M vagrant  1 Jan 12:34 4_MiB      .rw-r--r--    8 vagrant  1 Jan 12:34 8_bytes    .rw-r--r-- 13k vagrant  1 Jan 12:34 13_KiB
+.rw-r--r--    4 vagrant  1 Jan 12:34 4_bytes    .rw-r--r-- 9.2k vagrant  1 Jan 12:34 9_KiB      .rw-r--r-- 13M vagrant  1 Jan 12:34 13_MiB
+.rw-r--r-- 5.1k vagrant  1 Jan 12:34 5_KiB      .rw-r--r-- 9.4M vagrant  1 Jan 12:34 9_MiB      .rw-r--r--  13 vagrant  1 Jan 12:34 13_bytes

+ 10 - 0
xtests/files_lG_200

@@ -0,0 +1,10 @@
+.rw-r--r-- 1.0k vagrant  1 Jan 12:34 1_KiB      .rw-r--r-- 4.2M vagrant  1 Jan 12:34 4_MiB      .rw-r--r--    7 vagrant  1 Jan 12:34 7_bytes     .rw-r--r-- 11k vagrant  1 Jan 12:34 11_KiB
+.rw-r--r-- 1.0M vagrant  1 Jan 12:34 1_MiB      .rw-r--r--    4 vagrant  1 Jan 12:34 4_bytes    .rw-r--r-- 8.2k vagrant  1 Jan 12:34 8_KiB       .rw-r--r-- 11M vagrant  1 Jan 12:34 11_MiB
+.rw-r--r--    1 vagrant  1 Jan 12:34 1_bytes    .rw-r--r-- 5.1k vagrant  1 Jan 12:34 5_KiB      .rw-r--r-- 8.4M vagrant  1 Jan 12:34 8_MiB       .rw-r--r--  11 vagrant  1 Jan 12:34 11_bytes
+.rw-r--r-- 2.0k vagrant  1 Jan 12:34 2_KiB      .rw-r--r-- 5.2M vagrant  1 Jan 12:34 5_MiB      .rw-r--r--    8 vagrant  1 Jan 12:34 8_bytes     .rw-r--r-- 12k vagrant  1 Jan 12:34 12_KiB
+.rw-r--r-- 2.1M vagrant  1 Jan 12:34 2_MiB      .rw-r--r--    5 vagrant  1 Jan 12:34 5_bytes    .rw-r--r-- 9.2k vagrant  1 Jan 12:34 9_KiB       .rw-r--r-- 12M vagrant  1 Jan 12:34 12_MiB
+.rw-r--r--    2 vagrant  1 Jan 12:34 2_bytes    .rw-r--r-- 6.1k vagrant  1 Jan 12:34 6_KiB      .rw-r--r-- 9.4M vagrant  1 Jan 12:34 9_MiB       .rw-r--r--  12 vagrant  1 Jan 12:34 12_bytes
+.rw-r--r-- 3.1k vagrant  1 Jan 12:34 3_KiB      .rw-r--r-- 6.3M vagrant  1 Jan 12:34 6_MiB      .rw-r--r--    9 vagrant  1 Jan 12:34 9_bytes     .rw-r--r-- 13k vagrant  1 Jan 12:34 13_KiB
+.rw-r--r-- 3.1M vagrant  1 Jan 12:34 3_MiB      .rw-r--r--    6 vagrant  1 Jan 12:34 6_bytes    .rw-r--r--  10k vagrant  1 Jan 12:34 10_KiB      .rw-r--r-- 13M vagrant  1 Jan 12:34 13_MiB
+.rw-r--r--    3 vagrant  1 Jan 12:34 3_bytes    .rw-r--r-- 7.2k vagrant  1 Jan 12:34 7_KiB      .rw-r--r--  10M vagrant  1 Jan 12:34 10_MiB      .rw-r--r--  13 vagrant  1 Jan 12:34 13_bytes
+.rw-r--r-- 4.1k vagrant  1 Jan 12:34 4_KiB      .rw-r--r-- 7.3M vagrant  1 Jan 12:34 7_MiB      .rw-r--r--   10 vagrant  1 Jan 12:34 10_bytes    

+ 39 - 0
xtests/files_lG_40

@@ -0,0 +1,39 @@
+.rw-r--r-- 1.0k vagrant  1 Jan 12:34 1_KiB
+.rw-r--r-- 1.0M vagrant  1 Jan 12:34 1_MiB
+.rw-r--r--    1 vagrant  1 Jan 12:34 1_bytes
+.rw-r--r-- 2.0k vagrant  1 Jan 12:34 2_KiB
+.rw-r--r-- 2.1M vagrant  1 Jan 12:34 2_MiB
+.rw-r--r--    2 vagrant  1 Jan 12:34 2_bytes
+.rw-r--r-- 3.1k vagrant  1 Jan 12:34 3_KiB
+.rw-r--r-- 3.1M vagrant  1 Jan 12:34 3_MiB
+.rw-r--r--    3 vagrant  1 Jan 12:34 3_bytes
+.rw-r--r-- 4.1k vagrant  1 Jan 12:34 4_KiB
+.rw-r--r-- 4.2M vagrant  1 Jan 12:34 4_MiB
+.rw-r--r--    4 vagrant  1 Jan 12:34 4_bytes
+.rw-r--r-- 5.1k vagrant  1 Jan 12:34 5_KiB
+.rw-r--r-- 5.2M vagrant  1 Jan 12:34 5_MiB
+.rw-r--r--    5 vagrant  1 Jan 12:34 5_bytes
+.rw-r--r-- 6.1k vagrant  1 Jan 12:34 6_KiB
+.rw-r--r-- 6.3M vagrant  1 Jan 12:34 6_MiB
+.rw-r--r--    6 vagrant  1 Jan 12:34 6_bytes
+.rw-r--r-- 7.2k vagrant  1 Jan 12:34 7_KiB
+.rw-r--r-- 7.3M vagrant  1 Jan 12:34 7_MiB
+.rw-r--r--    7 vagrant  1 Jan 12:34 7_bytes
+.rw-r--r-- 8.2k vagrant  1 Jan 12:34 8_KiB
+.rw-r--r-- 8.4M vagrant  1 Jan 12:34 8_MiB
+.rw-r--r--    8 vagrant  1 Jan 12:34 8_bytes
+.rw-r--r-- 9.2k vagrant  1 Jan 12:34 9_KiB
+.rw-r--r-- 9.4M vagrant  1 Jan 12:34 9_MiB
+.rw-r--r--    9 vagrant  1 Jan 12:34 9_bytes
+.rw-r--r--  10k vagrant  1 Jan 12:34 10_KiB
+.rw-r--r--  10M vagrant  1 Jan 12:34 10_MiB
+.rw-r--r--   10 vagrant  1 Jan 12:34 10_bytes
+.rw-r--r--  11k vagrant  1 Jan 12:34 11_KiB
+.rw-r--r--  11M vagrant  1 Jan 12:34 11_MiB
+.rw-r--r--   11 vagrant  1 Jan 12:34 11_bytes
+.rw-r--r--  12k vagrant  1 Jan 12:34 12_KiB
+.rw-r--r--  12M vagrant  1 Jan 12:34 12_MiB
+.rw-r--r--   12 vagrant  1 Jan 12:34 12_bytes
+.rw-r--r--  13k vagrant  1 Jan 12:34 13_KiB
+.rw-r--r--  13M vagrant  1 Jan 12:34 13_MiB
+.rw-r--r--   13 vagrant  1 Jan 12:34 13_bytes

+ 39 - 0
xtests/files_lG_80

@@ -0,0 +1,39 @@
+.rw-r--r-- 1.0k vagrant  1 Jan 12:34 1_KiB
+.rw-r--r-- 1.0M vagrant  1 Jan 12:34 1_MiB
+.rw-r--r--    1 vagrant  1 Jan 12:34 1_bytes
+.rw-r--r-- 2.0k vagrant  1 Jan 12:34 2_KiB
+.rw-r--r-- 2.1M vagrant  1 Jan 12:34 2_MiB
+.rw-r--r--    2 vagrant  1 Jan 12:34 2_bytes
+.rw-r--r-- 3.1k vagrant  1 Jan 12:34 3_KiB
+.rw-r--r-- 3.1M vagrant  1 Jan 12:34 3_MiB
+.rw-r--r--    3 vagrant  1 Jan 12:34 3_bytes
+.rw-r--r-- 4.1k vagrant  1 Jan 12:34 4_KiB
+.rw-r--r-- 4.2M vagrant  1 Jan 12:34 4_MiB
+.rw-r--r--    4 vagrant  1 Jan 12:34 4_bytes
+.rw-r--r-- 5.1k vagrant  1 Jan 12:34 5_KiB
+.rw-r--r-- 5.2M vagrant  1 Jan 12:34 5_MiB
+.rw-r--r--    5 vagrant  1 Jan 12:34 5_bytes
+.rw-r--r-- 6.1k vagrant  1 Jan 12:34 6_KiB
+.rw-r--r-- 6.3M vagrant  1 Jan 12:34 6_MiB
+.rw-r--r--    6 vagrant  1 Jan 12:34 6_bytes
+.rw-r--r-- 7.2k vagrant  1 Jan 12:34 7_KiB
+.rw-r--r-- 7.3M vagrant  1 Jan 12:34 7_MiB
+.rw-r--r--    7 vagrant  1 Jan 12:34 7_bytes
+.rw-r--r-- 8.2k vagrant  1 Jan 12:34 8_KiB
+.rw-r--r-- 8.4M vagrant  1 Jan 12:34 8_MiB
+.rw-r--r--    8 vagrant  1 Jan 12:34 8_bytes
+.rw-r--r-- 9.2k vagrant  1 Jan 12:34 9_KiB
+.rw-r--r-- 9.4M vagrant  1 Jan 12:34 9_MiB
+.rw-r--r--    9 vagrant  1 Jan 12:34 9_bytes
+.rw-r--r--  10k vagrant  1 Jan 12:34 10_KiB
+.rw-r--r--  10M vagrant  1 Jan 12:34 10_MiB
+.rw-r--r--   10 vagrant  1 Jan 12:34 10_bytes
+.rw-r--r--  11k vagrant  1 Jan 12:34 11_KiB
+.rw-r--r--  11M vagrant  1 Jan 12:34 11_MiB
+.rw-r--r--   11 vagrant  1 Jan 12:34 11_bytes
+.rw-r--r--  12k vagrant  1 Jan 12:34 12_KiB
+.rw-r--r--  12M vagrant  1 Jan 12:34 12_MiB
+.rw-r--r--   12 vagrant  1 Jan 12:34 12_bytes
+.rw-r--r--  13k vagrant  1 Jan 12:34 13_KiB
+.rw-r--r--  13M vagrant  1 Jan 12:34 13_MiB
+.rw-r--r--   13 vagrant  1 Jan 12:34 13_bytes

+ 40 - 0
xtests/files_lh

@@ -0,0 +1,40 @@
+Permissions Size User    Date Modified Name
+.rw-r--r--  1.0k vagrant  1 Jan 12:34  1_KiB
+.rw-r--r--  1.0M vagrant  1 Jan 12:34  1_MiB
+.rw-r--r--     1 vagrant  1 Jan 12:34  1_bytes
+.rw-r--r--  2.0k vagrant  1 Jan 12:34  2_KiB
+.rw-r--r--  2.1M vagrant  1 Jan 12:34  2_MiB
+.rw-r--r--     2 vagrant  1 Jan 12:34  2_bytes
+.rw-r--r--  3.1k vagrant  1 Jan 12:34  3_KiB
+.rw-r--r--  3.1M vagrant  1 Jan 12:34  3_MiB
+.rw-r--r--     3 vagrant  1 Jan 12:34  3_bytes
+.rw-r--r--  4.1k vagrant  1 Jan 12:34  4_KiB
+.rw-r--r--  4.2M vagrant  1 Jan 12:34  4_MiB
+.rw-r--r--     4 vagrant  1 Jan 12:34  4_bytes
+.rw-r--r--  5.1k vagrant  1 Jan 12:34  5_KiB
+.rw-r--r--  5.2M vagrant  1 Jan 12:34  5_MiB
+.rw-r--r--     5 vagrant  1 Jan 12:34  5_bytes
+.rw-r--r--  6.1k vagrant  1 Jan 12:34  6_KiB
+.rw-r--r--  6.3M vagrant  1 Jan 12:34  6_MiB
+.rw-r--r--     6 vagrant  1 Jan 12:34  6_bytes
+.rw-r--r--  7.2k vagrant  1 Jan 12:34  7_KiB
+.rw-r--r--  7.3M vagrant  1 Jan 12:34  7_MiB
+.rw-r--r--     7 vagrant  1 Jan 12:34  7_bytes
+.rw-r--r--  8.2k vagrant  1 Jan 12:34  8_KiB
+.rw-r--r--  8.4M vagrant  1 Jan 12:34  8_MiB
+.rw-r--r--     8 vagrant  1 Jan 12:34  8_bytes
+.rw-r--r--  9.2k vagrant  1 Jan 12:34  9_KiB
+.rw-r--r--  9.4M vagrant  1 Jan 12:34  9_MiB
+.rw-r--r--     9 vagrant  1 Jan 12:34  9_bytes
+.rw-r--r--   10k vagrant  1 Jan 12:34  10_KiB
+.rw-r--r--   10M vagrant  1 Jan 12:34  10_MiB
+.rw-r--r--    10 vagrant  1 Jan 12:34  10_bytes
+.rw-r--r--   11k vagrant  1 Jan 12:34  11_KiB
+.rw-r--r--   11M vagrant  1 Jan 12:34  11_MiB
+.rw-r--r--    11 vagrant  1 Jan 12:34  11_bytes
+.rw-r--r--   12k vagrant  1 Jan 12:34  12_KiB
+.rw-r--r--   12M vagrant  1 Jan 12:34  12_MiB
+.rw-r--r--    12 vagrant  1 Jan 12:34  12_bytes
+.rw-r--r--   13k vagrant  1 Jan 12:34  13_KiB
+.rw-r--r--   13M vagrant  1 Jan 12:34  13_MiB
+.rw-r--r--    13 vagrant  1 Jan 12:34  13_bytes

+ 40 - 0
xtests/files_lhb

@@ -0,0 +1,40 @@
+Permissions  Size User    Date Modified Name
+.rw-r--r--  1.0Ki vagrant  1 Jan 12:34  1_KiB
+.rw-r--r--  1.0Mi vagrant  1 Jan 12:34  1_MiB
+.rw-r--r--      1 vagrant  1 Jan 12:34  1_bytes
+.rw-r--r--  2.0Ki vagrant  1 Jan 12:34  2_KiB
+.rw-r--r--  2.0Mi vagrant  1 Jan 12:34  2_MiB
+.rw-r--r--      2 vagrant  1 Jan 12:34  2_bytes
+.rw-r--r--  3.0Ki vagrant  1 Jan 12:34  3_KiB
+.rw-r--r--  3.0Mi vagrant  1 Jan 12:34  3_MiB
+.rw-r--r--      3 vagrant  1 Jan 12:34  3_bytes
+.rw-r--r--  4.0Ki vagrant  1 Jan 12:34  4_KiB
+.rw-r--r--  4.0Mi vagrant  1 Jan 12:34  4_MiB
+.rw-r--r--      4 vagrant  1 Jan 12:34  4_bytes
+.rw-r--r--  5.0Ki vagrant  1 Jan 12:34  5_KiB
+.rw-r--r--  5.0Mi vagrant  1 Jan 12:34  5_MiB
+.rw-r--r--      5 vagrant  1 Jan 12:34  5_bytes
+.rw-r--r--  6.0Ki vagrant  1 Jan 12:34  6_KiB
+.rw-r--r--  6.0Mi vagrant  1 Jan 12:34  6_MiB
+.rw-r--r--      6 vagrant  1 Jan 12:34  6_bytes
+.rw-r--r--  7.0Ki vagrant  1 Jan 12:34  7_KiB
+.rw-r--r--  7.0Mi vagrant  1 Jan 12:34  7_MiB
+.rw-r--r--      7 vagrant  1 Jan 12:34  7_bytes
+.rw-r--r--  8.0Ki vagrant  1 Jan 12:34  8_KiB
+.rw-r--r--  8.0Mi vagrant  1 Jan 12:34  8_MiB
+.rw-r--r--      8 vagrant  1 Jan 12:34  8_bytes
+.rw-r--r--  9.0Ki vagrant  1 Jan 12:34  9_KiB
+.rw-r--r--  9.0Mi vagrant  1 Jan 12:34  9_MiB
+.rw-r--r--      9 vagrant  1 Jan 12:34  9_bytes
+.rw-r--r--   10Ki vagrant  1 Jan 12:34  10_KiB
+.rw-r--r--   10Mi vagrant  1 Jan 12:34  10_MiB
+.rw-r--r--     10 vagrant  1 Jan 12:34  10_bytes
+.rw-r--r--   11Ki vagrant  1 Jan 12:34  11_KiB
+.rw-r--r--   11Mi vagrant  1 Jan 12:34  11_MiB
+.rw-r--r--     11 vagrant  1 Jan 12:34  11_bytes
+.rw-r--r--   12Ki vagrant  1 Jan 12:34  12_KiB
+.rw-r--r--   12Mi vagrant  1 Jan 12:34  12_MiB
+.rw-r--r--     12 vagrant  1 Jan 12:34  12_bytes
+.rw-r--r--   13Ki vagrant  1 Jan 12:34  13_KiB
+.rw-r--r--   13Mi vagrant  1 Jan 12:34  13_MiB
+.rw-r--r--     13 vagrant  1 Jan 12:34  13_bytes

+ 40 - 0
xtests/files_lhb2

@@ -0,0 +1,40 @@
+Permissions       Size User    Date Modified Name
+.rw-r--r--       1,024 vagrant  1 Jan 12:34  1_KiB
+.rw-r--r--   1,048,576 vagrant  1 Jan 12:34  1_MiB
+.rw-r--r--           1 vagrant  1 Jan 12:34  1_bytes
+.rw-r--r--       2,048 vagrant  1 Jan 12:34  2_KiB
+.rw-r--r--   2,097,152 vagrant  1 Jan 12:34  2_MiB
+.rw-r--r--           2 vagrant  1 Jan 12:34  2_bytes
+.rw-r--r--       3,072 vagrant  1 Jan 12:34  3_KiB
+.rw-r--r--   3,145,728 vagrant  1 Jan 12:34  3_MiB
+.rw-r--r--           3 vagrant  1 Jan 12:34  3_bytes
+.rw-r--r--       4,096 vagrant  1 Jan 12:34  4_KiB
+.rw-r--r--   4,194,304 vagrant  1 Jan 12:34  4_MiB
+.rw-r--r--           4 vagrant  1 Jan 12:34  4_bytes
+.rw-r--r--       5,120 vagrant  1 Jan 12:34  5_KiB
+.rw-r--r--   5,242,880 vagrant  1 Jan 12:34  5_MiB
+.rw-r--r--           5 vagrant  1 Jan 12:34  5_bytes
+.rw-r--r--       6,144 vagrant  1 Jan 12:34  6_KiB
+.rw-r--r--   6,291,456 vagrant  1 Jan 12:34  6_MiB
+.rw-r--r--           6 vagrant  1 Jan 12:34  6_bytes
+.rw-r--r--       7,168 vagrant  1 Jan 12:34  7_KiB
+.rw-r--r--   7,340,032 vagrant  1 Jan 12:34  7_MiB
+.rw-r--r--           7 vagrant  1 Jan 12:34  7_bytes
+.rw-r--r--       8,192 vagrant  1 Jan 12:34  8_KiB
+.rw-r--r--   8,388,608 vagrant  1 Jan 12:34  8_MiB
+.rw-r--r--           8 vagrant  1 Jan 12:34  8_bytes
+.rw-r--r--       9,216 vagrant  1 Jan 12:34  9_KiB
+.rw-r--r--   9,437,184 vagrant  1 Jan 12:34  9_MiB
+.rw-r--r--           9 vagrant  1 Jan 12:34  9_bytes
+.rw-r--r--      10,240 vagrant  1 Jan 12:34  10_KiB
+.rw-r--r--  10,485,760 vagrant  1 Jan 12:34  10_MiB
+.rw-r--r--          10 vagrant  1 Jan 12:34  10_bytes
+.rw-r--r--      11,264 vagrant  1 Jan 12:34  11_KiB
+.rw-r--r--  11,534,336 vagrant  1 Jan 12:34  11_MiB
+.rw-r--r--          11 vagrant  1 Jan 12:34  11_bytes
+.rw-r--r--      12,288 vagrant  1 Jan 12:34  12_KiB
+.rw-r--r--  12,582,912 vagrant  1 Jan 12:34  12_MiB
+.rw-r--r--          12 vagrant  1 Jan 12:34  12_bytes
+.rw-r--r--      13,312 vagrant  1 Jan 12:34  13_KiB
+.rw-r--r--  13,631,488 vagrant  1 Jan 12:34  13_MiB
+.rw-r--r--          13 vagrant  1 Jan 12:34  13_bytes

+ 3 - 0
xtests/passwd

@@ -0,0 +1,3 @@
+Permissions Size User    Group   Date Modified Name
+.rw-r--r--     0 vagrant 616      1 Jan 12:34  unknown-gid
+.rw-r--r--     0 666     vagrant  1 Jan 12:34  unknown-uid

+ 5 - 0
xtests/permissions

@@ -0,0 +1,5 @@
+/home/vagrant/testcases/permissions/forbidden-directory: Permission denied (os error 13)
+Permissions Size User    Group   Date Modified Name
+.rwxrwxrwx     0 vagrant vagrant  1 Jan 12:34  all-permissions
+d---------     - vagrant vagrant  1 Jan 12:34  forbidden-directory
+.---------     0 vagrant vagrant  1 Jan 12:34  no-permissions

+ 45 - 0
xtests/run.sh

@@ -0,0 +1,45 @@
+#!/bin/bash
+set +xe
+
+
+# The exa binary we want to run
+exa="$HOME/target/debug/exa --colour=always"
+
+# Directory containing our awkward testcase files
+testcases=~/testcases
+
+# Directory containing existing test results to compare against
+results=/vagrant/xtests
+
+
+# Long view tests
+$exa $testcases/files -l   | diff -q - $results/files_l     || exit 1
+$exa $testcases/files -lh  | diff -q - $results/files_lh    || exit 1
+$exa $testcases/files -lhb | diff -q - $results/files_lhb   || exit 1
+$exa $testcases/files -lhB | diff -q - $results/files_lhb2  || exit 1
+
+# Grid view tests
+COLUMNS=40  $exa $testcases/files | diff -q - $results/files_40   || exit 1
+COLUMNS=80  $exa $testcases/files | diff -q - $results/files_80   || exit 1
+COLUMNS=120 $exa $testcases/files | diff -q - $results/files_120  || exit 1
+COLUMNS=160 $exa $testcases/files | diff -q - $results/files_160  || exit 1
+COLUMNS=200 $exa $testcases/files | diff -q - $results/files_200  || exit 1
+
+# Long grid view tests
+COLUMNS=40  $exa $testcases/files -lG | diff -q - $results/files_lG_40   || exit 1
+COLUMNS=80  $exa $testcases/files -lG | diff -q - $results/files_lG_80   || exit 1
+COLUMNS=120 $exa $testcases/files -lG | diff -q - $results/files_lG_120  || exit 1
+COLUMNS=160 $exa $testcases/files -lG | diff -q - $results/files_lG_160  || exit 1
+COLUMNS=200 $exa $testcases/files -lG | diff -q - $results/files_lG_200  || exit 1
+
+# Attributes
+$exa $testcases/attributes -l@T | diff -q - $results/attributes  || exit 1
+
+# UIDs and GIDs
+$exa $testcases/passwd -lgh | diff -q - $results/passwd  || exit 1
+
+# Permissions
+$exa $testcases/permissions -lghR 2>&1 | diff -q - $results/permissions  || exit 1
+
+
+echo "All the tests passed!"