Package Peach :: Package Mutators :: Module datatree
[hide private]

Source Code for Module Peach.Mutators.datatree

  1   
  2  ''' 
  3  Mutators that modify the data tree structure. 
  4   
  5  @author: Michael Eddington 
  6  @version: $Id$ 
  7  ''' 
  8   
  9  # 
 10  # Copyright (c) 2008 Michael Eddington 
 11  # 
 12  # Permission is hereby granted, free of charge, to any person obtaining a copy  
 13  # of this software and associated documentation files (the "Software"), to deal 
 14  # in the Software without restriction, including without limitation the rights  
 15  # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell  
 16  # copies of the Software, and to permit persons to whom the Software is  
 17  # furnished to do so, subject to the following conditions: 
 18  # 
 19  # The above copyright notice and this permission notice shall be included in     
 20  # all copies or substantial portions of the Software. 
 21  # 
 22  # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  
 23  # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,  
 24  # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE  
 25  # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER  
 26  # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
 27  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
 28  # SOFTWARE. 
 29  # 
 30   
 31  # Authors: 
 32  #   Michael Eddington (mike@phed.org) 
 33   
 34  # $Id$ 
 35   
 36  import sys, os, time 
 37  from Peach.Generators.block import * 
 38  from Peach.Generators.data import * 
 39  from Peach.Generators.dictionary import * 
 40  from Peach.Generators.flipper import * 
 41  from Peach.Generators.static import Static, _StaticFromTemplate, _StaticCurrentValueFromDom 
 42  from Peach.Transformers.encode import WideChar 
 43  from Peach import Transformers 
 44  from Peach.mutator import * 
 45  from Peach.group import * 
 46  from Peach.Engine.common import * 
 47   
48 -class DataTreeRemoveMutator(Mutator):
49 ''' 50 Remove nodes from data tree. 51 ''' 52
53 - def __init__(self, peach):
54 Mutator.__init__(self) 55 56 self.name = "DataTreeRemoveMutator" 57 self._peach = peach 58 self._countThread = None 59 60 self._actionPos = 0 61 self._actions = [] 62 # Key is template object, value is current node position 63 self._templatePosition = {} 64 65 self._masterCount = 0 66 self._stateMasterCount = -1
67
68 - def isFinite(self):
69 ''' 70 Some mutators could contine forever, this 71 should indicate. 72 ''' 73 return True
74
75 - def reset(self):
76 ''' 77 Reset mutator 78 ''' 79 self._templatePosition = {}
80
81 - def _moveNext(self, currentNode):
82 83 # Check if we are top dog 84 if currentNode.parent == None or not isinstance(currentNode.parent, DataElement): 85 return None 86 87 # Get sibling 88 foundCurrent = False 89 for node in currentNode.parent: 90 if node == currentNode: 91 foundCurrent = True 92 continue 93 94 if foundCurrent and isinstance(node, DataElement): 95 return node 96 97 # Get sibling of parent 98 return self._moveNext(currentNode.parent)
99
100 - def _nextNode(self, action):
101 nextNode = None 102 103 # Get current node 104 node = action.template.findDataElementByName(self._templatePosition[action]) 105 106 # Walk down node tree 107 for child in node._children: 108 if isinstance(child, DataElement): 109 nextNode = child 110 break 111 112 # Walk over or up if we can 113 if nextNode == None: 114 nextNode = self._moveNext(node) 115 116 if nextNode != None: 117 return nextNode.getFullnameInDataModel() 118 119 return None
120
121 - def next(self):
122 ''' 123 Goto next mutation. When this is called 124 the state machine is updated as needed. 125 ''' 126 127 action = self._actions[self._actionPos] 128 129 if self._templatePosition[action] != None: 130 self._templatePosition[action] = self._nextNode(action) 131 132 if self._templatePosition[action] == None: 133 self._actionPos += 1 134 135 if self._actionPos >= len(self._actions): 136 self._actionPos -= 1 137 raise MutatorCompleted() 138 139 self._masterCount += 1
140
141 - def getState(self):
142 ''' 143 Return a binary string that contains 144 any information about current state of 145 Mutator. This state information should be 146 enough to let the same mutator "restart" 147 and continue when setState() is called. 148 ''' 149 150 return str(self._masterCount)
151 152
153 - def setState(self, state):
154 ''' 155 Set the state of this object. Should put us 156 back in the same place as when we said 157 "getState()". 158 ''' 159 160 self._stateMasterCount = int(state) 161 162 try: 163 for i in xrange(self._masterCount, self._stateMasterCount): 164 self.next() 165 166 self._stateMasterCount = -1 167 except: 168 pass
169
170 - def _countDataNodes(self, node):
171 172 cnt = 0 173 174 for n in node._children: 175 if n not in self.dataTypes: 176 continue; 177 cnt += 1 178 cnt += self._countDataNodes(n) 179 180 return cnt
181
182 - def getCount(self):
183 if self._countThread != None and self._countThread.hasCountEvent.isSet(): 184 self._count = self._countThread.count 185 self._countThread = None 186 self._countGroup = None 187 self._countGeneratorMap = None 188 189 return self._count
190
191 - def calculateCount(self):
192 # We just need to figure out how may data 193 # nodes are in the tree. 194 cnt = 0 195 for a in self._templatePosition.keys(): 196 cnt += 1 # for the template 197 cnt += self._countDataNodes(a.template) 198 199 return cnt
200 201 ##################################################### 202 # Callbacks when Action needs a value 203
204 - def getActionValue(self, action):
205 206 # Check if we know this template yet 207 if action not in self._templatePosition.keys(): 208 self._actions.append(action) 209 self._templatePosition[action] = action.template.getFullnameInDataModel() 210 211 # remove node 212 if self._actions[self._actionPos] == action: 213 if self._templatePosition[action] != None: 214 n = action.template.findDataElementByName(self._templatePosition[action]) 215 n.setValue("") 216 217 # return value 218 return action.template.getValue()
219
220 - def getActionParamValue(self, action):
221 return self.getActionValue(action)
222
223 - def getActionChangeStateValue(self, action, value):
224 return value
225 226 227 ##################################################### 228 # Event callbacks for state machine 229
230 - def onStateMachineComplete(self, stateMachine):
231 232 # Lets calc our count if we haven't already 233 if self._count == -1 and self._countThread == None: 234 self._countThread = MutatorCountCalculator(self) 235 self._countThread.start() 236 237 elif self._countThread != None: 238 if self._countThread.hasCountEvent.isSet(): 239 self._count = self._countThread.count
240
241 -class DataTreeDuplicateMutator(Mutator):
242 ''' 243 Duplicate nodes in data model. Currently we do a static 244 x2 duplication. 245 246 TODO: Change this todo x2 -> x10 247 ''' 248
249 - def __init__(self, peach):
250 Mutator.__init__(self) 251 252 self.name = "DataTreeDuplicateMutator" 253 self._peach = peach 254 self._countThread = None 255 256 self._actionPos = 0 257 self._actions = [] 258 # Key is action object, value is current node name 259 self._templatePosition = {} 260 self._cnt = 2 261 self._maxCount = 50 262 263 self._masterCount = 0 264 self._stateMasterCount = -1
265
266 - def isFinite(self):
267 ''' 268 Some mutators could contine forever, this 269 should indicate. 270 ''' 271 return True
272
273 - def reset(self):
274 ''' 275 Reset mutator 276 ''' 277 self._templatePosition = {}
278
279 - def _moveNext(self, currentNode):
280 281 # Check if we are top dog 282 if currentNode.parent == None or not isinstance(currentNode.parent, DataElement): 283 return None 284 285 # Get sibling 286 foundCurrent = False 287 for node in currentNode.parent: 288 if node == currentNode: 289 foundCurrent = True 290 continue 291 292 if foundCurrent and isinstance(node, DataElement): 293 return node 294 295 # Get sibling of parent 296 return self._moveNext(currentNode.parent)
297
298 - def _nextNode(self, action):
299 nextNode = None 300 301 # Get current node 302 node = action.template.findDataElementByName(self._templatePosition[action]) 303 304 # Walk down node tree 305 for child in node._children: 306 if isinstance(child, DataElement): 307 nextNode = child 308 break 309 310 # Walk over or up if we can 311 if nextNode == None: 312 nextNode = self._moveNext(node) 313 314 if nextNode != None: 315 return nextNode.getFullnameInDataModel() 316 317 return None
318
319 - def next(self):
320 ''' 321 Goto next mutation. When this is called 322 the state machine is updated as needed. 323 ''' 324 325 self._masterCount += 1 326 327 self._cnt+=1 328 if self._cnt < self._maxCount: 329 return 330 331 self._cnt = 0 332 action = self._actions[self._actionPos] 333 self._templatePosition[action] = self._nextNode(action) 334 335 if self._templatePosition[action] == None: 336 self._actionPos += 1 337 338 if self._actionPos >= len(self._actions): 339 self._actionPos -= 1 340 self._masterCount -= 1 341 raise MutatorCompleted()
342
343 - def getState(self):
344 ''' 345 Return a binary string that contains 346 any information about current state of 347 Mutator. This state information should be 348 enough to let the same mutator "restart" 349 and continue when setState() is called. 350 ''' 351 352 return str(self._masterCount)
353 354
355 - def setState(self, state):
356 ''' 357 Set the state of this object. Should put us 358 back in the same place as when we said 359 "getState()". 360 ''' 361 362 self._stateMasterCount = int(state) 363 try: 364 for i in xrange(self._masterCount, self._stateMasterCont): 365 self.next() 366 367 self._stateMasterCount = -1 368 except: 369 pass
370
371 - def _countDataNodes(self, node):
372 373 cnt = 2 374 375 for n in node._children: 376 if n not in self.dataTypes: 377 continue; 378 cnt += 1 379 cnt += self._countDataNodes(n) 380 381 return cnt
382
383 - def getCount(self):
384 if self._countThread != None and self._countThread.hasCountEvent.isSet(): 385 self._count = self._countThread.count 386 self._countThread = None 387 self._countGroup = None 388 self._countGeneratorMap = None 389 390 return self._count
391
392 - def calculateCount(self):
393 # We just need to figure out how may data 394 # nodes are in the tree. 395 cnt = 0 396 for a in self._templatePosition.keys(): 397 cnt += 1 # for the template 398 cnt += self._countDataNodes(a.template) 399 400 return cnt * self._maxCount
401 402 ##################################################### 403 # Callbacks when Action needs a value 404
405 - def getActionValue(self, action):
406 407 # Check if we know this template yet 408 if action not in self._templatePosition.keys(): 409 self._actions.append(action) 410 n = action.template 411 self._templatePosition[action] = n.getFullnameInDataModel() 412 413 # duplicate node 414 if self._actions[self._actionPos] == action: 415 if self._templatePosition[action] != None: 416 n = self._getElementByName(action.template, self._templatePosition[action] ) 417 n.setValue(n.getValue() * self._cnt) 418 419 # return value 420 return action.template.getValue()
421
422 - def getActionParamValue(self, action):
423 return self.getActionValue(action)
424
425 - def getActionChangeStateValue(self, action, value):
426 return value
427 428 429 ##################################################### 430 # Event callbacks for state machine 431
432 - def onStateStart(self, state):
433 pass
434
435 - def onStateComplete(self, state):
436 pass
437
438 - def onActionStart(self, action):
439 pass
440
441 - def onActionComplete(self, action):
442 pass
443
444 - def onStateMachineStart(self, stateMachine):
445 pass
446
447 - def onStateMachineComplete(self, stateMachine):
448 449 # Lets calc our count if we haven't already 450 if self._count == -1 and self._countThread == None: 451 self._countThread = MutatorCountCalculator(self) 452 self._countThread.start() 453 454 elif self._countThread != None: 455 if self._countThread.hasCountEvent.isSet(): 456 self._count = self._countThread.count
457 458
459 -class DataTreeSwapNearNodesMutator(Mutator):
460 ''' 461 Swap two nodes in the data model that 462 are near each other. 463 464 TODO: Actually move the nodes instead of 465 just the data. 466 ''' 467
468 - def __init__(self, peach):
469 Mutator.__init__(self) 470 471 self.name = "DataTreeSwapNearNodesMutator" 472 self._peach = peach 473 self._countThread = None 474 475 self._actionPos = 0 476 self._actions = [] 477 # Key is template object, value is current node position 478 self._templatePosition = {} 479 480 self._masterCount = 0 481 self._stateMasterCount = -1
482
483 - def isFinite(self):
484 ''' 485 Some mutators could contine forever, this 486 should indicate. 487 ''' 488 return True
489
490 - def reset(self):
491 ''' 492 Reset mutator 493 ''' 494 self._templatePosition = {}
495
496 - def _moveNext(self, currentNode):
497 498 # Check if we are top dog 499 if currentNode.parent == None or not isinstance(currentNode.parent, DataElement): 500 return None 501 502 # Get sibling 503 foundCurrent = False 504 for node in currentNode.parent: 505 if node == currentNode: 506 foundCurrent = True 507 continue 508 509 if foundCurrent and isinstance(node, DataElement): 510 return node 511 512 # Get sibling of parent 513 return self._moveNext(currentNode.parent)
514
515 - def _nextNode(self, action):
516 nextNode = None 517 518 # Get current node 519 node = action.template.findDataElementByName(self._templatePosition[action]) 520 521 # Walk down node tree 522 for child in node._children: 523 if isinstance(child, DataElement): 524 nextNode = child 525 break 526 527 # Walk over or up if we can 528 if nextNode == None: 529 nextNode = self._moveNext(node) 530 531 if nextNode != None: 532 return nextNode.getFullnameInDataModel() 533 534 return None
535
536 - def next(self):
537 ''' 538 Goto next mutation. When this is called 539 the state machine is updated as needed. 540 ''' 541 542 action = self._actions[self._actionPos] 543 544 if self._templatePosition[action] != None: 545 self._templatePosition[action] = self._nextNode(action) 546 547 if self._templatePosition[action] == None: 548 self._actionPos += 1 549 550 if self._actionPos >= len(self._actions): 551 self._actionPos -= 1 552 raise MutatorCompleted() 553 554 self._masterCount += 1
555
556 - def getState(self):
557 ''' 558 Return a binary string that contains 559 any information about current state of 560 Mutator. This state information should be 561 enough to let the same mutator "restart" 562 and continue when setState() is called. 563 ''' 564 565 return str(self._masterCount)
566
567 - def setState(self, state):
568 ''' 569 Set the state of this object. Should put us 570 back in the same place as when we said 571 "getState()". 572 ''' 573 self._stateMasterCount = int(state) 574 try: 575 for i in xrange(self._masterCount, self._stateMasterCont): 576 self.next() 577 578 self._stateMasterCount = -1 579 except: 580 pass
581
582 - def _countDataNodes(self, node):
583 584 cnt = 0 585 586 for n in node._children: 587 if n not in self.dataTypes: 588 continue; 589 cnt += 1 590 cnt += self._countDataNodes(n) 591 592 return cnt
593
594 - def getCount(self):
595 if self._countThread != None and self._countThread.hasCountEvent.isSet(): 596 self._count = self._countThread.count 597 self._countThread = None 598 self._countGroup = None 599 self._countGeneratorMap = None 600 601 return self._count
602
603 - def calculateCount(self):
604 # We just need to figure out how may data 605 # nodes are in the tree. 606 cnt = 0 607 for a in self._templatePosition.keys(): 608 cnt += 1 # for the template 609 cnt += self._countDataNodes(a.template) 610 611 return cnt
612 613 ##################################################### 614 # Callbacks when Action needs a value 615
616 - def getActionValue(self, action):
617 618 # Check if we know this template yet 619 if action not in self._templatePosition.keys(): 620 self._actions.append(action) 621 n = action.template 622 self._templatePosition[action] = n.getFullnameInDataModel() 623 624 # swap node 625 if self._actions[self._actionPos] == action: 626 if self._templatePosition[action] != None: 627 nextNode = self._nextNode(action) 628 if nextNode != None: 629 node = self._getElementByName(action.template, self._templatePosition[action] ) 630 nextNode = self._getElementByName(action.template, nextNode ) 631 632 v1 = node.getValue() 633 v2 = nextNode.getValue() 634 node.setValue(v2) 635 nextNode.setValue(v1) 636 637 # return value 638 return action.template.getValue()
639
640 - def getActionParamValue(self, action):
641 return self.getActionValue(action)
642
643 - def getActionChangeStateValue(self, action, value):
644 return value
645 646 647 ##################################################### 648 # Event callbacks for state machine 649
650 - def onStateStart(self, state):
651 pass
652
653 - def onStateComplete(self, state):
654 pass
655
656 - def onActionStart(self, action):
657 pass
658
659 - def onActionComplete(self, action):
660 pass
661
662 - def onStateMachineStart(self, stateMachine):
663 pass
664
665 - def onStateMachineComplete(self, stateMachine):
666 667 # Lets calc our count if we haven't already 668 if self._count == -1 and self._countThread == None: 669 self._countThread = MutatorCountCalculator(self) 670 self._countThread.start() 671 672 elif self._countThread != None: 673 if self._countThread.hasCountEvent.isSet(): 674 self._count = self._countThread.count
675 676 # end 677