/lib/erl_interface/test/runner.erl

https://github.com/elaufis/otp · Erlang · 130 lines · 70 code · 21 blank · 39 comment · 0 complexity · 684eed18e374632ad91442d3c5313301 MD5 · raw file

  1. %%
  2. %% %CopyrightBegin%
  3. %%
  4. %% Copyright Ericsson AB 1997-2010. All Rights Reserved.
  5. %%
  6. %% The contents of this file are subject to the Erlang Public License,
  7. %% Version 1.1, (the "License"); you may not use this file except in
  8. %% compliance with the License. You should have received a copy of the
  9. %% Erlang Public License along with this software. If not, it can be
  10. %% retrieved online at http://www.erlang.org/.
  11. %%
  12. %% Software distributed under the License is distributed on an "AS IS"
  13. %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
  14. %% the License for the specific language governing rights and limitations
  15. %% under the License.
  16. %%
  17. %% %CopyrightEnd%
  18. %%
  19. %%
  20. -module(runner).
  21. -export([test/1, test/2,
  22. start/1, send_term/2, finish/1, send_eot/1, recv_eot/1,
  23. get_term/1, get_term/2]).
  24. -define(default_timeout, test_server:seconds(5)).
  25. %% Executes a test case in a C program.
  26. %%
  27. %% This function is useful for test cases written in C which requires
  28. %% no further input, and only returns a result by calling report().
  29. test(Tc) ->
  30. test(Tc, ?default_timeout).
  31. test(Tc, Timeout) ->
  32. Port = start(Tc),
  33. case get_term(Port, Timeout) of
  34. eot ->
  35. ok;
  36. Other ->
  37. io:format("In this test case, a success/failure result was"),
  38. io:format("expected from the C program.\n"),
  39. io:format("Received: ~p", [Other]),
  40. test_server:fail()
  41. end.
  42. %% Executes a test case in a C program. Returns the port.
  43. %%
  44. %% Use get_term/1,2.
  45. %%
  46. %% Returns: {ok, Port}
  47. start({Prog, Tc}) when is_list(Prog), is_integer(Tc) ->
  48. Port = open_port({spawn, Prog}, [{packet, 4}]),
  49. Command = [Tc div 256, Tc rem 256],
  50. Port ! {self(), {command, Command}},
  51. Port.
  52. %% Finishes a test case by send an 'eot' message to the C program
  53. %% and waiting for an 'eot'.
  54. %%
  55. %% If the C program doesn't require an 'eot', use recv_eot/1 instead.
  56. finish(Port) when is_port(Port) ->
  57. send_eot(Port),
  58. recv_eot(Port).
  59. %% Sends an Erlang term to a C program.
  60. send_term(Port, Term) when is_port(Port) ->
  61. Port ! {self(), {command, [$t, term_to_binary(Term)]}}.
  62. %% Sends an 'eot' (end-of-test) indication to a C progrm.
  63. send_eot(Port) when is_port(Port) ->
  64. Port ! {self(), {command, [$e]}}.
  65. %% Waits for an 'eot' indication from the C program.
  66. %% Either returns 'ok' or invokes test_server:fail().
  67. recv_eot(Port) when is_port(Port) ->
  68. case get_term(Port) of
  69. eot ->
  70. ok;
  71. Other ->
  72. io:format("Error finishing test case. Expected eof from"),
  73. io:format("C program, but got:"),
  74. io:format("~p", [Other]),
  75. test_server:fail()
  76. end.
  77. %% Reads a term from the C program.
  78. %%
  79. %% Returns: {term, Term}|eot|'NULL' or calls test_server:fail/1,2.
  80. get_term(Port) ->
  81. get_term(Port, ?default_timeout).
  82. get_term(Port, Timeout) ->
  83. case get_reply(Port, Timeout) of
  84. [$b|Bytes] ->
  85. {bytes, Bytes};
  86. [$f] ->
  87. test_server:fail();
  88. [$f|Reason] ->
  89. test_server:fail(Reason);
  90. [$t|Term] ->
  91. {term, binary_to_term(list_to_binary(Term))};
  92. [$N] ->
  93. 'NULL';
  94. [$e] ->
  95. eot;
  96. [$m|Message] ->
  97. io:format("~s", [Message]),
  98. get_term(Port, Timeout);
  99. Other ->
  100. io:format("Garbage received from C program: ~p", [Other]),
  101. test_server:fail("Illegal response from C program")
  102. end.
  103. get_reply(Port, Timeout) when is_port(Port) ->
  104. receive
  105. {Port, {data, Reply}} ->
  106. Reply
  107. after Timeout ->
  108. test_server:fail("No response from C program")
  109. end.