00001 from copy import deepcopy
00002 import inspect
00003
00004 ACTIVATE_INSPECTION=True
00005
00006
00007
00008 def auto_inspect():
00009 if not ACTIVATE_INSPECTION:
00010 return [("unknown","unknown","unknown")]
00011 stack = inspect.stack()
00012 while len(stack)>=1 and len(stack[0])>=2 and ('FWCore/ParameterSet' in stack[0][1] or 'FWCore/GuiBrowsers' in stack[0][1]):
00013 stack = stack[1:]
00014 if len(stack)>=1 and len(stack[0])>=3:
00015 return stack
00016 else:
00017 return [("unknown","unknown","unknown")]
00018
00019
00020
00021 import FWCore.ParameterSet.DictTypes as typ
00022
00023 def new_SortedKeysDict__copy__(self):
00024 return self.__class__(self)
00025 typ.SortedKeysDict.__copy__ = new_SortedKeysDict__copy__
00026
00027 def new_SortedKeysDict__deepcopy__(self, memo=None):
00028 from copy import deepcopy
00029 if memo is None:
00030 memo = {}
00031 d = memo.get(id(self), None)
00032 if d is not None:
00033 return d
00034 memo[id(self)] = d = self.__class__()
00035 d.__init__(deepcopy(self.items(), memo))
00036 return d
00037 typ.SortedKeysDict.__deepcopy__ = new_SortedKeysDict__deepcopy__
00038
00039
00040
00041 import FWCore.ParameterSet.Config as cms
00042
00043 def new___init__(self,name):
00044 self.old___init__(name)
00045 self.__dict__['_Process__history'] = []
00046 self.__dict__['_Process__enableRecording'] = 0
00047 self.__dict__['_Process__modifiedobjects'] = []
00048 self.__dict__['_Process__modifiedcheckpoint'] = None
00049 self.__dict__['_Process__modifications'] = []
00050 cms.Process.old___init__=cms.Process.__init__
00051 cms.Process.__init__=new___init__
00052
00053 def new_modifiedObjects(self):
00054 return self.__dict__['_Process__modifiedobjects']
00055 cms.Process.modifiedObjects=new_modifiedObjects
00056
00057 def new_resetModifiedObjects(self):
00058 self.__dict__['_Process__modifiedobjects'] = []
00059 cms.Process.resetModifiedObjects=new_resetModifiedObjects
00060
00061 def new__place(self, name, mod, d):
00062 self.old__place(name, mod, d)
00063 if self._okToPlace(name, mod, d):
00064 self.__dict__['_Process__modifiedobjects'].append(mod)
00065 cms.Process.old__place=cms.Process._place
00066 cms.Process._place=new__place
00067
00068 def new__placeSource(self, name, mod):
00069 self.old__placeSource(name, mod)
00070 self.__dict__['_Process__modifiedobjects'].append(mod)
00071 cms.Process.old__placeSource=cms.Process._placeSource
00072 cms.Process._placeSource=new__placeSource
00073
00074 def new__placeLooper(self, name, mod):
00075 self.old__placeLooper(name, mod)
00076 self.__dict__['_Process__modifiedobjects'].append(mod)
00077 cms.Process.old__placeLooper=cms.Process._placeLooper
00078 cms.Process._placeLooper=new__placeLooper
00079
00080 def new__placeService(self, typeName, mod):
00081 self.old__placeService(typeName, mod)
00082 self.__dict__['_Process__modifiedobjects'].append(mod)
00083 cms.Process.old__placeService=cms.Process._placeService
00084 cms.Process._placeService=new__placeService
00085
00086 def new_setSchedule_(self, sch):
00087 self.old_setSchedule_(sch)
00088 self.__dict__['_Process__modifiedobjects'].append(sch)
00089 cms.Process.old_setSchedule_=cms.Process.setSchedule_
00090 cms.Process.setSchedule_=new_setSchedule_
00091
00092 def new_setLooper_(self, lpr):
00093 self.old_setLooper_(lpr)
00094 self.__dict__['_Process__modifiedobjects'].append(lpr)
00095 cms.Process.old_setLooper_=cms.Process.setLooper_
00096 cms.Process.setLooper_=new_setLooper_
00097
00098 def new_history(self, removeDuplicates=False):
00099 return self.__dict__['_Process__history']+self.dumpModificationsWithObjects(removeDuplicates)
00100 cms.Process.history=new_history
00101
00102 def new_resetHistory(self):
00103 self.__dict__['_Process__history'] = []
00104 self.resetModified()
00105 self.resetModifiedObjects()
00106 cms.Process.resetHistory=new_resetHistory
00107
00108 def new_dumpHistory(self,withImports=True):
00109 dumpHistory=[]
00110 for item,objects in self.history():
00111 if isinstance(item,str):
00112 dumpHistory.append(item +"\n")
00113 else:
00114 dump=item.dumpPython()
00115 if isinstance(dump,tuple):
00116 if withImports and dump[0] not in dumpHistory:
00117 dumpHistory.append(dump[0])
00118 dumpHistory.append(dump[1] +"\n")
00119 else:
00120 dumpHistory.append(dump +"\n")
00121
00122 return ''.join(dumpHistory)
00123 cms.Process.dumpHistory=new_dumpHistory
00124
00125 def new_addAction(self,tool):
00126 if self.__dict__['_Process__enableRecording'] == 0:
00127 modifiedObjects=self.modifiedObjects()
00128 for m,o in self.dumpModificationsWithObjects():
00129 modifiedObjects+=o
00130 self.__dict__['_Process__history'].append((tool,modifiedObjects))
00131 self.resetModified()
00132 self.resetModifiedObjects()
00133 cms.Process.addAction=new_addAction
00134
00135 def new_deleteAction(self,i):
00136 del self.__dict__['_Process__history'][i]
00137 cms.Process.deleteAction=new_deleteAction
00138
00139 def new_disableRecording(self):
00140 if self.__dict__['_Process__enableRecording'] == 0:
00141
00142 self.__dict__['_Process__history']+=self.dumpModificationsWithObjects()
00143 self.resetModified()
00144 self.resetModifiedObjects()
00145 self.__dict__['_Process__enableRecording'] += 1
00146 cms.Process.disableRecording=new_disableRecording
00147
00148 def new_enableRecording(self):
00149 self.__dict__['_Process__enableRecording'] -= 1
00150 cms.Process.enableRecording=new_enableRecording
00151
00152 def new_checkRecording(self):
00153 return self.__dict__['_Process__enableRecording']==0
00154 cms.Process.checkRecording=new_checkRecording
00155
00156 def new_setattr(self, name, value):
00157 """
00158 This catches modifications that occur during process.load,
00159 and only records a modification if there was an existing object
00160 and the version after __setattr__ has a different id().
00161 This does not mean that the object is different, only redefined.
00162 We still really need a recursive-comparison function for parameterizeable
00163 objects to determine if a real change has been made.
00164 """
00165 old = None
00166 existing = False
00167 if not name.startswith('_Process__'):
00168 existing = hasattr(self, name)
00169 if existing:
00170 old = getattr(self, name)
00171 self.old__setattr__(name, value)
00172 if existing:
00173 if id(getattr(self, name)) != id(old):
00174 stack = auto_inspect()
00175 self.__dict__['_Process__modifications'] += [{'name': name,
00176 'old': deepcopy(old),
00177 'new': deepcopy(getattr(self, name)),
00178 'file':stack[0][1],'line':stack[0][2],
00179 'action': 'replace'}]
00180 cms.Process.old__setattr__ = cms.Process.__setattr__
00181 cms.Process.__setattr__ = new_setattr
00182
00183 def new_recurseResetModified_(self, o):
00184 """
00185 Empty all the _modifications lists for
00186 all objects beneath this one.
00187 """
00188 properties = []
00189 if isinstance(o, cms._ModuleSequenceType):
00190 o.resetModified()
00191 if isinstance(o, cms._Parameterizable):
00192 o.resetModified()
00193 for key in o.parameterNames_():
00194 value = getattr(o,key)
00195 self.recurseResetModified_(value)
00196 if isinstance(o, cms._ValidatingListBase):
00197 for index,item in enumerate(o):
00198 self.recurseResetModified_(item)
00199 cms.Process.recurseResetModified_=new_recurseResetModified_
00200
00201 def new_recurseDumpModifications_(self, name, o):
00202 """
00203 Recursively return a standardised list of modifications
00204 from the object hierarchy.
00205 """
00206 modifications = []
00207 if isinstance(o, cms._ModuleSequenceType):
00208 if o._isModified:
00209 for mod in o._modifications:
00210 modifications.append({'name':name,
00211 'action':mod['action'],
00212 'old': mod['old'],
00213 'new': mod['new'],
00214 'file': mod['file'],
00215 'line': mod['line'],
00216 'dump': o.dumpPython({}),
00217 'type': 'seq'})
00218
00219 if isinstance(o, cms._Parameterizable):
00220 for mod in o._modifications:
00221 paramname = mod['name']
00222 if hasattr(o, paramname):
00223 paramvalue = getattr(o, paramname)
00224 else:
00225 paramvalue = None
00226 if isinstance(paramvalue,cms._ParameterTypeBase):
00227 dump = paramvalue.dumpPython()
00228 else:
00229 dump = paramvalue
00230 modifications.append({'name': '%s.%s' %(name, paramname),
00231 'old': mod['old'],
00232 'new': mod['new'],
00233 'file': mod['file'],
00234 'line': mod['line'],
00235 'action': mod['action'],
00236 'dump': dump,
00237 'type': 'param'})
00238
00239
00240 for key in o.parameterNames_():
00241 value = getattr(o,key)
00242 modifications += self.recurseDumpModifications_("%s.%s" % (name, key), value)
00243
00244 if isinstance(o, cms._ValidatingListBase):
00245 for index, item in enumerate(o):
00246 modifications += self.recurseDumpModifications_("%s[%s]" % (name, index), item)
00247 if isinstance(o, cms.Process):
00248 for mod in o.__dict__['_Process__modifications']:
00249 if hasattr(o, mod['name']) and hasattr(getattr(o, mod['name']), 'dumpPython'):
00250 dump = getattr(o, mod['name']).dumpPython()
00251 else:
00252 dump = None
00253 modifications.append({'name': mod['name'],
00254 'action': mod['action'],
00255 'old': mod['old'],
00256 'new': mod['new'],
00257 'dump': dump,
00258 'file': mod['file'],
00259 'line': mod['line'],
00260 'type': 'process'})
00261 return modifications
00262 cms.Process.recurseDumpModifications_=new_recurseDumpModifications_
00263
00264 def new_modificationCheckpoint(self):
00265 """
00266 Set a checkpoint, ie get the current list of all known
00267 top-level names and store them. Later, when we print out
00268 modifications we ignore any modifications that do not affect
00269 something in this list.
00270
00271 There is currently no way of clearing this, but I think this
00272 is generally a use-once feature.
00273 """
00274 existing_names = set()
00275 for item in self.items_():
00276 existing_names.add(item[0])
00277 self.__dict__['_Process__modifiedcheckpoint'] = list(existing_names)
00278 cms.Process.modificationCheckpoint=new_modificationCheckpoint
00279
00280 def new_resetModified(self):
00281 """
00282 Empty out all the modification lists, so we only see changes that
00283 happen from now onwards.
00284 """
00285 self.__dict__['_Process__modified'] = []
00286 for name, o in self.items_():
00287 self.recurseResetModified_(o)
00288 cms.Process.resetModified=new_resetModified
00289
00290 def new_dumpModifications(self, comments=True, process=True, module=False, sequence=True, value=True, sort=True, group=True):
00291 """
00292 Return some text describing all the modifications that have been made.
00293
00294 * comments: print out comments describing the file and line which triggered
00295 the modification, if determined.
00296 * process: print "process." in front of every name
00297 * module: only print out one entry per top-level module that has been
00298 changed, rather than the details
00299 * sequence: include changes to sequences
00300 * value: print out the latest value of each name
00301 * sort: whether to sort all the names before printing (otherwise they're in
00302 more-or-less time order, within each category)
00303 """
00304 modifications = self.recurseDumpModifications_('', self)
00305 text = []
00306 for name, o in self.items_():
00307 modifications += self.recurseDumpModifications_(name, o)
00308 if not sequence:
00309 modifications = filter(lambda x: not x['type'] == 'seq', modifications)
00310 checkpoint = self.__dict__['_Process__modifiedcheckpoint']
00311 if not checkpoint == None:
00312 modifications = filter(lambda x: any([x['name'].startswith(check) for check in checkpoint]), modifications)
00313 if module:
00314 value = False
00315 comments = False
00316 modules = list(set([m['name'].split('.')[0] for m in modifications]))
00317 if sort:
00318 modules = sorted(modules)
00319 if process:
00320 text = ['process.%s' % m for m in modules]
00321 else:
00322 text = modules
00323 else:
00324 if sort:
00325 modifications = sorted(modifications, key=lambda x: x['name'])
00326 for i, m in enumerate(modifications):
00327 t = ''
00328 if comments:
00329 if m['action'] == 'replace':
00330 t += '# %(file)s:%(line)s replace %(old)s->%(new)s\n' % m
00331 elif m['action'] == 'remove':
00332 t += '# %(file)s:%(line)s remove %(old)s\n' % m
00333 elif m['action'] == 'append':
00334 t += '# %(file)s:%(line)s append %(new)s\n' % m
00335 if not group or i==len(modifications)-1 or not modifications[i+1]['name'] == m['name']:
00336 if process and value:
00337 t += 'process.%s = %s' % (m['name'], m['dump'])
00338 elif value:
00339 t += '%s = %s' % (m['name'], m['dump'])
00340 elif process:
00341 t += 'process.%s' % (m['name'])
00342 else:
00343 t += '%s' % (m['name'])
00344 text += [t]
00345 return '\n'.join(text)+'\n'
00346 cms.Process.dumpModifications=new_dumpModifications
00347
00348 def new_dumpModificationsWithObjects(self, removeDuplicates=False):
00349 modifications = []
00350 last_modification=""
00351 for name, o in self.items_():
00352 for m in self.recurseDumpModifications_(name, o):
00353
00354 if removeDuplicates and last_modification==m['name']:
00355 modifications.pop()
00356 last_modification=m['name']
00357
00358 text = 'process.%s = %s' % (m['name'], m['dump'])
00359 modifications += [(text,[o])]
00360 return modifications
00361 cms.Process.dumpModificationsWithObjects=new_dumpModificationsWithObjects
00362
00363 def new_moduleItems_(self):
00364 items = []
00365 items += self.producers.items()
00366 items += self.filters.items()
00367 items += self.analyzers.items()
00368 return tuple(items)
00369 cms.Process.moduleItems_=new_moduleItems_
00370
00371 def new_items_(self):
00372 items = []
00373 if self.source:
00374 items += [("source", self.source)]
00375 if self.looper:
00376 items += [("looper", self.looper)]
00377 items += self.moduleItems_()
00378 items += self.outputModules.items()
00379 items += self.sequences.items()
00380 items += self.paths.iteritems()
00381 items += self.endpaths.items()
00382 items += self.services.items()
00383 items += self.es_producers.items()
00384 items += self.es_sources.items()
00385 items += self.es_prefers.items()
00386 items += self.psets.items()
00387 items += self.vpsets.items()
00388 if self.schedule:
00389 items += [("schedule", self.schedule)]
00390 return tuple(items)
00391 cms.Process.items_=new_items_
00392
00393
00394
00395 def new_Parameterizable_init(self,*a,**k):
00396 self.__dict__['_modifications'] = []
00397 self.old__init__(*a,**k)
00398 self._modifications = []
00399 cms._Parameterizable.old__init__ = cms._Parameterizable.__init__
00400 cms._Parameterizable.__init__ = new_Parameterizable_init
00401
00402 def new_Parameterizable_addParameter(self, name, value):
00403 self.old__addParameter(name,value)
00404 stack = auto_inspect()
00405 self._modifications.append({'file':stack[0][1],'line':stack[0][2],'name':name,'old':None,'new':deepcopy(value),'action':'add'})
00406 cms._Parameterizable.old__addParameter = cms._Parameterizable._Parameterizable__addParameter
00407 cms._Parameterizable._Parameterizable__addParameter = new_Parameterizable_addParameter
00408
00409 def new_Parameterizable_setattr(self, name, value):
00410 if (not self.isFrozen()) and (not name.startswith('_')) and (name in self.__dict__):
00411 stack = auto_inspect()
00412 self._modifications.append({'file':stack[0][1],'line':stack[0][2],'name':name,'old':deepcopy(self.__dict__[name]),'new':deepcopy(value),'action':'replace'})
00413 self._isModified = True
00414 self.old__setattr__(name,value)
00415 cms._Parameterizable.old__setattr__ = cms._Parameterizable.__setattr__
00416 cms._Parameterizable.__setattr__ = new_Parameterizable_setattr
00417
00418 def new_Parameterizeable_delattr(self, name):
00419 if not self.isFrozen():
00420 stack = auto_inspect()
00421 self._modifications.append({'file':stack[0][1],'line':stack[0][2],'name':name,'old':deepcopy(self.__dict__[name]), 'new':None,'action':'delete'})
00422 self.old__delattr__(name)
00423 cms._Parameterizable.old__delattr__ = cms._Parameterizable.__delattr__
00424 cms._Parameterizable.__delattr__ = new_Parameterizeable_delattr
00425
00426
00427 def new_Parameterizable_resetModified(self):
00428 self._isModified=False
00429 self._modifications = []
00430 for name in self.parameterNames_():
00431 param = self.__dict__[name]
00432 if isinstance(param, cms._Parameterizable):
00433 param.resetModified()
00434 cms._Parameterizable.resetModified = new_Parameterizable_resetModified
00435
00436 def new_ParameterTypeBase_resetModified(self):
00437 self._isModified=False
00438 self._modifications = []
00439 cms._ParameterTypeBase.resetModified = new_ParameterTypeBase_resetModified
00440
00441
00442
00443 def new__Sequenceable_name(self):
00444 return ''
00445 cms._Sequenceable._name = new__Sequenceable_name
00446
00447 try:
00448
00449 from FWCore.ParameterSet.SequenceTypes import _SequenceOperator
00450
00451 def new__SequenceOperator_name(self):
00452 return str(self._left._name())+str(self._pySymbol)+str(self._right._name())
00453 _SequenceOperator._name = new__SequenceOperator_name
00454 except:
00455 pass
00456
00457 from FWCore.ParameterSet.SequenceTypes import _SequenceNegation, _SequenceIgnore
00458
00459 def new__SequenceNegation_name(self):
00460 if self._operand:
00461 return '~'+str(self._operand._name())
00462 else:
00463 return '~()'
00464 _SequenceNegation._name = new__SequenceNegation_name
00465
00466 def new__SequenceIgnore_name(self):
00467 if self._operand:
00468 return '-'+str(self._operand._name())
00469 else:
00470 return '-()'
00471 _SequenceIgnore._name = new__SequenceIgnore_name
00472
00473 def new_Sequence_name(self):
00474 if self._seq:
00475 return '('+str(self._seq._name())+')'
00476 else:
00477 return '()'
00478 cms.Sequence._name = new_Sequence_name
00479
00480 def new__Module_name(self):
00481 if hasattr(self,'_Labelable__label'):
00482 return getattr(self,'_Labelable__label')
00483 elif hasattr(self,'_TypedParameterizable__type'):
00484 return 'unnamed(%s)'%getattr(self,'_TypedParameterizable__type')
00485 return type(self).__name__
00486 cms._Module._name = new__Module_name
00487
00488 def new__ModuleSequenceType__init__(self,*arg,**argv):
00489 self._modifications = []
00490 self.old__init__(*arg,**argv)
00491 cms._ModuleSequenceType.old__init__ = cms._ModuleSequenceType.__init__
00492 cms._ModuleSequenceType.__init__ = new__ModuleSequenceType__init__
00493
00494 def new__ModuleSequenceType_resetModified(self):
00495 self._isModified=False
00496 self._modifications = []
00497 cms._ModuleSequenceType.resetModified = new__ModuleSequenceType_resetModified
00498
00499 def new__ModuleSequenceType_isModified(self):
00500 return self._isModified
00501 cms._ModuleSequenceType.isModified = new__ModuleSequenceType_isModified
00502
00503 def new__ModuleSequenceType_copy(self):
00504 returnValue = cms._ModuleSequenceType.__new__(type(self))
00505 returnValue.__init__(self._seq)
00506 returnValue._isModified = self._isModified
00507 returnValue._modifications = deepcopy(self._modifications)
00508 return returnValue
00509 cms._ModuleSequenceType.copy = new__ModuleSequenceType_copy
00510
00511 def new__ModuleSequenceType_replace(self, original, replacement):
00512 stack = auto_inspect()
00513 self._isModified=True
00514 self._modifications.append({'file':stack[0][1],'line':stack[0][2],'action':'replace','old':original._name(),'new':replacement._name()})
00515 return self.old_replace(original, replacement)
00516 cms._ModuleSequenceType.old_replace = cms._ModuleSequenceType.replace
00517 cms._ModuleSequenceType.replace = new__ModuleSequenceType_replace
00518
00519 def new__ModuleSequenceType_remove(self, original):
00520 stack = auto_inspect()
00521 self._isModified=True
00522 self._modifications.append({'file':stack[0][1],'line':stack[0][2],'action':'remove','old':original._name(),'new':None})
00523 return self.old_remove(original)
00524 cms._ModuleSequenceType.old_remove = cms._ModuleSequenceType.remove
00525 cms._ModuleSequenceType.remove = new__ModuleSequenceType_remove
00526
00527 def new__ModuleSequenceType__imul__(self,other):
00528 stack = auto_inspect()
00529 self._modifications.append({'file':stack[0][1],'line':stack[0][2],'action':'append','new':other._name(),'old':None})
00530 self._isModified=True
00531 return self.old__iadd__(other)
00532 cms._ModuleSequenceType.old__imul__ = cms._ModuleSequenceType.__imul__
00533 cms._ModuleSequenceType.__imul__ = new__ModuleSequenceType__imul__
00534
00535 def new__ModuleSequenceType__iadd__(self,other):
00536 stack = auto_inspect()
00537 self._isModified=True
00538 self._modifications.append({'file':stack[0][1],'line':stack[0][2],'action':'append','new':other._name(),'old':None})
00539 return self.old__iadd__(other)
00540 cms._ModuleSequenceType.old__iadd__ = cms._ModuleSequenceType.__iadd__
00541 cms._ModuleSequenceType.__iadd__ = new__ModuleSequenceType__iadd__
00542
00543 from FWCore.ParameterSet.Modules import Source
00544 from FWCore.GuiBrowsers.editorTools import changeSource
00545
00546 if __name__=='__main__':
00547 import unittest
00548 class TestModificationTracking(unittest.TestCase):
00549 def setUp(self):
00550 pass
00551 def testPSet(self):
00552 ex = cms.EDAnalyzer("Example",
00553 one = cms.double(0),
00554 two = cms.bool(True),
00555 ps = cms.PSet(
00556 three = cms.int32(10),
00557 four = cms.string('abc')
00558 ),
00559 vps = cms.VPSet(
00560 cms.PSet(
00561 five = cms.InputTag('alpha')
00562 ),
00563 cms.PSet(
00564 six = cms.vint32(1,2,3)
00565 )
00566 ),
00567 seven = cms.vstring('alpha','bravo','charlie'),
00568 eight = cms.vuint32(range(10)),
00569 nine = cms.int32(0)
00570 )
00571 ex.zero = cms.string('hello')
00572 self.assertEqual(ex._modifications[-1]['name'],'zero')
00573 ex.one = cms.double(1)
00574 ex.one = cms.double(2)
00575 ex.one = cms.double(3)
00576 self.assertEqual(ex._modifications[-1]['name'],'one')
00577 self.assertEqual(ex._modifications[-2]['name'],'one')
00578 self.assertEqual(ex._modifications[-3]['name'],'one')
00579 ex.two = False
00580 self.assertEqual(ex._modifications[-1]['name'],'two')
00581 ex.ps.three.setValue(100)
00582
00583 ex.ps.four = 'def'
00584 self.assertEqual(ex.ps._modifications[-1]['name'],'four')
00585 ex.vps[0].five = cms.string('beta')
00586 self.assertEqual(ex.vps[0]._modifications[-1]['name'],'five')
00587 ex.vps[1].__dict__['six'] = cms.vint32(1,4,9)
00588
00589 ex.seven[0] = 'delta'
00590
00591 ex.eight.pop()
00592
00593 del ex.nine
00594
00595 ex.newvpset = cms.VPSet()
00596 self.assertEqual(ex._modifications[-1]['name'],'newvpset')
00597
00598 process = cms.Process('unittest')
00599 process.ex = ex
00600 mods = process.dumpModifications()
00601 self.assert_('process.ex.zero' in mods)
00602 self.assert_('process.ex.one' in mods)
00603 self.assert_('process.ex.two' in mods)
00604
00605 self.assert_('process.ex.ps.four' in mods)
00606 self.assert_('process.ex.vps[0].five' in mods)
00607
00608
00609
00610 self.assert_('process.ex.nine' in mods)
00611 self.assert_('process.ex.newvpset' in mods)
00612
00613
00614
00615 def testSeq(self):
00616 process = cms.Process('unittest')
00617 for i in range(10):
00618 setattr(process,'f%s'%i,cms.EDFilter('f%s'%i))
00619 process.seq1 = cms.Sequence(process.f1*process.f2*process.f3)
00620 self.assertEqual(process.seq1._modifications,[])
00621 process.seq2 = cms.Sequence(process.f4+process.f5+process.f6)
00622 self.assertEqual(process.seq2._modifications,[])
00623
00624 process.seq1.replace(process.f1,process.f0*process.f1)
00625 self.assertEqual(process.seq1._modifications[-1]['action'],'replace')
00626
00627 process.seq2.remove(process.f5)
00628 self.assertEqual(process.seq2._modifications[-1]['action'],'remove')
00629
00630 process.path = cms.Path(process.seq1*process.f7)
00631 self.assertEqual(process.path._modifications,[])
00632
00633 process.path *= process.seq2
00634 self.assertEqual(process.path._modifications[-1]['action'],'append')
00635 process.path.remove(process.f6)
00636 self.assertEqual(process.path._modifications[-1]['action'],'remove')
00637 process.path.replace(process.f2,~process.f2)
00638 self.assertEqual(process.path._modifications[-1]['action'],'replace')
00639
00640 mods = process.dumpModifications()
00641 self.assert_('process.seq1' in mods)
00642 self.assert_('process.seq2' in mods)
00643 self.assert_('process.path' in mods)
00644
00645 def testdumpHistory(self):
00646 process = cms.Process('unittest')
00647 process.source=Source("PoolSource",fileNames = cms.untracked.string("file:file.root"))
00648
00649 changeSource(process,"file:filename.root")
00650 self.assertEqual(changeSource._parameters['source'].value,"file:filename.root")
00651
00652 changeSource(process,"file:filename2.root")
00653 self.assertEqual(changeSource._parameters['source'].value,"file:filename2.root")
00654
00655 changeSource(process,"file:filename3.root")
00656 self.assertEqual(changeSource._parameters['source'].value,"file:filename3.root")
00657
00658 self.assertEqual(process.dumpHistory(),"\nfrom FWCore.GuiBrowsers.editorTools import *\n\nchangeSource(process , 'file:filename.root')\n\n\nchangeSource(process , 'file:filename2.root')\n\n\nchangeSource(process , 'file:filename3.root')\n\n")
00659
00660 process.source.fileNames=cms.untracked.vstring("file:replacedfile.root")
00661 self.assertEqual(process.dumpHistory(),"\nfrom FWCore.GuiBrowsers.editorTools import *\n\nchangeSource(process , 'file:filename.root')\n\n\nchangeSource(process , 'file:filename2.root')\n\n\nchangeSource(process , 'file:filename3.root')\n\nprocess.source.fileNames = cms.untracked.vstring('file:replacedfile.root')\n")
00662
00663 process.disableRecording()
00664 changeSource.setParameter('source',"file:filename4.root")
00665 action=changeSource.__copy__()
00666 process.addAction(action)
00667 self.assertEqual(process.dumpHistory(),"\nfrom FWCore.GuiBrowsers.editorTools import *\n\nchangeSource(process , 'file:filename.root')\n\n\nchangeSource(process , 'file:filename2.root')\n\n\nchangeSource(process , 'file:filename3.root')\n\nprocess.source.fileNames = cms.untracked.vstring('file:replacedfile.root')\n")
00668
00669 process.enableRecording()
00670 changeSource.setParameter('source',"file:filename5.root")
00671 action=changeSource.__copy__()
00672 process.addAction(action)
00673 process.deleteAction(3)
00674 self.assertEqual(process.dumpHistory(),"\nfrom FWCore.GuiBrowsers.editorTools import *\n\nchangeSource(process , 'file:filename.root')\n\n\nchangeSource(process , 'file:filename2.root')\n\n\nchangeSource(process , 'file:filename3.root')\n\n\nchangeSource(process , 'file:filename5.root')\n\n")
00675
00676 process.deleteAction(0)
00677 self.assertEqual(process.dumpHistory(),"\nfrom FWCore.GuiBrowsers.editorTools import *\n\nchangeSource(process , 'file:filename2.root')\n\n\nchangeSource(process , 'file:filename3.root')\n\n\nchangeSource(process , 'file:filename5.root')\n\n")
00678
00679 def testModifiedObjectsHistory(self):
00680 process = cms.Process('unittest')
00681 process.source=Source("PoolSource",fileNames = cms.untracked.string("file:file.root"))
00682
00683 changeSource(process,"file:filename.root")
00684 self.assertEqual(len(process.history()[0][1]),1)
00685
00686 process.source.fileNames=cms.untracked.vstring("file:replacedfile.root")
00687 self.assertEqual(len(process.history()[0][1]),1)
00688 self.assertEqual(len(process.history()[1][1]),1)
00689
00690 process.source.fileNames=["test2"]
00691 self.assertEqual(len(process.history()[0][1]),1)
00692 self.assertEqual(len(process.history()[1][1]),1)
00693
00694 changeSource(process,"file:filename2.root")
00695 self.assertEqual(len(process.history()[0][1]),1)
00696 self.assertEqual(len(process.history()[1][1]),1)
00697 self.assertEqual(len(process.history()[2][1]),1)
00698
00699 process.source.fileNames=cms.untracked.vstring("file:replacedfile2.root")
00700 self.assertEqual(len(process.history()[0][1]),1)
00701 self.assertEqual(len(process.history()[1][1]),1)
00702 self.assertEqual(len(process.history()[2][1]),1)
00703 self.assertEqual(len(process.history()[3][1]),1)
00704
00705 unittest.main()
00706