25
25
use Google \Cloud \TestUtils \EventuallyConsistentTestTrait ;
26
26
use Google \Cloud \TestUtils \TestTrait ;
27
27
use PHPUnit \Framework \TestCase ;
28
+ use Google \Cloud \Core \Exception \FailedPreconditionException ;
28
29
29
30
class spannerTest extends TestCase
30
31
{
@@ -628,11 +629,11 @@ public function testCancelBackup()
628
629
*/
629
630
public function testCreateBackup ()
630
631
{
631
- $ output = $ this ->traitRunCommand ( 'create-backup ' , [
632
+ $ output = $ this ->retry ([ $ this , ' traitRunCommand ' ], [ 'create-backup ' , [
632
633
'instance_id ' => self ::$ instanceId ,
633
634
'database_id ' => self ::$ databaseId ,
634
635
'backup_id ' => self ::$ backupId ,
635
- ]);
636
+ ]] );
636
637
$ this ->assertContains (self ::$ backupId , $ output );
637
638
}
638
639
@@ -678,11 +679,11 @@ public function testUpdateBackup()
678
679
*/
679
680
public function testRestoreBackup ()
680
681
{
681
- $ output = $ this ->traitRunCommand ( 'restore-backup ' , [
682
+ $ output = $ this ->retry ([ $ this , ' traitRunCommand ' ], [ 'restore-backup ' , [
682
683
'instance_id ' => self ::$ instanceId ,
683
684
'database_id ' => self ::$ databaseId . '-res ' ,
684
685
'backup_id ' => self ::$ backupId ,
685
- ]);
686
+ ]] );
686
687
$ this ->assertContains (self ::$ backupId , $ output );
687
688
$ this ->assertContains (self ::$ databaseId , $ output );
688
689
}
@@ -713,7 +714,8 @@ public function testDeleteBackup()
713
714
$ this ->assertContains (self ::$ backupId , $ output );
714
715
}
715
716
716
- private static function waitForBackupOperations ($ instance ) {
717
+ private static function waitForBackupOperations ($ instance )
718
+ {
717
719
$ filter = "(metadata.@type:type.googleapis.com/ " .
718
720
"google.spanner.admin.database.v1.CreateBackupMetadata) " ;
719
721
@@ -725,7 +727,8 @@ private static function waitForBackupOperations($instance) {
725
727
}
726
728
}
727
729
728
- private static function waitForDatabaseOperations ($ instance ) {
730
+ private static function waitForDatabaseOperations ($ instance )
731
+ {
729
732
$ filter = "(metadata.@type:type.googleapis.com/ " .
730
733
"google.spanner.admin.database.v1.OptimizeRestoredDatabaseMetadata) " ;
731
734
@@ -737,6 +740,33 @@ private static function waitForDatabaseOperations($instance) {
737
740
}
738
741
}
739
742
743
+ /**
744
+ * A workaround for backup creation/restore operation limit
745
+ * when several testing scripts using the same Spanner instance run in parallel.
746
+ *
747
+ * @param callable $call
748
+ * @param array $args
749
+ * @return mixed
750
+ */
751
+ private function retry ($ call , $ args )
752
+ {
753
+ $ cutoffTime = time () + 20 * 60 ;
754
+ $ sleepDuration = 10 ;
755
+
756
+ while (true ) {
757
+ try {
758
+ return call_user_func_array ($ call , $ args );
759
+
760
+ } catch (FailedPreconditionException $ e ) {
761
+ if (!strstr ($ e ->getMessage (), 'maximum number of pending ' ) or time () >= $ cutoffTime ) {
762
+ throw $ e ;
763
+ }
764
+
765
+ sleep ($ sleepDuration );
766
+ }
767
+ }
768
+ }
769
+
740
770
private function runCommand ($ commandName )
741
771
{
742
772
return $ this ->traitRunCommand ($ commandName , [
0 commit comments