devcreek 0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,10 @@
1
+ # devcreek.rb
2
+ #
3
+ # Copyright Caleb Powell 2007
4
+ #
5
+ # Licensed under the LGPL, see the file README.txt in the distribution
6
+
7
+ require 'devcreek_testrunnermediator.rb' #for test/unit library
8
+ module DevCreek
9
+ VERSION = "0.1"
10
+ end
@@ -0,0 +1,28 @@
1
+ # devcreek_core.rb
2
+ #
3
+ # Copyright Caleb Powell 2007
4
+ #
5
+ # Licensed under the LGPL, see the file COPYING in the distribution
6
+
7
+ require 'yaml'
8
+
9
+ module DevCreek
10
+ class Core
11
+ require 'singleton'
12
+ require 'socket'
13
+ include Singleton
14
+ attr_accessor :principal, :project, :user, :password, :enabled
15
+
16
+ def load(attributes=Hash.new)
17
+ attributes.each do |key, val|
18
+ instance_variable_set("@#{key}", val)
19
+ end
20
+ end
21
+
22
+ def load_from_yaml(file_name)
23
+ load(YAML.load_file(file_name))
24
+ end
25
+ end
26
+
27
+ Core.instance.principal = Socket.gethostname
28
+ end
@@ -0,0 +1,67 @@
1
+ # devcreek_record_template.rb
2
+ #
3
+ # Copyright Caleb Powell 2007
4
+ #
5
+ # Licensed under the LGPL, see the file COPYING in the distribution
6
+
7
+ module DevCreek
8
+ TRANSMISSION_RECORD_TEMPLATE = %{
9
+ <record>
10
+ <core.principal><%= DevCreek::Core.instance.principal %></core.principal>
11
+ <core.project><%= DevCreek::Core.instance.project %></core.project>
12
+ <core.sessionId><%= session_id %></core.sessionId>
13
+ <core.timeStamp><%= start.localtime.to_i * 1000 %></core.timeStamp>
14
+ <core.timeZoneOffset><%= start.localtime.gmt_offset * 1000 %></core.timeZoneOffset>
15
+ <core.type>unittest.TestRunStarted</core.type>
16
+ <unittest.testCount><%= run_count %></unittest.testCount>
17
+ <unittest.testFramework><%= framework %></unittest.testFramework>
18
+ <unittest.testLanguage>ruby</unittest.testLanguage>
19
+ <unittest.testRunLauncher>manual</unittest.testRunLauncher>
20
+ </record>
21
+ <% test_results.values.each do |test_result| %>
22
+ <record>
23
+ <core.principal><%= DevCreek::Core.instance.principal %></core.principal>
24
+ <core.project><%= DevCreek::Core.instance.project %></core.project>
25
+ <core.sessionId><%= session_id %></core.sessionId>
26
+ <core.timeStamp><%= test_result.start.localtime.to_i * 1000 %></core.timeStamp>
27
+ <core.timeZoneOffset><%= test_result.start.localtime.gmt_offset * 1000 %></core.timeZoneOffset>
28
+ <core.type>unittest.TestStarted</core.type>
29
+ <unittest.testClass><%= test_result.test_class %></unittest.testClass>
30
+ <unittest.testFramework><%= framework %></unittest.testFramework>
31
+ <unittest.testLanguage>ruby</unittest.testLanguage>
32
+ <unittest.testName><%= test_result.test_name %></unittest.testName>
33
+ <unittest.testRunLauncher>manual</unittest.testRunLauncher>
34
+ </record>
35
+ <record>
36
+ <core.principal><%= DevCreek::Core.instance.principal %></core.principal>
37
+ <core.project><%= DevCreek::Core.instance.project %></core.project>
38
+ <core.sessionId><%= session_id %></core.sessionId>
39
+ <core.timeStamp><%= test_result.finish.localtime.to_i * 1000 %></core.timeStamp>
40
+ <core.timeZoneOffset><%= test_result.finish.localtime.gmt_offset * 1000 %></core.timeZoneOffset>
41
+ <core.type>unittest.TestEnded</core.type>
42
+ <unittest.testClass><%= test_result.test_class %></unittest.testClass>
43
+ <unittest.testFramework><%= framework %></unittest.testFramework>
44
+ <unittest.testLanguage>ruby</unittest.testLanguage>
45
+ <unittest.testName><%= test_result.test_name %></unittest.testName>
46
+ <unittest.testRunLauncher>manual</unittest.testRunLauncher>
47
+ <unittest.testStatus><%= test_result.status %></unittest.testStatus>
48
+ </record>
49
+ <% end %>
50
+ <record>
51
+ <core.elapsedTime><%= elapsed_time %></core.elapsedTime>
52
+ <core.principal><%= DevCreek::Core.instance.principal %></core.principal>
53
+ <core.project><%= DevCreek::Core.instance.project %></core.project>
54
+ <core.sessionId><%= session_id %></core.sessionId>
55
+ <core.timeStamp><%= finish.localtime.to_i * 1000 %></core.timeStamp>
56
+ <core.timeZoneOffset><%= finish.localtime.gmt_offset * 1000 %></core.timeZoneOffset>
57
+ <core.type>unittest.TestRunEnded</core.type>
58
+ <unittest.errorTotal><%= error_count %></unittest.errorTotal>
59
+ <unittest.failureTotal><%= failure_count %></unittest.failureTotal>
60
+ <unittest.successTotal><%= success_count %></unittest.successTotal>
61
+ <unittest.testFramework><%= framework %></unittest.testFramework>
62
+ <unittest.testLanguage>ruby</unittest.testLanguage>
63
+ <unittest.testRunLauncher>manual</unittest.testRunLauncher>
64
+ <unittest.testRunStatus>ENDED</unittest.testRunStatus>
65
+ </record>
66
+ }.gsub(/^ /, '').freeze
67
+ end
@@ -0,0 +1,36 @@
1
+ # devcreek_testresult.rb
2
+ #
3
+ # Copyright Caleb Powell 2007
4
+ #
5
+ # Licensed under the LGPL, see the file COPYING in the distribution
6
+
7
+ module DevCreek
8
+ class TestResult
9
+ OK = "OK"
10
+ FAILURE = "FAILURE"
11
+ ERROR = "ERROR"
12
+
13
+ attr_reader :test_name, :test_class, :start, :finish, :status
14
+
15
+ def initialize(test_name, test_class, status=OK, start=Time.now)
16
+ @test_name, @test_class, @status, @start = test_name, test_class, status, start
17
+ end
18
+
19
+ def has_finished
20
+ raise ArgumentError, "The finish time cannot be set twice" unless @finish.nil?
21
+ @finish = Time.now
22
+ end
23
+
24
+ def elapsed_time
25
+ return finish - start unless finish.nil? or start.nil?
26
+ end
27
+
28
+ def has_a_failure
29
+ @status = FAILURE
30
+ end
31
+
32
+ def has_an_error
33
+ @status = ERROR
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,80 @@
1
+ # devcreek_testrunnermediator.rb
2
+ #
3
+ # Copyright Caleb Powell 2007
4
+ #
5
+ # Licensed under the LGPL, see the file COPYING in the distribution
6
+
7
+ require 'test/unit'
8
+ require 'test/unit/util/observable'
9
+ require 'test/unit/testresult'
10
+ require 'devcreek_testresult'
11
+ require 'devcreek_testsuite'
12
+ require 'devcreek_transmitter'
13
+ require 'devcreek_core'
14
+ require 'rubygems'
15
+ require 'uuidtools'
16
+ require 'test/unit/ui/testrunnermediator'
17
+
18
+ #class Test::Unit::TestCase
19
+ # alias_method :old_run, :run
20
+ # def run(*args)
21
+ # puts "TestCase.run.start #{name}"
22
+ ## result = old_run(*args, &block)
23
+ # puts "TestCase.run.start #{name}"
24
+ # end
25
+ #end
26
+
27
+ class Test::Unit::UI::TestRunnerMediator
28
+ alias_method :old_initialize, :initialize
29
+ def initialize(*args)
30
+ result = old_initialize(*args)
31
+
32
+ #DevCreek Modifications
33
+ @@dev_creek_test_suite = nil
34
+ @@dev_creek_reg = /([\w]*)\(([\w]*)\)/
35
+
36
+ add_listener(Test::Unit::UI::TestRunnerMediator::STARTED) do |test_result|
37
+ @@dev_creek_test_suite = DevCreek::TestSuite.new("Test::Unit")
38
+ end
39
+
40
+ add_listener(Test::Unit::TestCase::STARTED) do |name|
41
+ test_name = name.match(@@dev_creek_reg)[1]
42
+ test_class = name.match(@@dev_creek_reg)[2]
43
+ @@dev_creek_test_suite.test_results[name] = DevCreek::TestResult.new(test_name, test_class)
44
+ end
45
+
46
+ add_listener(Test::Unit::TestResult::FAULT) do |fault|
47
+ dc_test_result = @@dev_creek_test_suite.test_results[fault.test_name]
48
+ if fault.instance_of? Test::Unit::Failure
49
+ dc_test_result.has_a_failure
50
+ else
51
+ dc_test_result.has_an_error
52
+ end
53
+ end
54
+
55
+ add_listener(Test::Unit::TestCase::FINISHED) do |test_name|
56
+ @@dev_creek_test_suite.test_results[test_name].has_finished
57
+ end
58
+
59
+ add_listener(Test::Unit::UI::TestRunnerMediator::FINISHED) do |elapsed_time|
60
+ if DevCreek::Core.instance().enabled != false
61
+ @@dev_creek_test_suite.has_finished
62
+ if @@dev_creek_test_suite.has_test_results?
63
+ session_id = UUID.timestamp_create().to_s
64
+ xml_data = @@dev_creek_test_suite.to_xml(session_id)
65
+ puts xml_data
66
+ p 'Attempting DevCreek transmission...'
67
+ response = DevCreek::Transmitter.submit(session_id, xml_data)
68
+ case response
69
+ when Net::HTTPSuccess
70
+ puts '...transmission successful.'
71
+ else
72
+ puts "...failure transmiting TestUnit results to DevCreek: ${response.error!}"
73
+ end
74
+ end
75
+ end
76
+ end
77
+
78
+ return result
79
+ end
80
+ end
@@ -0,0 +1,58 @@
1
+ # devcreek_testsuite.rb
2
+ #
3
+ # Copyright Caleb Powell 2007
4
+ #
5
+ # Licensed under the LGPL, see the file COPYING in the distribution
6
+
7
+ require 'devcreek_core'
8
+ require 'devcreek_record_template'
9
+ require 'erb'
10
+
11
+ module DevCreek
12
+ class TestSuite
13
+ attr_accessor :test_results, :elapsed_time
14
+ attr_reader :start, :framework, :finish, :session_id
15
+ def initialize(framework)
16
+ @framework, @test_results, @start, @elapsed_time = framework, {}, Time.new, 0.0
17
+ end
18
+
19
+ private
20
+ def sum_test_results_with_status(status)
21
+ success = 0
22
+ test_results.values.each do |test|
23
+ success = success + 1 if test.status == status;
24
+ end
25
+ return success
26
+ end
27
+
28
+ public
29
+ def run_count
30
+ return test_results.size
31
+ end
32
+
33
+ def has_test_results?
34
+ return run_count > 0
35
+ end
36
+
37
+ def success_count
38
+ return sum_test_results_with_status("OK")
39
+ end
40
+
41
+ def failure_count
42
+ return sum_test_results_with_status("FAILURE")
43
+ end
44
+
45
+ def error_count
46
+ return sum_test_results_with_status("ERROR")
47
+ end
48
+
49
+ def has_finished
50
+ raise ArgumentError, "The finish time cannot be set twice" unless @finish.nil?
51
+ @finish = Time.now
52
+ end
53
+
54
+ def to_xml(session_id)
55
+ ERB.new(DevCreek::TRANSMISSION_RECORD_TEMPLATE, 0, "%<>").result(binding).gsub(/^ /, '')
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,35 @@
1
+ # devcreektansmitter_.rb
2
+ #
3
+ # Copyright Caleb Powell 2007
4
+ #
5
+ # Licensed under the LGPL, see the file COPYING in the distribution
6
+
7
+ require 'net/http'
8
+ require 'digest_auth'
9
+ require 'devcreek_core'
10
+
11
+ module DevCreek
12
+ module Transmitter
13
+
14
+ SUBMIT_URL = "http://devcreek.com/submitData/"
15
+
16
+ def Transmitter.submit(session_id, xml_data)
17
+
18
+ raise Exception.new("Invalid argument: session_id and xml_data cannot be nil") if session_id.nil? or xml_data.nil?
19
+ raise Exception.new("Core data not initialized") if DevCreek::Core.instance().project.nil? or
20
+ DevCreek::Core.instance().user.nil? or
21
+ DevCreek::Core.instance().password.nil?
22
+
23
+ url = URI.parse("#{SUBMIT_URL}#{DevCreek::Core.instance().project}/#{session_id}")
24
+ response = nil
25
+ Net::HTTP.start(url.host) do |http|
26
+ res = http.head(url.request_uri)
27
+ req = Net::HTTP::Post.new(url.path)
28
+ req.body= xml_data
29
+ req.digest_auth(DevCreek::Core.instance().user, DevCreek::Core.instance().password, res)
30
+ response = http.request(req)
31
+ end
32
+ return response
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,37 @@
1
+ # Written by Eric Hodel <drbrain@segment7.net>
2
+
3
+ require 'digest/md5'
4
+ require 'net/http'
5
+
6
+ module Net
7
+ module HTTPHeader
8
+ @@nonce_count = -1
9
+ CNONCE = Digest::MD5::hexdigest("%x" % (Time.now.to_i + rand(65535)))
10
+ def digest_auth(user, password, response) # based on http://segment7.net/projects/ruby/snippets/digest_auth.rb
11
+ @@nonce_count += 1
12
+ response['www-authenticate'] =~ /^(\w+) (.*)/
13
+ params = {}
14
+ $2.gsub(/(\w+)="(.*?)"/) { params[$1] = $2 }
15
+ a_1 = "#{user}:#{params['realm']}:#{password}"
16
+ a_2 = "#{@method}:#{@path}"
17
+ request_digest = ''
18
+ request_digest << Digest::MD5.hexdigest(a_1)
19
+ request_digest << ':' << params['nonce']
20
+ request_digest << ':' << ('%08x' % @@nonce_count)
21
+ request_digest << ':' << CNONCE
22
+ request_digest << ':' << params['qop']
23
+ request_digest << ':' << Digest::MD5.hexdigest(a_2)
24
+ header = []
25
+ header << "Digest username=\"#{user}\""
26
+ header << "realm=\"#{params['realm']}\""
27
+ header << "qop=#{params['qop']}"
28
+ header << "algorithm=MD5"
29
+ header << "uri=\"#{@path}\""
30
+ header << "nonce=\"#{params['nonce']}\""
31
+ header << "nc=#{'%08x' % @@nonce_count}"
32
+ header << "cnonce=\"#{CNONCE}\""
33
+ header << "response=\"#{Digest::MD5.hexdigest(request_digest)}\""
34
+ @header['Authorization'] = header
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,45 @@
1
+ # test_fiction.rb
2
+ #
3
+ # Copyright Caleb Powell 2007
4
+ #
5
+ # Licensed under the LGPL, see the file COPYING in the distribution
6
+
7
+ require 'test/unit'
8
+
9
+ class TestFiction < Test::Unit::TestCase
10
+
11
+ def test_success
12
+ assert(true)
13
+ end
14
+
15
+ def test_fail
16
+ assert(false)
17
+ end
18
+
19
+ def test_error
20
+ raise "I just disagree"
21
+ end
22
+
23
+ end
24
+
25
+ class TestMoreFiction < Test::Unit::TestCase
26
+
27
+ def test_success
28
+ assert(true)
29
+ end
30
+
31
+ def test_just_for_fun
32
+ assert true
33
+ end
34
+
35
+ def test_fail
36
+ assert(false)
37
+ end
38
+
39
+ def test_error
40
+ raise "I just disagree"
41
+ end
42
+
43
+
44
+ end
45
+
@@ -0,0 +1,70 @@
1
+ # testcore_spec.rb
2
+ #
3
+ # Copyright Caleb Powell 2007
4
+ #
5
+ # Licensed under the LGPL, see the file COPYING in the distribution
6
+
7
+ $LOAD_PATH.push(FileUtils::pwd + '/lib')
8
+ require 'devcreek'
9
+ require 'socket'
10
+
11
+ describe DevCreek::Core do
12
+
13
+ before :each do
14
+ DevCreek::Core.instance().load(
15
+ :user => nil,
16
+ :password => nil,
17
+ :project => nil
18
+ )
19
+ end
20
+
21
+ it "should be a singleton" do
22
+ lambda{Core.new}.should raise_error(NameError)
23
+ end
24
+
25
+ it "should have a principal attribute that defaults to the hostname" do
26
+ DevCreek::Core.instance().principal().should eql(Socket.gethostname)
27
+ end
28
+
29
+ it "should have a principal attribute that is mutable" do
30
+ DevCreek::Core.instance().principal().should_not eql("")
31
+ DevCreek::Core.instance().principal= "Mutable"
32
+ DevCreek::Core.instance().principal().should eql("Mutable")
33
+ end
34
+
35
+ it "load method should parse a Hash and set the properties correctly" do
36
+ DevCreek::Core.instance().user().should be_nil
37
+ DevCreek::Core.instance().password().should be_nil
38
+ DevCreek::Core.instance().project().should be_nil
39
+
40
+ DevCreek::Core.instance().load(
41
+ :user => 'foo@bar.com',
42
+ :password => 'pass_it_on',
43
+ :project => 'fooProject'
44
+ )
45
+
46
+ DevCreek::Core.instance().user().should eql("foo@bar.com")
47
+ DevCreek::Core.instance().password().should eql("pass_it_on")
48
+ DevCreek::Core.instance().project().should eql("fooProject")
49
+ end
50
+
51
+ it "load_from_yaml method should parse the file and set the properties correctly" do
52
+ DevCreek::Core.instance().user().should be_nil
53
+ DevCreek::Core.instance().password().should be_nil
54
+ DevCreek::Core.instance().project().should be_nil
55
+
56
+
57
+ def YAML.load_file(filename)
58
+ return {:user => 'foo@bar.com',
59
+ :password => 'pass_it_on',
60
+ :project => 'fooProject'}
61
+ end
62
+
63
+ DevCreek::Core.instance().load_from_yaml("props.yaml")
64
+
65
+ DevCreek::Core.instance().user().should eql("foo@bar.com")
66
+ DevCreek::Core.instance().password().should eql("pass_it_on")
67
+ DevCreek::Core.instance().project().should eql("fooProject")
68
+ end
69
+
70
+ end