GithubHelp home page GithubHelp logo

technicalassessment's Introduction

Quake 3 Arena Log Parser

This project is a technical assessment for a Senior Software Engineer position on CloudWalk. The test statement can be found here.

Technical Info

This projet use this tools:

  • Docker
  • Ruby 3.2.2
  • Rails 7.0.8
  • PostgreSQL 16
  • Redis 7
  • MinIO server
  • MinIO mc client

A little explaining

Building a CRUD API that receives a file via POST initially seemed boring to me. Instead, I opted for a more realistic approach by setting up a Bucket with a webhook event trigger, which notifies my Ruby on Rails app whenever a new file is uploaded. I'm assuming a scenario where this bucket belongs to Quake 3 Arena environment and isn't "anyone" that can send this file via POST, only tools that usually are available on bucket systems like this event trigger.

The Rails application processes the information received from the webhook to generate the URL from which the file can be downloaded. It then proceeds to parse the file and store the data accordingly.

Moreover, below is a brief list of points that I assumed for this project based on the requirements of the statement:

  • There is no need for a frontend, so the base application is a RESTful API.
  • As the application already processes and stores log data in a job, the main endpoints are GET only, in this case the /games/grouped_information and the /games/deaths_grouped_by_cause endpoints (and also variations of INDEX and SHOW in /games with pagination).
  • There is no authentication; the endpoints are public.
  • As the statement explains that the players' score in kills should receive -1 when <world> is the killer, but it doesn't say anything for when a player kills himself, I also considered this penalty for these cases of suicide.
  • Since a match is defined between the lines with InitGame and ShutdownGame, I include the has_crashed attribute in each game for cases where I encounter an InitGame without its respective ShutdownGame.

Executing on your machine

All project is dockerized, so you only need docker compose installed. After setting up with docker compose up you can access the application on localhost:3000

Docker Compose commands

Prepare docker images and containers:

docker compose build

Run all services:

docker compose up

with that you should also have a MinIO server up with a preconfigured bucket named minio/quake3logs with public access policy and a webhook trigger event for any upload event on this bucket that calls /uploaded-event endpoint

Other commands

Rails console (it needs the postgres and redis services running):

docker compose exec api bin/rails c

Run tests (it needs the api service running):

docker compose exec api bin/rspec

Watch jobs queue (with sidekiq) log:

tail -f log/sidekiq.log

Testing

This project has 100% test coverage. You can check this by running docker compose exec api bin/rspec and then accessing coverage/index.html

The endpoints for "grouped information for each match" and "deaths grouped by death cause for each match" required by the statement are respectively /games/grouped_information and /games/deaths_grouped_by_cause rendered as json. You can test them with tools like Postman or Insomnia. A simple curl for these is:

curl -X GET http://localhost:3000/games/grouped_information
curl -X GET http://localhost:3000/games/deaths_grouped_by_cause

Testing the upload on the bucket

Testing with MinIOWeb

With everything up, you can manually enter on the bucket with MinIOWeb. Access localhost:9090 with credentials admin and 12345678 and go to localhost:9090/browser/quake3logs and upload some example log available on spec/fixtures/. You can do a tail -f log/sidekiq.log before to see some logging of LogProcessJob.

Testing with minio/mc

You can generate an upload url with the following:

mc share upload --recursive minio/quake3logs

With this command you should get something like:

URL: http://localhost:9000/quake3logs
Expire: 7 days 0 hours 0 minutes 0 seconds
Share: curl http://localhost:9000/quake3logs/ \ 
-F policy=eyJleHBpcmF0aW9uIjoiMjAyNC0wNC0yM1QwMTo0NzoyNy4wMDVaIiwiY29uZGl0aW9ucyI6W1siZXEiLCIkYnVja2V0IiwicXVha2UzbG9ncyJdLFsic3RhcnRzLXdpdGgiLCIka2V5IiwiIl0sWyJlcSIsIiR4LWFtei1kYXRlIiwiMjAyNDA0MTZUMDE0NzI3WiJdLFsiZXEiLCIkeC1hbXotYWxnb3JpdGhtIiwiQVdTNC1ITUFDLVNIQTI1NiJdLFsiZXEiLCIkeC1hbXotY3JlZGVudGlhbCIsImFkbWluLzIwMjQwNDE2L3VzLWVhc3QtMS9zMy9hd3M0X3JlcXVlc3QiXV19 \
-F x-amz-algorithm=AWS4-HMAC-SHA256 \
-F x-amz-credential=admin/20240416/us-east-1/s3/aws4_request \
-F x-amz-date=20240416T014727Z \
-F x-amz-signature=d2e0f0a546e1d238150dd01bbf65f08fe3eacbf5d96907a419b17da5c5bdec41 \
-F bucket=quake3logs \
-F key=<NAME> \
-F file=@<FILE>

Just replace the <NAME> and <FILE> with the name that it'll be saved on the bucket and the filepath in your machine that you want to upload. On spec/fixtures/ you can find some log examples.

With the example before and using ./spec/fixtures/double-clean-games.log it should be:

curl http://localhost:9000/quake3logs/ \ 
-F policy=eyJleHBpcmF0aW9uIjoiMjAyNC0wNC0yM1QwMTo0NzoyNy4wMDVaIiwiY29uZGl0aW9ucyI6W1siZXEiLCIkYnVja2V0IiwicXVha2UzbG9ncyJdLFsic3RhcnRzLXdpdGgiLCIka2V5IiwiIl0sWyJlcSIsIiR4LWFtei1kYXRlIiwiMjAyNDA0MTZUMDE0NzI3WiJdLFsiZXEiLCIkeC1hbXotYWxnb3JpdGhtIiwiQVdTNC1ITUFDLVNIQTI1NiJdLFsiZXEiLCIkeC1hbXotY3JlZGVudGlhbCIsImFkbWluLzIwMjQwNDE2L3VzLWVhc3QtMS9zMy9hd3M0X3JlcXVlc3QiXV19 \
-F x-amz-algorithm=AWS4-HMAC-SHA256 \
-F x-amz-credential=admin/20240416/us-east-1/s3/aws4_request \
-F x-amz-date=20240416T014727Z \
-F x-amz-signature=d2e0f0a546e1d238150dd01bbf65f08fe3eacbf5d96907a419b17da5c5bdec41 \
-F bucket=quake3logs \
-F key=double-clean-games.log \
-F file=@./spec/fixtures/double-clean-games.log

technicalassessment's People

Contributors

callmarx avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.