mirror of
https://github.com/whyour/qinglong.git
synced 2026-09-23 12:05:27 +08:00
feat(ql3): establish 3.0 incubation baseline
This commit is contained in:
@@ -0,0 +1,257 @@
|
||||
const assert = require('node:assert/strict');
|
||||
const test = require('node:test');
|
||||
|
||||
const {
|
||||
createModelPriceCatalogHead,
|
||||
createModelPriceCatalogPublication,
|
||||
createModelPriceCatalogPublishCommand,
|
||||
} = require('../dist/pricing/modelPriceCatalog.js');
|
||||
const {
|
||||
InvalidModelPriceCatalogManagementValueError,
|
||||
ModelPriceCatalogManagementAuthenticationError,
|
||||
ModelPriceCatalogManagementAuthorizationError,
|
||||
ModelPriceCatalogManagementSeparationOfDutyError,
|
||||
createModelPriceCatalogAuthorization,
|
||||
createModelPriceCatalogManagementService,
|
||||
createModelPriceCatalogPolicyDecision,
|
||||
normalizeModelPriceCatalogAuthorization,
|
||||
normalizeModelPriceCatalogAuthorizationCommand,
|
||||
} = require('../dist/pricing/modelPriceCatalogManagement.js');
|
||||
|
||||
const NOW = 2_000_000;
|
||||
|
||||
function principal(userId, assurance = 'multi_factor') {
|
||||
return {
|
||||
subject: { type: 'user', id: userId },
|
||||
authenticationId: `auth-${userId}`,
|
||||
authenticatedAtMs: NOW - 1_000,
|
||||
expiresAtMs: NOW + 60_000,
|
||||
assurance,
|
||||
};
|
||||
}
|
||||
|
||||
function policy(effect = 'allow') {
|
||||
return createModelPriceCatalogPolicyDecision({
|
||||
effect,
|
||||
revision: 'platform-policy-7',
|
||||
reasons: [effect === 'allow' ? 'catalog_operator' : 'catalog_denied'],
|
||||
});
|
||||
}
|
||||
|
||||
function fakeRepository(publishedByUserId = 'publisher') {
|
||||
const calls = [];
|
||||
return {
|
||||
calls,
|
||||
async findPublication(lookup) {
|
||||
calls.push(['findPublication', lookup]);
|
||||
return createModelPriceCatalogPublication(
|
||||
createModelPriceCatalogPublishCommand({
|
||||
provider: lookup.provider,
|
||||
model: lookup.model,
|
||||
priceRevision: lookup.priceRevision,
|
||||
currency: 'USD',
|
||||
inputMicrosPerMillionTokens: 100,
|
||||
outputMicrosPerMillionTokens: 400,
|
||||
mutationId: 'existing-publication',
|
||||
publishedByUserId,
|
||||
}),
|
||||
NOW - 100,
|
||||
);
|
||||
},
|
||||
async findCurrent() {
|
||||
return null;
|
||||
},
|
||||
async findAuthorization() {
|
||||
return null;
|
||||
},
|
||||
async publish() {
|
||||
throw new Error('raw publish must not be used');
|
||||
},
|
||||
async transition() {
|
||||
throw new Error('raw transition must not be used');
|
||||
},
|
||||
async resolve() {
|
||||
return null;
|
||||
},
|
||||
async publishAuthorized(command, authorizationCommand) {
|
||||
calls.push(['publishAuthorized', command, authorizationCommand]);
|
||||
const publication = createModelPriceCatalogPublication(command, NOW);
|
||||
const authorization = createModelPriceCatalogAuthorization(
|
||||
authorizationCommand,
|
||||
publication.publicationDigest,
|
||||
NOW,
|
||||
);
|
||||
return { status: 'created', publication, authorization };
|
||||
},
|
||||
async transitionAuthorized(command, authorizationCommand) {
|
||||
calls.push(['transitionAuthorized', command, authorizationCommand]);
|
||||
const publication = await this.findPublication({
|
||||
provider: command.provider,
|
||||
model: command.model,
|
||||
priceRevision: command.priceRevision,
|
||||
});
|
||||
const head = createModelPriceCatalogHead(
|
||||
null,
|
||||
command,
|
||||
publication,
|
||||
false,
|
||||
NOW,
|
||||
);
|
||||
const authorization = createModelPriceCatalogAuthorization(
|
||||
authorizationCommand,
|
||||
head.headDigest,
|
||||
NOW,
|
||||
);
|
||||
return { status: 'created', head, authorization };
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function publishRequest(userId = 'publisher') {
|
||||
return {
|
||||
authorizationId: 'authorize-publish-1',
|
||||
requestId: 'request-publish-1',
|
||||
mutationId: 'publish-price-1',
|
||||
provider: 'remote',
|
||||
model: 'model-a',
|
||||
principal: principal(userId),
|
||||
priceRevision: 'price-1',
|
||||
currency: 'USD',
|
||||
inputMicrosPerMillionTokens: 150_000,
|
||||
outputMicrosPerMillionTokens: 600_000,
|
||||
};
|
||||
}
|
||||
|
||||
function transitionRequest(userId = 'reviewer') {
|
||||
return {
|
||||
authorizationId: 'authorize-activate-1',
|
||||
requestId: 'request-activate-1',
|
||||
mutationId: 'activate-price-1',
|
||||
provider: 'remote',
|
||||
model: 'model-a',
|
||||
principal: principal(userId),
|
||||
expectedGeneration: 0,
|
||||
expectedHeadDigest: null,
|
||||
action: 'activate',
|
||||
priceRevision: 'price-1',
|
||||
};
|
||||
}
|
||||
|
||||
test('authorization fact binds strong User, policy, catalog command and commit', () => {
|
||||
const decision = policy();
|
||||
const serviceRepository = fakeRepository();
|
||||
const service = createModelPriceCatalogManagementService(serviceRepository, {
|
||||
decisionMode: 'human_confirmation',
|
||||
authorizer: {
|
||||
async authorize() {
|
||||
return decision;
|
||||
},
|
||||
},
|
||||
now: () => NOW,
|
||||
});
|
||||
|
||||
return service.publish(publishRequest()).then((result) => {
|
||||
assert.equal(result.authorization.operation, 'publish');
|
||||
assert.equal(result.authorization.principal.subject.id, 'publisher');
|
||||
assert.equal(result.authorization.policy.revision, 'platform-policy-7');
|
||||
assert.equal(
|
||||
result.authorization.resultDigest,
|
||||
result.publication.publicationDigest,
|
||||
);
|
||||
assert.deepEqual(
|
||||
normalizeModelPriceCatalogAuthorization(result.authorization),
|
||||
result.authorization,
|
||||
);
|
||||
assert.deepEqual(
|
||||
normalizeModelPriceCatalogAuthorizationCommand(
|
||||
serviceRepository.calls[0][2],
|
||||
),
|
||||
serviceRepository.calls[0][2],
|
||||
);
|
||||
assert.throws(
|
||||
() =>
|
||||
normalizeModelPriceCatalogAuthorization({
|
||||
...result.authorization,
|
||||
resultDigest: 'f'.repeat(64),
|
||||
}),
|
||||
InvalidModelPriceCatalogManagementValueError,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test('management rejects weak principals and deny decisions before mutation', async () => {
|
||||
const repository = fakeRepository();
|
||||
let authorizations = 0;
|
||||
const service = createModelPriceCatalogManagementService(repository, {
|
||||
decisionMode: 'human_confirmation',
|
||||
authorizer: {
|
||||
async authorize() {
|
||||
authorizations += 1;
|
||||
return policy('deny');
|
||||
},
|
||||
},
|
||||
now: () => NOW,
|
||||
});
|
||||
|
||||
await assert.rejects(
|
||||
service.publish({
|
||||
...publishRequest(),
|
||||
principal: principal('publisher', 'single_factor'),
|
||||
}),
|
||||
ModelPriceCatalogManagementAuthenticationError,
|
||||
);
|
||||
assert.equal(authorizations, 0);
|
||||
await assert.rejects(
|
||||
service.publish(publishRequest()),
|
||||
ModelPriceCatalogManagementAuthorizationError,
|
||||
);
|
||||
assert.equal(authorizations, 1);
|
||||
assert.equal(
|
||||
repository.calls.some(([name]) => name === 'publishAuthorized'),
|
||||
false,
|
||||
);
|
||||
});
|
||||
|
||||
test('cluster activation requires a different strong publishing User', async () => {
|
||||
const sameUserRepository = fakeRepository('publisher');
|
||||
const sameUserService = createModelPriceCatalogManagementService(
|
||||
sameUserRepository,
|
||||
{
|
||||
decisionMode: 'separation_of_duty',
|
||||
authorizer: {
|
||||
async authorize() {
|
||||
return policy();
|
||||
},
|
||||
},
|
||||
now: () => NOW,
|
||||
},
|
||||
);
|
||||
await assert.rejects(
|
||||
sameUserService.transition(transitionRequest('publisher')),
|
||||
ModelPriceCatalogManagementSeparationOfDutyError,
|
||||
);
|
||||
assert.equal(
|
||||
sameUserRepository.calls.some(([name]) => name === 'transitionAuthorized'),
|
||||
false,
|
||||
);
|
||||
|
||||
const reviewedRepository = fakeRepository('publisher');
|
||||
const reviewedService = createModelPriceCatalogManagementService(
|
||||
reviewedRepository,
|
||||
{
|
||||
decisionMode: 'separation_of_duty',
|
||||
authorizer: {
|
||||
async authorize() {
|
||||
return policy();
|
||||
},
|
||||
},
|
||||
now: () => NOW,
|
||||
},
|
||||
);
|
||||
const result = await reviewedService.transition(
|
||||
transitionRequest('reviewer'),
|
||||
);
|
||||
assert.equal(result.head.activePriceRevision, 'price-1');
|
||||
assert.equal(result.authorization.principal.subject.id, 'reviewer');
|
||||
assert.equal(result.authorization.decisionMode, 'separation_of_duty');
|
||||
});
|
||||
Reference in New Issue
Block a user