indy 0.4.0.pre → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -19,7 +19,7 @@ class Indy
19
19
  @entry_regexp = Regexp.new(params_hash[:entry_regexp])
20
20
  end
21
21
  @entry_fields = params_hash[:entry_fields]
22
- @time_format = params_hash[:time_format]
22
+ @time_format = params_hash[:time_format] || Indy::LogFormats::DEFAULT_DATE_TIME # '%Y-%m-%d %H:%M:%S'
23
23
  define_struct
24
24
  end
25
25
 
@@ -27,6 +27,7 @@ class Indy
27
27
  params_hash = {}
28
28
  params_hash[:entry_regexp] = Indy::LogFormats::DEFAULT_ENTRY_REGEXP
29
29
  params_hash[:entry_fields] = Indy::LogFormats::DEFAULT_ENTRY_FIELDS
30
+ params_hash[:time_format] = Indy::LogFormats::DEFAULT_DATE_TIME
30
31
  params_hash
31
32
  end
32
33
 
@@ -54,7 +55,7 @@ class Indy
54
55
  end
55
56
 
56
57
  #
57
- # Define Struct::Entry with the fields from @log_definition. Ignore warnings.
58
+ # Define Struct::Entry. Ignore warnings.
58
59
  #
59
60
  def define_struct
60
61
  fields = (@entry_fields + [:raw_entry]).sort_by{|key|key.to_s}
@@ -85,13 +86,14 @@ class Indy
85
86
  match_data = /#{@entry_regexp}/.match(raw_entry)
86
87
  return nil unless match_data
87
88
  values = match_data.captures
89
+ values.shift if @multiline
88
90
  entry_hash([raw_entry, values].flatten)
89
91
  end
90
92
 
91
93
  #
92
94
  # Return a hash of field=>value pairs for the array of captured values from a log entry
93
95
  #
94
- # @param [Array] capture_array The array of values captured by the @log_definition.entry_regexp
96
+ # @param [Array] capture_array The array of values captured by the LogDefinition regexp
95
97
  #
96
98
  def parse_entry_captures( capture_array )
97
99
  entire_entry = capture_array.shift
@@ -106,7 +108,7 @@ class Indy
106
108
  if values.length == @entry_fields.length + 1 # values also includes raw_entry
107
109
  @field_list_is_valid = true
108
110
  else
109
- raise ArgumentError, "Field mismatch between log pattern and log data. The data is: '#{values.join(':::')}'"
111
+ raise Indy::Source::FieldMismatchException, "Number of expected fields does not match those captured via the regexp pattern.\nThe expected fields are:\n=> #{@entry_fields.join("\n=> ")}\nThe log entry and captured fields are:\n=> #{values.join("\n=> ")}"
110
112
  end
111
113
  end
112
114
 
@@ -17,17 +17,18 @@ class Indy
17
17
  NUMBER_REGEXP = '(\d+)'
18
18
  DQUOTE_DELIM_REGEXP = '"([^"]+)"'
19
19
 
20
- DEFAULT_DATE_TIME = '\d{4}.\d{2}.\d{2}\s+\d{2}.\d{2}.\d{2}' #"%Y-%m-%d %H:%M:%S"
20
+ DEFAULT_DATE_TIME = '\d{4}.\d{2}.\d{2}\s+\d{2}.\d{2}.\d{2}' # "%Y-%m-%d %H:%M:%S"
21
21
  DEFAULT_SEVERITY = [:trace,:debug,:info,:warn,:error,:fatal]
22
22
  DEFAULT_SEVERITY_PATTERN = "(?:#{DEFAULT_SEVERITY.map{|s| s.to_s.upcase}.join("|")})"
23
23
  DEFAULT_APPLICATION = '\w+'
24
24
  DEFAULT_MESSAGE = '.+'
25
25
 
26
- DEFAULT_ENTRY_FIELDS = [:time,:severity,:application,:message]
26
+ DEFAULT_ENTRY_FIELDS = [:time, :severity, :application, :message]
27
27
  DEFAULT_ENTRY_REGEXP = /^(#{DEFAULT_DATE_TIME})\s+(#{DEFAULT_SEVERITY_PATTERN})\s+(#{DEFAULT_APPLICATION})\s+-\s+(#{DEFAULT_MESSAGE})$/
28
28
 
29
29
  COMMON_FIELDS = [:host, :ident, :authuser, :time, :request, :status, :bytes]
30
30
  COMMON_REGEXP = /^#{IPV4_REGEXP} #{SPACE_DELIM_REGEXP} #{SPACE_DELIM_REGEXP} #{BRACKET_DELIM_REGEXP} #{DQUOTE_DELIM_REGEXP} #{HTTP_STATUS_REGEXP} #{NUMBER_REGEXP}$/
31
+ COMMON_TIME_FORMAT = "%d\/%b\/%Y:%H:%M:%S %z"
31
32
 
32
33
  COMBINED_FIELDS = COMMON_FIELDS + [:referrer, :user_agent]
33
34
  COMBINED_REGEXP = /^#{IPV4_REGEXP} #{SPACE_DELIM_REGEXP} #{SPACE_DELIM_REGEXP} #{BRACKET_DELIM_REGEXP} #{DQUOTE_DELIM_REGEXP} #{HTTP_STATUS_REGEXP} #{NUMBER_REGEXP} #{DQUOTE_DELIM_REGEXP} #{DQUOTE_DELIM_REGEXP}$/
@@ -42,7 +43,7 @@ class Indy
42
43
  #
43
44
  # Indy default log format
44
45
  # e.g.:
45
- # INFO 2000-09-07 MyApp - Entering APPLICATION.
46
+ # 2000-09-07 INFO MyApp - Entering APPLICATION.
46
47
  #
47
48
  DEFAULT_LOG_FORMAT = {:entry_regexp => LogFormats::DEFAULT_ENTRY_REGEXP, :entry_fields => LogFormats::DEFAULT_ENTRY_FIELDS}
48
49
 
@@ -59,11 +60,11 @@ class Indy
59
60
  #
60
61
  # NCSA Common Log Format log format
61
62
  #
62
- COMMON_LOG_FORMAT = {:entry_regexp => LogFormats::COMMON_REGEXP, :entry_fields => LogFormats::COMMON_FIELDS}
63
+ COMMON_LOG_FORMAT = {:entry_regexp => LogFormats::COMMON_REGEXP, :entry_fields => LogFormats::COMMON_FIELDS, :time_format => LogFormats::COMMON_TIME_FORMAT}
63
64
 
64
65
  #
65
66
  # NCSA Combined Log Format log format
66
67
  #
67
- COMBINED_LOG_FORMAT = {:entry_regexp => LogFormats::COMBINED_REGEXP, :entry_fields => LogFormats::COMBINED_FIELDS}
68
+ COMBINED_LOG_FORMAT = {:entry_regexp => LogFormats::COMBINED_REGEXP, :entry_fields => LogFormats::COMBINED_FIELDS, :time_format => LogFormats::COMMON_TIME_FORMAT}
68
69
 
69
70
  end
@@ -3,11 +3,10 @@ class Indy
3
3
  class Search
4
4
 
5
5
  attr_accessor :source
6
- attr_accessor :log_definition
7
6
 
8
7
  attr_accessor :start_time, :end_time, :inclusive
9
8
 
10
- def initialize(params_hash)
9
+ def initialize(params_hash={})
11
10
  while (param = params_hash.shift) do
12
11
  send("#{param.first}=",param.last)
13
12
  end
@@ -25,7 +24,7 @@ class Indy
25
24
  results = []
26
25
  results += search do |entry|
27
26
  if type == :all || is_match?(type,entry,search_criteria)
28
- result_struct = @log_definition.create_struct(entry)
27
+ result_struct = @source.log_definition.create_struct(entry)
29
28
  if block_given?
30
29
  block.call(result_struct)
31
30
  else
@@ -38,12 +37,12 @@ class Indy
38
37
 
39
38
  #
40
39
  # Search the @source and yield to the block the entry that was found
41
- # with @log_definition
40
+ # with the LogDefinition
42
41
  #
43
42
  # This method is supposed to be used internally.
44
43
  #
45
44
  def search(&block)
46
- if @log_definition.multiline
45
+ if @source.log_definition.multiline
47
46
  multiline_search(&block)
48
47
  else
49
48
  standard_search(&block)
@@ -58,9 +57,9 @@ class Indy
58
57
  results = []
59
58
  source_lines = (is_time_search ? @source.open([@start_time,@end_time]) : @source.open)
60
59
  source_lines.each do |single_line|
61
- hash = @log_definition.parse_entry(single_line)
60
+ hash = @source.log_definition.parse_entry(single_line)
62
61
  next unless hash
63
- next unless Indy::Time.inside_time_window?(hash[:time],@start_time,@end_time,@inclusive) if is_time_search
62
+ next unless inside_time_window?(hash[:time],@start_time,@end_time,@inclusive) if is_time_search
64
63
  results << (block.call(hash) if block_given?)
65
64
  end
66
65
  results.compact
@@ -72,10 +71,10 @@ class Indy
72
71
  def multiline_search(&block)
73
72
  is_time_search = use_time_criteria?
74
73
  source_io = StringIO.new( (is_time_search ? @source.open([@start_time,@end_time]) : @source.open ).join("\n") )
75
- results = source_io.read.scan(@log_definition.entry_regexp).collect do |entry|
76
- hash = @log_definition.parse_entry_captures(entry)
74
+ results = source_io.read.scan(@source.log_definition.entry_regexp).collect do |entry|
75
+ hash = @source.log_definition.parse_entry_captures(entry)
77
76
  next unless hash
78
- next unless Indy::Time.inside_time_window?(hash[:time],@start_time,@end_time,@inclusive) if is_time_search
77
+ next unless inside_time_window?(hash[:time],@start_time,@end_time,@inclusive) if is_time_search
79
78
  block.call(hash) if block_given?
80
79
  end
81
80
  results.compact
@@ -87,8 +86,8 @@ class Indy
87
86
  def use_time_criteria?
88
87
  if @start_time || @end_time
89
88
  # ensure both boundaries are set
90
- @start_time ||= Indy::Time.forever_ago(@log_definition.time_format)
91
- @end_time ||= Indy::Time.forever(@log_definition.time_format)
89
+ @start_time ||= Indy::Time.forever_ago(@source.log_definition.time_format)
90
+ @end_time ||= Indy::Time.forever(@source.log_definition.time_format)
92
91
  end
93
92
  @start_time && @end_time
94
93
  end
@@ -114,8 +113,8 @@ class Indy
114
113
  if params_hash[:time]
115
114
  time_scope_from_direction(params_hash[:direction], params_hash[:span], params_hash[:time])
116
115
  else
117
- @start_time = Indy::Time.parse_date(params_hash[:start_time]) if params_hash[:start_time]
118
- @end_time = Indy::Time.parse_date(params_hash[:end_time]) if params_hash[:end_time]
116
+ @start_time = Indy::Time.parse_date(params_hash[:start_time], @source.log_definition.time_format) if params_hash[:start_time]
117
+ @end_time = Indy::Time.parse_date(params_hash[:end_time], @source.log_definition.time_format) if params_hash[:end_time]
119
118
  end
120
119
  @inclusive = params_hash[:inclusive]
121
120
  end
@@ -124,7 +123,7 @@ class Indy
124
123
  # Parse direction, span, and time to set @start_time and @end_time
125
124
  #
126
125
  def time_scope_from_direction(direction, span, time)
127
- time = Indy::Time.parse_date(time)
126
+ time = Indy::Time.parse_date(time, @source.log_definition.time_format)
128
127
  span = (span.to_i * 60).seconds if span
129
128
  if direction == :before
130
129
  @end_time = time
@@ -142,6 +141,19 @@ class Indy
142
141
  @inclusive = @start_time = @end_time = nil
143
142
  end
144
143
 
145
- end
144
+ #
145
+ # Evaluate if a log entry satisfies the configured time conditions
146
+ #
147
+ def inside_time_window?(time_string,start_time,end_time,inclusive)
148
+ time = Indy::Time.parse_date(time_string, @source.log_definition.time_format)
149
+ return false unless time
150
+ if inclusive
151
+ return true unless (time > end_time || time < start_time)
152
+ else
153
+ return true unless (time >= end_time || time <= start_time)
154
+ end
155
+ return false
156
+ end
146
157
 
158
+ end
147
159
  end
@@ -5,6 +5,12 @@ class Indy
5
5
  #
6
6
  class Source
7
7
 
8
+ # Exception raised when entry regexp does not match data
9
+ class FieldMismatchException < Exception; end
10
+
11
+ # log definition
12
+ attr_accessor :log_definition
13
+
8
14
  # log source type. :cmd, :file, or :string
9
15
  attr_reader :type
10
16
 
@@ -14,9 +20,6 @@ class Indy
14
20
  # the StringIO object
15
21
  attr_reader :io
16
22
 
17
- # log definition
18
- attr_reader :log_definition
19
-
20
23
  # Exception raised when unable to open source
21
24
  class Invalid < Exception; end
22
25
 
@@ -27,7 +30,7 @@ class Indy
27
30
  #
28
31
  def initialize(param,log_definition=nil)
29
32
  raise Indy::Source::Invalid, "No source specified." if param.nil?
30
- @log_definition = log_definition || LogDefinition.new()
33
+ self.log_definition = log_definition || LogDefinition.new()
31
34
  return discover_connection(param) unless param.respond_to?(:keys)
32
35
  if param[:cmd]
33
36
  set_connection(:cmd, param[:cmd])
@@ -155,7 +158,20 @@ class Indy
155
158
  # Return the time of a log entry index, with an optional offset
156
159
  #
157
160
  def time_at(index, delta=0)
158
- ::Time.parse(@entries[index + delta])
161
+ begin
162
+ entry = @entries[index + delta]
163
+ time = @log_definition.parse_entry(entry)[:time]
164
+ result = Indy::Time.parse_date(time, @log_definition.time_format)
165
+ rescue FieldMismatchException => fme
166
+ raise
167
+ rescue Exception => e
168
+ msg = "Unable to parse time from entry. Time value was #{time.inspect}. Original exception was:\n#{e.class}\n"
169
+ raise Indy::Time::ParseException, msg + e.message
170
+ end
171
+ if result.nil?
172
+ raise Indy::Time::ParseException, "Unable to parse datetime. Raw value was #{time.inspect}. Entry was #{entry}."
173
+ end
174
+ result
159
175
  end
160
176
 
161
177
  #
@@ -1,38 +1,35 @@
1
+ require 'active_support'
1
2
  require 'active_support/core_ext'
2
3
 
3
4
  class Indy
4
5
 
5
6
  class Time
6
7
 
8
+ # Exception raised when unable to parse an entry's time value
9
+ class ParseException < Exception; end
10
+
7
11
  class << self
8
12
 
9
13
  #
10
14
  # Return a valid DateTime object for the log entry string or hash
11
15
  #
12
- # @param [String, Hash] param The log entry string or hash
16
+ # @param [String, Hash] time The log entry string or hash
17
+ #
18
+ # @param [String] time_format String of #strftime directives to define format
13
19
  #
14
20
  def parse_date(time,time_format=nil)
15
21
  return time if time.kind_of? ::Time or time.kind_of? DateTime
16
22
  if time_format
17
23
  begin
18
- # Attempt the appropriate parse method
19
24
  DateTime.strptime(time, time_format)
20
25
  rescue
21
- # If appropriate, fall back to simple parse method
22
26
  DateTime.parse(time) rescue nil
23
27
  end
24
28
  else
25
29
  begin
26
- # If appropriate, fall back to simple parse method
27
30
  ::Time.parse(time)
28
31
  rescue => e
29
32
  raise "Failed to create time object. The error was: #{e.message}"
30
- #begin
31
- # # one last try!!
32
- # DateTime.parse(time)
33
- #rescue Exception => e
34
- # raise "Failed to create time object. The error was: #{e.message}"
35
- #end
36
33
  end
37
34
  end
38
35
  end
@@ -56,23 +53,6 @@ class Indy
56
53
  end
57
54
  end
58
55
 
59
- #
60
- # Evaluate if a log entry satisfies the configured time conditions
61
- #
62
- # @param [Hash] entry_hash The log entry's hash
63
- #
64
- def inside_time_window?(time_string,start_time,end_time,inclusive)
65
- time = Indy::Time.parse_date(time_string)
66
- #return false unless time && entry_hash
67
- if inclusive
68
- true unless time > end_time or time < start_time
69
- else
70
- true unless time >= end_time or time <= start_time
71
- end
72
- end
73
-
74
56
  end
75
-
76
57
  end
77
-
78
58
  end
@@ -1,7 +1,7 @@
1
1
 
2
2
  class Indy
3
3
 
4
- VERSION = '0.4.0.pre'
4
+ VERSION = '0.5.0'
5
5
 
6
6
  def self.show_version_changes(version)
7
7
  date = ""
@@ -12,12 +12,12 @@ describe 'Indy' do
12
12
  end
13
13
 
14
14
  it "#last_entries should return an array of Struct::Entry object" do
15
- @indy.send(:last_entries, 2).class.should == Array
16
- @indy.send(:last_entries, 2).first.class.should == Struct::Entry
15
+ expect(@indy.send(:last_entries, 2).class).to eq(Array)
16
+ expect(@indy.send(:last_entries, 2).first.class).to eq(Struct::Entry)
17
17
  end
18
18
 
19
19
  it "#last_entries should return correct Struct::Entry objects" do
20
- @indy.send(:last_entries, 2).first.time.should == '2000-09-07 14:07:43'
20
+ expect(@indy.send(:last_entries, 2).first.time).to eq('2000-09-07 14:07:43')
21
21
  end
22
22
 
23
23
  end
@@ -7,20 +7,20 @@ describe 'Indy' do
7
7
  it "should accept v0.3.4 initialization params" do
8
8
  indy_obj = Indy.new(:source => "foo\nbar\n").with(Indy::DEFAULT_LOG_FORMAT)
9
9
  search_obj = indy_obj.search
10
- search_obj.log_definition.class.should eq Indy::LogDefinition
11
- search_obj.log_definition.entry_regexp.class.should eq Regexp
12
- search_obj.log_definition.entry_fields.class.should eq Array
10
+ expect(search_obj.source.log_definition.class).to eq Indy::LogDefinition
11
+ expect(search_obj.source.log_definition.entry_regexp.class).to eq Regexp
12
+ expect(search_obj.source.log_definition.entry_fields.class).to eq Array
13
13
  end
14
14
 
15
15
  it "should not raise error with non-conforming data" do
16
16
  @indy = Indy.new(:source => " \nfoobar\n\n baz", :entry_regexp => '([^\s]+) (\w+)', :entry_fields => [:time, :message])
17
- @indy.all.class.should == Array
17
+ expect(@indy.all.class).to eq(Array)
18
18
  end
19
19
 
20
20
  it "should accept time_format parameter" do
21
21
  @indy = Indy.new(:time_format => '%d-%m-%Y', :source => "1-13-2000 yes", :entry_regexp => '^([^\s]+) (\w+)$', :entry_fields => [:time, :message])
22
- @indy.all.class.should == Array
23
- @indy.search.log_definition.time_format.should == '%d-%m-%Y'
22
+ expect(@indy.all.class).to eq(Array)
23
+ expect(@indy.search.source.log_definition.time_format).to eq('%d-%m-%Y')
24
24
  end
25
25
 
26
26
  it "should accept an initialization hash passed to #search" do
@@ -29,8 +29,8 @@ describe 'Indy' do
29
29
  :entry_regexp => '^([^\s]+) (\w+)$',
30
30
  :entry_fields => [:time, :message]}
31
31
  @indy = Indy.search(hash)
32
- @indy.class.should == Indy
33
- @indy.all.length.should == 1
32
+ expect(@indy.class).to eq(Indy)
33
+ expect(@indy.all.length).to eq(1)
34
34
  end
35
35
 
36
36
  end
@@ -47,49 +47,51 @@ describe 'Indy' do
47
47
  context "method" do
48
48
 
49
49
  it "#with should return self" do
50
- @indy.with().class.should == Indy
50
+ expect(@indy.with().class).to eq(Indy)
51
51
  end
52
52
 
53
53
  it "#with should use default log pattern when passed :default" do
54
- @indy.with(:default).all.length.should == 3
54
+ expect(@indy.with(:default).all.length).to eq(3)
55
55
  end
56
56
 
57
- it "should raise ArgumentError when regexp captures don't match fields" do
57
+ it "should raise Exception when regexp captures don't match fields" do
58
58
  log = [ "2000-09-07 14:06:41 INFO MyApp - Entering APPLICATION.",
59
59
  "2000-09-07 14:07:42 DEBUG MyApp - Initializing APPLICATION."].join("\n")
60
- lambda{ Indy.search(log).
61
- with(:entry_regexp => Indy::LogFormats::DEFAULT_ENTRY_REGEXP, :entry_fields => [:field_one]).
62
- all.length.should > 0
63
- }.should raise_error ArgumentError
60
+ expect{
61
+ expect(Indy.search(log).
62
+ with(:entry_regexp => Indy::LogFormats::DEFAULT_ENTRY_REGEXP,
63
+ :entry_fields => [:field_one]
64
+ ).all.length).to be > 0
65
+ }.to raise_error Indy::Source::FieldMismatchException
64
66
  end
65
67
 
66
68
  [:for, :like, :matching].each do |method|
67
69
  it "##{method} should exist" do
68
- @indy.should respond_to(method)
70
+ expect(@indy).to respond_to(method)
69
71
  end
70
72
 
71
73
  it "##{method} should accept a hash of search criteria" do
72
- @indy.send(method,:severity => "INFO").should be_kind_of(Array)
74
+ expect(@indy.send(method,:severity => "INFO")).to be_kind_of(Array)
73
75
  end
74
76
 
75
77
  it "##{method} should return a set of results" do
76
- @indy.send(method,:severity => "DEBUG").should be_kind_of(Array)
78
+ expect(@indy.send(method,:severity => "DEBUG")).to be_kind_of(Array)
77
79
  end
78
80
  end
79
81
 
80
82
  it "#last should return self" do
81
- @indy.last(:span => 1).should be_kind_of Indy
83
+ expect(@indy.last(:span => 1)).to be_kind_of Indy
82
84
  end
83
85
 
84
86
  it "#last should set the time scope to the correct number of minutes" do
85
- @indy.last(:span => 1).all.count.should == 2
87
+ expect(@indy.last(:span => 1).all.count).to eq(2)
86
88
  end
87
89
 
88
90
  it "#last should raise an error if passed an invalid parameter" do
89
- lambda{ @indy.last('a') }.should raise_error( ArgumentError )
90
- lambda{ @indy.last() }.should raise_error( ArgumentError )
91
- lambda{ @indy.last(nil) }.should raise_error( ArgumentError )
92
- lambda{ @indy.last({}) }.should raise_error( ArgumentError )
91
+ expect{ @indy.last('a') }.to raise_error( ArgumentError )
92
+ expect{ @indy.last() }.to raise_error( ArgumentError )
93
+ expect{ @indy.last(nil) }.to raise_error( ArgumentError )
94
+ expect{ @indy.last({}) }.to raise_error( ArgumentError )
93
95
  end
94
96
 
95
97
  end
@@ -98,39 +100,39 @@ describe 'Indy' do
98
100
  context '#search' do
99
101
 
100
102
  it "should be a class method" do
101
- Indy.should respond_to(:search)
103
+ expect(Indy).to respond_to(:search)
102
104
  end
103
105
 
104
106
  it "should accept a string parameter" do
105
- Indy.search("String Log").class.should == Indy
107
+ expect(Indy.search("String Log").class).to eq(Indy)
106
108
  end
107
109
 
108
110
  it "should accept a hash with :cmd key" do
109
- Indy.search(:cmd => "ls").class.should == Indy
111
+ expect(Indy.search(:cmd => "ls").class).to eq(Indy)
110
112
  end
111
113
 
112
114
  it "should accept a hash with :file => filepath" do
113
- Indy.search(:file => "#{File.dirname(__FILE__)}/data.log").all.length.should == 2
115
+ expect(Indy.search(:file => "#{File.dirname(__FILE__)}/data.log").all.length).to eq(2)
114
116
  end
115
117
 
116
118
  it "should accept a hash with :file => File" do
117
- Indy.search(:file => File.open("#{File.dirname(__FILE__)}/data.log")).all.length.should == 2
119
+ expect(Indy.search(:file => File.open("#{File.dirname(__FILE__)}/data.log")).all.length).to eq(2)
118
120
  end
119
121
 
120
122
  it "should accept a valid :source hash" do
121
- Indy.search(:source => {:cmd => 'ls'}).class.should == Indy
123
+ expect(Indy.search(:source => {:cmd => 'ls'}).class).to eq(Indy)
122
124
  end
123
125
 
124
126
  it "should create an instance of Indy::Source in Search object" do
125
- Indy.search("source string").search.source.should be_kind_of(Indy::Source)
127
+ expect(Indy.search("source string").search.source).to be_kind_of(Indy::Source)
126
128
  end
127
129
 
128
130
  it "should raise an exception when passed an invalid source: nil" do
129
- lambda{ Indy.search(nil) }.should raise_error(Indy::Source::Invalid, /No source specified/)
131
+ expect{ Indy.search(nil) }.to raise_error(Indy::Source::Invalid, /No source specified/)
130
132
  end
131
133
 
132
134
  it "should raise an exception when the arity is incorrect" do
133
- lambda{ Indy.search( ) }.should raise_error Indy::Source::Invalid
135
+ expect{ Indy.search( ) }.to raise_error Indy::Source::Invalid
134
136
  end
135
137
 
136
138
  context "with explicit source hash" do
@@ -142,48 +144,46 @@ describe 'Indy' do
142
144
  end
143
145
 
144
146
  it "should attempt open the command" do
145
- IO.stub!(:popen).with('ssh user@system "bash --login -c \"cat /var/log/standard.log\" "')
147
+ allow(IO).to receive(:popen).with('ssh user@system "bash --login -c \"cat /var/log/standard.log\" "')
146
148
  Indy.search(:cmd => 'ssh user@system "bash --login -c \"cat /var/log/standard.log\" "')
147
149
  end
148
150
 
149
151
  it "should not throw an error for an invalid command" do
150
- IO.stub!(:popen).with('an invalid command').and_return('')
151
- Indy.search(:cmd => "an invalid command").class.should == Indy
152
+ allow(IO).to receive(:popen).with('an invalid command').and_return('')
153
+ expect(Indy.search(:cmd => "an invalid command").class).to eq(Indy)
152
154
  end
153
155
 
154
156
  it "should use IO.popen on cmd value" do
155
- IO.stub!(:popen).with("a command").and_return(StringIO.new("2000-09-07 14:07:41 INFO MyApp - Entering APPLICATION."))
156
- Indy.search(:cmd => "a command").for(:application => 'MyApp').length.should == 1
157
+ allow(IO).to receive(:popen).with("a command").and_return(StringIO.new("2000-09-07 14:07:41 INFO MyApp - Entering APPLICATION."))
158
+ expect(Indy.search(:cmd => "a command").for(:application => 'MyApp').length).to eq(1)
157
159
  end
158
160
 
159
161
  it "should handle a real command" do
160
162
  log_file = "data.log"
161
163
  cat_cmd = (is_windows? ? 'type' : 'cat')
162
- Indy.search(:cmd => "#{cat_cmd} #{log_file}").for(:application => 'MyApp').length.should == 2
164
+ expect(Indy.search(:cmd => "#{cat_cmd} #{log_file}").for(:application => 'MyApp').length).to eq(2)
163
165
  end
164
166
 
165
167
  it "should raise Source::Invalid for an invalid command" do
166
- IO.stub!(:popen).with("zzzzzzzzzzzz").and_return('Invalid command')
167
- lambda{ Indy.search(:cmd => "zzzzzzzzzzzz").all }.should raise_error( Indy::Source::Invalid, /Unable to open log source/)
168
+ allow(IO).to receive(:popen).with("zzzzzzzzzzzz").and_return('Invalid command')
169
+ expect{ Indy.search(:cmd => "zzzzzzzzzzzz").all }.to raise_error( Indy::Source::Invalid, /Unable to open log source/)
168
170
  end
169
171
 
170
172
  end
171
173
 
172
174
  it "using :file" do
173
- require 'tempfile'
174
- file = stub!(:size).and_return(1)
175
- lambda{ Indy.search(:file => file) }
175
+ expect(Indy.search(:file => "#{File.dirname(__FILE__)}/data.log").all.length).to eq(2)
176
176
  end
177
177
 
178
178
  it "using :string" do
179
179
  string = "2000-09-07 14:07:41 INFO MyApp - Entering APPLICATION."
180
180
  string_io = StringIO.new(string)
181
- StringIO.should_receive(:new).with(string).ordered.and_return(string_io)
182
- Indy.search(:string => string).for(:application => 'MyApp').length.should == 1
181
+ expect(StringIO).to receive(:new).with(string).ordered.and_return(string_io)
182
+ expect(Indy.search(:string => string).for(:application => 'MyApp').length).to eq(1)
183
183
  end
184
184
 
185
185
  it "should raise error when given an invalid key" do
186
- lambda{ Indy.search(:foo => "a string").all }.should raise_error( Indy::Source::Invalid )
186
+ expect{ Indy.search(:foo => "a string").all }.to raise_error( Indy::Source::Invalid )
187
187
  end
188
188
 
189
189
  end
@@ -196,7 +196,7 @@ describe 'Indy' do
196
196
  log = [ "2000-09-07 14:06:41 INFO MyApp - Entering APPLICATION.",
197
197
  "2000-09-07 14:07:42 DEBUG MyApp - Initializing APPLICATION.",
198
198
  "2000-09-07 14:07:43 INFO MyApp - Exiting APPLICATION."].join("\n")
199
- Indy.search(log).all.length.should == 3
199
+ expect(Indy.search(log).all.length).to eq(3)
200
200
  end
201
201
 
202
202
  it "should ignore invalid entries" do
@@ -204,13 +204,13 @@ describe 'Indy' do
204
204
  "2000-09-07 14:07:41 INFO MyApp - Entering APPLICATION.\n",
205
205
  " bad \n",
206
206
  "2000-09-07 14:07:41 INFO MyApp - Entering APPLICATION.\n\n"].join("\n")
207
- Indy.search(log).all.length.should == 3
207
+ expect(Indy.search(log).all.length).to eq(3)
208
208
  end
209
209
 
210
210
  it "should handle no matching entries" do
211
211
  log = ["2000-09-07 MyApp - Entering APPLICATION.\n \n",
212
212
  "2000-09-07 14:07:41\n"].join
213
- Indy.search(log).all.length.should == 0
213
+ expect(Indy.search(log).all.length).to eq(0)
214
214
  end
215
215
 
216
216
  context "with explicit time format" do
@@ -223,7 +223,7 @@ describe 'Indy' do
223
223
  :time_format => '%d-%Y-%m',
224
224
  :entry_regexp => /^(\d\d-\d\d\d\d-\d\d)\s+(#{Indy::LogFormats::DEFAULT_SEVERITY_PATTERN})\s+(#{Indy::LogFormats::DEFAULT_APPLICATION})\s+-\s+(#{Indy::LogFormats::DEFAULT_MESSAGE})$/,
225
225
  :entry_fields => Indy::LogFormats::DEFAULT_ENTRY_FIELDS)
226
- indy.all.length.should == 2
226
+ expect(indy.all.length).to eq(2)
227
227
  end
228
228
  end
229
229
 
@@ -242,20 +242,20 @@ describe 'Indy' do
242
242
  end
243
243
 
244
244
  it "should return all entries using #all" do
245
- @indy.all.count.should == 5
245
+ expect(@indy.all.count).to eq(5)
246
246
  end
247
247
 
248
248
  it "should return correct number of entries with #for" do
249
- @indy.for(:severity => 'INFO').count.should == 3
249
+ expect(@indy.for(:severity => 'INFO').count).to eq(3)
250
250
  end
251
251
 
252
252
  it "should return correct number of entries with #like" do
253
- @indy.like(:message => 'ntering').count.should == 2
253
+ expect(@indy.like(:message => 'ntering').count).to eq(2)
254
254
  end
255
255
 
256
256
  it "should return correct number of entries using #after time scope" do
257
257
  results = @indy.after(:time => '2000-09-07 14:07:43', :inclusive => false).all
258
- results.length.should == 2
258
+ expect(results.length).to eq(2)
259
259
  end
260
260
 
261
261
  end
@@ -270,7 +270,7 @@ describe 'Indy' do
270
270
 
271
271
  it "with #for should yield Struct::Entry" do
272
272
  Indy.search(log).all do |result|
273
- result.should be_kind_of(Struct::Entry)
273
+ expect(result).to be_kind_of(Struct::Entry)
274
274
  end
275
275
  end
276
276
 
@@ -279,7 +279,7 @@ describe 'Indy' do
279
279
  Indy.search(log).all do |result|
280
280
  actual_yield_count += 1
281
281
  end
282
- actual_yield_count.should == 3
282
+ expect(actual_yield_count).to eq(3)
283
283
  end
284
284
 
285
285
  it "with #for should yield each entry" do
@@ -287,7 +287,7 @@ describe 'Indy' do
287
287
  Indy.search(log).for(:severity => 'INFO') do |result|
288
288
  actual_yield_count += 1
289
289
  end
290
- actual_yield_count.should == 2
290
+ expect(actual_yield_count).to eq(2)
291
291
  end
292
292
 
293
293
  it "with #like should yield each entry" do
@@ -295,7 +295,7 @@ describe 'Indy' do
295
295
  Indy.search(log).like(:message => '\be\S+ing') do |result|
296
296
  actual_yield_count += 1
297
297
  end
298
- actual_yield_count.should == 2
298
+ expect(actual_yield_count).to eq(2)
299
299
  end
300
300
 
301
301
  end