Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions ICD_test_stages/file_browser.tests
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
src/test/ACCESS_WEBSOCKET.test.ts
src/test/ACCESS_CARTA_DEFAULT.test.ts
src/test/ACCESS_CARTA_DEFAULT_CONCURRENT.test.ts
src/test/ACCESS_CARTA_KNOWN_SESSION.test.ts
src/test/ACCESS_CARTA_NO_CLIENT_FEATURE.test.ts
src/test/ACCESS_CARTA_SAME_ID_TWICE.test.ts
src/test/GET_FILELIST_ROOTPATH_CONCURRENT.test.ts
src/test/FILEINFO_FITS_MULTIHDU.test.ts
src/test/FILEINFO_EXCEPTIONS.test.ts
Expand Down
60 changes: 45 additions & 15 deletions docs/source/access_carta.rst
Original file line number Diff line number Diff line change
Expand Up @@ -46,22 +46,26 @@ This test verifies that a default connection to the backend succeeds and returns

- REGISTER_VIEWER_ACK.success = True

- REGISTER_VIEWER_ACK.session_id is not None
- REGISTER_VIEWER_ACK.session_id is assigned by the backend (not 0)

- REGISTER_VIEWER_ACK.message is not empty
- REGISTER_VIEWER_ACK.session_type = CARTA.SessionType.NEW

- REGISTER_VIEWER_ACK.platformStrings is not empty
- REGISTER_VIEWER_ACK.message is a non-empty string reporting the assigned session_id

- REGISTER_VIEWER_ACK.user_preferences = None (empty object)
- REGISTER_VIEWER_ACK.server_feature_flags does not have the READ_ONLY bit set

- REGISTER_VIEWER_ACK.user_layouts = None (empty object)
- REGISTER_VIEWER_ACK.platform_strings has non-empty release_info, deployment, architecture and platform entries, where platform is "macOS" or "Linux"

- REGISTER_VIEWER_ACK.user_preferences = None (empty object), and server_feature_flags does not have the USER_PREFERENCES bit set

- REGISTER_VIEWER_ACK.user_layouts = None (empty object), and server_feature_flags does not have the USER_LAYOUTS bit set

ACCESS_CARTA_DEFAULT_CONCURRENT
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

See the `source code <https://github.com/CARTAvis/ICD-RxJS/blob/dev/src/test/ACCESS_CARTA_DEFAULT_CONCURRENT.test.ts>`__.

This test verifies that multiple concurrent connections (10 clients) to the backend all succeed, each receiving a unique session ID.
This test verifies that multiple concurrent connections (10 clients) to the backend all succeed, each receiving a unique session ID. The 10 clients connect simultaneously, so the backend registers them in parallel rather than one after another.

1. 10 clients each send: **REGISTER_VIEWER** (``RegisterViewer``)

Expand All @@ -76,15 +80,17 @@ This test verifies that multiple concurrent connections (10 clients) to the back

- REGISTER_VIEWER_ACK.success = True

- REGISTER_VIEWER_ACK.session_id is not None
- REGISTER_VIEWER_ACK.session_id is assigned by the backend (not 0)

- REGISTER_VIEWER_ACK.session_id is unique across all connections

- REGISTER_VIEWER_ACK.session_type = CARTA.SessionType.NEW

- REGISTER_VIEWER_ACK.message is not empty
- REGISTER_VIEWER_ACK.message is a non-empty string reporting its own session_id

- REGISTER_VIEWER_ACK.platform_strings has non-empty release_info, deployment, architecture and platform entries

- REGISTER_VIEWER_ACK.platformStrings is not empty
- REGISTER_VIEWER_ACK.server_feature_flags and REGISTER_VIEWER_ACK.platform_strings are identical across all connections

- REGISTER_VIEWER_ACK.user_preferences = None (empty object)

Expand All @@ -95,7 +101,7 @@ ACCESS_CARTA_KNOWN_SESSION

See the `source code <https://github.com/CARTAvis/ICD-RxJS/blob/dev/src/test/ACCESS_CARTA_KNOWN_SESSION.test.ts>`__.

This test verifies that connecting with a known (previously used) session ID results in a resumed session.
This test verifies that connecting with a client-supplied session ID results in a resumed session. Any non-zero session ID is treated as a resume request, and the backend adopts the requested ID and echoes it back.

1. Frontend sends: **REGISTER_VIEWER** (``RegisterViewer``)

Expand All @@ -114,7 +120,11 @@ This test verifies that connecting with a known (previously used) session ID res

- REGISTER_VIEWER_ACK.session_type = CARTA.SessionType.RESUMED

- REGISTER_VIEWER_ACK.message is a non-empty string
- REGISTER_VIEWER_ACK.message is a non-empty string reporting the requested session id

- REGISTER_VIEWER_ACK.server_feature_flags does not have the READ_ONLY bit set

- REGISTER_VIEWER_ACK.platform_strings has non-empty release_info, deployment, architecture and platform entries, where platform is "macOS" or "Linux"

- REGISTER_VIEWER_ACK.user_preferences = None (empty object)

Expand All @@ -125,7 +135,7 @@ ACCESS_CARTA_NO_CLIENT_FEATURE

See the `source code <https://github.com/CARTAvis/ICD-RxJS/blob/dev/src/test/ACCESS_CARTA_NO_CLIENT_FEATURE.test.ts>`__.

This test verifies that a connection without any client feature flags still succeeds.
This test verifies that a connection without any client feature flags still succeeds, and that the acknowledgement is the same as for a default connection. The backend does not read ``client_feature_flags``, so no part of the response may depend on it.

1. Frontend sends: **REGISTER_VIEWER** (``RegisterViewer``)

Expand All @@ -140,10 +150,16 @@ This test verifies that a connection without any client feature flags still succ

- REGISTER_VIEWER_ACK.success = True

- REGISTER_VIEWER_ACK.session_id is not None
- REGISTER_VIEWER_ACK.session_id is assigned by the backend (not 0)

- REGISTER_VIEWER_ACK.session_type = CARTA.SessionType.NEW

- REGISTER_VIEWER_ACK.message is a non-empty string reporting the assigned session_id

- REGISTER_VIEWER_ACK.server_feature_flags does not have the READ_ONLY bit set

- REGISTER_VIEWER_ACK.platform_strings has non-empty release_info, deployment, architecture and platform entries, where platform is "macOS" or "Linux"

- REGISTER_VIEWER_ACK.user_preferences = None (empty object)

- REGISTER_VIEWER_ACK.user_layouts = None (empty object)
Expand All @@ -153,7 +169,7 @@ ACCESS_CARTA_SAME_ID_TWICE

See the `source code <https://github.com/CARTAvis/ICD-RxJS/blob/dev/src/test/ACCESS_CARTA_SAME_ID_TWICE.test.ts>`__.

This test verifies that sending REGISTER_VIEWER twice on the same connection with the same session ID results in a resumed session on the second attempt.
This test verifies that sending REGISTER_VIEWER twice on the same connection with the same session ID results in a resumed session on both attempts. The two registrations take different branches in the backend: the first adopts the requested session ID, while the second finds the session already holding it, so the two acknowledgements report different messages.

1. Frontend sends: **REGISTER_VIEWER** (``RegisterViewer``) — first registration

Expand All @@ -164,6 +180,14 @@ This test verifies that sending REGISTER_VIEWER twice on the same connection wit

2. Backend returns: **REGISTER_VIEWER_ACK** (``RegisterViewerAck``)

:red-text:`Check 1:` the first REGISTER_VIEWER_ACK should satisfy:

- REGISTER_VIEWER_ACK.success = True

- REGISTER_VIEWER_ACK.session_id = 9999

- REGISTER_VIEWER_ACK.session_type = CARTA.SessionType.RESUMED

3. Frontend sends: **REGISTER_VIEWER** (``RegisterViewer``) — second registration on same connection

.. code-block:: text
Expand All @@ -173,14 +197,20 @@ This test verifies that sending REGISTER_VIEWER twice on the same connection wit

4. Backend returns: **REGISTER_VIEWER_ACK** (``RegisterViewerAck``)

:red-text:`Check 1:` the second REGISTER_VIEWER_ACK should satisfy:
:red-text:`Check 2:` the second REGISTER_VIEWER_ACK should satisfy:

- REGISTER_VIEWER_ACK.success = True

- REGISTER_VIEWER_ACK.session_id = 9999

- REGISTER_VIEWER_ACK.session_type = CARTA.SessionType.RESUMED

- REGISTER_VIEWER_ACK.message is a non-empty string reporting the session id, and differs from the message of the first acknowledgement

- REGISTER_VIEWER_ACK.server_feature_flags does not have the READ_ONLY bit set, and is identical to the first acknowledgement

- REGISTER_VIEWER_ACK.platform_strings has non-empty release_info, deployment, architecture and platform entries, is identical to the first acknowledgement, and platform is "macOS" or "Linux"

- REGISTER_VIEWER_ACK.user_preferences = None (empty object)

- REGISTER_VIEWER_ACK.user_layouts = None (empty object)
56 changes: 43 additions & 13 deletions src/test/ACCESS_CARTA_DEFAULT.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,38 +5,68 @@ import { MessageController } from './MessageController';
let testServerUrl = config.serverURL0;
let connectTimeout = config.timeout.connection;

const platformStringKeys = ['release_info', 'deployment', 'architecture', 'platform'];

describe(`ACCESS_CARTA_DEFAULT tests: Testing connections to the backend`, () => {
describe(`create a Websocket connection and receive REGISTER_VIEWER_ACK`, () => {
let RegisterViewerAckResponse: CARTA.IRegisterViewerAck;
const msgController = MessageController.Instance;

test(`Receive REGISTER_VIEWER_ACK`, async () => {
RegisterViewerAckResponse = await msgController.connect(testServerUrl);
test(
`Receive REGISTER_VIEWER_ACK`,
async () => {
RegisterViewerAckResponse = await msgController.connect(testServerUrl);
},
connectTimeout
);

test('REGISTER_VIEWER_ACK.success = True', () => {
expect(RegisterViewerAckResponse.success).toBe(true);
});

test(`REGISTER_VIEWER_ACK.message is not empty`, () => {
expect(RegisterViewerAckResponse.message).toBeDefined();
test('REGISTER_VIEWER_ACK.session_id is assigned by the backend', () => {
expect(RegisterViewerAckResponse.sessionId).toBeDefined();
expect(RegisterViewerAckResponse.sessionId).not.toEqual(0);
console.log(`Registered session ID is ${RegisterViewerAckResponse.sessionId} @${new Date()}`);
});

test(`REGISTER_VIEWER_ACK.platformStrings is not empty`, () => {
expect(RegisterViewerAckResponse.platformStrings).toBeDefined();
test(`REGISTER_VIEWER_ACK.session_type = "CARTA.SessionType.NEW"`, () => {
expect(RegisterViewerAckResponse.sessionType).toBe(CARTA.SessionType.NEW);
});

test('REGISTER_VIEWER_ACK.success = True', () => {
expect(RegisterViewerAckResponse.success).toBe(true);
test(`REGISTER_VIEWER_ACK.message is a non-empty string reporting the assigned session id`, () => {
expect(RegisterViewerAckResponse.message).toBeDefined();
expect(RegisterViewerAckResponse.message).not.toEqual('');
expect(RegisterViewerAckResponse.message).toContain(`${RegisterViewerAckResponse.sessionId}`);
});

test('REGISTER_VIEWER_ACK.session_id is not None', () => {
expect(RegisterViewerAckResponse.sessionId).toBeDefined();
console.log(`Registered session ID is ${RegisterViewerAckResponse.sessionId} @${new Date()}`);
test(`REGISTER_VIEWER_ACK.server_feature_flags does not report READ_ONLY`, () => {
expect(RegisterViewerAckResponse.serverFeatureFlags).toBeDefined();
expect(RegisterViewerAckResponse.serverFeatureFlags! & CARTA.ServerFeatureFlags.READ_ONLY).toEqual(0);
console.log(`Server feature flags are ${RegisterViewerAckResponse.serverFeatureFlags}`);
});

test(`REGISTER_VIEWER_ACK.platform_strings has ${platformStringKeys.join(', ')}`, () => {
const platformStrings = RegisterViewerAckResponse.platformStrings!;
expect(platformStrings).toBeDefined();
platformStringKeys.forEach((key) => {
expect(platformStrings[key]).toBeDefined();
expect(platformStrings[key]).not.toEqual('');
});
expect(['macOS', 'Linux']).toContain(platformStrings['platform']);
console.log(`Platform strings are ${JSON.stringify(platformStrings)}`);
});

test('REGISTER_VIEWER_ACK.user_preferences = None', () => {
expect(RegisterViewerAckResponse.userPreferences).toMatchObject({});
expect(RegisterViewerAckResponse.serverFeatureFlags! & CARTA.ServerFeatureFlags.USER_PREFERENCES).toEqual(
0
);
expect(RegisterViewerAckResponse.userPreferences).toEqual({});
});

test('REGISTER_VIEWER_ACK.user_layouts = None', () => {
expect(RegisterViewerAckResponse.userLayouts).toMatchObject({});
expect(RegisterViewerAckResponse.serverFeatureFlags! & CARTA.ServerFeatureFlags.USER_LAYOUTS).toEqual(0);
expect(RegisterViewerAckResponse.userLayouts).toEqual({});
});

afterAll(async () => {
Expand Down
80 changes: 49 additions & 31 deletions src/test/ACCESS_CARTA_DEFAULT_CONCURRENT.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,73 +7,91 @@ let testServerUrl = config.serverURL0;
let connectTimeout = config.timeout.connection;
let testNumber = config.repeat.concurrent;

let client: BackendService[] = Array(testNumber);
let RegisterViewerAckResponse: CARTA.RegisterViewerAck[] = new Array(testNumber);
const platformStringKeys = ['release_info', 'deployment', 'architecture', 'platform'];

let client: BackendService[] = [];
let RegisterViewerAckResponse: CARTA.IRegisterViewerAck[] = [];

describe(`ACCESS_CARTA_DEFAULT_CONCURRENT: Testing multiple concurrent connections to the backend.`, () => {
test(
`establish ${testNumber} connections to "${testServerUrl}".`,
`establish ${testNumber} concurrent connections to "${testServerUrl}".`,
async () => {
for (let i = 0; i < client.length; i++) {
client[i] = new BackendService();
RegisterViewerAckResponse[i] = await client[i].connect(testServerUrl);
expect(client[i].connection.readyState).toBe(WebSocket.OPEN);
}
client = Array.from({ length: testNumber }, () => new BackendService());
RegisterViewerAckResponse = await Promise.all(client.map((item) => item.connect(testServerUrl)));
client.forEach((item) => {
expect(item.connection.readyState).toBe(WebSocket.OPEN);
});
},
connectTimeout
);

test(`assert every REGISTER_VIEWER_ACK.success is True.`, () => {
RegisterViewerAckResponse.forEach((item, index, array) => {
RegisterViewerAckResponse.forEach((item) => {
expect(item.success).toBe(true);
});
});

test(`assert every REGISTER_VIEWER_ACK.session_id is not None.`, () => {
RegisterViewerAckResponse.forEach((item, index, array) => {
test(`assert every REGISTER_VIEWER_ACK.session_id is assigned by the backend.`, () => {
RegisterViewerAckResponse.forEach((item) => {
expect(item.sessionId).toBeDefined();
expect(item.sessionId).not.toEqual(0);
});
});

test(`assert every REGISTER_VIEWER_ACK.message is not empty`, () => {
RegisterViewerAckResponse.forEach((item, index, array) => {
expect(item.message).toBeDefined();
test(`assert every REGISTER_VIEWER_ACK.session_id is unique.`, () => {
const sessionIds = RegisterViewerAckResponse.map((item) => item.sessionId);
console.log(`Registered session IDs are ${sessionIds}`);
expect(new Set(sessionIds).size).toEqual(testNumber);
});

test(`assert every REGISTER_VIEWER_ACK.session_type is "CARTA.SessionType.NEW".`, () => {
RegisterViewerAckResponse.forEach((item) => {
expect(item.sessionType).toEqual(CARTA.SessionType.NEW);
});
});

test(`assert every REGISTER_VIEWER_ACK.platformStrings is not empty`, () => {
RegisterViewerAckResponse.forEach((item, index, array) => {
expect(item.platformStrings).toBeDefined();
test(`assert every REGISTER_VIEWER_ACK.message reports its own session_id`, () => {
RegisterViewerAckResponse.forEach((item) => {
expect(item.message).toBeDefined();
expect(item.message).not.toEqual('');
expect(item.message).toContain(`${item.sessionId}`);
});
});

test(`assert every REGISTER_VIEWER_ACK.session_id is unique.`, () => {
RegisterViewerAckResponse.forEach((item, index, array) => {
expect(array.filter((f) => f.sessionId === item.sessionId).length).toEqual(1);
test(`assert every REGISTER_VIEWER_ACK.platform_strings has ${platformStringKeys.join(', ')}`, () => {
RegisterViewerAckResponse.forEach((item) => {
const platformStrings = item.platformStrings!;
expect(platformStrings).toBeDefined();
platformStringKeys.forEach((key) => {
expect(platformStrings[key]).toBeDefined();
expect(platformStrings[key]).not.toEqual('');
});
});
});

test(`assert every REGISTER_VIEWER_ACK.session_type is "CARTA.SessionType.NEW".`, () => {
RegisterViewerAckResponse.forEach((item, index, array) => {
expect(item.sessionType).toEqual(CARTA.SessionType.NEW);
test(`assert every REGISTER_VIEWER_ACK reports the same server information`, () => {
const firstResponse = RegisterViewerAckResponse[0];
RegisterViewerAckResponse.forEach((item) => {
expect(item.serverFeatureFlags).toEqual(firstResponse.serverFeatureFlags);
expect(item.platformStrings).toEqual(firstResponse.platformStrings);
});
});

test('assert every REGISTER_VIEWER_ACK.user_preferences = None', () => {
RegisterViewerAckResponse.forEach((item, index, array) => {
expect(item.userPreferences).toMatchObject({});
RegisterViewerAckResponse.forEach((item) => {
expect(item.userPreferences).toEqual({});
});
});

test('assert every REGISTER_VIEWER_ACK.user_layouts = None', () => {
RegisterViewerAckResponse.forEach((item, index, array) => {
expect(item.userLayouts).toMatchObject({});
RegisterViewerAckResponse.forEach((item) => {
expect(item.userLayouts).toEqual({});
});
});

afterAll(async () => {
for (let i = 0; i < client.length; i++) {
await client[i].closeConnection();
}
afterAll(() => {
client.forEach((item) => {
item.closeConnection();
});
});
});
Loading