wackamole 0.0.8 → 0.0.9
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.
- data/History.txt +5 -1
- data/README.rdoc +12 -3
- data/bin/wackamole +2 -2
- data/data/fixtures.rb +132 -0
- data/features/env.rb +29 -0
- data/features/mission.feature +10 -0
- data/features/step_definitions/mission_steps.rb +5 -0
- data/lib/app.rb +23 -7
- data/lib/controllers/features.rb +3 -2
- data/lib/controllers/logs.rb +1 -0
- data/lib/controllers/mission.rb +14 -4
- data/lib/controllers/session.rb +32 -0
- data/lib/controllers/users.rb +3 -2
- data/lib/helpers/flash_helper.rb +4 -1
- data/lib/helpers/logs_helper.rb +2 -1
- data/lib/helpers/session_helper.rb +29 -0
- data/lib/wackamole.rb +1 -1
- data/lib/wackamole/models/control.rb +15 -1
- data/lib/wackamole/models/feature.rb +11 -2
- data/lib/wackamole/models/log.rb +1 -0
- data/lib/wackamole/models/mission.rb +9 -7
- data/lib/wackamole/models/mole_info.rb +8 -4
- data/lib/wackamole/models/search_filter.rb +48 -15
- data/lib/wackamole/models/user.rb +12 -1
- data/public/stylesheets/wackamole.css +60 -3
- data/spec/config/bogus_test.yml +1 -1
- data/spec/config/test.yml +1 -1
- data/spec/spec_helper.rb +3 -0
- data/spec/ui/log_spec.rb +68 -0
- data/spec/ui/mission_spec.rb +64 -0
- data/spec/ui/session_spec.rb +39 -0
- data/spec/ui_utils/mission_util.rb +41 -0
- data/spec/{models → wackamole/models}/control_spec.rb +21 -21
- data/spec/{models → wackamole/models}/feature_spec.rb +7 -7
- data/spec/{models → wackamole/models}/log_spec.rb +5 -5
- data/spec/{models → wackamole/models}/mission_spec.rb +11 -7
- data/spec/wackamole/models/moled_info_spec.rb +36 -0
- data/spec/{models → wackamole/models}/search_filter_spec.rb +12 -16
- data/spec/{models → wackamole/models}/user_spec.rb +5 -5
- data/spec/{wackamole_spec.rb → wackamole/wackamole_spec.rb} +2 -2
- data/tasks/fixtures.rake +3 -1
- data/tasks/setup.rb +2 -1
- data/tasks/spec.rake +17 -3
- data/views/dashboard/_report.erb +3 -3
- data/views/layout.erb +44 -11
- data/views/logs/show.erb +3 -0
- data/views/mission/_report.erb +2 -2
- data/views/session/login.erb +28 -0
- data/views/shared/_search.erb +1 -1
- data/views/users/index.js.erb +1 -1
- metadata +22 -10
- data/spec/models/moled_info_spec.rb +0 -30
data/lib/wackamole.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Wackamole
|
2
2
|
|
3
3
|
# :stopdoc:
|
4
|
-
VERSION = '0.0.
|
4
|
+
VERSION = '0.0.9' unless defined? Wackamole::VERSION
|
5
5
|
LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR unless defined? Wackamole::LIBPATH
|
6
6
|
PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR unless defined? Wackamole::PATH
|
7
7
|
# :startdoc:
|
@@ -8,7 +8,7 @@ module Wackamole
|
|
8
8
|
# Initialize app by reading off mongo configuration parameters if necessary
|
9
9
|
def self.init_config( config_file, env )
|
10
10
|
begin
|
11
|
-
config = YAML.load_file( config_file )
|
11
|
+
config = YAML.load_file( config_file )
|
12
12
|
@config = config[env]
|
13
13
|
raise "Invalid environment `#{env}" unless @config
|
14
14
|
raise "Unable to find host in - #{@config.inspect}" unless @config.has_key?('host')
|
@@ -81,6 +81,7 @@ module Wackamole
|
|
81
81
|
def self.mole_db?( db_name )
|
82
82
|
return false unless db_name =~ molex
|
83
83
|
db = connection.db( db_name )
|
84
|
+
db.authenticate( config['username'], config['password'] )
|
84
85
|
cltns = db.collection_names
|
85
86
|
return ((%w[users features logs] & cltns).size == 3)
|
86
87
|
end
|
@@ -98,6 +99,19 @@ module Wackamole
|
|
98
99
|
@config
|
99
100
|
end
|
100
101
|
|
102
|
+
#
|
103
|
+
def self.single_app?
|
104
|
+
config['db_name']
|
105
|
+
end
|
106
|
+
|
107
|
+
#
|
108
|
+
def self.app_info
|
109
|
+
if config['db_name']
|
110
|
+
return extract_app_info( config['db_name'] )
|
111
|
+
end
|
112
|
+
nil
|
113
|
+
end
|
114
|
+
|
101
115
|
# -----------------------------------------------------------------------
|
102
116
|
# Connects to mongo instance if necessary...
|
103
117
|
def self.connection( log=false )
|
@@ -21,12 +21,21 @@ module Wackamole
|
|
21
21
|
def self.paginate_tops( conds, page=1, page_size=default_page_size )
|
22
22
|
tops = logs_cltn.group( [:fid], conds, { :count => 0 }, 'function(obj,prev) { prev.count += 1}', true )
|
23
23
|
|
24
|
+
all_features = features_cltn.find( {}, :fields => [:_id] )
|
25
|
+
feature_ids = all_features.map{ |f| f['_id'] }
|
26
|
+
total_features = []
|
27
|
+
tops.each do |row|
|
28
|
+
total_features << row
|
29
|
+
feature_ids.delete( row['fid'] )
|
30
|
+
end
|
31
|
+
feature_ids.each { |f| total_features << {'fid' => f, 'count' => 0} }
|
32
|
+
|
24
33
|
features = []
|
25
|
-
|
34
|
+
total_features.sort{ |a,b| b['count'] <=> a['count'] }.each do |row|
|
26
35
|
features << { :fid => row['fid'], :total => row['count'].to_i }
|
27
36
|
end
|
28
37
|
|
29
|
-
WillPaginate::Collection.create( page, page_size, features.size ) do |pager|
|
38
|
+
WillPaginate::Collection.create( page, page_size, features.size ) do |pager|
|
30
39
|
offset = (page-1)*page_size
|
31
40
|
result = features[offset...(offset+page_size)]
|
32
41
|
result.each do |u|
|
data/lib/wackamole/models/log.rb
CHANGED
@@ -14,6 +14,7 @@ module Wackamole
|
|
14
14
|
# ---------------------------------------------------------------------------
|
15
15
|
# Fetch all logs matching the given condition
|
16
16
|
def self.paginate( conds, page=1, page_size=default_page_size )
|
17
|
+
puts conds.inspect
|
17
18
|
matching = logs_cltn.find( conds )
|
18
19
|
WillPaginate::Collection.create( page, page_size, matching.count ) do |pager|
|
19
20
|
pager.replace( logs_cltn.find( conds,
|
@@ -15,16 +15,18 @@ module Wackamole
|
|
15
15
|
|
16
16
|
# -----------------------------------------------------------------------
|
17
17
|
# generates mole logs conditons
|
18
|
-
def self.gen_conds( now, single_day )
|
18
|
+
def self.gen_conds( now, single_day )
|
19
19
|
conds = {}
|
20
20
|
if now
|
21
21
|
if single_day
|
22
|
-
|
22
|
+
conds = SearchFilter.time_conds( now, 1 )
|
23
|
+
else
|
24
|
+
now = now.clone.utc
|
25
|
+
date_id = now.to_date_id.to_s
|
26
|
+
time_id = now.to_time_id
|
27
|
+
conds[:did] = { '$gte' => date_id }
|
28
|
+
conds[:tid] = { '$gte' => time_id }
|
23
29
|
end
|
24
|
-
date_id = now.to_date_id.to_s
|
25
|
-
time_id = now.to_time_id
|
26
|
-
conds[:did] = date_id
|
27
|
-
conds[:tid] = {'$gte' => time_id}
|
28
30
|
end
|
29
31
|
conds
|
30
32
|
end
|
@@ -53,7 +55,7 @@ module Wackamole
|
|
53
55
|
row[t] = logs.count
|
54
56
|
end
|
55
57
|
end
|
56
|
-
counts
|
58
|
+
counts
|
57
59
|
end
|
58
60
|
|
59
61
|
# =========================================================================
|
@@ -19,10 +19,14 @@ module Wackamole
|
|
19
19
|
info[:fault_load] = 0
|
20
20
|
|
21
21
|
# Fetch day logs
|
22
|
-
|
22
|
+
utc_time = now.clone.utc
|
23
|
+
puts utc_time
|
24
|
+
conds = SearchFilter.time_conds( now, 0 )
|
25
|
+
day_logs = logs_cltn.find( conds,
|
23
26
|
:fields => [:typ, :fid, :tid, :did, :uid],
|
24
27
|
:sort => [ [:tid => Mongo::ASCENDING] ] )
|
25
|
-
|
28
|
+
puts conds.inspect
|
29
|
+
puts day_logs.count
|
26
30
|
# Count all logs per hourly time period
|
27
31
|
users = Set.new
|
28
32
|
features = Set.new
|
@@ -36,10 +40,10 @@ module Wackamole
|
|
36
40
|
log_utc = Time.utc( date_tokens[0], date_tokens[1], date_tokens[2], time_tokens[0], time_tokens[1], time_tokens[2] )
|
37
41
|
local = log_utc.clone.localtime
|
38
42
|
hour = local.hour
|
39
|
-
|
43
|
+
|
40
44
|
next if hour > local_time.hour
|
41
45
|
|
42
|
-
if log_utc.hour ==
|
46
|
+
if log_utc.hour == utc_time.hour
|
43
47
|
users << log['uid']
|
44
48
|
features << log['fid']
|
45
49
|
info[:fault_load] += 1 if log['typ'] == Rackamole.fault
|
@@ -34,6 +34,19 @@ module Wackamole
|
|
34
34
|
@time_frames ||= ['today', '2 days', '1 week', '2 weeks', '1 month', '3 months', '6 months', '1 year' ]
|
35
35
|
end
|
36
36
|
|
37
|
+
def self.time_frames_in_days
|
38
|
+
@time_frame_in_days ||= {
|
39
|
+
'today' => 0,
|
40
|
+
'2 days' => 1,
|
41
|
+
'1 week' => 7,
|
42
|
+
'2 weeks' => 14,
|
43
|
+
'1 month' => 30,
|
44
|
+
'3 months' => 90,
|
45
|
+
'6 months' => 180,
|
46
|
+
'1 year' => 360
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
37
50
|
# ---------------------------------------------------------------------------
|
38
51
|
# Available hours
|
39
52
|
def self.hourlies
|
@@ -45,7 +58,7 @@ module Wackamole
|
|
45
58
|
def self.mole_types
|
46
59
|
@types ||= %w[All Feature Perf Fault]
|
47
60
|
end
|
48
|
-
|
61
|
+
|
49
62
|
# ---------------------------------------------------------------------------
|
50
63
|
# Set filter type
|
51
64
|
def mole_type( type )
|
@@ -118,10 +131,41 @@ module Wackamole
|
|
118
131
|
end
|
119
132
|
end
|
120
133
|
|
134
|
+
# -------------------------------------------------------------------------
|
135
|
+
# compute query time factors
|
136
|
+
def self.time_conds( local_now, days, current_hour=0 )
|
137
|
+
conds = {}
|
138
|
+
|
139
|
+
if current_hour == 0 and days == 0
|
140
|
+
from_utc = Time.local( local_now.year, local_now.month, local_now.day, 0, 0, 1 ).utc
|
141
|
+
to_utc = Time.local( local_now.year, local_now.month, local_now.day, 23, 59, 59 ).utc
|
142
|
+
|
143
|
+
from_date_id = from_utc.to_date_id.to_s
|
144
|
+
to_date_id = to_utc.to_date_id.to_s
|
145
|
+
|
146
|
+
if from_date_id != to_date_id
|
147
|
+
from_time_id = from_utc.to_time_id.to_s
|
148
|
+
to_time_id = to_utc.to_time_id.to_s
|
149
|
+
conds['$where'] = "((this.did == '#{from_date_id}' && this.tid >= '#{from_time_id}') || ( this.did == '#{to_date_id}' && this.tid <= '#{to_time_id}') )"
|
150
|
+
else
|
151
|
+
conds[:did] = to_date_id
|
152
|
+
end
|
153
|
+
else
|
154
|
+
date = Chronic.parse( "#{days == 1 ? "now" : "#{days} days ago"}" )
|
155
|
+
current = "%4d/%02d/%02d %02d:%02d:%02d" % [date.year, date.month, date.day, current_hour, 0, 1]
|
156
|
+
time = Chronic.parse( current ).utc
|
157
|
+
conds[:did] = { '$gte' => time.to_date_id.to_s }
|
158
|
+
conds[:tid] = /^#{"%02d"%time.hour}.+/ unless current_hour == 0
|
159
|
+
end
|
160
|
+
conds
|
161
|
+
end
|
162
|
+
|
121
163
|
# ---------------------------------------------------------------------------
|
122
164
|
# Spews filter conditions
|
123
165
|
def to_conds
|
124
|
-
|
166
|
+
current_hour = self.hour
|
167
|
+
current_hour = 0 if self.hour == SearchFilter.hourlies.first
|
168
|
+
conds = SearchFilter.time_conds( Time.now, SearchFilter.time_frames_in_days[self.time_frame], current_hour )
|
125
169
|
|
126
170
|
# filter mole_types
|
127
171
|
if type != 'All'
|
@@ -136,19 +180,8 @@ module Wackamole
|
|
136
180
|
unless feature_id.to_s == "-1"
|
137
181
|
conds[:fid] = Mongo::ObjectID.from_string( feature_id )
|
138
182
|
end
|
139
|
-
|
140
|
-
|
141
|
-
time = Chronic.parse( time_frame + ( time_frame == SearchFilter.time_frames.first ? "" : " ago" ) )
|
142
|
-
conds[:did] = { '$gte' => time.to_date_id.to_s }
|
143
|
-
|
144
|
-
unless self.hour == 'all'
|
145
|
-
now = Time.now
|
146
|
-
current = "%4d/%02d/%02d %02d:%02d:%02d" % [now.year, now.month, now.day, self.hour, 0, 0]
|
147
|
-
time = Chronic.parse( current ).utc
|
148
|
-
conds[:tid] = /^#{"%02d"%time.hour}.+/
|
149
|
-
end
|
150
|
-
|
151
|
-
unless search_terms.empty?
|
183
|
+
|
184
|
+
if search_terms and !search_terms.empty?
|
152
185
|
tokens = search_terms.split( ":" ).collect{ |c| c.strip }
|
153
186
|
key = tokens.shift
|
154
187
|
if key
|
@@ -17,12 +17,23 @@ module Wackamole
|
|
17
17
|
tops.sort{ |a,b| b['count'] <=> a['count'] }.each do |row|
|
18
18
|
users << { :uid => row['uid'], :total => row['count'].to_i, :details => [] }
|
19
19
|
end
|
20
|
+
|
21
|
+
# BOZO !! Not too wise to fetch all users. allow for now and reconsider
|
22
|
+
all_users = users_cltn.find( {}, :fields => [:_id] )
|
23
|
+
user_ids = all_users.map{ |f| f['_id'] }
|
24
|
+
total_users = []
|
25
|
+
tops.each do |row|
|
26
|
+
total_users << row
|
27
|
+
user_ids.delete( row['uid'] )
|
28
|
+
end
|
29
|
+
user_ids.each { |u| total_users << {'uid' => u, 'count' => 0} }
|
20
30
|
|
21
31
|
WillPaginate::Collection.create( page, page_size, users.size ) do |pager|
|
22
32
|
offset = (page-1)*page_size
|
23
33
|
result = users[offset...(offset+page_size)]
|
24
34
|
result.each do |u|
|
25
|
-
|
35
|
+
# BOZO !! should group that call to retrieve all matching users
|
36
|
+
user = users_cltn.find_one( u[:uid], :fields => [:una] )
|
26
37
|
raise "Unable to find user with id `#{u[:uid].inspect}" unless user
|
27
38
|
u[:name] = user['una']
|
28
39
|
end
|
@@ -29,7 +29,7 @@ div#overall {
|
|
29
29
|
div#logo {
|
30
30
|
float: left;
|
31
31
|
width: 45%;
|
32
|
-
margin-bottom:
|
32
|
+
margin-bottom: 5px;
|
33
33
|
}
|
34
34
|
|
35
35
|
div#main {
|
@@ -291,10 +291,10 @@ a.fault {
|
|
291
291
|
div.flash {
|
292
292
|
display: none;
|
293
293
|
width: 95%;
|
294
|
+
text-align: center;
|
294
295
|
padding: 10px;
|
295
296
|
font-size: 1.5em;
|
296
297
|
color: #fff;
|
297
|
-
border: 1px #92b948 solid;
|
298
298
|
-moz-border-radius-bottomleft: 20px;
|
299
299
|
-moz-border-radius-topleft: 0px;
|
300
300
|
-moz-border-radius-bottomright: 0px;
|
@@ -595,7 +595,7 @@ table#mission thead tr {
|
|
595
595
|
font-size: 1.2em;
|
596
596
|
color: #808080;
|
597
597
|
}
|
598
|
-
table#mission tr.
|
598
|
+
table#mission tr.app_info {
|
599
599
|
border-bottom: 1px #c1c1c1 solid;
|
600
600
|
}
|
601
601
|
|
@@ -718,4 +718,61 @@ div.ie_8 {
|
|
718
718
|
}
|
719
719
|
div.unknown {
|
720
720
|
background-position: -154px 0;
|
721
|
+
}
|
722
|
+
|
723
|
+
/* ------------------------------------------------------------------------- */
|
724
|
+
/* Login */
|
725
|
+
|
726
|
+
div#dialog {
|
727
|
+
font-size: 1.5em;
|
728
|
+
padding-top: 30px;
|
729
|
+
}
|
730
|
+
|
731
|
+
div#inner_box {
|
732
|
+
width: 400px;
|
733
|
+
background: #eee;
|
734
|
+
height: 190px;
|
735
|
+
-moz-border-radius: 7px;
|
736
|
+
-webkit-border-radius: 7px;
|
737
|
+
-moz-box-shadow: 0 0 90px 0px #000;
|
738
|
+
-webkit-box-shadow: 0 0 90px #000;
|
739
|
+
margin-top: 40px;
|
740
|
+
padding: 30px;
|
741
|
+
}
|
742
|
+
|
743
|
+
form#login div {
|
744
|
+
margin-bottom: 10px;
|
745
|
+
}
|
746
|
+
|
747
|
+
form#login label {
|
748
|
+
color: #1d1d1d;
|
749
|
+
display: block;
|
750
|
+
width: 260px;
|
751
|
+
text-align: left;
|
752
|
+
}
|
753
|
+
|
754
|
+
form#login input {
|
755
|
+
width: 250px;
|
756
|
+
font-size: 1.0em;
|
757
|
+
font-weight: bold;
|
758
|
+
}
|
759
|
+
|
760
|
+
form#login input[type='text'] {
|
761
|
+
padding: 5px;
|
762
|
+
color: #1d1d1d;
|
763
|
+
background: transparent url(../images/fade.png);
|
764
|
+
}
|
765
|
+
|
766
|
+
form#login input[type='password'] {
|
767
|
+
padding: 5px;
|
768
|
+
background: transparent url(../images/fade.png);
|
769
|
+
}
|
770
|
+
|
771
|
+
form#login input[type='submit'] {
|
772
|
+
width: 100px;
|
773
|
+
}
|
774
|
+
|
775
|
+
div#copyright {
|
776
|
+
margin-top:4px;
|
777
|
+
color:#4974FF;
|
721
778
|
}
|
data/spec/config/bogus_test.yml
CHANGED
data/spec/config/test.yml
CHANGED
data/spec/spec_helper.rb
CHANGED
data/spec/ui/log_spec.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), %w[.. spec_helper])
|
2
|
+
require 'capybara'
|
3
|
+
require 'capybara/dsl'
|
4
|
+
require File.join(File.dirname(__FILE__), %w[.. ui_utils mission_util])
|
5
|
+
|
6
|
+
include Capybara
|
7
|
+
include MissionUtil
|
8
|
+
|
9
|
+
describe 'Mission' do
|
10
|
+
before( :all ) do
|
11
|
+
Capybara.default_driver = :selenium
|
12
|
+
@url = "http://localhost:4567/"
|
13
|
+
end
|
14
|
+
|
15
|
+
before :each do
|
16
|
+
visit( @url )
|
17
|
+
login( @url, 'admin', 'admin', @url + 'mission' )
|
18
|
+
rows = all( :css, "table#mission tr.app_info" )
|
19
|
+
show_logs( rows[0], 'app1', 'test', 0 )
|
20
|
+
current_url.should == @url + "logs/1"
|
21
|
+
end
|
22
|
+
|
23
|
+
after :each do
|
24
|
+
log_out
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should filter log's type correctly" do
|
28
|
+
expected = { 'Perf' => 4, 'Fault' => 2 }
|
29
|
+
expected.each_pair do |k,v|
|
30
|
+
within( "//form[@id='filter_form']" ) do
|
31
|
+
locate( :css, "select#time_frame").select( 'today' )
|
32
|
+
locate( :css, "select#hourly_frame").select( 'all' )
|
33
|
+
locate( :css, "select#type").select( k )
|
34
|
+
click_button( 'Filter' )
|
35
|
+
end
|
36
|
+
sleep( 0.2 )
|
37
|
+
find( :css, 'div.page_entries' ).text.should =~ /#{v}/
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should filter log's time range correctly" do
|
42
|
+
expected = { 'today' => 12, '2 days' => 15 }
|
43
|
+
expected.each_pair do |k,v|
|
44
|
+
within( "//form[@id='filter_form']" ) do
|
45
|
+
locate( :css, "select#hourly_frame").select( 'all' )
|
46
|
+
locate( :css, "select#type").select( 'All' )
|
47
|
+
locate( :css, "select#time_frame").select( k )
|
48
|
+
click_button( 'Filter' )
|
49
|
+
end
|
50
|
+
sleep( 0.2 )
|
51
|
+
find( :css, 'div.page_entries' ).text.should =~ /#{v}/
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should filter log's hour correctly" do
|
56
|
+
expected = { '17' => 5, '18' => 1 }
|
57
|
+
expected.each_pair do |k,v|
|
58
|
+
within( "//form[@id='filter_form']" ) do
|
59
|
+
locate( :css, "select#type").select( 'All' )
|
60
|
+
locate( :css, "select#time_frame").select( 'today' )
|
61
|
+
locate( :css, "select#hourly_frame").select( k )
|
62
|
+
click_button( 'Filter' )
|
63
|
+
end
|
64
|
+
sleep( 0.2 )
|
65
|
+
find( :css, 'div.page_entries' ).text.should =~ /#{v}/
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), %w[.. spec_helper])
|
2
|
+
require 'capybara'
|
3
|
+
require 'capybara/dsl'
|
4
|
+
require File.join(File.dirname(__FILE__), %w[.. ui_utils mission_util])
|
5
|
+
|
6
|
+
include Capybara
|
7
|
+
include MissionUtil
|
8
|
+
|
9
|
+
describe 'Mission' do
|
10
|
+
before( :all ) do
|
11
|
+
Capybara.default_driver = :selenium
|
12
|
+
@url = "http://localhost:4567/"
|
13
|
+
end
|
14
|
+
|
15
|
+
before :each do
|
16
|
+
visit( @url )
|
17
|
+
login( @url, 'admin', 'admin', @url + 'mission' )
|
18
|
+
end
|
19
|
+
|
20
|
+
after :each do
|
21
|
+
log_out
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should gather mission info correctly" do
|
25
|
+
rows = all( :css, "table#mission tr.app_info" )
|
26
|
+
rows.should have(2).items
|
27
|
+
|
28
|
+
check_app( rows[0], 'app1', 'test', [7,5,3], [6,4,2], [0,0,0] )
|
29
|
+
check_app( rows[1], 'app2', 'test', [7,5,3], [6,4,2], [0,0,0] )
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should have the right number of links" do
|
33
|
+
rows = all( :css, "table#mission tr.app_info" )
|
34
|
+
rows.first.all( :css, "a" ).should have(4).items
|
35
|
+
rows.last.all( :css, "a" ).should have(4).items
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should navigate to an application dasboard correctly" do
|
39
|
+
%w(app1).each do |app|
|
40
|
+
find_link( app ).click
|
41
|
+
current_url.should == "http://localhost:4567/dashboard/#{app}/test"
|
42
|
+
# visit( @url )
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should navigate to logs features correctly" do
|
47
|
+
[0,1].each do |i|
|
48
|
+
rows = all( :css, "table#mission tr.app_info" )
|
49
|
+
cells = rows[i].all( :css, 'td' )
|
50
|
+
app = cells[0].text
|
51
|
+
env = cells[1].text
|
52
|
+
vals = %w(Feature Perf Fault)
|
53
|
+
logs = [6,4,2]
|
54
|
+
[0,1,2].each do |type|
|
55
|
+
rows = all( :css, "table#mission tr.app_info" )
|
56
|
+
show_logs( rows[i], app, env, type )
|
57
|
+
current_url.should == @url + "logs/1"
|
58
|
+
find( :css, 'select#type' ).value.should == vals[type]
|
59
|
+
find( :css, 'div.page_entries' ).text.should =~ /#{logs[type]}/
|
60
|
+
nav_mission
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|