Skip to content

Commit

Permalink
Fix mount points conflict causing empty project DLL in research envir…
Browse files Browse the repository at this point in the history
…onment (#541)

* chore: exclude .python-version for git tracking

* fix: mount points conflict by LeanCLI and NoteBooks directory

* test: check both mount points available

* chore: add explanation for the test issue

* fix: use Assembly.LoadFrom(<csproj_name>) in Initialize.csx for research to keep consistent with docs

* Minor unit test fix

---------

Co-authored-by: Jhonathan Abreu <[email protected]>
  • Loading branch information
efJerryYang and jhonabreul authored Feb 3, 2025
1 parent 878d5f2 commit 6c6fa92
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 7 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
.python-version

# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
Expand Down
14 changes: 8 additions & 6 deletions lean/commands/research.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,14 @@ def research(project: Path,
research_image,
paths_to_mount)

# Mount project dir to the Notebooks directory first, avoid using volumes to prevent overwriting mounting logic for /LeanCLI
run_options["mounts"].append(Mount(
target=f"{LEAN_ROOT_PATH}/Notebooks",
source=str(project),
type="bind",
read_only=False
))

# Mount the config in the notebooks directory as well
local_config_path = next(m["Source"] for m in run_options["mounts"] if m["Target"].endswith("config.json"))
run_options["mounts"].append(Mount(target=f"{LEAN_ROOT_PATH}/Notebooks/config.json",
Expand All @@ -166,12 +174,6 @@ def research(project: Path,
# Make Ctrl+C stop Jupyter Lab immediately
run_options["stop_signal"] = "SIGKILL"

# Mount the project to the notebooks directory
run_options["volumes"][str(project)] = {
"bind": f"{LEAN_ROOT_PATH}/Notebooks",
"mode": "rw"
}

# Allow notebooks to be embedded in iframes
run_options["commands"].append("mkdir -p ~/.jupyter")
run_options["commands"].append(
Expand Down
40 changes: 40 additions & 0 deletions tests/commands/test_research.py
Original file line number Diff line number Diff line change
Expand Up @@ -280,3 +280,43 @@ def test_research_runs_lean_container_with_paths_to_mount() -> None:

assert mount is not None
assert mount["Target"] == "/Files/file.json"

def test_research_mounts_project_directory_to_leancli_and_notebooks() -> None:
create_fake_lean_cli_directory()

docker_manager = mock.MagicMock()
container.initialize(docker_manager)

project_dir = Path.cwd() / "CSharp Project"
(project_dir / "Main.cs").touch()
original_csproj = project_dir / "CSharp Project.csproj"
original_csproj.write_text("""
<Project>
<PropertyGroup></PropertyGroup>
<ItemGroup>
<PackageReference Include="QuantConnect.Lean.Engine" Version="2.5.*" />
</ItemGroup>
</Project>""")

result = CliRunner().invoke(lean, ["research", "CSharp Project"])

assert result.exit_code == 0

docker_manager.run_image.assert_called_once()
args, kwargs = docker_manager.run_image.call_args

leancli_volume = next(((k, v) for (k, v) in kwargs["volumes"].items() if v['bind'] == f"/LeanCLI"), None)
notebooks_mount = next((m for m in kwargs["mounts"] if m["Target"] == f"{LEAN_ROOT_PATH}/Notebooks"), None)

assert leancli_volume is not None, "/LeanCLI is not mounted"
assert notebooks_mount is not None, "/Notebooks is not mounted"
assert leancli_volume[0] == str(project_dir)
assert notebooks_mount["Source"] == str(project_dir)

temp_csproj_mounts = [
m for m in kwargs["mounts"]
if m["Target"].startswith(f"/LeanCLI") and m["Target"].endswith(".csproj")
]

assert len(temp_csproj_mounts) > 0, "No temporary csproj file mounts detected"
assert all(m["Source"] != str(original_csproj) for m in temp_csproj_mounts), "Temporary csproj did not correctly overwrite user file"

0 comments on commit 6c6fa92

Please sign in to comment.