File size: 3,163 Bytes
2c2dc59
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import { existsSync } from 'fs'
import { mkdir, mkdtemp, writeFile } from 'fs/promises'
import { dirname, join } from 'path'
import { tmpdir } from 'os'
import { describe, expect, test } from 'bun:test'
import { resolveTaskRuntime } from './sourceRuntimeResolver.js'

async function makePublicDir(): Promise<string> {
  return mkdtemp(join(tmpdir(), 'source-runtime-'))
}

describe('resolveTaskRuntime', () => {
  test('fails before agent startup when env_manifest points at a missing Python', async () => {
    const publicDir = await makePublicDir()
    await mkdir(join(publicDir, 'envs'), { recursive: true })
    await writeFile(
      join(publicDir, 'envs', 'env_manifest.json'),
      JSON.stringify({
        default_env: 'runtime',
        envs: {
          runtime: {
            python: {
              windows: 'envs/runtime/.venv/Scripts/python.exe',
              posix: 'envs/runtime/.venv/bin/python',
            },
          },
        },
      }),
      'utf8',
    )

    const runtime = await resolveTaskRuntime(publicDir)

    expect(runtime.ok).toBe(false)
    if (!runtime.ok) {
      expect(runtime.error).toContain('Unable to resolve task Python')
      expect(runtime.checked.length).toBeGreaterThan(0)
    }
  })

  test('uses the configured platform Python when it exists', async () => {
    const publicDir = await makePublicDir()
    const pythonRel =
      process.platform === 'win32'
        ? 'envs/runtime/.venv/Scripts/python.exe'
        : 'envs/runtime/.venv/bin/python'
    const pythonAbs = join(publicDir, ...pythonRel.split('/'))
    await mkdir(dirname(pythonAbs), { recursive: true })
    await writeFile(pythonAbs, '', 'utf8')
    await mkdir(join(publicDir, 'envs'), { recursive: true })
    await writeFile(
      join(publicDir, 'envs', 'env_manifest.json'),
      JSON.stringify({
        default_env: 'runtime',
        envs: {
          runtime: {
            python: {
              [process.platform === 'win32' ? 'windows' : 'posix']: pythonRel,
            },
          },
        },
      }),
      'utf8',
    )

    const runtime = await resolveTaskRuntime(publicDir)

    expect(runtime.ok).toBe(true)
    if (runtime.ok) {
      expect(existsSync(runtime.python)).toBe(true)
      expect(runtime.displayPath).toContain('public/')
    }
  })

  test('rejects configured Python paths outside the public bundle', async () => {
    const publicDir = await makePublicDir()
    const outsideDir = await makePublicDir()
    const outsidePython = join(outsideDir, 'python')
    await writeFile(outsidePython, '', 'utf8')
    await mkdir(join(publicDir, 'envs'), { recursive: true })
    await writeFile(
      join(publicDir, 'envs', 'env_manifest.json'),
      JSON.stringify({
        default_env: 'runtime',
        envs: {
          runtime: {
            python: {
              [process.platform === 'win32' ? 'windows' : 'posix']: outsidePython,
            },
          },
        },
      }),
      'utf8',
    )

    const runtime = await resolveTaskRuntime(publicDir)

    expect(runtime.ok).toBe(false)
    if (!runtime.ok) {
      expect(runtime.error).toContain('outside public/')
    }
  })
})