Skip to content

Commit

Permalink
simple escript that starts a release and performs tests (#712)
Browse files Browse the repository at this point in the history
* simple escript that starts a release and performs tests

* run tests against the release in CI
  • Loading branch information
Ino Murko authored Dec 10, 2018
1 parent 5a2f3f6 commit 8d059dd
Show file tree
Hide file tree
Showing 9 changed files with 171 additions and 1 deletion.
7 changes: 7 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ jobs:
- ethereum_common_tests
- rel
- MANA_VERSION
- priv

test:
docker:
Expand Down Expand Up @@ -382,6 +383,12 @@ jobs:
command: |
find -name 'mana.tar.gz' -exec sh -c 'mkdir -p ci_artifact && cp "$@" ci_artifact/ci_artifact_mana.tar.gz' _ {} +
when: always
- run:
name: Build and run tests
command: |
cd priv/itest/
mix escript.build
./itest
- store_artifacts:
name: Uploading CI artifacts
Expand Down
3 changes: 2 additions & 1 deletion .formatter.exs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"apps/*/mix.exs",
"rel/config.exs",
"config/*",
"mix.exs"
"mix.exs",
"priv/itest/*.{ex,exs}"
]
]
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,7 @@ apps/blockchain/config/dev.secret.exs

!/**/.gitkeep
/log/*
#release testing tool
/priv/itest/_build
/priv/itest/_build/itest
/priv/itest/itest
3 changes: 3 additions & 0 deletions priv/itest/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Build with `mix escript.build`.
Run: ./itest
Make sure you've built a release first with `mix release` in root project path.
24 changes: 24 additions & 0 deletions priv/itest/mix.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
defmodule Itest.MixProject do
use Mix.Project

def project do
[
app: :itest,
version: "0.1.0",
elixirc_options: [warnings_as_errors: true],
elixir: "~> 1.7.4",
escript: escript(),
elixirc_paths: ["release.ex", "websocket_test.ex", "starter.ex"],
deps: deps()
]
end

def escript() do
[main_module: Release]
end

# Run "mix help deps" to learn about dependencies.
defp deps do
[]
end
end
3 changes: 3 additions & 0 deletions priv/itest/mix.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
%{

}
60 changes: 60 additions & 0 deletions priv/itest/release.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
defmodule Release do
@moduledoc """
Finds the release tarball, extracts, and applies all tests.
"""
def main(_) do
# a list of test modules (We could discover them by test postfix in module name)
tests = [
WebsocketTest.tests()
]

untar_and_start()
|> find_and_extract_release()
|> do_test(tests)
end

defp untar_and_start() do
dir = Path.join(System.cwd(), "/../../")
path = recursive_search(dir, "mana.tar.gz")
path
end

defp find_and_extract_release(path) do
untar_path = '/tmp/mana/'
:ok = :erl_tar.extract(String.to_charlist(path), [{:cwd, untar_path}, :compressed])
recursive_search(untar_path, "mana")
end

defp do_test(_, []), do: :ok

defp do_test(start_path, [h | t]) do
[start_flags, tests] = h
GenServer.start(Starter, [start_path, start_flags.()])
Enum.each(tests, fn test -> test.() end)
GenServer.stop(Starter)
do_test(start_path, t)
end

defp recursive_search(dir, find_file) do
try do
do_recursive_search(dir, find_file)
catch
:throw, payload ->
payload
end
end

defp do_recursive_search(dir, find_file) do
Enum.find(
File.ls!(dir),
fn
^find_file ->
throw(Path.join([dir, find_file]))

file ->
fname = "#{dir}/#{file}"
if File.dir?(fname), do: do_recursive_search(fname, find_file)
end
)
end
end
52 changes: 52 additions & 0 deletions priv/itest/starter.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
defmodule Starter do
@moduledoc """
A server that starts a release with specified arguments.
"""
use GenServer

def start(path, arguments) do
GenServer.start_link(__MODULE__, [path, arguments], name: __MODULE__)
end

def init([path, arguments]) do
port =
:erlang.open_port({:spawn_executable, String.to_charlist(path)}, [
:exit_status,
:binary,
:hide,
{:args, arguments}
])

Process.flag(:trap_exit, true)
true = Process.register(self(), __MODULE__)
{:ok, Port.info(port)}
end

def handle_info({_port, {:data, _data}}, state) do
{:noreply, state}
end

def handle_info({_port, {:exit_status, 143}}, state) do
{:stop, :normal, state}
end

def handle_info({_port, {:exit_status, 129}}, state) do
# "outside HUP kill"
{:stop, :normal, state}
end

def handle_info({_port, {:exit_status, 137}}, state) do
# "outside -9 kill"
{:stop, :normal, state}
end

def handle_info({_port, {:exit_status, 1}}, state) do
{:stop, :normal, state}
end

def terminate(_, state) do
# cleanup by killing the
os_pid = Keyword.get(state, :os_pid)
:os.cmd('pkill -15 -g #{os_pid}')
end
end
16 changes: 16 additions & 0 deletions priv/itest/websocket_test.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
defmodule WebsocketTest do
@moduledoc """
Expose at least two functions.
1. Flags -> flags with which you would like to kick off the release
2. A list of tests you want to perform on the running release.
"""
def tests() do
[&flags/0, [&invoke_test/0]]
end

defp flags(), do: ['run']

defp invoke_test() do
IO.puts("Invoked test!")
end
end

0 comments on commit 8d059dd

Please sign in to comment.