mirror of
https://github.com/OpenHands/OpenHands.git
synced 2025-12-26 05:48:36 +08:00
Remove poetry dependency in Jupyter Plugin (#9789)
This commit is contained in:
parent
b96301061d
commit
ee14f1ea41
@ -1,5 +1,5 @@
|
||||
# Workflow that runs python unit tests
|
||||
name: Run Python Unit Tests
|
||||
# Workflow that runs python tests
|
||||
name: Run Python Tests
|
||||
|
||||
# The jobs in this workflow are required, so they must run at all times
|
||||
# * Always run on "main"
|
||||
@ -16,9 +16,9 @@ concurrency:
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
# Run python unit tests on Linux
|
||||
# Run python tests on Linux
|
||||
test-on-linux:
|
||||
name: Python Unit Tests on Linux
|
||||
name: Python Tests on Linux
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2204
|
||||
env:
|
||||
INSTALL_DOCKER: '0' # Set to '0' to skip Docker installation
|
||||
@ -51,6 +51,8 @@ jobs:
|
||||
run: poetry run pytest --forked -n auto -svv ./tests/unit
|
||||
- name: Run Runtime Tests with CLIRuntime
|
||||
run: TEST_RUNTIME=cli poetry run pytest -svv tests/runtime/test_bash.py
|
||||
- name: Run E2E Tests
|
||||
run: poetry run pytest -svv tests/e2e
|
||||
|
||||
# Run specific Windows python tests
|
||||
test-on-windows:
|
||||
@ -8,8 +8,6 @@ from openhands.events.action import (
|
||||
Action,
|
||||
AgentFinishAction,
|
||||
AgentRejectAction,
|
||||
BrowseInteractiveAction,
|
||||
BrowseURLAction,
|
||||
CmdRunAction,
|
||||
FileReadAction,
|
||||
FileWriteAction,
|
||||
@ -17,7 +15,6 @@ from openhands.events.action import (
|
||||
)
|
||||
from openhands.events.observation import (
|
||||
AgentStateChangedObservation,
|
||||
BrowserOutputObservation,
|
||||
CmdOutputMetadata,
|
||||
CmdOutputObservation,
|
||||
FileReadObservation,
|
||||
@ -54,17 +51,19 @@ class DummyAgent(Agent):
|
||||
},
|
||||
{
|
||||
'action': CmdRunAction(command='echo "foo"'),
|
||||
'observations': [CmdOutputObservation('foo', command='echo "foo"')],
|
||||
'observations': [
|
||||
CmdOutputObservation(
|
||||
'foo',
|
||||
command='echo "foo"',
|
||||
metadata=CmdOutputMetadata(exit_code=0),
|
||||
)
|
||||
],
|
||||
},
|
||||
{
|
||||
'action': FileWriteAction(
|
||||
content='echo "Hello, World!"', path='hello.sh'
|
||||
),
|
||||
'observations': [
|
||||
FileWriteObservation(
|
||||
content='echo "Hello, World!"', path='hello.sh'
|
||||
)
|
||||
],
|
||||
'observations': [FileWriteObservation(content='', path='hello.sh')],
|
||||
},
|
||||
{
|
||||
'action': FileReadAction(path='hello.sh'),
|
||||
@ -76,36 +75,12 @@ class DummyAgent(Agent):
|
||||
'action': CmdRunAction(command='bash hello.sh'),
|
||||
'observations': [
|
||||
CmdOutputObservation(
|
||||
'bash: hello.sh: No such file or directory',
|
||||
command='bash workspace/hello.sh',
|
||||
metadata=CmdOutputMetadata(exit_code=127),
|
||||
'Hello, World!',
|
||||
command='bash hello.sh',
|
||||
metadata=CmdOutputMetadata(exit_code=0),
|
||||
)
|
||||
],
|
||||
},
|
||||
{
|
||||
'action': BrowseURLAction(url='https://google.com'),
|
||||
'observations': [
|
||||
BrowserOutputObservation(
|
||||
'<html><body>Simulated Google page</body></html>',
|
||||
url='https://google.com',
|
||||
screenshot='',
|
||||
trigger_by_action='',
|
||||
),
|
||||
],
|
||||
},
|
||||
{
|
||||
'action': BrowseInteractiveAction(
|
||||
browser_actions='goto("https://google.com")'
|
||||
),
|
||||
'observations': [
|
||||
BrowserOutputObservation(
|
||||
'<html><body>Simulated Google page after interaction</body></html>',
|
||||
url='https://google.com',
|
||||
screenshot='',
|
||||
trigger_by_action='',
|
||||
),
|
||||
],
|
||||
},
|
||||
{
|
||||
'action': AgentRejectAction(),
|
||||
'observations': [AgentStateChangedObservation('', AgentState.REJECTED)],
|
||||
@ -147,6 +122,47 @@ class DummyAgent(Agent):
|
||||
obs.pop('timestamp', None)
|
||||
obs.pop('cause', None)
|
||||
obs.pop('source', None)
|
||||
# Remove dynamic metadata fields that vary between runs
|
||||
if 'extras' in obs and 'metadata' in obs['extras']:
|
||||
metadata = obs['extras']['metadata']
|
||||
if isinstance(metadata, dict):
|
||||
metadata.pop('pid', None)
|
||||
metadata.pop('username', None)
|
||||
metadata.pop('hostname', None)
|
||||
metadata.pop('working_dir', None)
|
||||
metadata.pop('py_interpreter_path', None)
|
||||
metadata.pop('suffix', None)
|
||||
# Normalize file paths for comparison - extract just the filename
|
||||
if 'extras' in obs and 'path' in obs['extras']:
|
||||
path = obs['extras']['path']
|
||||
if isinstance(path, str):
|
||||
# Extract just the filename from the path
|
||||
import os
|
||||
|
||||
obs['extras']['path'] = os.path.basename(path)
|
||||
# Normalize message field to handle path differences
|
||||
if 'message' in obs:
|
||||
import os
|
||||
|
||||
message = obs['message']
|
||||
if isinstance(message, str):
|
||||
# Replace full paths with just filenames in messages
|
||||
if 'I wrote to the file ' in message:
|
||||
parts = message.split('I wrote to the file ')
|
||||
if len(parts) == 2:
|
||||
filename = os.path.basename(
|
||||
parts[1].rstrip('.')
|
||||
)
|
||||
obs['message'] = (
|
||||
f'I wrote to the file {filename}.'
|
||||
)
|
||||
elif 'I read the file ' in message:
|
||||
parts = message.split('I read the file ')
|
||||
if len(parts) == 2:
|
||||
filename = os.path.basename(
|
||||
parts[1].rstrip('.')
|
||||
)
|
||||
obs['message'] = f'I read the file {filename}.'
|
||||
|
||||
if hist_obs != expected_obs:
|
||||
print(
|
||||
|
||||
@ -635,7 +635,8 @@ def _create_server(
|
||||
server_port=execution_server_port,
|
||||
plugins=plugins,
|
||||
app_config=config,
|
||||
python_prefix=['poetry', 'run'],
|
||||
python_prefix=[],
|
||||
python_executable=sys.executable,
|
||||
override_user_id=user_id,
|
||||
override_username=username,
|
||||
)
|
||||
|
||||
62
tests/e2e/test_local_runtime.py
Normal file
62
tests/e2e/test_local_runtime.py
Normal file
@ -0,0 +1,62 @@
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import tempfile
|
||||
|
||||
|
||||
def test_headless_mode_with_dummy_agent_no_browser():
|
||||
"""
|
||||
E2E test: build a docker image from python:3.13, install openhands from source,
|
||||
and run a local runtime task in headless mode.
|
||||
"""
|
||||
repo_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../'))
|
||||
dockerfile = """
|
||||
FROM python:3.13-slim
|
||||
WORKDIR /src
|
||||
RUN apt-get update && apt-get install -y git build-essential tmux
|
||||
COPY . /src
|
||||
RUN pip install --upgrade pip setuptools wheel
|
||||
RUN pip install .
|
||||
ENV PYTHONUNBUFFERED=1
|
||||
ENV RUNTIME=local
|
||||
ENV RUN_AS_OPENHANDS=false
|
||||
ENV ENABLE_BROWSER=false
|
||||
ENV AGENT_ENABLE_BROWSING=false
|
||||
ENV SKIP_DEPENDENCY_CHECK=1
|
||||
CMD ["python", "-m", "openhands.core.main", "-c", "DummyAgent", "-t", "Hello world"]
|
||||
"""
|
||||
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
dockerfile_path = os.path.join(tmpdir, 'Dockerfile')
|
||||
with open(dockerfile_path, 'w') as f:
|
||||
f.write(dockerfile)
|
||||
# Copy the repo into the temp dir for docker build context
|
||||
build_context = os.path.join(tmpdir, 'context')
|
||||
shutil.copytree(repo_root, build_context, dirs_exist_ok=True)
|
||||
|
||||
image_tag = 'openhands-e2e-local-runtime-test'
|
||||
build_cmd = [
|
||||
'docker',
|
||||
'build',
|
||||
'-t',
|
||||
image_tag,
|
||||
'-f',
|
||||
dockerfile_path,
|
||||
build_context,
|
||||
]
|
||||
run_cmd = ['docker', 'run', '--rm', image_tag]
|
||||
|
||||
# Build the image
|
||||
build_proc = subprocess.run(build_cmd, capture_output=True, text=True)
|
||||
print('Docker build stdout:', build_proc.stdout)
|
||||
print('Docker build stderr:', build_proc.stderr)
|
||||
assert build_proc.returncode == 0, 'Docker build failed'
|
||||
|
||||
# Run the container
|
||||
run_proc = subprocess.run(run_cmd, capture_output=True, text=True)
|
||||
print('Docker run stdout:', run_proc.stdout)
|
||||
print('Docker run stderr:', run_proc.stderr)
|
||||
assert run_proc.returncode == 0, (
|
||||
f'Docker run failed with code {run_proc.returncode}'
|
||||
)
|
||||
assert 'Warning: Observation mismatch' not in run_proc.stdout
|
||||
Loading…
x
Reference in New Issue
Block a user