aboutsummaryrefslogtreecommitdiff
path: root/test/mauve_test_helper.rb
blob: 8653bd596c091252af6ac72ff8906724d1c935a2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
require 'tmpdir'
require 'thread'
require 'timeout'
require 'mauve/configuration'

Thread.abort_on_exception = true

module MauveTestHelper
  include Mauve
  Notifications = Queue.new
  
  # Returns the base directory for temporary files for this test instance
  #
  def dir
    if !@test_dir
      now = ::Time.now
      base=Dir.tmpdir+"/mauve_test"
      Dir.mkdir(base) unless File.directory?(base)
      base=base+"/#{$$}"
      Dir.mkdir(base) unless File.directory?(base)
      Dir.mkdir(@test_dir="#{base}/#{name}")
    end
    @test_dir
  end
  
  # Starts the Mauve server with a configuration supplied as a string.
  #
  def start_server(config)
    @here = File.expand_path(__FILE__).split("/")[0..-2].join("/") + "/.."
    File.open("#{dir}/config_file", "w") { |fh| fh.write(config) }
    Notifications.clear
    
    Configuration.current = ConfigurationBuilder.load("#{dir}/config_file")
    Time.reset_to_midnight
    @thread = Thread.new do
      begin
        Configuration.current.server.run
      rescue Interrupt
        Configuration.current.close
      end
    end
    # avoids races if we try to shut down too quickly
    Configuration.current.server.sleep_until_ready
    Log.info "TEST RUN STARTED: #{name}"
  end
  
  # Stops the Mauve server, should reset it ready to start again within the
  # same process.
  #
  def stop_server
    @thread.raise(Interrupt.new)
    @thread.join
  end
  
  # Send an alert to the server, return when the server process has definitely
  # processed it (or die after 2s).
  #
  def mauvesend(cmd)
    Configuration.current.server.sleep_until_ready
    output = `TEST_TIME=#{Time.now.to_i} #{@here}/mauve_starter.rb #{@here}/bin/mauvesend -v 127.0.0.1:44444 #{cmd} 2>&1`
    status = $?.exitstatus
    raise "Exit #{status} from command: '#{output}'" unless status == 0
    raise "mauvesend did not return an integer" unless output.to_i > 0
    begin
      timeout(2) { Configuration.current.server.sleep_until_transmission_id_received(output.to_i) }
    rescue Timeout::Error
      flunk("Did not receive transmission id '#{output}'")
    end
  end
  
  # Assuming the test configuration contains a notification method with 
  # "deliver_to_queue TestClass::Notifications", this helper will return the next
  # alert notification by that method as a triplet:
  #
  #   [destination, alert, other_alerts]
  #
  # e.g. destination will be an email address, phone number or xmpp ID, just
  # as in the configuration file.  alert will be the subject of this 
  # alert, and other_alerts will be the other notifications that
  # are relevant for this person at this time.
  #
  # The test will fail after 2s if no alert is received.
  #
  def with_next_notification
    Timers.restart_and_then_wait_until_idle
    flunk("Nothing on Notifications queue when I expected one") if Notifications.empty?
    yield(*Notifications.pop)
  end
  
  def discard_next_notification
    with_next_notification { }
  end
  
  # The reverse of next_alert, the test fails if an alert is received
  # within 2s.
  # 
  def assert_no_notification
    Timers.restart_and_then_wait_until_idle
    flunk("#{Notifications.pop.inspect} on Notifications queue when I expected nothing") unless 
      Notifications.empty?
    true
  end
end