Class: RightDevelop::Testing::Client::Rest::Request::Playback

Inherits:
Base
  • Object
show all
Defined in:
lib/right_develop/testing/clients/rest/requests/playback.rb

Overview

Provides a middle-ware layer that intercepts transmition of the request and escapes out of the execute call with a stubbed response using throw/catch.

Defined Under Namespace

Classes: FakeNetHttpResponse, PeerResetConnectionError

Constant Summary collapse

HALT_TRANSMIT =
:halt_transmit
PLAYBACK_ERROR =

exceptions

::RightDevelop::Testing::Recording::Metadata::PlaybackError
RETRY_DELAY =
0.5
MAX_RETRIES =

50 seconds; a socket usually times out in 60-120 seconds

100

Constants inherited from Base

Base::METADATA_CLASS, Base::MUTEX

Instance Attribute Summary collapse

Attributes inherited from Base

#fixtures_dir, #logger, #request_metadata, #request_timestamp, #response_metadata, #response_timestamp, #route_data, #route_path, #state_file_path

Instance Method Summary collapse

Methods inherited from Base

#forget_outstanding_request, #log_response

Constructor Details

#initialize(args) ⇒ Playback

Returns a new instance of Playback.



69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/right_develop/testing/clients/rest/requests/playback.rb', line 69

def initialize(args)
  if args[:throttle]
    args = args.dup
    @throttle = Integer(args.delete(:throttle))
    if @throttle < 0 || @throttle > 100
      raise ::ArgumentError, 'throttle must be a percentage between 0 and 100'
    end
  else
    @throttle = 0
  end
  super(args)
end

Instance Attribute Details

#throttleObject (readonly)

Returns the value of attribute throttle.



67
68
69
# File 'lib/right_develop/testing/clients/rest/requests/playback.rb', line 67

def throttle
  @throttle
end

Instance Method Details

#handle_timeoutObject

Raises:

  • (::NotImplementedError)

See Also:

  • Base.handle_timeout


152
153
154
# File 'lib/right_develop/testing/clients/rest/requests/playback.rb', line 152

def handle_timeout
  raise ::NotImplementedError, 'Timeout is unexpected for stubbed API call.'
end

#log_requestObject

Overrides log_request to interrupt transmit before any connection is made.

Raises:

  • (Symbol)

    always throws HALT_TRANSMIT



85
86
87
88
# File 'lib/right_develop/testing/clients/rest/requests/playback.rb', line 85

def log_request
  super
  throw(HALT_TRANSMIT, HALT_TRANSMIT)
end

#transmit(uri, req, payload, &block) ⇒ Object

Overrides transmit to catch halt thrown by log_request.

Parameters:

  • URI[ (URI[ uri of some kind)

    uri of some kind

  • req (Net::HTTP)

    of some kind

  • of (RestClient::Payload)

    some kind

Returns:



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/right_develop/testing/clients/rest/requests/playback.rb', line 100

def transmit(uri, req, payload, &block)
  caught = catch(HALT_TRANSMIT) { super }
  if caught == HALT_TRANSMIT
    response = nil
    try_counter = 0
    while response.nil?
      with_state_lock do |state|
        response = catch(METADATA_CLASS::HALT) do
          fetch_response(state)
        end
      end
      case response
      when METADATA_CLASS::RetryableFailure
        try_counter += 1
        if try_counter >= MAX_RETRIES
          message =
            "Released thread id=#{::Thread.current.object_id} after " <<
            "#{try_counter} attempts to satisfy a retryable condition:\n" <<
            response.message
          raise PLAYBACK_ERROR, message
        end
        if 1 == try_counter
          message = "Blocking thread id=#{::Thread.current.object_id} " <<
                    'until a retryable condition is satisfied...'
          logger.debug(message)
        end
        response = nil
        sleep RETRY_DELAY
      else
        if try_counter > 0
          message = "Released thread id=#{::Thread.current.object_id} " <<
                    'after a retryable condition was satisfied.'
          logger.debug(message)
        end
      end
    end

    # delay, if throttled, to simulate server response time.
    if @throttle > 0 && response.elapsed_seconds > 0
      delay = (Float(response.elapsed_seconds) * @throttle) / 100.0
      logger.debug("throttle delay = #{delay}")
      sleep delay
    end
    log_response(response)
    process_result(response, &block)
  else
    raise PLAYBACK_ERROR,
          'Unexpected RestClient::Request#transmit returned without calling RestClient::Request#log_request'
  end
end