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