mailto:jenkins,subject:test case1, case2 on http://staging.site.com
So this is something we thought of
– email Jenkins
– to run one or more jobs
– against one of our deployed staging apps(given base_url)
We wrote a mail_watcher.rb, which periodically reads such emails, and rewrite <JENKINS_CHECKS_DIR>/<test_case_name>.checks files adding parameters to be passed on to the test case. In this case it is BASE_URL=. And all we know that we could make Jenkins
1. watch files getting modified
2. use file contents(key=val), as paramters further to be used or passed on to the job exec
Ohh, wait, I did not know how could Jenkins read parameters from a given key=val file and pass it on further. We actaully wrote another shell script which runs as the first step of every job and reads the testcase_name.checks file and set ENV variables like for example BASE_URL.
So in case of subject:test testcase1 on http://mysite.com
– mail watcher will write testcase1.checks file with BASE_URL=http://mysite.com
– shell script will set ENV variable BASE_URL=http://mysite.com
Following is the mail watcher that we simply run to be able to get Jenkins job triggered.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'net/imap' | |
class MailWatcher | |
Server = 'imap.gmail.com' | |
Username = '' | |
Password = '' | |
Folder = 'INBOX' | |
PollingInterval = 60 | |
CheckFileLocation = "#{File.dirname(__FILE__)}/../../tmp/checks/" | |
def fetch | |
@imap = Net::IMAP.new Server, 993, true | |
@imap.login Username, Password | |
@imap.select Folder | |
@imap.search(["NOT", "SEEN"]).each do |message_id| | |
env = @imap.fetch(message_id, "ENVELOPE")[0].attr["ENVELOPE"] | |
@subject = env.subject | |
return unless @subject.match(/^test .+/) | |
test_cases.each do |test_case_name| | |
File.open("#{CheckFileLocation}#{test_case_name}.check",'w') { |file| file.puts base_url } | |
end | |
mark_delete message_id | |
end | |
@imap.logout | |
@imap.disconnect | |
end | |
def start_watching | |
while(1) do | |
fetch | |
sleep PollingInterval | |
end | |
end | |
def base_url | |
@base_url ||= "base_url=#{@subject.match(/ on (https?\:\/\/[a-z\.]+)$/)[1]}" rescue 'base_url=' | |
end | |
def test_cases | |
@test_cases = @subject.split(' on http').first[5..-1].strip.split(',').collect{ |test_case| test_case.strip.gsub(' ','_')} | |
end | |
def mark_delete message_id | |
@imap.store(message_id, "+FLAGS", [:Seen]) | |
@imap.store(message_id, "+FLAGS", [:Deleted]) | |
end | |
end | |
Process.daemon(true) | |
MailWatcher.new.start_watching |
Now any of us teammates, can anytime send an email and get a test case executed. In addition we are as well generating a detailed report email for each job-run that gets published on a Google group. We do have our own custom, half-baked, reporting mechanism(ruby code), which we want to compile the job-execution-report email for each testcase/job executed.
Example reports
subject: testcase1 failed.
body: <Jenkins console output>
subject: rspec 231 passed, 2 failed.
body: <Jenkins console output>