Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/spec/lib/msf/debug_spec.rb
Views: 11655
require 'spec_helper'12RSpec.describe Msf::Ui::Debug do3let(:file_fixtures_path) { File.join(Msf::Config.install_root, 'spec', 'file_fixtures') }4let(:features) do5[6{7name: 'filtered_options',8description: 'Add option filtering functionality to Metasploit',9enabled: false10},11{12name: 'new_search_capabilities',13description: 'Add new search capabilities to Metasploit',14enabled: true15}16]17end1819it 'error parsing correctly parses framework.log and msf-ws.log' do20allow(::Msf::Config).to receive(:log_directory).and_return(Pathname.new(file_fixtures_path).join('debug', 'error_logs', 'basic'))2122error_log_output = <<~LOG23## %grnFramework Errors%clr2425The following framework errors occurred before the issue occurred:26<details>27<summary>Collapse</summary>2829```30[00/00/0000 00:00:00] [e(0)] core: [-] Error 13132[11/11/1111 11:11:11] [e(0)] core: [-] Error 233Call stack:34Stack_Trace35stack trace36STACK-TRACE3738[22/22/2222 22:22:22] [e(0)] core: [-] Error 339```4041</details>424344## %grnWeb Service Errors%clr4546The following web service errors occurred before the issue occurred:47<details>48<summary>Collapse</summary>4950```51[-] Error 15253[-] Error 254[-] Error 355```5657</details>585960LOG6162expect(subject.errors).to eql(error_log_output)63end6465it 'error parsing correctly parses log files larger than the log line total' do66allow(::Msf::Config).to receive(:log_directory).and_return(File.join(file_fixtures_path, 'debug', 'error_logs', 'long'))6768logs = ''69digits = 11..207071digits.each do |d|72logs += "[00/00/0000 00:00:00] [e(0)] core: [-] Error #{d}\n\n"73end7475error_log_output = <<~LOG76## %grnFramework Errors%clr7778The following framework errors occurred before the issue occurred:79<details>80<summary>Collapse</summary>8182```83[00/00/0000 00:00:00] [e(0)] core: [-] Error 118485[00/00/0000 00:00:00] [e(0)] core: [-] Error 128687[00/00/0000 00:00:00] [e(0)] core: [-] Error 138889[00/00/0000 00:00:00] [e(0)] core: [-] Error 149091[00/00/0000 00:00:00] [e(0)] core: [-] Error 159293[00/00/0000 00:00:00] [e(0)] core: [-] Error 169495[00/00/0000 00:00:00] [e(0)] core: [-] Error 179697[00/00/0000 00:00:00] [e(0)] core: [-] Error 189899[00/00/0000 00:00:00] [e(0)] core: [-] Error 19100101[00/00/0000 00:00:00] [e(0)] core: [-] Error 20102```103104</details>105106107## %grnWeb Service Errors%clr108109The following web service errors occurred before the issue occurred:110<details>111<summary>Collapse</summary>112113```114[-] Error 11115116[-] Error 12117118[-] Error 13119120[-] Error 14121122[-] Error 15123124[-] Error 16125126[-] Error 17127128[-] Error 18129130[-] Error 19131132[-] Error 20133```134135</details>136137138LOG139140expect(subject.errors).to eql(error_log_output)141end142143it 'error parsing correctly parses empty log files' do144allow(::Msf::Config).to receive(:log_directory).and_return(File.join(file_fixtures_path, 'debug', 'error_logs', 'empty'))145146error_log_output = <<~EMPTY147## %grnFramework Errors%clr148149The following framework errors occurred before the issue occurred:150<details>151<summary>Collapse</summary>152153```154No matching patterns were found in framework.log.155```156157</details>158159160## %grnWeb Service Errors%clr161162The following web service errors occurred before the issue occurred:163<details>164<summary>Collapse</summary>165166```167No matching patterns were found in msf-ws.log.168```169170</details>171172173EMPTY174175expect(subject.errors).to eql(error_log_output)176end177178it 'error parsing correctly returns a missing log file message' do179allow(::Msf::Config).to receive(:log_directory).and_return('FAKE_PATH')180181error_log_output = <<~EMPTY182## %grnFramework Errors%clr183184The following framework errors occurred before the issue occurred:185<details>186<summary>Collapse</summary>187188```189framework.log does not exist.190```191192</details>193194195## %grnWeb Service Errors%clr196197The following web service errors occurred before the issue occurred:198<details>199<summary>Collapse</summary>200201```202msf-ws.log does not exist.203```204205</details>206207208EMPTY209210expect(subject.errors).to eql(error_log_output)211end212213it 'correctly retrieves and parses a command history shorter than the command total' do214stub_const('Readline::HISTORY', Array.new(4) { |i| "Command #{i + 1}" })215216driver = instance_double(217Msf::Ui::Console::Driver,218hist_last_saved: 0219)220221stub_const('Msf::Ui::Debug::COMMAND_HISTORY_TOTAL', 10)222223history_output = <<~E_LOG224## %grnHistory%clr225226The following commands were ran during the session and before this issue occurred:227<details>228<summary>Collapse</summary>229230```2310 Command 12321 Command 22332 Command 32343 Command 4235```236237</details>238239240E_LOG241242expect(subject.history(driver)).to eql(history_output)243end244245it 'correctly retrieves and parses a command history equal in length to the command total' do246driver = instance_double(247::Msf::Ui::Console::Driver,248hist_last_saved: 0249)250251stub_const('Msf::Ui::Debug::COMMAND_HISTORY_TOTAL', 10)252253stub_const('Readline::HISTORY', Array.new(10) { |i| "Command #{i + 1}" })254255history_output = <<~E_LOG256## %grnHistory%clr257258The following commands were ran during the session and before this issue occurred:259<details>260<summary>Collapse</summary>261262```2630 Command 12641 Command 22652 Command 32663 Command 42674 Command 52685 Command 62696 Command 72707 Command 82718 Command 92729 Command 10273```274275</details>276277278E_LOG279280expect(subject.history(driver)).to eql(history_output)281end282283it 'correctly retrieves and parses a command history larger than the command total' do284driver = instance_double(285::Msf::Ui::Console::Driver,286hist_last_saved: 0287)288289stub_const('Msf::Ui::Debug::COMMAND_HISTORY_TOTAL', 10)290stub_const('Readline::HISTORY', Array.new(15) { |i| "Command #{i + 1}" })291292history_output = <<~E_LOG293## %grnHistory%clr294295The following commands were ran during the session and before this issue occurred:296<details>297<summary>Collapse</summary>298299```3005 Command 63016 Command 73027 Command 83038 Command 93049 Command 1030510 Command 1130611 Command 1230712 Command 1330813 Command 1430914 Command 15310```311312</details>313314315E_LOG316317expect(subject.history(driver)).to eql(history_output)318end319320it 'correctly retrieves and parses a command history larger than the command total and a session command count smaller than the command total' do321driver = instance_double(322::Msf::Ui::Console::Driver,323hist_last_saved: 10324)325326stub_const('Msf::Ui::Debug::COMMAND_HISTORY_TOTAL', 10)327stub_const('Readline::HISTORY', Array.new(15) { |i| "Command #{i + 1}" })328329history_output = <<~E_LOG330## %grnHistory%clr331332The following commands were ran during the session and before this issue occurred:333<details>334<summary>Collapse</summary>335336```33710 Command 1133811 Command 1233912 Command 1334013 Command 1434114 Command 15342```343344</details>345346347E_LOG348349expect(subject.history(driver)).to eql(history_output)350end351352it 'correctly retrieves and parses an empty config file and datastore' do353allow(::Msf::Config).to receive(:config_file).and_return(File.join(file_fixtures_path, 'config_files', 'empty.ini'))354355framework = instance_double(356::Msf::Framework,357datastore: Msf::DataStore.new358)359360driver = instance_double(361::Msf::Ui::Console::Driver,362get_config_core: 'config_core',363get_config: {},364get_config_group: 'config_group',365active_module: nil366)367368expected_output = <<~OUTPUT369## %grnModule/Datastore%clr370371The following global/module datastore, and database setup was configured before the issue occurred:372<details>373<summary>Collapse</summary>374375```376The local config file is empty, no global variables are set, and there is no active module.377```378379</details>380381382OUTPUT383384expect(subject.datastore(framework, driver)).to eql(expected_output)385end386387it 'correctly retrieves and parses a populated global datastore' do388allow(::Msf::Config).to receive(:config_file).and_return(File.join(file_fixtures_path, 'config_files', 'empty.ini'))389390framework_datastore = Msf::DataStore.new391framework_datastore.merge!(392{393'key1' => 'val1',394'key2' => 'val2',395'key3' => 'val3'396}397)398framework = instance_double(399::Msf::Framework,400datastore: framework_datastore401)402403driver = instance_double(404::Msf::Ui::Console::Driver,405get_config_core: 'group/name/1',406get_config: {},407get_config_group: 'config_group',408active_module: nil409)410411expected_output = <<~OUTPUT412## %grnModule/Datastore%clr413414The following global/module datastore, and database setup was configured before the issue occurred:415<details>416<summary>Collapse</summary>417418```419[group/name/1]420key1=val1421key2=val2422key3=val3423```424425</details>426427428OUTPUT429430expect(subject.datastore(framework, driver)).to eql(expected_output)431end432433it 'correctly retrieves and parses a populated global datastore and current module' do434allow(::Msf::Config).to receive(:config_file).and_return(File.join(file_fixtures_path, 'config_files', 'empty.ini'))435436datastore = Msf::DataStore.new437datastore.merge!(438{439'key1' => 'val1',440'key2' => 'val2',441'key3' => 'val3'442}443)444framework = instance_double(445::Msf::Framework,446datastore: datastore447)448449driver = instance_double(450::Msf::Ui::Console::Driver,451get_config_core: 'group/name/1',452get_config: {453'key4' => 'val4',454'key5' => 'val5',455'key6' => 'val6'456},457get_config_group: 'group/name/2',458active_module: nil459)460461expected_output = <<~OUTPUT462## %grnModule/Datastore%clr463464The following global/module datastore, and database setup was configured before the issue occurred:465<details>466<summary>Collapse</summary>467468```469[group/name/1]470key1=val1471key2=val2472key3=val3473474[group/name/2]475key4=val4476key5=val5477key6=val6478```479480</details>481482483OUTPUT484485expect(subject.datastore(framework, driver)).to eql(expected_output)486end487488it 'correctly retrieves and parses active module variables' do489allow(::Msf::Config).to receive(:config_file).and_return(File.join(file_fixtures_path, 'config_files', 'empty.ini'))490491framework_datastore = Msf::DataStore.new492framework = instance_double(493::Msf::Framework,494datastore: framework_datastore495)496497module_datastore = Msf::ModuleDataStore.new(framework_datastore)498module_datastore.merge!(499{500'key7' => 'val7',501'key8' => 'default_val8',502'key9' => 'val9'503}504)505active_module = instance_double(506Msf::Module,507datastore: module_datastore,508refname: 'active/module/variables'509)510511driver = instance_double(512::Msf::Ui::Console::Driver,513get_config_core: 'group/name/1',514get_config: {},515get_config_group: 'config_group',516active_module: active_module517)518519expected_output = <<~OUTPUT520## %grnModule/Datastore%clr521522The following global/module datastore, and database setup was configured before the issue occurred:523<details>524<summary>Collapse</summary>525526```527[active/module/variables]528key7=val7529key8=default_val8530key9=val9531```532533</details>534535536OUTPUT537538expect(subject.datastore(framework, driver)).to eql(expected_output)539end540541it 'preferences the framework datastore values over config stored values' do542allow(::Msf::Config).to receive(:config_file).and_return(File.join(file_fixtures_path, 'config_files', 'module.ini'))543544framework_datastore = Msf::DataStore.new545framework_datastore.merge!(546{547'key1' => 'val1',548'key2' => 'val2',549'key3' => 'val3'550}551)552framework = instance_double(553::Msf::Framework,554datastore: framework_datastore555)556557driver = instance_double(558::Msf::Ui::Console::Driver,559get_config_core: 'group/name/1',560get_config: {561'key4' => 'val4',562'key5' => 'val5',563'key6' => 'val6'564},565get_config_group: 'group/name/2',566active_module: nil567)568569expected_output = <<~OUTPUT570## %grnModule/Datastore%clr571572The following global/module datastore, and database setup was configured before the issue occurred:573<details>574<summary>Collapse</summary>575576```577[group/name/1]578key1=val1579key2=val2580key3=val3581582[group/name/2]583key4=val4584key5=val5585key6=val6586```587588</details>589590591OUTPUT592593expect(subject.datastore(framework, driver)).to eql(expected_output)594end595596it 'correctly retrieves and parses Database information' do597allow(::Msf::Config).to receive(:config_file).and_return(File.join(file_fixtures_path, 'config_files', 'db.ini'))598599framework_datastore = Msf::DataStore.new600framework = instance_double(601::Msf::Framework,602datastore: framework_datastore603)604605driver = instance_double(606::Msf::Ui::Console::Driver,607get_config_core: 'group/name/1',608get_config: {},609get_config_group: 'group/name/2',610active_module: nil611)612613expected_output = <<~OUTPUT614## %grnModule/Datastore%clr615616The following global/module datastore, and database setup was configured before the issue occurred:617<details>618<summary>Collapse</summary>619620```621[framework/database/1]622key10=[Filtered]623key11=[Filtered]624625[framework/database/2]626key12=[Filtered]627key13=[Filtered]628```629630</details>631632633OUTPUT634635expect(subject.datastore(framework, driver)).to eql(expected_output)636end637638it 'log parsing correctly retrieves and parses logs shorter than the log line total' do639range = 1..30640logs = ''641range.each do |i|642logs += "[00/00/0000 00:00:00] [e(0)] core: Log Line #{i}\n"643end644645allow(::Msf::Config).to receive(:log_directory).and_return(File.join(file_fixtures_path, 'debug', 'framework_logs', 'short'))646647error_log_output = <<~E_LOG648## %grnFramework Logs%clr649650The following framework logs were recorded before the issue occurred:651<details>652<summary>Collapse</summary>653654```655[00/00/0000 00:00:00] [e(0)] core: Log Line 1656[00/00/0000 00:00:00] [e(0)] core: Log Line 2657[00/00/0000 00:00:00] [e(0)] core: Log Line 3658[00/00/0000 00:00:00] [e(0)] core: Log Line 4659[00/00/0000 00:00:00] [e(0)] core: Log Line 5660[00/00/0000 00:00:00] [e(0)] core: Log Line 6661[00/00/0000 00:00:00] [e(0)] core: Log Line 7662[00/00/0000 00:00:00] [e(0)] core: Log Line 8663[00/00/0000 00:00:00] [e(0)] core: Log Line 9664[00/00/0000 00:00:00] [e(0)] core: Log Line 10665[00/00/0000 00:00:00] [e(0)] core: Log Line 11666[00/00/0000 00:00:00] [e(0)] core: Log Line 12667[00/00/0000 00:00:00] [e(0)] core: Log Line 13668[00/00/0000 00:00:00] [e(0)] core: Log Line 14669[00/00/0000 00:00:00] [e(0)] core: Log Line 15670[00/00/0000 00:00:00] [e(0)] core: Log Line 16671[00/00/0000 00:00:00] [e(0)] core: Log Line 17672[00/00/0000 00:00:00] [e(0)] core: Log Line 18673[00/00/0000 00:00:00] [e(0)] core: Log Line 19674[00/00/0000 00:00:00] [e(0)] core: Log Line 20675[00/00/0000 00:00:00] [e(0)] core: Log Line 21676[00/00/0000 00:00:00] [e(0)] core: Log Line 22677[00/00/0000 00:00:00] [e(0)] core: Log Line 23678[00/00/0000 00:00:00] [e(0)] core: Log Line 24679[00/00/0000 00:00:00] [e(0)] core: Log Line 25680[00/00/0000 00:00:00] [e(0)] core: Log Line 26681[00/00/0000 00:00:00] [e(0)] core: Log Line 27682[00/00/0000 00:00:00] [e(0)] core: Log Line 28683[00/00/0000 00:00:00] [e(0)] core: Log Line 29684[00/00/0000 00:00:00] [e(0)] core: Log Line 30685```686687</details>688689690## %grnWeb Service Logs%clr691692The following web service logs were recorded before the issue occurred:693<details>694<summary>Collapse</summary>695696```697[-] core: Log Line 1698[-] core: Log Line 2699[-] core: Log Line 3700[-] core: Log Line 4701[-] core: Log Line 5702[-] core: Log Line 6703[-] core: Log Line 7704[-] core: Log Line 8705[-] core: Log Line 9706[-] core: Log Line 10707[-] core: Log Line 11708[-] core: Log Line 12709[-] core: Log Line 13710[-] core: Log Line 14711[-] core: Log Line 15712[-] core: Log Line 16713[-] core: Log Line 17714[-] core: Log Line 18715[-] core: Log Line 19716[-] core: Log Line 20717[-] core: Log Line 21718[-] core: Log Line 22719[-] core: Log Line 23720[-] core: Log Line 24721[-] core: Log Line 25722[-] core: Log Line 26723[-] core: Log Line 27724[-] core: Log Line 28725[-] core: Log Line 29726[-] core: Log Line 30727```728729</details>730731732E_LOG733734expect(subject.logs).to eql(error_log_output)735end736737it 'log parsing correctly retrieves and parses logs equal to the log line total' do738range = 1..50739logs = ''740range.each do |i|741logs += "[00/00/0000 00:00:00] [e(0)] core: Log Line #{i}\n"742end743744allow(::Msf::Config).to receive(:log_directory).and_return(File.join(file_fixtures_path, 'debug', 'framework_logs', 'equal'))745746error_log_output = <<~E_LOG747## %grnFramework Logs%clr748749The following framework logs were recorded before the issue occurred:750<details>751<summary>Collapse</summary>752753```754[00/00/0000 00:00:00] [e(0)] core: Log Line 1755[00/00/0000 00:00:00] [e(0)] core: Log Line 2756[00/00/0000 00:00:00] [e(0)] core: Log Line 3757[00/00/0000 00:00:00] [e(0)] core: Log Line 4758[00/00/0000 00:00:00] [e(0)] core: Log Line 5759[00/00/0000 00:00:00] [e(0)] core: Log Line 6760[00/00/0000 00:00:00] [e(0)] core: Log Line 7761[00/00/0000 00:00:00] [e(0)] core: Log Line 8762[00/00/0000 00:00:00] [e(0)] core: Log Line 9763[00/00/0000 00:00:00] [e(0)] core: Log Line 10764[00/00/0000 00:00:00] [e(0)] core: Log Line 11765[00/00/0000 00:00:00] [e(0)] core: Log Line 12766[00/00/0000 00:00:00] [e(0)] core: Log Line 13767[00/00/0000 00:00:00] [e(0)] core: Log Line 14768[00/00/0000 00:00:00] [e(0)] core: Log Line 15769[00/00/0000 00:00:00] [e(0)] core: Log Line 16770[00/00/0000 00:00:00] [e(0)] core: Log Line 17771[00/00/0000 00:00:00] [e(0)] core: Log Line 18772[00/00/0000 00:00:00] [e(0)] core: Log Line 19773[00/00/0000 00:00:00] [e(0)] core: Log Line 20774[00/00/0000 00:00:00] [e(0)] core: Log Line 21775[00/00/0000 00:00:00] [e(0)] core: Log Line 22776[00/00/0000 00:00:00] [e(0)] core: Log Line 23777[00/00/0000 00:00:00] [e(0)] core: Log Line 24778[00/00/0000 00:00:00] [e(0)] core: Log Line 25779[00/00/0000 00:00:00] [e(0)] core: Log Line 26780[00/00/0000 00:00:00] [e(0)] core: Log Line 27781[00/00/0000 00:00:00] [e(0)] core: Log Line 28782[00/00/0000 00:00:00] [e(0)] core: Log Line 29783[00/00/0000 00:00:00] [e(0)] core: Log Line 30784[00/00/0000 00:00:00] [e(0)] core: Log Line 31785[00/00/0000 00:00:00] [e(0)] core: Log Line 32786[00/00/0000 00:00:00] [e(0)] core: Log Line 33787[00/00/0000 00:00:00] [e(0)] core: Log Line 34788[00/00/0000 00:00:00] [e(0)] core: Log Line 35789[00/00/0000 00:00:00] [e(0)] core: Log Line 36790[00/00/0000 00:00:00] [e(0)] core: Log Line 37791[00/00/0000 00:00:00] [e(0)] core: Log Line 38792[00/00/0000 00:00:00] [e(0)] core: Log Line 39793[00/00/0000 00:00:00] [e(0)] core: Log Line 40794[00/00/0000 00:00:00] [e(0)] core: Log Line 41795[00/00/0000 00:00:00] [e(0)] core: Log Line 42796[00/00/0000 00:00:00] [e(0)] core: Log Line 43797[00/00/0000 00:00:00] [e(0)] core: Log Line 44798[00/00/0000 00:00:00] [e(0)] core: Log Line 45799[00/00/0000 00:00:00] [e(0)] core: Log Line 46800[00/00/0000 00:00:00] [e(0)] core: Log Line 47801[00/00/0000 00:00:00] [e(0)] core: Log Line 48802[00/00/0000 00:00:00] [e(0)] core: Log Line 49803[00/00/0000 00:00:00] [e(0)] core: Log Line 50804```805806</details>807808809## %grnWeb Service Logs%clr810811The following web service logs were recorded before the issue occurred:812<details>813<summary>Collapse</summary>814815```816[-] core: Log Line 1817[-] core: Log Line 2818[-] core: Log Line 3819[-] core: Log Line 4820[-] core: Log Line 5821[-] core: Log Line 6822[-] core: Log Line 7823[-] core: Log Line 8824[-] core: Log Line 9825[-] core: Log Line 10826[-] core: Log Line 11827[-] core: Log Line 12828[-] core: Log Line 13829[-] core: Log Line 14830[-] core: Log Line 15831[-] core: Log Line 16832[-] core: Log Line 17833[-] core: Log Line 18834[-] core: Log Line 19835[-] core: Log Line 20836[-] core: Log Line 21837[-] core: Log Line 22838[-] core: Log Line 23839[-] core: Log Line 24840[-] core: Log Line 25841[-] core: Log Line 26842[-] core: Log Line 27843[-] core: Log Line 28844[-] core: Log Line 29845[-] core: Log Line 30846[-] core: Log Line 31847[-] core: Log Line 32848[-] core: Log Line 33849[-] core: Log Line 34850[-] core: Log Line 35851[-] core: Log Line 36852[-] core: Log Line 37853[-] core: Log Line 38854[-] core: Log Line 39855[-] core: Log Line 40856[-] core: Log Line 41857[-] core: Log Line 42858[-] core: Log Line 43859[-] core: Log Line 44860[-] core: Log Line 45861[-] core: Log Line 46862[-] core: Log Line 47863[-] core: Log Line 48864[-] core: Log Line 49865[-] core: Log Line 50866[-] core: Log Line 51867[-] core: Log Line 52868[-] core: Log Line 53869[-] core: Log Line 54870[-] core: Log Line 55871[-] core: Log Line 56872[-] core: Log Line 57873[-] core: Log Line 58874[-] core: Log Line 59875[-] core: Log Line 60876[-] core: Log Line 61877[-] core: Log Line 62878[-] core: Log Line 63879[-] core: Log Line 64880[-] core: Log Line 65881[-] core: Log Line 66882[-] core: Log Line 67883[-] core: Log Line 68884[-] core: Log Line 69885[-] core: Log Line 70886[-] core: Log Line 71887[-] core: Log Line 72888[-] core: Log Line 73889[-] core: Log Line 74890[-] core: Log Line 75891[-] core: Log Line 76892[-] core: Log Line 77893[-] core: Log Line 78894[-] core: Log Line 79895[-] core: Log Line 80896[-] core: Log Line 81897[-] core: Log Line 82898[-] core: Log Line 83899[-] core: Log Line 84900[-] core: Log Line 85901[-] core: Log Line 86902[-] core: Log Line 87903[-] core: Log Line 88904[-] core: Log Line 89905[-] core: Log Line 90906[-] core: Log Line 91907[-] core: Log Line 92908[-] core: Log Line 93909[-] core: Log Line 94910[-] core: Log Line 95911[-] core: Log Line 96912[-] core: Log Line 97913[-] core: Log Line 98914[-] core: Log Line 99915[-] core: Log Line 100916[-] core: Log Line 101917[-] core: Log Line 102918[-] core: Log Line 103919[-] core: Log Line 104920[-] core: Log Line 105921[-] core: Log Line 106922[-] core: Log Line 107923[-] core: Log Line 108924[-] core: Log Line 109925[-] core: Log Line 110926[-] core: Log Line 111927[-] core: Log Line 112928[-] core: Log Line 113929[-] core: Log Line 114930[-] core: Log Line 115931[-] core: Log Line 116932[-] core: Log Line 117933[-] core: Log Line 118934[-] core: Log Line 119935[-] core: Log Line 120936[-] core: Log Line 121937[-] core: Log Line 122938[-] core: Log Line 123939[-] core: Log Line 124940[-] core: Log Line 125941[-] core: Log Line 126942[-] core: Log Line 127943[-] core: Log Line 128944[-] core: Log Line 129945[-] core: Log Line 130946[-] core: Log Line 131947[-] core: Log Line 132948[-] core: Log Line 133949[-] core: Log Line 134950[-] core: Log Line 135951[-] core: Log Line 136952[-] core: Log Line 137953[-] core: Log Line 138954[-] core: Log Line 139955[-] core: Log Line 140956[-] core: Log Line 141957[-] core: Log Line 142958[-] core: Log Line 143959[-] core: Log Line 144960[-] core: Log Line 145961[-] core: Log Line 146962[-] core: Log Line 147963[-] core: Log Line 148964[-] core: Log Line 149965[-] core: Log Line 150966```967968</details>969970971E_LOG972973expect(subject.logs).to eql(error_log_output)974end975976it 'log parsing correctly retrieves and parses logs larger than the log line total' do977range = 51..100978logs = ''979range.each do |i|980logs += "[00/00/0000 00:00:00] [e(0)] core: Log Line #{i}\n"981end982983allow(::Msf::Config).to receive(:log_directory).and_return(File.join(file_fixtures_path, 'debug', 'framework_logs', 'long'))984985error_log_output = <<~E_LOG986## %grnFramework Logs%clr987988The following framework logs were recorded before the issue occurred:989<details>990<summary>Collapse</summary>991992```993[00/00/0000 00:00:00] [e(0)] core: Log Line 51994[00/00/0000 00:00:00] [e(0)] core: Log Line 52995[00/00/0000 00:00:00] [e(0)] core: Log Line 53996[00/00/0000 00:00:00] [e(0)] core: Log Line 54997[00/00/0000 00:00:00] [e(0)] core: Log Line 55998[00/00/0000 00:00:00] [e(0)] core: Log Line 56999[00/00/0000 00:00:00] [e(0)] core: Log Line 571000[00/00/0000 00:00:00] [e(0)] core: Log Line 581001[00/00/0000 00:00:00] [e(0)] core: Log Line 591002[00/00/0000 00:00:00] [e(0)] core: Log Line 601003[00/00/0000 00:00:00] [e(0)] core: Log Line 611004[00/00/0000 00:00:00] [e(0)] core: Log Line 621005[00/00/0000 00:00:00] [e(0)] core: Log Line 631006[00/00/0000 00:00:00] [e(0)] core: Log Line 641007[00/00/0000 00:00:00] [e(0)] core: Log Line 651008[00/00/0000 00:00:00] [e(0)] core: Log Line 661009[00/00/0000 00:00:00] [e(0)] core: Log Line 671010[00/00/0000 00:00:00] [e(0)] core: Log Line 681011[00/00/0000 00:00:00] [e(0)] core: Log Line 691012[00/00/0000 00:00:00] [e(0)] core: Log Line 701013[00/00/0000 00:00:00] [e(0)] core: Log Line 711014[00/00/0000 00:00:00] [e(0)] core: Log Line 721015[00/00/0000 00:00:00] [e(0)] core: Log Line 731016[00/00/0000 00:00:00] [e(0)] core: Log Line 741017[00/00/0000 00:00:00] [e(0)] core: Log Line 751018[00/00/0000 00:00:00] [e(0)] core: Log Line 761019[00/00/0000 00:00:00] [e(0)] core: Log Line 771020[00/00/0000 00:00:00] [e(0)] core: Log Line 781021[00/00/0000 00:00:00] [e(0)] core: Log Line 791022[00/00/0000 00:00:00] [e(0)] core: Log Line 801023[00/00/0000 00:00:00] [e(0)] core: Log Line 811024[00/00/0000 00:00:00] [e(0)] core: Log Line 821025[00/00/0000 00:00:00] [e(0)] core: Log Line 831026[00/00/0000 00:00:00] [e(0)] core: Log Line 841027[00/00/0000 00:00:00] [e(0)] core: Log Line 851028[00/00/0000 00:00:00] [e(0)] core: Log Line 861029[00/00/0000 00:00:00] [e(0)] core: Log Line 871030[00/00/0000 00:00:00] [e(0)] core: Log Line 881031[00/00/0000 00:00:00] [e(0)] core: Log Line 891032[00/00/0000 00:00:00] [e(0)] core: Log Line 901033[00/00/0000 00:00:00] [e(0)] core: Log Line 911034[00/00/0000 00:00:00] [e(0)] core: Log Line 921035[00/00/0000 00:00:00] [e(0)] core: Log Line 931036[00/00/0000 00:00:00] [e(0)] core: Log Line 941037[00/00/0000 00:00:00] [e(0)] core: Log Line 951038[00/00/0000 00:00:00] [e(0)] core: Log Line 961039[00/00/0000 00:00:00] [e(0)] core: Log Line 971040[00/00/0000 00:00:00] [e(0)] core: Log Line 981041[00/00/0000 00:00:00] [e(0)] core: Log Line 991042[00/00/0000 00:00:00] [e(0)] core: Log Line 1001043```10441045</details>104610471048## %grnWeb Service Logs%clr10491050The following web service logs were recorded before the issue occurred:1051<details>1052<summary>Collapse</summary>10531054```1055[-] core: Log Line 1511056[-] core: Log Line 1521057[-] core: Log Line 1531058[-] core: Log Line 1541059[-] core: Log Line 1551060[-] core: Log Line 1561061[-] core: Log Line 1571062[-] core: Log Line 1581063[-] core: Log Line 1591064[-] core: Log Line 1601065[-] core: Log Line 1611066[-] core: Log Line 1621067[-] core: Log Line 1631068[-] core: Log Line 1641069[-] core: Log Line 1651070[-] core: Log Line 1661071[-] core: Log Line 1671072[-] core: Log Line 1681073[-] core: Log Line 1691074[-] core: Log Line 1701075[-] core: Log Line 1711076[-] core: Log Line 1721077[-] core: Log Line 1731078[-] core: Log Line 1741079[-] core: Log Line 1751080[-] core: Log Line 1761081[-] core: Log Line 1771082[-] core: Log Line 1781083[-] core: Log Line 1791084[-] core: Log Line 1801085[-] core: Log Line 1811086[-] core: Log Line 1821087[-] core: Log Line 1831088[-] core: Log Line 1841089[-] core: Log Line 1851090[-] core: Log Line 1861091[-] core: Log Line 1871092[-] core: Log Line 1881093[-] core: Log Line 1891094[-] core: Log Line 1901095[-] core: Log Line 1911096[-] core: Log Line 1921097[-] core: Log Line 1931098[-] core: Log Line 1941099[-] core: Log Line 1951100[-] core: Log Line 1961101[-] core: Log Line 1971102[-] core: Log Line 1981103[-] core: Log Line 1991104[-] core: Log Line 2001105[-] core: Log Line 2011106[-] core: Log Line 2021107[-] core: Log Line 2031108[-] core: Log Line 2041109[-] core: Log Line 2051110[-] core: Log Line 2061111[-] core: Log Line 2071112[-] core: Log Line 2081113[-] core: Log Line 2091114[-] core: Log Line 2101115[-] core: Log Line 2111116[-] core: Log Line 2121117[-] core: Log Line 2131118[-] core: Log Line 2141119[-] core: Log Line 2151120[-] core: Log Line 2161121[-] core: Log Line 2171122[-] core: Log Line 2181123[-] core: Log Line 2191124[-] core: Log Line 2201125[-] core: Log Line 2211126[-] core: Log Line 2221127[-] core: Log Line 2231128[-] core: Log Line 2241129[-] core: Log Line 2251130[-] core: Log Line 2261131[-] core: Log Line 2271132[-] core: Log Line 2281133[-] core: Log Line 2291134[-] core: Log Line 2301135[-] core: Log Line 2311136[-] core: Log Line 2321137[-] core: Log Line 2331138[-] core: Log Line 2341139[-] core: Log Line 2351140[-] core: Log Line 2361141[-] core: Log Line 2371142[-] core: Log Line 2381143[-] core: Log Line 2391144[-] core: Log Line 2401145[-] core: Log Line 2411146[-] core: Log Line 2421147[-] core: Log Line 2431148[-] core: Log Line 2441149[-] core: Log Line 2451150[-] core: Log Line 2461151[-] core: Log Line 2471152[-] core: Log Line 2481153[-] core: Log Line 2491154[-] core: Log Line 2501155[-] core: Log Line 2511156[-] core: Log Line 2521157[-] core: Log Line 2531158[-] core: Log Line 2541159[-] core: Log Line 2551160[-] core: Log Line 2561161[-] core: Log Line 2571162[-] core: Log Line 2581163[-] core: Log Line 2591164[-] core: Log Line 2601165[-] core: Log Line 2611166[-] core: Log Line 2621167[-] core: Log Line 2631168[-] core: Log Line 2641169[-] core: Log Line 2651170[-] core: Log Line 2661171[-] core: Log Line 2671172[-] core: Log Line 2681173[-] core: Log Line 2691174[-] core: Log Line 2701175[-] core: Log Line 2711176[-] core: Log Line 2721177[-] core: Log Line 2731178[-] core: Log Line 2741179[-] core: Log Line 2751180[-] core: Log Line 2761181[-] core: Log Line 2771182[-] core: Log Line 2781183[-] core: Log Line 2791184[-] core: Log Line 2801185[-] core: Log Line 2811186[-] core: Log Line 2821187[-] core: Log Line 2831188[-] core: Log Line 2841189[-] core: Log Line 2851190[-] core: Log Line 2861191[-] core: Log Line 2871192[-] core: Log Line 2881193[-] core: Log Line 2891194[-] core: Log Line 2901195[-] core: Log Line 2911196[-] core: Log Line 2921197[-] core: Log Line 2931198[-] core: Log Line 2941199[-] core: Log Line 2951200[-] core: Log Line 2961201[-] core: Log Line 2971202[-] core: Log Line 2981203[-] core: Log Line 2991204[-] core: Log Line 3001205```12061207</details>120812091210E_LOG12111212expect(subject.logs).to eql(error_log_output)1213end12141215it 'log parsing correctly retrieves and parses an empty log file' do1216allow(::Msf::Config).to receive(:log_directory).and_return(File.join(file_fixtures_path, 'debug', 'framework_logs', 'empty'))12171218error_log_output = <<~E_LOG1219## %grnFramework Logs%clr12201221The following framework logs were recorded before the issue occurred:1222<details>1223<summary>Collapse</summary>12241225```12261227```12281229</details>123012311232## %grnWeb Service Logs%clr12331234The following web service logs were recorded before the issue occurred:1235<details>1236<summary>Collapse</summary>12371238```12391240```12411242</details>124312441245E_LOG12461247expect(subject.logs).to eql(error_log_output)1248end12491250it 'log parsing correctly retrieves and returns a missing log file message' do1251allow(::Msf::Config).to receive(:log_directory).and_return('FAKE_PATH')12521253error_log_output = <<~E_LOG1254## %grnFramework Logs%clr12551256The following framework logs were recorded before the issue occurred:1257<details>1258<summary>Collapse</summary>12591260```1261framework.log does not exist.1262```12631264</details>126512661267## %grnWeb Service Logs%clr12681269The following web service logs were recorded before the issue occurred:1270<details>1271<summary>Collapse</summary>12721273```1274msf-ws.log does not exist.1275```12761277</details>127812791280E_LOG12811282expect(subject.logs).to eql(error_log_output)1283end12841285it 'correctly retrieves features and outputs them' do1286db = instance_double(1287Msf::DBManager,1288connection_established?: false,1289driver: 'driver'1290)12911292framework = instance_double(1293::Msf::Framework,1294features: instance_double(Msf::FeatureManager, all: features),1295db: db1296)12971298expected_output = <<~OUTPUT1299## %grnFramework Configuration%clr13001301The features are configured as follows:1302<details>1303<summary>Collapse</summary>13041305| name | enabled |1306|-:|-:|1307| filtered_options | false |1308| new_search_capabilities | true |13091310</details>131113121313OUTPUT13141315expect(subject.framework_config(framework)).to eql(expected_output)1316end13171318it 'correctly retrieves version information with no connected DB' do1319db = instance_double(1320Msf::DBManager,1321connection_established?: false,1322driver: 'driver'1323)13241325framework = instance_double(1326::Msf::Framework,1327version: 'VERSION',1328db: db1329)13301331allow(::Msf::Config).to receive(:install_root).and_return('bad/path')13321333expected_output = <<~OUTPUT1334## %grnVersion/Install%clr13351336The versions and install method of your Metasploit setup:1337<details>1338<summary>Collapse</summary>13391340```1341Framework: VERSION1342Ruby: #{RUBY_DESCRIPTION}1343OpenSSL: #{OpenSSL::OPENSSL_VERSION}1344Install Root: bad/path1345Session Type: driver selected, no connection1346Install Method: Other - Please specify1347```13481349</details>135013511352OUTPUT13531354expect(subject.versions(framework)).to eql(expected_output)1355end13561357it 'correctly retrieves version information with DB connected via http' do1358db = double(1359'Metasploit::Framework::DataService::DataProxy',1360name: 'db_name',1361driver: 'http',1362connection_established?: true1363)13641365framework = instance_double(1366::Msf::Framework,1367version: 'VERSION',1368db: db1369)13701371allow(::Msf::Config).to receive(:install_root).and_return('bad/path')13721373expected_output = <<~OUTPUT1374## %grnVersion/Install%clr13751376The versions and install method of your Metasploit setup:1377<details>1378<summary>Collapse</summary>13791380```1381Framework: VERSION1382Ruby: #{RUBY_DESCRIPTION}1383OpenSSL: #{OpenSSL::OPENSSL_VERSION}1384Install Root: bad/path1385Session Type: Connected to db_name. Connection type: http.1386Install Method: Other - Please specify1387```13881389</details>139013911392OUTPUT13931394expect(subject.versions(framework)).to eql(expected_output)1395end13961397it 'correctly retrieves version information with DB connected via local connection' do1398db = double(1399'Metasploit::Framework::DataService::DataProxy',1400connection_established?: true,1401driver: 'local'1402)14031404framework = instance_double(1405::Msf::Framework,1406version: 'VERSION',1407db: db1408)14091410connection_pool = instance_double(ActiveRecord::ConnectionAdapters::ConnectionPool)1411connection = double(1412'connection',1413current_database: 'current_db_connection',1414respond_to?: true1415)1416allow(connection_pool).to receive(:with_connection).and_yield(connection)14171418allow(::ApplicationRecord).to receive(:connection_pool).and_return(connection_pool)1419allow(::Msf::Config).to receive(:install_root).and_return('bad/path')14201421expected_output = <<~OUTPUT1422## %grnVersion/Install%clr14231424The versions and install method of your Metasploit setup:1425<details>1426<summary>Collapse</summary>14271428```1429Framework: VERSION1430Ruby: #{RUBY_DESCRIPTION}1431OpenSSL: #{OpenSSL::OPENSSL_VERSION}1432Install Root: bad/path1433Session Type: Connected to current_db_connection. Connection type: local.1434Install Method: Other - Please specify1435```14361437</details>143814391440OUTPUT14411442expect(subject.versions(framework)).to eql(expected_output)1443end14441445it 'correctly retrieves version information with no connected DB and a Kali Install' do1446db = instance_double(1447Msf::DBManager,1448connection_established?: false,1449driver: 'driver'1450)14511452framework = instance_double(1453::Msf::Framework,1454version: 'VERSION',1455db: db1456)14571458allow(::Msf::Config).to receive(:install_root).and_return(File.join(File::SEPARATOR, 'usr', 'share', 'metasploit-framework'))14591460expected_output = <<~OUTPUT1461## %grnVersion/Install%clr14621463The versions and install method of your Metasploit setup:1464<details>1465<summary>Collapse</summary>14661467```1468Framework: VERSION1469Ruby: #{RUBY_DESCRIPTION}1470OpenSSL: #{OpenSSL::OPENSSL_VERSION}1471Install Root: #{File.join(File::SEPARATOR, 'usr', 'share', 'metasploit-framework')}1472Session Type: driver selected, no connection1473Install Method: Other - Please specify1474```14751476</details>147714781479OUTPUT14801481expect(subject.versions(framework)).to eql(expected_output)1482end14831484it 'correctly retrieves version information with no connected DB and an Omnibus Install' do1485db = instance_double(1486Msf::DBManager,1487connection_established?: false,1488driver: 'driver'1489)14901491framework = instance_double(1492::Msf::Framework,1493version: 'VERSION',1494db: db1495)14961497allow(::Msf::Config).to receive(:install_root).and_return(File.join(file_fixtures_path, 'debug', 'installs', 'omnibus'))14981499expected_output = <<~OUTPUT1500## %grnVersion/Install%clr15011502The versions and install method of your Metasploit setup:1503<details>1504<summary>Collapse</summary>15051506```1507Framework: VERSION1508Ruby: #{RUBY_DESCRIPTION}1509OpenSSL: #{OpenSSL::OPENSSL_VERSION}1510Install Root: #{File.join(file_fixtures_path, 'debug', 'installs', 'omnibus')}1511Session Type: driver selected, no connection1512Install Method: Omnibus Installer1513```15141515</details>151615171518OUTPUT15191520expect(subject.versions(framework)).to eql(expected_output)1521end15221523it 'correctly retrieves version information with no connected DB and a Git Clone' do1524db = instance_double(1525Msf::DBManager,1526connection_established?: false,1527driver: 'driver'1528)15291530framework = instance_double(1531::Msf::Framework,1532version: 'VERSION',1533db: db1534)15351536allow(::Msf::Config).to receive(:install_root).and_return(File.join(file_fixtures_path, 'debug', 'installs'))1537allow(File).to receive(:directory?).with(File.join(Msf::Config.install_root, '.git')).and_return(true)15381539expected_output = <<~OUTPUT1540## %grnVersion/Install%clr15411542The versions and install method of your Metasploit setup:1543<details>1544<summary>Collapse</summary>15451546```1547Framework: VERSION1548Ruby: #{RUBY_DESCRIPTION}1549OpenSSL: #{OpenSSL::OPENSSL_VERSION}1550Install Root: #{File.join(file_fixtures_path, 'debug', 'installs')}1551Session Type: driver selected, no connection1552Install Method: Git Clone1553```15541555</details>155615571558OUTPUT15591560expect(subject.versions(framework)).to eql(expected_output)1561end15621563it 'correctly retrieves version information with no connected DB and a Arch Pacman install' do1564db = instance_double(1565Msf::DBManager,1566connection_established?: false,1567driver: 'driver'1568)15691570framework = instance_double(1571::Msf::Framework,1572version: 'VERSION',1573db: db1574)15751576allow(::Msf::Config).to receive(:install_root).times.and_return(File.join(File::SEPARATOR, 'opt', 'metasploit'))15771578expected_output = <<~OUTPUT1579## %grnVersion/Install%clr15801581The versions and install method of your Metasploit setup:1582<details>1583<summary>Collapse</summary>15841585```1586Framework: VERSION1587Ruby: #{RUBY_DESCRIPTION}1588OpenSSL: #{OpenSSL::OPENSSL_VERSION}1589Install Root: #{File.join(File::SEPARATOR, 'opt', 'metasploit')}1590Session Type: driver selected, no connection1591Install Method: Other - Please specify1592```15931594</details>159515961597OUTPUT15981599expect(subject.versions(framework)).to eql(expected_output)1600end16011602context 'Database Configuration Debug' do16031604it 'correctly retrieves the current empty workspace with DB connected' do1605workspace = FactoryBot.create(:mdm_workspace)16061607db = instance_double(1608Msf::DBManager,1609connection_established?: true,1610name: 'msf',1611driver: 'postgresql',1612active: true,1613workspace: workspace,1614workspaces: [workspace]1615)16161617framework = instance_double(1618::Msf::Framework,1619version: 'VERSION',1620db: db1621)16221623connection_pool = instance_double(ActiveRecord::ConnectionAdapters::ConnectionPool)1624connection = double(1625'connection',1626current_database: 'msf',1627respond_to?: true1628)1629allow(connection_pool).to receive(:with_connection).and_yield(connection)1630allow(::ApplicationRecord).to receive(:connection_pool).and_return(connection_pool)16311632allow(::Mdm::Workspace).to receive(:count).and_return(1)1633allow(::Mdm::Workspace).to receive_message_chain(:order, :take).and_return([workspace])1634allow(::Mdm::Host).to receive(:count).and_return(0)1635allow(::Mdm::Vuln).to receive(:count).and_return(0)1636allow(::Mdm::Note).to receive(:count).and_return(0)1637allow(::Mdm::Service).to receive(:count).and_return(0)16381639expected_output = <<~OUTPUT1640## %grnDatabase Configuration%clr16411642The database contains the following information:1643<details>1644<summary>Collapse</summary>16451646```1647Session Type: Connected to msf. Connection type: postgresql.1648```16491650| ID | Hosts | Vulnerabilities | Notes | Services |1651|-:|-:|-:|-:|-:|1652| #{workspace.id.to_fs(:delimited)} **(Current)** | 0 | 0 | 0 | 0 |1653| **Total (#{::Mdm::Workspace.count})** | **#{::Mdm::Host.count}** | **#{::Mdm::Vuln.count}** | **#{::Mdm::Note.count}** | **#{::Mdm::Service.count}** |16541655</details>165616571658OUTPUT16591660expect(subject.database_configuration(framework)).to eql(expected_output)1661end16621663it 'correctly retrieves the current workspace with contents with DB connected' do1664workspace = FactoryBot.create(:mdm_workspace)1665host = FactoryBot.create(:mdm_host, workspace: workspace)1666vuln = FactoryBot.create(:mdm_vuln, host: host)1667service = FactoryBot.create(:mdm_service, host: host)1668note = FactoryBot.create(:mdm_note, workspace: workspace, host: host, service: service, vuln: vuln)16691670db = instance_double(1671Msf::DBManager,1672connection_established?: true,1673name: 'msf',1674driver: 'postgresql',1675active: true,1676workspace: workspace,1677workspaces: [workspace]1678)16791680framework = instance_double(1681::Msf::Framework,1682version: 'VERSION',1683db: db1684)16851686connection_pool = instance_double(ActiveRecord::ConnectionAdapters::ConnectionPool)1687connection = double(1688'connection',1689current_database: 'msf',1690respond_to?: true1691)1692allow(connection_pool).to receive(:with_connection).and_yield(connection)1693allow(::ApplicationRecord).to receive(:connection_pool).and_return(connection_pool)16941695allow(::Mdm::Workspace).to receive(:count).and_return(1)1696allow(::Mdm::Workspace).to receive_message_chain(:order, :take).and_return([workspace])1697allow(::Mdm::Host).to receive(:count).and_return(1)1698allow(::Mdm::Vuln).to receive(:count).and_return(1)1699allow(::Mdm::Note).to receive(:count).and_return(1)1700allow(::Mdm::Service).to receive(:count).and_return(1)17011702expected_output = <<~OUTPUT1703## %grnDatabase Configuration%clr17041705The database contains the following information:1706<details>1707<summary>Collapse</summary>17081709```1710Session Type: Connected to msf. Connection type: postgresql.1711```17121713| ID | Hosts | Vulnerabilities | Notes | Services |1714|-:|-:|-:|-:|-:|1715| #{workspace.id.to_fs(:delimited)} **(Current)** | 1 | 1 | 1 | 1 |1716| **Total (#{::Mdm::Workspace.count})** | **#{::Mdm::Host.count}** | **#{::Mdm::Vuln.count}** | **#{::Mdm::Note.count}** | **#{::Mdm::Service.count}** |17171718</details>171917201721OUTPUT17221723expect(subject.database_configuration(framework)).to eql(expected_output)1724end17251726it 'correctly retrieves session type with DB not connected' do1727db = instance_double(1728Msf::DBManager,1729connection_established?: false,1730driver: 'postgresql',1731active: false1732)17331734framework = instance_double(1735::Msf::Framework,1736db: db1737)17381739expected_output = <<~OUTPUT1740## %grnDatabase Configuration%clr17411742The database contains the following information:1743<details>1744<summary>Collapse</summary>17451746```1747Session Type: postgresql selected, no connection1748```17491750</details>175117521753OUTPUT17541755expect(subject.database_configuration(framework)).to eql(expected_output)1756end17571758it 'correctly retrieves multiple empty workspaces with DB connected' do1759workspaces = 5.times.map { FactoryBot.create(:mdm_workspace) }17601761db = instance_double(1762Msf::DBManager,1763connection_established?: true,1764name: 'msf',1765driver: 'postgresql',1766active: true,1767workspace: workspaces.last,1768workspaces: workspaces1769)17701771framework = instance_double(1772::Msf::Framework,1773version: 'VERSION',1774db: db1775)17761777connection_pool = instance_double(ActiveRecord::ConnectionAdapters::ConnectionPool)1778connection = double(1779'connection',1780current_database: 'msf',1781respond_to?: true1782)1783allow(connection_pool).to receive(:with_connection).and_yield(connection)1784allow(::ApplicationRecord).to receive(:connection_pool).and_return(connection_pool)17851786allow(::Mdm::Workspace).to receive(:count).and_return(5)1787allow(::Mdm::Workspace).to receive_message_chain(:order, :take).and_return(workspaces)1788allow(::Mdm::Host).to receive(:count).and_return(0)1789allow(::Mdm::Vuln).to receive(:count).and_return(0)1790allow(::Mdm::Note).to receive(:count).and_return(0)1791allow(::Mdm::Service).to receive(:count).and_return(0)17921793expected_output = <<~OUTPUT1794## %grnDatabase Configuration%clr17951796The database contains the following information:1797<details>1798<summary>Collapse</summary>17991800```1801Session Type: Connected to msf. Connection type: postgresql.1802```18031804| ID | Hosts | Vulnerabilities | Notes | Services |1805|-:|-:|-:|-:|-:|1806| #{workspaces[0].id.to_fs(:delimited)} | 0 | 0 | 0 | 0 |1807| #{workspaces[1].id.to_fs(:delimited)} | 0 | 0 | 0 | 0 |1808| #{workspaces[2].id.to_fs(:delimited)} | 0 | 0 | 0 | 0 |1809| #{workspaces[3].id.to_fs(:delimited)} | 0 | 0 | 0 | 0 |1810| #{workspaces[4].id.to_fs(:delimited)} **(Current)** | 0 | 0 | 0 | 0 |1811| **Total (#{::Mdm::Workspace.count})** | **#{::Mdm::Host.count}** | **#{::Mdm::Vuln.count}** | **#{::Mdm::Note.count}** | **#{::Mdm::Service.count}** |18121813</details>181418151816OUTPUT18171818expect(subject.database_configuration(framework)).to eql(expected_output)1819end18201821it 'correctly retrieves multiple workspaces with content with DB connected' do1822workspaces = 5.times.map do |index|1823workspace = FactoryBot.create(:mdm_workspace)1824# Only some of the workspaces should have values to make the output not be the same for every workspace.1825if index.even?1826host = FactoryBot.create(:mdm_host, workspace: workspace)1827vuln = FactoryBot.create(:mdm_vuln, host: host)1828service = FactoryBot.create(:mdm_service, host: host)1829note = FactoryBot.create(:mdm_note, workspace: workspace, host: host, service: service, vuln: vuln)1830end1831workspace1832end18331834db = instance_double(1835Msf::DBManager,1836connection_established?: true,1837name: 'msf',1838driver: 'postgresql',1839active: true,1840workspace: workspaces.last,1841workspaces: workspaces1842)18431844framework = instance_double(1845::Msf::Framework,1846version: 'VERSION',1847db: db1848)18491850connection_pool = instance_double(ActiveRecord::ConnectionAdapters::ConnectionPool)1851connection = double(1852'connection',1853current_database: 'msf',1854respond_to?: true1855)1856allow(connection_pool).to receive(:with_connection).and_yield(connection)1857allow(::ApplicationRecord).to receive(:connection_pool).and_return(connection_pool)18581859allow(::Mdm::Workspace).to receive(:count).and_return(5)1860allow(::Mdm::Workspace).to receive_message_chain(:order, :take).and_return(workspaces)1861allow(::Mdm::Host).to receive(:count).and_return(2)1862allow(::Mdm::Vuln).to receive(:count).and_return(2)1863allow(::Mdm::Note).to receive(:count).and_return(2)1864allow(::Mdm::Service).to receive(:count).and_return(2)18651866expected_output = <<~OUTPUT1867## %grnDatabase Configuration%clr18681869The database contains the following information:1870<details>1871<summary>Collapse</summary>18721873```1874Session Type: Connected to msf. Connection type: postgresql.1875```18761877| ID | Hosts | Vulnerabilities | Notes | Services |1878|-:|-:|-:|-:|-:|1879| #{workspaces[0].id.to_fs(:delimited)} | 1 | 1 | 1 | 1 |1880| #{workspaces[1].id.to_fs(:delimited)} | 0 | 0 | 0 | 0 |1881| #{workspaces[2].id.to_fs(:delimited)} | 1 | 1 | 1 | 1 |1882| #{workspaces[3].id.to_fs(:delimited)} | 0 | 0 | 0 | 0 |1883| #{workspaces[4].id.to_fs(:delimited)} **(Current)** | 1 | 1 | 1 | 1 |1884| **Total (#{::Mdm::Workspace.count})** | **#{::Mdm::Host.count}** | **#{::Mdm::Vuln.count}** | **#{::Mdm::Note.count}** | **#{::Mdm::Service.count}** |18851886</details>188718881889OUTPUT18901891expect(subject.database_configuration(framework)).to eql(expected_output)1892end1893end1894end189518961897