import crypto from 'crypto'; import fs from 'fs'; import {Uint64BE} from 'int64-buffer'; import * as repertory from '../index.js'; import connection from '../networking/connection'; import connection_pool from '../networking/connection_pool'; const TEST_HOST = process.env.TEST_HOST || 'localhost'; const TEST_PASSWORD = process.env.TEST_PASSWORD || ''; const TEST_PORT = process.env.TEST_PORT || 20000; const calculate_sha256 = path => { return new Promise((resolve, reject) => { const hash = crypto.createHash('sha256'); fs.createReadStream(path) .on('data', data => hash.update(data)) .on('error', err => reject(err)) .on('end', () => { const h = hash.digest('hex'); console.log(path, h); resolve(h); }); }); }; const test_connection = (conn, should_be_connected) => { expect(conn).toBeInstanceOf(connection); expect(conn.host_or_ip).toEqual(TEST_HOST); expect(conn.port).toEqual(TEST_PORT); expect(conn.password).toEqual(TEST_PASSWORD); expect(conn.connected).toEqual(should_be_connected); console.log(conn); }; test('can create a connection to repertory api', async () => { const conn = await repertory.connect(TEST_HOST, TEST_PORT, TEST_PASSWORD); test_connection(conn, true); await conn.disconnect(); }); test('create_pool returns a connection if pool size is <=1', async () => { for (let i = 0; i < 2; i++) { const conn = await repertory.create_pool(i, TEST_HOST, TEST_PORT, TEST_PASSWORD); expect(conn).toBeInstanceOf(connection); test_connection(conn, true); await conn.disconnect(); } }); test('can create a connection pool', async () => { const conn = await repertory.create_pool(2, TEST_HOST, TEST_PORT, TEST_PASSWORD); console.log(conn); expect(conn).toBeInstanceOf(connection_pool); expect(conn.host_or_ip).toEqual(TEST_HOST); expect(conn.port).toEqual(TEST_PORT); expect(conn.password).toEqual(TEST_PASSWORD); expect(conn.shutdown).toEqual(false); expect(conn.pool._pool.max).toEqual(2); expect(conn.pool._pool.min).toEqual(2); await conn.disconnect(); }); test('can get drive information using api', async () => { const conn = await repertory.create_pool(2, TEST_HOST, TEST_PORT, TEST_PASSWORD); const api = repertory.create_api(conn); const di = await api.get_drive_information(); console.log(di); expect(di.free).toBeDefined(); expect(di.total).toBeDefined(); expect(di.used).toBeDefined(); await conn.disconnect(); }); test('can create and remove a directory using api', async () => { const conn = await repertory.create_pool(2, TEST_HOST, TEST_PORT, TEST_PASSWORD); const api = repertory.create_api(conn); expect(await api.directory.create('/repertory_js')).toEqual(0); expect(await api.directory.remove('/repertory_js')).toEqual(0); await conn.disconnect(); }); test('can get directory list and snapshot using api', async () => { const conn = await repertory.create_pool(2, TEST_HOST, TEST_PORT, TEST_PASSWORD); const api = repertory.create_api(conn); const test_results = async (remote_path, page_count, get_page) => { expect(remote_path).toEqual('/'); expect(page_count).toBeGreaterThanOrEqual(1); expect(get_page).toBeInstanceOf(Function); for (let i = 0; i < page_count; i++) { const items = await get_page(i); console.log(items); expect(items.length).toBeGreaterThanOrEqual(2); expect(items[0].directory).toBeTruthy(); expect(items[0].path).toEqual('.'); expect(items[1].directory).toBeTruthy(); expect(items[1].path).toEqual('..'); } }; await api.directory.list('/', async (remote_path, page_count, get_page) => { console.log(remote_path, page_count, get_page); await test_results(remote_path, page_count, get_page); }); const snap = await api.directory.snapshot('/'); try { console.log(snap.remote_path, snap.page_count, snap.get_page); await test_results(snap.remote_path, snap.page_count, snap.get_page); } catch (err) { console.log(err); } finally { await snap.release(); } await conn.disconnect(); }); test('can create, close and delete a file using api', async () => { const conn = await repertory.create_pool(2, TEST_HOST, TEST_PORT, TEST_PASSWORD); const api = repertory.create_api(conn); const f = await api.file.create_or_open('/repertory_file.dat'); console.log(f); expect(f.remote_path).toEqual('/repertory_file.dat'); expect(f.conn).toEqual(conn); expect(new Uint64BE(f.handle).toNumber()).toBeGreaterThanOrEqual(0); expect(await f.close()).toEqual(0); expect(f.handle).toBeNull(); expect(await api.file.delete('/repertory_file.dat')).toEqual(0); await conn.disconnect(); }); test('can open, close and delete a file using api', async () => { const conn = await repertory.create_pool(2, TEST_HOST, TEST_PORT, TEST_PASSWORD); const api = repertory.create_api(conn); let f = await api.file.create_or_open('/repertory_file.dat'); expect(await f.close()).toEqual(0); f = await api.file.open('/repertory_file.dat'); console.log(f); expect(f.remote_path).toEqual('/repertory_file.dat'); expect(f.conn).toEqual(conn); expect(new Uint64BE(f.handle).toNumber()).toBeGreaterThanOrEqual(0); expect(await f.close()).toEqual(0); expect(f.handle).toBeNull(); expect(await api.file.delete('/repertory_file.dat')).toEqual(0); await conn.disconnect(); }); test('can write to and read from a file using api', async () => { const conn = await repertory.create_pool(2, TEST_HOST, TEST_PORT, TEST_PASSWORD); const api = repertory.create_api(conn); const f = await api.file.create_or_open('/repertory_file.dat'); const buffer = Buffer.alloc(4); buffer[0] = 1; buffer[1] = 2; buffer[2] = 3; buffer[3] = 4; expect(await f.write(0, buffer)).toEqual(buffer.length); expect(new Uint64BE(await f.get_size()).toNumber()).toEqual(buffer.length); const buffer2 = await f.read(0, 4); expect(buffer.compare(buffer2)).toEqual(0); expect(await f.close()).toEqual(0); expect(await api.file.delete('/repertory_file.dat')).toEqual(0); await conn.disconnect(); }); test('can truncate a file using api', async () => { const conn = await repertory.create_pool(2, TEST_HOST, TEST_PORT, TEST_PASSWORD); const api = repertory.create_api(conn); const f = await api.file.create_or_open('/repertory_file.dat'); expect(await f.truncate(10)).toEqual(0); expect(new Uint64BE(await f.get_size()).toNumber()).toEqual(10); expect(await f.truncate(0)).toEqual(0); expect(new Uint64BE(await f.get_size()).toNumber()).toEqual(0); expect(await f.close()).toEqual(0); expect(await api.file.delete('/repertory_file.dat')).toEqual(0); await conn.disconnect(); }); test('can upload and download a file using api', async () => { try { fs.unlinkSync('repertory_test.dat'); } catch { } const conn = await repertory.create_pool(2, TEST_HOST, TEST_PORT, TEST_PASSWORD); const api = repertory.create_api(conn); expect(await api.file.upload('test.dat', '/repertory_test.dat', (l, r, p, c) => { console.log(l, r, p, c); })) .toBeTruthy(); expect(await api.file.download('/repertory_test.dat', 'repertory_test.dat', (l, r, p, c) => { console.log(l, r, p, c); })) .toBeTruthy(); expect(await calculate_sha256('test.dat')) .toEqual(await calculate_sha256('repertory_test.dat')); expect(await api.file.delete('/repertory_test.dat')).toEqual(0); fs.unlinkSync('repertory_test.dat'); await conn.disconnect(); }, 60000); test('can download and overwrite a file using api', async () => { const conn = await repertory.create_pool(2, TEST_HOST, TEST_PORT, TEST_PASSWORD); const api = repertory.create_api(conn); expect(await api.file.upload('test.dat', '/repertory_test.dat', (l, r, p, c) => { console.log(l, r, p, c); })) .toBeTruthy(); expect(await api.file.download('/repertory_test.dat', 'repertory_test.dat', (l, r, p, c) => { console.log(l, r, p, c); })) .toBeTruthy(); expect(await api.file.download('/repertory_test.dat', 'repertory_test.dat', (l, r, p, c) => { console.log(l, r, p, c); }, true)) .toBeTruthy(); expect(await api.file.delete('/repertory_test.dat')).toEqual(0); fs.unlinkSync('repertory_test.dat'); await conn.disconnect(); }, 60000); test('download fails if overwrite is false using api', async () => { const conn = await repertory.create_pool(2, TEST_HOST, TEST_PORT, TEST_PASSWORD); const api = repertory.create_api(conn); expect(await api.file.upload('test.dat', '/repertory_test.dat', (l, r, p, c) => { console.log(l, r, p, c); })) .toBeTruthy(); expect(await api.file.download('/repertory_test.dat', 'repertory_test.dat', (l, r, p, c) => { console.log(l, r, p, c); })) .toBeTruthy(); await expect(api.file.download('/repertory_test.dat', 'repertory_test.dat', (l, r, p, c) => { console.log(l, r, p, c); }, false)) .rejects.toThrow(Error); expect(await api.file.delete('/repertory_test.dat')).toEqual(0); fs.unlinkSync('repertory_test.dat'); await conn.disconnect(); }, 60000); test('can upload and overwrite a file using api', async () => { const conn = await repertory.create_pool(2, TEST_HOST, TEST_PORT, TEST_PASSWORD); const api = repertory.create_api(conn); expect(await api.file.upload('test.dat', '/repertory_test.dat', (l, r, p, c) => { console.log(l, r, p, c); })) .toBeTruthy(); expect(await api.file.upload('test.dat', '/repertory_test.dat', (l, r, p, c) => { console.log(l, r, p, c); }, true)) .toBeTruthy(); expect(await api.file.delete('/repertory_test.dat')).toEqual(0); await conn.disconnect(); }, 60000); test('upload fails if overwrite is false using api', async () => { const conn = await repertory.create_pool(2, TEST_HOST, TEST_PORT, TEST_PASSWORD); const api = repertory.create_api(conn); expect(await api.file.upload('test.dat', '/repertory_test.dat', (l, r, p, c) => { console.log(l, r, p, c); })) .toBeTruthy(); await expect(api.file.upload('test.dat', '/repertory_test.dat', (l, r, p, c) => { console.log(l, r, p, c); }, false)) .rejects.toThrow(Error); expect(await api.file.delete('/repertory_test.dat')).toEqual(0); await conn.disconnect(); }, 60000); test('can resume download using api', async () => { const conn = await repertory.create_pool(2, TEST_HOST, TEST_PORT, TEST_PASSWORD); const api = repertory.create_api(conn); expect(await api.file.upload('test.dat', '/repertory_test.dat', (l, r, p, c) => { console.log(l, r, p, c); })) .toBeTruthy(); const fd = fs.openSync('test.dat', 'r'); const buffer = Buffer.alloc(1024); fs.readSync(fd, buffer, 0, buffer.length); fs.closeSync(fd); fs.writeFileSync('repertory_test.dat', buffer); expect(await api.file.download('/repertory_test.dat', 'repertory_test.dat', (l, r, p, c) => { console.log(l, r, p, c); }, false, true)) .toBeTruthy(); expect(await calculate_sha256('test.dat')) .toEqual(await calculate_sha256('repertory_test.dat')); expect(await api.file.delete('/repertory_test.dat')).toEqual(0); fs.unlinkSync('repertory_test.dat'); await conn.disconnect(); }, 60000); test('can resume upload using api', async () => { const conn = await repertory.create_pool(2, TEST_HOST, TEST_PORT, TEST_PASSWORD); const api = repertory.create_api(conn); const fd = fs.openSync('test.dat', 'r'); const buffer = Buffer.alloc(1024); fs.readSync(fd, buffer, 0, buffer.length); fs.closeSync(fd); const f = await api.file.create_or_open('/repertory_test.dat'); await f.write(0, buffer); await f.close(); expect(await api.file.upload('test.dat', '/repertory_test.dat', (l, r, p, c) => { console.log(l, r, p, c); }, false, true)) .toBeTruthy(); expect(await api.file.download('/repertory_test.dat', 'repertory_test.dat', (l, r, p, c) => { console.log(l, r, p, c); })) .toBeTruthy(); expect(await calculate_sha256('test.dat')) .toEqual(await calculate_sha256('repertory_test.dat')); expect(await api.file.delete('/repertory_test.dat')).toEqual(0); fs.unlinkSync('repertory_test.dat'); await conn.disconnect(); }, 60000);