private List<String> getSnapshotInfo(String snapshotName, String timestamp) {
        List<String> info = Lists.newArrayList();
        if (Strings.isNullOrEmpty(timestamp)) {
            // get all timestamp
            // path eg: /location/__starrocks_repository_repo_name/__ss_my_snap/__info_*
            String infoFilePath = assembleJobInfoFilePath(snapshotName, -1);
            LOG.debug("assemble infoFilePath: {}, snapshot: {}", infoFilePath, snapshotName);
            List<RemoteFile> results = Lists.newArrayList();
            Status st = storage.list(infoFilePath + "*", results);
            if (!st.ok()) {
                info.add(snapshotName);
                info.add(FeConstants.NULL_STRING);
                info.add("ERROR: Failed to get info: " + st.getErrMsg());
            } else {
                info.add(snapshotName);

                List<String> tmp = Lists.newArrayList();
                for (RemoteFile file : results) {
                    // __info_2018-04-18-20-11-00.Jdwnd9312sfdn1294343
                    Pair<String, String> pureFileName = decodeFileNameWithChecksum(file.getName());
                    if (pureFileName == null) {
                        // maybe: __info_2018-04-18-20-11-00.part
                        tmp.add("Invalid: " + file.getName());
                        continue;
                    }
                    tmp.add(disjoinPrefix(PREFIX_JOB_INFO, pureFileName.first));
                }
                info.add(Joiner.on("\n").join(tmp));
                info.add(tmp.isEmpty() ? "ERROR: no snapshot" : "OK");
            }
        } else {
            // get specified timestamp
            // path eg: /path/to/backup/__info_2081-04-19-12-59-11
            String localFilePath = BackupHandler.BACKUP_ROOT_DIR + "/" + Repository.PREFIX_JOB_INFO + timestamp;
            try {
                String remoteInfoFilePath = assembleJobInfoFilePath(snapshotName, -1) + timestamp;
                Status st = download(remoteInfoFilePath, localFilePath);
                if (!st.ok()) {
                    info.add(snapshotName);
                    info.add(timestamp);
                    info.add(FeConstants.NULL_STRING);
                    info.add(FeConstants.NULL_STRING);
                    info.add("Failed to get info: " + st.getErrMsg());
                } else {
                    try {
                        BackupJobInfo jobInfo = BackupJobInfo.fromFile(localFilePath);
                        info.add(snapshotName);
                        info.add(timestamp);
                        info.add(jobInfo.dbName);
                        info.add(jobInfo.getBrief());
                        info.add("OK");
                    } catch (IOException e) {
                        info.add(snapshotName);
                        info.add(timestamp);
                        info.add(FeConstants.NULL_STRING);
                        info.add(FeConstants.NULL_STRING);
                        info.add("Failed to read info from local file: " + e.getMessage());
                    }
                }
            } finally {
                // delete tmp local file
                File localFile = new File(localFilePath);
                if (localFile.exists()) {
                    if (!localFile.delete()) {
                        LOG.warn("Failed to delete file, filepath={}", localFile.getAbsolutePath());
                    }
                }
            }
        }

        return info;
    }
@Test
    public void testGetSnapshotInfo() {
        new Expectations() {
            {
                storage.list(anyString, (List<RemoteFile>) any);
                minTimes = 0;
                result = new Delegate() {
                    public Status list(String remotePath, List<RemoteFile> result) {
                        if (remotePath.contains(Repository.PREFIX_JOB_INFO)) {
                            result.add(new RemoteFile(" __info_2018-04-18-20-11-00.12345678123456781234567812345678",
                                    true,
                                    100));
                        } else {
                            result.add(new RemoteFile(Repository.PREFIX_SNAPSHOT_DIR + "s1", false, 100));
                            result.add(new RemoteFile(Repository.PREFIX_SNAPSHOT_DIR + "s2", false, 100));
                        }
                        return Status.OK;
                    }
                };
            }
        };

        repo = new Repository(10000, "repo", false, location, storage);
        String snapshotName = "";
        String timestamp = "";
        try {
            List<List<String>> infos = repo.getSnapshotInfos(snapshotName, timestamp, null);
            Assert.assertEquals(2, infos.size());

        } catch (SemanticException e) {
            e.printStackTrace();
            Assert.fail();
        }
    }