require File.dirname(__FILE__) + '/test_helper.rb'

class TestEvdispatch < Test::Unit::TestCase
  def setup
    TestServer.setup
  end

  def test_streaming
    d = Evdispatch::Loop.new
    d.start

    count = 10000

    streams = []
    # create 10 streams
    10.times do|i|
      stream = d.request("http://127.0.0.1:4044/bytes/#{count}", :stream => true )
      streams << stream
    end

    # TODO: we should expose the pipe so someone can select on ready responses
    for stream in streams do
      res = stream.read
      timer = Time.now
      diff = Time.now - timer
      while res != 0 and diff < 4.0
        res = stream.read
        diff = Time.now - timer
        #puts "diff: #{diff}"
      end

      next if diff >= 4.0

      assert_equal( 0, res )
      assert_equal( "C"*count, stream.body )
      headers = stream.headers
      assert_match( "Content-Length: 10000", headers )
      assert_match( "Content-Type: text/json", headers )
      assert_match( "HTTP/1.1 200 OK", headers )
    end

    d.stop
  end

  def test_object_allocation
    d = Evdispatch::Loop.new

    # start the event loop thread
    d.start

    # increase this to verify
    1.times do

      begin

        ObjectSpace.garbage_collect

        10.times do
          begin
            start_count = ObjectSpace.each_object { }
            duration =  run_trial(d, 100)
            new_count = ObjectSpace.each_object { }
            puts "10 trials: #{duration} seconds, new objects #{new_count - start_count}, #{new_count} - #{start_count}"
          end

          begin
            start_count = ObjectSpace.each_object { }
            duration = run_trial(d, 200)
            new_count = ObjectSpace.each_object { }
            puts "100 trials: #{duration} seconds, new objects #{new_count - start_count}, #{new_count} - #{start_count}"
          end

        end

      rescue => e
        puts e.message, e.backtrace
      end

    end

    count = ObjectSpace.each_object { }
    puts "Final Total objects: #{count}"
    count = nil
    ObjectSpace.garbage_collect
    count = ObjectSpace.each_object { }
    puts "After garbage collection objects: #{count}"
 
    # sometime later you can stop the event loop
    d.stop
  end

  def request_bytes_from( d, base, amount, range )
    ids = []
    amount.times do|i|
      am = rand( range )
      ids << d.request_http( base + "bytes/#{am}/" )
    end
    ids
  end

  def request_delay_from( d, base, amount, delay )
    ids = []
    amount.times do|i|
      am = rand( delay )
      ids << d.request_http( base + "delay/#{delay}/" )
    end
    ids
  end

  def run_trial( d, trials )

    ebbbase = "http://127.0.0.1:4044/"
    timer = Time.now
    ids = request_bytes_from( d, ebbbase, trials, 1000 )
    #ids += request_delay_from( d, ebbbase, trials, 1 )

    # wait for each response
    puts "expecting #{ids.size} responses..."
    ids.each do|id|
      response = d.response( id )
      #puts response[:name]
    end

    duration = Time.now - timer


    duration
  end
end