def validate( self, maintenance_view: MaintenanceView, maintenance: MaintenanceDefinition, node_index_to_node_view: Dict[int, NodeView], ) -> None: self.assertEqual(maintenance_view.allow_passive_drains, maintenance.allow_passive_drains) self.assertListEqual( sorted(ni.node_index for ni in maintenance_view.affected_sequencer_node_ids), sorted(sn.node_index for sn in maintenance.sequencer_nodes), ) self.assertTupleEqual( maintenance_view.affected_sequencer_node_indexes, tuple(sorted(sn.node_index for sn in maintenance.sequencer_nodes)), ) self.assertListEqual( sorted(ni.node_index for ni in maintenance_view.affected_storage_node_ids), sorted({shard.node.node_index for shard in maintenance.shards}), ) self.assertTupleEqual( maintenance_view.affected_storage_node_indexes, tuple( sorted({shard.node.node_index for shard in maintenance.shards})), ) self.assertListEqual( sorted(ni.node_index for ni in maintenance_view.affected_node_ids), sorted({sn.node_index for sn in maintenance.sequencer_nodes}.union({ shard.node.node_index for shard in maintenance.shards })), ) self.assertTupleEqual( maintenance_view.affected_node_indexes, tuple( sorted({sn.node_index for sn in maintenance.sequencer_nodes}.union({ shard.node.node_index for shard in maintenance.shards }))), ) if len(maintenance.shards) == 0: self.assertIsNone(maintenance_view.shard_target_state) else: self.assertEqual(maintenance_view.shard_target_state, maintenance.shard_target_state) if len(maintenance.sequencer_nodes) == 0: self.assertIsNone(maintenance_view.sequencer_target_state) else: self.assertEqual( maintenance_view.sequencer_target_state, maintenance.sequencer_target_state, ) if maintenance.ttl_seconds == 0: self.assertIsNone(maintenance_view.ttl) else: assert maintenance_view.ttl is not None self.assertEqual( maintenance.ttl_seconds, # pyre-fixme[16]: Optional type has no attribute `total_seconds`. maintenance_view.ttl.total_seconds(), ) if maintenance.created_on is None: self.assertIsNone(maintenance_view.created_on) else: assert maintenance_view.created_on is not None self.assertAlmostEqual( # pyre-fixme[16]: Optional type has no attribute `timestamp`. maintenance_view.created_on.timestamp() * 1000, maintenance.created_on, 1, ) if maintenance.expires_on is None: self.assertIsNone(maintenance_view.expires_on) else: assert maintenance_view.expires_on is not None self.assertAlmostEqual( maintenance_view.expires_on.timestamp() * 1000, maintenance.expires_on, 1, ) assert maintenance_view.expires_in is not None self.assertAlmostEqual( maintenance_view.expires_in.total_seconds(), # pyre-fixme[16]: Optional type has no attribute `__sub__`. (maintenance_view.expires_on - datetime.now()).total_seconds(), 1, ) self.assertEqual(maintenance_view.affects_shards, len(maintenance.shards) > 0) self.assertEqual(maintenance_view.affects_sequencers, len(maintenance.sequencer_nodes) > 0) self.assertEqual(maintenance_view.num_shards_total, len(maintenance.shards)) self.assertEqual(maintenance_view.num_sequencers_total, len(maintenance.sequencer_nodes)) for shard in maintenance.shards: assert shard.node.node_index is not None self.assertEqual( # pyre-fixme[6]: Expected `int` for 1st param but got `Optional[int]`. node_index_to_node_view[shard.node.node_index ].shard_states[shard.shard_index], maintenance_view.get_shard_state(shard), ) for sn in maintenance.sequencer_nodes: assert sn.node_index is not None self.assertEqual( # pyre-fixme[6]: Expected `int` for 1st param but got `Optional[int]`. node_index_to_node_view[sn.node_index].sequencer_state, maintenance_view.get_sequencer_state(sn), ) self.assertSetEqual(set(maintenance.shards), set(maintenance_view.shards)) for node_index in { shard.node.node_index for shard in maintenance.shards }: assert node_index is not None shards = { shard for shard in maintenance.shards if shard.node.node_index == node_index } self.assertSetEqual( shards, set(maintenance_view.get_shards_by_node_index(node_index)))
def validate( self, maintenance_view: MaintenanceView, maintenance: MaintenanceDefinition, node_index_to_node_view: Dict[int, NodeView], ) -> None: self.assertEqual( maintenance_view.allow_passive_drains, maintenance.allow_passive_drains ) self.assertListEqual( sorted( # pyre-fixme[6]: Expected `Iterable[Variable[_LT (bound to # _SupportsLessThan)]]` for 1st param but got # `Generator[typing.Optional[int], None, None]`. ni.node_index for ni in maintenance_view.affected_sequencer_node_ids ), # pyre-fixme[6]: Expected `Iterable[Variable[_LT (bound to # _SupportsLessThan)]]` for 1st param but got # `Generator[typing.Optional[int], None, None]`. sorted(sn.node_index for sn in maintenance.sequencer_nodes), ) self.assertTupleEqual( maintenance_view.affected_sequencer_node_indexes, # pyre-fixme[6]: Expected `Iterable[Variable[_LT (bound to # _SupportsLessThan)]]` for 1st param but got # `Generator[typing.Optional[int], None, None]`. tuple(sorted(sn.node_index for sn in maintenance.sequencer_nodes)), ) self.assertListEqual( # pyre-fixme[6]: Expected `Iterable[Variable[_LT (bound to # _SupportsLessThan)]]` for 1st param but got # `Generator[typing.Optional[int], None, None]`. sorted(ni.node_index for ni in maintenance_view.affected_storage_node_ids), # pyre-fixme[6]: Expected `Iterable[Variable[_LT (bound to # _SupportsLessThan)]]` for 1st param but got `Set[typing.Optional[int]]`. sorted({shard.node.node_index for shard in maintenance.shards}), ) self.assertTupleEqual( maintenance_view.affected_storage_node_indexes, # pyre-fixme[6]: Expected `Iterable[Variable[_LT (bound to # _SupportsLessThan)]]` for 1st param but got `Set[typing.Optional[int]]`. tuple(sorted({shard.node.node_index for shard in maintenance.shards})), ) self.assertListEqual( # pyre-fixme[6]: Expected `Iterable[Variable[_LT (bound to # _SupportsLessThan)]]` for 1st param but got # `Generator[typing.Optional[int], None, None]`. sorted(ni.node_index for ni in maintenance_view.affected_node_ids), sorted( # pyre-fixme[6]: Expected `Iterable[Variable[_LT (bound to # _SupportsLessThan)]]` for 1st param but got # `Set[typing.Optional[int]]`. {sn.node_index for sn in maintenance.sequencer_nodes}.union( {shard.node.node_index for shard in maintenance.shards} ) ), ) self.assertTupleEqual( maintenance_view.affected_node_indexes, tuple( sorted( # pyre-fixme[6]: Expected `Iterable[Variable[_LT (bound to # _SupportsLessThan)]]` for 1st param but got # `Set[typing.Optional[int]]`. {sn.node_index for sn in maintenance.sequencer_nodes}.union( {shard.node.node_index for shard in maintenance.shards} ) ) ), ) if len(maintenance.shards) == 0: self.assertIsNone(maintenance_view.shard_target_state) else: self.assertEqual( maintenance_view.shard_target_state, maintenance.shard_target_state ) if len(maintenance.sequencer_nodes) == 0: self.assertIsNone(maintenance_view.sequencer_target_state) else: self.assertEqual( maintenance_view.sequencer_target_state, maintenance.sequencer_target_state, ) if maintenance.ttl_seconds == 0: self.assertIsNone(maintenance_view.ttl) else: assert maintenance_view.ttl is not None self.assertEqual( maintenance.ttl_seconds, # pyre-fixme[16]: Optional type has no attribute `total_seconds`. maintenance_view.ttl.total_seconds(), ) if maintenance.created_on is None: self.assertIsNone(maintenance_view.created_on) else: assert maintenance_view.created_on is not None self.assertAlmostEqual( # pyre-fixme[16]: Optional type has no attribute `timestamp`. maintenance_view.created_on.timestamp() * 1000, maintenance.created_on, 1, ) if maintenance.expires_on is None: self.assertIsNone(maintenance_view.expires_on) else: # pull these into local vars to appease pyre view_expires_on = maintenance_view.expires_on view_expires_in = maintenance_view.expires_in assert view_expires_on is not None self.assertAlmostEqual( view_expires_on.timestamp() * 1000, maintenance.expires_on, 1 ) assert view_expires_in is not None self.assertAlmostEqual( view_expires_in.total_seconds(), (view_expires_on - datetime.now()).total_seconds(), 1, ) self.assertEqual(maintenance_view.affects_shards, len(maintenance.shards) > 0) self.assertEqual( maintenance_view.affects_sequencers, len(maintenance.sequencer_nodes) > 0 ) self.assertEqual(maintenance_view.num_shards_total, len(maintenance.shards)) self.assertEqual( maintenance_view.num_sequencers_total, len(maintenance.sequencer_nodes) ) for shard in maintenance.shards: assert shard.node.node_index is not None self.assertEqual( node_index_to_node_view[shard.node.node_index].shard_states[ shard.shard_index ], maintenance_view.get_shard_state(shard), ) for sn in maintenance.sequencer_nodes: assert sn.node_index is not None self.assertEqual( node_index_to_node_view[sn.node_index].sequencer_state, maintenance_view.get_sequencer_state(sn), ) self.assertSetEqual(set(maintenance.shards), set(maintenance_view.shards)) for node_index in {shard.node.node_index for shard in maintenance.shards}: assert node_index is not None shards = { shard for shard in maintenance.shards if shard.node.node_index == node_index } self.assertSetEqual( shards, set(maintenance_view.get_shards_by_node_index(node_index)) )