Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,9 @@ jobs:
python-version: ${{ matrix.python }}
allow-prereleases: true

- name: Install uv
uses: astral-sh/setup-uv@v7
- uses: astral-sh/setup-uv@v7
with:
version: "0.9.10"
version: "0.9.18"

- name: Run tests
run: uv run --extra solrcloud -- python run-tests.py
run: uv run --extra=solrcloud --with=pytest -- python run-tests.py
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ repos:
- tomli

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.14.7
rev: v0.14.9
hooks:
- id: ruff-check
args: [ --fix ]
Expand All @@ -53,6 +53,6 @@ repos:
- id: validate-pyproject

- repo: https://github.com/astral-sh/uv-pre-commit
rev: 0.9.14
rev: 0.9.18
hooks:
- id: uv-lock
5 changes: 3 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ urls.Homepage = "https://github.com/django-haystack/pysolr/"
dev = [
"coverage",
"pre-commit>=4.4",
"pytest",
]

[tool.hatch.build.targets.sdist]
Expand Down Expand Up @@ -100,8 +101,6 @@ lint.ignore = [
"PGH004",
"PLR5501",
"PLW2901",
"PT009",
"PT027",
"PTH123",
"RET505",
"RET506",
Expand All @@ -115,6 +114,8 @@ lint.per-file-ignores."tests/*" = [
]
lint.mccabe.max-complexity = 16
lint.pylint.allow-magic-value-types = [
"bytes",
"float",
"int",
"str",
]
Expand Down
6 changes: 6 additions & 0 deletions run-tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import subprocess
import unittest
from pathlib import Path


def main():
Expand All @@ -10,6 +11,11 @@ def main():
subprocess.run(["./solr-docker-test-env.sh", "setup"], check=True)

print("→ Running unit test suite...")
old_path = Path("tests/__init__.py")
new_path = old_path.with_name("z__init__.py")
old_path.rename(new_path) # rename tests/__init__.py to avoid duplicate tests
subprocess.run(["pytest"], check=True) # noqa: S607
new_path.rename(old_path)
unittest.main(module="tests", verbosity=1)

finally:
Expand Down
61 changes: 31 additions & 30 deletions tests/test_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
import json
import unittest

import pytest

from pysolr import SolrCoreAdmin, SolrError


Expand Down Expand Up @@ -49,28 +51,28 @@ def test_status(self):
raw_all = self.solr_admin.status()
all_data = json.loads(raw_all)

self.assertIn("core0", all_data["status"])
assert "core0" in all_data["status"]

# Status of a specific core
raw_single = self.solr_admin.status(core="core0")
single_data = json.loads(raw_single)

self.assertEqual(single_data["status"]["core0"]["name"], "core0")
assert single_data["status"]["core0"]["name"] == "core0"

def test_create(self):
"""Test creating a core returns a successful response."""
raw_response = self.solr_admin.create("demo_core1")
data = json.loads(raw_response)

self.assertEqual(data["responseHeader"]["status"], 0)
self.assertEqual(data["core"], "demo_core1")
assert data["responseHeader"]["status"] == 0
assert data["core"] == "demo_core1"

def test_reload(self):
"""Test reloading a core returns a successful response."""
raw_response = self.solr_admin.reload("core0")
data = json.loads(raw_response)

self.assertEqual(data["responseHeader"]["status"], 0)
assert data["responseHeader"]["status"] == 0

def test_rename(self):
"""Test renaming a core succeeds and the new name appears in the status."""
Expand All @@ -82,13 +84,13 @@ def test_rename(self):
raw_response = self.solr_admin.rename("demo_core1", "demo_core2")
data = json.loads(raw_response)

self.assertEqual(data["responseHeader"]["status"], 0)
assert data["responseHeader"]["status"] == 0

# Verify that the renamed core appears in the status response
raw_response2 = self.solr_admin.status(core="demo_core2")
data2 = json.loads(raw_response2)

self.assertEqual(data2["status"]["demo_core2"]["name"], "demo_core2")
assert data2["status"]["demo_core2"]["name"] == "demo_core2"

def test_swap(self):
"""
Expand All @@ -110,7 +112,7 @@ def test_swap(self):
raw_swap = self.solr_admin.swap("demo_core1", "demo_core2")
swap_data = json.loads(raw_swap)

self.assertEqual(swap_data["responseHeader"]["status"], 0)
assert swap_data["responseHeader"]["status"] == 0

def test_unload(self):
"""
Expand All @@ -124,18 +126,19 @@ def test_unload(self):
raw_response = self.solr_admin.unload("demo_core1")
data = json.loads(raw_response)

self.assertEqual(data["responseHeader"]["status"], 0)
assert data["responseHeader"]["status"] == 0

def test_load(self):
self.assertRaises(NotImplementedError, self.solr_admin.load, "wheatley")
with pytest.raises(NotImplementedError):
self.solr_admin.load("wheatley")

def test_status__nonexistent_core_returns_empty_response(self):
"""Test that requesting status for a missing core returns an empty response."""
raw_response = self.solr_admin.status(core="not_exists")
data = json.loads(raw_response)

self.assertNotIn("name", data["status"]["not_exists"])
self.assertNotIn("instanceDir", data["status"]["not_exists"])
assert "name" not in data["status"]["not_exists"]
assert "instanceDir" not in data["status"]["not_exists"]

def test_create__existing_core_raises_error(self):
"""Test creating a core that already exists returns a 500 error."""
Expand All @@ -147,20 +150,18 @@ def test_create__existing_core_raises_error(self):
raw_response = self.solr_admin.create("demo_core1")
data = json.loads(raw_response)

self.assertEqual(data["responseHeader"]["status"], 500)
self.assertEqual(
data["error"]["msg"], "Core with name 'demo_core1' already exists."
)
assert data["responseHeader"]["status"] == 500
assert data["error"]["msg"] == "Core with name 'demo_core1' already exists."

def test_reload__nonexistent_core_raises_error(self):
"""Test that reloading a non-existent core returns a 400 error."""
raw_response = self.solr_admin.reload("not_exists")
data = json.loads(raw_response)

# Solr returns a 400 error for missing cores
self.assertEqual(data["responseHeader"]["status"], 400)
self.assertIn("No such core", data["error"]["msg"])
self.assertIn("not_exists", data["error"]["msg"])
assert data["responseHeader"]["status"] == 400
assert "No such core" in data["error"]["msg"]
assert "not_exists" in data["error"]["msg"]

def test_rename__nonexistent_core_no_effect(self):
"""
Expand All @@ -179,8 +180,8 @@ def test_rename__nonexistent_core_no_effect(self):
data = json.loads(raw_response)

# The target core should not exist because the rename operation was ignored
self.assertNotIn("name", data["status"]["demo_core99"])
self.assertNotIn("instanceDir", data["status"]["demo_core99"])
assert "name" not in data["status"]["demo_core99"]
assert "instanceDir" not in data["status"]["demo_core99"]

def test_swap__missing_source_core_returns_error(self):
"""Test swapping when the source core is missing returns a 400 error."""
Expand All @@ -193,9 +194,9 @@ def test_swap__missing_source_core_returns_error(self):
data = json.loads(raw_response)

# Solr returns a 400 error when the source core does not exist
self.assertEqual(data["responseHeader"]["status"], 400)
self.assertIn("No such core", data["error"]["msg"])
self.assertIn("not_exists", data["error"]["msg"])
assert data["responseHeader"]["status"] == 400
assert "No such core" in data["error"]["msg"]
assert "not_exists" in data["error"]["msg"]

def test_swap__missing_target_core_returns_error(self):
"""Test swapping when the target core is missing returns a 400 error."""
Expand All @@ -208,9 +209,9 @@ def test_swap__missing_target_core_returns_error(self):
data = json.loads(raw_response)

# Solr returns a 400 error when the target core does not exist
self.assertEqual(data["responseHeader"]["status"], 400)
self.assertIn("No such core", data["error"]["msg"])
self.assertIn("not_exists", data["error"]["msg"])
assert data["responseHeader"]["status"] == 400
assert "No such core" in data["error"]["msg"]
assert "not_exists" in data["error"]["msg"]

def test_unload__nonexistent_core_returns_error(self):
"""Test unloading a non-existent core returns a 400 error response."""
Expand All @@ -220,6 +221,6 @@ def test_unload__nonexistent_core_returns_error(self):
data = json.loads(raw_response)

# Solr returns a 400 error for unloading a missing core
self.assertEqual(data["responseHeader"]["status"], 400)
self.assertIn("Cannot unload non-existent core", data["error"]["msg"])
self.assertIn("not_exists", data["error"]["msg"])
assert data["responseHeader"]["status"] == 400
assert "Cannot unload non-existent core" in data["error"]["msg"]
assert "not_exists" in data["error"]["msg"]
Loading