Skip to content

Commit 90114f0

Browse files
committed
Test HSDS API
1 parent 16eb6e5 commit 90114f0

File tree

16 files changed

+2268
-64
lines changed

16 files changed

+2268
-64
lines changed

.github/workflows/lint-test.yml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,12 +102,18 @@ jobs:
102102
if: steps.poetry-venvs.outputs.cache-hit != 'true'
103103
run: pnpm support:setup
104104

105-
- name: Create sample HDF5 file 🎨
106-
run: pnpm support:sample
105+
- name: Create sample HDF5 files 🎨
106+
run: pnpm support:sample && pnpm support:sample --hsds
107107

108108
- name: Start h5grove support server 🔌
109109
run: pnpm support:h5grove & pnpm wait-on http://localhost:8888 -t 1m
110110

111+
- name: Start HSDS support server 🔌
112+
run: pnpm support:hsds & pnpm wait-on http-get://localhost:5101/?domain=/sample-hsds.h5 -t 1m
113+
114+
- name: Load HSDS sample file 📥
115+
run: pnpm support:hsds:load
116+
111117
- name: Test 👓
112118
run: pnpm test
113119

.gitignore

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,13 @@ dist*/
77
/cypress/snapshots/**/__diff_output__
88
/cypress/snapshots/**/__received_output__
99

10+
/support/hsds/root/
11+
1012
.env.local
1113
.env.*.local
1214

1315
.DS_Store
1416
Thumbs.db
15-
*.log
16-
*.tsbuildinfo
17+
18+
**/*.log
19+
**/*.tsbuildinfo

CONTRIBUTING.md

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -306,8 +306,12 @@ install the recommended extensions.
306306
- `pnpm test --project <project-name>` - run Vitest on a specific project
307307
- `pnpm support:setup` - create/update Poetry environments required for
308308
[testing the providers](#providers-tests)
309-
- `pnpm support:sample` - create `sample.h5`
309+
- `pnpm support:sample` - create `sample.h5` (for h5grove and h5wasm)
310+
- `pnpm support:sample --hsds` - create `sample-hsds.h5` (for HSDS)
310311
- `pnpm support:h5grove` - start h5grove support server
312+
- `pnpm support:hsds` - start HSDS support server
313+
- `pnpm support:hsds:load` - load HSDS sample file (HSDS support server must be
314+
running in separate terminal)
311315
- `pnpm cypress` - open the
312316
[Cypress](https://docs.cypress.io/guides/overview/why-cypress.html) end-to-end
313317
test runner (local dev server must be running in separate terminal)
@@ -380,11 +384,11 @@ when calling `pnpm test`.
380384

381385
### Providers
382386

383-
Two data providers are currently tested through their respective APIs:
384-
`H5GroveApi` and `H5WasmApi`. Each API test (`<provider>-api.test.ts`) works as
387+
The data providers are tested through their respective APIs: `H5GroveApi`,
388+
`H5WasmApi` and `HsdsApi`. Each API test (`<provider>-api.test.ts`) works as
385389
follows:
386390

387-
1. It instanciates the API using a sample file called `sample.h5`, located in
391+
1. It instanciates the API using a sample HDF5 file, located in
388392
`support/sample/dist`, that contains a lot of HDF5 datasets of various shapes
389393
and types.
390394
1. It retrieves the values of all the datasets in the sample file and stores
@@ -412,13 +416,24 @@ pyenv and Poetry:
412416
pyenv exec pnpm support:setup
413417
```
414418

415-
Once the Poetry environments are created, you can create `sample.h5`, start
416-
h5grove and run the API tests:
419+
Once the Poetry environments are created, create the sample files, start the
420+
h5grove and HSDS support servers (h5wasm doesn't need one), and run the API
421+
tests:
417422

418423
```bash
419-
pyenv exec pnpm support:sample
424+
# Create sample files
425+
pyenv exec pnpm support:sample # for h5grove and h5wasm
426+
pyenv exec pnpm support:sample --hsds # for HSDS
427+
428+
# Start support servers in separate terminals
420429
pyenv exec pnpm support:h5grove
421-
pnpm test api
430+
pyenv exec pnpm support:hsds
431+
432+
# Load sample file into HSDS
433+
pyenv exec pnpm support:hsds:load
434+
435+
# Run the API tests
436+
pnpm test api # or `<provider>-api` for a specific provider's API test
422437
```
423438

424439
> If the Python version specified in `.python-version` is globally available on
@@ -440,6 +455,10 @@ environment lacks support for `float128`), you may
440455
it into the `support/sample/dist` folder. However, please beware that the file
441456
may not be up to date.
442457

458+
Environment variables defined in `.env.test` files, and overridden in
459+
`.env.test.local` files, can be used to skip a provider's API test, change its
460+
support server URL, or change its test file.
461+
443462
### Visual regression
444463

445464
Cypress is used for end-to-end testing but also for visual regression testing.

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,11 @@
3030
"lint:root:eslint": "eslint --max-warnings=0",
3131
"lint:root:tsc": "tsc",
3232
"test": "vitest",
33-
"support:setup": "poetry -C support/sample install && poetry -C support/h5grove install",
33+
"support:setup": "poetry -C support/sample install && poetry -C support/h5grove install && poetry -C support/hsds install",
3434
"support:sample": "poetry -C support/sample run python create_h5_sample.py",
3535
"support:h5grove": "poetry -C support/h5grove run python tornado_app.py --basedir ../sample/dist",
36+
"support:hsds": "rm -rf support/hsds/hs.log && poetry -C support/hsds run hsds --root_dir . --config_dir ./config --password_file ./config/passwd.txt",
37+
"support:hsds:load": "rm -rf support/hsds/root/* && poetry -C support/hsds run hsload -e http://localhost:5101 -u test -p test --link ../sample/dist/sample-hsds.h5 /",
3638
"cypress": "cypress open --e2e",
3739
"cypress:run": "cypress run --e2e",
3840
"version": "pnpm -r sync-version && git add .",

packages/app/.env.test

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
# Copy and configure the variables below in your own `.env.test.local` file
44
#####
55

6+
### h5grove API
7+
68
# URL of h5grove support server
79
VITE_H5GROVE_URL=http://localhost:8888
810

@@ -11,3 +13,14 @@ VITE_H5GROVE_TEST_FILE=sample.h5
1113

1214
# Set to `true` to skip testing h5grove API
1315
VITE_H5GROVE_SKIP=
16+
17+
### HSDS API
18+
19+
# URL of HSDS support server
20+
VITE_HSDS_URL=http://localhost:5101
21+
22+
# Name of test domain
23+
VITE_HSDS_TEST_DOMAIN=/sample-hsds.h5
24+
25+
# Set to `true` to skip testing HSDS API
26+
VITE_HSDS_SKIP=

packages/app/src/providers/h5grove/h5grove-api.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,16 @@ import { H5GroveApi } from './h5grove-api';
1313

1414
const SKIP = import.meta.env.VITE_H5GROVE_SKIP === 'true';
1515
const H5GROVE_URL = import.meta.env.VITE_H5GROVE_URL;
16-
const TEST_FILE = import.meta.env.VITE_H5GROVE_TEST_FILE;
16+
const H5GROVE_TEST_FILE = import.meta.env.VITE_H5GROVE_TEST_FILE;
1717
assertEnvVar(H5GROVE_URL, 'VITE_H5GROVE_URL');
18-
assertEnvVar(TEST_FILE, 'VITE_TEST_FILE');
18+
assertEnvVar(H5GROVE_TEST_FILE, 'VITE_H5GROVE_TEST_FILE');
1919

2020
beforeAll(async () => {
2121
await assertListeningAt(H5GROVE_URL);
2222
});
2323

2424
test.skipIf(SKIP)('test file matches snapshot', async () => {
25-
const api = new H5GroveApi(H5GROVE_URL, TEST_FILE);
25+
const api = new H5GroveApi(H5GROVE_URL, H5GROVE_TEST_FILE);
2626

2727
const root = await api.getEntity('/');
2828
assertGroup(root);

packages/app/src/providers/h5grove/h5grove-api.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import {
1818
} from '@h5web/shared/vis-models';
1919

2020
import { DataProviderApi } from '../api';
21-
import { type Fetcher, type ValuesStoreParams } from '../models';
21+
import { type ValuesStoreParams } from '../models';
2222
import { createBasicFetcher, FetcherError, toJSON } from '../utils';
2323
import {
2424
type H5GroveAttrValuesResponse,
@@ -38,7 +38,7 @@ export class H5GroveApi extends DataProviderApi {
3838
public constructor(
3939
private readonly baseURL: string,
4040
filepath: string,
41-
private readonly fetcher: Fetcher = createBasicFetcher(),
41+
private readonly fetcher = createBasicFetcher(),
4242
private readonly _getExportURL?: DataProviderApi['getExportURL'],
4343
) {
4444
super(filepath);
Binary file not shown.
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import {
2+
assertDataset,
3+
assertEnvVar,
4+
assertGroup,
5+
assertGroupWithChildren,
6+
hasNonNullShape,
7+
} from '@h5web/shared/guards';
8+
import { beforeAll, expect, test } from 'vitest';
9+
10+
import { assertListeningAt } from '../../test-utils';
11+
import { getValueOrError } from '../utils';
12+
import { HsdsApi } from './hsds-api';
13+
14+
const SKIP = import.meta.env.VITE_HSDS_SKIP === 'true';
15+
const HSDS_URL = import.meta.env.VITE_HSDS_URL;
16+
const HSDS_TEST_DOMAIN = import.meta.env.VITE_HSDS_TEST_DOMAIN;
17+
assertEnvVar(HSDS_URL, 'VITE_HSDS_URL');
18+
assertEnvVar(HSDS_TEST_DOMAIN, 'VITE_HSDS_TEST_DOMAIN');
19+
20+
beforeAll(async () => {
21+
await assertListeningAt(HSDS_URL);
22+
});
23+
24+
test.skipIf(SKIP)('test file matches snapshot', async () => {
25+
const api = new HsdsApi(HSDS_URL, HSDS_TEST_DOMAIN);
26+
27+
const root = await api.getEntity('/');
28+
assertGroup(root);
29+
assertGroupWithChildren(root);
30+
31+
const children = await Promise.all(
32+
root.children.map(async (child) => {
33+
assertDataset(child);
34+
const { name, shape, type, rawType } = child;
35+
36+
const value = hasNonNullShape(child)
37+
? await getValueOrError(api, child)
38+
: null;
39+
40+
return { name, shape, type, rawType, value };
41+
}),
42+
);
43+
44+
expect(children).toMatchSnapshot();
45+
});

packages/app/src/providers/hsds/hsds-api.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ import {
2424
} from '@h5web/shared/vis-models';
2525

2626
import { DataProviderApi } from '../api';
27-
import { type Fetcher, type ValuesStoreParams } from '../models';
28-
import { FetcherError, toJSON } from '../utils';
27+
import { type ValuesStoreParams } from '../models';
28+
import { createBasicFetcher, FetcherError, toJSON } from '../utils';
2929
import {
3030
type BaseHsdsEntity,
3131
type HsdsAttribute,
@@ -60,7 +60,7 @@ export class HsdsApi extends DataProviderApi {
6060
public constructor(
6161
private readonly baseURL: string,
6262
filepath: string,
63-
private readonly fetcher: Fetcher,
63+
private readonly fetcher = createBasicFetcher(),
6464
private readonly _getExportURL?: DataProviderApi['getExportURL'],
6565
) {
6666
super(filepath);

0 commit comments

Comments
 (0)