Skip to content

Commit a63b74b

Browse files
committed
RHELMISC-4745: Add ability to bring up previous session
1 parent 217a660 commit a63b74b

File tree

10 files changed

+162
-40
lines changed

10 files changed

+162
-40
lines changed

lib/all.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ module AutoHCK
5959
autoload_relative :PhysHCK, 'setupmanagers/physhck/physhck'
6060
autoload_relative :Playlist, 'engines/hcktest/playlist'
6161
autoload_relative :Project, 'project'
62+
autoload_relative :Session, 'session'
6263
autoload_relative :QemuHCK, 'setupmanagers/qemuhck/qemuhck'
6364
autoload_relative :QemuHCKError, 'setupmanagers/qemuhck/exceptions'
6465
autoload_relative :QemuMachine, 'setupmanagers/qemuhck/qemu_machine'

lib/cli.rb

Lines changed: 57 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
module AutoHCK
55
# class CLI
66
class CLI
7-
attr_reader :common, :install, :test, :mode
7+
attr_reader :install, :mode
8+
attr_accessor :common, :test
89

910
def initialize
1011
@common = CommonOptions.new
@@ -20,8 +21,15 @@ def initialize
2021
end
2122

2223
# class CommonOptions
23-
class CommonOptions
24-
attr_accessor :verbose, :config, :client_world_net, :id, :share_on_host_path, :workspace_path
24+
class CommonOptions < T::Struct
25+
include T::Sig
26+
27+
prop :verbose, T::Boolean, default: false
28+
prop :config, T.nilable(String)
29+
prop :client_world_net, T::Boolean, default: false
30+
prop :id, T.nilable(Integer), default: 2
31+
prop :share_on_host_path, T.nilable(String)
32+
prop :workspace_path, T.nilable(String)
2533

2634
def create_parser(sub_parser)
2735
OptionParser.new do |parser|
@@ -40,12 +48,6 @@ def create_parser(sub_parser)
4048

4149
# rubocop:disable Metrics/MethodLength
4250
def define_options(parser)
43-
@verbose = false
44-
@config = nil
45-
@client_world_net = false
46-
@id = 2
47-
@share_on_host_path = nil
48-
4951
parser.on('--share-on-host-path <path>', String,
5052
'For using Transfer Network specify the directory to share on host machine') do |share_on_host_path|
5153
@share_on_host_path = share_on_host_path
@@ -77,15 +79,30 @@ def define_options(parser)
7779
'Internal use only',
7880
&method(:workspace_path=))
7981
end
80-
# rubocop:enable Metrics/MethodLength
8182
end
8283

8384
# class TestOptions
84-
class TestOptions
85-
attr_accessor :platform, :drivers, :driver_path, :commit, :svvp, :dump,
86-
:gthb_context_prefix, :gthb_context_suffix, :playlist, :select_test_names,
87-
:reject_test_names, :reject_report_sections, :boot_device,
88-
:allow_test_duplication, :manual, :package_with_playlist
85+
class TestOptions < T::Struct
86+
include T::Sig
87+
88+
prop :platform, T.nilable(String)
89+
prop :drivers, T.nilable(T::Array[String])
90+
prop :driver_path, T.nilable(String)
91+
prop :commit, T.nilable(String)
92+
prop :svvp, T.nilable(T::Boolean)
93+
prop :dump, T.nilable(T::Boolean)
94+
prop :gthb_context_prefix, T.nilable(String)
95+
prop :gthb_context_suffix, T.nilable(String)
96+
prop :playlist, T.nilable(String)
97+
prop :select_test_names, T.nilable(String)
98+
prop :reject_test_names, T.nilable(String)
99+
prop :reject_report_sections, T.nilable(T::Array[String]), default: []
100+
prop :boot_device, T.nilable(String)
101+
prop :allow_test_duplication, T.nilable(T::Boolean)
102+
prop :manual, T.nilable(T::Boolean)
103+
prop :package_with_playlist, T.nilable(T::Boolean)
104+
prop :session, T.nilable(String)
105+
prop :latest_session, T.nilable(T::Boolean)
89106

90107
def create_parser
91108
OptionParser.new do |parser|
@@ -99,8 +116,7 @@ def create_parser
99116
end
100117
end
101118

102-
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
103-
def define_options(parser)
119+
def define_options(parser) # rubocop:disable Metrics/AbcSize
104120
@reject_report_sections = []
105121

106122
parser.on('-p', '--platform <platform_name>', String,
@@ -179,13 +195,28 @@ def define_options(parser)
179195
parser.on('--package-with-playlist', TrueClass,
180196
'Load playlist into HLKX project package',
181197
&method(:package_with_playlist=))
198+
199+
parser.on('--session <path>', String,
200+
'Load session from workspace',
201+
&method(:session=))
202+
203+
parser.on('--latest-session', TrueClass,
204+
'Load previous session',
205+
&method(:latest_session=))
182206
end
183-
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
207+
# rubocop:enable Metrics/MethodLength
184208
end
185209

186210
# class InstallOptions
187-
class InstallOptions
188-
attr_accessor :platform, :force, :skip_client, :drivers, :driver_path, :debug
211+
class InstallOptions < T::Struct
212+
include T::Sig
213+
214+
prop :platform, T.nilable(String)
215+
prop :force, T::Boolean, default: false
216+
prop :skip_client, T::Boolean, default: false
217+
prop :drivers, T::Array[String], default: []
218+
prop :driver_path, T.nilable(String)
219+
prop :debug, T::Boolean, default: false
189220

190221
def create_parser
191222
OptionParser.new do |parser|
@@ -199,13 +230,7 @@ def create_parser
199230
end
200231
end
201232

202-
# rubocop:disable Metrics/MethodLength
203233
def define_options(parser)
204-
@force = false
205-
@skip_client = false
206-
@drivers = []
207-
@debug = false
208-
209234
parser.on('--debug', TrueClass, 'Enable debug mode',
210235
&method(:debug=))
211236

@@ -229,13 +254,18 @@ def define_options(parser)
229254
'Path to the location of the driver wanted to be installed',
230255
&method(:driver_path=))
231256
end
232-
# rubocop:enable Metrics/MethodLength
233257
end
234258

235259
def parse(args)
236260
left = @parser.order(args)
237261
@mode = left.shift
238262
@sub_parser[@mode]&.order!(left) unless @mode.nil?
263+
264+
restore_session if @test.latest_session || @test.session
265+
end
266+
267+
def restore_session
268+
AutoHCK::Session.load(self)
239269
end
240270
end
241271
end

lib/engines/hcktest/hcktest.rb

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -160,13 +160,13 @@ def run_clients_post_start_host_commands
160160
end
161161

162162
def configure_and_synchronize_clients
163-
run_only = @project.options.test.manual && @project.options.test.driver_path.nil?
163+
run_only = @project.restored || (@project.options.test.manual && @project.options.test.driver_path.nil?)
164164

165165
@clients.each_value do |client|
166166
client.configure(run_only:)
167167
end
168168

169-
run_clients_post_start_host_commands
169+
run_clients_post_start_host_commands unless @project.restored
170170
@clients.each_value(&:synchronize)
171171
end
172172

@@ -183,7 +183,7 @@ def run_clients_and_configure_setup(scope, **opts)
183183
retries = 0
184184
begin
185185
scope.transaction do |tmp_scope|
186-
run_clients tmp_scope, keep_alive: true, **opts
186+
run_clients tmp_scope, keep_alive: true, **opts, **restored_options
187187

188188
configure_setup_and_synchronize
189189
end
@@ -245,9 +245,16 @@ def prepare_tests
245245
@test_list = @tests.list_tests(log: true)
246246
end
247247

248+
def restored_options
249+
{
250+
boot_from_snapshot: @project.restored,
251+
restored: @project.restored
252+
}
253+
end
254+
248255
def auto_run
249256
ResourceScope.open do |scope|
250-
run_studio scope
257+
run_studio(scope, create_snapshot: !@project.restored, **restored_options)
251258
sleep 5 until @studio.up?
252259

253260
run_tests_without_config
@@ -274,7 +281,7 @@ def run_tests_with_config
274281
next if tests.empty?
275282

276283
ResourceScope.open do |scope|
277-
run_clients_and_configure_setup(scope, group => true, create_snapshot: false, boot_from_snapshot: true)
284+
run_clients_and_configure_setup(scope, create_snapshot: false, group => true)
278285

279286
@logger.info("Clients ready, running #{group} tests")
280287
@tests.run(tests)
@@ -295,8 +302,8 @@ def group_tests_by_config
295302
grouped_tests
296303
end
297304

298-
def run
299-
upload_driver_package unless @driver_path.nil?
305+
def run # rubocop:disable Metrics/AbcSize
306+
upload_driver_package unless @driver_path.nil? || @project.restored
300307

301308
if @project.options.test.dump
302309
@project.logger.info('AutoHCK started in dump only mode')

lib/models.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ module Models
1111
autoload_relative :HCKTestConfig, 'models/hcktest_config'
1212
autoload_relative :JsonHelper, 'models/json_helper'
1313
autoload_relative :SVVPConfig, 'models/svvp_config'
14+
autoload_relative :Session, 'models/session'
1415
autoload_relative :QemuHCKDevice, 'models/qemuhck_device'
1516
end
1617
end

lib/models/session.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# typed: strict
2+
# frozen_string_literal: true
3+
4+
module AutoHCK
5+
module Models
6+
class Session < T::Struct
7+
extend T::Sig
8+
extend JsonHelper
9+
10+
const :test, AutoHCK::CLI::TestOptions
11+
const :common, AutoHCK::CLI::CommonOptions
12+
end
13+
end
14+
end

lib/project.rb

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ class Project
99
attr_reader :config, :logger, :timestamp, :setup_manager, :engine, :id,
1010
:workspace_path, :github, :result_uploader, :engine_tag,
1111
:engine_platform, :engine_type, :options, :extra_sw_manager,
12-
:run_terminated
12+
:run_terminated, :restored
1313

1414
def initialize(scope, options)
1515
@scope = scope
@@ -146,11 +146,24 @@ def check_run_termination
146146
end
147147

148148
def init_workspace
149+
@restored = @options.test.session
149150
unless @options.common.workspace_path.nil?
150151
@workspace_path = @options.common.workspace_path
151152
return
152153
end
153154

155+
if @restored
156+
restore_session
157+
else
158+
create_workspace
159+
save_session
160+
add_latest_symlink
161+
end
162+
163+
@setup_manager_type&.enter @workspace_path
164+
end
165+
166+
def create_workspace
154167
@workspace_path = File.join(@config['workspace_path'],
155168
@engine_name,
156169
@engine_tag,
@@ -161,15 +174,28 @@ def init_workspace
161174
@logger.warn('Workspace path already exists')
162175
end
163176
@logger.info("Workspace path: #{@workspace_path}")
177+
end
178+
179+
def restore_session
180+
@workspace_path = @options.test.session
164181

182+
raise AutoHCKError, 'Workspace path does not exist could not load session' unless File.directory?(@workspace_path)
183+
184+
@logger.info("Loading session from #{@workspace_path}")
185+
end
186+
187+
def save_session
188+
Session.save(@workspace_path, @options)
189+
end
190+
191+
def add_latest_symlink
165192
begin
166193
File.delete("#{@config['workspace_path']}/latest")
167194
rescue Errno::ENOENT
168195
# firts run, no symlink to delete
169196
end
170197

171198
File.symlink(@workspace_path, "#{@config['workspace_path']}/latest")
172-
@setup_manager_type&.enter @workspace_path
173199
end
174200

175201
def handle_cancel

lib/session.rb

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# frozen_string_literal: true
2+
3+
# rubocop:disable Metrics/AbcSize,Lint/MissingCopEnableDirective
4+
5+
module AutoHCK
6+
class Session
7+
extend T::Sig
8+
include Helper
9+
10+
def self.save(workspace_path, options)
11+
File.write("#{workspace_path}/session.json", compose_session_json(options, workspace_path))
12+
end
13+
14+
def self.load(cli)
15+
session = Models::Session.from_json_file("#{session_path(cli)}/session.json")
16+
17+
session.common.workspace_path = cli.common.workspace_path
18+
session.test.latest_session = cli.test.latest_session
19+
session.test.session = cli.test.session
20+
21+
cli.test = session.test
22+
cli.common = session.common
23+
24+
cli.test.manual = true
25+
end
26+
27+
def self.session_path(cli)
28+
cli.test.latest_session ? "#{Config.read['workspace_path']}/latest" : cli.test.session
29+
end
30+
31+
private_class_method def self.compose_session_json(options, workspace_path)
32+
session = AutoHCK::Models::Session.new(
33+
test: options.test,
34+
common: options.common
35+
)
36+
session.common.workspace_path = workspace_path
37+
session.serialize.to_json
38+
end
39+
end
40+
end

lib/setupmanagers/hckclient.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,8 @@ def prepare_machine
150150
def configure(run_only: false)
151151
@tools = @studio.tools
152152
@cooldown_thread = Thread.new do
153-
unless pool == @project.engine_tag
154-
return_when_client_up
153+
if @project.restored || pool != @project.engine_tag
154+
return_when_client_up unless @project.restored
155155
if run_only
156156
@logger.info("Preparing client skipped #{@name}...")
157157

lib/setupmanagers/hckstudio.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ def configure(clients)
8080
connect
8181
verify_tools
8282
update_filters
83+
return if @project.restored
84+
8385
create_pool
8486
create_project
8587
end

lib/setupmanagers/qemuhck/qemu_machine.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,8 @@ def close
154154
boot_from_snapshot: false,
155155
attach_iso_list: [],
156156
dump_only: false,
157-
secure: false
157+
secure: false,
158+
restored: false
158159
}.freeze
159160

160161
MACHINE_JSON = 'lib/setupmanagers/qemuhck/machine.json'
@@ -689,7 +690,7 @@ def run(scope, run_opts = nil)
689690
dump_commands
690691
else
691692
unless @configured
692-
run_config_commands
693+
run_config_commands unless @run_opts[:restored]
693694
@configured = true
694695
end
695696

0 commit comments

Comments
 (0)