summaryrefslogtreecommitdiff
path: root/test/common.rb
blob: e6a69bf81ea48b527819ec97c797807d59d8fec5 (plain)
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
$LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../lib"

if ENV["CI"]
  unless Gem.win_platform?
    require 'simplecov'
    SimpleCov.start

    #    require 'codecov'
    #    SimpleCov.formatter = SimpleCov::Formatter::Codecov
  end
end

require 'minitest'
require 'mocha/minitest'
require 'net/ssh/buffer'
require 'net/ssh/config'
require 'net/ssh/loggable'
require 'net/ssh/packet'
require 'net/ssh/transport/session'
require 'ostruct'

require 'minitest/autorun'

# clear the default files out so that tests don't get confused by existing
# SSH config files.
$_original_config_default_files = Net::SSH::Config.default_files.dup # rubocop:disable Style/GlobalVars
Net::SSH::Config.default_files.clear

# Ensures SSH_AUTH_SOCK set outside of test scenario (e.g. on dev's machine) isn't messing up test assertions
original_ssh_auth_sock, ENV['SSH_AUTH_SOCK'] = ENV['SSH_AUTH_SOCK'], nil
Minitest.after_run { ENV['SSH_AUTH_SOCK'] = original_ssh_auth_sock }

def with_restored_default_files(&block)
  act_default_files = Net::SSH::Config.default_files.dup
  begin
    Net::SSH::Config.default_files.clear
    Net::SSH::Config.default_files.concat($_original_config_default_files) # rubocop:disable Style/GlobalVars
    yield
  ensure
    Net::SSH::Config.default_files.clear
    Net::SSH::Config.default_files.concat(act_default_files)
  end
end

def P(*args)
  Net::SSH::Packet.new(Net::SSH::Buffer.from(*args))
end

class NetSSHTest < Minitest::Test
  def assert_nothing_raised(&block)
    yield
  end

  def assert_not_nil(obj, msg = nil)
    refute_nil obj, msg
  end
end

class MockPrompt
  def start(info)
    @info = info
    self
  end

  def ask(message, echo)
    _ask(message, @info, echo)
  end

  def success; end
end

class MockTransport < Net::SSH::Transport::Session
  class BlockVerifier
    def initialize(block)
      @block = block
    end

    def verify(data)
      @block.call(data)
    end

    def verify_signature(&block)
      yield
    end
  end

  attr_reader :host_key_verifier
  attr_accessor :host_as_string
  attr_accessor :server_version

  attr_reader :client_options
  attr_reader :server_options
  attr_reader :hints, :queue

  attr_accessor :mock_enqueue

  def initialize(options = {})
    @options = options
    self.logger = options[:logger]
    self.host_as_string = "net.ssh.test,127.0.0.1"
    self.server_version = OpenStruct.new(version: "SSH-2.0-Ruby/Net::SSH::Test")
    @expectations = []
    @queue = []
    @hints = {}
    @socket = options[:socket]
    @algorithms = OpenStruct.new(session_id: "abcxyz123")
    verifier { |_data| true }
  end

  def send_message(message)
    buffer = Net::SSH::Buffer.new(message.to_s)
    if @expectations.empty?
      raise "got #{message.to_s.inspect} but was not expecting anything"
    else
      block = @expectations.shift
      block.call(self, Net::SSH::Packet.new(buffer))
    end
  end

  def enqueue_message(message)
    if mock_enqueue
      send_message(message)
    else
      super
    end
  end

  def closed?
    false
  end

  def poll_message
    @queue.shift
  end

  def next_message
    @queue.shift or raise "expected a message from the server but nothing was ready to send"
  end

  def return(type, *args)
    @queue << P(:byte, type, *args)
  end

  def expect(&block)
    @expectations << block
  end

  def expect!
    expect {}
  end

  def verifier(&block)
    @host_key_verifier = BlockVerifier.new(block)
  end

  def configure_client(options)
    @client_options = options
  end

  def configure_server(options)
    @server_options = options
  end

  def hint(name, value = true)
    @hints[name] = value
  end
end