local_file_agent_spec.rb 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. require 'rails_helper'
  2. describe Agents::LocalFileAgent do
  3. before(:each) do
  4. @valid_params = {
  5. 'mode' => 'read',
  6. 'watch' => 'false',
  7. 'append' => 'false',
  8. 'path' => File.join(Rails.root, 'tmp', 'spec')
  9. }
  10. FileUtils.mkdir_p File.join(Rails.root, 'tmp', 'spec')
  11. @checker = Agents::LocalFileAgent.new(:name => "somename", :options => @valid_params)
  12. @checker.user = users(:jane)
  13. @checker.save!
  14. end
  15. after(:all) do
  16. FileUtils.rm_r File.join(Rails.root, 'tmp', 'spec')
  17. end
  18. describe "#validate_options" do
  19. it "is valid with the given options" do
  20. expect(@checker).to be_valid
  21. end
  22. it "requires mode to be either 'read' or 'write'" do
  23. @checker.options['mode'] = 'write'
  24. expect(@checker).to be_valid
  25. @checker.options['mode'] = 'write'
  26. expect(@checker).to be_valid
  27. @checker.options['mode'] = 'test'
  28. expect(@checker).not_to be_valid
  29. end
  30. it "requires the path to be set" do
  31. @checker.options['path'] = ''
  32. expect(@checker).not_to be_valid
  33. end
  34. it "requires watch to be present" do
  35. @checker.options['watch'] = ''
  36. expect(@checker).not_to be_valid
  37. end
  38. it "requires watch to be either 'true' or 'false'" do
  39. @checker.options['watch'] = 'true'
  40. expect(@checker).to be_valid
  41. @checker.options['watch'] = 'false'
  42. expect(@checker).to be_valid
  43. @checker.options['watch'] = 'test'
  44. expect(@checker).not_to be_valid
  45. end
  46. it "requires append to be either 'true' or 'false'" do
  47. @checker.options['append'] = 'true'
  48. expect(@checker).to be_valid
  49. @checker.options['append'] = 'false'
  50. expect(@checker).to be_valid
  51. @checker.options['append'] = 'test'
  52. expect(@checker).not_to be_valid
  53. end
  54. end
  55. context "#working" do
  56. it "is working with no recent errors in read mode" do
  57. @checker.last_check_at = Time.now
  58. expect(@checker).to be_working
  59. end
  60. it "is working with no recent errors in write mode" do
  61. @checker.options['mode'] = 'write'
  62. @checker.last_receive_at = Time.now
  63. expect(@checker).to be_working
  64. end
  65. end
  66. context "#check_path_existance" do
  67. it "is truethy when the path exists" do
  68. expect(@checker.check_path_existance).to be_truthy
  69. end
  70. it "is falsy when the path does not exist" do
  71. @checker.options['path'] = '/doesnotexist'
  72. expect(@checker.check_path_existance).to be_falsy
  73. end
  74. it "create a log entry" do
  75. @checker.options['path'] = '/doesnotexist'
  76. expect { @checker.check_path_existance(true) }.to change(AgentLog, :count).by(1)
  77. end
  78. it "works with non-expanded paths" do
  79. @checker.options['path'] = '~'
  80. expect(@checker.check_path_existance).to be_truthy
  81. end
  82. end
  83. def with_files(*files)
  84. files.each { |f| FileUtils.touch(f) }
  85. yield
  86. files.each { |f| FileUtils.rm(f) }
  87. end
  88. context "#check" do
  89. it "does not create events when the directory is empty" do
  90. expect { @checker.check }.to change(Event, :count).by(0)
  91. end
  92. it "creates an event for every file in the directory" do
  93. with_files(File.join(Rails.root, 'tmp', 'spec', 'one'), File.join(Rails.root, 'tmp', 'spec', 'two')) do
  94. expect { @checker.check }.to change(Event, :count).by(2)
  95. expect(Event.last.payload.has_key?('file_pointer')).to be_truthy
  96. end
  97. end
  98. it "creates an event if the configured file exists" do
  99. @checker.options['path'] = File.join(Rails.root, 'tmp', 'spec', 'one')
  100. with_files(File.join(Rails.root, 'tmp', 'spec', 'one'), File.join(Rails.root, 'tmp', 'spec', 'two')) do
  101. expect { @checker.check }.to change(Event, :count).by(1)
  102. payload = Event.last.payload
  103. expect(payload.has_key?('file_pointer')).to be_truthy
  104. expect(payload['file_pointer']['file']).to eq(@checker.options['path'])
  105. end
  106. end
  107. it "does not run when ENABLE_INSECURE_AGENTS is not set to true" do
  108. ENV['ENABLE_INSECURE_AGENTS'] = 'false'
  109. expect { @checker.check }.to change(AgentLog, :count).by(1)
  110. ENV['ENABLE_INSECURE_AGENTS'] = 'true'
  111. end
  112. end
  113. context "#event_description" do
  114. it "should include event_type when watch is set to true" do
  115. @checker.options['watch'] = 'true'
  116. expect(@checker.event_description).to include('event_type')
  117. end
  118. it "should not include event_type when watch is set to false" do
  119. @checker.options['watch'] = 'false'
  120. expect(@checker.event_description).not_to include('event_type')
  121. end
  122. end
  123. it "get_io opens the file" do
  124. expect(File).to receive(:open).with('test', 'r')
  125. @checker.get_io('test')
  126. end
  127. context "#start_worker?" do
  128. it "reeturns true when watch is true" do
  129. @checker.options['watch'] = 'true'
  130. expect(@checker.start_worker?).to be_truthy
  131. end
  132. it "returns false when watch is false" do
  133. @checker.options['watch'] = 'false'
  134. expect(@checker.start_worker?).to be_falsy
  135. end
  136. end
  137. context "#receive" do
  138. before(:each) do
  139. @checker.options['mode'] = 'write'
  140. @checker.options['data'] = '{{ data }}'
  141. @file_mock = double()
  142. end
  143. it "writes the data at data into a file" do
  144. expect(@file_mock).to receive(:write).with('hello world')
  145. event = Event.new(payload: {'data' => 'hello world'})
  146. expect(File).to receive(:open).with(File.join(Rails.root, 'tmp', 'spec'), 'w').and_yield(@file_mock)
  147. @checker.receive([event])
  148. end
  149. it "appends the data at data onto a file" do
  150. expect(@file_mock).to receive(:write).with('hello world')
  151. @checker.options['append'] = 'true'
  152. event = Event.new(payload: {'data' => 'hello world'})
  153. expect(File).to receive(:open).with(File.join(Rails.root, 'tmp', 'spec'), 'a').and_yield(@file_mock)
  154. @checker.receive([event])
  155. end
  156. it "does not receive when ENABLE_INSECURE_AGENTS is not set to true" do
  157. ENV['ENABLE_INSECURE_AGENTS'] = 'false'
  158. expect { @checker.receive([]) }.to change(AgentLog, :count).by(1)
  159. ENV['ENABLE_INSECURE_AGENTS'] = 'true'
  160. end
  161. it "emits an event containing the file pointer" do
  162. expect(@file_mock).to receive(:write).with('hello world')
  163. event = Event.new(payload: {'data' => 'hello world'})
  164. expect(File).to receive(:open).with(File.join(Rails.root, 'tmp', 'spec'), 'w').and_yield(@file_mock)
  165. expect { @checker.receive([event]) }.to change(Event, :count).by(1)
  166. expect(Event.last.payload.has_key?('file_pointer')).to be_truthy
  167. end
  168. end
  169. describe describe Agents::LocalFileAgent::Worker do
  170. require 'listen'
  171. before(:each) do
  172. @checker.options['watch'] = true
  173. @checker.save
  174. @worker = Agents::LocalFileAgent::Worker.new(agent: @checker)
  175. @listen_mock = double()
  176. end
  177. context "#setup" do
  178. it "initializes the listen gem" do
  179. expect(Listen).to receive(:to).with(@checker.options['path'], ignore!: [])
  180. @worker.setup
  181. end
  182. end
  183. context "#run" do
  184. before(:each) do
  185. allow(Listen).to receive(:to) { @listen_mock }
  186. @worker.setup
  187. end
  188. it "starts to listen to changes in the directory when the path is present" do
  189. expect(@worker).to receive(:sleep)
  190. expect(@listen_mock).to receive(:start)
  191. @worker.run
  192. end
  193. it "does nothing when the path does not exist" do
  194. expect(@worker.agent).to receive(:check_path_existance).with(true) { false }
  195. expect(@listen_mock).not_to receive(:start)
  196. expect(@worker).to receive(:sleep) { raise "Sleeping" }
  197. expect { @worker.run }.to raise_exception(RuntimeError, 'Sleeping')
  198. end
  199. end
  200. context "#stop" do
  201. it "stops the listen gem" do
  202. allow(Listen).to receive(:to) { @listen_mock }
  203. @worker.setup
  204. expect(@listen_mock).to receive(:stop)
  205. @worker.stop
  206. end
  207. end
  208. context "#callback" do
  209. let(:file) { File.join(Rails.root, 'tmp', 'one') }
  210. let(:file2) { File.join(Rails.root, 'tmp', 'one2') }
  211. it "creates an event for modifies files" do
  212. expect { @worker.send(:callback, [file], [], [])}.to change(Event, :count).by(1)
  213. payload = Event.last.payload
  214. expect(payload['event_type']).to eq('modified')
  215. end
  216. it "creates an event for modifies files" do
  217. expect { @worker.send(:callback, [], [file], [])}.to change(Event, :count).by(1)
  218. payload = Event.last.payload
  219. expect(payload['event_type']).to eq('added')
  220. end
  221. it "creates an event for modifies files" do
  222. expect { @worker.send(:callback, [], [], [file])}.to change(Event, :count).by(1)
  223. payload = Event.last.payload
  224. expect(payload['event_type']).to eq('removed')
  225. end
  226. it "creates an event each changed file" do
  227. expect { @worker.send(:callback, [], [file], [file2])}.to change(Event, :count).by(2)
  228. end
  229. end
  230. context "#listen_options" do
  231. it "returns the path when a directory is given" do
  232. expect(@worker.send(:listen_options)).to eq([File.join(Rails.root, 'tmp', 'spec'), ignore!: []])
  233. end
  234. it "restricts to only the specified filename" do
  235. @worker.agent.options['path'] = File.join(Rails.root, 'tmp', 'one')
  236. expect(@worker.send(:listen_options)).to eq([File.join(Rails.root, 'tmp'), { only: /\Aone\z/, ignore!: [] } ])
  237. end
  238. end
  239. end
  240. end