From c17dad5598bbee6773b87d2fd3c3cb7625ba5048 Mon Sep 17 00:00:00 2001
From: Patrik Nyblom <pan@erlang.org>
Date: Thu, 20 Dec 2012 11:10:24 +0100
Subject: Add testcase for oct counters

---
 lib/kernel/test/gen_tcp_misc_SUITE.erl | 72 +++++++++++++++++++++++++++++++++-
 1 file changed, 71 insertions(+), 1 deletion(-)

diff --git a/lib/kernel/test/gen_tcp_misc_SUITE.erl b/lib/kernel/test/gen_tcp_misc_SUITE.erl
index 93dc2a69d1..a72e76f813 100644
--- a/lib/kernel/test/gen_tcp_misc_SUITE.erl
+++ b/lib/kernel/test/gen_tcp_misc_SUITE.erl
@@ -42,11 +42,12 @@
 	 killing_acceptor/1,killing_multi_acceptors/1,killing_multi_acceptors2/1,
 	 several_accepts_in_one_go/1, accept_system_limit/1,
 	 active_once_closed/1, send_timeout/1, send_timeout_active/1,
-	 otp_7731/1, zombie_sockets/1, otp_7816/1, otp_8102/1,
+	 otp_7731/1, zombie_sockets/1, otp_7816/1, otp_8102/1, wrapping_oct/1,
          otp_9389/1]).
 
 %% Internal exports.
 -export([sender/3, not_owner/1, passive_sockets_server/2, priority_server/1, 
+	 oct_acceptor/1,
 	 otp_7731_server/1, zombie_server/2, do_iter_max_socks/2]).
 
 init_per_testcase(_Func, Config) when is_list(Config) ->
@@ -75,6 +76,7 @@ all() ->
      killing_acceptor, killing_multi_acceptors,
      killing_multi_acceptors2, several_accepts_in_one_go, accept_system_limit,
      active_once_closed, send_timeout, send_timeout_active, otp_7731,
+     wrapping_oct,
      zombie_sockets, otp_7816, otp_8102, otp_9389].
 
 groups() -> 
@@ -2581,3 +2583,71 @@ otp_9389_loop(S, OrigLinkHdr, State) ->
         3000 ->
             ?line error({timeout,header})
     end.
+
+wrapping_oct(doc) ->
+    "Check that 64bit octet counters work."; 
+wrapping_oct(suite) ->
+    [];
+wrapping_oct(Config) when is_list(Config) ->
+    Dog = test_server:timetrap(test_server:seconds(600)),
+    {ok,Sock} = gen_tcp:listen(0,[{active,false},{mode,binary}]),
+    {ok,Port} = inet:port(Sock),
+    spawn_link(?MODULE,oct_acceptor,[Sock]),
+    Res = oct_datapump(Port,16#1FFFFFFFF),
+    gen_tcp:close(Sock),
+    test_server:timetrap_cancel(Dog),
+    ok = Res,
+    ok.
+
+oct_datapump(Port,N) ->
+    {ok,Sock} = gen_tcp:connect("localhost",Port,
+				[{active,false},{mode,binary}]),
+    oct_pump(Sock,N,binary:copy(<<$a:8>>,100000),0).
+
+oct_pump(S,N,_,_) when N =< 0 ->
+    gen_tcp:close(S),
+    ok;
+oct_pump(S,N,Bin,Last) ->
+    case gen_tcp:send(S,Bin) of
+	ok ->
+	    {ok,Stat}=inet:getstat(S),
+	    {_,R}=lists:keyfind(send_oct,1,Stat),
+	    case (R < Last) of
+		true ->
+		    io:format("ERROR (output) ~p < ~p~n",[R,Last]),
+		    output_counter_error;
+		false ->
+		    oct_pump(S,N-byte_size(Bin),Bin,R)
+	    end;
+	_ ->
+	    input_counter_error
+    end.
+    
+
+oct_acceptor(Sock) ->
+    {ok,Data} = gen_tcp:accept(Sock),
+    oct_aloop(Data,0,0).
+
+oct_aloop(S,X,Times) ->
+    case gen_tcp:recv(S,0) of
+	{ok,_} ->
+	    {ok,Stat}=inet:getstat(S),
+	    {_,R}=lists:keyfind(recv_oct,1,Stat),
+	    case (R < X) of
+		true ->
+		    io:format("ERROR ~p < ~p~n",[R,X]),
+		    gen_tcp:close(S),
+		    input_counter_error;
+		false ->
+		    case Times rem 16#FFFFF of
+			0 ->
+			    io:format("Read: ~p~n",[R]);
+			_ ->
+			    ok
+		    end,
+		    oct_aloop(S,R,Times+1)
+	    end;
+	_ ->
+	    gen_tcp:close(S),
+	    closed
+    end.
-- 
cgit v1.2.3