Exemplo n.º 1
0
    def fixConflicts(self):
        """Fix elements in conflict

        Each local queue runs this to resolve its conflicts with global,
        resolution propagates up to global.

        Conflicting elements are merged into one element with others deleted.

        This will fail if elements are modified during the resolution -
        if this happens rerun.
        """
        for db in [self.inbox, self.db]:
            for row in db.loadView('WorkQueue', 'conflicts')['rows']:
                element_id = row['id']
                try:
                    conflicting_elements = [CouchWorkQueueElement.fromDocument(db, db.document(element_id, rev)) \
                                            for rev in row['value']]
                    fixed_elements = fixElementConflicts(*conflicting_elements)
                    if self.saveElements(fixed_elements[0]):
                        self.saveElements(
                            *fixed_elements[1:]
                        )  # delete others (if merged value update accepted)
                except Exception as ex:
                    self.logger.error("Error resolving conflict for %s: %s" %
                                      (element_id, str(ex)))
Exemplo n.º 2
0
 def testFixElementConflicts(self):
     """Element conflicts handled"""
     # list of before and after elements for comparison
     values = [
               # status conflict
               [[{'RequestName' : 'arequest', 'Status' : 'Available'}, {'RequestName' : 'arequest', 'Status' : 'CancelRequested'}],
               [{'RequestName' : 'arequest', 'Status' : 'CancelRequested'}, {'RequestName' : 'arequest', 'Status' : 'CancelRequested'}]
              ],
               # location conflict - local uses location and global subscriptions
               [[{'RequestName' : 'brequest', 'Status' : 'CancelRequested', 'Inputs' : {'a' : [1]}}, {'RequestName' : 'brequest', 'Status' : 'Available', 'Inputs' : {'a' : [1,2]}}],
               [{'RequestName' : 'brequest', 'Status' : 'CancelRequested', 'Inputs' : {'a' : [1,2]}}, {'RequestName' : 'brequest', 'Status' : 'Available', 'Inputs' : {'a' : [1,2]}}]
              ],
               # status and progress conflict
               [[{'RequestName' : 'crequest', 'Status' : 'Available', 'PercentComplete' : 69}, {'RequestName' : 'crequest', 'Status' : 'CancelRequested'}],
               [{'RequestName' : 'crequest', 'Status' : 'CancelRequested', 'PercentComplete' : 69}, {'RequestName' : 'crequest', 'Status' : 'CancelRequested'}]
              ],
               # status and subscription conflict
               [[{'RequestName' : 'drequest', 'Status' : 'Running', 'SubscriptionId' : 69}, {'RequestName' : 'drequest', 'Status' : 'CancelRequested'}],
               [{'RequestName' : 'drequest', 'Status' : 'CancelRequested', 'SubscriptionId' : 69}, {'RequestName' : 'drequest', 'Status' : 'CancelRequested'}]
              ],
               # whitelist conflict
               [[{'RequestName' : 'erequest', 'SiteWhitelist' : [1,2]}, {'RequestName' : 'erequest'}],
               [{'RequestName' : 'erequest', 'SiteWhitelist' : [1,2]}, {'RequestName' : 'erequest'}]
              ],
               # black conflict
               [[{'RequestName' : 'frequest'}, {'RequestName' : 'frequest', 'SiteBlacklist' : [1,2]}],
               [{'RequestName' : 'frequest', 'SiteBlacklist' : [1,2]}, {'RequestName' : 'frequest', 'SiteBlacklist' : [1,2]}]
              ],
               # priority conflict
               [[{'RequestName' : 'grequest'}, {'RequestName' : 'grequest', 'Priority' : 69}],
               [{'RequestName' : 'grequest', 'Priority' : 69}, {'RequestName' : 'grequest', 'Priority' : 69}]
              ],
             ]
     for before, after in values:
         before = [CouchWorkQueueElement(self.couch_db, 1, elementParams = x) for x in before]
         # add fake revs
         [x._document.__setitem__('_rev', "a") for x in before]
         after = [CouchWorkQueueElement(self.couch_db, 1, elementParams = x) for x in after]
         self.assertEqual(list(fixElementConflicts(*before)), after)
Exemplo n.º 3
0
    def fixConflicts(self):
        """Fix elements in conflict

        Each local queue runs this to resolve its conflicts with global,
        resolution propagates up to global.

        Conflicting elements are merged into one element with others deleted.

        This will fail if elements are modified during the resolution -
        if this happens rerun.
        """
        for db in [self.inbox, self.db]:
            for row in db.loadView('WorkQueue', 'conflicts')['rows']:
                element_id = row['id']
                try:
                    conflicting_elements = [CouchWorkQueueElement.fromDocument(db, db.document(element_id, rev)) \
                                                                                for rev in row['value']]
                    fixed_elements = fixElementConflicts(*conflicting_elements)
                    if self.saveElements(fixed_elements[0]):
                        self.saveElements(*fixed_elements[1:]) # delete others (if merged value update accepted)
                except Exception, ex:
                    self.logger.error("Error resolving conflict for %s: %s" % (element_id, str(ex)))
Exemplo n.º 4
0
 def testFixElementConflicts(self):
     """Element conflicts handled"""
     # list of before and after elements for comparison
     values = [
         # status conflict
         [[{
             'RequestName': 'arequest',
             'Status': 'Available'
         }, {
             'RequestName': 'arequest',
             'Status': 'CancelRequested'
         }],
          [{
              'RequestName': 'arequest',
              'Status': 'CancelRequested'
          }, {
              'RequestName': 'arequest',
              'Status': 'CancelRequested'
          }]],
         # location conflict - local uses location and global subscriptions
         [[{
             'RequestName': 'brequest',
             'Status': 'CancelRequested',
             'Inputs': {
                 'a': [1]
             }
         }, {
             'RequestName': 'brequest',
             'Status': 'Available',
             'Inputs': {
                 'a': [1, 2]
             }
         }],
          [{
              'RequestName': 'brequest',
              'Status': 'CancelRequested',
              'Inputs': {
                  'a': [1, 2]
              }
          }, {
              'RequestName': 'brequest',
              'Status': 'Available',
              'Inputs': {
                  'a': [1, 2]
              }
          }]],
         # status and progress conflict
         [[{
             'RequestName': 'crequest',
             'Status': 'Available',
             'PercentComplete': 69
         }, {
             'RequestName': 'crequest',
             'Status': 'CancelRequested'
         }],
          [{
              'RequestName': 'crequest',
              'Status': 'CancelRequested',
              'PercentComplete': 69
          }, {
              'RequestName': 'crequest',
              'Status': 'CancelRequested'
          }]],
         # status and subscription conflict
         [[{
             'RequestName': 'drequest',
             'Status': 'Running',
             'SubscriptionId': 69
         }, {
             'RequestName': 'drequest',
             'Status': 'CancelRequested'
         }],
          [{
              'RequestName': 'drequest',
              'Status': 'CancelRequested',
              'SubscriptionId': 69
          }, {
              'RequestName': 'drequest',
              'Status': 'CancelRequested'
          }]],
         # whitelist conflict
         [[{
             'RequestName': 'erequest',
             'SiteWhitelist': [1, 2]
         }, {
             'RequestName': 'erequest'
         }],
          [{
              'RequestName': 'erequest',
              'SiteWhitelist': [1, 2]
          }, {
              'RequestName': 'erequest'
          }]],
         # black conflict
         [[{
             'RequestName': 'frequest'
         }, {
             'RequestName': 'frequest',
             'SiteBlacklist': [1, 2]
         }],
          [{
              'RequestName': 'frequest',
              'SiteBlacklist': [1, 2]
          }, {
              'RequestName': 'frequest',
              'SiteBlacklist': [1, 2]
          }]],
         # priority conflict
         [[{
             'RequestName': 'grequest'
         }, {
             'RequestName': 'grequest',
             'Priority': 69
         }],
          [{
              'RequestName': 'grequest',
              'Priority': 69
          }, {
              'RequestName': 'grequest',
              'Priority': 69
          }]],
     ]
     for before, after in values:
         before = [
             CouchWorkQueueElement(self.couch_db, 1, elementParams=x)
             for x in before
         ]
         # add fake revs
         [x._document.__setitem__('_rev', "a") for x in before]
         after = [
             CouchWorkQueueElement(self.couch_db, 1, elementParams=x)
             for x in after
         ]
         self.assertEqual(list(fixElementConflicts(*before)), after)