public async Task TestAlterRangeParitioningInvalid() { // Create initial table with single range partition covering [0, 100). KuduTable table = await CreateTableAsync((0, 100)); await InsertRowsAsync(table, 0, 100); Assert.Equal(100, await ClientTestUtil.CountRowsAsync(_client, table)); // ADD [0, 100) <- already present (duplicate) var ex = await Assert.ThrowsAsync <NonRecoverableException>(async() => { await _client.AlterTableAsync(new AlterTableBuilder(table) .AddRangePartition((lower, upper) => { lower.SetInt32("c0", 0); upper.SetInt32("c0", 100); })); }); Assert.True(ex.Status.IsAlreadyPresent); Assert.Contains("range partition already exists", ex.Status.Message); Assert.Equal(100, await ClientTestUtil.CountRowsAsync(_client, table)); // ADD [50, 150) <- illegal (overlap) ex = await Assert.ThrowsAsync <NonRecoverableException>(async() => { await _client.AlterTableAsync(new AlterTableBuilder(table) .AddRangePartition((lower, upper) => { lower.SetInt32("c0", 50); upper.SetInt32("c0", 150); })); }); Assert.True(ex.Status.IsInvalidArgument); Assert.Contains("new range partition conflicts with existing one", ex.Status.Message); Assert.Equal(100, await ClientTestUtil.CountRowsAsync(_client, table)); // ADD [-50, 50) <- illegal (overlap) ex = await Assert.ThrowsAsync <NonRecoverableException>(async() => { await _client.AlterTableAsync(new AlterTableBuilder(table) .AddRangePartition((lower, upper) => { lower.SetInt32("c0", -50); upper.SetInt32("c0", 50); })); }); Assert.True(ex.Status.IsInvalidArgument); Assert.Contains("new range partition conflicts with existing one", ex.Status.Message); Assert.Equal(100, await ClientTestUtil.CountRowsAsync(_client, table)); // ADD [200, 300) // ADD [-50, 150) <- illegal (overlap) ex = await Assert.ThrowsAsync <NonRecoverableException>(async() => { await _client.AlterTableAsync(new AlterTableBuilder(table) .AddRangePartition((lower, upper) => { lower.SetInt32("c0", 200); upper.SetInt32("c0", 300); }) .AddRangePartition((lower, upper) => { lower.SetInt32("c0", -50); upper.SetInt32("c0", 150); })); }); Assert.True(ex.Status.IsInvalidArgument); Assert.Contains("new range partition conflicts with existing one", ex.Status.Message); Assert.Equal(100, await ClientTestUtil.CountRowsAsync(_client, table)); // DROP [<start>, <end>) ex = await Assert.ThrowsAsync <NonRecoverableException>(async() => { await _client.AlterTableAsync(new AlterTableBuilder(table) .DropRangePartition((lower, upper) => { })); }); Assert.True(ex.Status.IsInvalidArgument); Assert.Contains("no range partition to drop", ex.Status.Message); Assert.Equal(100, await ClientTestUtil.CountRowsAsync(_client, table)); // DROP [50, 150) // RENAME foo ex = await Assert.ThrowsAsync <NonRecoverableException>(async() => { await _client.AlterTableAsync(new AlterTableBuilder(table) .DropRangePartition((lower, upper) => { lower.SetInt32("c0", 50); upper.SetInt32("c0", 150); }) .RenameTable("foo")); }); Assert.True(ex.Status.IsInvalidArgument); Assert.Contains("no range partition to drop", ex.Status.Message); Assert.Equal(100, await ClientTestUtil.CountRowsAsync(_client, table)); Assert.Empty(await _client.GetTablesAsync("foo")); // DROP [0, 100) // ADD [100, 200) // DROP [100, 200) // ADD [150, 250) // DROP [0, 10) <- illegal ex = await Assert.ThrowsAsync <NonRecoverableException>(async() => { await _client.AlterTableAsync(new AlterTableBuilder(table) .DropRangePartition((lower, upper) => { lower.SetInt32("c0", 0); upper.SetInt32("c0", 100); }) .AddRangePartition((lower, upper) => { lower.SetInt32("c0", 100); upper.SetInt32("c0", 200); }) .DropRangePartition((lower, upper) => { lower.SetInt32("c0", 100); upper.SetInt32("c0", 200); }) .AddRangePartition((lower, upper) => { lower.SetInt32("c0", 150); upper.SetInt32("c0", 250); }) .DropRangePartition((lower, upper) => { lower.SetInt32("c0", 0); upper.SetInt32("c0", 10); })); }); Assert.True(ex.Status.IsInvalidArgument); Assert.Contains("no range partition to drop", ex.Status.Message); Assert.Equal(100, await ClientTestUtil.CountRowsAsync(_client, table)); }