| 1 | --- |
| 2 | title: A tester for extfs helpers |
| 3 | ... |
| 4 | |
| 5 | Guide |
| 6 | ===== |
| 7 | |
| 8 | Introduction |
| 9 | ------------ |
| 10 | |
| 11 | The extfs filesystem is composed of various helpers (uzip, urar, uarc, |
| 12 | ...). One command every helper must answer to is "list", to list the |
| 13 | files on its filesystem. |
| 14 | |
| 15 | The purpose of this tester is to test this "list" facet of every helper |
| 16 | to ensure that it indeed works, at present, and that we won't |
| 17 | inadvertently break it, in the future, as we modify its code or MC's |
| 18 | code. |
| 19 | |
| 20 | Key concept: Inputs |
| 21 | ------------------- |
| 22 | |
| 23 | Most helpers work by parsing the output of some 3'rd party software. |
| 24 | Which for them becomes the *input*. Helpers sometimes support **several |
| 25 | variations** of such input. E.g., the uzip helper supports three |
| 26 | variations. |
| 27 | |
| 28 | The tester keeps a repository, in the data folder, of the various inputs |
| 29 | each helper proclaims to support. Each input is stored in a file with an |
| 30 | `.input` suffix. |
| 31 | |
| 32 | Key concept: Outputs |
| 33 | -------------------- |
| 34 | |
| 35 | Along with each input file, the data folder also holds the output the |
| 36 | helper is expected to produce given the corresponding input. Each output |
| 37 | is stored in a file with an `.output` suffix. |
| 38 | |
| 39 | We call this output "the expected output". |
| 40 | |
| 41 | Incidentally, an `.output` file stores not the _raw_ output of the helper |
| 42 | but its output _after parsing_. In other words, what's stored is the |
| 43 | unambiguous _meaning_ of the helper's output. This means that as long as |
| 44 | the helper's code isn't modified in a way that changes the meaning of its |
| 45 | output, the `.output` file remains up-to-date. |
| 46 | |
| 47 | How the tester works |
| 48 | -------------------- |
| 49 | |
| 50 | The tester feeds each helper its prepared inputs and reads back the |
| 51 | helper's "list" answer -- the helper's **output**. This output is a list |
| 52 | of files in a format similar to `ls -l`, which MC is able to parse. The |
| 53 | tester checks that this output parses without errors (errors are, for |
| 54 | example, dates in unsupported format). It then compares this parsed |
| 55 | output (which we call "the actual output") with a previously saved copy |
| 56 | of this output which is known to be correct (and which we call "the |
| 57 | expected output", mentioned in the previous section). This previously |
| 58 | stored output too is in the data folder, in files with `.output` suffix. |
| 59 | |
| 60 | If there's any discrepancy between the *actual output* and the |
| 61 | *expected output*, the test fails. |
| 62 | |
| 63 | Running the tester |
| 64 | ------------------ |
| 65 | |
| 66 | You can run the tester with `make check`. |
| 67 | |
| 68 | But you'll find it more appealing to run the tester with the `run` |
| 69 | script. You'll get a colorful description of what's going on. |
| 70 | |
| 71 | (`run` is created by running `make check` for the 1st time, in the build |
| 72 | tree.) |
| 73 | |
| 74 | Reference |
| 75 | ========= |
| 76 | |
| 77 | The data folder |
| 78 | --------------- |
| 79 | |
| 80 | There are several types of files in the data folder: |
| 81 | |
| 82 | ### Input file ### |
| 83 | |
| 84 | An input file is named: |
| 85 | |
| 86 | > `<helper-name>[.optional-embedded-description].input` |
| 87 | |
| 88 | You create such files simply by redirecting the 3'rd party software's |
| 89 | output to a file. |
| 90 | |
| 91 | ### Output file ### |
| 92 | |
| 93 | This file is named the same as the corresponding input file but with an |
| 94 | `.output` suffix. |
| 95 | |
| 96 | The easiest way to create these files is by invoking the `run` script |
| 97 | with the `--create-output` option. |
| 98 | |
| 99 | ### Environment file ### |
| 100 | |
| 101 | Optional. This file defines environment variables the helper may use to |
| 102 | determine the variant of the input. This file is named the same as the |
| 103 | corresponding input file but with an `.env_var` suffix. |
| 104 | |
| 105 | ### Arguments file ### |
| 106 | |
| 107 | Optional. This file defines extra command-line options to pass to the |
| 108 | [parser](#mc_parse_ls_l). This file is named the same as the |
| 109 | corresponding input file but with an `.args` suffix. |
| 110 | |
| 111 | The contents of an output file must be the same no matter on what |
| 112 | computer and at what time we generate it. Therefore we need to tell the |
| 113 | parser to drop any non-fixed elements in that file. E.g., if the dates |
| 114 | used are relative (as is the case for the default `ls` dates), we need to |
| 115 | drop them with `--drop-mtime`. Similarly, if a helper returns user and |
| 116 | group _names_ that are different than the running user's, they must be |
| 117 | dropped with `--drop-ids`. |
| 118 | |
| 119 | ### Other files ### |
| 120 | |
| 121 | Any other file is ignored by the tester. |
| 122 | |
| 123 | mc_parse_ls_l |
| 124 | ------------- |
| 125 | |
| 126 | This program (built with `make check`) is at the heart of the tester |
| 127 | mechanism. It parses a list of files, in a format similar to `ls -l`, |
| 128 | just as MC would. This program is used to parse (and thereby verify) the |
| 129 | output of the helpers. _You don't need to invoke it yourself;_ but, for |
| 130 | educational purpose, here are a few examples: |
| 131 | |
| 132 | $ LC_ALL=C ls -l | ./mc_parse_ls_l |
| 133 | |
| 134 | $ LC_ALL=C ls -l | ./mc_parse_ls_l --symbolic-ids |
| 135 | |
| 136 | $ LC_ALL=C ls -l | ./mc_parse_ls_l --output-format yaml |
| 137 | |
| 138 | test_all |
| 139 | -------- |
| 140 | |
| 141 | This is the tester itself. You invoke it with `make check`, or with the |
| 142 | `run` script. Invoking it directly is a bit involving because you need to |
| 143 | provide it with 2 or 3 directory paths. `run` does this work for you. |
| 144 | |
| 145 | MC_TEST_EXTFS_LIST_CMD |
| 146 | ---------------------- |
| 147 | |
| 148 | When a helper runs under the tester, the environment variable |
| 149 | `MC_TEST_EXTFS_LIST_CMD` holds the command that's to provide input. The |
| 150 | helper's source code must be modified to use this command instead of the |
| 151 | command it usually uses. This is the device which lets us plug our own |
| 152 | input into the helper and *without which a helper can't be tested!* |
| 153 | |
| 154 | Let's have a little example. The uzoo helper originally has: |
| 155 | |
| 156 | ZOO=zoo |
| 157 | ... |
| 158 | mczoofs_list () { |
| 159 | $ZOO lq "$ARCHIVE" | mawk '......' |
| 160 | } |
| 161 | ... |
| 162 | |
| 163 | To make this helper testable, we need to change the first line to: |
| 164 | |
| 165 | ZOO=${MC_TEST_EXTFS_LIST_CMD:-zoo} |
| 166 | |
| 167 | (or equivalent.) |
| 168 | |
| 169 | The command in `MC_TEST_EXTFS_LIST_CMD` is a black-box for the helper, |
| 170 | and it intentionally ignores any arguments passed to it (so that `lq |
| 171 | "$ARCHIVE"`, above, won't cause problems). |