Skip to content

Commit 4ee7f70

Browse files
committed
cleanup: PR comments
1 parent 3d89331 commit 4ee7f70

File tree

5 files changed

+164
-107
lines changed

5 files changed

+164
-107
lines changed

README.md

Lines changed: 36 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,10 @@ Buildscripts to build numpy and other wheels for wasix. For convenience, this pa
8484

8585
The build script is controlled by the following environment variables:
8686

87-
- `CC`, `CXX`, `AR`, `LD`, `RANLIB`, etc... : The cross-compiler tools. These should all be normal clang tools, but target wasm32-wasix by default and use the wasix sysroot.
88-
- `WASIX_SYSROOT`: The path to the wasix sysroot that is used by the toolchain. Libraries will get installed here when you run `make install` or when they are required to build a package.
89-
- `INSTALL_DIR`: The path to the python library path. Wheels will get installed here when you run `make install`.
90-
- `WASMER`: The path to the wasmer binary. You must have it registered to handle wasm files as binfmt_misc. You can do this with `sudo $WASMER binfmt reregister`.
87+
* `CC`, `CXX`, `AR`, `LD`, `RANLIB`, etc... : The cross-compiler tools. These should all be normal clang tools, but target wasm32-wasix by default and use the wasix sysroot.
88+
* `WASIX_SYSROOT`: The path to the wasix sysroot that is used by the toolchain. Libraries will get installed here when you run `make install` or when they are required to build a package.
89+
* `INSTALL_DIR`: The path to the python library path. Wheels will get installed here when you run `make install`.
90+
* `WASMER`: The path to the wasmer binary. You must have it registered to handle wasm files as binfmt_misc. You can do this with `sudo $WASMER binfmt reregister`.
9191

9292
The easiest way to setup all the environment variables is to activate the wasix-clang environment using `source wasix-clang/activate`.
9393

@@ -339,7 +339,7 @@ to check which python libraries depend on shared libs. We try to keep that to a
339339

340340
### Structure
341341

342-
<!--
342+
<!--
343343
There is the pkgs folder that contains most stuff
344344
345345
For each project that can be built there are multiple files depending on the type.
@@ -365,52 +365,52 @@ TODO: Make this more understandable
365365

366366
Inside the pkgs/ folder there can be the following directories:
367367

368-
- `*.source`: clean submodule checkout
369-
- `*.prepared`: patched worktree of source
370-
- `*.build`: temporary build directory
371-
- `*.tar.gz`: python sdist
372-
- `*.sdist`: unpacked python sdist
373-
- `*.whl`: compiled python wheel
374-
- `*.wheel`: unpacked python wheel
375-
- `*.lib`: unpacked library/application
376-
- `*.tar.xz`: packed library/application
368+
* `*.source`: clean submodule checkout
369+
* `*.prepared`: patched worktree of source
370+
* `*.build`: temporary build directory
371+
* `*.tar.gz`: python sdist
372+
* `*.sdist`: unpacked python sdist
373+
* `*.whl`: compiled python wheel
374+
* `*.wheel`: unpacked python wheel
375+
* `*.lib`: unpacked library/application
376+
* `*.tar.xz`: packed library/application
377377

378378
#### Base structure
379379

380380
Each project follows a consistent flow through the first three main directories.
381381

382-
- `*.source`
383-
- This is a clean checkout of the project's upstream source code, tracked as a git submodule.
384-
- We avoid modifying this directly, since changes here would slow down git operations in the build-scripts repo.
385-
- `*.prepared`
386-
- A git worktree created from the `*.source` repository.
387-
- If patches are needed, they're applied here.
388-
- If no patches are needed, it's just a clean mirror of the source.
389-
- This directory is persistent and only refreshed if the source changes so new patches can be developed in this directory
390-
- `*.build`
391-
- A copy of the `*.prepared` directory, used for the actual build step.
392-
- Contains all intermediate build artifacts.
393-
- This directory is temporary and may be deleted between builds. Never make manual changes here.
382+
* `*.source`
383+
* This is a clean checkout of the project's upstream source code, tracked as a git submodule.
384+
* We avoid modifying this directly, since changes here would slow down git operations in the build-scripts repo.
385+
* `*.prepared`
386+
* A git worktree created from the `*.source` repository.
387+
* If patches are needed, they're applied here.
388+
* If no patches are needed, it's just a clean mirror of the source.
389+
* This directory is persistent and only refreshed if the source changes so new patches can be developed in this directory
390+
* `*.build`
391+
* A copy of the `*.prepared` directory, used for the actual build step.
392+
* Contains all intermediate build artifacts.
393+
* This directory is temporary and may be deleted between builds. Never make manual changes here.
394394

395395
The remaining steps are different depending on the type of project.
396396

397397
#### Python modules
398398

399-
- The build step creates a `*.tar.gz` sdist from the `*.build` directory.
400-
- The sdist is then extracted into a `*.sdist` folder.
401-
- Finally, a wheel (`*.whl`) is built from the `*.sdist`.
402-
- If you want to you can make a `*.wheel` directory to view the unpacked wheel
399+
* The build step creates a `*.tar.gz` sdist from the `*.build` directory.
400+
* The sdist is then extracted into a `*.sdist` folder.
401+
* Finally, a wheel (`*.whl`) is built from the `*.sdist`.
402+
* If you want to you can make a `*.wheel` directory to view the unpacked wheel
403403

404404
#### WASIX libraries and applications
405405

406-
- The build step builds the library and installs it into a `*.lib` folder, following the correct directory structure.
407-
- That folder is then compressed into a final distributable \*.tar.xz.
406+
* The build step builds the library and installs it into a `*.lib` folder, following the correct directory structure.
407+
* That folder is then compressed into a final distributable *.tar.xz.
408408

409409
#### Interdependencies
410410

411411
If a project depends on other project they can either be direct dependencies of that project or you can define a `*.sysroot` target with the dependencies as prerequisites.
412412

413-
- `*.sysroot`
414-
- Contains the merged builds of multiple other projects
415-
- Useful when a project is using pkg-config to find its dependencies
416-
- Automatically builds a sysroot from its list of prerequisites
413+
* `*.sysroot`
414+
* Contains the merged builds of multiple other projects
415+
* Useful when a project is using pkg-config to find its dependencies
416+
* Automatically builds a sysroot from its list of prerequisites

run-tests.sh

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
output_file=$(mktemp)
2+
3+
PYTHON_PACKAGE=${1:-"python-with-packages"}
4+
5+
# Set if a test that was not expected to fail did fail
6+
WORKING_FAILED=()
7+
BROKEN_FAILED=()
8+
WORKING_PASSED=()
9+
BROKEN_PASSED=()
10+
SKIPPED=()
11+
12+
GREEN="\033[0;32m"
13+
RED="\033[0;31m"
14+
YELLOW="\033[0;33m"
15+
RESET="\033[0m"
16+
17+
for testfile in tests/*.py; do
18+
# Extract just the filename without path
19+
TEST_NAME=$(basename "$testfile")
20+
21+
# Skip test if it is a *.skip.py file
22+
if [[ "$TEST_NAME" == *.skip.py ]]; then
23+
echo -e "${YELLOW}Skipping:${RESET} \033[1m$TEST_NAME${RESET}"
24+
SKIPPED+=( "$TEST_NAME" )
25+
continue
26+
fi
27+
28+
EXPECT_BROKEN=false
29+
if [[ "$TEST_NAME" == *-broken.py ]]; then
30+
EXPECT_BROKEN=true
31+
fi
32+
33+
# Print colorful running message
34+
echo -e "\033[0;34m▶ Running:${RESET} \033[1m$TEST_NAME${RESET}"
35+
36+
# Run the test
37+
$WASMER run --net --mapdir="/src:$(pwd)" --llvm $PYTHON_PACKAGE /src/$testfile
38+
EXIT_CODE=$?
39+
40+
# Prepare output color. This will be changed depending on what we expect for the test
41+
COLOR="$GREEN"
42+
# Log result and prepare colorful outcome for later
43+
if [ $EXIT_CODE -eq 0 ]; then
44+
if $EXPECT_BROKEN; then
45+
COLOR="${RED}"
46+
BROKEN_PASSED+=( "$TEST_NAME" )
47+
else
48+
COLOR="${GREEN}"
49+
WORKING_PASSED+=( "$TEST_NAME" )
50+
fi
51+
echo -e " ${COLOR}✓ PASSED${RESET} $TEST_NAME" | tee -a "$output_file"
52+
else
53+
if $EXPECT_BROKEN; then
54+
COLOR="${YELLOW}"
55+
BROKEN_FAILED+=( "$TEST_NAME" )
56+
else
57+
COLOR="${RED}"
58+
WORKING_FAILED+=( "$TEST_NAME" )
59+
fi
60+
echo -e " ${COLOR}✗ FAILED${RESET} $TEST_NAME" | tee -a "$output_file"
61+
echo -e " ${COLOR}└── Test failed with exit code $EXIT_CODE${RESET}" | tee -a "$output_file"
62+
fi
63+
echo ""
64+
done
65+
66+
# Check if all broken tests failed and all working tests passed
67+
EXPECTED_OUTCOME=false
68+
if [ ${#WORKING_FAILED[@]} -eq 0 ] && [ ${#BROKEN_PASSED[@]} -eq 0 ]; then
69+
EXPECTED_OUTCOME=true
70+
fi
71+
72+
BROKEN_TESTS=( ${BROKEN_FAILED[@]} ${BROKEN_PASSED[@]} )
73+
WORKING_TESTS=( ${WORKING_FAILED[@]} ${WORKING_PASSED[@]} )
74+
ALL_TESTS=( ${WORKING_FAILED[@]} ${WORKING_PASSED[@]} ${BROKEN_FAILED[@]} ${BROKEN_PASSED[@]} ${SKIPPED[@]} )
75+
76+
77+
# Print summary
78+
cat "$output_file"
79+
echo ""
80+
echo -e "\033[1;34mSummary:\033[0m"
81+
if $EXPECTED_OUTCOME; then
82+
echo -e " \033[0;32mAll tests behaved as expected!\033[0m"
83+
else
84+
echo -e " \033[0;31mSome tests did not behave as expected."
85+
fi
86+
87+
if test ${#WORKING_FAILED[@]} -gt 0; then
88+
echo -e " ${RED}Failed tests (that were expected to pass):${RESET}"
89+
for test in "${WORKING_FAILED[@]}"; do
90+
echo -e " $RED$test$RESET"
91+
done
92+
fi
93+
if test ${#BROKEN_FAILED[@]} -gt 0; then
94+
echo -e " ${YELLOW}However ${#BROKEN_TESTS[@]} are marked broken. ${RESET}\033[4;5mGo fix the underlying issues.${RESET}"
95+
fi
96+
if test ${#BROKEN_WORKING[@]} -gt 0; then
97+
echo -e " ${RED}The following tests were marked broken but passed.${RESET}"
98+
echo -e " ${RED}Go mark them as not broken 🎉:${RESET}"
99+
for test in "${BROKEN_WORKING[@]}"; do
100+
echo -e " $YELLOW$test$RESET"
101+
done
102+
fi
103+
104+
# Exit with the correct code
105+
$EXPECTED_OUTCOME
106+

tests/conftest.py

Lines changed: 0 additions & 21 deletions
This file was deleted.

tests/protobuf-test.py

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
# test_protobuf_basic.py
22

3-
import os
4-
import sys
53
import unittest
6-
7-
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
84
from person_pb2 import Person
95

106

@@ -38,9 +34,7 @@ def test_clear_field(self):
3834
def test_unknown_field_ignored(self):
3935
# Protocol Buffers ignore unknown fields during deserialization.
4036
serialized = self.person.SerializeToString()
41-
corrupted = (
42-
serialized + b"\x20\x01"
43-
) # Append unknown field (field number 4, varint 1)
37+
corrupted = serialized + b"\x20\x01" # Append unknown field (field number 4, varint 1)
4438
new_person = Person()
4539
new_person.ParseFromString(corrupted)
4640
self.assertEqual(new_person.name, "Alice")
@@ -57,5 +51,5 @@ def test_repr_str(self):
5751
self.assertIn("id: 123", repr_str)
5852

5953

60-
if __name__ == "__main__":
61-
unittest.main()
54+
if __name__ == '__main__':
55+
unittest.main()

tests/uvloop-test.py

Lines changed: 19 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,41 @@
11
import asyncio
2-
import pytest
32
import uvloop
43

5-
# Install uvloop as the default event loop policy so asyncio.run uses it
4+
# Install uvloop as the default event loop policy
65
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
76

8-
9-
# Internal async helpers (not collected directly by pytest)
10-
async def _sleep():
7+
async def test_sleep():
8+
print("Testing asyncio.sleep...")
119
await asyncio.sleep(0.1)
10+
print("Passed: asyncio.sleep")
1211

13-
14-
async def _task_creation():
12+
async def test_task_creation():
13+
print("Testing task creation...")
1514
async def dummy():
1615
await asyncio.sleep(0.01)
1716
return 42
1817

1918
task = asyncio.create_task(dummy())
2019
result = await task
2120
assert result == 42, "Task did not return expected result"
21+
print("Passed: task creation and execution")
2222

23+
async def test_tcp_echo_server():
24+
print("Testing TCP echo server...")
2325

24-
async def _tcp_echo_server():
2526
async def handle_echo(reader, writer):
2627
data = await reader.read(100)
2728
writer.write(data)
2829
await writer.drain()
2930
writer.close()
3031

31-
# Use port 0 to avoid conflicts when running under pytest
32-
try:
33-
server = await asyncio.start_server(handle_echo, "127.0.0.1", 0)
34-
except Exception as e: # Network may be sandboxed/disabled
35-
pytest.skip(f"Network unavailable for test: {e}")
36-
37-
if not server.sockets:
38-
server.close()
39-
await server.wait_closed()
40-
pytest.skip("No sockets available (network sandbox)")
41-
42-
host, port = server.sockets[0].getsockname()[:2]
32+
server = await asyncio.start_server(handle_echo, '127.0.0.1', 8888)
33+
addr = server.sockets[0].getsockname()
34+
print(f'Serving on {addr}')
4335

4436
async def client():
45-
reader, writer = await asyncio.open_connection(host, port)
46-
message = b"hello"
37+
reader, writer = await asyncio.open_connection('127.0.0.1', 8888)
38+
message = b'hello'
4739
writer.write(message)
4840
await writer.drain()
4941
data = await reader.read(100)
@@ -54,27 +46,13 @@ async def client():
5446
await asyncio.gather(client(), return_exceptions=False)
5547
server.close()
5648
await server.wait_closed()
57-
58-
59-
# Pytest-compatible sync wrappers
60-
def test_sleep():
61-
asyncio.run(_sleep())
62-
63-
64-
def test_task_creation():
65-
asyncio.run(_task_creation())
66-
67-
68-
def test_tcp_echo_server():
69-
asyncio.run(_tcp_echo_server())
70-
49+
print("Passed: TCP echo server")
7150

7251
async def main():
73-
await _sleep()
74-
await _task_creation()
75-
await _tcp_echo_server()
52+
await test_sleep()
53+
await test_task_creation()
54+
await test_tcp_echo_server()
7655
print("✅ All uvloop tests passed.")
7756

78-
7957
if __name__ == "__main__":
80-
asyncio.run(main())
58+
asyncio.run(main())

0 commit comments

Comments
 (0)