def test_plan_partition_changes_long_delay(self): planned = _plan_partition_changes( MockDatabase(), Table("table"), [ mkPPart("p_20210101", 100), mkPPart("p_20210415", 200), mkTailPart("future"), ], mkPos(50), datetime(2021, 3, 31, tzinfo=timezone.utc), timedelta(days=7), 2, ) self.assertEqual( planned, [ ChangePlannedPartition(mkPPart("p_20210101", 100)), ChangePlannedPartition(mkPPart( "p_20210415", 200)).set_timestamp( datetime(2021, 6, 28, tzinfo=timezone.utc)).set_important(), ChangePlannedPartition(mkTailPart("future")).set_timestamp( datetime(2021, 7, 5, tzinfo=timezone.utc)), ], )
def test_plan_partition_changes_misprediction(self): """ We have to handle the case where the partition list doesn't cleanly match reality. """ self.maxDiff = None planned = _plan_partition_changes( MockDatabase(), Table("table"), [ mkPPart("p_20210505", 9505010028), mkPPart("p_20210604", 10152257517), mkPPart("p_20210704", 10799505006), mkTailPart("p_20210803"), ], mkPos(10264818175), datetime(2021, 6, 8, tzinfo=timezone.utc), timedelta(days=30), 3, ) self.assertEqual( planned, [ ChangePlannedPartition(mkPPart("p_20210704", 10799505006)), ChangePlannedPartition(mkTailPart("p_20210803")).set_position([ 11578057459 ]).set_timestamp(datetime(2021, 6, 28, tzinfo=timezone.utc)), NewPlannedPartition().set_position( [12356609912]).set_timestamp( datetime(2021, 7, 28, tzinfo=timezone.utc)), NewPlannedPartition().set_columns(1).set_timestamp( datetime(2021, 8, 27, tzinfo=timezone.utc)), ], )
def test_plan_partition_changes_bespoke_names(self): planned = _plan_partition_changes( MockDatabase(), Table("table"), [mkPPart("p_start", 100), mkTailPart("p_future")], mkPos(50), datetime(2021, 1, 6, tzinfo=timezone.utc), timedelta(days=7), 2, ) self.assertEqual( planned, [ ChangePlannedPartition(mkPPart("p_start", 100)), ChangePlannedPartition(mkTailPart("p_future")).set_position([ 170 ]).set_timestamp(datetime(2021, 1, 8, tzinfo=timezone.utc)), NewPlannedPartition().set_columns(1).set_timestamp( datetime(2021, 1, 15, tzinfo=timezone.utc)), ], ) output = list( generate_sql_reorganize_partition_commands(Table("table"), planned)) self.assertEqual( output, [ "ALTER TABLE `table` REORGANIZE PARTITION `p_future` INTO " "(PARTITION `p_20210108` VALUES LESS THAN (170), " "PARTITION `p_20210115` VALUES LESS THAN MAXVALUE);" ], )
def test_plan_partition_changes(self): self.maxDiff = None planned = _plan_partition_changes( MockDatabase(), Table("table"), [ mkPPart("p_20201231", 100), mkPPart("p_20210102", 200), mkTailPart("future"), ], mkPos(50), datetime(2021, 1, 1, tzinfo=timezone.utc), timedelta(days=7), 2, ) self.assertEqual( planned, [ ChangePlannedPartition(mkPPart("p_20201231", 100)), ChangePlannedPartition(mkPPart("p_20210102", 200)), ChangePlannedPartition(mkTailPart("future")).set_timestamp( datetime(2021, 1, 4, tzinfo=timezone.utc)), ], ) self.assertEqual( _plan_partition_changes( MockDatabase(), Table("table"), [ mkPPart("p_20201231", 100), mkPPart("p_20210102", 200), mkTailPart("future"), ], mkPos(199), datetime(2021, 1, 3, tzinfo=timezone.utc), timedelta(days=7), 3, ), [ ChangePlannedPartition(mkPPart("p_20210102", 200)).set_position([200]), ChangePlannedPartition(mkTailPart("future")).set_position([ 320 ]).set_timestamp(datetime(2021, 1, 3, tzinfo=timezone.utc)), NewPlannedPartition().set_position([440]).set_timestamp( datetime(2021, 1, 10, tzinfo=timezone.utc)), NewPlannedPartition().set_columns(1).set_timestamp( datetime(2021, 1, 17, tzinfo=timezone.utc)), ], )
def testgenerate_sql_reorganize_partition_commands_maintain_new_partition( self): self.assertEqual( list( generate_sql_reorganize_partition_commands( Table("table"), [ ChangePlannedPartition( mkTailPart("future")).set_position([ 800 ]).set_timestamp( datetime(2021, 1, 14, tzinfo=timezone.utc)), NewPlannedPartition().set_position( [1000]).set_timestamp( datetime(2021, 1, 16, tzinfo=timezone.utc)), NewPlannedPartition().set_position( [1200]).set_timestamp( datetime(2021, 1, 23, tzinfo=timezone.utc)), NewPlannedPartition().set_columns(1).set_timestamp( datetime(2021, 1, 30, tzinfo=timezone.utc)), ], )), [ "ALTER TABLE `table` REORGANIZE PARTITION `future` INTO " "(PARTITION `p_20210114` VALUES LESS THAN (800), " "PARTITION `p_20210116` VALUES LESS THAN (1000), " "PARTITION `p_20210123` VALUES LESS THAN (1200), " "PARTITION `p_20210130` VALUES LESS THAN MAXVALUE);" ], )
def testgenerate_sql_reorganize_partition_commands_no_change(self): self.assertEqual( list( generate_sql_reorganize_partition_commands( Table("table"), [ChangePlannedPartition(mkPPart("p_20210102", 200))])), [], )
def test_plan_partition_changes_imminent(self): with self.assertLogs("plan_partition_changes:table", level="INFO") as logctx: planned = _plan_partition_changes( MockDatabase(), Table("table"), [ mkPPart("p_20201231", 100), mkPPart("p_20210102", 200), mkTailPart("future"), ], mkPos(50), datetime(2021, 1, 1, hour=23, minute=55, tzinfo=timezone.utc), timedelta(days=2), 3, ) self.assertEqual( logctx.output, [ "INFO:plan_partition_changes:table:Start-of-fill predicted at " "2021-01-03 which is not 2021-01-02. This change will be marked " "as important to ensure that p_20210102: (200) is moved to " "2021-01-03" ], ) self.assertEqual( planned, [ ChangePlannedPartition(mkPPart("p_20201231", 100)), ChangePlannedPartition(mkPPart( "p_20210102", 200)).set_timestamp( datetime(2021, 1, 3, tzinfo=timezone.utc)).set_important(), ChangePlannedPartition(mkTailPart("future")).set_position([ 250 ]).set_timestamp(datetime(2021, 1, 5, tzinfo=timezone.utc)), NewPlannedPartition().set_columns(1).set_timestamp( datetime(2021, 1, 7, tzinfo=timezone.utc)), ], )
def test_plan_partition_changes_short_names(self): self.maxDiff = None planned = _plan_partition_changes( MockDatabase(), Table("table"), [ mkPPart("p_2019", 1912499867), mkPPart("p_2020", 8890030931), mkPPart("p_20210125", 12010339136), mkTailPart("p_future"), ], mkPos(10810339136), datetime(2021, 1, 30, tzinfo=timezone.utc), timedelta(days=7), 2, ) self.assertEqual( planned, [ ChangePlannedPartition(mkPPart( "p_20210125", 12010339136)).set_position([12010339136]), ChangePlannedPartition(mkTailPart("p_future")).set_position([ 12960433003 ]).set_timestamp(datetime(2021, 2, 1, tzinfo=timezone.utc)), NewPlannedPartition().set_columns(1).set_timestamp( datetime(2021, 2, 8, tzinfo=timezone.utc)), ], ) output = list( generate_sql_reorganize_partition_commands(Table("table"), planned)) self.assertEqual( output, [ "ALTER TABLE `table` REORGANIZE PARTITION `p_future` INTO " "(PARTITION `p_20210201` VALUES LESS THAN (12960433003), " "PARTITION `p_20210208` VALUES LESS THAN MAXVALUE);" ], )
def testgenerate_sql_reorganize_partition_commands_out_of_order(self): with self.assertRaises(AssertionError): list( generate_sql_reorganize_partition_commands( Table("table_with_out_of_order_changeset"), [ ChangePlannedPartition( mkTailPart("past")).set_position([ 800 ]).set_timestamp( datetime(2021, 1, 14, tzinfo=timezone.utc)), NewPlannedPartition().set_position( [1000]).set_timestamp( datetime(2021, 1, 15, tzinfo=timezone.utc)), ChangePlannedPartition( mkTailPart("future")).set_position([ 1200 ]).set_timestamp( datetime(2021, 1, 16, tzinfo=timezone.utc)), ], ))
def test_plan_partition_changes_wildly_off_dates(self): with self.assertLogs("plan_partition_changes:table", level="INFO") as logctx: planned = _plan_partition_changes( MockDatabase(), Table("table"), [ mkPPart("p_20201231", 100), mkPPart("p_20210104", 200), mkTailPart("future"), ], mkPos(50), datetime(2021, 1, 1, tzinfo=timezone.utc), timedelta(days=7), 2, ) self.assertEqual( logctx.output, [ "INFO:plan_partition_changes:table:Start-of-fill predicted at " "2021-01-02 which is not 2021-01-04. This change will be marked " "as important to ensure that p_20210104: (200) is moved to " "2021-01-02" ], ) self.assertEqual( [ ChangePlannedPartition(mkPPart("p_20201231", 100)), ChangePlannedPartition(mkPPart( "p_20210104", 200)).set_timestamp( datetime(2021, 1, 2, tzinfo=timezone.utc)).set_important(), ChangePlannedPartition(mkTailPart("future")).set_timestamp( datetime(2021, 1, 5, tzinfo=timezone.utc)), ], planned, )
def testgenerate_sql_reorganize_partition_commands_two_changes(self): self.assertEqual( list( generate_sql_reorganize_partition_commands( Table("table"), [ ChangePlannedPartition(mkPPart( "p_20210102", 200)).set_position([500]).set_timestamp( datetime(2021, 1, 16, tzinfo=timezone.utc)), ChangePlannedPartition(mkPPart( "p_20210120", 1000)).set_position([2000]).set_timestamp( datetime(2021, 2, 14, tzinfo=timezone.utc)), ], )), [ "ALTER TABLE `table` REORGANIZE PARTITION `p_20210120` INTO " "(PARTITION `p_20210214` VALUES LESS THAN (2000));", "ALTER TABLE `table` REORGANIZE PARTITION `p_20210102` INTO " "(PARTITION `p_20210116` VALUES LESS THAN (500));", ], )
def testgenerate_sql_reorganize_partition_commands_with_duplicate(self): with self.assertRaises(DuplicatePartitionException): list( generate_sql_reorganize_partition_commands( Table("table_with_duplicate"), [ ChangePlannedPartition( mkTailPart("future")).set_position([ 800 ]).set_timestamp( datetime(2021, 1, 14, tzinfo=timezone.utc)), NewPlannedPartition().set_position( [1000]).set_timestamp( datetime(2021, 1, 14, tzinfo=timezone.utc)), NewPlannedPartition().set_position( [1200]).set_timestamp( datetime(2021, 1, 15, tzinfo=timezone.utc)), ], ))
def testgenerate_sql_reorganize_partition_commands_new_partitions(self): self.assertEqual( list( generate_sql_reorganize_partition_commands( Table("table"), [ ChangePlannedPartition(mkPPart("p_20210102", 200)), NewPlannedPartition().set_position( [542]).set_timestamp( datetime(2021, 1, 16, tzinfo=timezone.utc)), NewPlannedPartition().set_position( [662]).set_timestamp( datetime(2021, 1, 23, tzinfo=timezone.utc)), ], )), [ "ALTER TABLE `table` REORGANIZE PARTITION `p_20210102` INTO " "(PARTITION `p_20210102` VALUES LESS THAN (200), " "PARTITION `p_20210116` VALUES LESS THAN (542), " "PARTITION `p_20210123` VALUES LESS THAN (662));" ], )
def test_should_run_changes(self): self.assertFalse( _should_run_changes( Table("table"), [ ChangePlannedPartition(mkPPart("p_20210102", 200)).set_position([300]) ], )) self.assertFalse( _should_run_changes( Table("table"), [ ChangePlannedPartition(mkPPart("p_20210102", 200)).set_position([300]), ChangePlannedPartition(mkPPart("p_20210109", 1000)).set_position([1300]), ], )) with self.assertLogs("should_run_changes:table", level="DEBUG") as logctx: self.assertTrue( _should_run_changes( Table("table"), [ ChangePlannedPartition(mkPPart( "p_20210102", 200)).set_position([302]), ChangePlannedPartition( mkTailPart("future")).set_position( [422]).set_timestamp( datetime(2021, 1, 9, tzinfo=timezone.utc)), NewPlannedPartition().set_position( [542]).set_timestamp( datetime(2021, 1, 16, tzinfo=timezone.utc)), NewPlannedPartition().set_position( [662]).set_timestamp( datetime(2021, 1, 23, tzinfo=timezone.utc)), ], )) self.assertEqual( logctx.output, [ "DEBUG:should_run_changes:table:Add: [542] 2021-01-16 " "00:00:00+00:00 is new" ], ) with self.assertLogs("should_run_changes:table", level="DEBUG") as logctx: self.assertTrue( _should_run_changes( Table("table"), [ ChangePlannedPartition(mkPPart("p_20210102", 200)), NewPlannedPartition().set_position( [542]).set_timestamp( datetime(2021, 1, 16, tzinfo=timezone.utc)), NewPlannedPartition().set_position( [662]).set_timestamp( datetime(2021, 1, 23, tzinfo=timezone.utc)), ], )) self.assertEqual( logctx.output, [ "DEBUG:should_run_changes:table:Add: [542] 2021-01-16 " "00:00:00+00:00 is new" ], )