18004: Fixes a couple of race condition bugs related to caching remote users.
[arvados.git] / services / api / lib / simulate_job_log.rb
1 # Copyright (C) The Arvados Authors. All rights reserved.
2 #
3 # SPDX-License-Identifier: AGPL-3.0
4
5 require 'current_api_client'
6
7 module SimulateJobLog
8   include CurrentApiClient
9   def replay(filename, multiplier = 1, simulated_job_uuid = nil)
10     raise "Environment must be development or test" unless [ 'test', 'development' ].include? ENV['RAILS_ENV']
11
12     multiplier = multiplier.to_f
13     multiplier = 1.0 if multiplier <= 0
14
15     actual_start_time = Time.now
16     log_start_time = nil
17
18     if simulated_job_uuid and (job = Job.where(uuid: simulated_job_uuid).first)
19       job_owner_uuid = job.owner_uuid
20     else
21       job_owner_uuid = system_user_uuid
22     end
23
24     act_as_system_user do
25       File.open(filename).each.with_index do |line, index|
26         cols = {}
27         cols[:timestamp], rest_of_line = line.split(' ', 2)
28         begin
29           cols[:timestamp] = Time.strptime( cols[:timestamp], "%Y-%m-%d_%H:%M:%S" )
30         rescue ArgumentError
31           if line =~ /^((?:Sun|Mon|Tue|Wed|Thu|Fri|Sat) (?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) \d{1,2} \d\d:\d\d:\d\d \d{4}) (.*)/
32             # Wed Nov 19 07:12:39 2014
33             cols[:timestamp] = Time.strptime( $1, "%a %b %d %H:%M:%S %Y" )
34             rest_of_line = $2
35           else
36               STDERR.puts "Ignoring log line because of unknown time format: #{line}"
37           end
38         end
39         cols[:job_uuid], cols[:pid], cols[:task], cols[:event_type], cols[:message] = rest_of_line.split(' ', 5)
40         # Override job uuid with a simulated one if specified
41         cols[:job_uuid] = simulated_job_uuid || cols[:job_uuid]
42         # determine when we want to simulate this log being created, based on the time multiplier
43         log_start_time = cols[:timestamp] if log_start_time.nil?
44         log_time = cols[:timestamp]
45         actual_elapsed_time = Time.now - actual_start_time
46         log_elapsed_time = log_time - log_start_time
47         modified_elapsed_time = log_elapsed_time / multiplier
48         pause_time = modified_elapsed_time - actual_elapsed_time
49         sleep pause_time if pause_time > 0
50
51         Log.new({
52           owner_uuid:  job_owner_uuid,
53           event_at:    Time.zone.local_to_utc(cols[:timestamp]),
54           object_uuid: cols[:job_uuid],
55           event_type:  cols[:event_type],
56           properties:  { 'text' => line }
57         }).save!
58       end
59     end
60
61   end
62 end