fecgov / openFEC

The first RESTful API for the Federal Election Commission. We're aiming to make campaign finance more accessible for journalists, academics, developers, and other transparency seekers.
https://api.open.fec.gov/developers
Other
481 stars 106 forks source link

API load testing setup #4327

Closed lbeaufort closed 4 years ago

lbeaufort commented 4 years ago

Action item from https://github.com/fecgov/openFEC/issues/4314

Need to know what the system can handle before it "falls over". Need to know what the load was on April 15, for example.

Completion criteria:

Technical steps

Prepare the "locusts"

Set up environment

Communicate

lbeaufort commented 4 years ago

We should also let the team and cloud.gov know (ideally a week beforehand) which day we plan to test. Reference: https://cloud.gov/docs/compliance/pentest/

lbeaufort commented 4 years ago

Parsing script:

"""Extract API query from Kibana log file"""
import csv
import json

with open("LB_API_RTR_requests_4-15-20.csv", "r") as file:
    reader = csv.reader(file, delimiter=',')
    # Endpoint/uery lookup
    queries = {}
    count = 0
    for row in reader:
        # Column 2 has the queries. Throw out some bad data
        if 'v1' in row[1]:
            # Get the endpoint- everything after the 'v1' to the first '?'
            endpoint = row[1].partition("v1/")[2].partition("?")[0].partition(" ")[0]
            if endpoint[-1] != "/":
                endpoint += "/"
            # Get the query param string - everything between the ? and the ' '
            query_parameters = row[1].partition("?")[2].partition(" ")[0]
            # Parse arguments
            query_dict = {}
            if "&" in query_parameters:
                # Clean up some double &&
                query_parameters = query_parameters.replace("&&", "&")
                # Split each query pair out into a list
                parameter_groups = query_parameters.split("&")
                # Make a dictionary of the parameters (this is how locust needs them)
                for result in parameter_groups:
                    # Split the parameters from the values
                    if "=" in result and "api_key" not in result:
                        key, value = result.split("=")
                        if not query_dict.get(key):
                            query_dict[key] = [value]
                        else:
                            query_dict[key].append(value)
            if query_dict:
                # Add to the endpoint/query lookup
                if not queries.get(endpoint):
                    queries[endpoint] = [query_dict]
                else:
                    if query_dict not in queries[endpoint]:
                        queries[endpoint].append(query_dict)

print(json.dumps(queries, indent=1))
lbeaufort commented 4 years ago

In the console:

https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Overview.DBInstance.Modifying.html

lbeaufort commented 4 years ago

There were some issues with formatting the requests, so I also did some testing with the normal locust setup.