@@ -103,26 +103,9 @@ public static void createClient()
103103 prefix = String .format ("020%d" , System .currentTimeMillis ());
104104
105105 tableAdmin = testEnvRule .env ().getTableAdminClientForInstance (targetInstance );
106-
107- testTable =
108- tableAdmin .createTable (
109- CreateTableRequest .of (generateId (TEST_TABLE_SUFFIX )).addFamily ("cf1" ));
110-
111- // Populate test data.
112106 dataClient = testEnvRule .env ().getDataClientForInstance (targetInstance );
113- byte [] rowBytes = new byte [1024 ];
114- Random random = new Random ();
115- random .nextBytes (rowBytes );
116107
117- List <ApiFuture <?>> futures = Lists .newArrayList ();
118- for (int i = 0 ; i < 10 ; i ++) {
119- ApiFuture <Void > future =
120- dataClient .mutateRowAsync (
121- RowMutation .create (testTable .getId (), "test-row-" + i )
122- .setCell ("cf1" , ByteString .EMPTY , ByteString .copyFrom (rowBytes )));
123- futures .add (future );
124- }
125- ApiFutures .allAsList (futures ).get (3 , TimeUnit .MINUTES );
108+ testTable = createAndPopulateTestTable (tableAdmin , dataClient );
126109 }
127110
128111 @ AfterClass
@@ -266,32 +249,89 @@ public void deleteBackupTest() throws InterruptedException {
266249 @ Test
267250 public void restoreTableTest () throws InterruptedException , ExecutionException {
268251 String backupId = generateId ("restore-" + TEST_BACKUP_SUFFIX );
269- String tableId = generateId ("restored-table" );
252+ String restoredTableId = generateId ("restored-table" );
270253 tableAdmin .createBackup (createBackupRequest (backupId ));
271254
272255 // Wait 2 minutes so that the RestoreTable API will trigger an optimize restored
273256 // table operation.
274257 Thread .sleep (120 * 1000 );
275258
276259 try {
277- RestoreTableRequest req = RestoreTableRequest .of (targetCluster , backupId ).setTableId (tableId );
260+ RestoreTableRequest req =
261+ RestoreTableRequest .of (targetCluster , backupId ).setTableId (restoredTableId );
278262 RestoredTableResult result = tableAdmin .restoreTable (req );
279263 assertWithMessage ("Incorrect restored table id" )
280264 .that (result .getTable ().getId ())
281- .isEqualTo (tableId );
265+ .isEqualTo (restoredTableId );
282266
283267 if (result .getOptimizeRestoredTableOperationToken () != null ) {
284268 // The assertion might be missing if the test is running against a HDD cluster or an
285269 // optimization is not necessary.
286270 tableAdmin .awaitOptimizeRestoredTable (result .getOptimizeRestoredTableOperationToken ());
287- Table restoredTable = tableAdmin .getTable (tableId );
271+ Table restoredTable = tableAdmin .getTable (restoredTableId );
288272 assertWithMessage ("Incorrect restored table id" )
289273 .that (restoredTable .getId ())
290- .isEqualTo (tableId );
274+ .isEqualTo (restoredTableId );
291275 }
292276 } finally {
293277 tableAdmin .deleteBackup (targetCluster , backupId );
294- tableAdmin .deleteTable (tableId );
278+ tableAdmin .deleteTable (restoredTableId );
279+ }
280+ }
281+
282+ @ Test
283+ public void crossInstanceRestoreTest ()
284+ throws InterruptedException , IOException , ExecutionException , TimeoutException {
285+ String backupId = generateId ("cross-" + TEST_BACKUP_SUFFIX );
286+ String restoredTableId = generateId ("restored-table-2" );
287+
288+ // Set up a new instance to test cross-instance restore. The source backup is stored in this
289+ // instance.
290+ String sourceInstance =
291+ AbstractTestEnv .TEST_INSTANCE_PREFIX + "backup-" + Instant .now ().getEpochSecond ();
292+ String sourceCluster = AbstractTestEnv .TEST_CLUSTER_PREFIX + Instant .now ().getEpochSecond ();
293+ instanceAdmin .createInstance (
294+ CreateInstanceRequest .of (sourceInstance )
295+ .addCluster (sourceCluster , testEnvRule .env ().getSecondaryZone (), 3 , StorageType .SSD )
296+ .setDisplayName ("backups-source-test-instance" )
297+ .addLabel ("state" , "readytodelete" )
298+ .setType (Type .PRODUCTION ));
299+ BigtableTableAdminClient sourceTableAdmin =
300+ testEnvRule .env ().getTableAdminClientForInstance (sourceInstance );
301+ Table sourceTable =
302+ createAndPopulateTestTable (
303+ sourceTableAdmin , testEnvRule .env ().getDataClientForInstance (sourceInstance ));
304+ sourceTableAdmin .createBackup (
305+ CreateBackupRequest .of (sourceCluster , backupId )
306+ .setSourceTableId (sourceTable .getId ())
307+ .setExpireTime (Instant .now ().plus (Duration .ofHours (6 ))));
308+
309+ // Wait 2 minutes so that the RestoreTable API will trigger an optimize restored
310+ // table operation.
311+ Thread .sleep (120 * 1000 );
312+
313+ try {
314+ RestoreTableRequest req =
315+ RestoreTableRequest .of (sourceInstance , sourceCluster , backupId )
316+ .setTableId (restoredTableId );
317+ RestoredTableResult result = tableAdmin .restoreTable (req );
318+ assertWithMessage ("Incorrect restored table id" )
319+ .that (result .getTable ().getId ())
320+ .isEqualTo (restoredTableId );
321+ assertWithMessage ("Incorrect instance id" )
322+ .that (result .getTable ().getInstanceId ())
323+ .isEqualTo (targetInstance );
324+
325+ // The assertion might be missing if the test is running against a HDD cluster or an
326+ // optimization is not necessary.
327+ assertWithMessage ("Empty OptimizeRestoredTable token" )
328+ .that (result .getOptimizeRestoredTableOperationToken ())
329+ .isNotNull ();
330+ tableAdmin .awaitOptimizeRestoredTable (result .getOptimizeRestoredTableOperationToken ());
331+ tableAdmin .getTable (restoredTableId );
332+ } finally {
333+ sourceTableAdmin .deleteBackup (sourceCluster , backupId );
334+ instanceAdmin .deleteInstance (sourceInstance );
295335 }
296336 }
297337
@@ -327,13 +367,37 @@ public void backupIamTest() throws InterruptedException {
327367 }
328368 }
329369
330- private CreateBackupRequest createBackupRequest (String backupName ) {
331- return CreateBackupRequest .of (targetCluster , backupName )
370+ private CreateBackupRequest createBackupRequest (String backupId ) {
371+ return CreateBackupRequest .of (targetCluster , backupId )
332372 .setSourceTableId (testTable .getId ())
333373 .setExpireTime (Instant .now ().plus (Duration .ofDays (15 )));
334374 }
335375
336376 private static String generateId (String name ) {
337377 return prefix + "-" + name ;
338378 }
379+
380+ private static Table createAndPopulateTestTable (
381+ BigtableTableAdminClient tableAdmin , BigtableDataClient dataClient )
382+ throws InterruptedException , ExecutionException , TimeoutException {
383+ Table testTable =
384+ tableAdmin .createTable (
385+ CreateTableRequest .of (generateId (TEST_TABLE_SUFFIX )).addFamily ("cf1" ));
386+
387+ // Populate test data.
388+ byte [] rowBytes = new byte [1024 ];
389+ Random random = new Random ();
390+ random .nextBytes (rowBytes );
391+
392+ List <ApiFuture <?>> futures = Lists .newArrayList ();
393+ for (int i = 0 ; i < 10 ; i ++) {
394+ ApiFuture <Void > future =
395+ dataClient .mutateRowAsync (
396+ RowMutation .create (testTable .getId (), "test-row-" + i )
397+ .setCell ("cf1" , ByteString .EMPTY , ByteString .copyFrom (rowBytes )));
398+ futures .add (future );
399+ }
400+ ApiFutures .allAsList (futures ).get (3 , TimeUnit .MINUTES );
401+ return testTable ;
402+ }
339403}
0 commit comments