-
-
Notifications
You must be signed in to change notification settings - Fork 814
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix of issue dev/core#127 (at gitlab), incorrect cache records for smart groups #12249
Conversation
Can one of the admins verify this patch? |
Jenkins ok to test |
@hosseinamin Hossin are you able to fix the style issues found by our test bot? https://test.civicrm.org/job/CiviCRM-Core-PR/20982/checkstyleResult/new/ |
@seamuslee001 did fix the styling issues. |
looks like there are still a couple of issues https://test.civicrm.org/job/CiviCRM-Core-PR/20984/checkstyleResult/new/ |
test this please |
/** | ||
* group update_smart_groups action test | ||
*/ | ||
public function testGroupUpdateSmartGroupsForRelatedContacts() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't how the other tests would work. Did try to run the test with closest example i could find.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So this is probably the test I would start with
It already loads multiple groups - so that is good - but none of them have this specific related contact criteria that is hitting the problem
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(I'm trying to find a test that creates a smart group now)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK - this is from ActionSchedule Test
// create smart group which will contain all Male contacts
$smartGroupParams = array('formValues' => array('gender_id' => 1));
$smartGroupID = $this->smartGroupCreate(
$smartGroupParams,
array(
'name' => 'new_smart_group',
'title' => 'New Smart Group',
'parents' => array($groupID => 1),
)
);
So something like
public function testLoadMultipleRelatedGroups
// create smart group which will contain all Male contacts
$smartGroupParams = array('formValues' => array(... related group params 1....));
$smartGroupID = $this->smartGroupCreate(
$smartGroupParams,
array(
'name' => 'new_smart_group',
'title' => 'New Smart Group',
'parents' => array($groupID => 1),
)
);
// create related group 2
// create a contact that would be in only 1
$result = $this->callApiSuccess('Contact', 'get', ['group' => $group1['id']);
$result2 $this->callApiSuccess('Contact', 'get', ['group' => $group2['id']);
// Check result is not cross-contaminated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried to perform a unit-test. I get an error. Can you direct me to a guide for preparing to run the test?
Here's the command.
phpunit4 --filter testAddCreateIndividual tests/phpunit/api/v3/ContactTest.php
Error
exception 'RuntimeException' with message '_populateDB requires CIVICRM_UF=UnitTests'
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I normally run tests from within phpunit - this is what my command line (generated by phpunit) ooks like
phpunit.php --bootstrap /Users/emcnaughton/buildkit/build/dmaster/sites/all/modules/civicrm/tests/phpunit/CiviTest/bootstrap.php --configuration /Users/emcnaughton/buildkit/build/dmaster/sites/all/modules/civicrm/phpunit.xml.dist --filter "/::testAddCreateIndividual( .*)?$/" api_v3_ContactTest /Users/emcnaughton/buildkit/build/dmaster/sites/all/modules/civicrm/tests/phpunit/api/v3/ContactTest.php
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ohh - looks like this is specifically relevant https://docs.civicrm.org/dev/en/latest/testing/phpunit/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The doc helped. Thank you @eileenmcnaughton
@@ -81,19 +81,19 @@ public static function check($groupIDs) { | |||
* @return string | |||
* the sql query which lists the groups that need to be refreshed | |||
*/ | |||
public static function groupRefreshedClause($groupIDClause = NULL, $includeHiddenGroups = FALSE) { | |||
public static function groupRefreshedClause($groupIDClause = NULL, $includeHiddenGroups = FALSE, $ignoreCache = FALSE) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can avoid adding $ignoreCache here - I think it's being added purely for the unit test? If we use the \Civi::statics pattern we can probably solve the test issue
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's ok. We can remove it with unit-test.
I don't think \Civi::statics
will help with unit-test.
Edited: An independent call to removing cache. Before loadAll
method can help.
CRM/Contact/BAO/Query.php
Outdated
if (!$_rTypeProcessed) { | ||
$_rTypeProcessed = TRUE; | ||
|
||
static $_rTempCache = array(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so per above - the way we can avoid cross-test contamination is using \Civi::statics - eg.
$arg_sig = sha1("$from $where $having");
if (!isset(\Civi::statics[CLASS]['related_contacts_filter'][$arg_sig]) {
// buld that key}
return !isset(\Civi::statics[CLASS]['related_contacts_filter'][$arg_sig]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have not placed these code for the unit-test. This is the fix. Maybe changing it to \Civi::statics has advantages that i don't know.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@hosseinamin yes - I realised that the use of $arg_sig is the test & I think it will fix the bug as described once we get the tests sorted. And thank you for working on this!
You may find that once your test running in the phpunit Continuous integration the type of static might need changing. The reason is that the Civi::statics cache is flushed between tests so you might see unexpected fails elsewhere in the suite.
We used to have 2 suites of tests - the phpunit ones & the selenium / webtests ones. The latter still exist but they are too full of false negatives to run whereas the former run against every PR that is submitted and are run nightly on different php / mysql combos
@eileenmcnaughton I've removed ignore_cache, and new testing is working for me now. |
@hosseinamin - looks like a few style tweaks needed - https://test.civicrm.org/job/CiviCRM-Core-PR/20990/checkstyleResult/new/ |
I just checked & I can confirm the test fails without the patch and passes with it and the patch seems correct. A couple of stylistic things
|
CRM/Contact/BAO/Query.php
Outdated
} | ||
$arg_sig = sha1("$from $where $having"); | ||
if (isset($_rTempCache[$arg_sig])) { | ||
$cache =& $_rTempCache[$arg_sig]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case referring as reference doesn't actually help because it's being used read only anyway
CRM/Contact/BAO/Query.php
Outdated
"from" => "", | ||
"where" => "", | ||
); | ||
$cache =& $_rTempCache[$arg_sig]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case I think it would be more consistent with other places to build up the $cache value by itself & assign it to
Civi::$statics[CLASS]['related_contacts_filter'][$arg_sig] right at the end of this else
Did the changes. |
$_rTempCache =& Civi::$statics[__CLASS__]['related_contacts_filter']; | ||
// skip if filter has already applied | ||
foreach ($_rTempCache as $acache) { | ||
if (strpos($from, $acache['from']) !== FALSE) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm just wondering about this - it seems a bit unpredictable - ie. like it would happen when it is a subset of the response & like hopefully the improved $sig_arg would make it unnecessary - did you hit any case when it was invoked in your testing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes i received an error. for injection of select and where parts twice. This loop will prevent it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately we can't do much with $sig_arg. Since there's no unique argument given.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK - I think that convinces me - if there are scenarios that are not correctly calculated they will still be less & we can add tests for them if we find any. This one won't regress with your test
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried with turning the cache variable for each instance. The down side is, it is getting instantiated multiple times and going through filter.
merging as per the tag |
@eileenmcnaughton I have no particular procedure for bringing out the welcome wagon, but it would be great to have one. Frankly, I don't usually notice until compiling the credits for a release and noticing that someone's user name isn't in Realistically, that's probably where it has to happen--you can't count on reviewers to remember who's new when they're merging PRs. However, it's also not a bad time: it's one thing to have a PR merged, and you get emails about that automatically. It's another to have your contribution be out in the world in a release, so a welcome/congratulations note then would be nice. |
But to that end--welcome @hosseinamin and thanks for the contribution! |
Overview
There was an issue with creating multiple smart group with related contact component mode.
https://lab.civicrm.org/dev/core/issues/127
filterRelatedContacts at Query.php, was not distinguishing different queries.
Before
After
Technical Details
I did add a check for already filtered queries at the beginning to prevent multiple calls to filter duplicate it. And it prevents to not distinguish a unique
$arg_sig
for each input.