com.tascape.qa.th.Utils.java Source code

Java tutorial

Introduction

Here is the source code for com.tascape.qa.th.Utils.java

Source

/*
 * Copyright 2015.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.tascape.qa.th;

import java.awt.AWTException;
import java.awt.Desktop;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.nio.file.Paths;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import javax.imageio.ImageIO;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Appender;
import org.apache.log4j.FileAppender;
import org.apache.log4j.Level;
import org.apache.log4j.PatternLayout;
import org.apache.log4j.spi.Filter;
import org.apache.log4j.spi.LoggingEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Collection of utility methods.
 * <p>
 * @author linsong wang
 */
public class Utils {
    private static final Logger LOG = LoggerFactory.getLogger(Utils.class);

    public static final String PASS = Utils.class + "_PASS";

    public static final String FAIL = Utils.class + "_FAIL";

    private static final String DATE_TIME_FORMAT = "yyyy-MM-dd' 'HH:mm:ss.SSS";

    private static final String TIME_FORMAT = "HH:mm:ss.SSS";

    private static final String DATE_TIME_STRING = "yyyy_MM_dd_HH_mm_ss_SSS";

    /**
     * system specific file path separator, "/" for Linux, and "\" for Windows, etc
     */
    public static final String FS = System.getProperty("file.separator");

    public static void openFile(File file) {
        Desktop desktop = Desktop.getDesktop();
        try {
            desktop.open(file);
        } catch (IOException ex) {
            LOG.warn("Cannot open file {}", file, ex);
        }
    }

    private Utils() throws UnsupportedOperationException {
        throw new UnsupportedOperationException("Please use Utils.method");
    }

    public static String formatDateTime(long milliSinceEpoch) {
        return new SimpleDateFormat(DATE_TIME_FORMAT).format(new Date(milliSinceEpoch));
    }

    public static String formatTime(long milliSinceEpoch) {
        return new SimpleDateFormat(TIME_FORMAT).format(new Date(milliSinceEpoch));
    }

    public static String formatTime(long milliSinceEpoch, String format) {
        DateFormat formatter = new SimpleDateFormat(format);
        return formatter.format(new Date(milliSinceEpoch));
    }

    public static String getCurrentTime() {
        return new SimpleDateFormat(DATE_TIME_STRING).format(System.currentTimeMillis());
    }

    public static String getCurrentTime(String format) {
        DateFormat formatter = new SimpleDateFormat(format);
        return formatter.format(new Date());
    }

    public static String addLog4jFileAppender(String file) throws IOException {
        org.apache.log4j.Logger rootLogger = org.apache.log4j.Logger.getRootLogger();

        String pattern = "%d{HH:mm:ss.SSS} %-5p %t %C{1}.%M:%L - %m%n";
        final String threadName = Thread.currentThread().getName();

        class ThreadFilter extends Filter {
            @Override
            public int decide(LoggingEvent event) {
                if (event.getThreadName().startsWith(threadName)) {
                    return Filter.ACCEPT;
                }
                return Filter.DENY;
            }
        }

        FileAppender fa = new FileAppender(new PatternLayout(pattern), file);
        fa.addFilter(new ThreadFilter());
        fa.setThreshold(Level.DEBUG);

        fa.setImmediateFlush(true);
        fa.setAppend(true);
        fa.setName(file);

        fa.activateOptions();
        rootLogger.addAppender(fa);

        return file;
    }

    public static void removeLog4jAppender(String appenderName) {
        if (appenderName == null) {
            LOG.warn("Appender name is null");
            return;
        }
        org.apache.log4j.Logger rootLogger = org.apache.log4j.Logger.getRootLogger();
        Appender appender = rootLogger.getAppender(appenderName);
        if (appender != null) {
            appender.close();
            rootLogger.removeAppender(appender);
        }
    }

    /**
     * Executes command, and waits for the expected phrase in console printout.
     *
     * @param command command line
     *
     * @return console output as a list of strings
     *
     * @throws IOException          for command error
     * @throws InterruptedException when interrupted
     */
    public static List<String> cmd(String command) throws IOException, InterruptedException {
        return cmd(command.split(" "));
    }

    /**
     * Executes command, and waits for the expected phrase in console printout.
     *
     * @param command command line
     *
     * @return console output as a list of strings
     *
     * @throws IOException          for command error
     * @throws InterruptedException when interrupted
     */
    public static List<String> cmd(String[] command) throws IOException, InterruptedException {
        return cmd(command, null, null, 300000L, null);
    }

    /**
     * Executes command, and waits for the expected phrase in console printout.
     *
     * @param command    command line
     * @param workindDir working directory
     * @param timeout    in millisecond
     *
     * @return console output as a list of strings
     *
     * @throws IOException          for command error
     * @throws InterruptedException when interrupted
     */
    public static List<String> cmdWithWorkingDir(String[] command, String workindDir, final long timeout)
            throws IOException, InterruptedException {
        return cmd(command, null, null, timeout, workindDir);
    }

    /**
     * Executes command, and waits for the expected phrase in console printout.
     * <p>
     * @param command  command line
     * @param expected some expected output
     *
     * @return console output as a list of strings
     *
     * @throws IOException          for command error
     * @throws InterruptedException when interrupted
     */
    public static List<String> cmd(String[] command, String expected) throws IOException, InterruptedException {
        return cmd(command, expected, null, 300000L, null);
    }

    /**
     * Executes command, and waits for the expected pass/fail phrase in console printout within timeout,
     *
     * @param command    command line
     * @param pass       skip checking if null
     * @param fail       skip checking if null
     * @param timeout    set 0 for not to check the output message, otherwise, waiting for timeout
     * @param workingDir working directory
     *
     * @return console output as a list of strings
     *
     * @throws IOException          for command error
     * @throws InterruptedException when interrupted
     */
    public static List<String> cmd(String[] command, final String pass, final String fail, final long timeout,
            final String workingDir) throws IOException, InterruptedException {
        ProcessBuilder pb = new ProcessBuilder(command);
        if (workingDir != null) {
            pb.directory(new File(workingDir));
        }
        pb.redirectErrorStream(true);
        LOG.debug("Running command: " + pb.command().toString().replace(",", ""));
        final Process p = pb.start();
        Thread thread;
        final List<String> output = new ArrayList<>();

        if (timeout == 0) {
            LOG.debug("This is a start-and-exit command");
            output.add(PASS);
            return output;
        } else {
            thread = new Thread() {
                @Override
                public void run() {
                    try {
                        LOG.debug("Command timeouts in {} ms", timeout);
                        Thread.sleep(timeout);
                        try {
                            p.exitValue();
                        } catch (IllegalThreadStateException ex) {
                            LOG.debug("killing subprocess {} - {}", p, ex.getMessage());
                            p.destroy();
                        }
                    } catch (InterruptedException ex) {
                        LOG.warn(ex.getMessage());
                    }
                }
            };
            thread.setName(Thread.currentThread().getName() + "-" + p.hashCode());
            thread.setDaemon(true);
            thread.start();
        }

        BufferedReader stdIn = new BufferedReader(new InputStreamReader(p.getInputStream()));
        String c = p + " - ";
        for (String line = stdIn.readLine(); line != null;) {
            LOG.trace("{}{}", c, line);
            output.add(line);
            try {
                line = stdIn.readLine();
            } catch (IOException ex) {
                LOG.warn(ex.getMessage());
                break;
            }
        }
        LOG.debug("Command exit code {}", p.waitFor());
        thread.interrupt();
        try {
            stdIn.close();
        } catch (IOException ex) {
            LOG.warn("", ex);
        }

        for (String s : output) {
            if (pass != null && (s.contains(pass) || s.matches(pass))) {
                output.add(PASS);
                break;
            } else if (fail != null && s.contains(fail)) {
                output.add(FAIL);
                break;
            }
        }
        return output;
    }

    public static Process cmd(String[] commands, final File file) throws IOException {
        return cmd(commands, file, null, new String[0]);
    }

    public static Process cmd(String[] commands, final File file, final File workingDir) throws IOException {
        return cmd(commands, file, workingDir, new String[0]);
    }

    public static Process cmd(String[] commands, final File file, final File workingDir,
            final String... ignoreRegex) throws IOException {
        FileUtils.touch(file);
        LOG.debug("Saving console output to {}", file.getAbsolutePath());

        ProcessBuilder pb = new ProcessBuilder(commands);
        pb.redirectErrorStream(true);
        pb.directory(workingDir);
        LOG.info("Running command {}:  {}", workingDir == null ? "" : workingDir.getAbsolutePath(),
                pb.command().toString().replaceAll(",", ""));
        final Process p = pb.start();

        Thread t = new Thread(Thread.currentThread().getName() + "-" + p.hashCode()) {
            @Override
            public void run() {
                BufferedReader stdIn = new BufferedReader(new InputStreamReader(p.getInputStream()));
                String console = "console-" + stdIn.hashCode();
                try (PrintWriter pw = new PrintWriter(file)) {
                    for (String line = stdIn.readLine(); line != null;) {
                        LOG.trace("{}: {}", console, line);
                        if (null == ignoreRegex || ignoreRegex.length == 0) {
                            pw.println(line);
                        } else {
                            boolean ignore = false;
                            for (String regex : ignoreRegex) {
                                if (!regex.isEmpty() && (line.contains(regex) || line.matches(regex))) {
                                    ignore = true;
                                    break;
                                }
                            }
                            if (!ignore) {
                                pw.println(line);
                            }
                        }
                        pw.flush();
                        line = stdIn.readLine();
                    }
                } catch (IOException ex) {
                    LOG.warn(ex.getMessage());
                }
                LOG.trace("command is done");
            }
        };
        t.setDaemon(true);
        t.start();

        Runtime.getRuntime().addShutdownHook(new Thread() {
            @Override
            public void run() {
                if (p != null) {
                    p.destroy();
                }
            }
        });
        return p;
    }

    public static void waitForProcess(final Process process, final long timeout) throws InterruptedException {
        Thread t = new Thread() {
            @Override
            public void run() {
                try {
                    Thread.sleep(timeout);
                } catch (InterruptedException ex) {
                    LOG.warn(ex.getMessage());
                } finally {
                    if (process != null) {
                        process.destroy();
                    }
                }
            }
        };
        t.setDaemon(true);
        t.start();
        if (process != null) {
            int exitValue = process.waitFor();
            LOG.trace("process {} exits with {}", process, exitValue);
        }
    }

    public static void waitForOutputLine(final Process process, String lineExpected, final long timeout)
            throws IOException {
        Thread t = new Thread() {
            @Override
            public void run() {
                try {
                    Thread.sleep(timeout);
                } catch (InterruptedException ex) {
                    LOG.warn(ex.getMessage());
                } finally {
                    if (process != null) {
                        process.destroy();
                    }
                }
            }
        };
        t.setName(Thread.currentThread().getName() + "-" + t.hashCode());
        t.setDaemon(true);
        t.start();

        try (BufferedReader stdIn = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
            for (String line = stdIn.readLine(); line != null;) {
                if (line.contains(lineExpected)) {
                    break;
                }
                line = stdIn.readLine();
            }
        }
        t.interrupt();
    }

    public static void deleteFileAfterMinutes(final File file, final int minutes) {
        file.deleteOnExit();
        Thread t = new Thread() {
            @Override
            public void run() {
                try {
                    Thread.sleep(minutes * 60000);
                    FileUtils.deleteQuietly(file);
                } catch (InterruptedException ex) {
                    LOG.trace(ex.getMessage());
                }
            }
        };
        t.setDaemon(true);
        t.start();
    }

    public static String getUniqueId() {
        return getUniqueId("");
    }

    public static String getUniqueId(String prefix) {
        return new StringBuilder(prefix).append(UUID.randomUUID()).toString().replaceAll("-", "_");
    }

    public static void sleep(long millis, String message) throws InterruptedException {
        sleep(millis, 5000, message);
    }

    public static void sleep(long millis, int interval, String message) throws InterruptedException {
        long end = System.currentTimeMillis() + millis;
        while (true) {
            LOG.debug("{}", message);
            long t = end - System.currentTimeMillis();
            if (t > interval) {
                Thread.sleep(interval);
            } else if (t > 0) {
                Thread.sleep(t);
                break;
            } else {
                break;
            }
        }
    }

    public static String getKeepAliveFileName(String fileName) {
        return SystemConfiguration.CONSTANT_LOG_KEEP_ALIVE_PREFIX + fileName;
    }

    public static File getKeepAliveFile(File file) {
        String name = Utils.getKeepAliveFileName(file.getName());
        return Paths.get(file.getParent(), name).toFile();
    }

    /**
     *
     * @param path          directory to clean
     * @param keepAliveHour any file/directory having last modified time longer than keepAliveHour will be deleted
     * @param namePrefix    file name prefix
     */
    public static void cleanDirectory(final String path, final float keepAliveHour, final String namePrefix) {
        final long intervalMillis = 3600000;
        final File dir = new File(path);
        if (!dir.exists()) {
            return;
        }
        Thread thread = new Thread() {
            @Override
            public void run() {
                while (true) {
                    long lastModifiedMillis = (long) (System.currentTimeMillis() - keepAliveHour * 3600000);
                    Collection<File> files = FileUtils.listFiles(dir, null, true);
                    for (File file : files) {
                        if (file.lastModified() < lastModifiedMillis && file.getName().startsWith(namePrefix)) {
                            LOG.debug("Delete {}", file);
                            if (!FileUtils.deleteQuietly(file)) {
                                LOG.debug("Cannot delete {}", file);
                            }
                        }
                    }
                    try {
                        LOG.debug("Waiting for next cleanup...");
                        Thread.sleep(intervalMillis);
                    } catch (InterruptedException ex) {
                        LOG.warn(ex.getMessage());
                        return;
                    }
                }
            }
        };
        thread.setName(Thread.currentThread().getName() + "-cleaning-" + thread.hashCode());
        thread.setDaemon(true);
        LOG.info(
                "Starting directory cleaning thread (scanning hourly), all files/directories in {} and older than {} "
                        + "hour(s) and starts with {} will be deleted",
                dir, keepAliveHour, namePrefix);
        thread.start();
    }

    public static boolean isWindows() {
        String os = System.getProperty("os.name");
        return os.contains("Windows");
    }

    public static String buildClassPath(String[] paths) {
        String classPathDelimiter = Utils.isWindows() ? ";" : ":";
        return StringUtils.join(paths, classPathDelimiter).replaceAll("\\\\", "/");
    }

    /**
     *
     * @param png picture file name
     *
     * @throws AWTException UI related exception
     * @throws IOException  file IO issue
     */
    public static void captureScreen(File png) throws AWTException, IOException {
        Robot robot = new Robot();
        BufferedImage image = robot.createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()));
        ImageIO.write(image, "png", png);
        LOG.debug("Save screenshot to {}", png.getAbsolutePath());
    }

    public static long getTime(String time, String format) throws ParseException {
        DateFormat formatter = new SimpleDateFormat(format);
        Date date = formatter.parse(time);
        return date.getTime();
    }

    public static void main(String[] args) throws Exception {
        List<String> ss = Utils.cmd(new String[] { "adb", "devices" });
        for (String s : ss) {
            LOG.debug("{}", s);
        }
        System.exit(0);
    }
}