Skip to content

Conversation

@Kavi-25
Copy link
Owner

@Kavi-25 Kavi-25 commented Aug 19, 2025

PR Type

Enhancement, Tests


Description

  • Created Locust load testing script.

  • Simulates user actions.

  • Includes login, data fetching, and leave application.

  • Uses CSV for user credentials.


Diagram Walkthrough

flowchart LR
  A[Employee.csv] --> B(locust.py);
  B --> C{Login};
  C --> D[Data Fetching];
  D --> E[Leave Application];
  E --> F[Check-in/Check-out];
  F --> G[Other Actions];
  G --> H[Load Test];
Loading

File Walkthrough

Relevant files
Tests
locust.py
Locust script for load testing employee actions                   

locust.py

  • Created a Locust load testing script (locust.py).
  • Defined WebsiteUser class to simulate user actions.
  • Implemented tasks for login, data fetching, leave application, and
    more.
  • Included error handling and logging.
+445/-0 

@Kavi-25 Kavi-25 closed this Aug 19, 2025
@Kavi-25 Kavi-25 reopened this Aug 19, 2025
@Kavi-25
Copy link
Owner Author

Kavi-25 commented Aug 19, 2025

PR Reviewer Guide 🔍

(Review updated until commit b077e8d)

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 5 🔵🔵🔵🔵🔵
🧪 No relevant tests
🔒 Security concerns

Hardcoded Password:
The script uses a hardcoded password ('COMMON_PW'). This is a major security vulnerability. The password should be stored and accessed securely, for example, using environment variables. Storing passwords directly in the code is highly discouraged.

⚡ Recommended focus areas for review

Error Handling

The validate_resp function catches exceptions but only prints the error. More robust error handling is needed, perhaps logging the error details and potentially retrying failed requests. The current approach might mask underlying issues.

def validate_resp(self, resp):
    try:
        resp.raise_for_status()
        # if resp.status_code >= 500:
        #     raise SystemError(resp.text)
        return True
    except Exception as e:
        print("[ERROR]", e)
        return False
Hardcoded Password

The script uses a hardcoded password (COMMON_PW). This is a significant security risk. The password should be managed securely, perhaps through environment variables or a more secure configuration method.

COMMON_PW = "AVP@2023"
Date Range

The dates list is hardcoded with a specific date range. This limits the flexibility of the test. Consider making this configurable or dynamically generated.

dates  = [
    "2025-07-21", "2025-07-22", "2025-07-23", "2025-07-24", "2025-07-25",
    "2025-07-26", "2025-07-27", "2025-07-28", "2025-07-29", "2025-07-30",
    "2025-07-31", "2025-08-01", "2025-08-02", "2025-08-03", "2025-08-04",
    "2025-08-05", "2025-08-06", "2025-08-07", "2025-08-08", "2025-08-09",
    "2025-08-10", "2025-08-11", "2025-08-12", "2025-08-13", "2025-08-14",
    "2025-08-15", "2025-08-16", "2025-08-17", "2025-08-18", "2025-08-19",
    "2025-08-20", "2025-08-21", "2025-08-22", "2025-08-23", "2025-08-24",
    "2025-08-25", "2025-08-26", "2025-08-27", "2025-08-28", "2025-08-29",
    "2025-08-30", "2025-08-31", "2025-09-01", "2025-09-02", "2025-09-03",
    "2025-09-04", "2025-09-05", "2025-09-06", "2025-09-07", "2025-09-08",
    "2025-09-09", "2025-09-10", "2025-09-11", "2025-09-12", "2025-09-13",
    "2025-09-14", "2025-09-15", "2025-09-16", "2025-09-17", "2025-09-18",
    "2025-09-19", "2025-09-20", "2025-09-21", "2025-09-22", "2025-09-23",
    "2025-09-24", "2025-09-25", "2025-09-26", "2025-09-27", "2025-09-28",
    "2025-09-29", "2025-09-30"

@Kavi-25
Copy link
Owner Author

Kavi-25 commented Aug 19, 2025

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
General
Remove commented-out actions

The actions list in the execute_actions function contains many commented-out
actions. This makes the code harder to read and maintain. Either remove the
commented-out lines or uncomment them if they are intended to be part of the
execution flow. Decide whether to keep them or remove them for clarity.

locust.py [409-421]

 actions = [
     self.check_in,
-    # self.fetch_holiday_list,
-    # self.checkin_status,
-    # self.create_leave_app,
-    # self.fetch_salary_slip,
     self.check_out,
-    # self.get_leave_balance,
-    # self.fetch_leave_list,
-    # self.compensatory_leavereq,
-    # self.fetch_notificationlog,
 ]
Suggestion importance[1-10]: 5

__

Why: The suggestion is valid and improves code readability by removing commented-out code. The impact is moderate as it enhances maintainability. The improved_code accurately reflects the change, although the user might want to consider if some of the commented-out actions should be included.

Low
Possible issue
Fix indentation and add colons

The code has indentation issues. The if statements inside the get_list function
lack consistent indentation, leading to potential logic errors. Correct the
indentation to ensure proper execution flow. Also, add a colon after each if
statement.

locust.py [60-70]

-if filters
+if filters:
     params['filters'] = json.dumps(filters)
 if fields:
     params['fields'] = json.dumps(fields)
 if order_by:
     params['order_by'] = order_by
 if limit_page_length != 0:
     params['limit_page_length'] = str(limit_page_length)
 if as_dict:
     params['as_dict'] = as_dict
Suggestion importance[1-10]: 3

__

Why: The suggestion is correct in that it points out inconsistent indentation and missing colons in the if statements. However, the impact is minor as it's a stylistic issue and doesn't affect the functionality. The improved_code accurately reflects the changes.

Low
Fix indentation and add colon

The code within the fetch_holiday_list function has an indentation error. The inner
if statement is not properly indented, potentially causing unexpected behavior.
Ensure proper indentation to correctly handle the conditional logic. Also, add a
colon after if holiday_list.

locust.py [153-157]

-if holiday_list
+if holiday_list:
     resp = self.client.get(f"/api/resource/Holiday List/{holiday_list}", headers=headers,name= name)
     if not self.validate_resp(resp):
         raise Exception(f"[ERROR] Holiday fetch failed: {resp.text}")
Suggestion importance[1-10]: 3

__

Why: The suggestion correctly identifies and fixes an indentation error and adds a missing colon. The impact is minor, improving code readability but not functionality. The improved_code accurately reflects the change.

Low

@Kavi-25
Copy link
Owner Author

Kavi-25 commented Aug 19, 2025

/ask rate my coding style out of 10

@Kavi-25
Copy link
Owner Author

Kavi-25 commented Aug 19, 2025

Ask

rate my coding style out of 10

Answer:

I'd rate the coding style a 7/10.

Strengths:

  • Consistent indentation: The code uses consistent indentation, making it easy to read.
  • Clear variable names: Variable names are mostly descriptive (e.g., USER_CREDENTIALS, formatted_time).
  • Function decomposition: The code is broken down into several functions, improving readability and maintainability. This is a good practice.
  • Error handling: The validate_resp function and error handling within other functions demonstrate an attempt at robustness.
  • Comments: While not extensive, some comments are present to explain certain sections.
  • Use of external libraries: Leveraging pandas and locust is appropriate for the task.

Areas for Improvement:

  • Docstrings: The code lacks docstrings to explain the purpose and parameters of functions. Adding docstrings would significantly improve readability and understanding. For example:
def get_list(self, name, doctype, filters=None, ...):
    """Retrieves a list of items from the API.

    Args:
        name (str): The name of the API call.
        doctype (str): The type of document to retrieve.
        filters (list, optional): Filters to apply to the query. Defaults to None.
        ...
    Returns:
        list: A list of dictionaries representing the retrieved items.  Returns an empty list if no items are found or an error occurs.
    """
    # ... function body ...
  • Magic numbers: The code contains several magic numbers (e.g., 3, 6 in wait_time, 192.168.0.227:30626 as the host). These should be replaced with named constants for better readability and maintainability.
MIN_WAIT_TIME = 3
MAX_WAIT_TIME = 6
HOST = "http://192.168.0.227:30626"
  • Long functions: Some functions, like get_list and compensatory_leavereq, are quite long. Breaking them down into smaller, more focused functions would improve readability.

  • Hardcoded dates: The dates list contains a large number of hardcoded dates. Consider using a more dynamic approach to generate these dates, perhaps based on a start and end date.

  • Logging: While there's some printing for debugging, a more robust logging system (using the logging module) would be beneficial for production use.

  • Code Style Guide: The code would benefit from adhering to a consistent style guide (like PEP 8). Tools like pylint or flake8 can help enforce this.

Addressing these points would elevate the code quality and make it easier for others to understand, maintain, and extend.

@Kavi-25
Copy link
Owner Author

Kavi-25 commented Aug 19, 2025

/review review and suggest how can we implement DRY principal

@Kavi-25
Copy link
Owner Author

Kavi-25 commented Aug 19, 2025

Persistent review updated to latest commit b077e8d

@Kavi-25
Copy link
Owner Author

Kavi-25 commented Aug 19, 2025

/ask how can we implement and improve DRY principal in my codebase

@Kavi-25
Copy link
Owner Author

Kavi-25 commented Aug 19, 2025

Ask

how can we implement and improve dry principal in my codebase

Answer:

The provided locust.py script has several areas where the DRY (Don't Repeat Yourself) principle can be improved. The primary offender is the repetitive use of similar code blocks within the various methods (fetch_holiday_list, fetch_salary_slip, get_leave_balance, fetch_leave_list, compensatory_leavereq, fetch_notificationlog, checkin_status). These methods all share a common pattern:

  1. Check for employee_data and employee_id: Each method begins by checking if self.employee_data exists and extracts employee_id. This can be refactored into a helper method.

  2. Setting headers: Many methods set similar headers (Cookie, Accept, Content-Type). This can be consolidated.

  3. Making API calls: The core logic of making API calls with varying endpoints, parameters, and payloads is repeated. This can be abstracted.

  4. Error Handling: The validate_resp method is good, but the error handling within each method could be standardized.

Here's how you can improve the DRY principle:

1. Create Helper Methods:

    def _get_employee_id(self):
        if not self.employee_data:
            print("[SKIP] No employee data")
            return None
        return self.employee_data.get("employee_id")

    def _get_headers(self, content_type=False):
        headers = {
            'Cookie': f'sid={self.sid}',
            'Accept': 'application/json',
        }
        if content_type:
            headers['Content-Type'] = 'application/json'
        return headers

    def _make_api_call(self, method, endpoint, headers, payload=None, params=None, name=None):
        if payload:
            response = self.client.post(endpoint, headers=headers, json=payload, name=name)
        elif params:
            response = self.client.get(endpoint, headers=headers, params=params, name=name)
        else:
            response = self.client.get(endpoint, headers=headers, name=name)
        if not self.validate_resp(response):
            raise Exception(f"API call failed: {response.text} ({response.status_code})")
        return response.json()

2. Refactor Existing Methods:

Now, refactor methods like fetch_holiday_list to use these helpers:

    def fetch_holiday_list(self):
        emp_id = self._get_employee_id()
        if not emp_id:
            return

        headers = self._get_headers()
        response_data = self._make_api_call("GET", f"/api/resource/Employee/{emp_id}", headers, name="fetch_holiday_list_employee")
        holiday_list = response_data.get("data", {}).get("holiday_list")

        if holiday_list:
            response_data = self._make_api_call("GET", f"/api/resource/Holiday List/{holiday_list}", headers, name="fetch_holiday_list")

Apply this pattern to all other similar methods. This significantly reduces code duplication and improves maintainability. Remember to adjust the _make_api_call method to handle different HTTP methods and parameter types as needed. The name parameter allows you to maintain the method name for Locust reporting.

@Kavi-25 Kavi-25 changed the title Create locust.py Create locust.py with chat options Aug 19, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants