| Total Complexity | 21 | 
| Total Lines | 113 | 
| Duplicated Lines | 13.27 % | 
Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
| 1 | from nose.tools import assert_true, assert_false, assert_equal, assert_raises  | 
            ||
| 12 | class TestJobGenerator(object):  | 
            ||
| 13 | pbs_flags = ['-lfeature=k80', '-lwalltime=42:42', '-lnodes=6:gpus=66', '-m', '-A123-asd-11', '-t10,20,30']  | 
            ||
| 14 | |||
| 15 | def setUp(self):  | 
            ||
| 16 | self.testing_dir = tempfile.mkdtemp()  | 
            ||
| 17 | self.cluster_name = "skynet"  | 
            ||
| 18 | self.name = "9000@hal"  | 
            ||
| 19 | self.walltime = "10:00"  | 
            ||
| 20 | self.cores = 42  | 
            ||
| 21 | self.gpus = 42  | 
            ||
| 22 | self.mem_per_node = 32  | 
            ||
| 23 | self.modules = ["cuda", "python"]  | 
            ||
| 24 | |||
| 25 | self.queue = Queue(self.name, self.cluster_name, self.walltime, self.cores, 0, self.mem_per_node, self.modules)  | 
            ||
| 26 | self.queue_gpu = Queue(self.name, self.cluster_name, self.walltime, self.cores, self.gpus, self.mem_per_node, self.modules)  | 
            ||
| 27 | |||
| 28 | self.commands = ["echo 1", "echo 2", "echo 3", "echo 4"]  | 
            ||
| 29 | |||
| 30 | def tearDown(self):  | 
            ||
| 31 | shutil.rmtree(self.testing_dir)  | 
            ||
| 32 | |||
| 33 | def test_generate_pbs(self):  | 
            ||
| 34 | job_generator = JobGenerator(self.queue, self.commands)  | 
            ||
| 35 | |||
| 36 | # Test nb_cores_per_command argument  | 
            ||
| 37 | # Should needs one PBS file  | 
            ||
| 38 | assert_equal(len(job_generator.pbs_list), 1)  | 
            ||
| 39 | assert_equal(job_generator.pbs_list[0].commands, self.commands)  | 
            ||
| 40 | |||
| 41 | View Code Duplication | def test_generate_pbs2_cpu(self):  | 
            |
| 
                                                                                                    
                        
                         | 
                |||
| 42 | # Should needs two PBS file  | 
            ||
| 43 |         command_params = {'nb_cores_per_command': self.cores // 2} | 
            ||
| 44 | job_generator = JobGenerator(self.queue, self.commands, command_params)  | 
            ||
| 45 | assert_equal(len(job_generator.pbs_list), 2)  | 
            ||
| 46 | assert_equal(job_generator.pbs_list[0].commands, self.commands[:2])  | 
            ||
| 47 | assert_equal(job_generator.pbs_list[1].commands, self.commands[2:])  | 
            ||
| 48 | |||
| 49 | def test_generate_pbs4_cpu(self):  | 
            ||
| 50 | # Should needs four PBS file  | 
            ||
| 51 |         command_params = {'nb_cores_per_command': self.cores} | 
            ||
| 52 | job_generator = JobGenerator(self.queue, self.commands, command_params)  | 
            ||
| 53 | assert_equal(len(job_generator.pbs_list), 4)  | 
            ||
| 54 | assert_equal([pbs.commands[0] for pbs in job_generator.pbs_list], self.commands)  | 
            ||
| 55 | |||
| 56 | # Since queue has no gpus it should not be specified in PBS resource `nodes`  | 
            ||
| 57 |         assert_true('gpus' not in job_generator.pbs_list[0].resources['nodes']) | 
            ||
| 58 | |||
| 59 | # Test modules to load  | 
            ||
| 60 | # Check if needed modules for this queue are included in the PBS file  | 
            ||
| 61 | assert_equal(job_generator.pbs_list[0].modules, self.modules)  | 
            ||
| 62 | |||
| 63 | View Code Duplication | def test_generate_pbs2_gpu(self):  | 
            |
| 64 | # Test nb_gpus_per_command argument  | 
            ||
| 65 | # Should needs two PBS file  | 
            ||
| 66 |         command_params = {'nb_gpus_per_command': self.gpus // 2} | 
            ||
| 67 | job_generator = JobGenerator(self.queue_gpu, self.commands, command_params)  | 
            ||
| 68 | assert_equal(len(job_generator.pbs_list), 2)  | 
            ||
| 69 | assert_equal(job_generator.pbs_list[0].commands, self.commands[:2])  | 
            ||
| 70 | assert_equal(job_generator.pbs_list[1].commands, self.commands[2:])  | 
            ||
| 71 | |||
| 72 | def test_generate_pbs4_gpu(self):  | 
            ||
| 73 | # Should needs four PBS files  | 
            ||
| 74 |         command_params = {'nb_gpus_per_command': self.gpus} | 
            ||
| 75 | job_generator = JobGenerator(self.queue_gpu, self.commands, command_params)  | 
            ||
| 76 | assert_equal(len(job_generator.pbs_list), 4)  | 
            ||
| 77 | assert_equal([pbs.commands[0] for pbs in job_generator.pbs_list], self.commands)  | 
            ||
| 78 | |||
| 79 | # Since queue has gpus it should be specified in PBS resource `nodes`  | 
            ||
| 80 |         assert_true('gpus' in job_generator.pbs_list[0].resources['nodes']) | 
            ||
| 81 | |||
| 82 | # Test modules to load  | 
            ||
| 83 | # Check if needed modules for this queue are included in the PBS file  | 
            ||
| 84 | assert_equal(job_generator.pbs_list[0].modules, self.modules)  | 
            ||
| 85 | |||
| 86 | def test_write_pbs_files(self):  | 
            ||
| 87 | commands = ["echo 1", "echo 2", "echo 3", "echo 4"]  | 
            ||
| 88 |         command_params = {'nb_cores_per_command': self.cores} | 
            ||
| 89 | job_generator = JobGenerator(self.queue, commands, command_params)  | 
            ||
| 90 | filenames = job_generator.write_pbs_files(self.testing_dir)  | 
            ||
| 91 | assert_equal(len(filenames), 4)  | 
            ||
| 92 | |||
| 93 | def _test_add_pbs_flags(self, flags):  | 
            ||
| 94 | job_generator = JobGenerator(self.queue, self.commands)  | 
            ||
| 95 | job_generator.add_pbs_flags(flags)  | 
            ||
| 96 | |||
| 97 | resources = []  | 
            ||
| 98 | options = []  | 
            ||
| 99 | |||
| 100 | for flag in flags:  | 
            ||
| 101 |             if flag.startswith('-l'): | 
            ||
| 102 | resources += [flag[:2] + ' ' + flag[2:]]  | 
            ||
| 103 |             elif flag.startswith('-'): | 
            ||
| 104 | options += [(flag[:2] + ' ' + flag[2:]).strip()]  | 
            ||
| 105 | |||
| 106 | for pbs in job_generator.pbs_list:  | 
            ||
| 107 | pbs_str = pbs.__str__()  | 
            ||
| 108 | for flag in resources:  | 
            ||
| 109 | assert_equal(pbs_str.count(flag), 1)  | 
            ||
| 110 |                 assert_equal(pbs_str.count(flag[:flag.find('=')]), 1) | 
            ||
| 111 | for flag in options:  | 
            ||
| 112 | assert_equal(pbs_str.count(flag), 1)  | 
            ||
| 113 | |||
| 114 | def test_add_pbs_flags(self):  | 
            ||
| 115 | for flag in self.pbs_flags:  | 
            ||
| 116 | yield self._test_add_pbs_flags, [flag]  | 
            ||
| 117 | |||
| 118 | yield self._test_add_pbs_flags, self.pbs_flags  | 
            ||
| 119 | |||
| 120 | def test_add_pbs_flags_invalid(self):  | 
            ||
| 121 | assert_raises(ValueError, self._test_add_pbs_flags, 'weeee')  | 
            ||
| 122 | |||
| 123 | def test_add_pbs_flags_invalid_resource(self):  | 
            ||
| 124 | assert_raises(ValueError, self._test_add_pbs_flags, '-l weeee')  | 
            ||
| 125 | |||
| 275 |