@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Fix flaky subscribers policy rule unit test

Summary:
I'm about 90% sure this fixes the intermittent test failure on `testObjectSubscribersPolicyRule()` or whatever.

We use `spl_object_hash()` to identify objects when passing hints about policy changes to policy rules. This is hacky, and I think it's the source of the unit test issue.

Specifically, `spl_object_hash()` is approximately just returning the memory address of the object, and two objects can occasionally use the same memory address (one gets garbage collected; another uses the same memory).

If I replace `spl_object_hash()` with a static value like "zebra", the test failure reproduces.

Instead, sneak an object ID onto a runtime property. This is at least as hacky but shouldn't suffer from the same intermittent failure.

Test Plan: Ran `arc unit --everything`, but I never got a reliable repro of the issue in the first place, so who knows.

Reviewers: chad

Reviewed By: chad

Differential Revision: https://secure.phabricator.com/D17029

+31 -7
+24 -3
src/applications/policy/rule/PhabricatorPolicyRule.php
··· 144 144 private static function getObjectPolicyCacheKey( 145 145 PhabricatorPolicyInterface $object, 146 146 PhabricatorPolicyRule $rule) { 147 - $hash = spl_object_hash($object); 148 - $rule = get_class($rule); 149 - return 'policycache.'.$hash.'.'.$rule; 147 + 148 + // NOTE: This is quite a bit of a hack, but we don't currently have a 149 + // better way to carry hints from the TransactionEditor into PolicyRules 150 + // about pending policy changes. 151 + 152 + // Put some magic secret unique value on each object so we can pass 153 + // information about it by proxy. This allows us to test if pending 154 + // edits to an object will cause policy violations or not, before allowing 155 + // those edits to go through. 156 + 157 + // Some better approaches might be: 158 + // - Use traits to give `PhabricatorPolicyInterface` objects real 159 + // storage (requires PHP 5.4.0). 160 + // - Wrap policy objects in a container with extra storage which the 161 + // policy filter knows how to unbox (lots of work). 162 + 163 + // When this eventually gets cleaned up, the corresponding hack in 164 + // LiskDAO->__set() should also be cleaned up. 165 + static $id = 0; 166 + if (!isset($object->_hashKey)) { 167 + @$object->_hashKey = 'object.id('.(++$id).')'; 168 + } 169 + 170 + return $object->_hashKey; 150 171 } 151 172 152 173
+7 -4
src/infrastructure/storage/lisk/LiskDAO.php
··· 1780 1780 * @task util 1781 1781 */ 1782 1782 public function __set($name, $value) { 1783 - phlog( 1784 - pht( 1785 - 'Wrote to undeclared property %s.', 1786 - get_class($this).'::$'.$name)); 1783 + // Hack for policy system hints, see PhabricatorPolicyRule for notes. 1784 + if ($name != '_hashKey') { 1785 + phlog( 1786 + pht( 1787 + 'Wrote to undeclared property %s.', 1788 + get_class($this).'::$'.$name)); 1789 + } 1787 1790 $this->$name = $value; 1788 1791 } 1789 1792