Skip to content
Browse files

MDL-27475 backup - fix start/end notifications order + tests

  • Loading branch information...
1 parent de58499 commit 8298bedab7c507136cb3efe02a908da37c9bcee6 @stronk7 stronk7 committed May 11, 2011
View
12 backup/util/xml/parser/processors/grouped_parser_processor.class.php
@@ -71,16 +71,6 @@ public function add_path($path, $grouped = false) {
}
/**
- * Notify start of path if selected and not under grouped
- */
- public function before_path($path) {
- if ($this->path_is_selected($path) && !$this->grouped_parent_exists($path)) {
- parent::before_path($path);
- }
- }
-
-
- /**
* Dispatch grouped chunks safely once their end tag happens.
* Also notify end of path if selected and not under grouped
*/
@@ -110,6 +100,7 @@ protected function postprocess_chunk($data) {
$path = $data['path'];
// If the chunk is a grouped one, simply put it into currentdata
if ($this->path_is_grouped($path)) {
+ $this->notify_path_start($path);
$this->currentdata[$path] = $data;
// If the chunk is child of grouped one, add it to currentdata
@@ -119,6 +110,7 @@ protected function postprocess_chunk($data) {
// No grouped nor child of grouped, dispatch it
} else {
+ $this->notify_path_start($path);
$this->dispatch_chunk($data);
}
}
View
10 backup/util/xml/parser/processors/simplified_parser_processor.class.php
@@ -150,15 +150,6 @@ public function process_chunk($data) {
}
/**
- * The parser fires this each time one path is going to be parsed
- */
- public function before_path($path) {
- if ($this->path_is_selected($path)) {
- $this->notify_path_start($path);
- }
- }
-
- /**
* The parser fires this each time one path has been parsed
*/
public function after_path($path) {
@@ -170,6 +161,7 @@ public function after_path($path) {
// Protected API starts here
protected function postprocess_chunk($data) {
+ $this->notify_path_start($data['path']);
$this->dispatch_chunk($data);
}
View
84 backup/util/xml/parser/simpletest/testparser.php
@@ -330,6 +330,13 @@ function test_simplified_parser_results() {
sort($snotifs);
sort($enotifs);
$this->assertEqual($snotifs, $enotifs);
+
+ // Now verify that the start/process/end order is correct
+ $allnotifs = $pr->get_all_notifications();
+ $this->assertEqual(count($allnotifs), count($snotifs) + count($enotifs) + count($chunks)); // The count
+ // Check integrity of the notifications
+ $errcount = $this->helper_check_notifications_order_integrity($allnotifs);
+ $this->assertEqual($errcount, 0); // No errors found, plz
}
/*
@@ -498,6 +505,67 @@ function test_grouped_parser_results() {
sort($snotifs);
sort($enotifs);
$this->assertEqual($snotifs, $enotifs);
+
+ // Now verify that the start/process/end order is correct
+ $allnotifs = $pr->get_all_notifications();
+ $this->assertEqual(count($allnotifs), count($snotifs) + count($enotifs) + count($chunks)); // The count
+ // Check integrity of the notifications
+ $errcount = $this->helper_check_notifications_order_integrity($allnotifs);
+ $this->assertEqual($errcount, 0); // No errors found, plz
+ }
+
+ /**
+ * Helper function that given one array of ordered start/process/end notifications will
+ * check it of integrity like:
+ * - process only happens if start is the previous notification
+ * - end only happens if dispatch is the previous notification
+ * - start only happen with level > than last one and if there is no already started like that
+ *
+ * @param array $notifications ordered array of notifications with format [start|process|end]:path
+ * @return int number of integrity problems found (errors)
+ */
+ function helper_check_notifications_order_integrity($notifications) {
+ $numerrors = 0;
+ $notifpile = array('pilebase' => 'start');
+ $lastpile = 'start:pilebase';
+ foreach ($notifications as $notif) {
+ $lastpilelevel = strlen(preg_replace('/[^\/]/', '', $lastpile));
+ $lastpiletype = preg_replace('/:.*/', '', $lastpile);
+ $lastpilepath = preg_replace('/.*:/', '', $lastpile);
+
+ $notiflevel = strlen(preg_replace('/[^\/]/', '', $notif));
+ $notiftype = preg_replace('/:.*/', '', $notif);
+ $notifpath = preg_replace('/.*:/', '', $notif);
+
+ switch ($notiftype) {
+ case 'process':
+ if ($lastpilepath != $notifpath or $lastpiletype != 'start') {
+ $numerrors++; // Only start for same path is allowed before process
+ }
+ $notifpile[$notifpath] = 'process'; // Update the status in the pile
+ break;
+ case 'end':
+ if ($lastpilepath != $notifpath or $lastpiletype != 'process') {
+ $numerrors++; // Only process for same path is allowed before end
+ }
+ unset($notifpile[$notifpath]); // Delete from the pile
+ break;
+ case 'start':
+ if (array_key_exists($notifpath, $notifpile) or $notiflevel <= $lastpilelevel) {
+ $numerrors++; // If same path exists or the level is < than the last one
+ }
+ $notifpile[$notifpath] = 'start'; // Add to the pile
+ break;
+ default:
+ $numerrors++; // Incorrect type of notification => error
+ }
+ // Update lastpile
+ end($notifpile);
+ $path = key($notifpile);
+ $type = $notifpile[$path];
+ $lastpile = $type. ':' . $path;
+ }
+ return $numerrors;
}
}
@@ -572,17 +640,21 @@ class mock_simplified_parser_processor extends simplified_parser_processor {
private $chunksarr = array(); // To accumulate the found chunks
private $startarr = array(); // To accumulate all the notified path starts
private $endarr = array(); // To accumulate all the notified path ends
+ private $allnotif = array(); // To accumulate all the notified and dispatched events in an ordered way
public function dispatch_chunk($data) {
$this->chunksarr[] = $data;
+ $this->allnotif[] = 'process:' . $data['path'];
}
public function notify_path_start($path) {
$this->startarr[] = $path;
+ $this->allnotif[] = 'start:' . $path;
}
public function notify_path_end($path) {
$this->endarr[] = $path;
+ $this->allnotif[] = 'end:' . $path;
}
public function get_chunks() {
@@ -596,6 +668,10 @@ public function get_start_notifications() {
public function get_end_notifications() {
return $this->endarr;
}
+
+ public function get_all_notifications() {
+ return $this->allnotif;
+ }
}
/*
@@ -606,17 +682,21 @@ class mock_grouped_parser_processor extends grouped_parser_processor {
private $chunksarr = array(); // To accumulate the found chunks
private $startarr = array(); // To accumulate all the notified path starts
private $endarr = array(); // To accumulate all the notified path ends
+ private $allnotif = array(); // To accumulate all the notified and dispatched events in an ordered way
public function dispatch_chunk($data) {
$this->chunksarr[] = $data;
+ $this->allnotif[] = 'process:' . $data['path'];
}
public function notify_path_start($path) {
$this->startarr[] = $path;
+ $this->allnotif[] = 'start:' . $path;
}
public function notify_path_end($path) {
$this->endarr[] = $path;
+ $this->allnotif[] = 'end:' . $path;
}
public function get_chunks() {
@@ -630,4 +710,8 @@ public function get_start_notifications() {
public function get_end_notifications() {
return $this->endarr;
}
+
+ public function get_all_notifications() {
+ return $this->allnotif;
+ }
}

0 comments on commit 8298bed

Please sign in to comment.
Something went wrong with that request. Please try again.