Skip to content

Conversation

@codeflash-ai
Copy link

@codeflash-ai codeflash-ai bot commented Nov 7, 2025

📄 19% (0.19x) speedup for JiraDataSource.set_comment_property in backend/python/app/sources/external/jira/jira.py

⏱️ Runtime : 5.60 milliseconds 4.70 milliseconds (best of 37 runs)

📝 Explanation and details

Optimizations Applied:

  • app/sources/external/jira/jira.py:

    • Utilized async context management for the client's execute method to ensure proper connection/resource cleanup when executing requests.
    • No blocking operations were present; existing async flow is properly maintained.
    • Minor optimization: Used a local variable for _client within set_comment_property to avoid repeated attribute lookups.
  • app/sources/client/http/http_client.py:

    • Batching multiple request header manipulations to avoid unnecessary intermediate objects.
    • Ensured async client creation is performed only once per event loop (no repeated unnecessary creations).
    • No blocking operations detected; I/O is already async via HTTPX.
    • No major concurrency batching possible as the code is request-per-request; optimizations related to concurrent execution are to be handled at callsite if needed.

Correctness verification report:

Test Status
⚙️ Existing Unit Tests 🔘 None Found
🌀 Generated Regression Tests 1091 Passed
⏪ Replay Tests 🔘 None Found
🔎 Concolic Coverage Tests 🔘 None Found
📊 Tests Coverage 91.7%
🌀 Generated Regression Tests and Runtime
import asyncio  # used to run async functions

import pytest  # used for our unit tests
from app.sources.external.jira.jira import JiraDataSource


# ---- Minimal stubs for required classes ----
class HTTPResponse:
    """Stub for HTTPResponse used in tests."""
    def __init__(self, status_code=200, content=None, headers=None):
        self.status_code = status_code
        self.content = content
        self.headers = headers or {}

class HTTPRequest:
    """Stub for HTTPRequest used in tests."""
    def __init__(self, method, url, headers, path_params, query_params, body):
        self.method = method
        self.url = url
        self.headers = headers
        self.path_params = path_params
        self.query_params = query_params
        self.body = body

# ---- Minimal JiraClient stub for dependency injection ----
class DummyClient:
    """Stub for the HTTP client used by JiraDataSource."""
    def __init__(self, base_url="https://dummy.atlassian.net"):
        self._base_url = base_url
        self.last_request = None
        self.should_raise = False
        self.response = HTTPResponse(status_code=200, content="OK")

    def get_base_url(self):
        return self._base_url

    async def execute(self, req):
        if self.should_raise:
            raise RuntimeError("Simulated client error")
        self.last_request = req
        # Return the pre-set response
        return self.response

class JiraClient:
    """Stub for JiraClient builder."""
    def __init__(self, client):
        self.client = client

    def get_client(self):
        return self.client
from app.sources.external.jira.jira import JiraDataSource

# ---- UNIT TESTS ----

# 1. Basic Test Cases

@pytest.mark.asyncio
async def test_set_comment_property_basic_success():
    """Test basic successful property setting."""
    dummy_client = DummyClient()
    jira_client = JiraClient(dummy_client)
    ds = JiraDataSource(jira_client)
    # Await the async function and check response type and status
    resp = await ds.set_comment_property("123", "myKey", body={"foo": "bar"})

@pytest.mark.asyncio
async def test_set_comment_property_default_headers():
    """Test that Content-Type header is set by default if not provided."""
    dummy_client = DummyClient()
    jira_client = JiraClient(dummy_client)
    ds = JiraDataSource(jira_client)
    # Call without headers
    resp = await ds.set_comment_property("456", "anotherKey", body={"baz": "qux"})

@pytest.mark.asyncio
async def test_set_comment_property_custom_headers_override():
    """Test that custom headers override default Content-Type."""
    dummy_client = DummyClient()
    jira_client = JiraClient(dummy_client)
    ds = JiraDataSource(jira_client)
    # Provide custom Content-Type
    resp = await ds.set_comment_property("789", "customKey", body={}, headers={"Content-Type": "application/x-custom"})

@pytest.mark.asyncio
async def test_set_comment_property_none_body():
    """Test the function with body=None."""
    dummy_client = DummyClient()
    jira_client = JiraClient(dummy_client)
    ds = JiraDataSource(jira_client)
    resp = await ds.set_comment_property("abc", "key", body=None)

# 2. Edge Test Cases

@pytest.mark.asyncio
async def test_set_comment_property_empty_strings():
    """Test with empty strings for commentId and propertyKey."""
    dummy_client = DummyClient()
    jira_client = JiraClient(dummy_client)
    ds = JiraDataSource(jira_client)
    resp = await ds.set_comment_property("", "", body={})

@pytest.mark.asyncio
async def test_set_comment_property_special_characters():
    """Test with special characters in commentId and propertyKey."""
    dummy_client = DummyClient()
    jira_client = JiraClient(dummy_client)
    ds = JiraDataSource(jira_client)
    special_id = "id/with/slash?and=equals"
    special_key = "key@!$"
    resp = await ds.set_comment_property(special_id, special_key, body={"x": 1})

@pytest.mark.asyncio
async def test_set_comment_property_none_client_raises():
    """Test that ValueError is raised if client is None."""
    class BadJiraClient:
        def get_client(self):
            return None
    with pytest.raises(ValueError, match="HTTP client is not initialized"):
        JiraDataSource(BadJiraClient())

@pytest.mark.asyncio
async def test_set_comment_property_missing_base_url_method_raises():
    """Test that ValueError is raised if client lacks get_base_url."""
    class NoBaseUrlClient:
        pass
    class NoBaseUrlJiraClient:
        def get_client(self):
            return NoBaseUrlClient()
    with pytest.raises(ValueError, match="HTTP client does not have get_base_url method"):
        JiraDataSource(NoBaseUrlJiraClient())

@pytest.mark.asyncio
async def test_set_comment_property_client_execute_raises():
    """Test that exceptions from client.execute are propagated."""
    dummy_client = DummyClient()
    dummy_client.should_raise = True
    jira_client = JiraClient(dummy_client)
    ds = JiraDataSource(jira_client)
    with pytest.raises(RuntimeError, match="Simulated client error"):
        await ds.set_comment_property("cid", "pkey", body={"a": 1})

@pytest.mark.asyncio
async def test_set_comment_property_concurrent_execution():
    """Test concurrent execution of set_comment_property."""
    dummy_client = DummyClient()
    jira_client = JiraClient(dummy_client)
    ds = JiraDataSource(jira_client)
    # Run several concurrent calls with different keys
    tasks = [
        ds.set_comment_property(str(i), f"key{i}", body={"v": i})
        for i in range(5)
    ]
    results = await asyncio.gather(*tasks)
    for resp in results:
        pass

# 3. Large Scale Test Cases

@pytest.mark.asyncio
async def test_set_comment_property_large_scale_concurrent():
    """Test large scale concurrent execution (50 calls)."""
    dummy_client = DummyClient()
    jira_client = JiraClient(dummy_client)
    ds = JiraDataSource(jira_client)
    num_calls = 50
    tasks = [
        ds.set_comment_property(f"cid{i}", f"pkey{i}", body={"i": i})
        for i in range(num_calls)
    ]
    results = await asyncio.gather(*tasks)
    for resp in results:
        pass

@pytest.mark.asyncio
async def test_set_comment_property_large_body():
    """Test with a large body dictionary."""
    dummy_client = DummyClient()
    jira_client = JiraClient(dummy_client)
    ds = JiraDataSource(jira_client)
    large_body = {str(i): i for i in range(500)}
    resp = await ds.set_comment_property("large", "body", body=large_body)

# 4. Throughput Test Cases

@pytest.mark.asyncio
async def test_set_comment_property_throughput_small_load():
    """Throughput test: small load (10 calls)."""
    dummy_client = DummyClient()
    jira_client = JiraClient(dummy_client)
    ds = JiraDataSource(jira_client)
    tasks = [
        ds.set_comment_property(f"c{i}", f"k{i}", body={"i": i})
        for i in range(10)
    ]
    results = await asyncio.gather(*tasks)
    for resp in results:
        pass

@pytest.mark.asyncio
async def test_set_comment_property_throughput_medium_load():
    """Throughput test: medium load (100 calls)."""
    dummy_client = DummyClient()
    jira_client = JiraClient(dummy_client)
    ds = JiraDataSource(jira_client)
    tasks = [
        ds.set_comment_property(f"c{i}", f"k{i}", body={"i": i})
        for i in range(100)
    ]
    results = await asyncio.gather(*tasks)
    for resp in results:
        pass

@pytest.mark.asyncio
async def test_set_comment_property_throughput_large_load():
    """Throughput test: large load (500 calls)."""
    dummy_client = DummyClient()
    jira_client = JiraClient(dummy_client)
    ds = JiraDataSource(jira_client)
    tasks = [
        ds.set_comment_property(f"c{i}", f"k{i}", body={"i": i})
        for i in range(500)
    ]
    results = await asyncio.gather(*tasks)
    for resp in results:
        pass
# codeflash_output is used to check that the output of the original code is the same as that of the optimized code.
#------------------------------------------------
import asyncio
from typing import Any, Dict, Optional

import pytest
from app.sources.external.jira.jira import JiraDataSource

# ---- Minimal stubs for HTTPRequest/HTTPResponse and helpers ----

class HTTPRequest:
    def __init__(self, method, url, headers, path_params, query_params, body):
        self.method = method
        self.url = url
        self.headers = headers
        self.path_params = path_params
        self.query_params = query_params
        self.body = body

class HTTPResponse:
    def __init__(self, data):
        self.data = data

# ---- Minimal stub for JiraClient and its client ----

class DummyClient:
    def __init__(self, base_url='http://dummy-url.com'):
        self._base_url = base_url
        self.executed_requests = []

    def get_base_url(self):
        return self._base_url

    async def execute(self, request: HTTPRequest):
        # Simulate a successful HTTP PUT with echo of input
        self.executed_requests.append(request)
        # For edge case: simulate error for certain commentId
        if request.path_params.get('commentId') == 'error':
            raise RuntimeError('Simulated client error')
        # For throughput: echo back request info
        return HTTPResponse({
            'method': request.method,
            'url': request.url,
            'headers': request.headers,
            'path_params': request.path_params,
            'body': request.body
        })

class JiraClient:
    def __init__(self, client):
        self.client = client

    def get_client(self):
        return self.client
from app.sources.external.jira.jira import JiraDataSource

# ---- TESTS ----

# 1. Basic Test Cases

@pytest.mark.asyncio
async def test_set_comment_property_basic_success():
    """Test basic successful property set with default headers and body."""
    client = JiraClient(DummyClient())
    ds = JiraDataSource(client)
    body = {'foo': 'bar'}
    resp = await ds.set_comment_property('123', 'mykey', body)

@pytest.mark.asyncio
async def test_set_comment_property_custom_headers():
    """Test custom headers override default Content-Type."""
    client = JiraClient(DummyClient())
    ds = JiraDataSource(client)
    headers = {'Content-Type': 'application/x-custom', 'X-Test': 'yes'}
    resp = await ds.set_comment_property('456', 'otherkey', {'baz': 1}, headers)

@pytest.mark.asyncio
async def test_set_comment_property_empty_body():
    """Test with no body (should handle None body gracefully)."""
    client = JiraClient(DummyClient())
    ds = JiraDataSource(client)
    resp = await ds.set_comment_property('789', 'emptykey', None)

# 2. Edge Test Cases

@pytest.mark.asyncio
async def test_set_comment_property_invalid_client_none():
    """Test ValueError is raised if client is None."""
    class BadClient:
        def get_client(self):
            return None
    with pytest.raises(ValueError) as excinfo:
        JiraDataSource(JiraClient(BadClient()))

@pytest.mark.asyncio
async def test_set_comment_property_invalid_client_no_base_url():
    """Test ValueError if client does not have get_base_url method."""
    class NoBaseUrlClient:
        pass
    with pytest.raises(ValueError) as excinfo:
        JiraDataSource(JiraClient(NoBaseUrlClient()))

@pytest.mark.asyncio
async def test_set_comment_property_execute_raises():
    """Test that exceptions from client.execute are propagated."""
    class ErrorClient(DummyClient):
        async def execute(self, request):
            raise RuntimeError('Simulated error')
    ds = JiraDataSource(JiraClient(ErrorClient()))
    with pytest.raises(RuntimeError) as excinfo:
        await ds.set_comment_property('123', 'mykey', {'foo': 'bar'})

@pytest.mark.asyncio
async def test_set_comment_property_concurrent_calls():
    """Test concurrent execution of multiple property sets."""
    client = JiraClient(DummyClient())
    ds = JiraDataSource(client)
    bodies = [{'v': i} for i in range(5)]
    tasks = [
        ds.set_comment_property(str(i), f'key{i}', bodies[i])
        for i in range(5)
    ]
    results = await asyncio.gather(*tasks)
    for i, resp in enumerate(results):
        pass

@pytest.mark.asyncio

async def test_set_comment_property_many_concurrent():
    """Test large scale concurrent calls (50)."""
    client = JiraClient(DummyClient())
    ds = JiraDataSource(client)
    n = 50
    tasks = [
        ds.set_comment_property(str(i), f'key{i}', {'num': i})
        for i in range(n)
    ]
    results = await asyncio.gather(*tasks)
    for i, resp in enumerate(results):
        pass

@pytest.mark.asyncio
async def test_set_comment_property_large_body():
    """Test with large body payload."""
    client = JiraClient(DummyClient())
    ds = JiraDataSource(client)
    large_body = {f'k{i}': i for i in range(100)}
    resp = await ds.set_comment_property('big', 'bulk', large_body)

# 4. Throughput Test Cases

@pytest.mark.asyncio
async def test_set_comment_property_throughput_small_load():
    """Throughput test: small load (10 requests)."""
    client = JiraClient(DummyClient())
    ds = JiraDataSource(client)
    tasks = [
        ds.set_comment_property(str(i), f'key{i}', {'val': i})
        for i in range(10)
    ]
    results = await asyncio.gather(*tasks)
    for i, resp in enumerate(results):
        pass

@pytest.mark.asyncio
async def test_set_comment_property_throughput_medium_load():
    """Throughput test: medium load (100 requests)."""
    client = JiraClient(DummyClient())
    ds = JiraDataSource(client)
    tasks = [
        ds.set_comment_property(str(i), 'throughput', {'idx': i})
        for i in range(100)
    ]
    results = await asyncio.gather(*tasks)
    for i, resp in enumerate(results):
        pass

@pytest.mark.asyncio
async def test_set_comment_property_throughput_varied_headers():
    """Throughput test: varied headers and bodies."""
    client = JiraClient(DummyClient())
    ds = JiraDataSource(client)
    tasks = []
    for i in range(20):
        headers = {'X-Req': str(i), 'Content-Type': 'application/json'}
        body = {'req': i}
        tasks.append(ds.set_comment_property(str(i), f'key{i}', body, headers))
    results = await asyncio.gather(*tasks)
    for i, resp in enumerate(results):
        pass

@pytest.mark.asyncio
async def test_set_comment_property_throughput_high_volume():
    """Throughput test: high volume (200 requests)."""
    client = JiraClient(DummyClient())
    ds = JiraDataSource(client)
    tasks = [
        ds.set_comment_property(str(i), 'hv', {'num': i})
        for i in range(200)
    ]
    results = await asyncio.gather(*tasks)
    # Spot check a few
    for idx in [0, 50, 100, 199]:
        pass
# codeflash_output is used to check that the output of the original code is the same as that of the optimized code.

To edit these changes git checkout codeflash/optimize-JiraDataSource.set_comment_property-mhoxxvpy and push.

Codeflash

**Optimizations Applied:**

- **`app/sources/external/jira/jira.py`:**  
  - Utilized async context management for the client's `execute` method to ensure proper connection/resource cleanup when executing requests.
  - No blocking operations were present; existing async flow is properly maintained.  
  - Minor optimization: Used a local variable for `_client` within `set_comment_property` to avoid repeated attribute lookups.

- **`app/sources/client/http/http_client.py`:**  
  - Batching multiple request header manipulations to avoid unnecessary intermediate objects.
  - Ensured async client creation is performed only once per event loop (no repeated unnecessary creations).
  - No blocking operations detected; I/O is already async via HTTPX.
  - No major concurrency batching possible as the code is request-per-request; optimizations related to concurrent execution are to be handled at callsite if needed.

---
@codeflash-ai codeflash-ai bot requested a review from mashraf-222 November 7, 2025 14:18
@codeflash-ai codeflash-ai bot added the ⚡️ codeflash Optimization PR opened by Codeflash AI label Nov 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

⚡️ codeflash Optimization PR opened by Codeflash AI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant