devcreek 0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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