mirror of
https://github.com/HeyPuter/puter.git
synced 2026-01-06 05:00:29 -06:00
fs: fix failed tests in move and stat
This commit is contained in:
@@ -147,7 +147,7 @@ class HLMove extends HLFilesystemOperation {
|
||||
if ( await dest.exists() ) {
|
||||
if ( ! values.overwrite && ! values.dedupe_name ) {
|
||||
throw APIError.create('item_with_same_name_exists', null, {
|
||||
entry_name: target_name,
|
||||
entry_name: await dest.get('name'),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -55,7 +55,10 @@ class HLStat extends HLFilesystemOperation {
|
||||
|
||||
if (return_size) await subject.fetchSize(user);
|
||||
if (return_subdomains) await subject.fetchSubdomains(user)
|
||||
if (return_permissions) await subject.fetchShares();
|
||||
if (return_permissions) {
|
||||
subject.entry.permissions = [];
|
||||
await subject.fetchShares();
|
||||
}
|
||||
if (return_versions) await subject.fetchVersions();
|
||||
|
||||
await subject.fetchIsEmpty();
|
||||
|
||||
@@ -1,5 +1,130 @@
|
||||
## It takes 3 steps to run the tests :)
|
||||
# API Tester
|
||||
|
||||
1. run `npm install`
|
||||
2. copy `example_config.yml` and add the correct values
|
||||
3. run `node apitest.js --config=your_config_file.yml`
|
||||
A test framework for testing the backend API of puter.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [API Tester](#api-tester)
|
||||
- [How to use](#how-to-use)
|
||||
- [Workflow](#workflow)
|
||||
- [Shorthands](#shorthands)
|
||||
- [Basic Concepts](#basic-concepts)
|
||||
- [Behaviors](#behaviors)
|
||||
- [Isolation of `t.cwd`](#isolation-of-t-cwd)
|
||||
- [Implementation](#implementation)
|
||||
- [TODO](#todo)
|
||||
|
||||
## How to use
|
||||
|
||||
### Workflow
|
||||
|
||||
All commands below should be run from the root directory of puter.
|
||||
|
||||
1. (Optional) Start a backend server:
|
||||
|
||||
```bash
|
||||
npm start
|
||||
```
|
||||
|
||||
2. Copy `example_config.yml` and add the correct values:
|
||||
|
||||
```bash
|
||||
cp ./tools/api-tester/example_config.yml ./tools/api-tester/config.yml
|
||||
```
|
||||
|
||||
Fields:
|
||||
- url: The endpoint of the backend server. (default: http://api.puter.localhost:4100/)
|
||||
- username: The username of the admin user. (e.g. admin)
|
||||
- token: The token of the user. (can be obtained by typing `puter.authToken` in Developer Tools's console)
|
||||
|
||||
3. Run the tests:
|
||||
|
||||
```bash
|
||||
node ./tools/api-tester/apitest.js --config=./tools/api-tester/config.yml
|
||||
```
|
||||
|
||||
### Shorthands
|
||||
|
||||
- Run unit tests only:
|
||||
|
||||
```bash
|
||||
node ./tools/api-tester/apitest.js --config=./tools/api-tester/config.yml --unit
|
||||
```
|
||||
|
||||
- Filter tests by suite name:
|
||||
|
||||
```bash
|
||||
node ./tools/api-tester/apitest.js --config=./tools/api-tester/config.yml --unit --suite=mkdir
|
||||
```
|
||||
|
||||
- Rerun failed tests in the last run:
|
||||
|
||||
```bash
|
||||
node ./tools/api-tester/apitest.js --config=./tools/api-tester/config.yml --rerun-failed
|
||||
```
|
||||
|
||||
## Basic Concepts
|
||||
|
||||
A *test case* is a function that tests a specific behavior of the backend API. Test cases can be nested:
|
||||
|
||||
```js
|
||||
await t.case('normal mkdir', async () => {
|
||||
const result = await t.mkdir_v2('foo');
|
||||
expect(result.name).equal('foo');
|
||||
|
||||
await t.case('can stat the created directory', async () => {
|
||||
const stat = await t.stat('foo');
|
||||
expect(stat.name).equal('foo');
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
A *test suite* is a collection of test cases. A `.js` file should contain exactly one test suite.
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
name: 'mkdir',
|
||||
do: async t => {
|
||||
await t.case('normal mkdir', async () => {
|
||||
...
|
||||
});
|
||||
|
||||
await t.case('recursive mkdir', async () => {
|
||||
...
|
||||
});
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
## Behaviors
|
||||
|
||||
### Isolation of `t.cwd`
|
||||
|
||||
- `t.cwd` is reset at the beginning of each test suite, since a test suite usually doesn't want to be affected by other test suites.
|
||||
- `t.cwd` will be inherited from the cases in the same test suite, since a leaf case might want to share the context with its parent/sibling cases.
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
name: 'readdir',
|
||||
do: async t => {
|
||||
// t.cwd is reset to /admin/api_test
|
||||
|
||||
await t.case('normal mkdir', async () => {
|
||||
// inherits cwd from parent/sibling cases
|
||||
|
||||
await t.case('mkdir in subdir', async () => {
|
||||
// inherits cwd from parent/sibling cases
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
## Implementation
|
||||
|
||||
- Test suites are registered in `tools/api-tester/tests/__entry__.js`.
|
||||
|
||||
## TODO
|
||||
|
||||
- [ ] Update usage of apitest.js. (Is it possible to generate the usage automatically?)
|
||||
- [ ] Integrate it into CI, optionally running it only in specific scenarios (e.g., when backend code changes).
|
||||
|
||||
@@ -9,7 +9,7 @@ const { parseArgs } = require('node:util');
|
||||
|
||||
const args = process.argv.slice(2);
|
||||
|
||||
let config, report;
|
||||
let config, report, suiteName;
|
||||
|
||||
try {
|
||||
const parsed = parseArgs({
|
||||
@@ -23,6 +23,7 @@ try {
|
||||
onlycase: { type: 'string' },
|
||||
bench: { type: 'boolean' },
|
||||
unit: { type: 'boolean' },
|
||||
suite: { type: 'string' },
|
||||
},
|
||||
allowPositionals: true,
|
||||
});
|
||||
@@ -33,9 +34,12 @@ try {
|
||||
onlycase,
|
||||
bench,
|
||||
unit,
|
||||
suite: suiteName,
|
||||
}, positionals: [id] } = parsed);
|
||||
|
||||
onlycase = onlycase !== undefined ? Number.parseInt(onlycase) : undefined;
|
||||
// Ensure suiteName is a string or undefined
|
||||
suiteName = suiteName || undefined;
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
console.error(
|
||||
@@ -44,6 +48,7 @@ try {
|
||||
'Options:\n' +
|
||||
' --config=<path> (required) Path to configuration file\n' +
|
||||
' --report=<path> (optional) Output file for full test results\n' +
|
||||
' --suite=<name> (optional) Run only tests with matching suite name\n' +
|
||||
''
|
||||
);
|
||||
process.exit(1);
|
||||
@@ -56,6 +61,7 @@ const main = async () => {
|
||||
const context = {
|
||||
options: {
|
||||
onlycase,
|
||||
suite: suiteName,
|
||||
}
|
||||
};
|
||||
const ts = new TestSDK(conf, context);
|
||||
@@ -87,7 +93,7 @@ const main = async () => {
|
||||
}
|
||||
|
||||
if ( unit ) {
|
||||
await registry.run_all_tests();
|
||||
await registry.run_all_tests(suiteName);
|
||||
} else if ( bench ) {
|
||||
await registry.run_all_benches();
|
||||
} else {
|
||||
|
||||
@@ -18,8 +18,12 @@ module.exports = class TestRegistry {
|
||||
this.benches[id] = benchDefinition;
|
||||
}
|
||||
|
||||
async run_all_tests () {
|
||||
async run_all_tests(suiteName) {
|
||||
for ( const id in this.tests ) {
|
||||
if (suiteName && id !== suiteName) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const testDefinition = this.tests[id];
|
||||
await this.t.runTestPackage(testDefinition);
|
||||
}
|
||||
|
||||
@@ -96,8 +96,8 @@ module.exports = class TestSDK {
|
||||
async case (id, fn) {
|
||||
this.nameStack.push(id);
|
||||
|
||||
// Always reset cwd for top-level cases to prevent them from affecting
|
||||
// each other.
|
||||
// Always reset cwd at the beginning of a test suite to prevent it
|
||||
// from affected by others.
|
||||
if (this.nameStack.length === 1) {
|
||||
this.resetCwd();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user