3 import unittest
, os
, time
, re
, glob
, logging
5 from autotest_lib
.client
.common_lib
.test_utils
import mock
6 from autotest_lib
.client
.bin
import kernel
, job
, utils
, kernelexpand
7 from autotest_lib
.client
.bin
import kernel_config
, boottool
, os_dep
10 class TestAddKernelToBootLoader(unittest
.TestCase
):
12 def add_to_bootloader(self
, base_args
, args
, bootloader_args
,
13 bootloader_root
, tag
='image', image
='image',
16 bootloader
= god
.create_mock_class(boottool
.boottool
, "boottool")
19 bootloader
.remove_kernel
.expect_call(tag
)
20 bootloader
.add_kernel
.expect_call(image
, tag
, initrd
=initrd
,
21 args
='_dummy_', root
=bootloader_root
)
23 for a
in bootloader_args
.split():
24 bootloader
.add_args
.expect_call(kernel
=tag
, args
=a
)
25 bootloader
.remove_args
.expect_call(kernel
=tag
, args
='_dummy_')
28 kernel
._add
_kernel
_to
_bootloader
(bootloader
, base_args
, tag
, args
,
33 def test_add_kernel_to_bootloader(self
):
34 self
.add_to_bootloader(base_args
='baseargs', args
='',
35 bootloader_args
='baseargs', bootloader_root
=None)
36 self
.add_to_bootloader(base_args
='arg1 root=/dev/oldroot arg2',
37 args
='root=/dev/newroot arg3',
38 bootloader_args
='arg1 arg2 arg3',
39 bootloader_root
='/dev/newroot')
42 class TestBootableKernel(unittest
.TestCase
):
45 self
.god
= mock
.mock_god()
46 self
.god
.stub_function(time
, "time")
47 self
.god
.stub_function(utils
, "system")
48 self
.god
.stub_function(kernel
, "_add_kernel_to_bootloader")
49 job_
= self
.god
.create_mock_class(job
.job
, "job")
50 self
.kernel
= kernel
.BootableKernel(job_
)
51 self
.kernel
.job
.bootloader
= self
.god
.create_mock_class(
52 boottool
.boottool
, "boottool")
56 # note: time.time() can only be unstubbed via tearDown()
60 def boot_kernel(self
, ident_check
):
61 notes
= "applied_patches"
64 base_args
= 'base_args'
67 self
.kernel
.image
= 'image'
68 self
.kernel
.initrd
= 'initrd'
69 self
.kernel
.installed_as
= tag
74 time
.time
.expect_call().and_return(when
)
75 args_
+= " IDENT=%d" % when
76 status
= ["job.end_reboot_and_verify", when
, tag
, subdir
, notes
]
78 status
= ["job.end_reboot", subdir
, tag
, notes
]
79 self
.kernel
.job
.next_step_prepend
.expect_call(status
)
80 self
.kernel
.job
.config_get
.expect_call(
81 'boot.default_args').and_return(base_args
)
82 kernel
._add
_kernel
_to
_bootloader
.expect_call(
83 self
.kernel
.job
.bootloader
, base_args
, tag
,
84 args_
, self
.kernel
.image
, self
.kernel
.initrd
)
85 utils
.system
.expect_call('touch /fastboot')
86 self
.kernel
.job
.start_reboot
.expect_call()
87 self
.kernel
.job
.reboot
.expect_call(tag
=tag
)
90 self
.kernel
._boot
_kernel
(args
=args
, ident_check
=ident_check
,
91 expected_ident
=tag
, subdir
=subdir
, notes
=notes
)
92 self
.god
.check_playback()
95 def test_boot_kernel(self
):
96 self
.boot_kernel(ident_check
=False)
97 self
.boot_kernel(ident_check
=True)
100 class TestKernel(unittest
.TestCase
):
102 self
.god
= mock
.mock_god()
104 logging
.disable(logging
.CRITICAL
)
106 self
.god
.stub_function(time
, "time")
107 self
.god
.stub_function(os
, "mkdir")
108 self
.god
.stub_function(os
, "chdir")
109 self
.god
.stub_function(os
, "symlink")
110 self
.god
.stub_function(os
, "remove")
111 self
.god
.stub_function(os
.path
, "isdir")
112 self
.god
.stub_function(os
.path
, "exists")
113 self
.god
.stub_function(os
.path
, "isfile")
114 self
.god
.stub_function(os_dep
, "commands")
115 self
.god
.stub_function(kernel
, "open")
116 self
.god
.stub_function(utils
, "system")
117 self
.god
.stub_function(utils
, "system_output")
118 self
.god
.stub_function(utils
, "get_file")
119 self
.god
.stub_function(utils
, "get_current_kernel_arch")
120 self
.god
.stub_function(utils
, "cat_file_to_cmd")
121 self
.god
.stub_function(utils
, "force_copy")
122 self
.god
.stub_function(utils
, "extract_tarball_to_dir")
123 self
.god
.stub_function(utils
, "count_cpus")
124 self
.god
.stub_function(utils
, "get_os_vendor")
125 self
.god
.stub_function(kernelexpand
, "expand_classic")
126 self
.god
.stub_function(kernel_config
, "modules_needed")
127 self
.god
.stub_function(glob
, "glob")
128 def dummy_mark(filename
, msg
):
130 self
.god
.stub_with(kernel
, '_mark', dummy_mark
)
132 self
.job
= self
.god
.create_mock_class(job
.job
, "job")
133 self
.job
.bootloader
= self
.god
.create_mock_class(boottool
.boottool
,
136 class DummyLoggingManager(object):
137 def tee_redirect_debug_dir(self
, *args
, **kwargs
):
141 def restore(self
, *args
, **kwargs
):
144 self
.job
.logging
= DummyLoggingManager()
146 self
.job
.autodir
= "autodir"
147 self
.base_tree
= "2.6.24"
148 self
.tmp_dir
= "tmpdir"
149 self
.subdir
= "subdir"
153 self
.god
.unstub_all()
156 def construct_kernel(self
):
157 self
.kernel
= kernel
.kernel
.__new
__(kernel
.kernel
)
158 self
.god
.stub_function(self
.kernel
, "extract")
161 self
.src_dir
= os
.path
.join(self
.tmp_dir
, 'src')
162 self
.build_dir
= os
.path
.join(self
.tmp_dir
, "build_dir")
163 self
.config_dir
= os
.path
.join(self
.subdir
, 'config')
164 self
.log_dir
= os
.path
.join(self
.subdir
, 'debug')
165 self
.results_dir
= os
.path
.join(self
.subdir
, 'results')
168 os
.path
.isdir
.expect_call(self
.src_dir
).and_return(True)
169 utils
.system
.expect_call('rm -rf ' + self
.src_dir
)
170 os
.path
.isdir
.expect_call(self
.build_dir
).and_return(True)
171 utils
.system
.expect_call('rm -rf ' + self
.build_dir
)
172 os
.path
.exists
.expect_call(self
.src_dir
).and_return(False)
173 os
.mkdir
.expect_call(self
.src_dir
)
174 for path
in [self
.config_dir
, self
.log_dir
, self
.results_dir
]:
175 os
.path
.exists
.expect_call(path
).and_return(True)
176 utils
.system
.expect_call('rm -rf ' + path
)
177 os
.mkdir
.expect_call(path
)
179 logpath
= os
.path
.join(self
.log_dir
, 'build_log')
180 self
.logfile
= self
.god
.create_mock_class(file, "file")
181 kernel
.open.expect_call(logpath
, 'w+').and_return(self
.logfile
)
182 utils
.get_current_kernel_arch
.expect_call().and_return('ia64')
183 self
.logfile
.write
.expect_call('BASE: %s\n' % self
.base_tree
)
184 self
.kernel
.extract
.expect_call(self
.base_tree
)
186 # finish creation of kernel object and test (and unstub extract)
187 self
.kernel
.__init
__(self
.job
, self
.base_tree
, self
.subdir
,
188 self
.tmp_dir
, "build_dir")
189 self
.god
.check_playback()
190 self
.god
.unstub(self
.kernel
, "extract")
193 def test_constructor(self
):
194 self
.construct_kernel()
197 def test_kernelexpand1(self
):
198 self
.construct_kernel()
200 ret_val
= self
.kernel
.kernelexpand("/path/to/kernel")
201 self
.assertEquals(ret_val
, ["/path/to/kernel"])
202 self
.god
.check_playback()
205 def test_kernel_expand2(self
):
206 self
.construct_kernel()
207 kernel
= "kernel.tar.gz"
210 self
.job
.config_get
.expect_call('mirror.mirrors').and_return('mirror')
211 kernelexpand
.expand_classic
.expect_call(kernel
,
212 'mirror').and_return('patches')
215 self
.assertEquals(self
.kernel
.kernelexpand(kernel
), 'patches')
216 self
.god
.check_playback()
219 def test_kernel_expand3(self
):
220 self
.construct_kernel()
221 kernel
= "kernel.tar.gz"
224 self
.job
.config_get
.expect_call('mirror.mirrors')
225 self
.job
.config_get
.expect_call(
226 'mirror.ftp_kernel_org').and_return('mirror')
227 korg
= 'http://www.kernel.org/pub/linux/kernel'
229 [ korg
+ '/v2.6', 'mirror' + '/v2.6' ],
230 [ korg
+ '/people/akpm/patches/2.6', 'mirror' + '/akpm' ],
231 [ korg
+ '/people/mbligh', 'mirror' + '/mbligh' ],
233 kernelexpand
.expand_classic
.expect_call(kernel
,
234 mirrors
).and_return('patches')
237 self
.assertEquals(self
.kernel
.kernelexpand(kernel
), 'patches')
238 self
.god
.check_playback()
241 def test_extract1(self
):
242 self
.construct_kernel()
245 self
.god
.stub_function(self
.kernel
, "get_kernel_tree")
248 os
.path
.exists
.expect_call(self
.base_tree
).and_return(True)
249 self
.kernel
.get_kernel_tree
.expect_call(self
.base_tree
)
250 self
.job
.record
.expect_call('GOOD', self
.subdir
, 'kernel.extract')
253 self
.kernel
.extract(self
.base_tree
)
254 self
.god
.check_playback()
255 self
.god
.unstub(self
.kernel
, "get_kernel_tree")
258 def test_extract2(self
):
259 self
.construct_kernel()
262 self
.god
.stub_function(self
.kernel
, "kernelexpand")
263 self
.god
.stub_function(self
.kernel
, "get_kernel_tree")
264 self
.god
.stub_function(self
.kernel
, "patch")
267 os
.path
.exists
.expect_call(self
.base_tree
).and_return(False)
268 components
= ["component0", "component1"]
269 self
.kernel
.kernelexpand
.expect_call(self
.base_tree
).and_return(
271 self
.kernel
.get_kernel_tree
.expect_call(components
[0])
272 self
.kernel
.patch
.expect_call(components
[1])
273 self
.job
.record
.expect_call('GOOD', self
.subdir
, 'kernel.extract')
276 self
.kernel
.extract(self
.base_tree
)
277 self
.god
.check_playback()
278 self
.god
.unstub(self
.kernel
, "kernelexpand")
279 self
.god
.unstub(self
.kernel
, "get_kernel_tree")
280 self
.god
.unstub(self
.kernel
, "patch")
283 def test_patch1(self
):
284 self
.construct_kernel()
285 patches
= ('patch1', 'patch2')
286 self
.god
.stub_function(self
.kernel
, "apply_patches")
287 self
.god
.stub_function(self
.kernel
, "get_patches")
290 self
.kernel
.get_patches
.expect_call(patches
).and_return(patches
)
291 self
.kernel
.apply_patches
.expect_call(patches
)
292 self
.job
.record
.expect_call('GOOD', self
.subdir
, 'kernel.patch')
295 self
.kernel
.patch(*patches
)
296 self
.god
.check_playback()
297 self
.god
.unstub(self
.kernel
, "apply_patches")
298 self
.god
.unstub(self
.kernel
, "get_patches")
301 def test_patch2(self
):
302 self
.construct_kernel()
306 self
.job
.record
.expect_call('GOOD', self
.subdir
, 'kernel.patch')
309 self
.kernel
.patch(*patches
)
310 self
.god
.check_playback()
313 def test_config(self
):
314 self
.construct_kernel()
317 self
.god
.stub_function(self
.kernel
, "set_cross_cc")
318 self
.god
.stub_class(kernel_config
, "kernel_config")
321 self
.kernel
.set_cross_cc
.expect_call()
322 kernel_config
.kernel_config
.expect_new(self
.job
, self
.build_dir
,
323 self
.config_dir
, '', None,
324 False, self
.base_tree
, None)
325 self
.job
.record
.expect_call('GOOD', self
.subdir
, 'kernel.config')
329 self
.god
.check_playback()
330 self
.god
.unstub(self
.kernel
, "set_cross_cc")
333 def test_get_patches(self
):
334 self
.construct_kernel()
337 patches
= ['patch1', 'patch2', 'patch3']
341 for patch
in patches
:
342 dest
= os
.path
.join(self
.src_dir
, os
.path
.basename(patch
))
343 utils
.get_file
.expect_call(patch
, dest
)
344 utils
.system_output
.expect_call(
345 'md5sum ' + dest
).and_return('md5sum')
346 local_patches
.append((patch
, dest
, 'md5sum'))
349 self
.assertEquals(self
.kernel
.get_patches(patches
), local_patches
)
350 self
.god
.check_playback()
353 def test_apply_patches(self
):
354 self
.construct_kernel()
358 patches
.append(('patch1', 'patch1.gz', 'md5sum1'))
359 patches
.append(('patch2', 'patch2.bz2', 'md5sum2'))
360 patches
.append(('patch3', 'patch3', 'md5sum3'))
364 os
.chdir
.expect_call(self
.build_dir
)
366 patch_id
= "%s %s %s" % ('patch1', 'patch1', 'md5sum1')
367 log
= "PATCH: " + patch_id
+ "\n"
368 utils
.cat_file_to_cmd
.expect_call('patch1.gz',
369 'patch -p1 > /dev/null')
370 self
.logfile
.write
.expect_call(log
)
371 applied_patches
.append(patch_id
)
373 patch_id
= "%s %s %s" % ('patch2', 'patch2', 'md5sum2')
374 log
= "PATCH: " + patch_id
+ "\n"
375 utils
.cat_file_to_cmd
.expect_call('patch2.bz2',
376 'patch -p1 > /dev/null')
377 self
.logfile
.write
.expect_call(log
)
378 applied_patches
.append(patch_id
)
380 utils
.force_copy
.expect_call('patch3',
381 self
.results_dir
).and_return('local_patch3')
382 self
.job
.relative_path
.expect_call('local_patch3').and_return(
384 patch_id
= "%s %s %s" % ('patch3', 'rel_local_patch3', 'md5sum3')
385 log
= "PATCH: " + patch_id
+ "\n"
386 utils
.cat_file_to_cmd
.expect_call('patch3',
387 'patch -p1 > /dev/null')
388 self
.logfile
.write
.expect_call(log
)
389 applied_patches
.append(patch_id
)
392 self
.kernel
.apply_patches(patches
)
393 self
.assertEquals(self
.kernel
.applied_patches
, applied_patches
)
394 self
.god
.check_playback()
397 def test_get_kernel_tree1(self
):
398 self
.construct_kernel()
401 os
.path
.isdir
.expect_call(self
.base_tree
).and_return(True)
402 os
.symlink
.expect_call(self
.base_tree
, self
.build_dir
)
405 self
.kernel
.get_kernel_tree(self
.base_tree
)
406 self
.god
.check_playback()
409 def test_get_kernel_tree2(self
):
410 self
.construct_kernel()
413 os
.path
.isdir
.expect_call(self
.base_tree
).and_return(False)
414 os
.chdir
.expect_call(os
.path
.dirname(self
.src_dir
))
415 tarball
= os
.path
.join(self
.src_dir
, os
.path
.basename(self
.base_tree
))
416 utils
.get_file
.expect_call(self
.base_tree
, tarball
)
417 utils
.extract_tarball_to_dir
.expect_call(tarball
,
421 self
.kernel
.get_kernel_tree(self
.base_tree
)
422 self
.god
.check_playback()
425 def test_extraversion(self
):
426 self
.construct_kernel()
429 self
.god
.stub_function(self
.kernel
, "config")
432 os
.chdir
.expect_call(self
.build_dir
)
433 extraversion_sub
= r
's/^CONFIG_LOCALVERSION=\s*"\(.*\)"/CONFIG_LOCALVERSION='
434 cfg
= self
.build_dir
+ '/.config'
435 p
= extraversion_sub
+ '"\\1-%s"/' % tag
436 utils
.system
.expect_call('mv %s %s.old' % (cfg
, cfg
))
437 utils
.system
.expect_call("sed '%s' < %s.old > %s" % (p
, cfg
, cfg
))
438 self
.kernel
.config
.expect_call(make
='oldconfig')
441 self
.kernel
.extraversion(tag
)
442 self
.god
.check_playback()
445 def test_build(self
):
446 self
.construct_kernel()
447 self
.god
.stub_function(self
.kernel
, "extraversion")
448 self
.god
.stub_function(self
.kernel
, "set_cross_cc")
449 self
.god
.stub_function(self
.kernel
, "get_kernel_build_ver")
450 self
.kernel
.build_target
= 'build_target'
453 os_dep
.commands
.expect_call('gcc', 'make')
454 logfile
= os
.path
.join(self
.log_dir
, 'kernel_build')
455 os
.chdir
.expect_call(self
.build_dir
)
456 self
.kernel
.extraversion
.expect_call('autotest')
457 self
.kernel
.set_cross_cc
.expect_call()
458 utils
.system
.expect_call('make dep', ignore_status
=True)
459 utils
.count_cpus
.expect_call().and_return(4)
461 build_string
= 'make -j %d %s %s' % (threads
, '', 'build_target')
462 utils
.system
.expect_call(build_string
)
463 kernel_config
.modules_needed
.expect_call('.config').and_return(True)
464 utils
.system
.expect_call('make -j %d modules' % (threads
))
465 self
.kernel
.get_kernel_build_ver
.expect_call().and_return('2.6.24')
466 kernel_version
= re
.sub('-autotest', '', '2.6.24')
467 self
.logfile
.write
.expect_call('BUILD VERSION: %s\n' % kernel_version
)
468 utils
.force_copy
.expect_call(self
.build_dir
+'/System.map',
470 self
.job
.record
.expect_call('GOOD', self
.subdir
, 'kernel.build')
474 self
.god
.check_playback()
477 def test_build_timed(self
):
478 self
.construct_kernel()
479 self
.god
.stub_function(self
.kernel
, "set_cross_cc")
480 self
.god
.stub_function(self
.kernel
, "clean")
483 os
.chdir
.expect_call(self
.build_dir
)
484 self
.kernel
.set_cross_cc
.expect_call()
485 self
.kernel
.clean
.expect_call()
486 build_string
= "/usr/bin/time -o /dev/null make -j 8 vmlinux"
487 build_string
+= ' > /dev/null 2>&1'
488 utils
.system
.expect_call(build_string
)
489 os
.path
.isfile
.expect_call('vmlinux').and_return(True)
492 self
.kernel
.build_timed(threads
=8)
493 self
.god
.check_playback()
496 def test_clean(self
):
497 self
.construct_kernel()
500 os
.chdir
.expect_call(self
.build_dir
)
501 utils
.system
.expect_call('make clean > /dev/null 2> /dev/null')
502 self
.job
.record
.expect_call('GOOD', self
.subdir
, 'kernel.clean')
506 self
.god
.check_playback()
509 def test_mkinitrd(self
):
510 self
.construct_kernel()
513 utils
.get_os_vendor
.expect_call().and_return('Ubuntu')
514 os
.path
.isfile
.expect_call('initrd').and_return(True)
515 os
.remove
.expect_call('initrd')
516 self
.job
.config_get
.expect_call(
517 'kernel.mkinitrd_extra_args').and_return(None)
519 glob
.glob
.expect_call('/lib/modules/2.6.24*').and_return(['2.6.24'])
520 os
.path
.isfile
.expect_call('/usr/sbin/mkinitrd').and_return(True)
521 cmd
= '/usr/sbin/mkinitrd'
522 utils
.system
.expect_call('%s %s -o initrd 2.6.24' % (cmd
, args
))
523 self
.job
.record
.expect_call('GOOD', self
.subdir
, 'kernel.mkinitrd')
526 self
.kernel
.mkinitrd(version
="2.6.24", image
="image",
527 system_map
="system_map", initrd
="initrd")
528 self
.god
.check_playback()
531 def test_install(self
):
532 self
.construct_kernel()
535 self
.kernel
.build_image
= None
536 self
.kernel
.build_target
= 'build_target'
537 self
.god
.stub_function(self
.kernel
, "get_kernel_build_ver")
538 self
.god
.stub_function(self
.kernel
, "mkinitrd")
541 os
.chdir
.expect_call(self
.build_dir
)
542 os
.path
.isdir
.expect_call(prefix
).and_return(False)
543 os
.mkdir
.expect_call(prefix
)
544 boot_dir
= os
.path
.join(prefix
, 'boot')
545 os
.path
.isdir
.expect_call(boot_dir
).and_return(False)
546 os
.mkdir
.expect_call(boot_dir
)
547 glob
.glob
.expect_call(
548 'arch/*/boot/' + 'build_target').and_return('')
549 build_image
= self
.kernel
.build_target
550 utils
.force_copy
.expect_call('vmlinux',
551 '/boot/vmlinux-autotest')
552 utils
.force_copy
.expect_call('build_target',
553 '/boot/vmlinuz-autotest')
554 utils
.force_copy
.expect_call('System.map',
555 '/boot/System.map-autotest')
556 utils
.force_copy
.expect_call('.config',
557 '/boot/config-autotest')
558 kernel_config
.modules_needed
.expect_call('.config').and_return(True)
559 utils
.system
.expect_call('make modules_install INSTALL_MOD_PATH=%s'
561 initrd
= boot_dir
+ '/initrd-' + tag
562 self
.kernel
.get_kernel_build_ver
.expect_call().and_return('2.6.24')
563 self
.kernel
.mkinitrd
.expect_call('2.6.24', '/boot/vmlinuz-autotest',
564 '/boot/System.map-autotest', '/boot/initrd-autotest')
565 self
.job
.record
.expect_call('GOOD', self
.subdir
, 'kernel.install')
568 self
.kernel
.install()
569 self
.god
.check_playback()
572 def test_get_kernel_build_arch1(self
):
573 self
.construct_kernel()
576 utils
.get_current_kernel_arch
.expect_call().and_return("i386")
579 self
.assertEquals(self
.kernel
.get_kernel_build_arch(), "i386")
580 self
.god
.check_playback()
583 def test_get_kernel_build_arch2(self
):
584 self
.construct_kernel()
587 self
.assertEquals(self
.kernel
.get_kernel_build_arch('i586'), "i386")
588 self
.god
.check_playback()
591 def test_get_kernel_build_release(self
):
592 self
.construct_kernel()
593 mock_file
= self
.god
.create_mock_class(file, "file")
596 for f
in [self
.build_dir
+ "/include/linux/version.h",
597 self
.build_dir
+ "/include/linux/utsrelease.h"]:
598 os
.path
.exists
.expect_call(f
).and_return(True)
599 kernel
.open.expect_call(f
, 'r').and_return(mock_file
)
600 mock_file
.readlines
.expect_call().and_return("Some lines")
601 mock_file
.close
.expect_call()
603 for f
in [self
.build_dir
+ "/include/linux/compile.h",
604 self
.build_dir
+ "/include/generated/utsrelease.h",
605 self
.build_dir
+ "/include/generated/compile.h"]:
606 os
.path
.exists
.expect_call(f
).and_return(False)
609 self
.kernel
.get_kernel_build_release()
610 self
.god
.check_playback()
613 def test_get_kernel_build_ident(self
):
614 self
.construct_kernel()
615 self
.god
.stub_function(self
.kernel
, "get_kernel_build_release")
618 self
.kernel
.get_kernel_build_release
.expect_call().and_return(
619 ("AwesomeRelease", "1.0"))
622 self
.assertEquals(self
.kernel
.get_kernel_build_ident(),
623 "AwesomeRelease::1.0")
624 self
.god
.check_playback()
628 self
.construct_kernel()
629 self
.god
.stub_function(self
.kernel
, "get_kernel_build_ident")
630 self
.god
.stub_function(self
.kernel
, "install")
631 self
.god
.stub_function(self
.kernel
, "_boot_kernel")
632 self
.kernel
.applied_patches
= "applied_patches"
633 self
.kernel
.installed_as
= None
635 expected_ident
= 'ident'
639 self
.kernel
.install
.expect_call()
640 self
.kernel
.get_kernel_build_ident
.expect_call(
641 ).and_return(expected_ident
)
642 self
.kernel
._boot
_kernel
.expect_call(
643 args
, ident
, expected_ident
,
644 self
.subdir
, self
.kernel
.applied_patches
)
647 self
.kernel
.boot(args
=args
, ident
=ident
)
648 self
.god
.check_playback()
651 if __name__
== "__main__":