From 5b7434ccad2c02aaae00894f253663674fdc22c6 Mon Sep 17 00:00:00 2001 From: connor rigby Date: Mon, 27 Mar 2017 09:26:35 -0700 Subject: [PATCH] tests pass with new farmbot simulator app. Slow though. --- config/dev.exs | 3 +- config/test.exs | 3 +- lib/serial/gcode/parser.ex | 4 +- lib/serial/handler.ex | 18 ++- lib/serial/supervisor.ex | 6 +- lib/system/farmbot_system_network.ex | 1 + mix.exs | 1 + mix.lock | 1 + priv/configs/default_config.json | 2 +- .../commands/config_update_test.exs | 10 +- test/celery_script/commands/home_test.exs | 8 +- .../commands/move_absolute_test.exs | 8 +- .../commands/move_relative_test.exs | 8 +- .../commands/read_all_params_test.exs | 16 +- test/serial/gcode_mock_test.exs | 153 ------------------ test/serial/handler_test.exs | 25 ++- test/test_helper.exs | 4 + 17 files changed, 72 insertions(+), 199 deletions(-) delete mode 100644 test/serial/gcode_mock_test.exs diff --git a/config/dev.exs b/config/dev.exs index 1d07c115..39bf749a 100644 --- a/config/dev.exs +++ b/config/dev.exs @@ -1,4 +1,5 @@ use Mix.Config config :farmbot, configurator_port: System.get_env("CONFIGURATOR_PORT") || 5000, - streamer_port: System.get_env("STREAMER_PORT") || 5050 + streamer_port: System.get_env("STREAMER_PORT") || 5050, + tty: System.get_env("ARDUINO_TTY") diff --git a/config/test.exs b/config/test.exs index 20b72802..65630e98 100644 --- a/config/test.exs +++ b/config/test.exs @@ -7,7 +7,8 @@ config :logger, :console, config :farmbot, path: "/tmp", - config_file_name: "default_config.json" + config_file_name: "default_config.json", + tty: "/dev/tnt1" config :farmbot, auth_callbacks: [] diff --git a/lib/serial/gcode/parser.ex b/lib/serial/gcode/parser.ex index 62003997..d93dcd1e 100644 --- a/lib/serial/gcode/parser.ex +++ b/lib/serial/gcode/parser.ex @@ -299,8 +299,8 @@ defmodule Farmbot.Serial.Gcode.Parser do def parse_param(:encoder_missed_steps_max_z), do: 113 def parse_param(:encoder_scaling_x), do: 115 - def parse_param(:encoder_scaling_x), do: 116 - def parse_param(:encoder_scaling_x), do: 117 + def parse_param(:encoder_scaling_y), do: 116 + def parse_param(:encoder_scaling_z), do: 117 def parse_param(:encoder_missed_steps_decay_x), do: 121 def parse_param(:encoder_missed_steps_decay_y), do: 122 diff --git a/lib/serial/handler.ex b/lib/serial/handler.ex index 9ac50aaa..dda63d95 100644 --- a/lib/serial/handler.ex +++ b/lib/serial/handler.ex @@ -136,6 +136,7 @@ defmodule Farmbot.Serial.Handler do {:ok, state} else Logger.warn "Handshake failed!" + IO.puts "BLERP" state = %{ tty: tty, nerves: nerves, queue: :queue.new(), current: :no_firm } @@ -250,12 +251,17 @@ defmodule Farmbot.Serial.Handler do end def handle_cast({:update_fw, hex_file, pid}, state) do - UART.close(state.nerves) - Process.sleep(100) - flash_firmware(state.tty, hex_file, pid) - Process.sleep(5000) - {:ok, new_state} = init({state.nerves, state.tty}) - {:noreply, new_state} + if String.contains?(state.tty, "tnt") do + send(pid, :done) + {:noreply, state} + else + UART.close(state.nerves) + Process.sleep(100) + flash_firmware(state.tty, hex_file, pid) + Process.sleep(5000) + {:ok, new_state} = init({state.nerves, state.tty}) + {:noreply, new_state} + end end def handle_info({:timeout, from, handshake}, state) do diff --git a/lib/serial/supervisor.ex b/lib/serial/supervisor.ex index 26d0a9c3..f27d6552 100644 --- a/lib/serial/supervisor.ex +++ b/lib/serial/supervisor.ex @@ -29,12 +29,12 @@ defmodule Farmbot.Serial.Supervisor do blah |> try_open(supervisor) end else + @tty Application.get_env(:farmbot, :tty, nil) @spec open_ttys(atom | pid, [binary]) :: :ok | no_return def open_ttys(supervisor, list \\ nil) def open_ttys(supervisor, _) do - tty = System.get_env("ARDUINO_TTY") - if tty do - try_open([tty], supervisor) + if @tty do + try_open([@tty], supervisor) else Logger.warn ">> EXPORT ARDUINO_TTY to initialize arduino in Host mode" :ok diff --git a/lib/system/farmbot_system_network.ex b/lib/system/farmbot_system_network.ex index 2140194a..efc43e39 100644 --- a/lib/system/farmbot_system_network.ex +++ b/lib/system/farmbot_system_network.ex @@ -110,6 +110,7 @@ defmodule Farmbot.System.Network do # First Party Farmware is not really a network concern but here we are... {:ok, fpf} = GenServer.call(CS, {:get, Configuration, "first_party_farmware"}) + IO.puts "FIRST PARTY FIRMWARE BOOL: #{inspect fpf}" if ntp do Logger.info ">> ntp" diff --git a/mix.exs b/mix.exs index b8f5e9f3..075385de 100644 --- a/mix.exs +++ b/mix.exs @@ -162,6 +162,7 @@ defmodule Farmbot.Mixfile do {:cors_plug, "~> 1.1"}, {:cowboy, "~> 1.0.0"}, {:ex_webpack, "~> 0.1.1", runtime: false, warn_missing: false}, + {:farmbot_simulator, "~> 0.1.0", only: [:test, :dev]}, {:tzdata, "~> 0.1.201601", override: true}, {:fs, "~> 0.9.1"} diff --git a/mix.lock b/mix.lock index cbcf46ab..ec7d872c 100644 --- a/mix.lock +++ b/mix.lock @@ -22,6 +22,7 @@ "exquisite": {:hex, :exquisite, "0.1.7", "4106503e976f409246731b168cd76eb54262bd04f4facc5cba82c2f53982aaf0", [:mix], []}, "exvcr": {:hex, :exvcr, "0.8.7", "e76f33b10dfefbcf32afa6d6867140566d0d54797e352b47485eed0241dd7edf", [:mix], [{:exactor, "~> 2.2", [hex: :exactor, optional: false]}, {:exjsx, "~> 3.2", [hex: :exjsx, optional: false]}, {:httpoison, "~> 0.8", [hex: :httpoison, optional: true]}, {:httpotion, "~> 3.0", [hex: :httpotion, optional: true]}, {:ibrowse, "~> 4.2.2", [hex: :ibrowse, optional: true]}, {:meck, "~> 0.8.3", [hex: :meck, optional: false]}]}, "faker": {:hex, :faker, "0.7.0", "2c42deeac7be717173c78c77fb3edc749fb5d5e460e33d01fe592ae99acc2f0d", [:mix], []}, + "farmbot_simulator": {:hex, :farmbot_simulator, "0.1.0", "436decb5e05a08b937ee21d8de4600c07f4a4487cf4e814d712cb578e350197c", [:make, :mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, optional: false]}, {:nerves_uart, "~> 0.1.2", [hex: :nerves_uart, optional: false]}]}, "fs": {:hex, :fs, "0.9.2", "ed17036c26c3f70ac49781ed9220a50c36775c6ca2cf8182d123b6566e49ec59", [:rebar], []}, "gen_mqtt": {:hex, :gen_mqtt, "0.3.1", "6ce6af7c2bcb125d5b4125c67c5ab1f29bcec2638236509bcc6abf510a6661ed", [:mix], [{:vmq_commons, "1.0.0", [hex: :vmq_commons, optional: false]}]}, "gen_stage": {:hex, :gen_stage, "0.11.0", "943bdfa85c75fa624e0a36a9d135baad20a523be040178f5a215444b45c66ea4", [:mix], []}, diff --git a/priv/configs/default_config.json b/priv/configs/default_config.json index 05903bce..ac0a5856 100644 --- a/priv/configs/default_config.json +++ b/priv/configs/default_config.json @@ -6,7 +6,7 @@ "configuration": { "user_env": {}, "os_auto_update": false, - "first_party_farmware": true, + "first_party_farmware": false, "steps_per_mm_x": 5, "steps_per_mm_y": 5, "steps_per_mm_z": 25, diff --git a/test/celery_script/commands/config_update_test.exs b/test/celery_script/commands/config_update_test.exs index f20e6d13..b6d5408f 100644 --- a/test/celery_script/commands/config_update_test.exs +++ b/test/celery_script/commands/config_update_test.exs @@ -5,12 +5,12 @@ defmodule Farmbot.CeleryScript.Command.ConfigUpdateTest do alias Farmbot.CeleryScript.Command setup_all do - GcodeMockTest.common_setup() + Farmbot.Serial.HandlerTest.wait_for_serial_available() + :ok end - test "makes sure we have serial", %{handler: handler} do - assert is_pid(handler) - assert Farmbot.Serial.Handler.available?(handler) == true + test "makes sure we have serial" do + assert Farmbot.Serial.Handler.available?() == true end test "sets some hardware params" do @@ -40,7 +40,7 @@ defmodule Farmbot.CeleryScript.Command.ConfigUpdateTest do test "wont put garbage in the state" do params = [ Command.pair(%{label: "some_garbage", value: "9001"}, []) ] - # ITS OVER NINE THOUSAND!!! + # ITS OVER NINE THOUSAND!!! Command.config_update(%{package: "arduino_firmware"}, params) conf = Farmbot.BotState.get_param "some_garbage" assert is_nil(conf) diff --git a/test/celery_script/commands/home_test.exs b/test/celery_script/commands/home_test.exs index 0be9e2be..5095b1cf 100644 --- a/test/celery_script/commands/home_test.exs +++ b/test/celery_script/commands/home_test.exs @@ -5,7 +5,8 @@ defmodule Farmbot.CeleryScript.Command.HomeTest do alias Farmbot.CeleryScript.Command setup_all do - GcodeMockTest.common_setup() + Farmbot.Serial.HandlerTest.wait_for_serial_available() + :ok end setup do @@ -13,9 +14,8 @@ defmodule Farmbot.CeleryScript.Command.HomeTest do :ok end - test "makes sure we have serial", %{handler: handler} do - assert is_pid(handler) - assert Farmbot.Serial.Handler.available?(handler) == true + test "makes sure we have serial" do + assert Farmbot.Serial.Handler.available?() == true end test "homes all axises" do diff --git a/test/celery_script/commands/move_absolute_test.exs b/test/celery_script/commands/move_absolute_test.exs index db67df1e..1252e731 100644 --- a/test/celery_script/commands/move_absolute_test.exs +++ b/test/celery_script/commands/move_absolute_test.exs @@ -5,12 +5,12 @@ defmodule Farmbot.CeleryScript.Command.MoveAbsoluteTest do alias Farmbot.CeleryScript.Command setup_all do - GcodeMockTest.common_setup() + Farmbot.Serial.HandlerTest.wait_for_serial_available() + :ok end - test "makes sure we have serial", %{handler: handler} do - assert is_pid(handler) - assert Farmbot.Serial.Handler.available?(handler) == true + test "makes sure we have serial" do + assert Farmbot.Serial.Handler.available?() == true end test "moves to a location" do diff --git a/test/celery_script/commands/move_relative_test.exs b/test/celery_script/commands/move_relative_test.exs index bd752561..3a8f1127 100644 --- a/test/celery_script/commands/move_relative_test.exs +++ b/test/celery_script/commands/move_relative_test.exs @@ -4,12 +4,12 @@ defmodule Farmbot.CeleryScript.Command.MoveRelativeTest do alias Farmbot.CeleryScript.Command setup_all do - GcodeMockTest.common_setup() + Farmbot.Serial.HandlerTest.wait_for_serial_available() + :ok end - test "makes sure we have serial", %{handler: handler} do - assert is_pid(handler) - assert Farmbot.Serial.Handler.available?(handler) == true + test "makes sure we have serial" do + assert Farmbot.Serial.Handler.available?() == true end test "moves to a location" do diff --git a/test/celery_script/commands/read_all_params_test.exs b/test/celery_script/commands/read_all_params_test.exs index 2487116d..50950981 100644 --- a/test/celery_script/commands/read_all_params_test.exs +++ b/test/celery_script/commands/read_all_params_test.exs @@ -5,20 +5,20 @@ defmodule Farmbot.CeleryScript.Command.ReadAllParamsTest do alias Farmbot.CeleryScript.Command setup_all do - GcodeMockTest.common_setup() + Farmbot.Serial.HandlerTest.wait_for_serial_available() + :ok end - test "makes sure we have serial", %{handler: handler} do - assert is_pid(handler) - assert Farmbot.Serial.Handler.available?(handler) == true + test "makes sure we have serial" do + assert Farmbot.Serial.Handler.available?() == true end - test "reads all params", %{mock: mock} do - old = Farmbot.BotState.get_all_mcu_params - GcodeMockTest.invalidate_params(mock) + test "reads all params" do + # old = Farmbot.BotState.get_all_mcu_params Command.read_all_params(%{}, []) Process.sleep(100) new = Farmbot.BotState.get_all_mcu_params - assert old != new + assert is_map(new) + assert !Enum.empty?(new) end end diff --git a/test/serial/gcode_mock_test.exs b/test/serial/gcode_mock_test.exs deleted file mode 100644 index 65595b48..00000000 --- a/test/serial/gcode_mock_test.exs +++ /dev/null @@ -1,153 +0,0 @@ -defmodule GcodeMockTest do - @moduledoc false - - use ExUnit.Case - alias Nerves.UART - alias Farmbot.Serial.Handler - @mock_tty "/dev/tnt1" - use GenServer - def start_link do - GenServer.start_link(__MODULE__, [], name: __MODULE__) - end - - def init([]) do - tty = @mock_tty - {:ok, uart} = UART.start_link() - UART.open(uart, tty) - UART.configure(uart, - framing: {UART.Framing.Line, separator: "\r\n"}, - active: true, - rx_framing_timeout: 500) - {:ok, %{uart: uart, params: default_params(), position: nil}} - end - - def invalidate_params(mock) do - GenServer.call(mock, :invalidate_params) - end - - defp default_params do - %{ - "movement_timeout_x" => 100, - "movement_timeout_y" => 200 - } - end - - def handle_call(:invalidate_params, _, state) do - {random_param, _old_value} = Enum.random(state.params) - new_params = %{state.params | random_param => Enum.random(0..100)} - IO.inspect state.params - IO.inspect new_params - {:reply, :ok, %{state | params: new_params}} - end - - def handle_info({:nerves_uart, @mock_tty, code}, state) do - reply = handle_code(code, state) - case reply do - {:params, map, reply} -> - do_reply(reply, state.uart) - new_params = Map.merge(state.params, map) - {:noreply, %{state | params: new_params}} - - {:position, pos, reply} -> - do_reply(reply, state.uart) - {:noreply, %{state | position: pos}} - - nil -> - {:noreply, state} - - reply -> - do_reply(reply, state.uart) - {:noreply, state} - end - end - - defp do_reply([], _uart), do: :ok - - defp do_reply([str | rest], uart) do - do_reply(str, uart) - do_reply(rest, uart) - end - - defp do_reply(str, uart) when is_binary(str) do - UART.write(uart, str) - end - - defp handle_code("F83 Q" <> code, _state) do - "R83 mock_fw Q#{code}" - end - - defp handle_code("F22 P" <> params, _state) do - # "F22 P11 V1000 Q8" - {rest, code} = split_by_q(params) - # "11 V1000" - [param_int | [value]] = String.split(rest, " V") - - reply = [ "R01 Q#{code}", "R02 Q#{code}" ] - {:params, %{param_int => value}, reply} - end - - defp handle_code("F21 P" <> params, state) do - # "F21 P12 Q89" - {rest, code} = split_by_q(params) - # "12 " - param_int = String.trim(rest) - value = (state.params[param_int] || "-1") |> String.trim - [ - "R01 Q#{code}", - "R21 P#{param_int} V#{value} Q#{code}", - "R02 Q#{code}" - ] - end - - defp handle_code("F20 Q" <> code, state) do - reply = Enum.map(state.params, fn({param, value}) -> - param_int = Farmbot.Serial.Gcode.Parser.parse_param(param) - "R21 P#{param_int} V#{value} Q#{code}" - end) - ["R01 Q#{code}"] ++ reply ++ ["R02 Q#{code}"] - end - - defp handle_code("G00 " <> params, _state) do - # G00 X123000 Y0 Z0 S800 QQ35 - {pos, code} = split_by_q(params) - [rpos | _] = String.split(pos, " S") - reply = [ - "R01 Q#{code}", - "R82 #{rpos} Q#{code}", - "R02 Q#{code}" - ] - {:position, rpos, reply} - end - - defp handle_code(code, _state) do - IO.warn "whoops!: #{inspect code}" - "!-!-!-ERROR-!-!-!" - end - - defp split_by_q(params) do - [params| [code]] = String.split(params, "Q") - {params, code} - end - - def common_setup do - {:ok, mock} = GcodeMockTest.start_link() - - # start a nerves genserver - {:ok, nerves} = UART.start_link() - {:ok, handler} = Handler.start_link(nerves, "/dev/tnt0") - - on_exit(fn() -> - if Process.alive?(mock) do - GenServer.stop(mock, :normal) - end - - if Process.alive?(handler) do - GenServer.stop(handler, :normal) - end - Process.sleep(500) - end) - - {:ok, mock: mock, handler: handler, handler_nerves: nerves} - end - -end diff --git a/test/serial/handler_test.exs b/test/serial/handler_test.exs index 805d4977..225c41a7 100644 --- a/test/serial/handler_test.exs +++ b/test/serial/handler_test.exs @@ -3,17 +3,28 @@ defmodule Farmbot.Serial.HandlerTest do alias Farmbot.Serial.Handler setup_all do - GcodeMockTest.common_setup() + wait_for_serial_available() + :ok end - test "checks serial availablity", %{handler: handler} do - bool = Handler.available?(handler) + test "checks serial availablity" do + bool = Handler.available? assert bool == true end - test "gets the state", %{handler: handler, handler_nerves: nerves} do - state = Handler.get_state(handler) - assert state.nerves == nerves - assert state.tty == "/dev/tnt0" + test "gets the state" do + state = Handler.get_state + assert is_pid(state.nerves) + assert state.tty == "/dev/tnt1" end + + def wait_for_serial_available do + case Process.whereis(Handler) do + nil -> + Process.sleep(10) + wait_for_serial_available() + _ -> Farmbot.CeleryScript.Command.home(%{axis: "all"}, []) + end + end + end diff --git a/test/test_helper.exs b/test/test_helper.exs index 56c47f53..87e7c335 100644 --- a/test/test_helper.exs +++ b/test/test_helper.exs @@ -1,4 +1,8 @@ ExUnit.start + +Mix.shell.info [:green, "Starting FarmbotSimulator"] +# :ok = Application.ensure_started(:farmbot_simulator) + Mix.shell.info [:green, "deleting config and secret"] File.rm_rf! "/tmp/config.json" File.rm_rf! "/tmp/secret"