elixir-maru / maru

Elixir RESTful Framework
https://maru.readme.io
BSD 3-Clause "New" or "Revised" License
1.32k stars 85 forks source link

Running with MIX_ENV=test results in "Server Error" #38

Closed aisrael closed 7 years ago

aisrael commented 8 years ago

I was trying to write espec + tesla tests to exercise my maru Web service.

I'm following the guide, and so when I run iex -S mix then I curl localhost:8880, I get the expected response ({"hello":"world"}).

However, when I try to write espec tests or run MIX_ENV=test iex -S mix, then curl reports Server Error. Further poking around (I replaced text("Server Error") with text(inspect(e)) reveals:

MIX_ENV=test iex -S mix
Erlang/OTP 19 [erts-8.0.2] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe]
[kernel-poll:false] [dtrace]

20:14:08.902 [info]  Running Elixir.MyApp.API with Cowboy on http://127.0.0.1:8880
Interactive Elixir (1.3.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)>
$ curl localhost:8880
%Maru.Exceptions.NotFound{method: "GET", path_info: []}

I'm a bit lost why MIX_ENV=test would result in such behavior.

aisrael commented 8 years ago

Upon closer inspection, when iex -S mix is used normally, I see

Compiling 1 file (.ex)
Generated my_app app

When MIX_ENV=test is provided, there's no Generated my_app app line.

So, I guess this isn't a maru issue again, just me not understanding the tooling (mix with MIX_ENV=test).

aisrael commented 8 years ago

Sorry, am still struggling with this. Apparently the generated my_app app occurs whenever I do mix clean, regardless of MIX_ENV=test or not.

So, back to square one. I actually have a bare minimum project that exhibits this. iex -S mix and all is well, MIX_ENV=test iex -S mix and %Maru.Exceptions.NotFound{method: "GET", path_info: []}, but the output of iex is identical.

falood commented 8 years ago

test ENV is special for maru, you can use any ENV to run a server except test. Thank you chose maru and I have stared your repo and I'll keep an eye on it!

I have so many things to do theses days, I'm sorry for the delay.

aisrael commented 8 years ago

Thanks for the response @falood. Anyway I'm trying to "go deep" inside maru code itself to see if this is something I can 'hack' a solution or at least workaround for.

aisrael commented 8 years ago

I noticed that in line 51 of builder.ex you do a test for the :test configuration item, or default to Mix.env == test.

I also noticed that maru needs to check Mix.env == test in order for maru's unit tests themselves to pass.

So, here's what I've tried. I changed that line a bit so that it first checks if the :test configuration key is provided. If so, then it checks if the value is true. Only if the :test key isn't provided does it default to checking Mix.env:

@test if (Keyword.has_key?(Application.get_all_env(:maru), :test)), do: Application.get_env(:maru, :test), else: Mix.env == :test

This allows the maru tests to proceed and pass as before.

But it also allows folks like me to go:

config :maru, MyApp.API, http: [port: p]
config :maru, test: false

To 'force' maru to ignore MIX_ENV=test and startup 'normally'.

@falood Do you think this is acceptable? If so, I'll gladly raise a PR.

falood commented 8 years ago

Thank you for your suggestion. Do you think it's better to bind test to router? Like this:

config :maru, MyApp.API, 
  http: [port: 8000],
  test: false