@Override
    public List<String> listPartitionNames(String databaseName, String tableName, TableVersionRange version) {
        updatePartitionInfo(databaseName, tableName);
        return new ArrayList<>(this.partitionInfos.keySet());
    }
@Test
    public void testListPartitionNames(@Mocked FileStoreTable mockPaimonTable,
                                       @Mocked PartitionsTable mockPartitionTable,
                                       @Mocked RecordReader<InternalRow> mockRecordReader)
            throws Catalog.TableNotExistException, IOException {

        RowType tblRowType = RowType.of(
                new DataType[] {
                        new IntType(true),
                        new IntType(true)
                },
                new String[] {"year", "month"});

        List<String> partitionNames = Lists.newArrayList("year", "month");

        Identifier tblIdentifier = new Identifier("db1", "tbl1");
        Identifier partitionTblIdentifier = new Identifier("db1", "tbl1$partitions");

        RowType partitionRowType = new RowType(
                Arrays.asList(
                        new DataField(0, "partition", SerializationUtils.newStringType(true)),
                        new DataField(1, "record_count", new BigIntType(false)),
                        new DataField(2, "file_size_in_bytes", new BigIntType(false)),
                        new DataField(3, "file_count", new BigIntType(false)),
                        new DataField(4, "last_update_time", DataTypes.TIMESTAMP_MILLIS())
                ));

        GenericRow row1 = new GenericRow(2);
        row1.setField(0, BinaryString.fromString("[2020, 1]"));
        row1.setField(1, Timestamp.fromLocalDateTime(LocalDateTime.of(2023, 1, 1, 0, 0, 0, 0)));

        GenericRow row2 = new GenericRow(2);
        row2.setField(0, BinaryString.fromString("[2020, 2]"));
        row2.setField(1, Timestamp.fromLocalDateTime(LocalDateTime.of(2023, 2, 1, 0, 0, 0, 0)));
        new MockUp<RecordReaderIterator>() {
            private int callCount;
            private final GenericRow[] elements = {row1, row2};
            private final boolean[] hasNextOutputs = {true, true, false};

            @Mock
            public boolean hasNext() {
                if (callCount < hasNextOutputs.length) {
                    return hasNextOutputs[callCount];
                }
                return false;
            }

            @Mock
            public InternalRow next() {
                if (callCount < elements.length) {
                    return elements[callCount++];
                }
                return null;
            }
        };

        new Expectations() {
            {
                paimonNativeCatalog.getTable(tblIdentifier);
                result = mockPaimonTable;
                mockPaimonTable.partitionKeys();
                result = partitionNames;
                mockPaimonTable.rowType();
                result = tblRowType;
                paimonNativeCatalog.getTable(partitionTblIdentifier);
                result = mockPartitionTable;
                mockPartitionTable.rowType();
                result = partitionRowType;

                mockPartitionTable.newReadBuilder().withProjection((int[]) any).newRead().createReader((TableScan.Plan) any);
                result = mockRecordReader;
            }
        };
        List<String> result = metadata.listPartitionNames("db1", "tbl1", TableVersionRange.empty());
        Assert.assertEquals(2, result.size());
        List<String> expections = Lists.newArrayList("year=2020/month=1", "year=2020/month=2");
        Assertions.assertThat(result).hasSameElementsAs(expections);
    }