Skip to content

Commit d94c3da

Browse files
authored
testscripts: python tests for numpy and psycopg2 (#2214)
Add tests that install Python with Devbox and then run scripts that import numpy and psycopg2. They currently fail on Linux due to linker errors. To run the tests on Linux with Docker, run: devbox run -e DEVBOX_RUN_FAILING_TESTS=1 docker-testscripts -test.run '^TestScripts$/python' The new docker-testscripts script in devbox.json runs testscripts in a Docker container to make it easier to test various Linux distros and architectures.
1 parent 245b33a commit d94c3da

File tree

6 files changed

+414
-1
lines changed

6 files changed

+414
-1
lines changed

devbox.json

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,27 @@
3939
"test-projects-only": "DEVBOX_RUN_PROJECT_TESTS=1 go test -v -timeout ${DEVBOX_GOLANG_TEST_TIMEOUT:-30m} ./... -run \"TestExamples|TestScriptsWithProjects\"",
4040
"update-examples": "devbox run build && go run testscripts/testrunner/updater/main.go",
4141
"tidy": "go mod tidy",
42+
43+
// docker-testscripts runs the testscripts with Docker to exercise
44+
// Linux-specific tests. It invokes the test binary directly, so any extra
45+
// test runner flags must have their "-test." prefix.
46+
//
47+
// For example, to only run Python tests:
48+
//
49+
// devbox run docker-testscripts -test.run ^TestScripts$/python
50+
"docker-testscripts": [
51+
"cd testscripts",
52+
53+
// The Dockerfile looks for a testscripts-$TARGETOS-$TARGETARCH binary
54+
// to run the tests. Pre-compiling a static test binary lets us avoid
55+
// polluting the container with a Go toolchain or shared libraries that
56+
// might interfere with linker tests.
57+
"trap 'rm -f testscripts-linux-amd64 testscripts-linux-arm64' EXIT",
58+
"GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go test -c -o testscripts-linux-amd64",
59+
"GOOS=linux GOARCH=arm64 CGO_ENABLED=0 go test -c -o testscripts-linux-arm64",
60+
"image=$(docker build --quiet --tag devbox-ubuntu:noble --platform linux/amd64 .)",
61+
"docker run --rm --platform linux/amd64 -e DEVBOX_RUN_FAILING_TESTS -e DEVBOX_RUN_PROJECT_TESTS -e DEVBOX_DEBUG $image \"$@\"",
62+
],
4263
},
4364
},
4465
}

testscripts/Dockerfile

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# syntax=docker/dockerfile:1
2+
3+
# This Dockerfile is designed to be as distro-agnostic as possible. By default
4+
# it uses ubuntu:noble as its base image, but this can be overridden by setting
5+
# the BASEIMAGE and BASETAG build args. This makes it easier to run Devbox tests
6+
# against different distros/versions without creating a bunch of separate
7+
# Dockerfiles.
8+
9+
ARG BASEIMAGE=ubuntu
10+
ARG BASETAG=noble
11+
12+
FROM scratch AS installer
13+
14+
ADD --chmod=0755 --link https://install.determinate.systems/nix/nix-installer-x86_64-linux /nix-installer-linux-amd64
15+
ADD --chmod=0755 --link https://install.determinate.systems/nix/nix-installer-aarch64-linux /nix-installer-linux-arm64
16+
17+
FROM $BASEIMAGE:$BASETAG
18+
19+
ARG TARGETOS
20+
ARG TARGETARCH
21+
22+
COPY --from=installer --link /nix-installer-$TARGETOS-$TARGETARCH nix-installer
23+
RUN <<EOF
24+
set -e
25+
26+
# Setting this env var is the same as passing --extra-conf to nix-installer.
27+
export NIX_INSTALLER_EXTRA_CONF="filter-syscalls = false
28+
sandbox = false"
29+
30+
./nix-installer install linux --no-confirm --logger full --init none
31+
rm nix-installer
32+
EOF
33+
ENV SSL_CERT_FILE=/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt
34+
35+
COPY --link */*.test.txt /devbox/testscripts/
36+
COPY --link testscripts-$TARGETOS-$TARGETARCH /devbox/testscripts/test
37+
38+
VOLUME /nix/store
39+
WORKDIR /devbox/testscripts
40+
ENTRYPOINT [ "/devbox/testscripts/test" ]
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
# Python Missing Shared Library Test
2+
#
3+
# Install NumPy as a binary wheel using pip and verify that it loads.
4+
# The PIP_ONLY_BINARY environment variable forces downloading the binary wheel.
5+
#
6+
# Naively installing and loading NumPy fails because it cannot find
7+
# libstdc++.so. The nixpkgs Python interpreter doesn't search standard system
8+
# paths, so Devbox must patch it or provide the location of native dependencies.
9+
10+
[!env:DEVBOX_RUN_FAILING_TESTS] [linux] skip 'this test doesn''t pass on Linux yet'
11+
12+
exec devbox install
13+
14+
# pip install numpy
15+
exec devbox run venv -- pip install numpy==2.1.0
16+
stdout 'Successfully installed numpy'
17+
18+
# run python test script that imports numpy
19+
exec devbox run venv -- python main.py
20+
! stderr 'libstdc\+\+\.so\.6: cannot open shared object file: No such file or directory'
21+
22+
-- main.py --
23+
import numpy
24+
25+
array = numpy.array([1, 2, 3, 4, 5])
26+
print("Array:", array)
27+
print("Mean:", numpy.mean(array))
28+
29+
-- devbox.json --
30+
{
31+
"packages": {
32+
"python": "latest"
33+
},
34+
"env": {
35+
"PIP_DISABLE_PIP_VERSION_CHECK": "1",
36+
"PIP_NO_CACHE_DIR": "1",
37+
"PIP_NO_INPUT": "1",
38+
"PIP_NO_PYTHON_VERSION_WARNING": "1",
39+
"PIP_ONLY_BINARY": "numpy",
40+
"PIP_PROGRESS_BAR": "off",
41+
"PIP_REQUIRE_VIRTUALENV": "1",
42+
"PIP_ROOT_USER_ACTION": "ignore"
43+
},
44+
"shell": {
45+
"scripts": {
46+
"venv": ". $VENV_DIR/bin/activate && \"$@\""
47+
}
48+
}
49+
}
50+
51+
-- devbox.lock --
52+
{
53+
"lockfile_version": "1",
54+
"packages": {
55+
"python@latest": {
56+
"last_modified": "2024-07-07T07:43:47Z",
57+
"plugin_version": "0.0.3",
58+
"resolved": "github:NixOS/nixpkgs/b60793b86201040d9dee019a05089a9150d08b5b#python3",
59+
"source": "devbox-search",
60+
"version": "3.12.4",
61+
"systems": {
62+
"aarch64-darwin": {
63+
"outputs": [
64+
{
65+
"name": "out",
66+
"path": "/nix/store/3swy1vadi125g0c1vxqp8ykdr749803j-python3-3.12.4",
67+
"default": true
68+
}
69+
],
70+
"store_path": "/nix/store/3swy1vadi125g0c1vxqp8ykdr749803j-python3-3.12.4"
71+
},
72+
"aarch64-linux": {
73+
"outputs": [
74+
{
75+
"name": "out",
76+
"path": "/nix/store/sz2facg15yq3ziqkidb1dkkglwzkkg8a-python3-3.12.4",
77+
"default": true
78+
},
79+
{
80+
"name": "debug",
81+
"path": "/nix/store/19vjjqg7jbfblqapf63nm9ich1xdq9dx-python3-3.12.4-debug"
82+
}
83+
],
84+
"store_path": "/nix/store/sz2facg15yq3ziqkidb1dkkglwzkkg8a-python3-3.12.4"
85+
},
86+
"x86_64-darwin": {
87+
"outputs": [
88+
{
89+
"name": "out",
90+
"path": "/nix/store/3y5wy1i9nq5293knm23mxsj5l6w41h2l-python3-3.12.4",
91+
"default": true
92+
}
93+
],
94+
"store_path": "/nix/store/3y5wy1i9nq5293knm23mxsj5l6w41h2l-python3-3.12.4"
95+
},
96+
"x86_64-linux": {
97+
"outputs": [
98+
{
99+
"name": "out",
100+
"path": "/nix/store/z7xxy35k7620hs6fn6la5fg2lgklv72l-python3-3.12.4",
101+
"default": true
102+
},
103+
{
104+
"name": "debug",
105+
"path": "/nix/store/3x6jqv5yw212v8rlwql88cn94dginq32-python3-3.12.4-debug"
106+
}
107+
],
108+
"store_path": "/nix/store/z7xxy35k7620hs6fn6la5fg2lgklv72l-python3-3.12.4"
109+
}
110+
}
111+
}
112+
}
113+
}
Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
# Python Old glibc Test
2+
#
3+
# Check that an older version of the Python interpreter (3.7) can import and run
4+
# pip packages that are built from source.
5+
6+
[!env:DEVBOX_RUN_FAILING_TESTS] [linux] skip 'this test doesn''t pass on Linux yet'
7+
8+
exec devbox install
9+
10+
# pip install psycopg2
11+
exec devbox run venv -- pip install psycopg2==2.9.5
12+
stdout 'Successfully installed psycopg2'
13+
14+
# run python test script that imports psycopg2
15+
exec devbox run venv -- python main.py
16+
! stderr '.*glibc-2.35-224/lib/libc\.so\.6: version `GLIBC_2.38'' not found \(required by .*/site-packages/psycopg2/_psycopg\.cpython-37m-x86_64-linux-gnu\.so\)'
17+
18+
-- main.py --
19+
import psycopg2
20+
21+
try:
22+
conn = psycopg2.connect(dbname="test", user="postgres")
23+
except psycopg2.OperationalError:
24+
pass
25+
26+
-- devbox.json --
27+
{
28+
"packages": {
29+
"python": "3.7",
30+
"postgresql": "15.5"
31+
},
32+
"env": {
33+
"PIP_DISABLE_PIP_VERSION_CHECK": "1",
34+
"PIP_NO_CACHE_DIR": "1",
35+
"PIP_NO_INPUT": "1",
36+
"PIP_NO_PYTHON_VERSION_WARNING": "1",
37+
"PIP_PROGRESS_BAR": "off",
38+
"PIP_REQUIRE_VIRTUALENV": "1",
39+
"PIP_ROOT_USER_ACTION": "ignore"
40+
},
41+
"shell": {
42+
"scripts": {
43+
"venv": ". $VENV_DIR/bin/activate && \"$@\""
44+
}
45+
}
46+
}
47+
48+
-- devbox.lock --
49+
{
50+
"lockfile_version": "1",
51+
"packages": {
52+
"postgresql@latest": {
53+
"last_modified": "2024-02-22T01:07:56Z",
54+
"plugin_version": "0.0.2",
55+
"resolved": "github:NixOS/nixpkgs/98b00b6947a9214381112bdb6f89c25498db4959#postgresql",
56+
"source": "devbox-search",
57+
"version": "15.5",
58+
"systems": {
59+
"aarch64-darwin": {
60+
"outputs": [
61+
{
62+
"name": "out",
63+
"path": "/nix/store/6cn0kmav77wba54xibfg9clqzbpan74b-postgresql-15.5",
64+
"default": true
65+
},
66+
{
67+
"name": "man",
68+
"path": "/nix/store/588y60371pqh3vc9rasjawfwmchpac9d-postgresql-15.5-man",
69+
"default": true
70+
},
71+
{
72+
"name": "doc",
73+
"path": "/nix/store/dxivb9x0iwssqzz8wsswis9q9r1sjm18-postgresql-15.5-doc"
74+
},
75+
{
76+
"name": "lib",
77+
"path": "/nix/store/dbc9hjh5ll5pjgxwl3r9nymdxw7sw8cl-postgresql-15.5-lib"
78+
}
79+
]
80+
},
81+
"aarch64-linux": {
82+
"outputs": [
83+
{
84+
"name": "out",
85+
"path": "/nix/store/kvpjir3cjbijs2w8b20yzqjq0nsd63mp-postgresql-15.5",
86+
"default": true
87+
},
88+
{
89+
"name": "man",
90+
"path": "/nix/store/4kcdjf0gg9jl4n9kxvj5iq92byry6b7l-postgresql-15.5-man",
91+
"default": true
92+
},
93+
{
94+
"name": "debug",
95+
"path": "/nix/store/srqwd7alwglrsjclsfnrlx01n69iyy9s-postgresql-15.5-debug"
96+
},
97+
{
98+
"name": "doc",
99+
"path": "/nix/store/5fn32sdar6nk5ha9d5zb6rfpndgdbg68-postgresql-15.5-doc"
100+
},
101+
{
102+
"name": "lib",
103+
"path": "/nix/store/addi70hgggl75jm74p0s435bfaay6m1w-postgresql-15.5-lib"
104+
}
105+
]
106+
},
107+
"x86_64-darwin": {
108+
"outputs": [
109+
{
110+
"name": "out",
111+
"path": "/nix/store/v5ym92k3kss1af7n1788653vis1d6qsc-postgresql-15.5",
112+
"default": true
113+
},
114+
{
115+
"name": "man",
116+
"path": "/nix/store/x9hm4ip61cichmhzhzpykzypn3pqkh01-postgresql-15.5-man",
117+
"default": true
118+
},
119+
{
120+
"name": "doc",
121+
"path": "/nix/store/nd1mhmgpm9w5rfpiibg6m7g4difpl5af-postgresql-15.5-doc"
122+
},
123+
{
124+
"name": "lib",
125+
"path": "/nix/store/q8lijs7rmlkx4qssmh0sjyy77f41y2jh-postgresql-15.5-lib"
126+
}
127+
]
128+
},
129+
"x86_64-linux": {
130+
"outputs": [
131+
{
132+
"name": "out",
133+
"path": "/nix/store/vvd65gjggb2n8wxbsk1cyxx0wpfidagf-postgresql-15.5",
134+
"default": true
135+
},
136+
{
137+
"name": "man",
138+
"path": "/nix/store/88jhk99imah1v19xqkldi1lfyaayni71-postgresql-15.5-man",
139+
"default": true
140+
},
141+
{
142+
"name": "lib",
143+
"path": "/nix/store/w109qgbl14afcg5akhnahf8r0hkdqqb6-postgresql-15.5-lib"
144+
},
145+
{
146+
"name": "debug",
147+
"path": "/nix/store/ia44jr4m4jyf3a48qwpf6vgrr95jig46-postgresql-15.5-debug"
148+
},
149+
{
150+
"name": "doc",
151+
"path": "/nix/store/7vfnvfb6scmf23y6yj5zx8p5r3wsgnq5-postgresql-15.5-doc"
152+
}
153+
]
154+
}
155+
}
156+
},
157+
158+
"last_modified": "2022-12-17T09:19:40Z",
159+
"plugin_version": "0.0.3",
160+
"resolved": "github:NixOS/nixpkgs/80c24eeb9ff46aa99617844d0c4168659e35175f#python37",
161+
"source": "devbox-search",
162+
"version": "3.7.16",
163+
"systems": {
164+
"aarch64-darwin": {
165+
"outputs": [
166+
{
167+
"name": "out",
168+
"path": "/nix/store/a89sd5jwn01cdg97lkspl8cpf75y5142-python3-3.7.16",
169+
"default": true
170+
}
171+
],
172+
"store_path": "/nix/store/a89sd5jwn01cdg97lkspl8cpf75y5142-python3-3.7.16"
173+
},
174+
"aarch64-linux": {
175+
"outputs": [
176+
{
177+
"name": "out",
178+
"path": "/nix/store/ymrbxfmljyl73rmh5cfk0bzk3ydcbqg8-python3-3.7.16",
179+
"default": true
180+
},
181+
{
182+
"name": "debug",
183+
"path": "/nix/store/3x7736j3fyw6j9fzn1y9fc0iqyf1rncc-python3-3.7.16-debug"
184+
}
185+
],
186+
"store_path": "/nix/store/ymrbxfmljyl73rmh5cfk0bzk3ydcbqg8-python3-3.7.16"
187+
},
188+
"x86_64-darwin": {
189+
"outputs": [
190+
{
191+
"name": "out",
192+
"path": "/nix/store/i028a4nf177g23ksa7kc63ld9nys17nb-python3-3.7.16",
193+
"default": true
194+
}
195+
],
196+
"store_path": "/nix/store/i028a4nf177g23ksa7kc63ld9nys17nb-python3-3.7.16"
197+
},
198+
"x86_64-linux": {
199+
"outputs": [
200+
{
201+
"name": "out",
202+
"path": "/nix/store/ik7s754pwxhiky396mjagzmjs1kp0wzq-python3-3.7.16",
203+
"default": true
204+
},
205+
{
206+
"name": "debug",
207+
"path": "/nix/store/l0xi13a88d4vjn8ada3a58zkwm88hq7h-python3-3.7.16-debug"
208+
}
209+
],
210+
"store_path": "/nix/store/ik7s754pwxhiky396mjagzmjs1kp0wzq-python3-3.7.16"
211+
}
212+
}
213+
}
214+
}
215+
}

0 commit comments

Comments
 (0)