|
131 | 131 | end
|
132 | 132 |
|
133 | 133 | describe '#store_history_file' do
|
134 |
| - context 'when storing above max history lines' do |
135 |
| - def clear_readline |
136 |
| - ::Readline::HISTORY.pop until ::Readline::HISTORY.empty? |
137 |
| - end |
138 |
| - |
139 |
| - def clear_reline |
140 |
| - ::Reline::HISTORY.pop until ::Reline::HISTORY.empty? |
141 |
| - end |
| 134 | + let(:initial_history) { [] } |
| 135 | + let(:history_mock) { initial_history } |
| 136 | + let(:history_choices) { %w[sessions run query help] } |
| 137 | + let(:history_file) { ::Tempfile.new('history') } |
142 | 138 |
|
143 |
| - before(:each) do |
144 |
| - @history_file = ::Tempfile.new('history') |
145 |
| - |
146 |
| - # Store the current history & clear Readline && Reline |
147 |
| - @readline_history_before = ::Readline::HISTORY.to_a |
148 |
| - @reline_history_before = ::Reline::HISTORY.to_a |
| 139 | + after(:each) do |
| 140 | + # https://ruby-doc.org/stdlib-2.5.3/libdoc/tempfile/rdoc/Tempfile.html#class-Tempfile-label-Explicit+close |
| 141 | + history_file.unlink |
| 142 | + end |
149 | 143 |
|
150 |
| - clear_readline |
151 |
| - clear_reline |
152 |
| - end |
| 144 | + [ |
| 145 | + { history_size: described_class::MAX_HISTORY + 10, expected_size: described_class::MAX_HISTORY }, |
| 146 | + { history_size: described_class::MAX_HISTORY, expected_size: described_class::MAX_HISTORY }, |
| 147 | + { history_size: described_class::MAX_HISTORY - 10, expected_size: described_class::MAX_HISTORY - 10 }, |
| 148 | + ].each do |test| |
| 149 | + context "when storing #{test[:history_size]} lines" do |
| 150 | + it "correctly stores #{test[:expected_size]} lines" do |
| 151 | + allow(subject).to receive(:_remaining_work).and_call_original |
| 152 | + allow(subject).to receive(:store_history_file).and_call_original |
| 153 | + allow(subject).to receive(:map_library_to_history).and_return(history_mock) |
| 154 | + |
| 155 | + test[:history_size].times do |
| 156 | + # This imitates the user typing in a command and pressing the 'enter' key. |
| 157 | + history_mock << history_choices.sample |
| 158 | + end |
153 | 159 |
|
154 |
| - after(:each) do |
155 |
| - clear_readline |
156 |
| - @readline_history_before.each { |line| ::Readline::HISTORY << line } |
| 160 | + context = { input_library: :readline, history_file: history_file.path, name: 'history'} |
157 | 161 |
|
158 |
| - clear_reline |
159 |
| - @reline_history_before.each { |line| ::Reline::HISTORY << line } |
160 |
| - end |
| 162 | + subject.send(:store_history_file, context) |
161 | 163 |
|
162 |
| - it 'truncates to max allowed history' do |
163 |
| - allow(subject).to receive(:_remaining_work).and_call_original |
164 |
| - allow(subject).to receive(:store_history_file).and_call_original |
| 164 | + sleep(0.1) until subject._remaining_work.empty? |
165 | 165 |
|
166 |
| - history_choices = %w[sessions run query help] |
167 |
| - max_history = subject.class::MAX_HISTORY |
168 |
| - # Populate example history we want to store |
169 |
| - total_times = max_history + 10 |
170 |
| - total_times.times do |
171 |
| - ::Readline::HISTORY << history_choices[rand(history_choices.count)] |
| 166 | + expect(history_file.read.split("\n").count).to eq(test[:expected_size]) |
172 | 167 | end
|
173 |
| - |
174 |
| - context = { input_library: :readline, history_file: @history_file.path, name: 'history'} |
175 |
| - |
176 |
| - subject.send(:store_history_file, context) |
177 |
| - |
178 |
| - sleep(0.1) until subject._remaining_work.empty? |
179 |
| - |
180 |
| - expect(@history_file.read.split("\n").count).to eq(max_history) |
181 | 168 | end
|
182 | 169 | end
|
183 | 170 | end
|
184 | 171 |
|
185 | 172 | describe '#load_history_file' do
|
186 |
| - def clear_readline |
187 |
| - ::Readline::HISTORY.pop until ::Readline::HISTORY.empty? |
188 |
| - end |
189 |
| - |
190 |
| - def clear_reline |
191 |
| - ::Reline::HISTORY.pop until ::Reline::HISTORY.empty? |
192 |
| - end |
193 |
| - |
194 |
| - before(:each) do |
195 |
| - @history_file = ::Tempfile.new('history') |
196 |
| - |
197 |
| - # Store the current history & clear Readline && Reline |
198 |
| - @readline_history_before = ::Readline::HISTORY.to_a |
199 |
| - @reline_history_before = ::Reline::HISTORY.to_a |
200 |
| - |
201 |
| - clear_readline |
202 |
| - clear_reline |
203 |
| - end |
| 173 | + let(:initial_history) { [] } |
| 174 | + let(:history_mock) { initial_history } |
| 175 | + let(:history_choices) { %w[sessions run query help] } |
| 176 | + let(:history_file) { ::Tempfile.new('history') } |
204 | 177 |
|
205 | 178 | after(:each) do
|
206 |
| - clear_readline |
207 |
| - @readline_history_before.each { |line| ::Readline::HISTORY << line } |
208 |
| - |
209 |
| - clear_reline |
210 |
| - @reline_history_before.each { |line| ::Reline::HISTORY << line } |
| 179 | + history_file.unlink |
211 | 180 | end
|
212 | 181 |
|
213 | 182 | context 'when history file is not accessible' do
|
214 | 183 | it 'the library history remains unchanged' do
|
| 184 | + allow(subject).to receive(:map_library_to_history).and_return(history_mock) |
215 | 185 | history_file = ::File.join('does/not/exist/history')
|
216 | 186 | context = { input_library: :readline, history_file: history_file, name: 'history' }
|
217 | 187 |
|
218 | 188 | subject.send(:load_history_file, context)
|
219 |
| - expect(::Readline::HISTORY.to_a).to eq(@readline_history_before) |
| 189 | + expect(history_mock).to eq(initial_history) |
220 | 190 | end
|
221 | 191 | end
|
222 | 192 |
|
223 | 193 | context 'when history file is accessible' do
|
224 | 194 | it 'correctly loads the history' do
|
225 |
| - history_file = ::File.join(Msf::Config.history_file) |
226 |
| - history_lines = ::File.read(history_file).split("\n") |
| 195 | + allow(subject).to receive(:map_library_to_history).and_return(history_mock) |
227 | 196 |
|
228 |
| - context = { input_library: :readline, history_file: history_file, name: 'history' } |
| 197 | + # Populate our own history file with random entries. |
| 198 | + # Using this allows us to not have to worry about history files present/not present on disk. |
| 199 | + new_history = [] |
| 200 | + 50.times do |
| 201 | + new_history << history_choices.sample |
| 202 | + end |
| 203 | + history_file.puts new_history |
| 204 | + history_file.rewind |
| 205 | + |
| 206 | + context = { input_library: :readline, history_file: history_file.path, name: 'history' } |
229 | 207 |
|
230 | 208 | subject.send(:load_history_file, context)
|
231 | 209 |
|
232 |
| - expect(::Readline::HISTORY.to_a).to eq(history_lines) |
| 210 | + expect(history_mock).to eq(new_history) |
233 | 211 | end
|
234 | 212 | end
|
235 | 213 | end
|
|
0 commit comments