Problem/Motivation

Splitting task from #2791619: Test Monitoring Mail with real examples, this issue is created to fix the bug for the status race condition:

a result is/is not logged based on status change, but to send a mail we always checked with the second last sensor result which could be/not be outdated (as we store the current result as the "last sensor result" if the status changes).
Added a setter/getter to set the previous result when we want to log the current one, so we don't get the wrong result and don't need to fancy store the previous status to check if a mail needs to be sent.

And write a test.

Proposed resolution

- fix the bug implementing a setter/getter for SensorResult
- write a test to check if the previous sensor result is what we expect.

Remaining tasks

User interface changes

API changes

Data model changes

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

tduong created an issue. See original summary.

tduong’s picture

Status: Active » Needs review
Parent issue: » #2791619: Test Monitoring Mail with real examples
FileSize
10.96 KB

Here is a first patch. Still needs work for the test, left a @todo in the assert helper method.

Status: Needs review » Needs work

The last submitted patch, 2: get_the_correct_previous_result-2800055-2.patch, failed testing.

tduong’s picture

Priority: Normal » Major

Raise priority because the parent issue is waiting for this to be committed.

Ginovski’s picture

+++ b/tests/src/Kernel/MonitoringCoreKernelTest.php
@@ -770,4 +771,114 @@ class MonitoringCoreKernelTest extends MonitoringUnitTestBase {
+    //$this->assertSameResult($sensor_result_0, $previous_result_1);

Here there are 2 results asserted, but one is a SensorResultEntity and the other is SensorResult. So the function assertSameResultHelper would take an entity and a result object and try to compare them (right now it takes 2 entities instead). But I don't think this is necessary, because we are comparing 2 different objects and we only need to compare some properties between the entity and the result. I suggest we can do a regular assertion in this test only for the statuses?

Ginovski’s picture

Status: Needs work » Needs review
FileSize
8.82 KB

Here is a patch with the solution suggested in #5, along with some minor changes:
1. Changed the test comments and some result comparison.
2. Removed monitoring_sensor_result_second_last() since it is not used anymore.

Berdir’s picture

Status: Needs review » Needs work
  1. +++ b/monitoring.module
    @@ -266,30 +266,6 @@ function monitoring_sensor_result_last($sensor_name) {
    -function monitoring_sensor_result_second_last($sensor_name) {
    -  $result = \Drupal::entityQuery('monitoring_sensor_result')
    -    ->condition('sensor_name', $sensor_name)
    -    ->sort('timestamp', 'DESC')
    -    ->sort('record_id', 'DESC')
    -    ->range(1, 1)
    

    monitoring is now stable and this is a method in a non-experimental module.

    I suppose nobody uses it yet, but we can't just remove this now.

    So, keep it but add a @deprecated method like they exist on deprecated core methods. Schedule removel for 8.x-2.0 or something like that.

  2. +++ b/src/Result/SensorResult.php
    @@ -65,6 +62,13 @@ class SensorResult implements SensorResultInterface {
    +   * The previous sensor result.
    +   *
    +   * @var \Drupal\monitoring\Entity\SensorResultEntity|null
    +   */
    +  protected $previousResult = NULL;
    +
    
    +++ b/src/Result/SensorResultInterface.php
    @@ -197,4 +195,22 @@ interface SensorResultInterface extends SensorResultDataInterface {
    +   * @param \Drupal\monitoring\Entity\SensorResultEntity|null $previous_result
    ...
    +   * @return \Drupal\monitoring\Entity\SensorResultEntity|null
    

    use the interface

  3. +++ b/src/SensorRunner.php
    @@ -133,6 +129,7 @@ class SensorRunner {
         foreach ($sensors_config_all as $name => $sensor_config) {
           if ($result = $this->runSensor($sensor_config)) {
    +        $result->setPreviousResult(monitoring_sensor_result_last($result->getSensorId()));
             $results[$name] = $result;
           }
    

    what happens with cached sensors? are we now serializing the injected object when caching? We should avoid that and set it again or so.

miro_dietiker’s picture

We could drop setPreviousResult() and simply use call getPreviousResult() here that internally uses monitoring_sensor_result_last().
Then internally set the property and simply drop it on serialisation.

Berdir’s picture

3. We checked that and the current logic is fine, so you can ignore that part.

Ginovski’s picture

Status: Needs work » Needs review
FileSize
4.05 KB
8.37 KB

1. Added the second_last function again.
2. Using the DataInterface for the previous result. (this makes it easier to assert results with Tramy's method - assertSameResult() ).

miro_dietiker’s picture

Status: Needs review » Fixed

In general looks fine to me. :-)

However, lots of small unrelated changes... Reverted them.
And please don't touch things such as removing file headers. If you want to do this, submit a separate issue that does this for ALL files.
Otherwise, patches conflict with those clean-ups being present here and there.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.