feat(core,storage,oci,registry-config): add streaming response support and configurable registry URLs across protocols

This commit is contained in:
2026-03-24 22:59:37 +00:00
parent 1f0acf2825
commit 7da1a35efe
42 changed files with 4179 additions and 5396 deletions

View File

@@ -1,32 +1,34 @@
/**
* Integration test for smartregistry with smarts3
* Integration test for smartregistry with smartstorage
* Verifies that smartregistry works with a local S3-compatible server
*/
import { expect, tap } from '@git.zone/tstest/tapbundle';
import * as smarts3Module from '@push.rocks/smarts3';
import * as smartstorageModule from '@push.rocks/smartstorage';
import { SmartRegistry } from '../ts/classes.smartregistry.js';
import type { IRegistryConfig } from '../ts/core/interfaces.core.js';
import { streamToJson } from '../ts/core/helpers.stream.js';
import * as crypto from 'crypto';
let s3Server: smarts3Module.Smarts3;
let s3Server: smartstorageModule.SmartStorage;
let registry: SmartRegistry;
/**
* Setup: Start smarts3 server
* Setup: Start smartstorage server
*/
tap.test('should start smarts3 server', async () => {
s3Server = await smarts3Module.Smarts3.createAndStart({
tap.test('should start smartstorage server', async () => {
s3Server = await smartstorageModule.SmartStorage.createAndStart({
server: {
port: 3456, // Use different port to avoid conflicts with other tests
host: '0.0.0.0',
port: 3456,
address: '0.0.0.0',
silent: true,
},
storage: {
cleanSlate: true, // Fresh storage for each test run
bucketsDir: './.nogit/smarts3-test-buckets',
cleanSlate: true,
directory: './.nogit/smartstorage-test-buckets',
},
logging: {
silent: true, // Reduce test output noise
enabled: false,
},
});
@@ -34,20 +36,10 @@ tap.test('should start smarts3 server', async () => {
});
/**
* Setup: Create SmartRegistry with smarts3 configuration
* Setup: Create SmartRegistry with smartstorage configuration
*/
tap.test('should create SmartRegistry instance with smarts3 IS3Descriptor', async () => {
// Manually construct IS3Descriptor based on smarts3 configuration
// Note: smarts3.getS3Descriptor() returns empty object as of v5.1.0
// This is a known limitation - smarts3 doesn't expose its config properly
const s3Descriptor = {
endpoint: 'localhost',
port: 3456,
accessKey: 'test', // smarts3 doesn't require real credentials
accessSecret: 'test',
useSsl: false,
region: 'us-east-1',
};
const s3Descriptor = await s3Server.getStorageDescriptor();
const config: IRegistryConfig = {
storage: {
@@ -97,7 +89,7 @@ tap.test('should create SmartRegistry instance with smarts3 IS3Descriptor', asyn
});
/**
* Test NPM protocol with smarts3
* Test NPM protocol with smartstorage
*/
tap.test('NPM: should publish package to smarts3', async () => {
const authManager = registry.getAuthManager();
@@ -139,7 +131,7 @@ tap.test('NPM: should publish package to smarts3', async () => {
body: packageData,
});
expect(response.status).toEqual(201); // 201 Created is correct for publishing
expect(response.status).toEqual(201);
});
tap.test('NPM: should retrieve package from smarts3', async () => {
@@ -151,12 +143,13 @@ tap.test('NPM: should retrieve package from smarts3', async () => {
});
expect(response.status).toEqual(200);
expect(response.body).toHaveProperty('name');
expect(response.body.name).toEqual('test-package-smarts3');
const body = await streamToJson(response.body);
expect(body).toHaveProperty('name');
expect(body.name).toEqual('test-package-smarts3');
});
/**
* Test OCI protocol with smarts3
* Test OCI protocol with smartstorage
*/
tap.test('OCI: should store blob in smarts3', async () => {
const authManager = registry.getAuthManager();
@@ -173,7 +166,7 @@ tap.test('OCI: should store blob in smarts3', async () => {
// Initiate blob upload
const initiateResponse = await registry.handleRequest({
method: 'POST',
path: '/oci/v2/test-image/blobs/uploads/',
path: '/oci/test-image/blobs/uploads/',
headers: {
'Authorization': `Bearer ${token}`,
},
@@ -196,7 +189,7 @@ tap.test('OCI: should store blob in smarts3', async () => {
const uploadResponse = await registry.handleRequest({
method: 'PUT',
path: `/oci/v2/test-image/blobs/uploads/${uploadId}`,
path: `/oci/test-image/blobs/uploads/${uploadId}`,
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/octet-stream',
@@ -209,18 +202,9 @@ tap.test('OCI: should store blob in smarts3', async () => {
});
/**
* Test PyPI protocol with smarts3
* Test PyPI protocol with smartstorage
*/
tap.test('PyPI: should upload package to smarts3', async () => {
const authManager = registry.getAuthManager();
const userId = await authManager.authenticate({
username: 'testuser',
password: 'testpass',
});
const token = await authManager.createPypiToken(userId, false);
// Note: In a real test, this would be multipart/form-data
// For simplicity, we're testing the storage layer
const storage = registry.getStorage();
// Store a test package file
@@ -252,7 +236,7 @@ tap.test('PyPI: should upload package to smarts3', async () => {
});
/**
* Test Cargo protocol with smarts3
* Test Cargo protocol with smartstorage
*/
tap.test('Cargo: should store crate in smarts3', async () => {
const storage = registry.getStorage();
@@ -281,11 +265,11 @@ tap.test('Cargo: should store crate in smarts3', async () => {
});
/**
* Cleanup: Stop smarts3 server
* Cleanup: Stop smartstorage server
*/
tap.test('should stop smarts3 server', async () => {
tap.test('should stop smartstorage server', async () => {
await s3Server.stop();
expect(true).toEqual(true); // Just verify it completes without error
expect(true).toEqual(true);
});
export default tap.start();