mirror of
https://github.com/whyour/qinglong.git
synced 2026-09-20 16:07:11 +08:00
183 lines
5.7 KiB
JavaScript
183 lines
5.7 KiB
JavaScript
const assert = require('node:assert/strict');
|
|
const { test } = require('node:test');
|
|
|
|
const {
|
|
PluginPackageAutomationPublicationConflictError,
|
|
createInitialPluginPackageAutomationPublication,
|
|
createNextPluginPackageAutomationPublication,
|
|
} = require('../../packages/ql3-runtime-core/dist/plugin-package/pluginPackageAutomationPublication');
|
|
const {
|
|
pluginPackageTaskReconciliationFixture,
|
|
} = require('./pluginPackageTaskReconciliationRepositoryContract.cjs');
|
|
|
|
function automationOptions(name = 'daily') {
|
|
return {
|
|
workflows: [
|
|
{
|
|
schema: 'qinglong/plugin-package-workflow-resource@v1',
|
|
id: name,
|
|
name: `Workflow ${name}`,
|
|
enabled: true,
|
|
steps: [{ id: 'run', task: 'alpha', needs: [] }],
|
|
},
|
|
],
|
|
prompts: [
|
|
{
|
|
schema: 'qinglong/plugin-package-prompt-resource@v1',
|
|
id: `${name}-prompt`,
|
|
name: `Prompt ${name}`,
|
|
template: 'Hello {{name}}',
|
|
parameters: [{ name: 'name', required: true }],
|
|
},
|
|
],
|
|
};
|
|
}
|
|
|
|
function fixture(namespace, options = {}) {
|
|
return pluginPackageTaskReconciliationFixture(namespace, {
|
|
profile: options.profile,
|
|
previous: options.previous,
|
|
...automationOptions(options.name),
|
|
});
|
|
}
|
|
|
|
function registerPluginPackageAutomationPublicationRepositoryContract(options) {
|
|
test(`${options.name} publishes and replays one exact current head`, async (t) => {
|
|
const value = fixture(`${options.namespace}-initial`, {
|
|
profile: options.profile,
|
|
name: 'daily',
|
|
});
|
|
const harness = await options.createRepository(t, value);
|
|
t.after(() => harness.close?.());
|
|
await harness.materializedRepository.publish(value.revision);
|
|
const publication = createInitialPluginPackageAutomationPublication(
|
|
value.revision,
|
|
value.registry,
|
|
1_000,
|
|
);
|
|
const created = await harness.repository.publish(publication);
|
|
assert.equal(created.status, 'created');
|
|
assert.deepEqual(created.publication, publication);
|
|
assert.equal((await harness.repository.publish(publication)).status, 'existing');
|
|
assert.deepEqual(
|
|
await harness.repository.findByDigest(publication.publicationDigest),
|
|
publication,
|
|
);
|
|
assert.deepEqual(
|
|
await harness.repository.findCurrent(value.projectId, value.packageName),
|
|
publication,
|
|
);
|
|
});
|
|
|
|
test(`${options.name} advances generations with one CAS publication chain`, async (t) => {
|
|
const first = fixture(`${options.namespace}-upgrade`, {
|
|
profile: options.profile,
|
|
name: 'daily',
|
|
});
|
|
const harness = await options.createRepository(t, first);
|
|
t.after(() => harness.close?.());
|
|
await harness.materializedRepository.publish(first.revision);
|
|
const initial = createInitialPluginPackageAutomationPublication(
|
|
first.revision,
|
|
first.registry,
|
|
1_000,
|
|
);
|
|
await harness.repository.publish(initial);
|
|
|
|
const second = fixture(first.namespace, {
|
|
profile: options.profile,
|
|
previous: first,
|
|
name: 'hourly',
|
|
});
|
|
await harness.materializedRepository.publish(second.revision);
|
|
const next = createNextPluginPackageAutomationPublication(
|
|
second.revision,
|
|
second.registry,
|
|
initial,
|
|
1_100,
|
|
);
|
|
assert.equal((await harness.repository.publish(next)).status, 'created');
|
|
assert.deepEqual(
|
|
await harness.repository.findCurrent(first.projectId, first.packageName),
|
|
next,
|
|
);
|
|
assert.deepEqual(
|
|
await harness.repository.findByDigest(initial.publicationDigest),
|
|
initial,
|
|
);
|
|
|
|
const staleFork = createNextPluginPackageAutomationPublication(
|
|
second.revision,
|
|
second.registry,
|
|
initial,
|
|
1_101,
|
|
);
|
|
await assert.rejects(
|
|
harness.repository.publish(staleFork),
|
|
PluginPackageAutomationPublicationConflictError,
|
|
);
|
|
assert.deepEqual(
|
|
await harness.repository.findCurrent(first.projectId, first.packageName),
|
|
next,
|
|
);
|
|
});
|
|
|
|
test(`${options.name} persists absent tombstones across Package generations`, async (t) => {
|
|
const first = fixture(`${options.namespace}-tombstone`, {
|
|
profile: options.profile,
|
|
name: 'daily',
|
|
});
|
|
const harness = await options.createRepository(t, first);
|
|
t.after(() => harness.close?.());
|
|
await harness.materializedRepository.publish(first.revision);
|
|
const initial = createInitialPluginPackageAutomationPublication(
|
|
first.revision,
|
|
first.registry,
|
|
1_000,
|
|
);
|
|
await harness.repository.publish(initial);
|
|
|
|
const second = pluginPackageTaskReconciliationFixture(first.namespace, {
|
|
profile: options.profile,
|
|
previous: first,
|
|
});
|
|
await harness.materializedRepository.publish(second.revision);
|
|
const absent = createNextPluginPackageAutomationPublication(
|
|
second.revision,
|
|
second.registry,
|
|
initial,
|
|
1_100,
|
|
);
|
|
assert.equal(absent.state, 'absent');
|
|
assert.equal((await harness.repository.publish(absent)).status, 'created');
|
|
|
|
const third = fixture(first.namespace, {
|
|
profile: options.profile,
|
|
previous: second,
|
|
name: 'restored',
|
|
});
|
|
await harness.materializedRepository.publish(third.revision);
|
|
const restored = createNextPluginPackageAutomationPublication(
|
|
third.revision,
|
|
third.registry,
|
|
absent,
|
|
1_200,
|
|
);
|
|
assert.equal(restored.state, 'active');
|
|
assert.equal((await harness.repository.publish(restored)).status, 'created');
|
|
assert.deepEqual(
|
|
await harness.repository.findCurrent(first.projectId, first.packageName),
|
|
restored,
|
|
);
|
|
assert.deepEqual(
|
|
await harness.repository.findByDigest(absent.publicationDigest),
|
|
absent,
|
|
);
|
|
});
|
|
}
|
|
|
|
module.exports = {
|
|
pluginPackageAutomationPublicationFixture: fixture,
|
|
registerPluginPackageAutomationPublicationRepositoryContract,
|
|
};
|