12
12
# See the License for the specific language governing permissions and
13
13
# limitations under the License.
14
14
15
- """End-to-end tests for the toolbox SDK interacting with the toolbox server.
16
-
17
- This file covers the following test cases:
18
-
19
- 1. Loading a tool.
20
- 2. Loading a specific toolset.
21
- 3. Loading the default toolset (contains all tools).
22
- 4. Running a tool with
23
- a. Missing params.
24
- b. Wrong param type.
25
- 5. Running a tool with no required auth, with auth provided.
26
- 6. Running a tool with required auth:
27
- a. No auth provided.
28
- b. Wrong auth provided: The tool requires a different authentication
29
- than the one provided.
30
- c. Correct auth provided.
31
- 7. Running a tool with a parameter that requires auth:
32
- a. No auth provided.
33
- b. Correct auth provided.
34
- c. Auth provided does not contain the required claim.
35
- """
36
15
import pytest
37
16
import pytest_asyncio
38
17
39
18
from toolbox_core .client import ToolboxClient
40
19
from toolbox_core .tool import ToolboxTool
41
20
21
+ # --- Shared Fixtures Defined at Module Level ---
22
+ @pytest_asyncio .fixture (scope = "function" )
23
+ async def toolbox ():
24
+ """Creates a ToolboxClient instance shared by all tests in this module."""
25
+ toolbox = ToolboxClient ("http://localhost:5000" )
26
+ try :
27
+ yield toolbox
28
+ finally :
29
+ await toolbox .close ()
30
+
31
+
32
+ @pytest_asyncio .fixture (scope = "function" )
33
+ async def get_n_rows_tool (toolbox : ToolboxClient ) -> ToolboxTool :
34
+ """Load the 'get-n-rows' tool using the shared toolbox client."""
35
+ tool = await toolbox .load_tool ("get-n-rows" )
36
+ assert tool .__name__ == "get-n-rows"
37
+ return tool
38
+
42
39
43
40
@pytest .mark .asyncio
44
41
@pytest .mark .usefixtures ("toolbox_server" )
45
- class TestE2EClient :
46
- @pytest_asyncio .fixture (scope = "function" )
47
- async def toolbox (self ):
48
- toolbox = ToolboxClient ("http://localhost:5000" )
49
- try :
50
- yield toolbox
51
- finally :
52
- await toolbox .close ()
53
-
54
- @pytest_asyncio .fixture (scope = "function" )
55
- async def get_n_rows_tool (self , toolbox : ToolboxClient ) -> ToolboxTool :
56
- tool = await toolbox .load_tool ("get-n-rows" )
57
- assert tool .__name__ == "get-n-rows"
58
- return tool
59
-
60
- #### Basic e2e tests
42
+ class TestBasicE2E :
61
43
@pytest .mark .parametrize (
62
44
"toolset_name, expected_length, expected_tools" ,
63
45
[
@@ -72,83 +54,105 @@ async def test_load_toolset_specific(
72
54
expected_length : int ,
73
55
expected_tools : list [str ],
74
56
):
57
+ """Load a specific toolset"""
75
58
toolset = await toolbox .load_toolset (toolset_name )
76
59
assert len (toolset ) == expected_length
77
60
tool_names = {tool .__name__ for tool in toolset }
78
61
assert tool_names == set (expected_tools )
79
62
80
63
async def test_run_tool (self , get_n_rows_tool : ToolboxTool ):
64
+ """Invoke a tool."""
81
65
response = await get_n_rows_tool (num_rows = "2" )
82
66
83
67
assert isinstance (response , str )
84
68
assert "row1" in response
85
69
assert "row2" in response
86
70
assert "row3" not in response
87
71
88
- async def test_run_tool_missing_params (self , get_n_rows_tool ):
72
+ async def test_run_tool_missing_params (self , get_n_rows_tool : ToolboxTool ):
73
+ """Invoke a tool with missing params."""
89
74
with pytest .raises (TypeError , match = "missing a required argument: 'num_rows'" ):
90
75
await get_n_rows_tool ()
91
76
92
77
async def test_run_tool_wrong_param_type (self , get_n_rows_tool : ToolboxTool ):
78
+ """Invoke a tool with wrong param type."""
93
79
with pytest .raises (
94
80
Exception ,
95
81
match = 'provided parameters were invalid: unable to parse value for "num_rows": .* not type "string"' ,
96
82
):
97
83
await get_n_rows_tool (num_rows = 2 )
98
84
99
- ##### Bind param tests
100
- async def test_bind_params (self , toolbox , get_n_rows_tool ):
101
- new_tool = get_n_rows_tool .bind_parameters ({"num_rows" : lambda : "3" })
85
+
86
+ @pytest .mark .asyncio
87
+ @pytest .mark .usefixtures ("toolbox_server" )
88
+ class TestBindParams :
89
+ async def test_bind_params (
90
+ self , toolbox : ToolboxClient , get_n_rows_tool : ToolboxTool
91
+ ):
92
+ """Bind a param to an existing tool."""
93
+ new_tool = get_n_rows_tool .bind_parameters ({"num_rows" : "3" })
102
94
response = await new_tool ()
95
+ assert isinstance (response , str )
96
+ assert "row1" in response
97
+ assert "row2" in response
98
+ assert "row3" in response
99
+ assert "row4" not in response
103
100
101
+ async def test_bind_params_callable (
102
+ self , toolbox : ToolboxClient , get_n_rows_tool : ToolboxTool
103
+ ):
104
+ """Bind a callable param to an existing tool."""
105
+ new_tool = get_n_rows_tool .bind_parameters ({"num_rows" : lambda : "3" })
106
+ response = await new_tool ()
104
107
assert isinstance (response , str )
105
108
assert "row1" in response
106
109
assert "row2" in response
107
110
assert "row3" in response
108
111
assert "row4" not in response
109
112
110
- ##### Auth tests
111
- async def test_run_tool_unauth_with_auth (self , toolbox , auth_token2 ):
113
+ @pytest .mark .asyncio
114
+ @pytest .mark .usefixtures ("toolbox_server" )
115
+ class TestAuth :
116
+ async def test_run_tool_unauth_with_auth (
117
+ self , toolbox : ToolboxClient , auth_token2 : str
118
+ ):
112
119
"""Tests running a tool that doesn't require auth, with auth provided."""
113
120
tool = await toolbox .load_tool (
114
121
"get-row-by-id" , auth_token_getters = {"my-test-auth" : lambda : auth_token2 }
115
122
)
116
123
response = await tool (id = "2" )
117
124
assert "row2" in response
118
125
119
- async def test_run_tool_no_auth (self , toolbox ):
126
+
127
+ async def test_run_tool_no_auth (self , toolbox : ToolboxClient ):
120
128
"""Tests running a tool requiring auth without providing auth."""
121
- tool = await toolbox .load_tool (
122
- "get-row-by-id-auth" ,
123
- )
129
+ tool = await toolbox .load_tool ("get-row-by-id-auth" )
124
130
with pytest .raises (
125
131
Exception ,
126
132
match = "tool invocation not authorized. Please make sure your specify correct auth headers" ,
127
133
):
128
134
await tool (id = "2" )
129
135
130
- async def test_run_tool_wrong_auth (self , toolbox , auth_token2 ):
131
- """Tests running a tool with incorrect auth."""
132
- tool = await toolbox .load_tool (
133
- "get-row-by-id-auth" ,
134
- )
136
+ async def test_run_tool_wrong_auth (self , toolbox : ToolboxClient , auth_token2 : str ):
137
+ """Tests running a tool with incorrect auth. The tool
138
+ requires a different authentication than the one provided."""
139
+ tool = await toolbox .load_tool ("get-row-by-id-auth" )
135
140
auth_tool = tool .add_auth_token_getters ({"my-test-auth" : lambda : auth_token2 })
136
141
with pytest .raises (
137
142
Exception ,
138
143
match = "tool invocation not authorized" ,
139
144
):
140
145
await auth_tool (id = "2" )
141
146
142
- async def test_run_tool_auth (self , toolbox , auth_token1 ):
147
+ async def test_run_tool_auth (self , toolbox : ToolboxClient , auth_token1 : str ):
143
148
"""Tests running a tool with correct auth."""
144
- tool = await toolbox .load_tool (
145
- "get-row-by-id-auth" ,
146
- )
149
+ tool = await toolbox .load_tool ("get-row-by-id-auth" )
147
150
auth_tool = tool .add_auth_token_getters ({"my-test-auth" : lambda : auth_token1 })
148
151
response = await auth_tool (id = "2" )
149
152
assert "row2" in response
150
153
151
- async def test_run_tool_param_auth_no_auth (self , toolbox ):
154
+
155
+ async def test_run_tool_param_auth_no_auth (self , toolbox : ToolboxClient ):
152
156
"""Tests running a tool with a param requiring auth, without auth."""
153
157
tool = await toolbox .load_tool ("get-row-by-email-auth" )
154
158
with pytest .raises (
@@ -157,7 +161,8 @@ async def test_run_tool_param_auth_no_auth(self, toolbox):
157
161
):
158
162
await tool ()
159
163
160
- async def test_run_tool_param_auth (self , toolbox , auth_token1 ):
164
+
165
+ async def test_run_tool_param_auth (self , toolbox : ToolboxClient , auth_token1 : str ):
161
166
"""Tests running a tool with a param requiring auth, with correct auth."""
162
167
tool = await toolbox .load_tool (
163
168
"get-row-by-email-auth" ,
@@ -168,7 +173,9 @@ async def test_run_tool_param_auth(self, toolbox, auth_token1):
168
173
assert "row5" in response
169
174
assert "row6" in response
170
175
171
- async def test_run_tool_param_auth_no_field (self , toolbox , auth_token1 ):
176
+ async def test_run_tool_param_auth_no_field (
177
+ self , toolbox : ToolboxClient , auth_token1 : str
178
+ ):
172
179
"""Tests running a tool with a param requiring auth, with insufficient auth."""
173
180
tool = await toolbox .load_tool (
174
181
"get-row-by-content-auth" ,
0 commit comments