File: fake_wire_server.rb

package info (click to toggle)
ruby-cucumber-wire 0.0.1-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, buster, forky, sid, trixie
  • size: 224 kB
  • sloc: ruby: 754; makefile: 3
file content (80 lines) | stat: -rw-r--r-- 1,890 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
require 'multi_json'
require 'socket'

class FakeWireServer
  def initialize(port, protocol_table)
    @port, @protocol_table = port, protocol_table
    @delays = {}
  end

  def run(io)
    @server = TCPServer.open(@port)
    loop { handle_connections(io) }
  end

  def delay_response(message, delay)
    @delays[message] = delay
  end

  private

  def handle_connections(io)
    Thread.start(@server.accept) { |socket| open_session_on socket, io }
  end

  def open_session_on(socket, io)
    begin
      on_message = lambda { |message| io.puts message }
      SocketSession.new(socket, @protocol_table, @delays, on_message).start
    rescue Exception => e
      raise e
    ensure
      socket.close
    end
  end

  class SocketSession
    def initialize(socket, protocol, delays, on_message)
      @socket = socket
      @protocol = protocol
      @delays = delays
      @on_message = on_message
    end

    def start
      while message = @socket.gets
        handle(message)
      end
    end

    private

    def handle(data)
      if protocol_entry = response_to(data.strip)
        sleep delay(data)
        @on_message.call(MultiJson.load(protocol_entry['request'])[0])
        send_response(protocol_entry['response'])
      else
        serialized_exception = { :message => "Not understood: #{data}", :backtrace => [] }
        send_response(['fail', serialized_exception ].to_json)
      end
    rescue => e
      send_response(['fail', { :message => e.message, :backtrace => e.backtrace, :exception => e.class } ].to_json)
    end

    def response_to(data)
      @protocol.detect do |entry|
        MultiJson.load(entry['request']) == MultiJson.load(data)
      end
    end

    def send_response(response)
      @socket.puts response + "\n"
    end

    def delay(data)
      message = MultiJson.load(data.strip)[0]
      @delays[message.to_sym] || 0
    end
  end
end