6bf8bebf51
CI / Test and Build (push) Failing after 1s
CI / Migrate Dev DB (push) Has been skipped
CI / Migrate DB (push) Has been skipped
CodeQL / Analyze actions (push) Has been cancelled
CodeQL / Analyze javascript-typescript (push) Has been cancelled
CI / Detect Version (push) Has been cancelled
CI / Detect Desktop Changes (push) Has been cancelled
CI / Build AMD64 (blacksmith-2vcpu-ubuntu-2404, ./docker/cron.Dockerfile, ubuntu-latest, ghcr.io/simstudioai/cron) (push) Has been cancelled
CI / Build AMD64 (blacksmith-2vcpu-ubuntu-2404, ./docker/db.Dockerfile, ECR_MIGRATIONS, ubuntu-latest, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (blacksmith-4vcpu-ubuntu-2404, ./docker/pii.Dockerfile, ECR_PII, ubuntu-latest, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (blacksmith-4vcpu-ubuntu-2404, ./docker/realtime.Dockerfile, ECR_REALTIME, ubuntu-latest, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build AMD64 (blacksmith-8vcpu-ubuntu-2404, ./docker/app.Dockerfile, ECR_APP, linux-x64-8-core, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (blacksmith-4vcpu-ubuntu-2404-arm, ./docker/cron.Dockerfile, ubuntu-24.04-arm, ghcr.io/simstudioai/cron) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (blacksmith-4vcpu-ubuntu-2404-arm, ./docker/db.Dockerfile, ubuntu-24.04-arm, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (blacksmith-4vcpu-ubuntu-2404-arm, ./docker/pii.Dockerfile, ubuntu-24.04-arm, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (blacksmith-4vcpu-ubuntu-2404-arm, ./docker/realtime.Dockerfile, ubuntu-24.04-arm, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (blacksmith-8vcpu-ubuntu-2404-arm, ./docker/app.Dockerfile, linux-arm64-8-core, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
Publish CLI Package / publish-npm (push) Has been cancelled
Publish Python SDK / publish-pypi (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
Helm Chart / Lint, test, and validate chart (push) Has been cancelled
Helm Chart / Chart version bumped (push) Has been cancelled
Publish TypeScript SDK / publish-npm (push) Has been cancelled
CI / Build Dev ECR (blacksmith-8vcpu-ubuntu-2404, ./docker/app.Dockerfile, ECR_APP, linux-x64-8-core) (push) Has been cancelled
CI / Promote Images (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/cron) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build Dev ECR (blacksmith-2vcpu-ubuntu-2404, ./docker/db.Dockerfile, ECR_MIGRATIONS, ubuntu-latest) (push) Has been cancelled
CI / Build Dev ECR (blacksmith-4vcpu-ubuntu-2404, ./docker/pii.Dockerfile, ECR_PII, ubuntu-latest) (push) Has been cancelled
CI / Build Dev ECR (blacksmith-4vcpu-ubuntu-2404, ./docker/realtime.Dockerfile, ECR_REALTIME, ubuntu-latest) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Check Desktop Signing Secrets (push) Has been cancelled
CI / Desktop Release (push) Has been cancelled
CI / Create Desktop Prerelease (push) Has been cancelled
CI / Desktop Prerelease Build (push) Has been cancelled
CI / Publish Desktop Prerelease (push) Has been cancelled
CI / Prune Desktop Prereleases (push) Has been cancelled
Helm Chart / Install on kind and run helm test (push) Has been cancelled
151 lines
4.9 KiB
TypeScript
151 lines
4.9 KiB
TypeScript
import { describe, expect, it } from 'bun:test'
|
|
import {
|
|
SANDBOX_CAPABILITY,
|
|
validateCapabilityFieldInput,
|
|
} from '../../apps/sim/lib/core/config/env-capabilities.ts'
|
|
import { SANDBOX_SETUP } from './capability-config.ts'
|
|
import { buildCapabilitySetupTransition } from './capability-setup.ts'
|
|
import type { ConfigurationSource } from './configuration-sources.ts'
|
|
import { reconcileLlmSetup, resolveFeatureSetupDestination } from './feature-setup.ts'
|
|
|
|
const E2B_FUNCTION_TEMPLATE_ID = 'sim-function:00000000-0000-4000-8000-000000000001'
|
|
const DAYTONA_FUNCTION_SNAPSHOT_ID = '00000000-0000-4000-8000-000000000002'
|
|
|
|
function source(
|
|
kind: ConfigurationSource['kind'],
|
|
managedByCurrentCheckout: boolean,
|
|
values: Map<string, string> | null = new Map()
|
|
): ConfigurationSource {
|
|
return {
|
|
kind,
|
|
label: `${kind} source`,
|
|
location: `${kind} location`,
|
|
values,
|
|
managedByCurrentCheckout,
|
|
}
|
|
}
|
|
|
|
describe('resolveFeatureSetupDestination', () => {
|
|
it('uses the effective values of the one setup-managed source', () => {
|
|
const effective = new Map([['RESEND_API_KEY', 'effective-key']])
|
|
const destination = resolveFeatureSetupDestination([
|
|
source('compose', false),
|
|
source('dev', true, effective),
|
|
])
|
|
|
|
expect(destination.target).toBe('sim')
|
|
expect(destination.containerized).toBe(false)
|
|
expect(destination.vars).toBe(effective)
|
|
})
|
|
|
|
it('maps a managed Compose source to the root env file', () => {
|
|
const destination = resolveFeatureSetupDestination([source('compose', true)])
|
|
|
|
expect(destination.target).toBe('root')
|
|
expect(destination.containerized).toBe(true)
|
|
})
|
|
|
|
it('refuses effective sources this checkout cannot safely update', () => {
|
|
expect(() => resolveFeatureSetupDestination([source('dev', false)])).toThrow(
|
|
/No effective configuration is safely writable/
|
|
)
|
|
expect(() => resolveFeatureSetupDestination([source('helm', false)])).toThrow(
|
|
/No effective configuration is safely writable/
|
|
)
|
|
})
|
|
|
|
it('refuses an unreadable managed source instead of claiming success', () => {
|
|
expect(() => resolveFeatureSetupDestination([source('compose', true, null)])).toThrow(
|
|
/effective environment could not be resolved/
|
|
)
|
|
})
|
|
})
|
|
|
|
describe('sandbox capability setup', () => {
|
|
it('requires immutable Function base references', () => {
|
|
expect(
|
|
validateCapabilityFieldInput(
|
|
SANDBOX_CAPABILITY,
|
|
'DAYTONA_FUNCTION_SNAPSHOT_ID',
|
|
DAYTONA_FUNCTION_SNAPSHOT_ID
|
|
)
|
|
).toBeUndefined()
|
|
expect(
|
|
validateCapabilityFieldInput(
|
|
SANDBOX_CAPABILITY,
|
|
'DAYTONA_FUNCTION_SNAPSHOT_ID',
|
|
'mothership-shell:v1'
|
|
)
|
|
).toContain('immutable Daytona snapshot ID')
|
|
expect(
|
|
validateCapabilityFieldInput(
|
|
SANDBOX_CAPABILITY,
|
|
'E2B_FUNCTION_TEMPLATE_ID',
|
|
E2B_FUNCTION_TEMPLATE_ID
|
|
)
|
|
).toBeUndefined()
|
|
expect(
|
|
validateCapabilityFieldInput(
|
|
SANDBOX_CAPABILITY,
|
|
'E2B_FUNCTION_TEMPLATE_ID',
|
|
'sim-function:latest'
|
|
)
|
|
).toContain('immutable E2B build reference')
|
|
})
|
|
|
|
it('writes Daytona API and Function snapshot configuration and disables E2B', () => {
|
|
const result = buildCapabilitySetupTransition(
|
|
SANDBOX_SETUP,
|
|
'daytona',
|
|
{
|
|
DAYTONA_API_KEY: 'daytona-key',
|
|
DAYTONA_FUNCTION_SNAPSHOT_ID,
|
|
},
|
|
{}
|
|
)
|
|
|
|
expect(result.remove).toContain('E2B_API_KEY')
|
|
expect(result.values).toMatchObject({
|
|
DAYTONA_API_KEY: 'daytona-key',
|
|
DAYTONA_FUNCTION_SNAPSHOT_ID,
|
|
E2B_ENABLED: 'false',
|
|
NEXT_PUBLIC_E2B_ENABLED: 'false',
|
|
NEXT_PUBLIC_SANDBOXES_ENABLED: 'true',
|
|
})
|
|
})
|
|
|
|
it('removes stale Daytona configuration for E2B and disabled modes', () => {
|
|
expect(
|
|
buildCapabilitySetupTransition(
|
|
SANDBOX_SETUP,
|
|
'e2b',
|
|
{
|
|
E2B_API_KEY: 'e2b-key',
|
|
E2B_FUNCTION_TEMPLATE_ID,
|
|
E2B_FUNCTION_TEMPLATE_GENERATION: '1',
|
|
},
|
|
{}
|
|
).remove
|
|
).toEqual(expect.arrayContaining(['DAYTONA_API_KEY', 'DAYTONA_FUNCTION_SNAPSHOT_ID']))
|
|
expect(buildCapabilitySetupTransition(SANDBOX_SETUP, 'disabled', {}, {}).remove).toEqual(
|
|
expect.arrayContaining(['DAYTONA_API_KEY', 'DAYTONA_FUNCTION_SNAPSHOT_ID'])
|
|
)
|
|
})
|
|
})
|
|
|
|
describe('reconcileLlmSetup', () => {
|
|
it('removes trailing rotation keys omitted after empty-to-finish', () => {
|
|
expect(reconcileLlmSetup('openai', { OPENAI_API_KEY_1: 'replacement' })).toEqual({
|
|
values: { OPENAI_API_KEY_1: 'replacement' },
|
|
remove: ['OPENAI_API_KEY_2', 'OPENAI_API_KEY_3', 'OPENAI_API_KEY'],
|
|
})
|
|
})
|
|
|
|
it('removes a legacy fallback when rotation keys replace it', () => {
|
|
expect(reconcileLlmSetup('fireworks', { FIREWORKS_API_KEY_1: 'replacement' })).toEqual({
|
|
values: { FIREWORKS_API_KEY_1: 'replacement' },
|
|
remove: ['FIREWORKS_API_KEY_2', 'FIREWORKS_API_KEY_3', 'FIREWORKS_API_KEY'],
|
|
})
|
|
})
|
|
})
|