Skip to content

Testing Instructions

Piyush Ahuja edited this page Feb 14, 2020 · 4 revisions

How to test the COGS application on your local development machine

  • Start local PostgreSQL database instance
  • Ensure that the Pagesmith authentification is disabled in configuration for the COGS backend server.

File: config.yaml

Relevant Lines:

pagesmith_auth: 
enabled: False

This will ensure that auth is bypassed and routed to a dummy auth (auth/pagesmith_dummy.py).

  • Initiating the COGS backend server should add several dummy users. Relevant File: /db/interface.py

Simulating a Role

There are four possible user roles to test for: student, grad_office, supervisor and cogs_member. To change the role of the logged-in user, either manually edit the role of the first user (default dummy user) in the User table. However, it is more convenient to have four dummy users, one for each role, and change the get_user_from_request method in auth/pagesmith_dummy.py to return the user with the relevant role.

Relevant Lines:

  async def get_user_from_request(self, request: Request) -> User:
        """Extract the user from the request.

        Since this authenticator is just for debugging, we look at the
        `email_address` cookie and get that user from the database if
        possible; if there's no such cookie, or if it doesn't match up
        with a known user, just use the user with ID 1.
        """
        user = None
        if "email_address" in request.cookies:
            user = self._cogs_db.get_user_by_email(request.cookies["email_address"])
        if user is None:
            user = self._cogs_db.get_user_by_id(2) # Change to id of  dummy user with relevant role to be tested
        return user

Simulating the state of a rotation

The COGS application can be thought of a state machine where each rotation goes through a series of state transitions from creation to completed. To simulate a particular state of rotation, toggle the following flags:

`Project_Group' Table:

  • student_viewable – whether students are allowed to view the projects in the rotation
  • student_choosable – whether students are allowed to submit votes for their preferred projects for the rotation
  • student_uploadable – whether students are allowed to upload reports for their project in this rotation
  • can_finalise – whether the Graduate Office can finalise the assignment of projects to students
  • read_only – whether supervisors/the Graduate Office are allowed to create/delete projects or pre-assign students to projects

Project Table:

  • uploaded
  • grace_passed

To decide which combination of flags simulate which rotation, refer to state machine.

Simulating File Upload

To test the project upload function on your local machine, ensure that the configured relevant directory has the relevant permissions. One can change the upload directory by modifying the following lines in config.yaml:

upload_directory: /Users/pa11/cogs/uploads

When the app's running from the development configuration, there should be checkboxes next to the dates for each rotation on the homepage, so you can change some of the state without going into the database

Testing Schedule Jobs on Development Instance with Docker

There are two other things available to help with testing:

  • libfaketime is installed in the development Docker container, so you can do things like make the backend think the date has changed by 24 hours
  • Secondly, you can set the "email_address" cookie to any user's email address to log in as that user (again, only in the development configuration!).

Testing time-based events

The development Docker image (use Dockerfile.dev) has libfaketime installed and configured, so you can modify the apparent flow of time inside the container by writing to a file. Full documentation is available in the libfaketime repository, but typically you would use it like so:

$ # Start up the container and add a rotation, then:
$ docker exec -ti name_of_the_container bash
# echo '+1d' > /etc/faketimerc
# # Now the application thinks one day has passed
# echo '+2d' > /etc/faketime
# # Now two days have passed, etc.

If there are events scheduled to happen between old and new times, you will probably need to make some kind of HTTP request to the backend to wake up the event loop and make the scheduler take notice of the new time (due to caching inside libfaketime, you may need to wait up to 10 seconds before a refresh will have any effect). There is an API endpoint enabled in development mode that shows the time inside the container, /api/util/time, which you can use for this purpose.

libfaketime also supports altering the speed of the clock, so you can run a full test at an increased rate without manual intervention:

$ docker exec -ti name_of_the_container bash
# echo '+0 x144' > /etc/faketimerc
# # Ten minutes outside the container corresponds to one day inside the container

However, changing the multiplier at runtime won't work how you expect.

If you use a bind-mount or volume to make the faketimerc available outside the container, you must ensure that your editor does not use any kind of "atomic save" where it writes to a different file and moves it on top of the existing file, because this will break the bind-mount, and until you restart the container, the contents of the files inside and outside the container will no longer be synchronised.