Lokasi ngalangkungan proxy:   [ UP ]  
[Ngawartoskeun bug]   [Panyetelan cookie]                
Skip to content

Commit 3439c9d

Browse files
authored
feat(ci): run tests against multiple versions (#51)
* feat(ci): run tests against multiple versions * add uuid to test * fix and lint * fix table name * fix type * Update DEVELOPER.md * Update DEVELOPER.md
1 parent bc45740 commit 3439c9d

5 files changed

Lines changed: 119 additions & 22 deletions

File tree

.github/sync-repo-settings.yaml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,11 @@ branchProtectionRules:
2727
requiredStatusCheckContexts:
2828
- "cla/google"
2929
- "lint"
30-
- "mysql-integration-test-pr (langchain-cloud-sql-testing)"
30+
- "mysql-integration-test-pr-py38 (langchain-cloud-sql-testing)"
31+
- "mysql-integration-test-pr-py39 (langchain-cloud-sql-testing)"
32+
- "mysql-integration-test-pr-py310 (langchain-cloud-sql-testing)"
33+
- "mysql-integration-test-pr-py311 (langchain-cloud-sql-testing)"
34+
- "mysql-integration-test-pr-py312 (langchain-cloud-sql-testing)"
3135
- "conventionalcommits.org"
3236
- "header-check"
3337
# - Add required status checks like presubmit tests

DEVELOPER.md

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# DEVELOPER.md
2+
3+
## Versioning
4+
5+
This library follows [Semantic Versioning](http://semver.org/).
6+
7+
## Processes
8+
9+
### Conventional Commit messages
10+
11+
This repository uses tool [Release Please](https://github.com/googleapis/release-please) to create GitHub and PyPi releases. It does so by parsing your
12+
git history, looking for [Conventional Commit messages](https://www.conventionalcommits.org/),
13+
and creating release PRs.
14+
15+
Learn more by reading [How should I write my commits?](https://github.com/googleapis/release-please?tab=readme-ov-file#how-should-i-write-my-commits)
16+
17+
## Testing
18+
19+
### Run tests locally
20+
21+
1. Set environment variables for `INSTANCE_ID`, `DB_NAME`, `TABLE_NAME`, `REGION`, `DB_USER`, `DB_PASSWORD`
22+
23+
1. Run pytest to automatically run all tests:
24+
25+
```bash
26+
pytest
27+
```
28+
29+
### CI Platform Setup
30+
31+
Cloud Build is used to run tests against Google Cloud resources in test project: langchain-cloud-sql-testing.
32+
Each test has a corresponding Cloud Build trigger, see [all triggers][triggers].
33+
These tests are registered as required tests in `.github/sync-repo-settings.yaml`.
34+
35+
#### Trigger Setup
36+
37+
Cloud Build triggers (for Python versions 3.8 to 3.11) were created with the following specs:
38+
39+
```YAML
40+
name: mysql-integration-test-pr-py38
41+
description: Run integration tests on PR for Python 3.8
42+
filename: integration.cloudbuild.yaml
43+
github:
44+
name: langchain-google-cloud-sql-mysql-python
45+
owner: googleapis
46+
pullRequest:
47+
branch: .*
48+
commentControl: COMMENTS_ENABLED_FOR_EXTERNAL_CONTRIBUTORS_ONLY
49+
ignoredFiles:
50+
- docs/**
51+
- .kokoro/**
52+
- .github/**
53+
- "*.md"
54+
substitutions:
55+
_INSTANCE_ID: <ADD_VALUE>
56+
_DB_NAME: <ADD_VALUE>
57+
_REGION: us-central1
58+
_VERSION: "3.8"
59+
```
60+
61+
Use `gcloud builds triggers import --source=trigger.yaml` create triggers via the command line
62+
63+
#### Project Setup
64+
65+
1. Create an Cloud SQL for PostgreSQL instance and database
66+
1. Setup Cloud Build triggers (above)
67+
68+
#### Run tests with Cloud Build
69+
70+
* Run integration test:
71+
72+
```bash
73+
gcloud builds submit --config integration.cloudbuild.yaml --region us-central1 --substitutions=_INSTANCE_ID=$INSTANCE_ID,_DB_NAME=$DB_NAME,_REGION=$REGION
74+
```
75+
76+
#### Trigger
77+
78+
To run Cloud Build tests on GitHub from external contributors, ie RenovateBot, comment: `/gcbrun`.
79+
80+
81+
[triggers]: https://console.cloud.google.com/cloud-build/triggers?e=13802955&project=langchain-cloud-sql-testing

integration.cloudbuild.yaml

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,35 +14,39 @@
1414

1515
steps:
1616
- id: Install dependencies
17-
name: python:3.11
17+
name: python:${_VERSION}
1818
entrypoint: pip
1919
args: ["install", "--user", "-r", "requirements.txt"]
2020

2121
- id: Install module (and test requirements)
22-
name: python:3.11
22+
name: python:${_VERSION}
2323
entrypoint: pip
2424
args: ["install", ".[test]", "--user"]
2525

2626
- id: Run integration tests
27-
name: python:3.11
27+
name: python:${_VERSION}
2828
entrypoint: python
2929
args: ["-m", "pytest"]
3030
env:
31-
- 'PROJECT_ID=$PROJECT_ID'
32-
- 'INSTANCE_ID=$_INSTANCE_ID'
33-
- 'DB_NAME=$_DB_NAME'
34-
- 'TABLE_NAME=test-$BUILD_ID'
35-
- 'REGION=$_REGION'
36-
secretEnv: ['DB_USER', 'DB_PASSWORD']
31+
- "PROJECT_ID=$PROJECT_ID"
32+
- "INSTANCE_ID=$_INSTANCE_ID"
33+
- "DB_NAME=$_DB_NAME"
34+
- "TABLE_NAME=test-$BUILD_ID"
35+
- "REGION=$_REGION"
36+
secretEnv: ["DB_USER", "DB_PASSWORD"]
3737

3838
availableSecrets:
3939
secretManager:
40-
- versionName: projects/$PROJECT_ID/secrets/langchain-test-mysql-username/versions/1
41-
env: 'DB_USER'
42-
- versionName: projects/$PROJECT_ID/secrets/langchain-test-mysql-password/versions/1
43-
env: 'DB_PASSWORD'
40+
- versionName: projects/$PROJECT_ID/secrets/langchain-test-mysql-username/versions/1
41+
env: "DB_USER"
42+
- versionName: projects/$PROJECT_ID/secrets/langchain-test-mysql-password/versions/1
43+
env: "DB_PASSWORD"
4444

4545
substitutions:
4646
_INSTANCE_ID: test-instance
4747
_REGION: us-central1
4848
_DB_NAME: test
49+
_VERSION: "3.8"
50+
51+
options:
52+
dynamicSubstitutions: true

src/langchain_google_cloud_sql_mysql/loader.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414
import json
15-
from collections.abc import Iterable
16-
from typing import Any, Dict, Iterator, List, Optional, Sequence, cast
15+
from typing import Any, Dict, Iterable, Iterator, List, Optional, cast
1716

1817
import pymysql
1918
import sqlalchemy

tests/integration/test_mysql_chat_message_history.py

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414
import os
15+
import uuid
1516
from typing import Generator
1617

1718
import pytest
@@ -25,17 +26,21 @@
2526
region = os.environ["REGION"]
2627
instance_id = os.environ["INSTANCE_ID"]
2728
db_name = os.environ["DB_NAME"]
28-
table_name = "message_store"
29+
table_name = "message_store" + str(uuid.uuid4())
30+
malformed_table = "malformed_table" + str(uuid.uuid4())
2931

3032

3133
@pytest.fixture(name="memory_engine")
3234
def setup() -> Generator:
3335
engine = MySQLEngine.from_instance(
34-
project_id=project_id, region=region, instance=instance_id, database=db_name
36+
project_id=project_id,
37+
region=region,
38+
instance=instance_id,
39+
database=db_name,
3540
)
3641

3742
# create table with malformed schema (missing 'type')
38-
query = """CREATE TABLE malformed_table (
43+
query = f"""CREATE TABLE `{malformed_table}` (
3944
id INT AUTO_INCREMENT PRIMARY KEY,
4045
session_id TEXT NOT NULL,
4146
data JSON NOT NULL
@@ -47,7 +52,7 @@ def setup() -> Generator:
4752
# use default table for MySQLChatMessageHistory
4853
with engine.connect() as conn:
4954
conn.execute(sqlalchemy.text(f"DROP TABLE IF EXISTS `{table_name}`"))
50-
conn.execute(sqlalchemy.text(f"DROP TABLE IF EXISTS malformed_table"))
55+
conn.execute(sqlalchemy.text(f"DROP TABLE IF EXISTS `{malformed_table}`"))
5156
conn.commit()
5257

5358

@@ -71,7 +76,9 @@ def test_chat_message_history(memory_engine: MySQLEngine) -> None:
7176
assert len(history.messages) == 0
7277

7378

74-
def test_chat_message_history_table_does_not_exist(memory_engine: MySQLEngine) -> None:
79+
def test_chat_message_history_table_does_not_exist(
80+
memory_engine: MySQLEngine,
81+
) -> None:
7582
"""Test that MySQLChatMessageHistory fails if table does not exist."""
7683
with pytest.raises(AttributeError) as exc_info:
7784
MySQLChatMessageHistory(
@@ -90,5 +97,7 @@ def test_chat_message_history_table_malformed_schema(
9097
"""Test that MySQLChatMessageHistory fails if schema is malformed."""
9198
with pytest.raises(IndexError):
9299
MySQLChatMessageHistory(
93-
engine=memory_engine, session_id="test", table_name="malformed_table"
100+
engine=memory_engine,
101+
session_id="test",
102+
table_name=malformed_table,
94103
)

0 commit comments

Comments
 (0)