File indexing completed on 2026-04-25 08:29:11
0001 """Tests for PCS command/task-param generation.
0002
0003 Uses lightweight fakes rather than Django fixtures — the builders are pure
0004 mapping functions, so we do not need the ORM.
0005 """
0006 from types import SimpleNamespace
0007 from unittest import TestCase
0008
0009 from pcs.commands import build_task_params
0010
0011
0012 def _make_task():
0013 """Build a SimpleNamespace task matching the example in docs/JEDI_INTEGRATION.md."""
0014 physics_tag = SimpleNamespace(
0015 tag_label='p3001',
0016 parameters={'beam_energy_electron': 10, 'beam_energy_hadron': 100},
0017 )
0018 evgen_tag = SimpleNamespace(tag_label='e1', parameters={})
0019 simu_tag = SimpleNamespace(tag_label='s1', parameters={})
0020 reco_tag = SimpleNamespace(tag_label='r1', parameters={})
0021
0022 task_name = 'group.EIC.26.02.0.epic_craterlake.p3001.e1.s1.r1'
0023 dataset = SimpleNamespace(
0024 scope='group.EIC',
0025 detector_version='26.02.0',
0026 detector_config='epic_craterlake',
0027 physics_tag=physics_tag,
0028 evgen_tag=evgen_tag,
0029 simu_tag=simu_tag,
0030 reco_tag=reco_tag,
0031 block_num=1,
0032 did=f'group.EIC:{task_name}.b1',
0033 task_name=task_name,
0034 )
0035
0036 cfg = {
0037 'panda_site': 'BNL_EPIC_PROD_1',
0038 'panda_working_group': 'EIC',
0039 'container_image': 'docker://eicweb/jug_xl:26.02.0-stable',
0040 'jug_xl_tag': '26.02.0-stable',
0041 'target_hours_per_job': 2,
0042 'events_per_task': 1000,
0043 'use_rucio': True,
0044 'copy_reco': True,
0045 'copy_full': False,
0046 'copy_log': True,
0047 'bg_mixing': False,
0048 'data': {
0049 'prod_source_label': 'managed',
0050 'processing_type': 'epicproduction',
0051 'n_jobs': 10,
0052 'events_per_job': 100,
0053 'corecount': 1,
0054 'ram_count': 4000,
0055 'transformation': 'https://pandaserver-doma.cern.ch/trf/user/runGen-00-00-02',
0056 },
0057 }
0058
0059 return SimpleNamespace(
0060 dataset=dataset,
0061 created_by='wenaus',
0062 get_effective_config=lambda: cfg,
0063 )
0064
0065
0066 class BuildTaskParamsTest(TestCase):
0067 def test_matches_design_example(self):
0068 params = build_task_params(_make_task())
0069
0070
0071 self.assertEqual(params['taskName'],
0072 'group.EIC.26.02.0.epic_craterlake.p3001.e1.s1.r1')
0073 self.assertEqual(params['userName'], 'wenaus')
0074 self.assertEqual(params['vo'], 'eic')
0075 self.assertEqual(params['workingGroup'], 'EIC')
0076 self.assertEqual(params['campaign'], '26.02.0')
0077
0078
0079 self.assertEqual(params['prodSourceLabel'], 'managed')
0080 self.assertEqual(params['taskType'], 'production')
0081 self.assertEqual(params['processingType'], 'epicproduction')
0082 self.assertEqual(params['taskPriority'], 900)
0083
0084
0085 self.assertEqual(params['transPath'],
0086 'https://pandaserver-doma.cern.ch/trf/user/runGen-00-00-02')
0087 self.assertEqual(params['transUses'], '')
0088 self.assertEqual(params['transHome'], '')
0089 self.assertEqual(params['architecture'], '')
0090 self.assertEqual(params['container_name'],
0091 'docker://eicweb/jug_xl:26.02.0-stable')
0092
0093
0094 self.assertTrue(params['noInput'])
0095 self.assertEqual(params['nFiles'], 10)
0096 self.assertEqual(params['nFilesPerJob'], 1)
0097 self.assertEqual(params['nEventsPerJob'], 100)
0098 self.assertEqual(params['coreCount'], 1)
0099 self.assertEqual(params['ramCount'], 4000)
0100 self.assertEqual(params['ramUnit'], 'MBPerCore')
0101 self.assertEqual(params['walltime'], 7200)
0102
0103
0104 self.assertEqual(params['site'], 'BNL_EPIC_PROD_1')
0105 self.assertEqual(params['cloud'], 'EIC')
0106
0107
0108 self.assertEqual(params['log']['dataset'],
0109 'group.EIC:group.EIC.26.02.0.epic_craterlake.p3001.e1.s1.r1.log')
0110 self.assertEqual(params['log']['param_type'], 'log')
0111 self.assertEqual(params['log']['type'], 'template')
0112 self.assertIn('.${SN}.log.tgz', params['log']['value'])
0113
0114
0115 constant_entry = params['jobParameters'][0]
0116 self.assertEqual(constant_entry['type'], 'constant')
0117 for expected in ('EBEAM=10', 'PBEAM=100',
0118 'DETECTOR_VERSION=26.02.0',
0119 'DETECTOR_CONFIG=epic_craterlake',
0120 'JUG_XL_TAG=26.02.0-stable',
0121 'COPYRECO=true', 'COPYFULL=false', 'COPYLOG=true',
0122 './run.sh'):
0123 self.assertIn(expected, constant_entry['value'])
0124
0125 output_entry = params['jobParameters'][1]
0126 self.assertEqual(output_entry['type'], 'template')
0127 self.assertEqual(output_entry['param_type'], 'output')
0128 self.assertEqual(output_entry['dataset'],
0129 'group.EIC:group.EIC.26.02.0.epic_craterlake.p3001.e1.s1.r1')
0130 self.assertIn('.${SN}.root', output_entry['value'])
0131 self.assertEqual(output_entry['offset'], 1000)
0132
0133 def test_defaults_when_data_missing(self):
0134 task = _make_task()
0135
0136 task.get_effective_config = lambda: {
0137 'panda_site': '',
0138 'panda_working_group': '',
0139 'container_image': '',
0140 'target_hours_per_job': None,
0141 'events_per_task': None,
0142 'use_rucio': False,
0143 'copy_reco': False,
0144 'copy_full': False,
0145 'copy_log': False,
0146 'bg_mixing': False,
0147 'data': {},
0148 }
0149 params = build_task_params(task)
0150
0151 self.assertEqual(params['vo'], 'eic')
0152 self.assertEqual(params['workingGroup'], 'EIC')
0153 self.assertEqual(params['prodSourceLabel'], 'test')
0154 self.assertEqual(params['processingType'], 'epicproduction')
0155 self.assertEqual(params['coreCount'], 1)
0156 self.assertEqual(params['ramCount'], 2000)
0157 self.assertNotIn('walltime', params)
0158 self.assertNotIn('nFiles', params)
0159 self.assertNotIn('skipScout', params)
0160 self.assertNotIn('useRucio', params)