@Override
    public TopicAssignment place(
        PlacementSpec placement,
        ClusterDescriber cluster
    ) throws InvalidReplicationFactorException {
        RackList rackList = new RackList(random, cluster.usableBrokers());
        throwInvalidReplicationFactorIfNonPositive(placement.numReplicas());
        throwInvalidReplicationFactorIfZero(rackList.numUnfencedBrokers());
        throwInvalidReplicationFactorIfTooFewBrokers(placement.numReplicas(),
            rackList.numTotalBrokers());
        List<List<Integer>> placements = new ArrayList<>(placement.numPartitions());
        for (int partition = 0; partition < placement.numPartitions(); partition++) {
            placements.add(rackList.place(placement.numReplicas()));
        }
        return new TopicAssignment(
            placements.stream().map(replicas -> new PartitionAssignment(replicas, cluster)).collect(Collectors.toList())
        );
    }
@Test
    public void testRackListWithMultipleRacks() {
        MockRandom random = new MockRandom();
        RackList rackList = new RackList(random, Arrays.asList(
            new UsableBroker(11, Optional.of("1"), false),
            new UsableBroker(10, Optional.of("1"), false),
            new UsableBroker(30, Optional.of("3"), false),
            new UsableBroker(31, Optional.of("3"), false),
            new UsableBroker(21, Optional.of("2"), false),
            new UsableBroker(20, Optional.of("2"), true)).iterator());
        assertEquals(6, rackList.numTotalBrokers());
        assertEquals(5, rackList.numUnfencedBrokers());
        assertEquals(Arrays.asList(Optional.of("1"), Optional.of("2"), Optional.of("3")), rackList.rackNames());
        assertEquals(Arrays.asList(11, 21, 31, 10), rackList.place(4));
        assertEquals(Arrays.asList(21, 30, 10, 20), rackList.place(4));
        assertEquals(Arrays.asList(31, 11, 21, 30), rackList.place(4));
    }