Skip to content

Commit 8e5616e

Browse files
authored
Repair CI (#1547)
* Fix issue in agent_features with sticky app name * Fix imports in lanchain tests * Fix imports in botocore tests * Add additional hook path for langchain Chain * Re-enable tests disabled for cryptography * Re-enable tests disabled for httptools * Re-enable tests disabled for pydantic-core * Misc tox edits * Repair event loop policy with uvloop * Remove arbitrary pin * Remove PyPy tests for mcp * Remove pypy aiobotocore tests * Disable aiobotocore py314 tests again
1 parent 2b8ae93 commit 8e5616e

File tree

7 files changed

+74
-33
lines changed

7 files changed

+74
-33
lines changed

newrelic/config.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2097,6 +2097,9 @@ def _process_module_builtin_defaults():
20972097
_process_module_definition(
20982098
"langchain.chains.base", "newrelic.hooks.mlmodel_langchain", "instrument_langchain_chains_base"
20992099
)
2100+
_process_module_definition(
2101+
"langchain_classic.chains.base", "newrelic.hooks.mlmodel_langchain", "instrument_langchain_chains_base"
2102+
)
21002103
_process_module_definition(
21012104
"langchain_core.callbacks.manager", "newrelic.hooks.mlmodel_langchain", "instrument_langchain_callbacks_manager"
21022105
)

tests/agent_features/test_agent_control_health_check.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
14+
import copy
1415
import re
1516
import sys
1617
import threading
@@ -37,6 +38,20 @@ def get_health_file_contents(tmp_path):
3738
return contents
3839

3940

41+
@pytest.fixture(scope="module", autouse=True)
42+
def restore_settings_fixture():
43+
# Backup settings from before this test file runs
44+
original_settings = global_settings()
45+
backup = copy.deepcopy(original_settings.__dict__)
46+
47+
# Run tests
48+
yield
49+
50+
# Restore settings after tests run
51+
original_settings.__dict__.clear()
52+
original_settings.__dict__.update(backup)
53+
54+
4055
@pytest.mark.parametrize("file_uri", ["", "file://", "/test/dir", "foo:/test/dir"])
4156
def test_invalid_file_directory_supplied(monkeypatch, file_uri):
4257
# Setup expected env vars to run agent control health check
@@ -247,6 +262,7 @@ def test_max_app_name_status(monkeypatch, tmp_path):
247262
file_path = tmp_path.as_uri()
248263
monkeypatch.setenv("NEW_RELIC_AGENT_CONTROL_HEALTH_DELIVERY_LOCATION", file_path)
249264

265+
# Set app name to exceed maximum allowed configured names
250266
_reset_configuration_done()
251267
initialize_agent(app_name="test1;test2;test3;test4")
252268
# Give time for the scheduler to kick in and write to the health file
@@ -259,7 +275,3 @@ def test_max_app_name_status(monkeypatch, tmp_path):
259275
assert contents[0] == "healthy: False\n"
260276
assert contents[1] == "status: The maximum number of configured app names (3) exceeded\n"
261277
assert contents[4] == "last_error: NR-APM-006\n"
262-
263-
# Set app name back to original name specific
264-
settings = global_settings()
265-
settings.app_name = "Python Agent Test (agent_features)"

tests/coroutines_asyncio/test_context_propagation.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,18 @@
3535
try:
3636
import uvloop
3737

38-
loop_policies = (None, uvloop.EventLoopPolicy())
38+
loop_policies = (pytest.param(None, id="asyncio"), pytest.param(uvloop.EventLoopPolicy(), id="uvloop"))
3939
except ImportError:
40-
loop_policies = (None,)
40+
loop_policies = (pytest.param(None, id="asyncio"),)
41+
42+
43+
@pytest.fixture(autouse=True)
44+
def reset_event_loop():
45+
from asyncio import set_event_loop, set_event_loop_policy
46+
47+
# Remove the loop policy to avoid side effects
48+
set_event_loop_policy(None)
49+
set_event_loop(None)
4150

4251

4352
@function_trace("waiter3")
@@ -166,6 +175,7 @@ def test_two_transactions(event_loop, trace):
166175

167176
tasks = []
168177

178+
asyncio.set_event_loop(event_loop)
169179
ready = asyncio.Event()
170180
done = asyncio.Event()
171181

@@ -194,11 +204,11 @@ async def await_task():
194204
if sys.version_info >= (3, 10, 0):
195205
afut = asyncio.ensure_future(create_coro(), loop=event_loop)
196206
bfut = asyncio.ensure_future(await_task(), loop=event_loop)
197-
event_loop.run_until_complete(asyncio.gather(afut, bfut))
198207
else:
199208
afut = asyncio.ensure_future(create_coro())
200209
bfut = asyncio.ensure_future(await_task())
201-
asyncio.get_event_loop().run_until_complete(asyncio.gather(afut, bfut))
210+
211+
event_loop.run_until_complete(asyncio.gather(afut, bfut))
202212

203213

204214
# Sentinel left in cache transaction exited

tests/external_botocore/test_bedrock_chat_completion_via_langchain.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,14 @@ def response_streaming(request):
5757
def exercise_model(bedrock_server, model_id, response_streaming):
5858
try:
5959
# These are only available in certain botocore environments.
60-
from langchain.chains import ConversationChain
60+
from langchain_classic.chains import ConversationChain
6161
from langchain_community.chat_models import BedrockChat
6262
except ImportError:
63-
pytest.skip(reason="Langchain not installed.")
63+
try:
64+
from langchain.chains import ConversationChain
65+
from langchain_community.chat_models import BedrockChat
66+
except ImportError:
67+
pytest.skip(reason="Langchain not installed.")
6468

6569
def _exercise_model(prompt):
6670
bedrock_llm = BedrockChat(model_id=model_id, client=bedrock_server, streaming=response_streaming)

tests/mlmodel_langchain/test_agent.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,24 @@
1414

1515
import langchain
1616
import pytest
17-
from langchain.agents import AgentExecutor, create_openai_functions_agent
18-
from langchain.prompts import ChatPromptTemplate
1917
from langchain.tools import tool
2018
from langchain_core.prompts import MessagesPlaceholder
2119
from testing_support.fixtures import reset_core_stats_engine, validate_attributes
2220
from testing_support.validators.validate_transaction_metrics import validate_transaction_metrics
2321

2422
from newrelic.api.background_task import background_task
2523

24+
# Moved in langchain v1.0.1
25+
try:
26+
from langchain_classic.agents import AgentExecutor, create_openai_functions_agent
27+
except ImportError:
28+
from langchain.agents import AgentExecutor, create_openai_functions_agent
29+
30+
try:
31+
from langchain_core.prompts import ChatPromptTemplate
32+
except Exception:
33+
from langchain.prompts import ChatPromptTemplate
34+
2635

2736
@pytest.fixture
2837
def tools():

tests/mlmodel_langchain/test_chain.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@
2020
import langchain_core
2121
import openai
2222
import pytest
23-
from langchain.chains.combine_documents import create_stuff_documents_chain
24-
from langchain.chains.openai_functions import create_structured_output_chain, create_structured_output_runnable
2523
from langchain_community.vectorstores.faiss import FAISS
2624
from testing_support.fixtures import reset_core_stats_engine, validate_attributes
2725
from testing_support.ml_testing_utils import (
@@ -42,6 +40,20 @@
4240
from newrelic.api.transaction import add_custom_attribute
4341
from newrelic.common.object_names import callable_name
4442

43+
try:
44+
from langchain_classic.chains import create_retrieval_chain
45+
from langchain_classic.chains.combine_documents import create_stuff_documents_chain
46+
from langchain_classic.chains.openai_functions import (
47+
create_structured_output_chain,
48+
create_structured_output_runnable,
49+
)
50+
from langchain_core.output_parsers import BaseOutputParser
51+
except ImportError:
52+
from langchain.chains import create_retrieval_chain
53+
from langchain.chains.combine_documents import create_stuff_documents_chain
54+
from langchain.chains.openai_functions import create_structured_output_chain, create_structured_output_runnable
55+
from langchain.schema import BaseOutputParser
56+
4557
_test_openai_chat_completion_messages = (
4658
{"role": "system", "content": "You are a scientist."},
4759
{"role": "user", "content": "What is 212 degrees Fahrenheit converted to Celsius?"},
@@ -1678,7 +1690,7 @@ def test_retrieval_chains(set_trace_info, retrieval_chain_prompt, embedding_open
16781690
retriever = vectordb.as_retriever()
16791691
question_answer_chain = create_stuff_documents_chain(llm=chat_openai_client, prompt=retrieval_chain_prompt)
16801692

1681-
rag_chain = langchain.chains.create_retrieval_chain(retriever, question_answer_chain)
1693+
rag_chain = create_retrieval_chain(retriever, question_answer_chain)
16821694
response = rag_chain.invoke({"input": "math"})
16831695

16841696
assert response
@@ -1746,7 +1758,7 @@ def prompt_openai_error():
17461758

17471759
@pytest.fixture
17481760
def comma_separated_list_output_parser():
1749-
class _CommaSeparatedListOutputParser(langchain.schema.BaseOutputParser):
1761+
class _CommaSeparatedListOutputParser(BaseOutputParser):
17501762
"""Parse the output of an LLM call to a comma-separated list."""
17511763

17521764
def parse(self, text):

tox.ini

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -87,14 +87,12 @@ envlist =
8787
mongodb8-datastore_motor-{py38,py39,py310,py311,py312,py313,py314}-motorlatest,
8888
mongodb3-datastore_pymongo-{py38,py39,py310,py311,py312}-pymongo03,
8989
mongodb8-datastore_pymongo-{py38,py39,py310,py311,py312,py313,py314,pypy311}-pymongo04,
90-
; aiomysql tests on PyPy disabled for now due to issues building cryptography
91-
mysql-datastore_aiomysql-{py38,py39,py310,py311,py312,py313,py314},
90+
mysql-datastore_aiomysql-{py38,py39,py310,py311,py312,py313,py314,pypy311},
9291
mssql-datastore_pymssql-pymssqllatest-{py39,py310,py311,py312,py313,py314},
9392
mssql-datastore_pymssql-pymssql020301-py38,
9493
mysql-datastore_mysql-mysqllatest-{py38,py39,py310,py311,py312,py313,py314},
9594
mysql-datastore_mysqldb-{py38,py39,py310,py311,py312,py313,py314},
96-
; pymysql tests on PyPy disabled for now due to issues building cryptography
97-
mysql-datastore_pymysql-{py38,py39,py310,py311,py312,py313,py314},
95+
mysql-datastore_pymysql-{py38,py39,py310,py311,py312,py313,py314,pypy311},
9896
oracledb-datastore_oracledb-{py39,py310,py311,py312,py313,py314}-oracledblatest,
9997
oracledb-datastore_oracledb-{py39,py313,py314}-oracledb02,
10098
oracledb-datastore_oracledb-{py39,py312}-oracledb01,
@@ -116,7 +114,6 @@ envlist =
116114
; python-adapter_gunicorn-py314-aiohttp03-gunicornlatest,
117115
python-adapter_hypercorn-{py38,py39,py310,py311,py312,py313,py314}-hypercornlatest,
118116
python-adapter_hypercorn-py38-hypercorn{0010,0011,0012,0013},
119-
; mcp tests on PyPy disabled for now due to issues building cryptography
120117
python-adapter_mcp-{py310,py311,py312,py313,py314},
121118
python-adapter_uvicorn-{py38,py39,py310,py311,py312,py313,py314}-uvicornlatest,
122119
python-adapter_uvicorn-py38-uvicorn014,
@@ -132,7 +129,7 @@ envlist =
132129
python-coroutines_asyncio-{py38,py39,py310,py311,py312,py313,py314,pypy311},
133130
python-datastore_sqlite-{py38,py39,py310,py311,py312,py313,py314,pypy311},
134131
python-external_aiobotocore-{py38,py39,py310,py311,py312,py313}-aiobotocorelatest,
135-
;; Package not ready for Python 3.14 or PyPy 3.11 (httptools fails to compile)
132+
;; Package not ready for Python 3.14 (hangs when running)
136133
; python-external_aiobotocore-py314-aiobotocorelatest,
137134
python-external_botocore-{py38,py39,py310,py311,py312,py313,py314}-botocorelatest,
138135
python-external_botocore-{py311}-botocorelatest-langchain,
@@ -143,7 +140,7 @@ envlist =
143140
python-external_httplib-{py38,py39,py310,py311,py312,py313,py314,pypy311},
144141
python-external_httplib2-{py38,py39,py310,py311,py312,py313,py314,pypy311},
145142
# pyzeebe requires grpcio which does not support pypy
146-
python-external_pyzeebe-{py39,py310,py311,py312},
143+
python-external_pyzeebe-{py39,py310,py311,py312,py313,py314},
147144
python-external_requests-{py38,py39,py310,py311,py312,py313,py314,pypy311},
148145
python-external_urllib3-{py38,py39,py310,py311,py312,py313,py314,pypy311}-urllib3latest,
149146
python-external_urllib3-{py312,py313,py314,pypy311}-urllib30126,
@@ -170,9 +167,7 @@ envlist =
170167
python-framework_pyramid-{py38,py39,py310,py311,py312,py313,py314,pypy311}-Pyramidlatest,
171168
python-framework_pyramid-{py38,py39,py310,py311,py312,py313,py314,pypy311}-cornicelatest,
172169
python-framework_sanic-py38-sanic2406,
173-
python-framework_sanic-{py39,py310,py311,py312,py313}-saniclatest,
174-
;; Package not ready for Python 3.14 or PyPy 3.11 (httptools fails to compile)
175-
; python-framework_sanic-{py314,pypy311}-saniclatest,
170+
python-framework_sanic-{py39,py310,py311,py312,py313,py314,pypy311}-saniclatest,
176171
python-framework_sanic-py38-sanic2290,
177172
python-framework_starlette-{py310,pypy311}-starlette{0014,0015,0019,0028},
178173
python-framework_starlette-{py38,py39,py310,py311,py312,py313,py314,pypy311}-starlettelatest,
@@ -184,14 +179,11 @@ envlist =
184179
python-logger_logging-{py38,py39,py310,py311,py312,py313,py314,pypy311},
185180
python-logger_loguru-{py38,py39,py310,py311,py312,py313,py314,pypy311}-logurulatest,
186181
python-logger_structlog-{py38,py39,py310,py311,py312,py313,py314,pypy311}-structloglatest,
187-
python-mlmodel_autogen-{py310,py311,py312,py313,py314}-autogen061,
188-
python-mlmodel_autogen-{py310,py311,py312,py313,py314}-autogenlatest,
189-
;; Package not ready for PyPy 3.11 (pydantic-core not updated)
190-
; python-mlmodel_autogen-pypy311-autogen061,
191-
; python-mlmodel_autogen-pypy311-autogenlatest,
182+
python-mlmodel_autogen-{py310,py311,py312,py313,py314,pypy311}-autogen061,
183+
python-mlmodel_autogen-{py310,py311,py312,py313,py314,pypy311}-autogenlatest,
192184
python-mlmodel_gemini-{py39,py310,py311,py312,py313,py314},
193185
python-mlmodel_langchain-{py39,py310,py311,py312,py313},
194-
;; Package not ready for Python 3.14 (pydantic not updated)
186+
;; Package not ready for Python 3.14 (type annotations not updated)
195187
; python-mlmodel_langchain-py314,
196188
python-mlmodel_openai-openai0-{py38,py39,py310,py311,py312},
197189
python-mlmodel_openai-openai107-py312,
@@ -236,7 +228,6 @@ deps =
236228
adapter_gevent: gevent
237229
adapter_gevent: urllib3
238230
adapter_gunicorn-aiohttp03: aiohttp<4.0
239-
adapter_gunicorn-aiohttp03-py312: aiohttp==3.9.0rc0
240231
adapter_gunicorn-gunicorn19: gunicorn<20
241232
adapter_gunicorn-gunicornlatest: gunicorn
242233
adapter_hypercorn-hypercornlatest: hypercorn[h3]

0 commit comments

Comments
 (0)