Skip to content

Commit 2a0fdd6

Browse files
committed
test cases for opapluginfilter
Signed-off-by: Shriti Priya <[email protected]>
1 parent 18928e9 commit 2a0fdd6

File tree

2 files changed

+112
-6
lines changed

2 files changed

+112
-6
lines changed
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# -*- coding: utf-8 -*-
2+
"""Test cases for OPA plugin
3+
4+
Copyright 2025
5+
SPDX-License-Identifier: Apache-2.0
6+
Authors: Shriti Priya
7+
8+
This module mocks up an opa server for testing.
9+
"""
10+
11+
12+
# Standard
13+
import json
14+
import threading
15+
16+
# Third-Party
17+
from http.server import BaseHTTPRequestHandler, HTTPServer
18+
19+
20+
# This class mocks up the post request for OPA server to evaluate policies.
21+
class MockOPAHandler(BaseHTTPRequestHandler):
22+
def do_POST(self):
23+
if self.path == "/v1/data/example/allow":
24+
content_length = int(self.headers.get('Content-Length', 0))
25+
post_body = self.rfile.read(content_length).decode('utf-8')
26+
try:
27+
data = json.loads(post_body)
28+
if "IBM" in data["input"]["payload"]["args"]["repo_path"]:
29+
self.send_response(200)
30+
self.send_header("Content-Type", "application/json")
31+
self.end_headers()
32+
self.wfile.write(b'{"result": true}')
33+
else:
34+
self.send_response(200)
35+
self.send_header("Content-Type", "application/json")
36+
self.end_headers()
37+
self.wfile.write(b'{"result": false}')
38+
# Process data dictionary...
39+
except json.JSONDecodeError:
40+
# Handle invalid JSON
41+
self.send_response(400)
42+
self.end_headers()
43+
self.wfile.write(b"Invalid JSON")
44+
return
45+
46+
# This creates a mock up server for OPA at port 8181
47+
def run_mock_opa():
48+
server = HTTPServer(('localhost', 8181), MockOPAHandler)
49+
threading.Thread(target=server.serve_forever, daemon=True).start()
50+
return server
Lines changed: 62 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
# -*- coding: utf-8 -*-
2-
"""Tests for plugin."""
2+
"""Test cases for OPA plugin
3+
4+
Copyright 2025
5+
SPDX-License-Identifier: Apache-2.0
6+
Authors: Shriti Priya
7+
8+
This module contains test cases for running opa plugin.
9+
"""
10+
311

412
# Third-Party
513
import pytest
@@ -13,23 +21,71 @@
1321
GlobalContext
1422
)
1523

24+
from tests.server.opa_server import run_mock_opa
25+
1626

1727
@pytest.mark.asyncio
18-
async def test_opapluginfilter():
28+
# Test for when opaplugin is not applied to a tool
29+
async def test_benign_opapluginfilter():
1930
"""Test plugin prompt prefetch hook."""
2031
config = PluginConfig(
2132
name="test",
2233
kind="opapluginfilter.OPAPluginFilter",
2334
hooks=["tool_pre_invoke"],
24-
config={"setting_one": "test_value"},
35+
applied_to = {"tools" : [{"tool_name": "fast-time-git-status", "context": ["global.opa_policy_context.git_context"], "extensions": {"policy": "example", "policy_endpoint" : "allow"}}]},
36+
config={"opa_base_url": "http://127.0.0.1:8181/v1/data/"}
2537
)
38+
mock_server = run_mock_opa()
39+
2640

2741
plugin = OPAPluginFilter(config)
2842

2943
# Test your plugin logic
30-
payload = ToolPreInvokePayload(name="test_tool", args={"repo_path": "This is an argument"})
44+
payload = ToolPreInvokePayload(name="fast-time-git-status", args={"repo_path": "/path/IBM"})
3145
context = PluginContext(global_context=GlobalContext(request_id="1", server_id="2"))
3246
result = await plugin.tool_pre_invoke(payload, context)
33-
import pdb
34-
pdb.set_trace()
47+
mock_server.shutdown()
3548
assert result.continue_processing
49+
50+
51+
@pytest.mark.asyncio
52+
# Test for when opaplugin is not applied to a tool
53+
async def test_malign_opapluginfilter():
54+
"""Test plugin prompt prefetch hook."""
55+
config = PluginConfig(
56+
name="test",
57+
kind="opapluginfilter.OPAPluginFilter",
58+
hooks=["tool_pre_invoke"],
59+
applied_to = {"tools" : [{"tool_name": "fast-time-git-status", "context": ["global.opa_policy_context.git_context"], "extensions": {"policy": "example", "policy_endpoint" : "allow"}}]},
60+
config={"opa_base_url": "http://127.0.0.1:8181/v1/data/"}
61+
)
62+
mock_server = run_mock_opa()
63+
plugin = OPAPluginFilter(config)
64+
65+
# Test your plugin logic
66+
payload = ToolPreInvokePayload(name="fast-time-git-status", args={"repo_path": "/path/IM"})
67+
context = PluginContext(global_context=GlobalContext(request_id="1", server_id="2"))
68+
result = await plugin.tool_pre_invoke(payload, context)
69+
mock_server.shutdown()
70+
assert not result.continue_processing and result.violation.code == "deny"
71+
72+
@pytest.mark.asyncio
73+
# Test for opa plugin not applied to any of the tools
74+
async def test_applied_to_opaplugin():
75+
"""Test plugin prompt prefetch hook."""
76+
config = PluginConfig(
77+
name="test",
78+
kind="opapluginfilter.OPAPluginFilter",
79+
hooks=["tool_pre_invoke"],
80+
applied_to = {},
81+
config={"opa_base_url": "http://127.0.0.1:8181/v1/data/"}
82+
)
83+
mock_server = run_mock_opa()
84+
plugin = OPAPluginFilter(config)
85+
86+
# Test your plugin logic
87+
payload = ToolPreInvokePayload(name="fast-time-git-status", args={"repo_path": "/path/IM"})
88+
context = PluginContext(global_context=GlobalContext(request_id="1", server_id="2"))
89+
result = await plugin.tool_pre_invoke(payload, context)
90+
mock_server.shutdown()
91+
assert result.continue_processing

0 commit comments

Comments
 (0)