hw

module
v0.0.0-...-9f01b0d Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 12, 2023 License: GPL-2.0

README

HW (homework)

How to ...

... build the services
  • make bin/port-domain to build the port-domain service
  • make bin/client-api to build the client-api service

This will produce binary in bin/ directory

Running make clean/<service> will delete the binary.

... re-generate protocol buffers

./scripts/gen-proto.sh regenerates any changes of proto/port-domain.proto into pb.go

Please note, that this is poor man's protobuf generation. Although good enough for a PoC like this, a better way would be to use something like https://github.com/bufbuild/buf where using config yaml's you can descriptively control what and how is generated without the need for the nitty-gritty details of protoc and protoc-gen-go-grpc :) Not even mentioning that the tools and their options keep changing with every major version (not in backwards-compatible way) which makes it hard to write by hand.

... re-generate sqlboiler

First run ./scripts/run-postgres.sh then sqlboiler psql from services/port-domain directory, where the sqlboiler.toml is.

The ./scripts/run-postgres.sh is also a poor man's way of doing the db migration (even for development), but it's quick and ok for PoC. Better way of doing this would be to ingergate migration tool (like sql-migrate) with the make or compose tools or write an internal binary that would initialize an migrate an empty postgres database.

... build docker images
  • docker build -f docker/Dockerfile.port-domain --tag port-domain:latest . to build the port-domain image
  • docker build -f docker/Dockerfile.client-api --tag client-api:latest . to build the client-api image
... re-generate Wire

Run wire in services/port-domain or service/client-api.

... install dependencies
  • google.golang.org/protobuf/cmd/protoc-gen-go
  • google.golang.org/grpc/cmd/protoc-gen-go-grpc
  • github.com/volatiletech/sqlboiler/v4
  • github.com/google/wire
  • github.com/golangci/golangci-lint

I am assuming that you have all the other tools (like docker, docker-compose, go compiler...) installed.

If I had time I would at least make a target in Makefile and make use of go install a certain version of each tool.

Running the app (i.e. demo)

docker-compose --project-name=hw -f docker-compose-main.yml up

Network is set to be reachable from outside. With the help of scripts from testdata, we can

  • ./api_post.sh which will make a POST request to /v1/ports/import
  • then we can list them back: ./api_list.sh
  • and even check the database: ./hw_psql.sh (will ask for password, from .env file, it is: "password")
  • using a bloomRPC or similar tool, we can even test gRPC of port-domain

Tests

Unfortunately, I ran out of time and wasn't able to write any (unit)tests. Let me at least write here, what I would do if I had time.

  • unit tests: port-domain:

    • the PortStorer interface can be mocked (using for e.g. stretchr testify/mock) and all cases, even errors, can be simulated using the On() methods and furthermore asserted at the end.
    • conversion functions.

    client-api:

    • gRPC client dependency is an interface too. Although I would probably use testify/mock for this (it's a small interface) but there are mock generators fo gRPC clients as well.
    • unit tests for handlers, for the conversion functions
  • integration tests: To test the whole thing, I'd make a docker image + compose to run the whole setup, and on the extra image I'd run the integration tests that would call the main interface (http rest api, i.e. the import as well as list) and could even check what has been stored in the database.

  • gray-area: Sometimes it may be a good idea to run a test suite, but against a real dependency, like a DB. Here it would be the storage implementation. I would simply use stretchr testify Suite to create unit test suites, where before the the whole suite a db migration would be run and before each test the db table would be truncated so that each test would have empty database.

I am more than happy to talk about all the actual test (corner)cases on the technical interview, I simply ran out of time to write them out individually (similar time to actualy write the suites 🤷)

directory structure

  • services: Client-api and port-domain applications (services).

  • docker: Docker files for both services.

  • pkg: Go packages. Basically code that is shared/used by more than one service.

  • proto: gRPC protocol buffer definitions. They are generated into pb.go directory.

  • pb.go: Generated protoco buffer gRPC files and stubs.

  • scripts: Helper scripts (for building services, generating protobufs, running postgres...) some of which are used by Makefile.

  • bin: Built service binaries.

  • testdata: Tools/scripts that I used to test the application.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL