Skip to content

Commit 6003cef

Browse files
fix(runtime): provision default test dependencies
1 parent b60ee71 commit 6003cef

4 files changed

Lines changed: 60 additions & 2 deletions

File tree

‎.github/workflows/ci.yml‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ jobs:
1515
- uses: actions/setup-go@v5
1616
with:
1717
go-version-file: 'go.mod'
18+
- name: Install uv
19+
uses: astral-sh/setup-uv@v9.0.0
1820
- name: Build
1921
run: go build ./...
2022
- name: Vet

‎go.mod‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ go 1.25.12
55
toolchain go1.26.4
66

77
require (
8-
github.com/codefly-dev/core v0.2.70
8+
github.com/codefly-dev/core v0.2.71
99
gopkg.in/yaml.v3 v3.0.1
1010
)
1111

‎go.sum‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ github.com/codefly-dev/core v0.2.69 h1:HAtygNa7YdV9zcPG5lwCuRnYKfewTK/qKG2QNJIyO
4141
github.com/codefly-dev/core v0.2.69/go.mod h1:oP2Ob8tuMJU5wkHN57cR8AcNs6WfkhqmMdTlZLqFipA=
4242
github.com/codefly-dev/core v0.2.70 h1:cLkadz1SqhCX/6nPES62NDZlxP7fbNYAUxJRR88AZ7Q=
4343
github.com/codefly-dev/core v0.2.70/go.mod h1:oP2Ob8tuMJU5wkHN57cR8AcNs6WfkhqmMdTlZLqFipA=
44+
github.com/codefly-dev/core v0.2.71 h1:FyB0WeYKVLDSH+fR9tDLlTjAVxyMZI+Ol0M9wNiD31Y=
45+
github.com/codefly-dev/core v0.2.71/go.mod h1:oP2Ob8tuMJU5wkHN57cR8AcNs6WfkhqmMdTlZLqFipA=
4446
github.com/codefly-dev/gortk v0.2.0 h1:7bOlS5valYz2zil+fZctQNcPCYBcPj86abcw9N8h1hQ=
4547
github.com/codefly-dev/gortk v0.2.0/go.mod h1:dDWUMFgAP063OCGhTEpV7FFUj9+zTcxxO/nV80VKEwg=
4648
github.com/cyphar/filepath-securejoin v0.6.1 h1:5CeZ1jPXEiYt3+Z6zqprSAgSWiggmpVyciv8syjIpVE=

‎pkg/runtime/runtime_test.go‎

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ func TestRuntimeInitDoesNotMutateSourceCheckout(t *testing.T) {
6565
// returns the structured acknowledgement even though the selected test fails.
6666
func TestRuntimeHonorsTypedSelectionWithDefaultRunner(t *testing.T) {
6767
if _, err := exec.LookPath("uv"); err != nil {
68-
t.Skip("uv is not installed")
68+
t.Fatalf("uv is required for the production Python runtime: %v", err)
6969
}
7070
dir := t.TempDir()
7171
content := "import unittest\n\n\nclass CalculatorTests(unittest.TestCase):\n def test_selected_failure(self):\n self.assertEqual(1, 2)\n\n def test_unselected_pass(self):\n self.assertEqual(2, 2)\n"
@@ -98,3 +98,57 @@ func TestRuntimeHonorsTypedSelectionWithDefaultRunner(t *testing.T) {
9898
}
9999
}
100100
}
101+
102+
// TestRuntimeDefaultRunnerMaterializesDeclaredRequirements proves the remote
103+
// agent surface, not only Core's helper. The imported package is available
104+
// exclusively through requirements.txt, so a pytest-only uv overlay must fail
105+
// and the project-derived provisioning contract must pass.
106+
func TestRuntimeDefaultRunnerMaterializesDeclaredRequirements(t *testing.T) {
107+
if _, err := exec.LookPath("uv"); err != nil {
108+
t.Fatalf("uv is required for the production Python runtime: %v", err)
109+
}
110+
root := t.TempDir()
111+
if err := os.MkdirAll(filepath.Join(root, "supportdep"), 0o755); err != nil {
112+
t.Fatal(err)
113+
}
114+
write := func(path, content string) {
115+
t.Helper()
116+
if err := os.WriteFile(filepath.Join(root, path), []byte(content), 0o644); err != nil {
117+
t.Fatal(err)
118+
}
119+
}
120+
write("supportdep/pyproject.toml", `[build-system]
121+
requires = ["setuptools>=68"]
122+
build-backend = "setuptools.build_meta"
123+
124+
[project]
125+
name = "codefly-agent-declared-probe-dependency"
126+
version = "0.0.1"
127+
128+
[tool.setuptools]
129+
py-modules = ["agent_declared_probe_dependency"]
130+
`)
131+
write("supportdep/agent_declared_probe_dependency.py", "VALUE = 'from-agent-declared-requirements'\n")
132+
write("requirements.txt", "./supportdep\n")
133+
write("test_declared_dependency.py", `import agent_declared_probe_dependency
134+
135+
def test_dependency_was_materialized_from_project_declaration():
136+
assert agent_declared_probe_dependency.VALUE == "from-agent-declared-requirements"
137+
`)
138+
139+
svc := pythonservice.New(&resources.Agent{Kind: "codefly:service", Name: "python"})
140+
svc.SourceLocation = root
141+
rt := pythonruntime.New(svc)
142+
resp, err := rt.Test(context.Background(), &runtimev0.TestRequest{})
143+
if err != nil {
144+
t.Fatalf("Test: %v", err)
145+
}
146+
if resp.GetResult().GetState() != runtimev0.TestRunResult_PASSED || resp.GetCounts().GetTotal() != 1 || resp.GetCounts().GetPassed() != 1 {
147+
t.Fatalf("result = %s counts=%+v message=%q, want one passed test", resp.GetResult().GetState(), resp.GetCounts(), resp.GetResult().GetMessage())
148+
}
149+
for _, generated := range []string{"uv.lock", ".venv", ".pytest_cache", "__pycache__"} {
150+
if _, err := os.Stat(filepath.Join(root, generated)); !os.IsNotExist(err) {
151+
t.Fatalf("production agent generated %s in source checkout", generated)
152+
}
153+
}
154+
}

0 commit comments

Comments
 (0)