/** * Candybean is a next generation automation and testing framework suite. * It is a collection of components that foster test automation, execution * configuration, data abstraction, results illustration, tag-based execution, * top-down and bottom-up batches, mobile variants, test translation across * languages, plain-language testing, and web service testing. * Copyright (C) 2013 SugarCRM, Inc. <candybean@sugarcrm.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.sugarcrm.candybean.utilities; import java.io.BufferedReader; import java.io.Closeable; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; import java.util.logging.Logger; import java.util.regex.Matcher; /** * Utils is simply a container for automation/Java-related helper functions that * are relatively non-specific to any particular library/framework. * * @author cwarmbold, wli, Jason Lin (ylin) * */ public class Utils { private static Logger log = Logger.getLogger(Utils.class.getSimpleName()); /** * Executes a forked process that runs some given command string. Prints the output of the command execution to console. * * @param cmd * @throws IOException */ public static void run(String cmd) throws IOException { Process process = new ProcessBuilder(cmd).start(); BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); String line = reader.readLine(); log.info("Run command: " + cmd); while (line != null) { log.info(line); line = reader.readLine(); } } /** * Given a string, this function returns the suffix of that string matching the given length. * * @param s * @param length * @return */ public static String pretruncate(String s, int length) { if (s.length() <= length) { return s; } return s.substring(s.length() - length); } /** * adjustPath - This method adds robustness to a given path for different platforms. * * @author wli * * @param path * @return */ public static String adjustPath(String path){ String tempPath = path; // replace all single backslash (not followed by space) with forward slash String comparePath = tempPath; tempPath = tempPath.replaceAll("\\\\(?! )", "/"); while (!comparePath.equals(tempPath)) { comparePath = tempPath; tempPath = tempPath.replaceAll("\\\\(?! )", "/"); } // replace all one or more consecutive forward slashes with a File Separator tempPath = tempPath.replaceAll("/+", Matcher.quoteReplacement(File.separator)); if (!tempPath.equals(path)) { log.info("The following path: " + path + " has been adjusted to: " + tempPath); } return tempPath; } /** * Can be used to close any closeable stream. For example, Scanners and Writers. * * @author Jason Lin (ylin) * * @param s */ public static void closeStream(Closeable s) { try { if (s != null) { s.close(); } } catch (IOException e) { log.severe(e.getMessage()); } } /** * Retrieves all tables from the database currently connected to and store them in an ArrayList of Strings. * * @author Jason Lin (ylin) * * @return * @throws SQLException */ public static List<String> getTables(Connection connection) throws SQLException { DatabaseMetaData dbmd = connection.getMetaData(); List<String> tables = new ArrayList<String>(); String[] types = { "TABLE" }; ResultSet resultSet = dbmd.getTables(null, null, "%", types); while (resultSet.next()) { String tableName = resultSet.getString("TABLE_NAME"); tables.add(tableName); } resultSet.close(); return tables; } /** * Establishes a connection to a database. * * @author Jason Lin (ylin) * * @param dbServer - database server * @param dbName - name of the database to use * @param dbUser - database username * @param dbPass - database password * @throws ClassNotFoundException * @throws SQLException */ public static Connection getDBConnection(String dbServer, String dbName, String dbUser, String dbPass) throws ClassNotFoundException, SQLException { Class.forName("com.mysql.jdbc.Driver"); return DriverManager.getConnection("jdbc:mysql://" + dbServer + "/" + dbName + "?useUnicode=true&characterEncoding=utf-8", dbUser, dbPass); } /** * Returns a string representation of elapsed time from seconds to days:hr:min:s * @param seconds The number of seconds * @return */ public static String calculateTime(float seconds) { double partialSeconds = (double) (seconds - ((int)seconds)); int milliseconds = (int) (partialSeconds * 1000); long secs = (long)seconds; int day = (int) TimeUnit.SECONDS.toDays(secs); long hours = TimeUnit.SECONDS.toHours(secs) - (day * 24); long minute = TimeUnit.SECONDS.toMinutes(secs) - (TimeUnit.SECONDS.toHours(secs) * 60); long second = TimeUnit.SECONDS.toSeconds(secs) - (TimeUnit.SECONDS.toMinutes(secs) * 60); return day + "days " + hours + "hr " + minute + "min " + second + "s " + milliseconds + "ms"; } /** * Utility function to get the current operating system. * * @author Larry Cao * * @return string representing the current operating system. */ public static String getCurrentPlatform() { String os = System.getProperty("os.name").toLowerCase(); if (os.contains("mac")) { return "mac"; } else if (os.contains("nux")) { return "linux"; } else if (os.contains("win")) { return "windows"; } else { return "unknown"; } } /** * Pair is a python-2-tuple lightweight equivalent for convenience. * * @author cwarmbold * * @param <X> * @param <Y> */ public static class Pair<X, Y> { public final X x; public final Y y; public Pair(X x, Y y) { this.x = x; this.y = y; } @Override public String toString() { return "x:" + this.x.toString() + ",y:" + this.y.toString(); } } /** * Triplet is a python-3-tuple lightweight equivalent for convenience. * * @author cwarmbold * * @param <X> * @param <Y> * @param <Z> */ public static class Triplet<X, Y, Z> { public final X x; public final Y y; public final Z z; public Triplet(X x, Y y, Z z) { this.x = x; this.y = y; this.z = z; } @Override public String toString() { return "x:" + this.x.toString() + ",y:" + this.y.toString() + ",z:" + this.z.toString(); } } }