Refactoring


Codesafe Testing

This module on Refactoring is developed to align with the lecture material and learning outcomes of UC Irvine's INF122 Software Design - Structure and Implementation, specifically the Winter 2025 offering of the course taught by Dr. Joshua Garcia. The current set of challenges are meant to be completed in order.


Lectures and Reading


Challenges

Welcome to the refactoring module! This challenge will serve as the first tutorial to how you will mainly be completing the challenges in this specific module. "Start" this challenge, and then you can interact with it by clicking on "Workspace" in the site's navigation bar or "VSCode Workspace" in the pop-up after the challenge has successfully started.

Start by running the checker Python executable by doing the following in the terminal:

$ cd /challenge
$ ./checker

The executable will then give you further instructions.

NOTE: For a Python file, you would usually run it by doing $ python3 [filename]. For this environment and platform, due to how permissions are handled so that you cannot simply read the flag, you MUST run checker by doing $ ./checker so that it can successfully read the flag and print it in the terminal. If you complete the tasks for the challenges but use $ python3 checker, you will get an error in the terminal (the file won't actually be executed).

In addition, you will get an error if you try to read the checker file / open it up in VSCode. This is intentional. Again, you MUST run checker as specified above.

Scenario

These challenges will ask you to refactor certain aspects of each challenge's provided 'codebase'. In this scenario, you will be refactoring a simplified version of a security information and event management (SIEM) solution, also known as a logging solution. Examples of these include Splunk, Datadog, and Wazuh.

To assist with these refactoring challenges, we will introduce you to the 'ruff' linter that will be checking your code to adhere to certain properties. You will be told what needs to be refactored, as if this is your first week on the job. To learn more about ruff: https://docs.astral.sh/ruff/.

Note that there are many other linters and code formatters out there, with different ones available for different programming languages. We happened to pick ruff as it is both a linter and formatter for Python with over hundreds of built-in rules and is used in major open-source projects. If you are not yet familiar with working with these kinds of tools for software development, these challenges are also designed to introduce and expose you to tools created and used by other developers.

In this tutorial, all you have to do is remove some unused imports. While unused imports can be helpful for future convenience, they end up adding some additional performance overhead, which can certainly stack up if you have a lot of them. They also add unnecessary clutter to the code, and you can easily add them back when you really need them.

This challenge will run the following command against 'simple_siem.py':

$ ruff check --select F401 /challenge/simple_siem.py

Run checker in the challenge environment to get a more in-depth breakdown!

Tasks

  1. Remove the unused imports in simple_siem.py.

Scenario

In this last tutorial for this module on refactoring, you are asked by your manager to make sure the code is not using any constants in any logic that involves comparisons. They anticipate the codebase to grow exponentially, and it'd be annoying to go change values manually at every single location it matters. For now, you have been told to keep the alert thresholds for error logs to be at 5 logs.

This time, there are also test cases to make sure SimpleSIEM operates as usual after your refactoring. This concept is known as 'regression testing', where tests are run against the codebase after a change is made to ensure that the application's functionality has not had any intentional changes. That way, you can't just delete the function and call it a day. Usage test cases will continue to be another component in these challenges to factor in moving forward. You can check the list of test cases in checker under the TestSimpleSIEM class.

Tasks

  1. Refactor away any constants that are used in logic that involves comparisons. The ruff check command, when ran, should pass when you are done.
  2. Ensure that the functionality of SimpleSIEM remains the same - all the test cases must pass.

This challenge will run the following command against 'simple_siem.py':

$ ruff check --select PLR2004 /challenge/simple_siem.py

You should consult Ruff's rules documentation to figure out what PLR2004 is, but you can also figure it out based on the error messages from ruff.

Start by running the checker Python executable in /challenge. Make sure to run it with the following:

$ ./checker

Scenario

Imagine if you had to run the following command everytime you want to run ruff on your code:

$ ruff check --verbose --target-version py310 --preview --statistics --select E4,E7,E9,F simple_siem.py

This can get quickly annoying everytime you want to check your code, even more so if you are constantly changing what you are configuring ruff to do on the command line. Instead of configuring ruff on the command line, ruff supports creating a configuration file (i.e., ruff.toml or pyproject.toml). Through this, you can set whatever options you would like ruff to run with that will persist across multiple usages - it's also much easier to edit and maintain your options within a file.

Configuration files, or 'configs', are commonly used throughout software development tooling, and learning how to comprehend them quickly can save on any onboarding time when you are getting acquainted with a new environment and codebase. You will often see .yaml and .toml file extensions to signify that they are configuration files used by some tool or application, but note that there are many other extensions that signify a config file out there.

The config has been made for you, /challenge/ruff.toml. You are intentionally unable to edit it, but you can read through it to determine what this challenge asks of you.

Another engineer recently implemented specific alerts into SimpleSIEM using some rudimentary analysis, but the code is not very readable. Use ruff and the config to guide your refactoring efforts. Note that you are able to create helper functions in simple_siem.py to help clean up the code. Keep in mind that regression testing will be done on your code, in addition to the ruff checks. You are NOT able to change the original function names since the test cases are immutable to you. If you need to restore parts of or all of simple_siem.py, you can use the copy in /challenge/backup.

Tasks

  1. Refactor SimpleSIEM to be more readable - for exactly what you need to do, you can run ruff check /challenge/simple_siem.py to get an idea of what issues are present.
  2. Ensure that the functionality of SimpleSIEM remains the same - all the test cases must pass.

From now on, the checker script will run ruff with the config using the following command:

$ ruff check /challenge/simple_siem.py


30-Day Scoreboard:

This scoreboard reflects solves for challenges in this module after the module launched in this dojo.

Rank Hacker Badges Score