naf 2.1.6 → 2.1.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. data/Gemfile +0 -1
  2. data/README.rdoc +3 -3
  3. data/RELEASE_NOTES.rdoc +19 -0
  4. data/app/controllers/naf/api_simple_cluster_authenticator_application_controller.rb +9 -0
  5. data/app/controllers/naf/application_controller.rb +18 -1
  6. data/app/controllers/naf/log_parsers_controller.rb +11 -7
  7. data/app/models/logical/naf/construction_zone/boss.rb +21 -13
  8. data/app/models/logical/naf/construction_zone/foreman.rb +1 -1
  9. data/app/models/logical/naf/construction_zone/proletariat.rb +9 -1
  10. data/app/models/logical/naf/user_session.rb +53 -0
  11. data/app/models/naf/application_schedule.rb +14 -3
  12. data/app/models/naf/application_type.rb +7 -1
  13. data/app/models/naf/machine.rb +4 -4
  14. data/app/models/process/naf/log_archiver.rb +2 -1
  15. data/app/models/process/naf/log_archiver_queuer.rb +25 -0
  16. data/app/models/process/naf/logger/base.rb +0 -2
  17. data/app/views/naf/log_viewer/_log_display.html.erb +6 -1
  18. data/lib/naf.rb +16 -4
  19. data/lib/naf/configuration.rb +9 -3
  20. data/lib/naf/version.rb +1 -1
  21. data/naf.gemspec +2 -2
  22. data/spec/controllers/naf/application_controller_spec.rb +1 -1
  23. data/spec/factories/naf.rb +39 -0
  24. data/spec/models/logical/naf/construction_zone/boss_rspec.rb +119 -0
  25. data/spec/models/logical/naf/construction_zone/foreman_spec.rb +105 -0
  26. data/spec/models/logical/naf/construction_zone/proletariat_spec.rb +67 -0
  27. data/spec/models/logical/naf/construction_zone/work_order_spec.rb +2 -1
  28. data/spec/models/logical/naf/user_session_spec.rb +92 -0
  29. data/spec/models/naf/application_schedule_spec.rb +61 -0
  30. data/spec/models/naf/machine_spec.rb +5 -3
  31. metadata +13 -4
data/Gemfile CHANGED
@@ -13,7 +13,6 @@ gem 'will_paginate'
13
13
  gem 'facter'
14
14
  gem 'shoulda-matchers', '2.0.0'
15
15
  gem 'timecop', '0.4.5'
16
- gem 'open4'
17
16
  gem 'yajl-ruby'
18
17
  gem 'aws-sdk'
19
18
  gem 'fiksu-af'
data/README.rdoc CHANGED
@@ -40,8 +40,8 @@ Machines have an allocate-able number of slots of a specific affinity. Applicati
40
40
  === Tags
41
41
  Scripts have tags to describe the stage/progress of the process. They can be system or custom tags. All tags are visible by the user, so set tags at different stages of your script. This is a way of knowing what is happening in the script without having to take a look at the logs.
42
42
 
43
-
44
43
  === Please find up-to-date information on Naf here: {Naf Wiki}[http://www.github.com/fiksu/naf/wiki]
45
- === Instructions on upgrading to Naf v1.1.4: {Instructions}[https://github.com/fiksu/naf/wiki/Upgrading-to-Naf-v1.1.4]
44
+ === Instructions on upgrading to Naf v2.1.8: {Instructions}[https://github.com/fiksu/naf/wiki/Upgrading-from-Naf-v2.1.6-to-Naf-v2.1.8]
45
+ === Instructions on upgrading to Naf v2.1.6: {Instructions}[https://github.com/fiksu/naf/wiki/Upgrading-to-Naf-v2.1.6]
46
46
  === Instructions on upgrading to Naf v2.0: {Instructions}[https://github.com/fiksu/naf/wiki/Upgrading-to-Naf-v2.0]
47
- === Instructions on upgrading to Naf v2.1: {Instructions}[https://github.com/fiksu/naf/wiki/Upgrading-to-Naf-v2.1]
47
+ === Instructions on upgrading to Naf v1.1.4: {Instructions}[https://github.com/fiksu/naf/wiki/Upgrading-to-Naf-v1.1.4]
data/RELEASE_NOTES.rdoc CHANGED
@@ -1,5 +1,24 @@
1
1
  = Release Notes
2
2
 
3
+ === Version 2.1.8
4
+ Bug fixes:
5
+ * Removed check for signed message. Encrypted data generated by ActiveSupport::MessageVerifier is different depending on the ruby version.
6
+
7
+ === Version 2.1.7
8
+ Bug fixes:
9
+ * Boss#enqueue_command had the first two parameters switched
10
+ * Boss#enqueue_n_commands referenced a machine object, but that object did not exist in the scope
11
+ * Boss#enqueue_n_commands called job_affinity_tabs on a job when it should be calling historical_job_affinity_tabs
12
+ * Foreman#limited_by_run_group? checked the affinity_classification_name of an affinity, but did not check if the affinity was null
13
+ * Job exit status always set to 0, even after the job errors
14
+ * Unnecessary 'open4' require statements
15
+ * Deleted application still runs if it has an enabled schedule
16
+ * LogArchiver did not delete empty folders
17
+
18
+ Changes:
19
+ * Created a log archival queuer script
20
+ * Created Api Authenticator for logs
21
+
3
22
  === Version 2.1.6
4
23
  Bug fixes:
5
24
  * Historical jobs application_schedule_id was not getting set, causing the runner to constantly queue applications.
@@ -0,0 +1,9 @@
1
+ module Naf
2
+ class ApiSimpleClusterAuthenticatorApplicationController < ActionController::Base
3
+
4
+ def naf_cookie_valid?
5
+ ::Logical::Naf::UserSession.new(session[::Naf.configuration.api_domain_cookie_name]).valid?
6
+ end
7
+
8
+ end
9
+ end
@@ -1,11 +1,13 @@
1
1
  module Naf
2
- class ApplicationController < Naf.controller_class
2
+ class ApplicationController < Naf.ui_controller_class
3
3
  layout Naf.layout
4
4
 
5
5
  require 'will_paginate/array'
6
6
 
7
7
  protect_from_forgery
8
8
 
9
+ before_filter :check_naf_cookie_presence
10
+
9
11
  protected
10
12
 
11
13
  # Sets current rows_per_page direction from cookies or params.
@@ -39,5 +41,20 @@ module Naf
39
41
  end
40
42
  cookies[:search_status] = @search_status
41
43
  end
44
+
45
+ private
46
+
47
+ def check_naf_cookie_presence
48
+ user_session = ::Logical::Naf::UserSession.new(session[domain_cookie_name])
49
+ if !user_session.valid?
50
+ session.delete(domain_cookie_name)
51
+ session[domain_cookie_name] = user_session.token_cookie
52
+ end
53
+ end
54
+
55
+ def domain_cookie_name
56
+ @domain_cookie_name ||= ::Naf.configuration.api_domain_cookie_name
57
+ end
58
+
42
59
  end
43
60
  end
@@ -1,15 +1,19 @@
1
1
  module Naf
2
- class LogParsersController < Naf::ApplicationController
2
+ class LogParsersController < Naf::ApiSimpleClusterAuthenticatorApplicationController
3
3
 
4
4
  def logs
5
- response = params['logical_type'].constantize.new(params).logs
6
- if response.present?
7
- success = true
5
+ if naf_cookie_valid?
6
+ response = params['logical_type'].constantize.new(params).logs
7
+ if response.present?
8
+ success = true
9
+ else
10
+ success = false
11
+ end
12
+
13
+ render json: "convertToJsonCallback(" + { success: success }.merge(response).to_json + ")"
8
14
  else
9
- success = false
15
+ render json: "convertToJsonCallback(" + { success: false }.to_json + ")"
10
16
  end
11
-
12
- render json: "convertToJsonCallback(" + { success: success }.merge(response).to_json + ")"
13
17
  end
14
18
 
15
19
  end
@@ -60,8 +60,8 @@ module Logical::Naf::ConstructionZone
60
60
  affinities = [],
61
61
  prerequisites = [],
62
62
  enqueue_backlogs = false)
63
- work_order = WorkOrder.new(application_type,
64
- command,
63
+ work_order = WorkOrder.new(command,
64
+ application_type,
65
65
  application_run_group_restriction,
66
66
  application_run_group_name,
67
67
  application_run_group_limit,
@@ -79,22 +79,18 @@ module Logical::Naf::ConstructionZone
79
79
 
80
80
  def enqueue_n_commands_on_machines(parameters, number_of_jobs = :from_limit, machines = [])
81
81
  logger.detail "enqueuing #{parameters[:command]} #{number_of_jobs} time(s) on #{machines.length} machine(s)"
82
+ # enqueue the command on each machine
82
83
  machines.each do |machine|
83
84
  number_of_jobs = (parameters[:application_run_group_quantum] || 1) if number_of_jobs == :from_limit
84
85
  logger.info "enqueuing #{parameters[:command]} #{number_of_jobs} time(s) on #{machine}"
86
+ # enqueue the command number_of_jobs times
85
87
  (1..number_of_jobs).each do
86
88
  machine_parameters = {
87
89
  application_run_group_restriction: ::Naf::ApplicationRunGroupRestriction.limited_per_machine
88
90
  }.merge(parameters)
89
- machine_parameters[:affinities] =
90
- [machine.affinity] + if machine_parameters[:affinities].nil?
91
- []
92
- elsif machine_parameters[:affinities].is_a? Array
93
- machine_parameters[:affinities]
94
- else
95
- [machine_parameters[:affinities]]
96
- end
97
- work_order = AdHocWorkOrder.new(machine_parameters)
91
+ machine_parameters[:affinities] = [machine.affinity] + affinities(machine_parameters)
92
+ work_order = AdHocWorkOrder.new(machine_parameters)
93
+
98
94
  @foreman.enqueue(work_order)
99
95
  end
100
96
  end
@@ -102,7 +98,7 @@ module Logical::Naf::ConstructionZone
102
98
 
103
99
  def enqueue_n_commands(parameters, number_of_jobs = :from_limit)
104
100
  number_of_jobs = (parameters[:application_run_group_quantum] || 1) if number_of_jobs == :from_limit
105
- logger.info "enqueuing #{parameters[:command]} #{number_of_jobs} time(s) on #{machine}"
101
+ logger.info "enqueuing #{parameters[:command]} #{number_of_jobs} time(s)"
106
102
  (1..number_of_jobs).each do
107
103
  work_order = AdHocWorkOrder.new(parameters)
108
104
  @foreman.enqueue(work_order)
@@ -115,7 +111,19 @@ module Logical::Naf::ConstructionZone
115
111
  job.application_run_group_name,
116
112
  job.application_run_group_limit,
117
113
  job.priority,
118
- job.job_affinity_tabs.map{|jat| jat.affinity})
114
+ job.historical_job_affinity_tabs.map{|jat| jat.affinity})
115
+ end
116
+
117
+ private
118
+
119
+ def affinities(params)
120
+ if params[:affinities].nil?
121
+ []
122
+ elsif params[:affinities].is_a? Array
123
+ params[:affinities]
124
+ else
125
+ [params[:affinities]]
126
+ end
119
127
  end
120
128
 
121
129
  end
@@ -32,7 +32,7 @@ module Logical::Naf::ConstructionZone
32
32
  machine_affinity = nil
33
33
  affinities.each do |affinity|
34
34
  machine_affinity = ::Naf::Affinity.find_by_id(affinity[:affinity_id])
35
- if machine_affinity.affinity_classification_name == 'machine'
35
+ if machine_affinity.present? && machine_affinity.affinity_classification_name == 'machine'
36
36
  break
37
37
  end
38
38
  end
@@ -3,7 +3,8 @@ module Logical::Naf::ConstructionZone
3
3
  def create_job(parameters, affinities, prerequisites)
4
4
  ::Naf::HistoricalJob.transaction do
5
5
  historical_job = create_historical_job(parameters, affinities, prerequisites)
6
- queued_job = create_queued_job(historical_job)
6
+ create_queued_job(historical_job)
7
+
7
8
  return historical_job
8
9
  end
9
10
  end
@@ -11,16 +12,20 @@ module Logical::Naf::ConstructionZone
11
12
  def create_historical_job(parameters, affinities, prerequisites)
12
13
  ::Naf::HistoricalJob.transaction do
13
14
  historical_job = ::Naf::HistoricalJob.create!(parameters)
15
+ # Create affinity tabs, if affinities are provided
14
16
  affinities.each do |affinity|
15
17
  ::Naf::HistoricalJobAffinityTab.create(affinity.merge(historical_job_id: historical_job.id))
16
18
  end
19
+ # Verify there is no loop found in prerequisites
17
20
  historical_job.verify_prerequisites(prerequisites)
21
+ # Create historical job prerequesites, if prerequisites are provided
18
22
  prerequisites.each do |prerequisite|
19
23
  ::Naf::HistoricalJobPrerequisite.create({
20
24
  historical_job_id: historical_job.id,
21
25
  prerequisite_historical_job_id: prerequisite.id
22
26
  })
23
27
  end
28
+
24
29
  return historical_job
25
30
  end
26
31
  end
@@ -36,6 +41,9 @@ module Logical::Naf::ConstructionZone
36
41
  priority: historical_job.priority)
37
42
  queued_job.id = historical_job.id
38
43
  queued_job.save!
44
+
45
+ return queued_job
39
46
  end
47
+
40
48
  end
41
49
  end
@@ -0,0 +1,53 @@
1
+ module Logical
2
+ module Naf
3
+ class UserSession
4
+
5
+ attr_reader :message
6
+
7
+ def initialize(signed_message)
8
+ @message = self.class.unsign_message(signed_message)
9
+ end
10
+
11
+ def valid?
12
+ message.present? && message[:value].present? &&
13
+ (Time.zone.now - message[:value]) < ::Naf.configuration.
14
+ simple_cluster_authenticator_cookie_expiration_time
15
+ end
16
+
17
+ def token_cookie
18
+ self.class.sign_message(self.class.build_token_cookie)
19
+ end
20
+
21
+ def self.build_token_cookie
22
+ {
23
+ value: Time.zone.now
24
+ }
25
+ end
26
+
27
+ # Sign the provided string using a MessageVerifier.
28
+ def self.sign_message(message)
29
+ self.message_verifier.generate(message) if !message.nil?
30
+ end
31
+
32
+ # Unsign the provided string using a MessageVerifier.
33
+ def self.unsign_message(message)
34
+ if message.nil?
35
+ return nil
36
+ end
37
+
38
+ begin
39
+ self.message_verifier.verify(message)
40
+ rescue ActiveSupport::MessageVerifier::InvalidSignature
41
+ nil
42
+ end
43
+ end
44
+
45
+ # Returns an ActiveSuport MessageVerifier for signing/unsigning strings seeded with the
46
+ # applications secret token.
47
+ def self.message_verifier
48
+ @@message_verifier ||= ActiveSupport::MessageVerifier.new(Rails.application.class.config.secret_token)
49
+ end
50
+
51
+ end
52
+ end
53
+ end
@@ -106,7 +106,7 @@ module Naf
106
106
  schedules = ::Naf::ApplicationSchedule.
107
107
  joins(:run_interval_style).
108
108
  where("#{Naf.schema_name}.run_interval_styles.name IN (?)", ['at beginning of day', 'at beginning of hour']).
109
- enabled.select do |schedule|
109
+ enabled.application_not_deleted.select do |schedule|
110
110
 
111
111
  interval_time = time.to_date
112
112
  if schedule.run_interval_style.name == 'at beginning of day'
@@ -133,7 +133,7 @@ module Naf
133
133
  schedules = ::Naf::ApplicationSchedule.
134
134
  joins(:run_interval_style).
135
135
  where("#{Naf.schema_name}.run_interval_styles.name = ?", 'after previous run').
136
- enabled.select do |schedule|
136
+ enabled.application_not_deleted.select do |schedule|
137
137
 
138
138
  (not_finished_applications[schedule.id].nil? &&
139
139
  (application_last_runs[schedule.id].nil? ||
@@ -149,13 +149,24 @@ module Naf
149
149
  ::Naf::ApplicationSchedule.
150
150
  joins(:run_interval_style).
151
151
  where("#{Naf.schema_name}.run_interval_styles.name = ?", 'keep running').
152
- enabled
152
+ enabled.application_not_deleted
153
153
  end
154
154
 
155
155
  def self.enabled
156
156
  where(enabled: true)
157
157
  end
158
158
 
159
+ def self.application_not_deleted
160
+ where("
161
+ NOT EXISTS (
162
+ SELECT 1
163
+ FROM #{Naf.schema_name}.applications AS app
164
+ WHERE app.id = #{Naf.schema_name}.application_schedules.application_id AND
165
+ app.deleted = true
166
+ )
167
+ ")
168
+ end
169
+
159
170
  def self.should_be_queued
160
171
  current_time = Time.zone.now
161
172
  # Applications that are still running
@@ -33,8 +33,14 @@ module Naf
33
33
  self.send(invocation_method.to_sym, job)
34
34
  end
35
35
 
36
+ # This method calls Process.spawn to excute a built command. The first part
37
+ # of the command is the execution of the job command, redirecting stderr to
38
+ # stdout. Stdout and stderr are then sent through a pipe to be used as input
39
+ # for the job logger. The job logger will also redirect stderr to stdout, and
40
+ # save any crash logs. At the end of the built command, there is a exit $PIPESTATUS
41
+ # command that will return the exit status of the whole command.
36
42
  def invoke(job, job_command)
37
- command = job_command + " 2>&1 | #{JOB_LOGGER} >> #{LOGGING_ROOT_DIRECTORY}/naf/crash.log 2>&1"
43
+ command = job_command + " 2>&1 | #{JOB_LOGGER} >> #{LOGGING_ROOT_DIRECTORY}/naf/crash.log 2>&1; exit $PIPESTATUS"
38
44
  Process.spawn({ 'NAF_JOB_ID' => job.id.to_s }, command)
39
45
  end
40
46
 
@@ -202,9 +202,9 @@ module Naf
202
202
  started_on(self).each do |job|
203
203
 
204
204
  marking_at = Time.zone.now
205
- machine_logger.alarm "#{by_machine.id} marking #{job} as dead at #{marking_at}"
205
+ machine_logger.alarm "#{by_machine.try(:id)} marking #{job} as dead at #{marking_at}"
206
206
  job.request_to_terminate = job.historical_job.request_to_terminate = true
207
- job.marked_dead_by_machine_id = job.historical_job.marked_dead_by_machine_id = by_machine.id
207
+ job.marked_dead_by_machine_id = job.historical_job.marked_dead_by_machine_id = by_machine.try(:id)
208
208
  job.marked_dead_at = job.historical_job.marked_dead_at = marking_at
209
209
  job.historical_job.finished_at = marking_at
210
210
  job.save!
@@ -216,7 +216,7 @@ module Naf
216
216
  marking_at = Time.zone.now
217
217
  machine_logger.alarm "#{by_machine.try(:id)} marking #{self} as down at #{marking_at}"
218
218
  self.marked_down = true
219
- self.marked_down_by_machine_id = by_machine.id
219
+ self.marked_down_by_machine_id = by_machine.try(:id)
220
220
  self.marked_down_at = marking_at
221
221
  save!
222
222
  mark_processes_as_dead(by_machine)
@@ -224,7 +224,7 @@ module Naf
224
224
 
225
225
  def affinity
226
226
  return ::Naf::Affinity.
227
- where(affinity_classification_id: ::Naf::AffinityClassification.location.id,
227
+ where(affinity_classification_id: ::Naf::AffinityClassification.machine.id,
228
228
  affinity_name: self.id.to_s).first
229
229
  end
230
230
 
@@ -66,7 +66,8 @@ module Process::Naf
66
66
  today = Time.zone.now.to_date
67
67
  files.each do |file|
68
68
  logger.info "Archived file: #{file}"
69
- `rm #{file}`
69
+ directory = `dirname #{file}`
70
+ `rm -r #{directory}`
70
71
  end
71
72
  end
72
73
 
@@ -0,0 +1,25 @@
1
+ module Process::Naf
2
+ class LogArchiverQueuer < ::Process::Naf::Application
3
+
4
+ def work
5
+ # Archive logs
6
+ params = { command: log_archiver.command }
7
+ boss.enqueue_n_commands_on_machines(params, :from_limit, machines)
8
+ end
9
+
10
+ private
11
+
12
+ def boss
13
+ ::Logical::Naf::ConstructionZone::Boss.new
14
+ end
15
+
16
+ def machines
17
+ ::Naf::Machine.enabled.up.all
18
+ end
19
+
20
+ def log_archiver
21
+ ::Naf::Application.where(command: '::Process::Naf::LogArchiver.run').first
22
+ end
23
+
24
+ end
25
+ end
@@ -1,5 +1,3 @@
1
- require 'open4'
2
-
3
1
  module Process::Naf::Logger
4
2
  class Base < ::Af::Application
5
3
 
@@ -165,7 +165,12 @@
165
165
  }
166
166
  },
167
167
  error: function(response) {
168
- jQuery('#stdout').prepend('Something went wrong, retry your search.');
168
+ message = '&nbsp;&nbsp;<span>Failed to retrieve ' + '<%= record_type %>' + '(' +
169
+ '<%= record_id %>' + ') logs from ' + '<%= logs_url %>'.match(/^https?\:\/\/([^\/?#]+)/).pop() + '. Please refer to ' +
170
+ 'Naf FAQs on the' + ' wiki'.link('https://github.com/fiksu/naf/wiki/Frequently-Asked-Questions') +
171
+ ' for further information.<br></span>';
172
+
173
+ jQuery('#stdout').prepend(message);
169
174
  }
170
175
  });
171
176
  }
data/lib/naf.rb CHANGED
@@ -21,10 +21,6 @@ module Naf
21
21
  configuration.model_class.constantize
22
22
  end
23
23
 
24
- def controller_class
25
- configuration.controller_class.constantize
26
- end
27
-
28
24
  def title
29
25
  configuration.title
30
26
  end
@@ -33,6 +29,22 @@ module Naf
33
29
  configuration.layout
34
30
  end
35
31
 
32
+ def ui_controller_class
33
+ configuration.ui_controller_class.constantize
34
+ end
35
+
36
+ def api_controller_class
37
+ configuration.api_controller_class.constantize
38
+ end
39
+
40
+ def api_domain_cookie_name
41
+ configuration.api_domain_cookie_name
42
+ end
43
+
44
+ def simple_cluster_authenticator_cookie_expiration_time
45
+ configuration.simple_cluster_authenticator_cookie_expiration_time
46
+ end
47
+
36
48
  def using_another_database?
37
49
  model_class != ActiveRecord::Base
38
50
  end
@@ -2,17 +2,23 @@ module Naf
2
2
  class Configuration
3
3
  attr_accessor :schema_name,
4
4
  :model_class,
5
- :controller_class,
5
+ :ui_controller_class,
6
+ :api_controller_class,
6
7
  :title,
7
8
  :layout,
8
- :default_page_options
9
+ :default_page_options,
10
+ :api_domain_cookie_name,
11
+ :simple_cluster_authenticator_cookie_expiration_time
9
12
 
10
13
  def initialize
11
14
  @model_class = "::ActiveRecord::Base"
12
- @controller_class = "::ApplicationController"
15
+ @ui_controller_class = "::ApplicationController"
13
16
  @title = "Naf - a Rails Job Scheduling Engine"
14
17
  @layout = "naf_layout"
15
18
  @default_page_options = [10, 20, 50, 100, 250, 500, 750, 1000, 1500, 2000]
19
+ @api_controller_class = "Naf::ApiSimpleClusterAuthenticatorApplicationController"
20
+ @simple_cluster_authenticator_cookie_expiration_time = 1.week
21
+ @api_domain_cookie_name = "naf_#{Rails.application.class.parent.name.underscore}"
16
22
  end
17
23
 
18
24
  end
data/lib/naf/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Naf
2
- VERSION = '2.1.6'
2
+ VERSION = '2.1.8'
3
3
  end
data/naf.gemspec CHANGED
@@ -8,11 +8,11 @@ Gem::Specification.new do |s|
8
8
  s.name = "naf"
9
9
  s.version = Naf::VERSION
10
10
  s.license = 'New BSD License'
11
- s.date = '2014-03-05'
11
+ s.date = '2014-03-24'
12
12
  s.summary = "Creates infrastructure for a customizable and robust Postgres-backed script scheduling/running"
13
13
  s.description = "A cloud based distributed cron, application framework and operations console. Naf works as a distributed script running " +
14
14
  "system that provides scheduling, logging, alarming, machine redundancy, and the ability to set constraint during script execution"
15
- s.authors = ["Keith Gabryelski", "Leonardo Meira", "Nathaniel Lim", "Aleksandr Dembskiy"]
15
+ s.authors = ["Keith Gabryelski", "Leonardo Meira"]
16
16
  s.email = ['keith@fiksu.com', 'lmeira@fiksu.com']
17
17
  s.files = `git ls-files`.split("\n")
18
18
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
@@ -3,7 +3,7 @@ require 'spec_helper'
3
3
  module Naf
4
4
  describe ApplicationController do
5
5
  it "should inherit from specified controller" do
6
- ApplicationController.superclass.should == Naf.controller_class
6
+ ApplicationController.superclass.should == Naf.ui_controller_class
7
7
  end
8
8
  end
9
9
 
@@ -224,6 +224,11 @@ FactoryGirl.define do
224
224
  end
225
225
  end
226
226
 
227
+ factory :run_group_restriction, class: ::Naf::ApplicationRunGroupRestriction do
228
+ id 4
229
+ application_run_group_restriction_name "restriction"
230
+ end
231
+
227
232
  #############################################################
228
233
  ####### Application Types #################################
229
234
  #############################################################
@@ -307,6 +312,16 @@ FactoryGirl.define do
307
312
  end
308
313
  end
309
314
 
315
+ factory :machine_affinity, class: ::Naf::Affinity do
316
+ id 4
317
+ association :affinity_classification, factory: :machine_affinity_classification
318
+ affinity_name "machine"
319
+ # Ensure single creation
320
+ initialize_with do
321
+ ::Naf::Affinity.find_or_initialize_by_id(id)
322
+ end
323
+ end
324
+
310
325
  factory :affinity, class: ::Naf::Affinity do
311
326
  association :affinity_classification, factory: :purpose_affinity_classification
312
327
  sequence(:affinity_name) do |n|
@@ -342,6 +357,22 @@ FactoryGirl.define do
342
357
  end
343
358
  end
344
359
 
360
+ factory :weight_affinity_classification, class: ::Naf::AffinityClassification do
361
+ id 4
362
+ affinity_classification_name "weight"
363
+ initialize_with do
364
+ ::Naf::AffinityClassification.find_or_initialize_by_id(id)
365
+ end
366
+ end
367
+
368
+ factory :machine_affinity_classification, class: ::Naf::AffinityClassification do
369
+ id 5
370
+ affinity_classification_name "machine"
371
+ initialize_with do
372
+ ::Naf::AffinityClassification.find_or_initialize_by_id(id)
373
+ end
374
+ end
375
+
345
376
  factory :affinity_classification, class: ::Naf::AffinityClassification do
346
377
  sequence(:affinity_classification_name) { |n| "affinity_classification_#{n}" }
347
378
  end
@@ -368,6 +399,14 @@ FactoryGirl.define do
368
399
  association :affinity, factory: :canary_affinity
369
400
  end
370
401
 
402
+ factory :weight_job_affinity_tab, parent: :job_affinity_tab_base do
403
+ association :affinity, factory: :weight_affinity
404
+ end
405
+
406
+ factory :machine_job_affinity_tab, parent: :job_affinity_tab_base do
407
+ association :affinity, factory: :machine_affinity
408
+ end
409
+
371
410
  # Application Schedule Affinity Tabs
372
411
 
373
412
  factory :app_schedule_affinity_tab_base, class: ::Naf::ApplicationScheduleAffinityTab do
@@ -0,0 +1,119 @@
1
+ require 'spec_helper'
2
+
3
+ module Logical::Naf::ConstructionZone
4
+
5
+ describe Boss do
6
+ let!(:boss) { Logical::Naf::ConstructionZone::Boss.new }
7
+ let!(:work_order) {
8
+ Logical::Naf::ConstructionZone::WorkOrder.new('::Process::Naf::Janitor.run')
9
+ }
10
+ let(:params) { {
11
+ command: '::Process::Naf::Janitor.run',
12
+ application_type: ::Naf::ApplicationType.rails,
13
+ application_run_group_restriction: ::Naf::ApplicationRunGroupRestriction.
14
+ limited_per_all_machines,
15
+ application_run_group_name: '::Process::Naf::Janitor.run',
16
+ application_run_group_limit: 1,
17
+ priority: 0,
18
+ affinities: [],
19
+ prerequisites: [],
20
+ enqueue_backlogs: false,
21
+ application: nil,
22
+ application_schedule: nil
23
+ } }
24
+
25
+ shared_examples 'create one historical job' do |num_records|
26
+ it 'return the correct object' do
27
+ job.should be_a(::Naf::HistoricalJob)
28
+ end
29
+
30
+ it 'return correct number of historical jobs' do
31
+ ::Naf::HistoricalJob.should have(num_records).records
32
+ end
33
+ end
34
+
35
+ describe '#enqueue_application' do
36
+ let(:application) { FactoryGirl.create(:application) }
37
+ let!(:job) {
38
+ boss.enqueue_application(application,
39
+ ::Naf::ApplicationRunGroupRestriction.no_limit,
40
+ application.command)
41
+ }
42
+
43
+ it_should_behave_like 'create one historical job', 1
44
+ end
45
+
46
+ describe '#enqueue_application_schedule' do
47
+ let!(:job) { boss.enqueue_application_schedule(FactoryGirl.create(:schedule)) }
48
+
49
+ it_should_behave_like 'create one historical job', 1
50
+ end
51
+
52
+ describe '#enqueue_rails_command' do
53
+ let!(:job) { boss.enqueue_rails_command('::Process::Naf::Janitor.run') }
54
+
55
+ it_should_behave_like 'create one historical job', 1
56
+ end
57
+
58
+ describe '#enqueue_command' do
59
+ let!(:job) { boss.enqueue_command('::Process::Naf::Janitor.run') }
60
+
61
+ it_should_behave_like 'create one historical job', 1
62
+ end
63
+
64
+ describe '#enqueue_ad_hoc_command' do
65
+ let!(:job) { boss.enqueue_ad_hoc_command(params) }
66
+
67
+ it_should_behave_like 'create one historical job', 1
68
+ end
69
+
70
+ describe '#enqueue_n_commands_on_machines' do
71
+ let!(:affinity) { FactoryGirl.create(:normal_affinity) }
72
+
73
+ before do
74
+ params[:application_run_group_quantum] = 2
75
+ params[:application_run_group_limit] = 5
76
+ end
77
+
78
+ it 'not create a historical job when array of machines is empty' do
79
+ boss.enqueue_n_commands_on_machines({})
80
+ ::Naf::HistoricalJob.should have(0).records
81
+ end
82
+
83
+ it 'create two historical jobs when a machine is present' do
84
+ machine = FactoryGirl.create(:machine)
85
+ classification = FactoryGirl.create(:location_affinity_classification)
86
+ FactoryGirl.create(:affinity, id: 5,
87
+ affinity_name: machine.id.to_s,
88
+ affinity_classification: classification)
89
+
90
+ boss.enqueue_n_commands_on_machines(params, :from_limit, [machine])
91
+ ::Naf::HistoricalJob.should have(2).records
92
+ end
93
+ end
94
+
95
+ describe '#enqueue_n_commands' do
96
+ subject { boss.enqueue_n_commands(params) }
97
+
98
+ it 'create one historical jobs when application_run_group_quantum is not specified' do
99
+ params[:application_run_group_quantum] = 1
100
+ subject
101
+ ::Naf::HistoricalJob.should have(1).records
102
+ end
103
+
104
+ it 'create five historical jobs' do
105
+ params[:application_run_group_quantum] = 5
106
+ params[:application_run_group_limit] = 5
107
+ subject
108
+ ::Naf::HistoricalJob.should have(5).records
109
+ end
110
+ end
111
+
112
+ describe '#reenqueue' do
113
+ let!(:job) { boss.reenqueue(FactoryGirl.create(:job)) }
114
+
115
+ it_should_behave_like 'create one historical job', 2
116
+ end
117
+ end
118
+
119
+ end
@@ -0,0 +1,105 @@
1
+ require 'spec_helper'
2
+
3
+ module Logical::Naf::ConstructionZone
4
+ describe Foreman do
5
+
6
+ let!(:foreman) { Logical::Naf::ConstructionZone::Foreman.new }
7
+ let!(:work_order) {
8
+ Logical::Naf::ConstructionZone::WorkOrder.new('::Process::Naf::Janitor.run')
9
+ }
10
+
11
+ describe '#enqueue' do
12
+ it 'return historical job when enqueue_backlogs is set to true' do
13
+ work_order.enqueue_backlogs
14
+ foreman.enqueue(work_order).should be_a(::Naf::HistoricalJob)
15
+ end
16
+
17
+ it 'return historical job when enqueue_backlogs is set to false and there is not run group limit' do
18
+ foreman.enqueue(work_order).should be_a(::Naf::HistoricalJob)
19
+ end
20
+
21
+ it 'return nil when work order is limited by run group' do
22
+ foreman.should_receive(:limited_by_run_group?).and_return(true)
23
+ foreman.enqueue(work_order).should be_nil
24
+ end
25
+ end
26
+
27
+ describe '#limited_by_run_group?' do
28
+ let!(:no_limit) { FactoryGirl.create(:no_limit) }
29
+ let!(:limited_per_machine) { FactoryGirl.create(:limited_per_machine) }
30
+ let!(:limited_per_all_machines) { FactoryGirl.create(:limited_per_all_machines) }
31
+
32
+ it 'return false when run group restriction is set to no limit' do
33
+ foreman.limited_by_run_group?(no_limit, nil, nil, []).should be_false
34
+ end
35
+
36
+ it 'return false when run group limit is nil' do
37
+ foreman.limited_by_run_group?(limited_per_machine, 'test', nil, []).should be_false
38
+ end
39
+
40
+ it 'return false when run group name is nil' do
41
+ foreman.limited_by_run_group?(limited_per_machine, nil, 1, []).should be_false
42
+ end
43
+
44
+ describe 'run group restriction is set to limited per machine' do
45
+ let!(:machine) { FactoryGirl.create(:machine) }
46
+ let(:historical_job) { FactoryGirl.create(:job, application_run_group_name: 'test') }
47
+ let(:tab) { FactoryGirl.create(:machine_job_affinity_tab, historical_job_id: historical_job.id) }
48
+
49
+ before do
50
+ FactoryGirl.create(:queued_job, application_run_group_name: 'test', id: historical_job.id)
51
+ FactoryGirl.create(:running_job_base, application_run_group_name: 'test',
52
+ started_on_machine_id: machine.id,
53
+ application_run_group_name: 'test')
54
+ end
55
+
56
+ it 'return false when application does not have affinity associated with machine' do
57
+ foreman.limited_by_run_group?(limited_per_machine, 'test', 1, []).should be_false
58
+ end
59
+
60
+ it 'return false when limit is greater than number of running/queued jobs' do
61
+ foreman.limited_by_run_group?(
62
+ limited_per_machine, 'test', 5, [{ affinity_id: tab.affinity.id }]
63
+ ).should be_false
64
+ end
65
+
66
+ it 'return true when limit is equal to number of running/queued jobs' do
67
+ foreman.limited_by_run_group?(
68
+ limited_per_machine, 'test', 1, [{ affinity_id: tab.affinity.id }]
69
+ ).should be_true
70
+ end
71
+
72
+ it 'return true when limit is less than number of running/queued jobs' do
73
+ FactoryGirl.create(:running_job_base, application_run_group_name: 'test',
74
+ started_on_machine_id: machine.id,
75
+ application_run_group_name: 'test')
76
+ foreman.limited_by_run_group?(
77
+ limited_per_machine, 'test', 1, [{ affinity_id: tab.affinity.id }]
78
+ ).should be_true
79
+ end
80
+ end
81
+
82
+ describe 'run group restriction is set to limited per all machines' do
83
+ it 'return false when limit is greater than number of running/queued jobs' do
84
+ foreman.limited_by_run_group?(limited_per_all_machines, 'test', 1, []).should be_false
85
+ end
86
+
87
+ it 'return true when limit is equal to number of running/queued jobs' do
88
+ FactoryGirl.create(:queued_job, application_run_group_name: 'test')
89
+ foreman.limited_by_run_group?(limited_per_all_machines, 'test', 1, []).should be_true
90
+ end
91
+
92
+ it 'return true when limit is less than number of running/queued jobs' do
93
+ FactoryGirl.create(:queued_job, application_run_group_name: 'test')
94
+ FactoryGirl.create(:running_job_base, application_run_group_name: 'test')
95
+ foreman.limited_by_run_group?(limited_per_all_machines, 'test', 1, []).should be_true
96
+ end
97
+ end
98
+
99
+ it 'return true when a different run group restriction is found' do
100
+ restriction = FactoryGirl.create(:run_group_restriction)
101
+ foreman.limited_by_run_group?(restriction, 'test', 1, []).should be_true
102
+ end
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,67 @@
1
+ require 'spec_helper'
2
+
3
+ module Logical::Naf::ConstructionZone
4
+
5
+ describe Proletariat do
6
+
7
+ let!(:proletariat) { ::Logical::Naf::ConstructionZone::Proletariat.new }
8
+ let(:application) { FactoryGirl.create(:scheduled_application) }
9
+ let(:application_type) { FactoryGirl.create(:rails_app_type) }
10
+ let(:restriction) { FactoryGirl.create(:no_limit) }
11
+ let!(:params) {
12
+ {
13
+ command: '::Process::Naf::Janitor.run',
14
+ application_type_id: application_type.id,
15
+ application_run_group_restriction_id: restriction.id,
16
+ application_run_group_name: '::Process::Naf::Janitor.run',
17
+ application_run_group_limit: 1,
18
+ priority: 0,
19
+ application_id: application.id,
20
+ application_schedule_id: application.application_schedules.first.id
21
+ }
22
+ }
23
+ let!(:affinity) { { affinity_id: FactoryGirl.create(:normal_affinity).id } }
24
+ let!(:prerequisite) { FactoryGirl.create(:job) }
25
+
26
+ describe '#create_job' do
27
+ it 'return a historical job' do
28
+ proletariat.create_job(params, [], []).should be_a(::Naf::HistoricalJob)
29
+ end
30
+ end
31
+
32
+ describe '#create_historical_job' do
33
+ let!(:historical_job) { proletariat.create_historical_job(params, [affinity], [prerequisite]) }
34
+
35
+ it 'return historical job when exception is not raised' do
36
+ historical_job.should be_a(::Naf::HistoricalJob)
37
+ end
38
+
39
+ it 'create a historical job affinity tab' do
40
+ ::Naf::HistoricalJobAffinityTab.should have(1).records
41
+ end
42
+
43
+ it 'create a historical job affinity tab' do
44
+ ::Naf::HistoricalJobPrerequisite.should have(1).records
45
+ end
46
+
47
+ it 'raise an exception when there is a loop found in prerequisites' do
48
+ prerequisite.should_receive(:prerequisites).and_raise(::Naf::HistoricalJob::JobPrerequisiteLoop.new(prerequisite))
49
+ begin
50
+ job = proletariat.create_historical_job(params, [affinity], [prerequisite])
51
+ rescue
52
+ end
53
+ job.should be_nil
54
+ end
55
+ end
56
+
57
+ describe '#create_queued_job' do
58
+ let!(:historical_job) { FactoryGirl.create(:scheduled_job) }
59
+
60
+ it 'return a queued job' do
61
+ historical_job.application_schedule_id = historical_job.application.application_schedules.first.id
62
+ proletariat.create_queued_job(historical_job).should be_a(::Naf::QueuedJob)
63
+ end
64
+ end
65
+ end
66
+
67
+ end
@@ -21,6 +21,7 @@ module Logical::Naf::ConstructionZone
21
21
  application_schedule_id: nil
22
22
  }
23
23
  }
24
+
24
25
  it 'return correct values' do
25
26
  work_order.historical_job_parameters.should == params
26
27
  end
@@ -49,7 +50,7 @@ module Logical::Naf::ConstructionZone
49
50
 
50
51
  it 'return hash with the affinity_id when a Machine object is provided' do
51
52
  machine = FactoryGirl.create(:machine)
52
- classification = FactoryGirl.create(:location_affinity_classification)
53
+ classification = FactoryGirl.create(:machine_affinity_classification)
53
54
  affinity = FactoryGirl.create(:affinity, id: 4,
54
55
  affinity_name: machine.id.to_s,
55
56
  affinity_classification: classification)
@@ -0,0 +1,92 @@
1
+ require 'spec_helper'
2
+
3
+ module Logical
4
+ module Naf
5
+
6
+ describe UserSession do
7
+ let!(:user_session) { ::Logical::Naf::UserSession.new(nil) }
8
+
9
+ describe '#valid?' do
10
+ it 'return false when message is not present' do
11
+ user_session.valid?.should be_false
12
+ end
13
+
14
+ it 'return false when value is not present' do
15
+ user_session.instance_variable_set(:@message, {})
16
+ user_session.valid?.should be_false
17
+ end
18
+
19
+ it 'return false when session is expired' do
20
+ user_session.instance_variable_set(:@message, { value: Time.zone.now - 1.month })
21
+ user_session.valid?.should be_false
22
+ end
23
+
24
+ it 'return true for invalid signed message' do
25
+ user_session.instance_variable_set(:@message, { value: Time.zone.now - 1.hour })
26
+ user_session.valid?.should be_true
27
+ end
28
+ end
29
+
30
+ describe '#token_cookie' do
31
+ let!(:signed_message) { user_session.token_cookie }
32
+
33
+ it 'not be nil' do
34
+ signed_message.should_not be_nil
35
+ end
36
+ end
37
+
38
+ describe '#build_token_cookie' do
39
+ before do
40
+ Timecop.freeze(Time.zone.now)
41
+ end
42
+
43
+ after do
44
+ Timecop.return
45
+ end
46
+
47
+ it 'return hash with current time' do
48
+ ::Logical::Naf::UserSession.build_token_cookie.should == { value: Time.zone.now }
49
+ end
50
+ end
51
+
52
+ describe '#sign_message' do
53
+ it 'return nil when message is nil' do
54
+ ::Logical::Naf::UserSession.sign_message(nil).should be_nil
55
+ end
56
+
57
+ it 'sign the message when message is present' do
58
+ ::Logical::Naf::UserSession.sign_message(::Logical::Naf::UserSession.build_token_cookie).
59
+ should =~ /^.{123}={1}-{2}[a-zA-Z0-9]{40}$/
60
+ end
61
+ end
62
+
63
+ describe '#unsign_message' do
64
+ it 'return nil when message is not signed' do
65
+ ::Logical::Naf::UserSession.unsign_message(nil).should be_nil
66
+ end
67
+
68
+ it 'return nil when InvalidSignature exception is raised' do
69
+ ::Logical::Naf::UserSession.stub(:message_verifier).
70
+ and_raise(ActiveSupport::MessageVerifier::InvalidSignature)
71
+ ::Logical::Naf::UserSession.unsign_message(nil).should be_nil
72
+ end
73
+
74
+ it 'return message when signed message is valid' do
75
+ message_verifier = ActiveSupport::MessageVerifier.
76
+ new(Rails.application.class.config.secret_token)
77
+ message = { value: Time.zone.now }
78
+
79
+ ::Logical::Naf::UserSession.
80
+ unsign_message(message_verifier.generate(message)).should == message
81
+ end
82
+ end
83
+
84
+ describe '#message_verifier' do
85
+ it 'return instance of ActiveSupport::MessageVerifier' do
86
+ ::Logical::Naf::UserSession.message_verifier.should be_a(ActiveSupport::MessageVerifier)
87
+ end
88
+ end
89
+ end
90
+
91
+ end
92
+ end
@@ -95,6 +95,12 @@ module Naf
95
95
  time = Time.zone.now
96
96
  ::Naf::ApplicationSchedule.exact_schedules(time, {}, {}).should == []
97
97
  end
98
+
99
+ it "return no schedules when application is deleted" do
100
+ schedule.application.deleted = true
101
+ schedule.application.save!
102
+ ::Naf::ApplicationSchedule.exact_schedules(time, {}, {}).should == []
103
+ end
98
104
  end
99
105
 
100
106
  describe "#relative_schedules" do
@@ -116,6 +122,61 @@ module Naf
116
122
  schedule.run_interval = 20
117
123
  ::Naf::ApplicationSchedule.relative_schedules(time, {}, apps).should == []
118
124
  end
125
+
126
+ it "return no schedules when application is deleted" do
127
+ schedule.application.deleted = true
128
+ schedule.application.save!
129
+ ::Naf::ApplicationSchedule.exact_schedules(time, {}, {}).should == []
130
+ end
131
+ end
132
+
133
+ describe "#constant_schedules" do
134
+ it "return schedule when it is ready" do
135
+ schedule.run_interval_style.name = 'keep running'
136
+ schedule.run_interval_style.save!
137
+
138
+ ::Naf::ApplicationSchedule.constant_schedules.should == [schedule]
139
+ end
140
+
141
+ it "return no schedules when application is deleted" do
142
+ schedule.application.deleted = true
143
+ schedule.application.save!
144
+ ::Naf::ApplicationSchedule.constant_schedules.should == []
145
+ end
146
+
147
+ it "return no schedules when schedule is disabled" do
148
+ schedule.enabled = false
149
+ schedule.save!
150
+ ::Naf::ApplicationSchedule.constant_schedules.should == []
151
+ end
152
+
153
+ it "return no schdules when run interval style is not keep running" do
154
+ ::Naf::ApplicationSchedule.constant_schedules.should == []
155
+ end
156
+ end
157
+
158
+ describe "#enabled" do
159
+ it "return empty array when schedule is disabled" do
160
+ schedule.enabled = false
161
+ schedule.save!
162
+ ::Naf::ApplicationSchedule.enabled.should == []
163
+ end
164
+
165
+ it "return array with schedule when schedule is enabled" do
166
+ ::Naf::ApplicationSchedule.enabled.should == [schedule]
167
+ end
168
+ end
169
+
170
+ describe "#application_not_deleted" do
171
+ it "return empty array when application is deleted" do
172
+ schedule.application.deleted = true
173
+ schedule.application.save!
174
+ ::Naf::ApplicationSchedule.application_not_deleted.should == []
175
+ end
176
+
177
+ it "return array with schedule when application is not deleted" do
178
+ ::Naf::ApplicationSchedule.application_not_deleted.should == [schedule]
179
+ end
119
180
  end
120
181
 
121
182
  #-------------------------
@@ -396,10 +396,12 @@ module Naf
396
396
  end
397
397
 
398
398
  describe "#affinity" do
399
+ let!(:classification) { FactoryGirl.create(:machine_affinity_classification) }
399
400
  it "return affinity associated with machine's id" do
400
- affinity = FactoryGirl.create(:affinity, id: 4,
401
- affinity_classification_id: 1,
402
- affinity_name: machine.id.to_s)
401
+ affinity = FactoryGirl.create(:affinity,
402
+ id: 4,
403
+ affinity_classification_id: FactoryGirl.create(:machine_affinity_classification).id,
404
+ affinity_name: machine.id.to_s)
403
405
  machine.affinity.should == affinity
404
406
  end
405
407
 
metadata CHANGED
@@ -1,18 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: naf
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.6
4
+ version: 2.1.8
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - Keith Gabryelski
9
9
  - Leonardo Meira
10
- - Nathaniel Lim
11
- - Aleksandr Dembskiy
12
10
  autorequire:
13
11
  bindir: bin
14
12
  cert_chain: []
15
- date: 2014-03-05 00:00:00.000000000 Z
13
+ date: 2014-03-24 00:00:00.000000000 Z
16
14
  dependencies:
17
15
  - !ruby/object:Gem::Dependency
18
16
  name: rails
@@ -239,6 +237,7 @@ files:
239
237
  - app/assets/stylesheets/naf.css
240
238
  - app/assets/stylesheets/naf/layout.css.scss
241
239
  - app/controllers/naf/affinities_controller.rb
240
+ - app/controllers/naf/api_simple_cluster_authenticator_application_controller.rb
242
241
  - app/controllers/naf/application_controller.rb
243
242
  - app/controllers/naf/application_schedule_affinity_tabs_controller.rb
244
243
  - app/controllers/naf/application_schedules_controller.rb
@@ -287,6 +286,7 @@ files:
287
286
  - app/models/logical/naf/machine_runner_invocation.rb
288
287
  - app/models/logical/naf/pickler.rb
289
288
  - app/models/logical/naf/unpickler.rb
289
+ - app/models/logical/naf/user_session.rb
290
290
  - app/models/naf/affinity.rb
291
291
  - app/models/naf/affinity_classification.rb
292
292
  - app/models/naf/application.rb
@@ -319,6 +319,7 @@ files:
319
319
  - app/models/process/naf/data_migration/backfill_application_schedule_run_interval.rb
320
320
  - app/models/process/naf/janitor.rb
321
321
  - app/models/process/naf/log_archiver.rb
322
+ - app/models/process/naf/log_archiver_queuer.rb
322
323
  - app/models/process/naf/log_reader.rb
323
324
  - app/models/process/naf/logger/base.rb
324
325
  - app/models/process/naf/logger/job_log.rb
@@ -485,6 +486,9 @@ files:
485
486
  - spec/factories/naf.rb
486
487
  - spec/helpers/naf/application_helper_spec.rb
487
488
  - spec/models/logical/naf/application_spec.rb
489
+ - spec/models/logical/naf/construction_zone/boss_rspec.rb
490
+ - spec/models/logical/naf/construction_zone/foreman_spec.rb
491
+ - spec/models/logical/naf/construction_zone/proletariat_spec.rb
488
492
  - spec/models/logical/naf/construction_zone/work_order_spec.rb
489
493
  - spec/models/logical/naf/job_fetcher_spec.rb
490
494
  - spec/models/logical/naf/job_spec.rb
@@ -492,6 +496,7 @@ files:
492
496
  - spec/models/logical/naf/machine_runner_invocation_spec.rb
493
497
  - spec/models/logical/naf/machine_runner_spec.rb
494
498
  - spec/models/logical/naf/machine_spec.rb
499
+ - spec/models/logical/naf/user_session_spec.rb
495
500
  - spec/models/naf/affinity_classification_spec.rb
496
501
  - spec/models/naf/affinity_spec.rb
497
502
  - spec/models/naf/application_run_group_restriction_spec.rb
@@ -600,6 +605,9 @@ test_files:
600
605
  - spec/factories/naf.rb
601
606
  - spec/helpers/naf/application_helper_spec.rb
602
607
  - spec/models/logical/naf/application_spec.rb
608
+ - spec/models/logical/naf/construction_zone/boss_rspec.rb
609
+ - spec/models/logical/naf/construction_zone/foreman_spec.rb
610
+ - spec/models/logical/naf/construction_zone/proletariat_spec.rb
603
611
  - spec/models/logical/naf/construction_zone/work_order_spec.rb
604
612
  - spec/models/logical/naf/job_fetcher_spec.rb
605
613
  - spec/models/logical/naf/job_spec.rb
@@ -607,6 +615,7 @@ test_files:
607
615
  - spec/models/logical/naf/machine_runner_invocation_spec.rb
608
616
  - spec/models/logical/naf/machine_runner_spec.rb
609
617
  - spec/models/logical/naf/machine_spec.rb
618
+ - spec/models/logical/naf/user_session_spec.rb
610
619
  - spec/models/naf/affinity_classification_spec.rb
611
620
  - spec/models/naf/affinity_spec.rb
612
621
  - spec/models/naf/application_run_group_restriction_spec.rb