Vardarac
Vardarac

Reputation: 563

Readlines for part of a file?

I am testing a Rails function that leaves several different messages in a log file upon encountering errors. The tests are to ensure that the proper messages are recorded under the right circumstances.

This log file is quite large; what I'd like to be able to do is ignore all the lines that didn't exist prior to running my test, then search the remainder generated by the operation of my tests for the messages so that I don't have to stuff this entire file into memory.

Is this doable?

Upvotes: 0

Views: 74

Answers (2)

Shadwell
Shadwell

Reputation: 34774

You could get the file size at the beginning of your test and then seek to that point:

the_log = Rails.root.join("log", "test.log")
size_at_start = the_log.size
... test stuff ...
File.open(the_log) do |f|
  # Skip to the point in the log where our test started
  f.seek(size_at_the_start)
  while line = f.gets
    # We found what we were looking for
    break if line =~ /required message/
  end
  fail("We haven't found what we were looking for")
end

If you really wanted to DRY it up you could make that a method in your test helper, something like:

def test_log_output(required_output_regexp, 
                    the_log = Rails.root.join("log", "test.log"), 
                    &test_code)
  size_at_start = the_log.size
  test_code.call
  File.open(the_log) do |f|
    f.seek(size_at_the_start)
    while line = f.gets
      # We found what we were looking for
      break if line =~ required_output_regexp
    end
    fail("We haven't found what we were looking for")
  end
end

Upvotes: 1

Damp
Damp

Reputation: 3348

While not exactly an answer, this other s.o. question - Insert rows on specific line in a file - highlights quite a few methods (readline, seek) that should help you do what you want.

Upvotes: 0

Related Questions