travis-surveillance 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,60 @@
1
+ module Travis
2
+ module Surveillance
3
+ class Project
4
+ attr_accessor :description, :id, :name, :owner, :slug, :status
5
+
6
+ def initialize(name)
7
+ @owner, @name = name.split('/')
8
+ @slug = name
9
+ populate
10
+ end
11
+
12
+ def add_build(json)
13
+ if build = build_for(json['id'])
14
+ return build
15
+ end
16
+
17
+ build = Build.new(json.merge({'project' => self}))
18
+ builds << build
19
+ build
20
+ end
21
+
22
+ def build_for(id)
23
+ builds.find { |b| b.id == id }
24
+ end
25
+
26
+ def building?
27
+ status.nil?
28
+ end
29
+
30
+ def builds
31
+ @builds ||= []
32
+ end
33
+
34
+ def failed?
35
+ !status.nil? && !passed?
36
+ end
37
+
38
+ def passed?
39
+ !status.nil? && status.zero?
40
+ end
41
+
42
+ private
43
+
44
+ def get_details
45
+ if Travis::Surveillance.mocking?
46
+ JSON.parse(IO.read(File.dirname(__FILE__) + "/../../../spec/support/projects/#{slug.gsub('/', '-')}.json"))
47
+ else
48
+ JSON.parse(open("http://travis-ci.org/#{slug}.json").read)
49
+ end
50
+ end
51
+
52
+ def populate
53
+ details = get_details
54
+ @description = details['description']
55
+ @id = details['id']
56
+ @status = details['last_build_status']
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,106 @@
1
+ require "json"
2
+ require "open-uri"
3
+
4
+ gem "pusher-client-merman"
5
+ require "pusher-client"
6
+ PusherClient.logger.level = Logger::INFO
7
+
8
+ module Travis
9
+ module Surveillance
10
+ class Surveyor
11
+ attr_accessor :project, :socket
12
+
13
+ def initialize(project, pusher_token = "23ed642e81512118260e")
14
+ @project = project
15
+ @socket = PusherClient::Socket.new(pusher_token)
16
+ end
17
+
18
+ def survey(&block)
19
+ @socket.subscribe('common')
20
+
21
+ @socket['common'].bind('build:started') do |payload|
22
+ payload_to_new_build(payload)
23
+ yield if block_given?
24
+ end
25
+ @socket['common'].bind('build:finished') do |payload|
26
+ payload_to_finished_build(payload)
27
+ yield if block_given?
28
+ end
29
+ @socket['common'].bind('job:started') do |payload|
30
+ payload_to_job_started(payload)
31
+ yield if block_given?
32
+ end
33
+ @socket['common'].bind('job:finished') do |payload|
34
+ payload_to_job_finished(payload)
35
+ yield if block_given?
36
+ end
37
+
38
+ @socket.connect unless Travis::Surveillance.mocking?
39
+ end
40
+
41
+ private
42
+
43
+ def add_missing_build(build)
44
+ Travis::Surveillance.log({ surveyor: true, build: true, missing: true, id: build['id'] })
45
+ @project.add_build(build)
46
+ end
47
+
48
+ def parse_and_check(payload)
49
+ json = JSON.parse(payload)
50
+ repository_id = json['repository'] ? json['repository']['id'] : json['repository_id']
51
+ repository_id == @project.id ? json : nil
52
+ end
53
+
54
+ def parse_and_check_and_build(payload)
55
+ return unless json = parse_and_check(payload)
56
+
57
+ json_build = json['build'] ? json['build'] : { 'id' => json['build_id'] }
58
+
59
+ unless build = @project.build_for(json_build['id'])
60
+ build = add_missing_build(json_build)
61
+ end
62
+
63
+ [json, build]
64
+ end
65
+
66
+ def payload_to_new_build(payload)
67
+ return unless json = parse_and_check(payload)
68
+
69
+ unless build = @project.build_for(json['build']['id'])
70
+ Travis::Surveillance.log({ surveyor: true, build: true, started: true, id: json['build']['id'] })
71
+ @project.add_build(json['build'])
72
+ end
73
+ end
74
+
75
+ def payload_to_finished_build(payload)
76
+ json, build = parse_and_check_and_build(payload)
77
+ return unless build
78
+
79
+ Travis::Surveillance.log({ surveyor: true, build: true, finished: true, id: build.id })
80
+ build.attributes = json['build']
81
+ @project.status = build.status
82
+ end
83
+
84
+ def payload_to_job_started(payload)
85
+ json, build = parse_and_check_and_build(payload)
86
+ return unless build
87
+
88
+ Travis::Surveillance.log({ surveyor: true, job: true, started: true, id: json['id'], build_id: build.id })
89
+ build.add_job(json)
90
+ end
91
+
92
+ def payload_to_job_finished(payload)
93
+ json, build = parse_and_check_and_build(payload)
94
+ return unless build
95
+
96
+ unless job = build.job_for(json['id'])
97
+ Travis::Surveillance.log({ surveyor: true, job: true, missing: true, id: json['id'], build_id: build.id })
98
+ job = build.add_job(json)
99
+ end
100
+
101
+ Travis::Surveillance.log({ surveyor: true, job: true, finished: true, id: json['id'], build_id: build.id })
102
+ job.attributes = json
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,5 @@
1
+ module Travis
2
+ module Surveillance
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
data/logs/.gitignore ADDED
@@ -0,0 +1 @@
1
+ *.log
data/spec/helper.rb ADDED
@@ -0,0 +1,40 @@
1
+ require "simplecov" unless ENV['NO_SIMPLECOV']
2
+ require 'minitest/autorun'
3
+
4
+ require "scrolls"
5
+ require "travis/surveillance"
6
+
7
+ Scrolls::Log.stream = File.open(File.dirname(__FILE__) + '/../logs/test.log', 'w')
8
+
9
+ module TestLogger
10
+ def self.log(data, &blk)
11
+ Scrolls.log(data, &blk)
12
+ end
13
+ end
14
+
15
+ Travis::Surveillance.instrument_with(TestLogger.method(:log))
16
+ Travis::Surveillance.mock!
17
+
18
+ # "".deindent from https://github.com/visionmedia/terminal-table/blob/master/spec/spec_helper.rb
19
+
20
+ class String
21
+ def deindent
22
+ strip.gsub(/^ */, '')
23
+ end
24
+ end
25
+
26
+ # PusherClient mock from https://github.com/pusher/pusher-ruby-client/blob/master/test/teststrap.rb
27
+
28
+ module PusherClient
29
+ class Socket
30
+ def simulate_received(event_name, event_data, channel_name)
31
+ send_local_event(event_name, event_data, channel_name)
32
+ end
33
+ end
34
+ end
35
+
36
+ PusherClient.logger.level = Logger::INFO
37
+
38
+ def pusher_json_for(slug, event)
39
+ JSON.parse(IO.read(File.dirname(__FILE__) + "/support/pusher/#{slug.gsub('/', '-')}-#{event.gsub(':', '-')}.json")).to_json
40
+ end
@@ -0,0 +1,16 @@
1
+ {
2
+ "id":1,
3
+ "number":"1",
4
+ "config":{
5
+ "language":"ruby"
6
+ },
7
+ "started_at":"2012-08-04T13:28:29Z",
8
+ "commit":"af0d1c46e019ff61f1faaba7003ebf912ab245d6",
9
+ "branch":"master",
10
+ "message":"Test",
11
+ "compare_url":"https://github.com/dylanegan/travis-surveillance/compare/74791a0faacf...af0d1c46e019",
12
+ "committed_at":"2012-08-04T13:28:22Z",
13
+ "author_name":"Dylan Egan",
14
+ "committer_name":"Dylan Egan",
15
+ "status":null
16
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "id":1,
3
+ "number":"1.1",
4
+ "started_at":"2012-08-04T13:28:29Z",
5
+ "config": {
6
+ "env":"NO_SIMPLECOV=true",
7
+ "rvm":"1.9.3"
8
+ },
9
+ "result":null
10
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "id":143690,
3
+ "slug":"dylanegan/travis-surveillance",
4
+ "description":"",
5
+ "public_key":"-----BEGIN RSA PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCPeL3PD+uSXgaF4bvK4BMfCB3g\nple4P8PD+klPMQi3FTjXgyzPqsbiTaeKka0WNtmd+BXKIdczxrbjqNIAPurE3NeT\nM8aPbnkW0HNZ+oL1AsZveUyxjwMqN6iwrPbuLEKnueSpTcBOPBk3TY7Lec/HmlPV\n2PZM4LHOgmFA1P29pwIDAQAB\n-----END RSA PUBLIC KEY-----\n",
6
+ "last_build_id":2026814,
7
+ "last_build_number":"1",
8
+ "last_build_status":0,
9
+ "last_build_result":0,
10
+ "last_build_duration":113,
11
+ "last_build_language":null,
12
+ "last_build_started_at":"2012-08-03T09:13:51Z",
13
+ "last_build_finished_at":"2012-08-03T09:14:31Z"
14
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "build":{
3
+ "id":1,
4
+ "finished_at":"2012-08-04T13:28:59Z",
5
+ "result":1
6
+ },
7
+ "repository":{
8
+ "id":143690
9
+ }
10
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "build": {
3
+ "id":1,
4
+ "number":"1",
5
+ "result":null,
6
+ "matrix": [{
7
+ "number":"1.1"
8
+ }]
9
+ },
10
+ "repository": {
11
+ "id":143690
12
+ }
13
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "id":1,
3
+ "build_id":1,
4
+ "finished_at":"2012-08-04T13:28:59Z",
5
+ "repository_id":143690,
6
+ "result":1
7
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "id":1,
3
+ "build_id":1,
4
+ "repository_id":143690
5
+ }
@@ -0,0 +1,116 @@
1
+ require "helper"
2
+
3
+ describe Travis::Surveillance::Build do
4
+ before do
5
+ @project = Travis::Surveillance::Project.new("dylanegan/travis-surveillance")
6
+ @build = @project.add_build({'id' => 1})
7
+ end
8
+
9
+ describe "a new build" do
10
+ it "should have an author_name" do
11
+ @build.author_name.must_equal "Dylan Egan"
12
+ end
13
+
14
+ it "should have a branch" do
15
+ @build.branch.must_equal "master"
16
+ end
17
+
18
+ it "should have a commit" do
19
+ @build.commit.must_equal "af0d1c46e019ff61f1faaba7003ebf912ab245d6"
20
+ end
21
+
22
+ it "should have a committed_at" do
23
+ @build.committed_at.must_equal Time.parse("2012-08-04T13:28:22Z")
24
+ end
25
+
26
+ it "should have a committer_name" do
27
+ @build.committer_name.must_equal "Dylan Egan"
28
+ end
29
+
30
+ it "should have a compare_url" do
31
+ @build.compare_url.must_equal "https://github.com/dylanegan/travis-surveillance/compare/74791a0faacf...af0d1c46e019"
32
+ end
33
+
34
+ it "should have a configuration" do
35
+ @build.config.language.must_equal "ruby"
36
+ end
37
+
38
+ it "should have an id" do
39
+ @build.id.must_equal 1
40
+ end
41
+
42
+ it "should have a message" do
43
+ @build.message.must_equal "Test"
44
+ end
45
+
46
+ it "should have a number" do
47
+ @build.number.must_equal "1"
48
+ end
49
+
50
+ it "should have a project" do
51
+ @build.project.must_equal @project
52
+ end
53
+
54
+ it "should have a started_at" do
55
+ @build.started_at.must_equal Time.parse("2012-08-04T13:28:29Z")
56
+ end
57
+ end
58
+
59
+ describe "a finished build" do
60
+ before do
61
+ @surveyor = Travis::Surveillance::Surveyor.new(@project)
62
+ @surveyor.survey
63
+ @surveyor.socket.simulate_received('build:finished', pusher_json_for(@project.slug, 'build:finished'), 'common')
64
+ end
65
+
66
+ it "should have a duration" do
67
+ @build.duration.must_equal 30
68
+ end
69
+
70
+ it "should have a finished_at" do
71
+ @build.finished_at.must_equal Time.parse("2012-08-04T13:28:59Z")
72
+ end
73
+
74
+ it "should have a status" do
75
+ @build.status.must_equal 1
76
+ end
77
+ end
78
+
79
+ describe "status" do
80
+ describe "when nil" do
81
+ before do
82
+ @build.status = nil
83
+ end
84
+
85
+ it "should be building" do
86
+ @build.building?.must_equal true
87
+ @build.failed?.must_equal false
88
+ @build.passed?.must_equal false
89
+ end
90
+ end
91
+
92
+ describe "when zero" do
93
+ before do
94
+ @build.status = 0
95
+ end
96
+
97
+ it "should have passed" do
98
+ @build.building?.must_equal false
99
+ @build.failed?.must_equal false
100
+ @build.passed?.must_equal true
101
+ end
102
+ end
103
+
104
+ describe "when one" do
105
+ before do
106
+ @build.status = 1
107
+ end
108
+
109
+ it "should have failed" do
110
+ @build.building?.must_equal false
111
+ @build.failed?.must_equal true
112
+ @build.passed?.must_equal false
113
+ end
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,89 @@
1
+ require "helper"
2
+
3
+ describe Travis::Surveillance::Job do
4
+ before do
5
+ @project = Travis::Surveillance::Project.new("dylanegan/travis-surveillance")
6
+ @build = @project.add_build({'id' => 1})
7
+ @job = @build.add_job({'id' => 1})
8
+ end
9
+
10
+ describe "a new job" do
11
+ it "should have a build" do
12
+ @job.build.must_equal @build
13
+ end
14
+
15
+ it "should have a config" do
16
+ @job.config.env.must_equal "NO_SIMPLECOV=true"
17
+ end
18
+
19
+ it "should have an id" do
20
+ @job.id.must_equal 1
21
+ end
22
+
23
+ it "should have a number" do
24
+ @job.number.must_equal "1.1"
25
+ end
26
+
27
+ it "should have a started_at" do
28
+ @job.started_at.must_equal Time.parse("2012-08-04T13:28:29Z")
29
+ end
30
+ end
31
+
32
+ describe "a finished job" do
33
+ before do
34
+ @surveyor = Travis::Surveillance::Surveyor.new(@project)
35
+ @surveyor.survey
36
+ @surveyor.socket.simulate_received('job:finished', pusher_json_for(@project.slug, 'job:finished'), 'common')
37
+ end
38
+
39
+ it "should have a duration" do
40
+ @job.duration.must_equal 30
41
+ end
42
+
43
+ it "should have a finished_at" do
44
+ @job.finished_at.must_equal Time.parse("2012-08-04T13:28:59Z")
45
+ end
46
+
47
+ it "should have a status" do
48
+ @job.status.must_equal 1
49
+ end
50
+ end
51
+
52
+ describe "status" do
53
+ describe "when nil" do
54
+ before do
55
+ @job.status = nil
56
+ end
57
+
58
+ it "should be running" do
59
+ @job.running?.must_equal true
60
+ @job.failed?.must_equal false
61
+ @job.passed?.must_equal false
62
+ end
63
+ end
64
+
65
+ describe "when zero" do
66
+ before do
67
+ @job.status = 0
68
+ end
69
+
70
+ it "should have passed" do
71
+ @job.running?.must_equal false
72
+ @job.failed?.must_equal false
73
+ @job.passed?.must_equal true
74
+ end
75
+ end
76
+
77
+ describe "when one" do
78
+ before do
79
+ @job.status = 1
80
+ end
81
+
82
+ it "should have failed" do
83
+ @job.running?.must_equal false
84
+ @job.failed?.must_equal true
85
+ @job.passed?.must_equal false
86
+ end
87
+ end
88
+ end
89
+ end