errno.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. /*
  2. * Copyright (C) 2024 Puter Technologies Inc.
  3. *
  4. * This file is part of Phoenix Shell.
  5. *
  6. * Phoenix Shell is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU Affero General Public License as published
  8. * by the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU Affero General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Affero General Public License
  17. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  18. */
  19. import assert from 'assert';
  20. import { MakeTestContext } from './harness.js'
  21. import builtins from '../../src/puter-shell/coreutils/__exports__.js';
  22. import { ErrorCodes, ErrorMetadata } from '@heyputer/puter-js-common/src/PosixError.js';
  23. export const runErrnoTests = () => {
  24. describe('errno', function () {
  25. const testCases = [
  26. {
  27. description: 'exits normally if nothing is passed in',
  28. input: [ ],
  29. values: {},
  30. expectedStdout: '',
  31. expectedStderr: '',
  32. expectedFail: false,
  33. },
  34. {
  35. description: 'can search by number',
  36. input: [ ErrorMetadata.get(ErrorCodes.EFBIG).code.toString() ],
  37. values: {},
  38. expectedStdout: 'EFBIG 27 File too big\n',
  39. expectedStderr: '',
  40. expectedFail: false,
  41. },
  42. {
  43. description: 'can search by number',
  44. input: [ ErrorCodes.EIO.description ],
  45. values: {},
  46. expectedStdout: 'EIO 5 IO error\n',
  47. expectedStderr: '',
  48. expectedFail: false,
  49. },
  50. {
  51. description: 'prints an error message and returns a code > 0 if an error is not found',
  52. input: [ 'NOT-A-REAL-ERROR' ],
  53. values: {},
  54. expectedStdout: '',
  55. expectedStderr: 'ERROR: Not understood: NOT-A-REAL-ERROR\n',
  56. expectedFail: true,
  57. },
  58. {
  59. description: 'accepts multiple arguments and prints each',
  60. input: [ ErrorMetadata.get(ErrorCodes.ENOENT).code.toString(), 'NOT-A-REAL-ERROR', ErrorCodes.EPIPE.description ],
  61. values: {},
  62. expectedStdout:
  63. 'ENOENT 2 File or directory not found\n' +
  64. 'EPIPE 32 Pipe broken\n',
  65. expectedStderr: 'ERROR: Not understood: NOT-A-REAL-ERROR\n',
  66. expectedFail: true,
  67. },
  68. {
  69. description: 'searches descriptions if --search is provided',
  70. input: [ 'directory' ],
  71. values: { search: true },
  72. expectedStdout:
  73. 'ENOENT 2 File or directory not found\n' +
  74. 'ENOTDIR 20 Is not a directory\n' +
  75. 'EISDIR 21 Is a directory\n' +
  76. 'ENOTEMPTY 39 Directory is not empty\n',
  77. expectedStderr: '',
  78. expectedFail: false,
  79. },
  80. {
  81. description: 'lists all errors if --list is provided, ignoring parameters',
  82. input: [ 'directory' ],
  83. values: { list: true },
  84. expectedStdout:
  85. 'EPERM 1 Operation not permitted\n' +
  86. 'ENOENT 2 File or directory not found\n' +
  87. 'EIO 5 IO error\n' +
  88. 'EACCES 13 Permission denied\n' +
  89. 'EEXIST 17 File already exists\n' +
  90. 'ENOTDIR 20 Is not a directory\n' +
  91. 'EISDIR 21 Is a directory\n' +
  92. 'EINVAL 22 Argument invalid\n' +
  93. 'EMFILE 24 Too many open files\n' +
  94. 'EFBIG 27 File too big\n' +
  95. 'ENOSPC 28 Device out of space\n' +
  96. 'EPIPE 32 Pipe broken\n' +
  97. 'ENOTEMPTY 39 Directory is not empty\n' +
  98. 'EADDRINUSE 98 Address already in use\n' +
  99. 'ECONNRESET 104 Connection reset\n' +
  100. 'ETIMEDOUT 110 Connection timed out\n' +
  101. 'ECONNREFUSED 111 Connection refused\n',
  102. expectedStderr: '',
  103. expectedFail: false,
  104. },
  105. {
  106. description: '--search overrides --list',
  107. input: [ 'directory' ],
  108. values: { list: true, search: true },
  109. expectedStdout:
  110. 'ENOENT 2 File or directory not found\n' +
  111. 'ENOTDIR 20 Is not a directory\n' +
  112. 'EISDIR 21 Is a directory\n' +
  113. 'ENOTEMPTY 39 Directory is not empty\n',
  114. expectedStderr: '',
  115. expectedFail: false,
  116. },
  117. ];
  118. for (const { description, input, values, expectedStdout, expectedStderr, expectedFail } of testCases) {
  119. it(description, async () => {
  120. let ctx = MakeTestContext(builtins.errno, { positionals: input, values });
  121. let hadError = false;
  122. try {
  123. const result = await builtins.errno.execute(ctx);
  124. if (!expectedFail) {
  125. assert.equal(result, undefined, 'should exit successfully, returning nothing');
  126. }
  127. } catch (e) {
  128. hadError = true;
  129. if (!expectedFail) {
  130. assert.fail(e);
  131. }
  132. }
  133. if (expectedFail && !hadError) {
  134. assert.fail('should have returned an error code');
  135. }
  136. assert.equal(ctx.externs.out.output, expectedStdout, 'wrong output written to stdout');
  137. assert.equal(ctx.externs.err.output, expectedStderr, 'wrong output written to stderr');
  138. });
  139. }
  140. });
  141. }