# HG changeset patch # User Simon Tooke # Date 1485790219 18000 # Node ID cd5b08c320526f06530ca22a3c99511e1a05d0a6 # Parent 006ac47d1506c4dd70cde7c76236ff1cb7b0d0f6 [PATCH] refactoring portable code part 2 Move more of the Linux "/proc" code into the portability package. Change pom files to detect linux using os name rather than os family. Reviewed-by: ebaron, neugens Review Thread:http://icedtea.classpath.org/pipermail/thermostat/2017-January/022054.html diff -r 006ac47d1506 -r cd5b08c32052 agent/ipc/server/src/main/java/com/redhat/thermostat/agent/ipc/server/internal/IPCConfigurationWriter.java --- a/agent/ipc/server/src/main/java/com/redhat/thermostat/agent/ipc/server/internal/IPCConfigurationWriter.java Thu Jan 26 12:14:51 2017 -0500 +++ b/agent/ipc/server/src/main/java/com/redhat/thermostat/agent/ipc/server/internal/IPCConfigurationWriter.java Mon Jan 30 10:30:19 2017 -0500 @@ -111,7 +111,7 @@ // note: this is required for UNIX too if (OS.IS_WINDOWS) { int uport = aport == 0 ? 0 : findUnusedTCPSocket( aport + 1, TEST_SOCKET_HIGH); - int uid = PortableProcessImpl.INSTANCE.getUid(0); // if pid=0, gets uid of current process + int uid = PortableProcessImpl.getInstance().getUid(0); // if pid=0, gets uid of current process props.setProperty("agent-proxy-" + uid + PROP_TCP_SOCKET_SUFFIX, Integer.toString(uport)); } } diff -r 006ac47d1506 -r cd5b08c32052 common/portability/pom.xml --- a/common/portability/pom.xml Thu Jan 26 12:14:51 2017 -0500 +++ b/common/portability/pom.xml Mon Jan 30 10:30:19 2017 -0500 @@ -139,6 +139,7 @@ com.redhat.thermostat.common.portability.internal, com.redhat.thermostat.common.portability.internal.linux, + com.redhat.thermostat.common.portability.internal.linux.vmio, com.redhat.thermostat.common.portability.internal.windows diff -r 006ac47d1506 -r cd5b08c32052 common/portability/src/main/java/com/redhat/thermostat/common/portability/PortableHostImpl.java --- a/common/portability/src/main/java/com/redhat/thermostat/common/portability/PortableHostImpl.java Thu Jan 26 12:14:51 2017 -0500 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/PortableHostImpl.java Mon Jan 30 10:30:19 2017 -0500 @@ -36,11 +36,21 @@ package com.redhat.thermostat.common.portability; -import com.redhat.thermostat.common.portability.internal.windows.WindowsHostImpl; +import com.redhat.thermostat.common.portability.internal.linux.LinuxPortableHostImpl; +import com.redhat.thermostat.common.portability.internal.windows.WindowsPortableHostImpl; import com.redhat.thermostat.shared.config.OS; public class PortableHostImpl { - public static final PortableHost INSTANCE = OS.IS_WINDOWS ? WindowsHostImpl.INSTANCE : null; + private static final PortableHost INSTANCE = createInstance(); + + private static PortableHost createInstance() { + return OS.IS_LINUX ? LinuxPortableHostImpl.createInstance() + : OS.IS_WINDOWS ? WindowsPortableHostImpl.createInstance() : null; + } + + public static PortableHost getInstance() { + return INSTANCE; + } } diff -r 006ac47d1506 -r cd5b08c32052 common/portability/src/main/java/com/redhat/thermostat/common/portability/PortableMemoryStat.java --- a/common/portability/src/main/java/com/redhat/thermostat/common/portability/PortableMemoryStat.java Thu Jan 26 12:14:51 2017 -0500 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/PortableMemoryStat.java Mon Jan 30 10:30:19 2017 -0500 @@ -84,6 +84,6 @@ } public static PortableMemoryStat build() { - return PortableHostImpl.INSTANCE.getMemoryStat(); + return PortableHostImpl.getInstance().getMemoryStat(); } } diff -r 006ac47d1506 -r cd5b08c32052 common/portability/src/main/java/com/redhat/thermostat/common/portability/PortableProcessImpl.java --- a/common/portability/src/main/java/com/redhat/thermostat/common/portability/PortableProcessImpl.java Thu Jan 26 12:14:51 2017 -0500 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/PortableProcessImpl.java Mon Jan 30 10:30:19 2017 -0500 @@ -36,11 +36,20 @@ package com.redhat.thermostat.common.portability; -import com.redhat.thermostat.common.portability.internal.linux.LinuxProcessImpl; -import com.redhat.thermostat.common.portability.internal.windows.WindowsHelperImpl; -import com.redhat.thermostat.common.portability.internal.windows.WindowsProcessImpl; +import com.redhat.thermostat.common.portability.internal.linux.LinuxPortableProcessImpl; +import com.redhat.thermostat.common.portability.internal.windows.WindowsPortableProcessImpl; import com.redhat.thermostat.shared.config.OS; public final class PortableProcessImpl { - public static final PortableProcess INSTANCE = OS.IS_WINDOWS ? WindowsProcessImpl.INSTANCE : LinuxProcessImpl.INSTANCE; + + private static final PortableProcess INSTANCE = createInstance(); + + private static PortableProcess createInstance() { + return OS.IS_LINUX ? LinuxPortableProcessImpl.createInstance() + : OS.IS_WINDOWS ? WindowsPortableProcessImpl.createInstance() : null; + } + + public static PortableProcess getInstance() { + return INSTANCE; + } } diff -r 006ac47d1506 -r cd5b08c32052 common/portability/src/main/java/com/redhat/thermostat/common/portability/PortableProcessStat.java --- a/common/portability/src/main/java/com/redhat/thermostat/common/portability/PortableProcessStat.java Thu Jan 26 12:14:51 2017 -0500 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/PortableProcessStat.java Mon Jan 30 10:30:19 2017 -0500 @@ -71,7 +71,7 @@ } public static PortableProcessStat build(int pid) { - return PortableProcessImpl.INSTANCE.getProcessStat(pid); + return PortableProcessImpl.getInstance().getProcessStat(pid); } } diff -r 006ac47d1506 -r cd5b08c32052 common/portability/src/main/java/com/redhat/thermostat/common/portability/PortableVmIoStat.java --- a/common/portability/src/main/java/com/redhat/thermostat/common/portability/PortableVmIoStat.java Thu Jan 26 12:14:51 2017 -0500 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/PortableVmIoStat.java Mon Jan 30 10:30:19 2017 -0500 @@ -56,7 +56,7 @@ } public static PortableVmIoStat build(Clock clock, int pid) { - return PortableProcessImpl.INSTANCE.getVmIoStat(clock, pid); + return PortableProcessImpl.getInstance().getVmIoStat(clock, pid); } public long getTimeStamp() { diff -r 006ac47d1506 -r cd5b08c32052 common/portability/src/main/java/com/redhat/thermostat/common/portability/SysConf.java --- a/common/portability/src/main/java/com/redhat/thermostat/common/portability/SysConf.java Thu Jan 26 12:14:51 2017 -0500 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/SysConf.java Mon Jan 30 10:30:19 2017 -0500 @@ -58,7 +58,7 @@ } private static long getWindowsClockTicksPerSecond() { - return PortableHostImpl.INSTANCE.getClockTicksPerSecond(); + return PortableHostImpl.getInstance().getClockTicksPerSecond(); } public static long getLinuxClockTicksPerSecond() { diff -r 006ac47d1506 -r cd5b08c32052 common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/linux/DistributionInformation.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/linux/DistributionInformation.java Mon Jan 30 10:30:19 2017 -0500 @@ -0,0 +1,107 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.common.portability.internal.linux; + +import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; + +import com.redhat.thermostat.common.utils.LoggingUtils; + +public class DistributionInformation { + + static final String UNKNOWN_NAME = "Unknown Distribution"; + static final String UNKNOWN_VERSION = "Unknown Version"; + + private static final Logger logger = LoggingUtils.getLogger(DistributionInformation.class); + + private final String name; + private final String version; + + public DistributionInformation(String name, String version) { + this.name = name; + this.version = version; + } + + public static DistributionInformation get() { + EtcOsRelease etcOsRelease = new EtcOsRelease(); + LsbRelease lsbRelease = new LsbRelease(); + return get(etcOsRelease, lsbRelease); + } + + // package-private for testing + static DistributionInformation get(EtcOsRelease etcOsRelease, LsbRelease lsbRelease) { + try { + DistributionInformation etcOsDistroInfo = etcOsRelease.getDistributionInformation(); + // if both name and version are unknown defer to lsb fallback + if (!DistributionInformation.UNKNOWN_NAME.equals(etcOsDistroInfo.getName()) && + !DistributionInformation.UNKNOWN_VERSION.equals(etcOsDistroInfo.getVersion())) { + return etcOsDistroInfo; + } + logger.log(Level.FINE, "/etc/os-release existing, but does not contain useful info"); + } catch (IOException e) { + // Log only at level FINE, since we have the LSB fallback + logger.log(Level.FINE, "unable to use os-release", e); + } + try { + return lsbRelease.getDistributionInformation(); + } catch (IOException e) { + // Log exception at level FINE only. + logger.log(Level.FINE, "unable to use lsb_release", e); + logger.log(Level.WARNING, "unable to use os-release AND lsb_release"); + } + return new DistributionInformation(UNKNOWN_NAME, UNKNOWN_VERSION); + } + + /** + * @return the name of the distribution, or {@link #UNKNOWN_NAME} if it can not be + * identified + */ + public String getName() { + return name; + } + + /** + * @return the release of the distribution or {@link #UNKNOWN_VERSION} if it can not be + * identified + */ + public String getVersion() { + return version; + } + +} + diff -r 006ac47d1506 -r cd5b08c32052 common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/linux/DistributionInformationSource.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/linux/DistributionInformationSource.java Mon Jan 30 10:30:19 2017 -0500 @@ -0,0 +1,46 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.common.portability.internal.linux; + +import java.io.IOException; + +public interface DistributionInformationSource { + + DistributionInformation getDistributionInformation() throws IOException; + +} + diff -r 006ac47d1506 -r cd5b08c32052 common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/linux/EtcOsRelease.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/linux/EtcOsRelease.java Mon Jan 30 10:30:19 2017 -0500 @@ -0,0 +1,112 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.common.portability.internal.linux; + +import java.io.BufferedReader; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; + +public class EtcOsRelease implements DistributionInformationSource { + + private static final String EMPTY_STRING = ""; + private static final String OS_RELEASE = "/etc/os-release"; + private final String osReleaseFile; + + EtcOsRelease() { + this.osReleaseFile = OS_RELEASE; + } + + // package-private for testing + EtcOsRelease(String osReleaseFile) { + this.osReleaseFile = osReleaseFile; + } + + @Override + public DistributionInformation getDistributionInformation() throws IOException { + return getFromOsRelease(); + } + + DistributionInformation getFromOsRelease() throws IOException { + return getFromOsRelease(osReleaseFile); + } + + DistributionInformation getFromOsRelease(String releaseFile) throws IOException { + try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(releaseFile), StandardCharsets.UTF_8))) { + return getFromOsRelease(reader); + } + } + + DistributionInformation getFromOsRelease(BufferedReader reader) throws IOException { + String version = DistributionInformation.UNKNOWN_VERSION; + String name = DistributionInformation.UNKNOWN_NAME; + String line = null; + while ((line = reader.readLine()) != null) { + // skip whitespace only lines + line = line.trim(); + if (line.equals(EMPTY_STRING)) { + continue; + } + if (line.matches("^NAME *=.*")) { + name = readShellVariable(line); + } + if (line.matches("^VERSION *=.*")) { + version = readShellVariable(line); + } + } + return new DistributionInformation(name, version); + } + + /** Reads and parses a shell variable declaration: {@code FOO="bar"} + * + * @return the value of the shell variable + */ + private String readShellVariable(String line) { + // TODO we should try to handle shell quotes better + String result = line.substring(line.indexOf("=")+1); + result = result.trim(); + if (result.startsWith("\"") && result.endsWith("\"")) { + result = result.substring(1, result.length()-1); + result = result.trim(); + } + return result; + } + + +} + diff -r 006ac47d1506 -r cd5b08c32052 common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/linux/LinuxPortableHostImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/linux/LinuxPortableHostImpl.java Mon Jan 30 10:30:19 2017 -0500 @@ -0,0 +1,217 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.common.portability.internal.linux; + +import java.io.BufferedReader; +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.logging.Level; +import java.util.logging.Logger; + +import com.redhat.thermostat.common.Size; +import com.redhat.thermostat.common.Size.Unit; +import com.redhat.thermostat.common.portability.HostName; +import com.redhat.thermostat.common.portability.PortableHost; +import com.redhat.thermostat.common.portability.PortableMemoryStat; +import com.redhat.thermostat.common.portability.internal.UnimplementedError; +import com.redhat.thermostat.common.portability.linux.ProcDataSource; +import com.redhat.thermostat.common.utils.LoggingUtils; + +public class LinuxPortableHostImpl implements PortableHost { + + public static PortableHost INSTANCE = new LinuxPortableHostImpl(new ProcDataSource()); + + private static final Logger logger = LoggingUtils.getLogger(LinuxPortableHostImpl.class); + + private static final String FALLBACK_LOCAL_HOSTNAME = "localhost"; + + private final ProcDataSource dataSource; + + public static PortableHost createInstance() { + return new LinuxPortableHostImpl(new ProcDataSource()); + } + + static class HostCpuInfo { + final String model; + final int count; + + HostCpuInfo(String model, int count) { + this.count = count; + this.model = model; + } + } + + static class HostOsInfo { + final String kernel; + final String distribution; + + HostOsInfo(String kernel, String distribution) { + this.kernel = kernel; + this.distribution = distribution; + } + } + + + LinuxPortableHostImpl(ProcDataSource dataSource) { + this.dataSource = dataSource; + } + + HostCpuInfo getCpuInfo() { + final String KEY_PROCESSOR_ID = "processor"; + final String KEY_CPU_MODEL = "model name"; + int cpuCount = 0; + String cpuModel = null; + try (BufferedReader bufferedReader = new BufferedReader(dataSource.getCpuInfoReader())) { + String line; + while ((line = bufferedReader.readLine()) != null) { + if (line.startsWith(KEY_PROCESSOR_ID)) { + cpuCount++; + } else if (line.startsWith(KEY_CPU_MODEL)) { + cpuModel = line.substring(line.indexOf(":") + 1).trim(); + } + } + } catch (IOException ioe) { + logger.log(Level.WARNING, "unable to read cpu info"); + } + + logger.log(Level.FINEST, "cpuModel: " + cpuModel); + logger.log(Level.FINEST, "cpuCount: " + cpuCount); + + return new HostCpuInfo(cpuModel, cpuCount); + } + + Size getTotalMemorySize() { + Size totalMemory = null; + try (BufferedReader bufferedReader = new BufferedReader(dataSource.getMemInfoReader())) { + String[] memTotalParts = bufferedReader.readLine().split(" +"); + long data = Long.valueOf(memTotalParts[1]); + String units = memTotalParts[2]; + if (units.equals("kB")) { + totalMemory = new Size(data, Size.Unit.KiB); + } + } catch (IOException ioe) { + logger.log(Level.WARNING, "unable to read memory info"); + } + + logger.log(Level.FINEST, "totalMemory: " + (totalMemory != null ? totalMemory.toString() : "(null)")); + return totalMemory; + } + + @Override + public String getHostName() { + String hostname = null; + + try { + InetAddress localAddress = InetAddress.getLocalHost(); + hostname = getHostName(localAddress); + } catch (UnknownHostException uhe) { + logger.log(Level.WARNING, "unable to get hostname", uhe); + } + + // if fails, try to get hostname without dns lookup + if (hostname == null) { + hostname = HostName.getLocalHostName(); + } + + // still null, use localhost + if (hostname == null) { + hostname = FALLBACK_LOCAL_HOSTNAME; + + } + + return hostname; + } + + HostOsInfo getOsInfo(DistributionInformation distroInfo) { + String osName = distroInfo.getName() + " " + distroInfo.getVersion(); + logger.log(Level.FINEST, "osName: " + osName); + String osKernel = System.getProperty("os.name") + " " + System.getProperty("os.version"); + logger.log(Level.FINEST, "osKernel: " + osKernel); + return new HostOsInfo(osKernel, osName); + } + + private HostOsInfo getOsInfo() { + DistributionInformation distroInfo = DistributionInformation.get(); + return getOsInfo(distroInfo); + } + + @Override + public String getOSName() { + return getOsInfo().distribution; + } + + @Override + public String getOSVersion() { + return getOsInfo().kernel; + } + + @Override + public String getCPUModel() { + return getCpuInfo().model; + } + + @Override + public int getCPUCount() { + return getCpuInfo().count; + } + + @Override + public long getTotalMemory() { + return (long) getTotalMemorySize().convertTo(Unit.B).getValue(); + } + + @Override + public long getClockTicksPerSecond() { + // TODO + throw new UnimplementedError("getClockTicksPerSecond()"); + } + + @Override + public PortableMemoryStat getMemoryStat() { + // TODO + throw new UnimplementedError("getMemoryStat()"); + } + + String getHostName(InetAddress localAddress) { + String hostname = localAddress.getCanonicalHostName(); + logger.log(Level.FINEST, "hostname: " + hostname); + return hostname; + } + +} + diff -r 006ac47d1506 -r cd5b08c32052 common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/linux/LinuxPortableProcessImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/linux/LinuxPortableProcessImpl.java Mon Jan 30 10:30:19 2017 -0500 @@ -0,0 +1,114 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.common.portability.internal.linux; + +import com.redhat.thermostat.common.Clock; +import com.redhat.thermostat.common.SystemClock; +import com.redhat.thermostat.common.portability.PortableProcess; +import com.redhat.thermostat.common.portability.PortableProcessStat; +import com.redhat.thermostat.common.portability.PortableVmIoStat; +import com.redhat.thermostat.common.portability.ProcessChecker; +import com.redhat.thermostat.common.portability.internal.UnimplementedError; +import com.redhat.thermostat.common.portability.internal.linux.vmio.LinuxVmIoStatBuilderImpl; +import com.redhat.thermostat.common.portability.internal.linux.vmio.ProcIoDataReader; +import com.redhat.thermostat.common.portability.linux.ProcDataSource; + +import java.util.Map; + +public class LinuxPortableProcessImpl implements PortableProcess { + + private LinuxPortableProcessStatBuilderImpl procStatHelper; + private LinuxProcessEnvironmentBuilderImpl procEnvHelper; + private LinuxVmIoStatBuilderImpl vmioHelper; + + public static LinuxPortableProcessImpl INSTANCE = new LinuxPortableProcessImpl(new SystemClock(), new ProcDataSource()); + + public static PortableProcess createInstance() { + return new LinuxPortableProcessImpl(new SystemClock(), new ProcDataSource()); + } + + private LinuxPortableProcessImpl(Clock clock, ProcDataSource dataSource) { + procStatHelper = new LinuxPortableProcessStatBuilderImpl(dataSource); + procEnvHelper = new LinuxProcessEnvironmentBuilderImpl(dataSource); + vmioHelper = new LinuxVmIoStatBuilderImpl(clock, new ProcIoDataReader(dataSource)); + } + + @Override + public boolean exists(int pid) { + return new ProcessChecker().exists(pid); + } + + @Override + public String getUserName(int pid) { + throw new UnimplementedError("getUserName()"); + } + + @Override + public int getUid(int pid) { + throw new UnimplementedError("getUid()"); + } + + @Override + public Map getEnvironment(int pid) { + return procEnvHelper.build(pid); + } + + @Override + public PortableProcessStat getProcessStat(int pid) { + return procStatHelper.build(pid); + } + + @Override + public PortableVmIoStat getVmIoStat(Clock clock, int pid) { + return vmioHelper.build(pid); + } + + @Override + public boolean terminateProcess(int pid) { + throw new UnimplementedError("terminateProcess()"); + } + + @Override + public boolean terminateProcess(int pid, boolean wait) { + throw new UnimplementedError("terminateProcess()"); + } + + @Override + public boolean terminateProcess(int pid, int exitcode, int waitMillis) { + throw new UnimplementedError("terminateProcess()"); + } +} diff -r 006ac47d1506 -r cd5b08c32052 common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/linux/LinuxPortableProcessStatBuilderImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/linux/LinuxPortableProcessStatBuilderImpl.java Mon Jan 30 10:30:19 2017 -0500 @@ -0,0 +1,121 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.common.portability.internal.linux; + +import com.redhat.thermostat.common.portability.PortableProcessStat; +import com.redhat.thermostat.common.portability.linux.ProcDataSource; +import com.redhat.thermostat.common.utils.LoggingUtils; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.Reader; +import java.util.Scanner; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Extract status information about the process from /proc/. This is what tools + * like {@code ps} and {@code top} use. + * + * @see {@code proc(5)} + */ +public class LinuxPortableProcessStatBuilderImpl { + + private static final Logger logger = LoggingUtils.getLogger(LinuxPortableProcessStatBuilderImpl.class); + + private final ProcDataSource dataSource; + + public LinuxPortableProcessStatBuilderImpl(ProcDataSource dataSource) { + this.dataSource = dataSource; + } + + public PortableProcessStat build(int pid) { + try (BufferedReader reader = new BufferedReader(dataSource.getStatReader(pid))) { + return build(reader); + } catch (IOException e) { + logger.log(Level.FINE, "Unable to read stat info for: " + pid); + } + + return null; + } + + PortableProcessStat build(Reader r) throws IOException { + + int pid = -1; + long utime = -1; + long stime = -1; + + Scanner scanner = null; + + /* TODO map these (effectively c) data types to java types more sanely */ + + try (BufferedReader reader = new BufferedReader(r)) { + String statusLine = reader.readLine(); + + /* be prepared for process names like '1 ) 2 3 4 foo 5' */ + + scanner = new Scanner(statusLine); + pid = scanner.nextInt(); + scanner.close(); + + int execEndNamePos = statusLine.lastIndexOf(')'); + + String cleanStatusLine = statusLine.substring(execEndNamePos + 1); + + scanner = new Scanner(cleanStatusLine); + /* state = */scanner.next(); + /* ppid = */scanner.nextInt(); + /* pgrp = */scanner.nextInt(); + /* session = */scanner.nextInt(); + /* tty_nr = */scanner.nextInt(); + /* tpgid = */scanner.nextInt(); + /* flags = */scanner.nextInt(); + /* minflt = */scanner.nextLong(); + /* cminflt = */scanner.nextLong(); + /* majflt = */scanner.nextLong(); + /* cmajflt = */scanner.nextLong(); + utime = scanner.nextLong(); + stime = scanner.nextLong(); + scanner.close(); + } + + return new PortableProcessStat(pid, utime, stime); + + } + +} + diff -r 006ac47d1506 -r cd5b08c32052 common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/linux/LinuxProcessEnvironmentBuilderImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/linux/LinuxProcessEnvironmentBuilderImpl.java Mon Jan 30 10:30:19 2017 -0500 @@ -0,0 +1,126 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.common.portability.internal.linux; + +import java.io.IOException; +import java.io.Reader; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; + +import com.redhat.thermostat.common.portability.linux.ProcDataSource; +import com.redhat.thermostat.common.utils.LoggingUtils; + +class LinuxProcessEnvironmentBuilderImpl { + + private static final Logger logger = LoggingUtils.getLogger(LinuxProcessEnvironmentBuilderImpl.class); + + private final ProcDataSource dataSource; + + LinuxProcessEnvironmentBuilderImpl(ProcDataSource dataSource) { + this.dataSource = dataSource; + } + + public Map build(int pid) { + try (Reader reader = dataSource.getEnvironReader(pid)) { + return build(reader); + } catch (IOException ioe) { + logger.log(Level.WARNING, "error reading env", ioe); + } + + return Collections.emptyMap(); + } + + private Map build(Reader reader) throws IOException { + + Map env = new HashMap(); + + char[] fileBuffer = new char[1024]; + int fileBufferIndex = 0; + char[] buffer = new char[1024]; + int read = 0; + while (true) { + read = reader.read(buffer); + if (read == -1) { + break; + } + + if (read + fileBufferIndex > fileBuffer.length) { + char[] newFileBuffer = new char[fileBuffer.length * 2]; + System.arraycopy(fileBuffer, 0, newFileBuffer, 0, fileBufferIndex); + fileBuffer = newFileBuffer; + } + System.arraycopy(buffer, 0, fileBuffer, fileBufferIndex, read); + fileBufferIndex = fileBufferIndex + read; + + } + List parts = getParts(fileBuffer, fileBufferIndex); + for (String part : parts) { + int splitterPos = part.indexOf("="); + String key = part.substring(0, splitterPos); + String value = part.substring(splitterPos + 1); + env.put(key, value); + } + + return env; + } + + /** + * Split a char array, where items are separated by a null into into a list + * of strings + */ + private List getParts(char[] nullSeparatedBuffer, int bufferLength) { + int maxLength = Math.min(nullSeparatedBuffer.length, bufferLength); + List parts = new ArrayList(); + + int lastStart = 0; + for (int i = 0; i < maxLength; i++) { + if (nullSeparatedBuffer[i] == '\0') { + String string = new String(nullSeparatedBuffer, lastStart, (i - lastStart)); + parts.add(string); + lastStart = i + 1; + } + } + return parts; + } + +} + diff -r 006ac47d1506 -r cd5b08c32052 common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/linux/LinuxProcessImpl.java --- a/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/linux/LinuxProcessImpl.java Thu Jan 26 12:14:51 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,100 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.common.portability.internal.linux; - -import com.redhat.thermostat.common.Clock; -import com.redhat.thermostat.common.portability.*; -import com.redhat.thermostat.common.portability.internal.UnimplementedError; -import com.redhat.thermostat.common.portability.linux.ProcDataSource; - -import java.util.Map; - -public class LinuxProcessImpl implements PortableProcess { - - private final ProcDataSource dataSource; - - public static LinuxProcessImpl INSTANCE = new LinuxProcessImpl(new ProcDataSource()); - - LinuxProcessImpl(ProcDataSource ds) { - this.dataSource = ds; - } - - @Override - public boolean exists(int pid) { - return new ProcessChecker().exists(pid); - } - - @Override - public String getUserName(int pid) { - throw new UnimplementedError("getUserName()"); - } - - @Override - public int getUid(int pid) { - throw new UnimplementedError("getUid()"); - } - - @Override - public Map getEnvironment(int pid) { - throw new UnimplementedError("getEnvironment()"); - } - - @Override - public PortableProcessStat getProcessStat(int pid) { - throw new UnimplementedError("PortableProcessStat()"); - } - - @Override - public PortableVmIoStat getVmIoStat(Clock clock, int pid) { - throw new UnimplementedError("getVmIoStat()"); - } - - @Override - public boolean terminateProcess(int pid) { - throw new UnimplementedError("terminateProcess()"); - } - - @Override - public boolean terminateProcess(int pid, boolean wait) { - throw new UnimplementedError("terminateProcess()"); - } - - @Override - public boolean terminateProcess(int pid, int exitcode, int waitMillis) { - throw new UnimplementedError("terminateProcess()"); - } -} diff -r 006ac47d1506 -r cd5b08c32052 common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/linux/LsbRelease.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/linux/LsbRelease.java Mon Jan 30 10:30:19 2017 -0500 @@ -0,0 +1,123 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.common.portability.internal.linux; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.logging.Level; +import java.util.logging.Logger; + +import com.redhat.thermostat.common.utils.LoggingUtils; + +class LsbRelease implements DistributionInformationSource { + + private static final Logger logger = LoggingUtils.getLogger(LsbRelease.class); + + private static final String DISTRIBUTION_NAME = "distributor id"; + private static final String DISTRIBUTION_VERSION = "release"; + private static final String LSB_RELEASE_SCRIPT = "lsb_release"; + + private final String lsbRelaseBin; + + LsbRelease() { + this.lsbRelaseBin = LSB_RELEASE_SCRIPT; + } + + // package-private for testing + LsbRelease(String lsbReleaseBin) { + this.lsbRelaseBin = lsbReleaseBin; + } + + @Override + public DistributionInformation getDistributionInformation() + throws IOException { + return getFromLsbRelease(); + } + + private DistributionInformation getFromLsbRelease() throws IOException { + BufferedReader reader = null; + try { + Process lsbProc = Runtime.getRuntime().exec(new String[] { lsbRelaseBin, "-a" }); + InputStream progOutput = lsbProc.getInputStream(); + reader = new BufferedReader(new InputStreamReader(progOutput)); + DistributionInformation result = getFromLsbRelease(reader); + int exitValue = lsbProc.waitFor(); + if (exitValue != 0) { + logger.log(Level.WARNING, "unable to identify distribution, problems running 'lsb_release'"); + } + return result; + } catch (InterruptedException e) { + throw new IOException(e); + } finally { + if (reader != null) { + try { + reader.close(); + } catch (IOException e) { + logger.log(Level.WARNING, "unable to close a child's output stream"); + } + } + } + + } + + DistributionInformation getFromLsbRelease(BufferedReader reader) throws IOException { + String name = DistributionInformation.UNKNOWN_NAME; + String version = DistributionInformation.UNKNOWN_VERSION; + + String line; + while ((line = reader.readLine()) != null) { + int sepLocation = line.indexOf(":"); + if (sepLocation != -1) { + String key = line.substring(0, sepLocation).toLowerCase(); + if (key.equals(DISTRIBUTION_NAME)) { + name = line.substring(sepLocation + 1).trim(); + } else if (key.equals(DISTRIBUTION_VERSION)) { + version = line.substring(sepLocation + 1).trim(); + } + } + } + + logger.log(Level.FINE, "distro-name: " + name); + logger.log(Level.FINE, "distro-version: " + version); + + return new DistributionInformation(name, version); + } + +} + diff -r 006ac47d1506 -r cd5b08c32052 common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/linux/vmio/LinuxVmIoStatBuilderImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/linux/vmio/LinuxVmIoStatBuilderImpl.java Mon Jan 30 10:30:19 2017 -0500 @@ -0,0 +1,61 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.common.portability.internal.linux.vmio; + +import com.redhat.thermostat.common.Clock; +import com.redhat.thermostat.common.portability.PortableVmIoStat; + +public class LinuxVmIoStatBuilderImpl { + + private final Clock clock; + private final ProcIoDataReader ioReader; + + public LinuxVmIoStatBuilderImpl(Clock clock, ProcIoDataReader ioReader) { + this.clock = clock; + this.ioReader = ioReader; + } + + public synchronized PortableVmIoStat build(Integer pid) { + ProcIoData data = ioReader.read(pid); + if (data == null) { + return null; + } + long miliTime = clock.getRealTimeMillis(); + return new PortableVmIoStat(miliTime, data.syscr, data.syscw, data.rchar, data.wchar); + } + +} diff -r 006ac47d1506 -r cd5b08c32052 common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/linux/vmio/ProcIoData.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/linux/vmio/ProcIoData.java Mon Jan 30 10:30:19 2017 -0500 @@ -0,0 +1,66 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.common.portability.internal.linux.vmio; + +public class ProcIoData { + + // This matches the proc file format. The file format is described at: + // http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/filesystems/proc.txt + + public final long rchar; + public final long wchar; + public final long syscr; + public final long syscw; + public final long read_bytes; + public final long write_bytes; + public final long cancelled_write_bytes; + + public ProcIoData(long rchar, long wchar, + long syscr, long syscw, + long read_bytes, long write_bytes, + long cancelled_write_bytes) { + this.rchar = rchar; + this.wchar = wchar; + this.syscr = syscr; + this.syscw = syscw; + this.read_bytes = read_bytes; + this.write_bytes = write_bytes; + this.cancelled_write_bytes = cancelled_write_bytes; + } + +} + diff -r 006ac47d1506 -r cd5b08c32052 common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/linux/vmio/ProcIoDataReader.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/linux/vmio/ProcIoDataReader.java Mon Jan 30 10:30:19 2017 -0500 @@ -0,0 +1,117 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.common.portability.internal.linux.vmio; + +import java.io.BufferedReader; +import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; + +import com.redhat.thermostat.common.portability.linux.ProcDataSource; +import com.redhat.thermostat.common.utils.LoggingUtils; + +/** + * Extract information from {@code /proc//io}. + */ +public class ProcIoDataReader { + + private static final Logger logger = LoggingUtils.getLogger(ProcIoDataReader.class); + + private final ProcDataSource dataSource; + + public ProcIoDataReader(ProcDataSource dataSource) { + this.dataSource = dataSource; + } + + public ProcIoData read(int pid) { + try (BufferedReader reader = new BufferedReader(dataSource.getIoReader(pid))) { + return read(reader); + } catch (IOException e) { + logger.log(Level.FINE, "Unable to read io info for: " + pid); + } + + return null; + } + + private ProcIoData read(BufferedReader r) throws IOException { + // The file format is described at: + // http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/filesystems/proc.txt + + final int UNKNOWN_VALUE = -1; + long rchar = UNKNOWN_VALUE; + long wchar = UNKNOWN_VALUE; + long syscr = UNKNOWN_VALUE; + long syscw = UNKNOWN_VALUE; + long read_bytes = UNKNOWN_VALUE; + long write_bytes = UNKNOWN_VALUE; + long cancelled_write_bytes = UNKNOWN_VALUE; + + String line; + while ((line = r.readLine()) != null) { + String[] parts = line.split(":"); + String key = parts[0].trim(); + String value = parts[1].trim(); + switch (key) { + case "rchar": + rchar = Long.valueOf(value); + break; + case "wchar": + wchar = Long.valueOf(value); + break; + case "syscr": + syscr = Long.valueOf(value); + break; + case "syscw": + syscw = Long.valueOf(value); + break; + case "read_bytes": + read_bytes = Long.valueOf(value); + break; + case "write_bytes": + write_bytes = Long.valueOf(value); + break; + case "cancelled_write_bytes": + cancelled_write_bytes = Long.valueOf(value); + break; + } + } + + return new ProcIoData(rchar, wchar, syscr, syscw, read_bytes, write_bytes, cancelled_write_bytes); + } + +} + diff -r 006ac47d1506 -r cd5b08c32052 common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/windows/WindowsHostImpl.java --- a/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/windows/WindowsHostImpl.java Thu Jan 26 12:14:51 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,86 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.common.portability.internal.windows; - -import com.redhat.thermostat.common.portability.PortableHost; -import com.redhat.thermostat.common.portability.PortableMemoryStat; - -public class WindowsHostImpl implements PortableHost { - - public static final WindowsHostImpl INSTANCE = new WindowsHostImpl(); - private static final WindowsHelperImpl helper = WindowsHelperImpl.INSTANCE; - - @Override - public String getHostName() { - return helper.getHostName(); - } - - @Override - public String getOSName() { - return helper.getOSName(); - } - - @Override - public String getOSVersion() { - return helper.getOSVersion(); - } - - @Override - public String getCPUModel() { - return helper.getCPUModel(); - } - - @Override - public int getCPUCount() { - return helper.getCPUCount(); - } - - @Override - public long getTotalMemory() { - return helper.getTotalMemory(); - } - - @Override - public long getClockTicksPerSecond() { - return helper.getClockTicksPerSecond(); - } - - @Override - public PortableMemoryStat getMemoryStat() { - return new WindowsMemoryStat(); - } -} diff -r 006ac47d1506 -r cd5b08c32052 common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/windows/WindowsPortableHostImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/windows/WindowsPortableHostImpl.java Mon Jan 30 10:30:19 2017 -0500 @@ -0,0 +1,91 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.common.portability.internal.windows; + +import com.redhat.thermostat.common.portability.PortableHost; +import com.redhat.thermostat.common.portability.PortableMemoryStat; + +public class WindowsPortableHostImpl implements PortableHost { + + public static final WindowsPortableHostImpl INSTANCE = new WindowsPortableHostImpl(); + + public static PortableHost createInstance() { + return new WindowsPortableHostImpl(); + } + + private static final WindowsHelperImpl helper = WindowsHelperImpl.INSTANCE; + + @Override + public String getHostName() { + return helper.getHostName(); + } + + @Override + public String getOSName() { + return helper.getOSName(); + } + + @Override + public String getOSVersion() { + return helper.getOSVersion(); + } + + @Override + public String getCPUModel() { + return helper.getCPUModel(); + } + + @Override + public int getCPUCount() { + return helper.getCPUCount(); + } + + @Override + public long getTotalMemory() { + return helper.getTotalMemory(); + } + + @Override + public long getClockTicksPerSecond() { + return helper.getClockTicksPerSecond(); + } + + @Override + public PortableMemoryStat getMemoryStat() { + return new WindowsMemoryStat(); + } +} diff -r 006ac47d1506 -r cd5b08c32052 common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/windows/WindowsPortableProcessImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/windows/WindowsPortableProcessImpl.java Mon Jan 30 10:30:19 2017 -0500 @@ -0,0 +1,102 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.common.portability.internal.windows; + +import com.redhat.thermostat.common.Clock; +import com.redhat.thermostat.common.portability.PortableProcess; +import com.redhat.thermostat.common.portability.PortableProcessStat; +import com.redhat.thermostat.common.portability.PortableVmIoStat; + +import java.util.Map; + +public class WindowsPortableProcessImpl implements PortableProcess { + + public static final WindowsPortableProcessImpl INSTANCE = new WindowsPortableProcessImpl(); + private static final WindowsHelperImpl helper = WindowsHelperImpl.INSTANCE; + + public static PortableProcess createInstance() { + return new WindowsPortableProcessImpl(); + } + + @Override + public boolean exists(int pid) { + return helper.exists(pid); + } + + @Override + public String getUserName(int pid) { + return helper.getUserName(pid); + } + + @Override + public int getUid(int pid) { + return helper.getUid(pid); + } + + @Override + public Map getEnvironment(int pid) { + return helper.getEnvironment(pid); + } + + @Override + public PortableProcessStat getProcessStat(int pid) { + final long[] info = helper.getProcessCPUInfo(pid); + final long utime = info[1]; + final long stime = info[2]; + return new PortableProcessStat(pid, utime, stime); + } + + @Override + public PortableVmIoStat getVmIoStat(Clock clock, int pid) { + return new WindowsVmIoStat(clock, pid); + } + + @Override + public boolean terminateProcess(int pid) { + return helper.terminateProcess(pid); + } + + @Override + public boolean terminateProcess(int pid, boolean wait) { + return helper.terminateProcess(pid, wait); + } + + @Override + public boolean terminateProcess(int pid, int exitcode, int waitMillis) { + return helper.terminateProcess(pid, exitcode, waitMillis); + } +} diff -r 006ac47d1506 -r cd5b08c32052 common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/windows/WindowsProcessImpl.java --- a/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/windows/WindowsProcessImpl.java Thu Jan 26 12:14:51 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,98 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.common.portability.internal.windows; - -import com.redhat.thermostat.common.Clock; -import com.redhat.thermostat.common.portability.PortableProcess; -import com.redhat.thermostat.common.portability.PortableProcessStat; -import com.redhat.thermostat.common.portability.PortableVmIoStat; - -import java.util.Map; - -public class WindowsProcessImpl implements PortableProcess { - - public static final WindowsProcessImpl INSTANCE = new WindowsProcessImpl(); - private static final WindowsHelperImpl helper = WindowsHelperImpl.INSTANCE; - - @Override - public boolean exists(int pid) { - return helper.exists(pid); - } - - @Override - public String getUserName(int pid) { - return helper.getUserName(pid); - } - - @Override - public int getUid(int pid) { - return helper.getUid(pid); - } - - @Override - public Map getEnvironment(int pid) { - return helper.getEnvironment(pid); - } - - @Override - public PortableProcessStat getProcessStat(int pid) { - final long[] info = helper.getProcessCPUInfo(pid); - final long utime = info[1]; - final long stime = info[2]; - return new PortableProcessStat(pid, utime, stime); - } - - @Override - public PortableVmIoStat getVmIoStat(Clock clock, int pid) { - return new WindowsVmIoStat(clock, pid); - } - - @Override - public boolean terminateProcess(int pid) { - return helper.terminateProcess(pid); - } - - @Override - public boolean terminateProcess(int pid, boolean wait) { - return helper.terminateProcess(pid, wait); - } - - @Override - public boolean terminateProcess(int pid, int exitcode, int waitMillis) { - return helper.terminateProcess(pid, exitcode, waitMillis); - } -} diff -r 006ac47d1506 -r cd5b08c32052 common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/windows/WindowsUserInfoBuilderImpl.java --- a/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/windows/WindowsUserInfoBuilderImpl.java Thu Jan 26 12:14:51 2017 -0500 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/windows/WindowsUserInfoBuilderImpl.java Mon Jan 30 10:30:19 2017 -0500 @@ -56,7 +56,7 @@ private static final Logger logger = LoggingUtils.getLogger(WindowsUserInfoBuilderImpl.class); public WindowsUserInfoBuilderImpl() { - this(PortableProcessImpl.INSTANCE); + this(PortableProcessImpl.getInstance()); } WindowsUserInfoBuilderImpl(PortableProcess helper) { diff -r 006ac47d1506 -r cd5b08c32052 common/portability/src/main/java/com/redhat/thermostat/common/portability/linux/ProcDataSource.java --- a/common/portability/src/main/java/com/redhat/thermostat/common/portability/linux/ProcDataSource.java Thu Jan 26 12:14:51 2017 -0500 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/linux/ProcDataSource.java Mon Jan 30 10:30:19 2017 -0500 @@ -43,8 +43,8 @@ /** * Wrapper for files under {@code /proc/}. See proc(5) for details about this. * - * This class is inherently unportable, but a _lot_ of Linux code would need refactoring - * before it can be unexported from the portability package. + * This class is inherently unportable, but a _lot_ of Linux code needs refactoring + * before it can be make package private * * Note that different Unix-like OSs may or may not have a /proc (and the format may be different) * for example Darwin/OSX doesn't have /proc diff -r 006ac47d1506 -r cd5b08c32052 common/portability/src/test/java/com/redhat/thermostat/common/portability/ProcessCheckerTest.java --- a/common/portability/src/test/java/com/redhat/thermostat/common/portability/ProcessCheckerTest.java Thu Jan 26 12:14:51 2017 -0500 +++ b/common/portability/src/test/java/com/redhat/thermostat/common/portability/ProcessCheckerTest.java Mon Jan 30 10:30:19 2017 -0500 @@ -42,7 +42,6 @@ import java.io.File; -import com.redhat.thermostat.common.portability.ProcessChecker; import org.junit.Test; public class ProcessCheckerTest { diff -r 006ac47d1506 -r cd5b08c32052 common/portability/src/test/java/com/redhat/thermostat/common/portability/internal/linux/DistributionInformationTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/test/java/com/redhat/thermostat/common/portability/internal/linux/DistributionInformationTest.java Mon Jan 30 10:30:19 2017 -0500 @@ -0,0 +1,179 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.common.portability.internal.linux; + +import java.io.IOException; +import java.util.logging.Handler; +import java.util.logging.Logger; + +import com.redhat.thermostat.shared.config.OS; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class DistributionInformationTest { + + private Logger logger; + private TestLogHandler handler; + + @Before + public void setup() { + setupTestLogger(); + } + + @After + public void tearDown() { + if (handler != null) { + logger.removeHandler(handler); + handler = null; + } + } + + private void setupTestLogger() { + logger = Logger.getLogger("com.redhat.thermostat"); + handler = new TestLogHandler(); + logger.addHandler(handler); + } + + /* + * Verifies that no warning gets logged if EtcOsRelease fails, but + * LsbRelease works. Since LsbRelease is the fallback, all is well. + * + * see: http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=1628 + */ + @Test + public void testNoWarningLoggedOnFallback() { + // verify preconditions + assertFalse(handler.isEtcOsReleaseLogged()); + assertTestHandlerRegistered(); + + // Default LSB release + LsbRelease lsbRelease = new LsbRelease(); + // EtcOsRelease with non existent file + EtcOsRelease etcOsRelease = new EtcOsRelease(EtcOsReleaseTest.NOT_EXISTING_OS_RELEASE_FILE); + DistributionInformation.get(etcOsRelease, lsbRelease); + assertFalse(handler.isEtcOsReleaseLogged()); + } + + /* + * Verifies that a warning gets logged if os-release and lsb_release both + * fail. + * + * see: http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=1628 + */ + @Test + public void testWarningLoggedIfBothFail() { + // verify preconditions + assertFalse(handler.isEtcOsReleaseLogged()); + assertFalse(handler.isLsbReleaseLogged()); + assertTestHandlerRegistered(); + + // both etc-os-release and lsb-release don't exist for this test + EtcOsRelease etcOsRelease = new EtcOsRelease(EtcOsReleaseTest.NOT_EXISTING_OS_RELEASE_FILE); + LsbRelease lsbRelease = new LsbRelease(LsbReleaseTest.NOT_EXISTING_LSB_RELEASE); + + DistributionInformation info = DistributionInformation.get(etcOsRelease, lsbRelease); + assertFalse(handler.isEtcOsReleaseLogged()); + assertTrue(handler.isLsbReleaseLogged()); + assertNotNull(info); + assertEquals(DistributionInformation.UNKNOWN_NAME, info.getName()); + assertEquals(DistributionInformation.UNKNOWN_VERSION, info.getVersion()); + } + + @Test + public void verifyFallbackToLsbWhenEtcOsReturnsUnknown() throws IOException { + EtcOsRelease mockEtcOsRelease = mock(EtcOsRelease.class); + DistributionInformation mockDistro = mock(DistributionInformation.class); + when(mockEtcOsRelease.getDistributionInformation()).thenReturn(mockDistro); + when(mockDistro.getName()).thenReturn(DistributionInformation.UNKNOWN_NAME); + when(mockDistro.getVersion()).thenReturn(DistributionInformation.UNKNOWN_VERSION); + + LsbRelease mockLsbRelease = mock(LsbRelease.class); + DistributionInformation mockLsbDistro = mock(DistributionInformation.class); + when(mockLsbRelease.getDistributionInformation()).thenReturn(mockLsbDistro); + + DistributionInformation info = DistributionInformation.get(mockEtcOsRelease, mockLsbRelease); + assertSame("Expected lsb info to be used since etc returns unknown", + mockLsbDistro, info); + } + + private void assertTestHandlerRegistered() { + assertNotNull(logger); + boolean testLogHandlerRegistered = false; + for (Handler h: logger.getHandlers()) { + if (h instanceof TestLogHandler) { + testLogHandlerRegistered = true; + } + } + assertTrue(testLogHandlerRegistered); + } + + @Test + public void testName() { + if (OS.IS_LINUX) { + DistributionInformation info = DistributionInformation.get(); + String name = info.getName(); + assertNotNull(name); + assertTrue(name.length() > 0); + assertFalse(name.startsWith(":")); + assertFalse(name.equals(DistributionInformation.UNKNOWN_NAME)); + } + } + + @Test + public void testVersion() { + if (OS.IS_LINUX) { + DistributionInformation info = DistributionInformation.get(); + String version = info.getVersion(); + assertNotNull(version); + assertTrue(version.length()> 0); + assertFalse(version.startsWith(":")); + assertFalse(version.equals(DistributionInformation.UNKNOWN_VERSION)); + } + } + +} + diff -r 006ac47d1506 -r cd5b08c32052 common/portability/src/test/java/com/redhat/thermostat/common/portability/internal/linux/EtcOsReleaseTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/test/java/com/redhat/thermostat/common/portability/internal/linux/EtcOsReleaseTest.java Mon Jan 30 10:30:19 2017 -0500 @@ -0,0 +1,125 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.common.portability.internal.linux; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.StringReader; +import java.util.UUID; + +import com.redhat.thermostat.shared.config.OS; +import org.junit.Assume; +import org.junit.Test; + +import com.redhat.thermostat.common.internal.test.Bug; + +public class EtcOsReleaseTest { + + static final String NOT_EXISTING_OS_RELEASE_FILE = "/thermostat-os-release-testing-" + + UUID.randomUUID(); + + @Test + public void testName() throws IOException, InterruptedException { + BufferedReader reader = new BufferedReader(new StringReader("NAME=\"Name\"\n")); + DistributionInformation info = new EtcOsRelease().getFromOsRelease(reader); + assertEquals("Name", info.getName()); + } + + + @Test + public void testVersion() throws IOException { + BufferedReader reader = new BufferedReader(new StringReader("VERSION=\"Version\"\n")); + DistributionInformation info = new EtcOsRelease().getFromOsRelease(reader); + assertEquals("Version", info.getVersion()); + } + + @Bug(id="981", + summary="DistributionInformationTest fails on OpenSUSE Linux 12.1", + url="http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=981") + @Test + public void testFormattedOutput() throws IOException { + String output = + "NAME=openSUSE\n" + + "VERSION = 12.1 (Asparagus)\n" + + "VERSION_ID=\"12.1\"\n" + + "PRETTY_NAME=\"openSUSE 12.1 (Asparagus) (x86_64)\"\n" + + "ID=opensuse"; + BufferedReader reader = new BufferedReader(new StringReader(output)); + DistributionInformation info = new EtcOsRelease().getFromOsRelease(reader); + + assertEquals("openSUSE", info.getName()); + assertEquals("12.1 (Asparagus)", info.getVersion()); + } + + /** + * DistributionInformation falls back on LSB when /etc/os-release contains + * inconclusive content (empty in this case). It should not return some + * info as "Linux". + * + * @throws IOException + */ + @Test + public void testEmpty() throws IOException { + String output = ""; + BufferedReader reader = new BufferedReader(new StringReader(output)); + + DistributionInformation info = new EtcOsRelease().getFromOsRelease(reader); + assertEquals(DistributionInformation.UNKNOWN_NAME, info.getName()); + assertEquals(DistributionInformation.UNKNOWN_VERSION, info.getVersion()); + } + + @Test + public void getDistributionInformationThrowsIOExceptionIfFileNotThere() { + Assume.assumeTrue(OS.IS_LINUX); + EtcOsRelease etcOsRelease = new EtcOsRelease(NOT_EXISTING_OS_RELEASE_FILE); + try { + etcOsRelease.getDistributionInformation(); + fail("Should have thrown IOException, since file is not there!"); + } catch (IOException e) { + // pass + String message = e.getMessage(); + assertTrue(message.contains("/thermostat-os-release-testing-")); + assertTrue(message.contains("(No such file or directory)")); + } + } + +} + diff -r 006ac47d1506 -r cd5b08c32052 common/portability/src/test/java/com/redhat/thermostat/common/portability/internal/linux/LinuxPortableHostImplTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/test/java/com/redhat/thermostat/common/portability/internal/linux/LinuxPortableHostImplTest.java Mon Jan 30 10:30:19 2017 -0500 @@ -0,0 +1,126 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.common.portability.internal.linux; + +import com.redhat.thermostat.common.portability.PortableHost; +import com.redhat.thermostat.common.portability.linux.ProcDataSource; + +import java.io.IOException; +import java.io.StringReader; +import java.net.InetAddress; + +import com.redhat.thermostat.shared.config.OS; +import org.junit.Assume; +import org.junit.Test; + +import com.redhat.thermostat.common.Size; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +public class LinuxPortableHostImplTest { + + final int KILOBYTES_TO_BYTES = 1024; + + @Test + public void testSimpleBuild() { + Assume.assumeTrue(OS.IS_LINUX); + PortableHost info = new LinuxPortableHostImpl(new ProcDataSource()); + assertNotNull(info); + } + + @Test + public void testCpuInfo() throws IOException { + String cpuInfoString = + "processor: 1\n" + + "model name: Test Model\n" + + "processor: 0\n" + + "model name: Test Model\n"; + + StringReader cpuInfoReader = new StringReader(cpuInfoString); + + ProcDataSource dataSource = mock(ProcDataSource.class); + when(dataSource.getCpuInfoReader()).thenReturn(cpuInfoReader); + + LinuxPortableHostImpl.HostCpuInfo cpuInfo = new LinuxPortableHostImpl(dataSource).getCpuInfo(); + assertEquals(2, cpuInfo.count); + assertEquals("Test Model", cpuInfo.model); + verify(dataSource).getCpuInfoReader(); + } + + @Test + public void testMemoryInfo() throws IOException { + String memoryInfoString = + "MemTotal: 12345 kB"; + + StringReader memoryInfoReader = new StringReader(memoryInfoString); + ProcDataSource dataSource = mock(ProcDataSource.class); + when(dataSource.getMemInfoReader()).thenReturn(memoryInfoReader); + + LinuxPortableHostImpl memoryInfo = new LinuxPortableHostImpl(dataSource); + assertNotNull(memoryInfo); + assertEquals(Size.bytes(12345 * KILOBYTES_TO_BYTES), memoryInfo.getTotalMemorySize()); + verify(dataSource).getMemInfoReader(); + + } + + @Test + public void testOsInfo() { + DistributionInformation distroInfo = new DistributionInformation("distro-name", "distro-version"); + ProcDataSource dataSource = mock(ProcDataSource.class); + LinuxPortableHostImpl.HostOsInfo osInfo = new LinuxPortableHostImpl(dataSource).getOsInfo(distroInfo); + assertEquals("distro-name distro-version", osInfo.distribution); + assertEquals(System.getProperty("os.name") + " " + System.getProperty("os.version"), osInfo.kernel); + } + + @Test + public void testHostname() { + + InetAddress address = mock(InetAddress.class); + when(address.getCanonicalHostName()).thenReturn("test-hostname"); + + ProcDataSource dataSource = mock(ProcDataSource.class); + + String name = new LinuxPortableHostImpl(dataSource).getHostName(address); + assertEquals("test-hostname", name); + } + +} + diff -r 006ac47d1506 -r cd5b08c32052 common/portability/src/test/java/com/redhat/thermostat/common/portability/internal/linux/LinuxPortableProcessStatBuilderImplTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/test/java/com/redhat/thermostat/common/portability/internal/linux/LinuxPortableProcessStatBuilderImplTest.java Mon Jan 30 10:30:19 2017 -0500 @@ -0,0 +1,144 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.common.portability.internal.linux; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.io.IOException; +import java.io.StringReader; + +import com.redhat.thermostat.common.portability.PortableProcessStat; +import org.junit.Test; + +import com.redhat.thermostat.common.portability.linux.ProcDataSource; + +public class LinuxPortableProcessStatBuilderImplTest { + + @Test + public void testSimpleProcessStatus() { + ProcDataSource dataSource = new ProcDataSource(); + PortableProcessStat stat = new LinuxPortableProcessStatBuilderImpl(dataSource).build(1); + assertNotNull(stat); + } + + @Test + public void testKnownProcessStatus() throws IOException { + final int PID = 10363; + String PROCESS_NAME = "(bash)"; + String STATE = "S"; + String PPID = "1737"; + String PROCESS_GROUP_ID = "10363"; + String SESSION_ID = "10363"; + String TTY_NUMBER = "34817"; + String TTY_PROCESS_GROUP_ID = "11404"; + String FLAGS_WORD = "4202496"; + String MINOR_FAULTS = "8093"; + String MINOR_FAULTS_CHILDREN = "607263"; + String MAJOR_FAULTS = "1"; + String MAJOR_FAULTS_CHILDREN = "251"; + final long USER_TIME_TICKS = 21; + final long KERNEL_TIME_TICKS = 7; + final long USER_TIME_CHILDREN = 10; + String KERNEL_TIME_CHILDREN = "1000"; + String PRIORITY = "20"; + String statString = "" + + PID + " " + PROCESS_NAME + " " + STATE + " " + PPID + " " + + PROCESS_GROUP_ID + " " + SESSION_ID + " " + TTY_NUMBER + " " + + TTY_PROCESS_GROUP_ID + " " + FLAGS_WORD + " " + MINOR_FAULTS + " " + + MINOR_FAULTS_CHILDREN + " " + MAJOR_FAULTS + " " + MAJOR_FAULTS_CHILDREN + " " + + USER_TIME_TICKS + " " + KERNEL_TIME_TICKS + " " + USER_TIME_CHILDREN + " " + + KERNEL_TIME_CHILDREN + " " + PRIORITY; + + ProcDataSource dataSource = mock(ProcDataSource.class); + when(dataSource.getStatReader(any(Integer.class))).thenReturn(new StringReader(statString)); + LinuxPortableProcessStatBuilderImpl builder = new LinuxPortableProcessStatBuilderImpl(dataSource); + PortableProcessStat stat = builder.build(PID); + + verify(dataSource).getStatReader(PID); + assertNotNull(stat); + assertEquals(PID, stat.getPid()); + assertEquals(USER_TIME_TICKS, stat.getUserTime()); + assertEquals(KERNEL_TIME_TICKS, stat.getKernelTime()); + } + + @Test + public void testBadProcessName() throws IOException { + final int PID = 10363; + String PROCESS_NAME = "(secretly-bad process sleep 10 20 ) 6)"; + String STATE = "S"; + String PPID = "1737"; + String PROCESS_GROUP_ID = "10363"; + String SESSION_ID = "10363"; + String TTY_NUMBER = "34817"; + String TTY_PROCESS_GROUP_ID = "11404"; + String FLAGS_WORD = "4202496"; + String MINOR_FAULTS = "8093"; + String MINOR_FAULTS_CHILDREN = "607263"; + String MAJOR_FAULTS = "1"; + String MAJOR_FAULTS_CHILDREN = "251"; + final long USER_TIME_TICKS = 21; + final long KERNEL_TIME_TICKS = 7; + final long USER_TIME_CHILDREN = 10; + String KERNEL_TIME_CHILDREN = "1000"; + String PRIORITY = "20"; + String statString = "" + + PID + " " + PROCESS_NAME + " " + STATE + " " + PPID + " " + + PROCESS_GROUP_ID + " " + SESSION_ID + " " + TTY_NUMBER + " " + + TTY_PROCESS_GROUP_ID + " " + FLAGS_WORD + " " + MINOR_FAULTS + " " + + MINOR_FAULTS_CHILDREN + " " + MAJOR_FAULTS + " " + MAJOR_FAULTS_CHILDREN + " " + + USER_TIME_TICKS + " " + KERNEL_TIME_TICKS + " " + USER_TIME_CHILDREN + " " + + KERNEL_TIME_CHILDREN + " " + PRIORITY; + + ProcDataSource dataSource = mock(ProcDataSource.class); + when(dataSource.getStatReader(any(Integer.class))).thenReturn(new StringReader(statString)); + LinuxPortableProcessStatBuilderImpl builder = new LinuxPortableProcessStatBuilderImpl(dataSource); + PortableProcessStat stat = builder.build(PID); + + verify(dataSource).getStatReader(PID); + assertNotNull(stat); + assertEquals(PID, stat.getPid()); + assertEquals(USER_TIME_TICKS, stat.getUserTime()); + assertEquals(KERNEL_TIME_TICKS, stat.getKernelTime()); + } + +} + diff -r 006ac47d1506 -r cd5b08c32052 common/portability/src/test/java/com/redhat/thermostat/common/portability/internal/linux/LinuxProcessEnvironmentBuilderImplTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/test/java/com/redhat/thermostat/common/portability/internal/linux/LinuxProcessEnvironmentBuilderImplTest.java Mon Jan 30 10:30:19 2017 -0500 @@ -0,0 +1,137 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.common.portability.internal.linux; + +import com.redhat.thermostat.common.portability.linux.ProcDataSource; +import org.mockito.Matchers; +import org.mockito.Mockito; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.util.Map; +import java.util.Random; + +import com.redhat.thermostat.shared.config.OS; +import org.junit.Assume; +import org.junit.Test; + +import com.redhat.thermostat.testutils.TestUtils; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + + +public class LinuxProcessEnvironmentBuilderImplTest { + + private final Random r = new Random(); + + @Test + public void testBasicBuild() { + Assume.assumeTrue(OS.IS_LINUX); + ProcDataSource dataSource = new ProcDataSource(); + Map result = new LinuxProcessEnvironmentBuilderImpl(dataSource).build(TestUtils.getProcessId()); + assertNotNull(result); + assertFalse(result.isEmpty()); + assertTrue(result.containsKey("USER")); + } + + @Test + public void testCustomEnvironment() throws IOException { + byte[] data = ("USER=test\000HOME=house\000").getBytes(); + + Reader r = new InputStreamReader(new ByteArrayInputStream(data)); + ProcDataSource dataSource = Mockito.mock(ProcDataSource.class); + Mockito.when(dataSource.getEnvironReader(Matchers.any(Integer.class))).thenReturn(r); + + Map result = new LinuxProcessEnvironmentBuilderImpl(dataSource).build(0); + + Mockito.verify(dataSource).getEnvironReader(Matchers.eq(0)); + assertEquals("test", result.get("USER")); + assertEquals("house", result.get("HOME")); + } + + @Test + public void testLargeRandomEnvironment() throws IOException { + int TEST_ENV_SIZE = 1024 * 1024; + byte[] data = new byte[TEST_ENV_SIZE]; + int currentPosition = 0; + do { + byte[] key = generateRandomBytes(); + byte[] value = generateRandomBytes(); + if (currentPosition + key.length + value.length + 2 >= data.length) { + break; + } + System.arraycopy(key, 0, data, currentPosition, key.length); + currentPosition += key.length; + data[currentPosition] = (byte) '='; + currentPosition++; + System.arraycopy(value, 0, data, currentPosition, value.length); + currentPosition += value.length; + data[currentPosition] = 0x00; + currentPosition++; + } while (true); + Reader r = new InputStreamReader(new ByteArrayInputStream(data, 0, currentPosition)); + ProcDataSource dataSource = Mockito.mock(ProcDataSource.class); + Mockito.when(dataSource.getEnvironReader(Matchers.any(Integer.class))).thenReturn(r); + + Map result = new LinuxProcessEnvironmentBuilderImpl(dataSource).build(0); + + Mockito.verify(dataSource).getEnvironReader(Matchers.eq(0)); + assertNotNull(result); + } + + private byte[] generateRandomBytes() { + byte start = (byte) 'a'; + byte end = (byte) 'z' + 1; + + byte[] alphabet = new byte[end - start]; + for (int i = 0; i < (end-start); i++) { + alphabet[i] = (byte) (i + start); + } + int size = r.nextInt(15) + 10; + byte[] result = new byte[size]; + for (int i = 0; i < result.length; i++) { + result[i] = alphabet[r.nextInt(alphabet.length)]; + } + return result; + } +} + diff -r 006ac47d1506 -r cd5b08c32052 common/portability/src/test/java/com/redhat/thermostat/common/portability/internal/linux/LsbReleaseTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/test/java/com/redhat/thermostat/common/portability/internal/linux/LsbReleaseTest.java Mon Jan 30 10:30:19 2017 -0500 @@ -0,0 +1,91 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.common.portability.internal.linux; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.StringReader; +import java.util.UUID; + +import com.redhat.thermostat.common.portability.internal.linux.DistributionInformation; +import com.redhat.thermostat.common.portability.internal.linux.LsbRelease; +import com.redhat.thermostat.shared.config.OS; +import org.junit.Assume; +import org.junit.Test; + +public class LsbReleaseTest { + + static final String NOT_EXISTING_LSB_RELEASE = "lsb_release-" + + UUID.randomUUID(); + + @Test + public void testName() throws IOException, InterruptedException { + Assume.assumeTrue(OS.IS_LINUX); + BufferedReader reader = new BufferedReader(new StringReader("Distributor ID: Name")); + DistributionInformation info = new LsbRelease().getFromLsbRelease(reader); + assertEquals("Name", info.getName()); + } + + @Test + public void testVersion() throws IOException { + Assume.assumeTrue(OS.IS_LINUX); + BufferedReader reader = new BufferedReader(new StringReader("Release: Version")); + DistributionInformation info = new LsbRelease().getFromLsbRelease(reader); + assertEquals("Version", info.getVersion()); + } + + @Test + public void getDistributionInformationThrowsIOExceptionIfScriptNotThere() { + Assume.assumeTrue(OS.IS_LINUX); + LsbRelease lsbRelease = new LsbRelease(NOT_EXISTING_LSB_RELEASE); + try { + lsbRelease.getDistributionInformation(); + fail("Should have thrown IOException, since file is not there!"); + } catch (IOException e) { + // pass + String message = e.getMessage(); + assertTrue(message.contains("Cannot run program \"lsb_release-")); + assertTrue(message.contains("No such file or directory")); + } + } + +} + diff -r 006ac47d1506 -r cd5b08c32052 common/portability/src/test/java/com/redhat/thermostat/common/portability/internal/linux/TestLogHandler.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/test/java/com/redhat/thermostat/common/portability/internal/linux/TestLogHandler.java Mon Jan 30 10:30:19 2017 -0500 @@ -0,0 +1,87 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.common.portability.internal.linux; + +import java.util.logging.Handler; +import java.util.logging.Level; +import java.util.logging.LogRecord; + +/* + * Test log handler used for DistributionInformation log testing. + */ +public class TestLogHandler extends Handler { + + private boolean etcOsReleaseLogged; + private boolean lsbReleaseLogged; + private static final String EXPECTED_OS_RELEASE_FAIL_MSG = + "unable to use os-release"; + private static final String EXPECTED_LSB_RELEASE_FAIL_MSG = + "unable to use os-release AND lsb_release"; + + @Override + public void publish(LogRecord record) { + String logMessage = record.getMessage(); + if (record.getLevel().intValue() >= Level.WARNING.intValue() && + logMessage.equals(EXPECTED_OS_RELEASE_FAIL_MSG)) { + etcOsReleaseLogged = true; + }; + if (record.getLevel().intValue() >= Level.WARNING.intValue() && + logMessage.equals(EXPECTED_LSB_RELEASE_FAIL_MSG)) { + lsbReleaseLogged = true; + } + } + + @Override + public void flush() { + // nothing + } + + @Override + public void close() throws SecurityException { + // nothing + } + + boolean isEtcOsReleaseLogged() { + return etcOsReleaseLogged; + } + + boolean isLsbReleaseLogged() { + return lsbReleaseLogged; + } + +} + diff -r 006ac47d1506 -r cd5b08c32052 common/portability/src/test/java/com/redhat/thermostat/common/portability/internal/linux/vmio/LinuxVmIoStatBuilderTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/test/java/com/redhat/thermostat/common/portability/internal/linux/vmio/LinuxVmIoStatBuilderTest.java Mon Jan 30 10:30:19 2017 -0500 @@ -0,0 +1,91 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.common.portability.internal.linux.vmio; + +import com.redhat.thermostat.common.portability.PortableVmIoStat; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import org.junit.Test; + +import com.redhat.thermostat.common.Clock; + +public class LinuxVmIoStatBuilderTest { + + + @Test + public void testBuilderBuildsNullForUnknownPid() { + Clock clock = mock(Clock.class); + ProcIoDataReader procDataReader = mock(ProcIoDataReader.class); + LinuxVmIoStatBuilderImpl builder = new LinuxVmIoStatBuilderImpl(clock, procDataReader); + PortableVmIoStat result = builder.build(0); + assertNull(result); + } + + @Test + public void testBuildWithSufficientInformation() { + final int PID = 0; + + int rchar = 1; + int wchar = 2; + int syscr = 3; + int syscw = 4; + int read_bytes = 5; + int write_bytes = 6; + int cancelled_write_bytes = 7; + + final ProcIoData data = new ProcIoData(rchar, wchar, syscr, syscw, + read_bytes, write_bytes, cancelled_write_bytes); + + ProcIoDataReader ioReader = mock(ProcIoDataReader.class); + when(ioReader.read(PID)).thenReturn(data); + Clock clock = mock(Clock.class); + + LinuxVmIoStatBuilderImpl builder = new LinuxVmIoStatBuilderImpl(clock, ioReader); + + PortableVmIoStat ioData = builder.build(PID); + assertNotNull(ioData); + assertEquals(rchar, ioData.getCharactersRead()); + assertEquals(wchar, ioData.getCharactersWritten()); + assertEquals(syscr, ioData.getReadSyscalls()); + assertEquals(syscw, ioData.getWriteSyscalls()); + } + +} diff -r 006ac47d1506 -r cd5b08c32052 common/portability/src/test/java/com/redhat/thermostat/common/portability/internal/linux/vmio/ProcIoDataReaderTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/test/java/com/redhat/thermostat/common/portability/internal/linux/vmio/ProcIoDataReaderTest.java Mon Jan 30 10:30:19 2017 -0500 @@ -0,0 +1,76 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.common.portability.internal.linux.vmio; + +import java.io.StringReader; + +import org.junit.Test; + +import com.redhat.thermostat.common.portability.linux.ProcDataSource; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class ProcIoDataReaderTest { + + @Test + public void verifyIsParsedCorrectly() throws Exception { + final int SOME_PID = 0; + String fileContents = "" + + "rchar: 19961133\n" + + "wchar: 2451715\n" + + "syscr: 17880\n" + + "syscw: 13870\n" + + "read_bytes: 21004288\n" + + "write_bytes: 811008\n" + + "cancelled_write_bytes: 16384\n"; + ProcDataSource dataSource = mock(ProcDataSource.class); + when(dataSource.getIoReader(SOME_PID)).thenReturn(new StringReader(fileContents)); + + ProcIoData parsedData = new ProcIoDataReader(dataSource).read(SOME_PID); + + assertEquals(19961133, parsedData.rchar); + assertEquals(2451715, parsedData.wchar); + assertEquals(17880, parsedData.syscr); + assertEquals(13870, parsedData.syscw); + assertEquals(21004288, parsedData.read_bytes); + assertEquals(811008, parsedData.write_bytes); + assertEquals(16384, parsedData.cancelled_write_bytes); + + } +} diff -r 006ac47d1506 -r cd5b08c32052 common/portability/src/test/java/com/redhat/thermostat/common/portability/internal/windows/WindowsHelperImplTest.java --- a/common/portability/src/test/java/com/redhat/thermostat/common/portability/internal/windows/WindowsHelperImplTest.java Thu Jan 26 12:14:51 2017 -0500 +++ b/common/portability/src/test/java/com/redhat/thermostat/common/portability/internal/windows/WindowsHelperImplTest.java Mon Jan 30 10:30:19 2017 -0500 @@ -38,7 +38,6 @@ import com.redhat.thermostat.shared.config.OS; -import org.junit.Assert; import org.junit.Assume; import org.junit.Ignore; import org.junit.Test; @@ -61,21 +60,21 @@ public void loadNativeLib() { Assume.assumeTrue(OS.IS_WINDOWS); final WindowsHelperImpl impl = WindowsHelperImpl.INSTANCE; - Assert.assertNotNull(impl); + assertNotNull(impl); } @Test public void testGetHostInfo() { Assume.assumeTrue(OS.IS_WINDOWS); final WindowsHelperImpl impl = WindowsHelperImpl.INSTANCE; - Assert.assertNotNull(impl); + assertNotNull(impl); assertContainsData(impl.getHostName()); assertContainsData(impl.getOSName()); - Assert.assertTrue(impl.getOSName().toLowerCase().contains("win")); + assertTrue(impl.getOSName().toLowerCase().contains("win")); assertContainsData(impl.getOSVersion()); assertContainsData(impl.getCPUModel()); - Assert.assertTrue(impl.getCPUCount() > 0); - Assert.assertTrue(impl.getTotalMemory() > 0); + assertTrue(impl.getCPUCount() > 0); + assertTrue(impl.getTotalMemory() > 0); } @Test @@ -83,17 +82,17 @@ public void testGetProcessInfo() { Assume.assumeTrue(OS.IS_WINDOWS); final WindowsHelperImpl impl = WindowsHelperImpl.INSTANCE; - Assert.assertNotNull(impl); + assertNotNull(impl); int pid = /*TODO: retrieve current process identifier*/0; assertContainsData(impl.getUserName(pid)); - Assert.assertTrue(impl.getUid(pid) >= 0); + assertTrue(impl.getUid(pid) >= 0); Map envMap = impl.getEnvironment(pid); - Assert.assertNotNull(envMap); - Assert.assertFalse(envMap.isEmpty()); + assertNotNull(envMap); + assertFalse(envMap.isEmpty()); } private static void assertContainsData( final String s ) { - Assert.assertNotNull(s); - Assert.assertFalse(s.isEmpty()); + assertNotNull(s); + assertFalse(s.isEmpty()); } } diff -r 006ac47d1506 -r cd5b08c32052 common/portability/src/test/java/com/redhat/thermostat/common/portability/internal/windows/WindowsProcessUserInfoBuilderTest.java --- a/common/portability/src/test/java/com/redhat/thermostat/common/portability/internal/windows/WindowsProcessUserInfoBuilderTest.java Thu Jan 26 12:14:51 2017 -0500 +++ b/common/portability/src/test/java/com/redhat/thermostat/common/portability/internal/windows/WindowsProcessUserInfoBuilderTest.java Mon Jan 30 10:30:19 2017 -0500 @@ -41,7 +41,6 @@ import com.redhat.thermostat.common.portability.PortableProcess; import com.redhat.thermostat.shared.config.OS; -import org.junit.Assert; import org.junit.Assume; import org.junit.Before; import org.junit.Ignore; @@ -81,7 +80,7 @@ public void testSimpleBuild() { Assume.assumeTrue(OS.IS_WINDOWS); ProcessUserInfo info = new WindowsUserInfoBuilderImpl().build(FAKE_PID); - Assert.assertNotNull(info); + assertNotNull(info); } @Test @@ -96,7 +95,7 @@ public void testGetInfoFromBadPid() { final ProcessUserInfoBuilder ib = new WindowsUserInfoBuilderImpl(whelp); final ProcessUserInfo hi = ib.build(FAKE_PID+1); - Assert.assertNotSame(FAKE_USERNAME,hi.getUsername()); - Assert.assertNotSame(FAKE_UID, hi.getUid()); + assertNotSame(FAKE_USERNAME,hi.getUsername()); + assertNotSame(FAKE_UID, hi.getUid()); } } diff -r 006ac47d1506 -r cd5b08c32052 common/portability/src/test/java/com/redhat/thermostat/common/portability/linux/ProcDataSourceTest.java --- a/common/portability/src/test/java/com/redhat/thermostat/common/portability/linux/ProcDataSourceTest.java Thu Jan 26 12:14:51 2017 -0500 +++ b/common/portability/src/test/java/com/redhat/thermostat/common/portability/linux/ProcDataSourceTest.java Mon Jan 30 10:30:19 2017 -0500 @@ -36,44 +36,43 @@ package com.redhat.thermostat.common.portability.linux; -import static org.junit.Assert.*; - import java.io.IOException; import java.io.Reader; -import com.redhat.thermostat.common.portability.linux.ProcDataSource; import com.redhat.thermostat.shared.config.OS; + +import com.redhat.thermostat.testutils.TestUtils; + import org.junit.Assume; import org.junit.Test; - -import com.redhat.thermostat.testutils.TestUtils; +import static org.junit.Assert.assertNotNull; public class ProcDataSourceTest { @Test public void testGetCpuInfoReader() throws IOException { - Assume.assumeTrue(OS.IS_UNIX); + Assume.assumeTrue(OS.IS_LINUX); Reader r = new ProcDataSource().getCpuInfoReader(); assertNotNull(r); } @Test public void testGetCpuLoadReader() throws IOException { - Assume.assumeTrue(OS.IS_UNIX); + Assume.assumeTrue(OS.IS_LINUX); Reader r = new ProcDataSource().getCpuLoadReader(); assertNotNull(r); } @Test public void testGetMemInfoReader() throws IOException { - Assume.assumeTrue(OS.IS_UNIX); + Assume.assumeTrue(OS.IS_LINUX); Reader r = new ProcDataSource().getMemInfoReader(); assertNotNull(r); } @Test public void testGetStatReader() throws IOException { - Assume.assumeTrue(OS.IS_UNIX); + Assume.assumeTrue(OS.IS_LINUX); int pid = TestUtils.getProcessId(); Reader r = new ProcDataSource().getStatReader(pid); assertNotNull(r); @@ -81,7 +80,7 @@ @Test public void testGetEnvironReader() throws IOException { - Assume.assumeTrue(OS.IS_UNIX); + Assume.assumeTrue(OS.IS_LINUX); int pid = TestUtils.getProcessId(); Reader r = new ProcDataSource().getEnvironReader(pid); assertNotNull(r); @@ -89,7 +88,7 @@ @Test public void testIoReader() throws Exception { - Assume.assumeTrue(OS.IS_UNIX); + Assume.assumeTrue(OS.IS_LINUX); int pid = TestUtils.getProcessId(); Reader r = new ProcDataSource().getIoReader(pid); assertNotNull(r); @@ -97,7 +96,7 @@ @Test public void testStatReader() throws Exception { - Assume.assumeTrue(OS.IS_UNIX); + Assume.assumeTrue(OS.IS_LINUX); int pid = TestUtils.getProcessId(); Reader r = new ProcDataSource().getStatReader(pid); assertNotNull(r); @@ -105,7 +104,7 @@ @Test public void testStatusReader() throws Exception { - Assume.assumeTrue(OS.IS_UNIX); + Assume.assumeTrue(OS.IS_LINUX); int pid = TestUtils.getProcessId(); Reader r = new ProcDataSource().getStatusReader(pid); assertNotNull(r); diff -r 006ac47d1506 -r cd5b08c32052 distribution/windows/scripts/thermostat-ipc-client-common.cmd --- a/distribution/windows/scripts/thermostat-ipc-client-common.cmd Thu Jan 26 12:14:51 2017 -0500 +++ b/distribution/windows/scripts/thermostat-ipc-client-common.cmd Mon Jan 30 10:30:19 2017 -0500 @@ -52,7 +52,7 @@ set IPC_CLASSPATH=%IPC_CLASSPATH%;%THERMOSTAT_LIBS%\jnr-ffi-@jnr-ffi.version@.jar set IPC_CLASSPATH=%IPC_CLASSPATH%;%THERMOSTAT_LIBS%\jnr-x86asm-@jnr-x86asm.version@.jar set IPC_CLASSPATH=%IPC_CLASSPATH%;%THERMOSTAT_LIBS%\jffi-@jffi.version@.jar -set IPC_CLASSPATH=%IPC_CLASSPATH%;%THERMOSTAT_LIBS%\jffi-@jffi.version%-native.jar +set IPC_CLASSPATH=%IPC_CLASSPATH%;%THERMOSTAT_LIBS%\jffi-@jffi.version@-native.jar set IPC_CLASSPATH=%IPC_CLASSPATH%;%THERMOSTAT_LIBS%\asm-@asm.version@.jar set IPC_CLASSPATH=%IPC_CLASSPATH%;%THERMOSTAT_LIBS%\asm-commons-@asm.version@.jar set IPC_CLASSPATH=%IPC_CLASSPATH%;%THERMOSTAT_LIBS%\asm-util-@asm.version@.jar diff -r 006ac47d1506 -r cd5b08c32052 host-cpu/agent/src/main/java/com/redhat/thermostat/host/cpu/agent/internal/CpuStatBuilder.java --- a/host-cpu/agent/src/main/java/com/redhat/thermostat/host/cpu/agent/internal/CpuStatBuilder.java Thu Jan 26 12:14:51 2017 -0500 +++ b/host-cpu/agent/src/main/java/com/redhat/thermostat/host/cpu/agent/internal/CpuStatBuilder.java Mon Jan 30 10:30:19 2017 -0500 @@ -74,12 +74,8 @@ throw new IllegalStateException("already initialized"); } - if (OS.IS_WINDOWS) { - logger.log(Level.WARNING, "CPU backend is not yet ported to Windows"); - } - previousTime = clock.getMonotonicTimeNanos(); - previousCpuTicks = OS.IS_LINUX ? getCurrentCpuTicksLinux() : getCurrentCpuTicksWindows(); + previousCpuTicks = OS.IS_LINUX ? getCurrentCpuTicksLinux() : getCurrentCpuTicks(); initialized = true; } @@ -90,7 +86,7 @@ long currentRealTime = clock.getRealTimeMillis(); long currentTime = clock.getMonotonicTimeNanos(); - long[] currentValues = OS.IS_LINUX ? getCurrentCpuTicksLinux() : getCurrentCpuTicksWindows(); + long[] currentValues = OS.IS_LINUX ? getCurrentCpuTicksLinux() : getCurrentCpuTicks(); double[] cpuUsage = new double[currentValues.length]; @@ -137,7 +133,7 @@ return values; } - private long[] getCurrentCpuTicksWindows() { + private long[] getCurrentCpuTicks() { long[] values = new long[1]; values[0] = clock.getMonotonicTimeNanos(); return values; diff -r 006ac47d1506 -r cd5b08c32052 host-memory/agent/src/main/java/com/redhat/thermostat/host/memory/agent/internal/MemoryStatBuilder.java --- a/host-memory/agent/src/main/java/com/redhat/thermostat/host/memory/agent/internal/MemoryStatBuilder.java Thu Jan 26 12:14:51 2017 -0500 +++ b/host-memory/agent/src/main/java/com/redhat/thermostat/host/memory/agent/internal/MemoryStatBuilder.java Mon Jan 30 10:30:19 2017 -0500 @@ -57,7 +57,7 @@ private static final long UNAVAILABLE = -1; - private static final boolean IS_UNIX = OS.IS_UNIX; + private static final boolean IS_LINUX = OS.IS_LINUX; private static final String KEY_MEMORY_TOTAL = "MemTotal"; private static final String KEY_MEMORY_FREE = "MemFree"; @@ -75,13 +75,10 @@ public MemoryStatBuilder(ProcDataSource dataSource, WriterID writerId) { this.dataSource = dataSource; this.writerId = writerId; - if (OS.IS_WINDOWS) { - logger.log(Level.WARNING, "Memory backend is not yet ported to Windows"); - } } protected MemoryStat build() { - return IS_UNIX ? buildFromLinuxProc() : buildFromWindows(); + return IS_LINUX ? buildFromLinuxProc() : buildPortably(); } private MemoryStat buildFromLinuxProc() { @@ -127,7 +124,7 @@ } - private MemoryStat buildFromWindows() { + private MemoryStat buildPortably() { long timestamp = System.currentTimeMillis(); PortableMemoryStat memstat = PortableMemoryStat.build(); diff -r 006ac47d1506 -r cd5b08c32052 keyring/pom.xml --- a/keyring/pom.xml Thu Jan 26 12:14:51 2017 -0500 +++ b/keyring/pom.xml Mon Jan 30 10:30:19 2017 -0500 @@ -52,12 +52,12 @@ linux - Unix + linux .sh gcc - + linux lib .so @@ -102,12 +102,6 @@ all - - - JAVA_HOME - ${java.home} - - @@ -169,7 +163,7 @@ - + diff -r 006ac47d1506 -r cd5b08c32052 keyring/src/main/java/com/redhat/thermostat/utils/keyring/internal/Activator.java --- a/keyring/src/main/java/com/redhat/thermostat/utils/keyring/internal/Activator.java Thu Jan 26 12:14:51 2017 -0500 +++ b/keyring/src/main/java/com/redhat/thermostat/utils/keyring/internal/Activator.java Mon Jan 30 10:30:19 2017 -0500 @@ -79,7 +79,7 @@ try { theKeyring = new KeyringImpl(); } catch (UnsatisfiedLinkError e) { - if (OS.IS_UNIX) { + if (OS.IS_LINUX) { theKeyring = new DummyKeyringImpl(); } else { diff -r 006ac47d1506 -r cd5b08c32052 laf-utils/pom.xml --- a/laf-utils/pom.xml Thu Jan 26 12:14:51 2017 -0500 +++ b/laf-utils/pom.xml Mon Jan 30 10:30:19 2017 -0500 @@ -53,7 +53,7 @@ linux - unix + linux @@ -136,7 +136,7 @@ - + diff -r 006ac47d1506 -r cd5b08c32052 numa/agent/src/main/java/com/redhat/thermostat/numa/agent/internal/Activator.java --- a/numa/agent/src/main/java/com/redhat/thermostat/numa/agent/internal/Activator.java Thu Jan 26 12:14:51 2017 -0500 +++ b/numa/agent/src/main/java/com/redhat/thermostat/numa/agent/internal/Activator.java Mon Jan 30 10:30:19 2017 -0500 @@ -80,10 +80,10 @@ NumaDAO numaDAO = services.get(NumaDAO.class); Version version = new Version(context.getBundle()); WriterID writerId = services.get(WriterID.class); - NumaCollector collector = OS.IS_LINUX ? new NumaLinuxCollectorImpl() : new NumaWindowsCollectorImpl(); + NumaCollector collector = OS.IS_LINUX ? new NumaLinuxCollectorImpl() : new NumaCollectorImpl(); backend = new NumaBackend(appService, numaDAO, collector, version, writerId); reg = context.registerService(Backend.class, backend, null); - if (OS.IS_WINDOWS) { + if (!OS.IS_LINUX) { logger.log(Level.WARNING, "NUMA backend is not yet ported to Windows"); } } diff -r 006ac47d1506 -r cd5b08c32052 numa/agent/src/main/java/com/redhat/thermostat/numa/agent/internal/NumaCollectorImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/numa/agent/src/main/java/com/redhat/thermostat/numa/agent/internal/NumaCollectorImpl.java Mon Jan 30 10:30:19 2017 -0500 @@ -0,0 +1,57 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.numa.agent.internal; + +import com.redhat.thermostat.numa.common.NumaNodeStat; + +import java.io.IOException; + +public class NumaCollectorImpl implements NumaCollector { + + @Override + public NumaNodeStat[] collectData() throws IOException { + final NumaNodeStat[] nsa = new NumaNodeStat[1]; + final NumaNodeStat ns = new NumaNodeStat(); + nsa[0] = ns; + return nsa; + } + + @Override + public int getNumberOfNumaNodes() { + return 1; + } +} diff -r 006ac47d1506 -r cd5b08c32052 numa/agent/src/main/java/com/redhat/thermostat/numa/agent/internal/NumaWindowsCollectorImpl.java --- a/numa/agent/src/main/java/com/redhat/thermostat/numa/agent/internal/NumaWindowsCollectorImpl.java Thu Jan 26 12:14:51 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.numa.agent.internal; - -import com.redhat.thermostat.numa.common.NumaNodeStat; - -import java.io.IOException; - -public class NumaWindowsCollectorImpl implements NumaCollector { - - @Override - public NumaNodeStat[] collectData() throws IOException { - final NumaNodeStat[] nsa = new NumaNodeStat[1]; - final NumaNodeStat ns = new NumaNodeStat(); - nsa[0] = ns; - return nsa; - } - - @Override - public int getNumberOfNumaNodes() { - return 1; - } -} diff -r 006ac47d1506 -r cd5b08c32052 pom.xml --- a/pom.xml Thu Jan 26 12:14:51 2017 -0500 +++ b/pom.xml Mon Jan 30 10:30:19 2017 -0500 @@ -61,12 +61,12 @@ linux - Unix + linux .sh gcc - + linux lib .so diff -r 006ac47d1506 -r cd5b08c32052 process-handler/src/main/java/com/redhat/thermostat/service/internal/windows/WindowsProcessUtilities.java --- a/process-handler/src/main/java/com/redhat/thermostat/service/internal/windows/WindowsProcessUtilities.java Thu Jan 26 12:14:51 2017 -0500 +++ b/process-handler/src/main/java/com/redhat/thermostat/service/internal/windows/WindowsProcessUtilities.java Mon Jan 30 10:30:19 2017 -0500 @@ -74,7 +74,7 @@ @Override public void sendSignal(Integer pid, UNIXSignal signal) { - PortableProcessImpl.INSTANCE.terminateProcess(pid); + PortableProcessImpl.getInstance().terminateProcess(pid); } } diff -r 006ac47d1506 -r cd5b08c32052 system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/HostInfoBuilderImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/HostInfoBuilderImpl.java Mon Jan 30 10:30:19 2017 -0500 @@ -0,0 +1,73 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.backend.system.internal; + +import com.redhat.thermostat.common.portability.PortableHost; +import com.redhat.thermostat.backend.system.internal.models.HostInfoBuilder; +import com.redhat.thermostat.common.portability.PortableHostImpl; +import com.redhat.thermostat.storage.core.WriterID; +import com.redhat.thermostat.storage.model.HostInfo; + +/** + * Build Host information via helper classes + */ +class HostInfoBuilderImpl implements HostInfoBuilder { + + private final WriterID writerID; + private final PortableHost helper; + + HostInfoBuilderImpl(final WriterID writerID) { + this(writerID, PortableHostImpl.getInstance()); + } + + HostInfoBuilderImpl(final WriterID writerID, PortableHost helper) { + this.writerID = writerID; + this.helper = helper; + } + + @Override + public HostInfo build() { + String wId = writerID.getWriterID(); + return new HostInfo(wId, + helper.getHostName(), + helper.getOSName(), + helper.getOSVersion(), + helper.getCPUModel(), + helper.getCPUCount(), + helper.getTotalMemory()); + } +} diff -r 006ac47d1506 -r cd5b08c32052 system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/InfoBuilderFactoryImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/InfoBuilderFactoryImpl.java Mon Jan 30 10:30:19 2017 -0500 @@ -0,0 +1,67 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.backend.system.internal; + +import com.redhat.thermostat.common.portability.ProcessUserInfo; +import com.redhat.thermostat.common.portability.ProcessUserInfoBuilder; +import com.redhat.thermostat.common.portability.UserNameUtil; +import com.redhat.thermostat.backend.system.internal.models.HostInfoBuilder; +import com.redhat.thermostat.backend.system.internal.models.InfoBuilderFactory; +import com.redhat.thermostat.backend.system.internal.models.ProcessEnvironmentBuilder; +import com.redhat.thermostat.common.portability.linux.ProcDataSource; +import com.redhat.thermostat.storage.core.WriterID; + +/** + * Allows callers to access Windows-specific builders portably + */ +public class InfoBuilderFactoryImpl implements InfoBuilderFactory { + + public InfoBuilderFactoryImpl() { + } + + public HostInfoBuilder createHostInfoBuilder(final WriterID writerID) { + return new HostInfoBuilderImpl(writerID); + } + + public ProcessEnvironmentBuilder createProcessEnvironmentBuilder() { + return new ProcessEnvironmentBuilderImpl(); + } + + public ProcessUserInfoBuilder createProcessUserInfoBuilder(final UserNameUtil userNameUtil) { + return ProcessUserInfo.createBuilder(new ProcDataSource(), userNameUtil); + } +} diff -r 006ac47d1506 -r cd5b08c32052 system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/ProcessEnvironmentBuilderImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/ProcessEnvironmentBuilderImpl.java Mon Jan 30 10:30:19 2017 -0500 @@ -0,0 +1,64 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.backend.system.internal; + +import com.redhat.thermostat.backend.system.internal.models.ProcessEnvironmentBuilder; +import com.redhat.thermostat.common.portability.PortableProcess; +import com.redhat.thermostat.common.portability.PortableProcessImpl; + +import java.util.Map; + +/** + * Build process environment information via portable helper classes + */ +class ProcessEnvironmentBuilderImpl implements ProcessEnvironmentBuilder { + + private final PortableProcess helper; + + ProcessEnvironmentBuilderImpl() { + this(PortableProcessImpl.getInstance()); + } + + ProcessEnvironmentBuilderImpl(PortableProcess wh) { + helper = wh; + } + + @Override + public Map build(int pid) { + return helper.getEnvironment(pid); + } +} diff -r 006ac47d1506 -r cd5b08c32052 system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/linux/DistributionInformation.java --- a/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/linux/DistributionInformation.java Thu Jan 26 12:14:51 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,107 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.backend.system.internal.linux; - -import java.io.IOException; -import java.util.logging.Level; -import java.util.logging.Logger; - -import com.redhat.thermostat.common.utils.LoggingUtils; - -public class DistributionInformation { - - public static final String UNKNOWN_NAME = "Unknown Distribution"; - public static final String UNKNOWN_VERSION = "Unknown Version"; - - private static final Logger logger = LoggingUtils.getLogger(DistributionInformation.class); - - private final String name; - private final String version; - - public DistributionInformation(String name, String version) { - this.name = name; - this.version = version; - } - - public static DistributionInformation get() { - EtcOsRelease etcOsRelease = new EtcOsRelease(); - LsbRelease lsbRelease = new LsbRelease(); - return get(etcOsRelease, lsbRelease); - } - - // package-private for testing - static DistributionInformation get(EtcOsRelease etcOsRelease, LsbRelease lsbRelease) { - try { - DistributionInformation etcOsDistroInfo = etcOsRelease.getDistributionInformation(); - // if both name and version are unknown defer to lsb fallback - if (!DistributionInformation.UNKNOWN_NAME.equals(etcOsDistroInfo.getName()) && - !DistributionInformation.UNKNOWN_VERSION.equals(etcOsDistroInfo.getVersion())) { - return etcOsDistroInfo; - } - logger.log(Level.FINE, "/etc/os-release existing, but does not contain useful info"); - } catch (IOException e) { - // Log only at level FINE, since we have the LSB fallback - logger.log(Level.FINE, "unable to use os-release", e); - } - try { - return lsbRelease.getDistributionInformation(); - } catch (IOException e) { - // Log exception at level FINE only. - logger.log(Level.FINE, "unable to use lsb_release", e); - logger.log(Level.WARNING, "unable to use os-release AND lsb_release"); - } - return new DistributionInformation(UNKNOWN_NAME, UNKNOWN_VERSION); - } - - /** - * @return the name of the distribution, or {@link #UNKNOWN_NAME} if it can not be - * identified - */ - public String getName() { - return name; - } - - /** - * @return the release of the distribution or {@link #UNKNOWN_VERSION} if it can not be - * identified - */ - public String getVersion() { - return version; - } - -} - diff -r 006ac47d1506 -r cd5b08c32052 system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/linux/DistributionInformationSource.java --- a/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/linux/DistributionInformationSource.java Thu Jan 26 12:14:51 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.backend.system.internal.linux; - -import java.io.IOException; - -public interface DistributionInformationSource { - - public DistributionInformation getDistributionInformation() throws IOException; - -} - diff -r 006ac47d1506 -r cd5b08c32052 system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/linux/EtcOsRelease.java --- a/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/linux/EtcOsRelease.java Thu Jan 26 12:14:51 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,112 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.backend.system.internal.linux; - -import java.io.BufferedReader; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.nio.charset.StandardCharsets; - -public class EtcOsRelease implements DistributionInformationSource { - - private static final String EMPTY_STRING = ""; - private static final String OS_RELEASE = "/etc/os-release"; - private final String osReleaseFile; - - public EtcOsRelease() { - this.osReleaseFile = OS_RELEASE; - } - - // package-private for testing - EtcOsRelease(String osReleaseFile) { - this.osReleaseFile = osReleaseFile; - } - - @Override - public DistributionInformation getDistributionInformation() throws IOException { - return getFromOsRelease(); - } - - public DistributionInformation getFromOsRelease() throws IOException { - return getFromOsRelease(osReleaseFile); - } - - public DistributionInformation getFromOsRelease(String releaseFile) throws IOException { - try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(releaseFile), StandardCharsets.UTF_8))) { - return getFromOsRelease(reader); - } - } - - public DistributionInformation getFromOsRelease(BufferedReader reader) throws IOException { - String version = DistributionInformation.UNKNOWN_VERSION; - String name = DistributionInformation.UNKNOWN_NAME; - String line = null; - while ((line = reader.readLine()) != null) { - // skip whitespace only lines - line = line.trim(); - if (line.equals(EMPTY_STRING)) { - continue; - } - if (line.matches("^NAME *=.*")) { - name = readShellVariable(line); - } - if (line.matches("^VERSION *=.*")) { - version = readShellVariable(line); - } - } - return new DistributionInformation(name, version); - } - - /** Reads and parses a shell variable declaration: {@code FOO="bar"} - * - * @return the value of the shell variable - */ - private String readShellVariable(String line) { - // TODO we should try to handle shell quotes better - String result = line.substring(line.indexOf("=")+1); - result = result.trim(); - if (result.startsWith("\"") && result.endsWith("\"")) { - result = result.substring(1, result.length()-1); - result = result.trim(); - } - return result; - } - - -} - diff -r 006ac47d1506 -r cd5b08c32052 system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/linux/HostInfoBuilderImpl.java --- a/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/linux/HostInfoBuilderImpl.java Thu Jan 26 12:14:51 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,194 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.backend.system.internal.linux; - -import java.io.BufferedReader; -import java.io.IOException; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.logging.Level; -import java.util.logging.Logger; - -import com.redhat.thermostat.common.portability.linux.ProcDataSource; -import com.redhat.thermostat.common.portability.HostName; -import com.redhat.thermostat.backend.system.internal.models.HostInfoBuilder; -import com.redhat.thermostat.common.Size; -import com.redhat.thermostat.common.Size.Unit; -import com.redhat.thermostat.common.utils.LoggingUtils; -import com.redhat.thermostat.storage.core.WriterID; -import com.redhat.thermostat.storage.model.HostInfo; - -public class HostInfoBuilderImpl implements HostInfoBuilder { - - private static final Logger logger = LoggingUtils.getLogger(HostInfoBuilderImpl.class); - - private static final String FALLBACK_LOCAL_HOSTNAME = "localhost"; - - static class HostCpuInfo { - final String model; - final int count; - - HostCpuInfo(String model, int count) { - this.count = count; - this.model = model; - } - } - - static class HostOsInfo { - final String kernel; - final String distribution; - - HostOsInfo(String kernel, String distribution) { - this.kernel = kernel; - this.distribution = distribution; - } - } - - static class HostMemoryInfo { - final Size totalMemory; - - HostMemoryInfo(Size totalMemory) { - this.totalMemory = totalMemory; - } - } - - private final ProcDataSource dataSource; - private final WriterID writerId; - - HostInfoBuilderImpl(ProcDataSource dataSource, WriterID writerId) { - this.dataSource = dataSource; - this.writerId = writerId; - } - - public HostInfo build() { - String hostname = getHostName(); - HostCpuInfo cpuInfo = getCpuInfo(); - HostMemoryInfo memoryInfo = getMemoryInfo(); - long totalMemorySize = (long) memoryInfo.totalMemory.convertTo(Unit.B).getValue(); - HostOsInfo osInfo = getOsInfo(); - String wId = writerId.getWriterID(); - return new HostInfo(wId, hostname, osInfo.distribution, osInfo.kernel, cpuInfo.model, cpuInfo.count, totalMemorySize); - } - - HostCpuInfo getCpuInfo() { - final String KEY_PROCESSOR_ID = "processor"; - final String KEY_CPU_MODEL = "model name"; - int cpuCount = 0; - String cpuModel = null; - try (BufferedReader bufferedReader = new BufferedReader(dataSource.getCpuInfoReader())) { - String line = null; - while ((line = bufferedReader.readLine()) != null) { - if (line.startsWith(KEY_PROCESSOR_ID)) { - cpuCount++; - } else if (line.startsWith(KEY_CPU_MODEL)) { - cpuModel = line.substring(line.indexOf(":") + 1).trim(); - } - } - } catch (IOException ioe) { - logger.log(Level.WARNING, "unable to read cpu info"); - } - - logger.log(Level.FINEST, "cpuModel: " + cpuModel); - logger.log(Level.FINEST, "cpuCount: " + cpuCount); - - return new HostCpuInfo(cpuModel, cpuCount); - } - - HostMemoryInfo getMemoryInfo() { - Size totalMemory = null; - try (BufferedReader bufferedReader = new BufferedReader(dataSource.getMemInfoReader())) { - String[] memTotalParts = bufferedReader.readLine().split(" +"); - long data = Long.valueOf(memTotalParts[1]); - String units = memTotalParts[2]; - if (units.equals("kB")) { - totalMemory = new Size(data, Size.Unit.KiB); - } - } catch (IOException ioe) { - logger.log(Level.WARNING, "unable to read memory info"); - } - - logger.log(Level.FINEST, "totalMemory: " + (totalMemory != null ? totalMemory.toString() : "(null)")); - return new HostMemoryInfo(totalMemory); - } - - HostOsInfo getOsInfo() { - return getOsInfo(DistributionInformation.get()); - } - - HostOsInfo getOsInfo(DistributionInformation distroInfo) { - String osName = distroInfo.getName() + " " + distroInfo.getVersion(); - logger.log(Level.FINEST, "osName: " + osName); - - String osKernel = System.getProperty("os.name") + " " + System.getProperty("os.version"); - logger.log(Level.FINEST, "osKernel: " + osKernel); - - return new HostOsInfo(osKernel, osName); - } - - String getHostName() { - String hostname = null; - - try { - InetAddress localAddress = null; - localAddress = InetAddress.getLocalHost(); - hostname = getHostName(localAddress); - } catch (UnknownHostException uhe) { - logger.log(Level.WARNING, "unable to get hostname", uhe); - } - - // if fails, try to get hostname without dns lookup - if (hostname == null) { - hostname = HostName.getLocalHostName(); - } - - // still null, use localhost - if (hostname == null) { - hostname = FALLBACK_LOCAL_HOSTNAME; - - } - - return hostname; - } - - String getHostName(InetAddress localAddress) { - String hostname = localAddress.getCanonicalHostName(); - logger.log(Level.FINEST, "hostname: " + hostname); - return hostname; - } - -} - diff -r 006ac47d1506 -r cd5b08c32052 system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/linux/LinuxInfoBuilderFactory.java --- a/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/linux/LinuxInfoBuilderFactory.java Thu Jan 26 12:14:51 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,75 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.backend.system.internal.linux; - -import com.redhat.thermostat.common.portability.ProcessUserInfo; -import com.redhat.thermostat.common.portability.ProcessUserInfoBuilder; - -import com.redhat.thermostat.common.portability.linux.ProcDataSource; -import com.redhat.thermostat.common.portability.UserNameUtil; -import com.redhat.thermostat.backend.system.internal.models.HostInfoBuilder; -import com.redhat.thermostat.backend.system.internal.models.InfoBuilderFactory; -import com.redhat.thermostat.backend.system.internal.models.ProcessEnvironmentBuilder; -import com.redhat.thermostat.storage.core.WriterID; - -/** - * Allows callers to access Linux-specific builders portably - */ -public class LinuxInfoBuilderFactory implements InfoBuilderFactory { - - private final ProcDataSource dataSource; - - public LinuxInfoBuilderFactory() { - dataSource = new ProcDataSource(); - } - - public LinuxInfoBuilderFactory(final ProcDataSource ds) { - dataSource = ds; - } - - public HostInfoBuilder createHostInfoBuilder(final WriterID writerID) { - return new HostInfoBuilderImpl(dataSource, writerID); - } - - public ProcessEnvironmentBuilder createProcessEnvironmentBuilder() { - return new ProcessEnvironmentBuilderImpl(dataSource); - } - - public ProcessUserInfoBuilder createProcessUserInfoBuilder(final UserNameUtil userNameUtil) { - return ProcessUserInfo.createBuilder(dataSource, userNameUtil); - } -} diff -r 006ac47d1506 -r cd5b08c32052 system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/linux/LsbRelease.java --- a/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/linux/LsbRelease.java Thu Jan 26 12:14:51 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,123 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.backend.system.internal.linux; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.logging.Level; -import java.util.logging.Logger; - -import com.redhat.thermostat.common.utils.LoggingUtils; - -class LsbRelease implements DistributionInformationSource { - - private static final Logger logger = LoggingUtils.getLogger(LsbRelease.class); - - private static final String DISTRIBUTION_NAME = "distributor id"; - private static final String DISTRIBUTION_VERSION = "release"; - private static final String LSB_RELEASE_SCRIPT = "lsb_release"; - - private final String lsbRelaseBin; - - LsbRelease() { - this.lsbRelaseBin = LSB_RELEASE_SCRIPT; - } - - // package-private for testing - LsbRelease(String lsbReleaseBin) { - this.lsbRelaseBin = lsbReleaseBin; - } - - @Override - public DistributionInformation getDistributionInformation() - throws IOException { - return getFromLsbRelease(); - } - - DistributionInformation getFromLsbRelease() throws IOException { - BufferedReader reader = null; - try { - Process lsbProc = Runtime.getRuntime().exec(new String[] { lsbRelaseBin, "-a" }); - InputStream progOutput = lsbProc.getInputStream(); - reader = new BufferedReader(new InputStreamReader(progOutput)); - DistributionInformation result = getFromLsbRelease(reader); - int exitValue = lsbProc.waitFor(); - if (exitValue != 0) { - logger.log(Level.WARNING, "unable to identify distribution, problems running 'lsb_release'"); - } - return result; - } catch (InterruptedException e) { - throw new IOException(e); - } finally { - if (reader != null) { - try { - reader.close(); - } catch (IOException e) { - logger.log(Level.WARNING, "unable to close a child's output stream"); - } - } - } - - } - - DistributionInformation getFromLsbRelease(BufferedReader reader) throws IOException { - String name = DistributionInformation.UNKNOWN_NAME; - String version = DistributionInformation.UNKNOWN_VERSION; - - String line; - while ((line = reader.readLine()) != null) { - int sepLocation = line.indexOf(":"); - if (sepLocation != -1) { - String key = line.substring(0, sepLocation).toLowerCase(); - if (key.equals(DISTRIBUTION_NAME)) { - name = line.substring(sepLocation + 1).trim(); - } else if (key.equals(DISTRIBUTION_VERSION)) { - version = line.substring(sepLocation + 1).trim(); - } - } - } - - logger.log(Level.FINE, "distro-name: " + name); - logger.log(Level.FINE, "distro-version: " + version); - - return new DistributionInformation(name, version); - } - -} - diff -r 006ac47d1506 -r cd5b08c32052 system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/linux/ProcessEnvironmentBuilderImpl.java --- a/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/linux/ProcessEnvironmentBuilderImpl.java Thu Jan 26 12:14:51 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,127 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.backend.system.internal.linux; - -import java.io.IOException; -import java.io.Reader; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.logging.Level; -import java.util.logging.Logger; - -import com.redhat.thermostat.common.portability.linux.ProcDataSource; -import com.redhat.thermostat.backend.system.internal.models.ProcessEnvironmentBuilder; -import com.redhat.thermostat.common.utils.LoggingUtils; - -class ProcessEnvironmentBuilderImpl implements ProcessEnvironmentBuilder { - - private static final Logger logger = LoggingUtils.getLogger(ProcessEnvironmentBuilderImpl.class); - - private final ProcDataSource dataSource; - - ProcessEnvironmentBuilderImpl(ProcDataSource dataSource) { - this.dataSource = dataSource; - } - - public Map build(int pid) { - try (Reader reader = dataSource.getEnvironReader(pid)) { - return build(reader); - } catch (IOException ioe) { - logger.log(Level.WARNING, "error reading env", ioe); - } - - return Collections.emptyMap(); - } - - private Map build(Reader reader) throws IOException { - - Map env = new HashMap(); - - char[] fileBuffer = new char[1024]; - int fileBufferIndex = 0; - char[] buffer = new char[1024]; - int read = 0; - while (true) { - read = reader.read(buffer); - if (read == -1) { - break; - } - - if (read + fileBufferIndex > fileBuffer.length) { - char[] newFileBuffer = new char[fileBuffer.length * 2]; - System.arraycopy(fileBuffer, 0, newFileBuffer, 0, fileBufferIndex); - fileBuffer = newFileBuffer; - } - System.arraycopy(buffer, 0, fileBuffer, fileBufferIndex, read); - fileBufferIndex = fileBufferIndex + read; - - } - List parts = getParts(fileBuffer, fileBufferIndex); - for (String part : parts) { - int splitterPos = part.indexOf("="); - String key = part.substring(0, splitterPos); - String value = part.substring(splitterPos + 1); - env.put(key, value); - } - - return env; - } - - /** - * Split a char array, where items are separated by a null into into a list - * of strings - */ - private List getParts(char[] nullSeparatedBuffer, int bufferLength) { - int maxLength = Math.min(nullSeparatedBuffer.length, bufferLength); - List parts = new ArrayList(); - - int lastStart = 0; - for (int i = 0; i < maxLength; i++) { - if (nullSeparatedBuffer[i] == '\0') { - String string = new String(nullSeparatedBuffer, lastStart, (i - lastStart)); - parts.add(string); - lastStart = i + 1; - } - } - return parts; - } - -} - diff -r 006ac47d1506 -r cd5b08c32052 system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/models/InfoBuilderFactory.java --- a/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/models/InfoBuilderFactory.java Thu Jan 26 12:14:51 2017 -0500 +++ b/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/models/InfoBuilderFactory.java Mon Jan 30 10:30:19 2017 -0500 @@ -38,9 +38,7 @@ import com.redhat.thermostat.common.portability.ProcessUserInfoBuilder; import com.redhat.thermostat.common.portability.UserNameUtil; -import com.redhat.thermostat.backend.system.internal.linux.LinuxInfoBuilderFactory; -import com.redhat.thermostat.backend.system.internal.windows.WindowsInfoBuilderFactory; -import com.redhat.thermostat.shared.config.OS; +import com.redhat.thermostat.backend.system.internal.InfoBuilderFactoryImpl; import com.redhat.thermostat.storage.core.WriterID; /** @@ -48,7 +46,7 @@ */ public interface InfoBuilderFactory { - static InfoBuilderFactory INSTANCE = OS.IS_UNIX ? new LinuxInfoBuilderFactory() : new WindowsInfoBuilderFactory(); + static InfoBuilderFactory INSTANCE = new InfoBuilderFactoryImpl(); public HostInfoBuilder createHostInfoBuilder(final WriterID writerID); diff -r 006ac47d1506 -r cd5b08c32052 system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/windows/WindowsHostInfoBuilderImpl.java --- a/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/windows/WindowsHostInfoBuilderImpl.java Thu Jan 26 12:14:51 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.backend.system.internal.windows; - -import com.redhat.thermostat.common.portability.PortableHost; -import com.redhat.thermostat.backend.system.internal.models.HostInfoBuilder; -import com.redhat.thermostat.common.portability.PortableHostImpl; -import com.redhat.thermostat.storage.core.WriterID; -import com.redhat.thermostat.storage.model.HostInfo; - -/** - * Build Host information via Windows helper classes - */ -class WindowsHostInfoBuilderImpl implements HostInfoBuilder { - - private final WriterID writerID; - private final PortableHost helper; - - WindowsHostInfoBuilderImpl(final WriterID writerID) { - this(writerID, PortableHostImpl.INSTANCE); - } - - WindowsHostInfoBuilderImpl(final WriterID writerID, PortableHost helper) { - this.writerID = writerID; - this.helper = helper; - } - - @Override - public HostInfo build() { - String wId = writerID.getWriterID(); - return new HostInfo(wId, - helper.getHostName(), - helper.getOSName(), - helper.getOSVersion(), - helper.getCPUModel(), - helper.getCPUCount(), - helper.getTotalMemory()); - } -} diff -r 006ac47d1506 -r cd5b08c32052 system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/windows/WindowsInfoBuilderFactory.java --- a/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/windows/WindowsInfoBuilderFactory.java Thu Jan 26 12:14:51 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,66 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.backend.system.internal.windows; - -import com.redhat.thermostat.common.portability.ProcessUserInfo; -import com.redhat.thermostat.common.portability.ProcessUserInfoBuilder; -import com.redhat.thermostat.common.portability.UserNameUtil; -import com.redhat.thermostat.backend.system.internal.models.HostInfoBuilder; -import com.redhat.thermostat.backend.system.internal.models.InfoBuilderFactory; -import com.redhat.thermostat.backend.system.internal.models.ProcessEnvironmentBuilder; -import com.redhat.thermostat.storage.core.WriterID; - -/** - * Allows callers to access Windows-specific builders portably - */ -public class WindowsInfoBuilderFactory implements InfoBuilderFactory { - - public WindowsInfoBuilderFactory() { - } - - public HostInfoBuilder createHostInfoBuilder(final WriterID writerID) { - return new WindowsHostInfoBuilderImpl(writerID); - } - - public ProcessEnvironmentBuilder createProcessEnvironmentBuilder() { - return new WindowsProcessEnvironmentBuilderImpl(); - } - - public ProcessUserInfoBuilder createProcessUserInfoBuilder(final UserNameUtil userNameUtil) { - return ProcessUserInfo.createBuilder(null, userNameUtil); - } -} diff -r 006ac47d1506 -r cd5b08c32052 system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/windows/WindowsProcessEnvironmentBuilderImpl.java --- a/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/windows/WindowsProcessEnvironmentBuilderImpl.java Thu Jan 26 12:14:51 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,64 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.backend.system.internal.windows; - -import com.redhat.thermostat.backend.system.internal.models.ProcessEnvironmentBuilder; -import com.redhat.thermostat.common.portability.PortableProcess; -import com.redhat.thermostat.common.portability.PortableProcessImpl; - -import java.util.Map; - -/** - * Build process environment information via Windows helper classes - */ -class WindowsProcessEnvironmentBuilderImpl implements ProcessEnvironmentBuilder { - - private final PortableProcess helper; - - WindowsProcessEnvironmentBuilderImpl() { - this(PortableProcessImpl.INSTANCE); - } - - WindowsProcessEnvironmentBuilderImpl(PortableProcess wh) { - helper = wh; - } - - @Override - public Map build(int pid) { - return helper.getEnvironment(pid); - } -} diff -r 006ac47d1506 -r cd5b08c32052 system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/HostInfoBuilderTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/HostInfoBuilderTest.java Mon Jan 30 10:30:19 2017 -0500 @@ -0,0 +1,92 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.backend.system.internal; + +import com.redhat.thermostat.common.portability.PortableHost; +import com.redhat.thermostat.backend.system.internal.models.HostInfoBuilder; +import com.redhat.thermostat.shared.config.OS; +import com.redhat.thermostat.storage.core.WriterID; +import com.redhat.thermostat.storage.model.HostInfo; +import org.junit.Assume; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class HostInfoBuilderTest { + + private WriterID writerId; + private PortableHost helper; + + @Before + public void setup() { + writerId = mock(WriterID.class); + helper = mock(PortableHost.class); + when(helper.getHostName()).thenReturn("testhost"); + when(helper.getOSName()).thenReturn("testos"); + when(helper.getOSVersion()).thenReturn("testversion"); + when(helper.getCPUModel()).thenReturn("testcpu"); + when(helper.getCPUCount()).thenReturn(4567); + when(helper.getTotalMemory()).thenReturn(9876L); + } + + // TODO - This test currently fails on Windows because the helper DLL isn't on the execution path + @Test + @Ignore + public void testSimpleBuild() { + Assume.assumeTrue(OS.IS_WINDOWS); + HostInfo info = new HostInfoBuilderImpl(writerId).build(); + assertNotNull(info); + } + + @Test + public void testGetInfo() { + final HostInfoBuilder ib = new HostInfoBuilderImpl(writerId, helper); + final HostInfo hi = ib.build(); + assertEquals("testhost",hi.getHostname()); + assertEquals("testos", hi.getOsName()); + assertEquals("testcpu", hi.getCpuModel()); + assertEquals("testversion", hi.getOsKernel()); + assertEquals(4567, hi.getCpuCount()); + assertEquals(9876L, hi.getTotalMemory()); + } +} + diff -r 006ac47d1506 -r cd5b08c32052 system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/InfoBuilderFactoryTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/InfoBuilderFactoryTest.java Mon Jan 30 10:30:19 2017 -0500 @@ -0,0 +1,64 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.backend.system.internal; + +import com.redhat.thermostat.backend.system.internal.models.HostInfoBuilder; +import com.redhat.thermostat.backend.system.internal.models.InfoBuilderFactory; +import com.redhat.thermostat.backend.system.internal.models.ProcessEnvironmentBuilder; +import org.junit.Test; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +public class InfoBuilderFactoryTest { + + @Test + public void testCreateHostInfoBuilder() { + final InfoBuilderFactory builder = new InfoBuilderFactoryImpl(); + final HostInfoBuilder hib = builder.createHostInfoBuilder(null); + assertNotNull(hib); + assertTrue(hib instanceof HostInfoBuilderImpl); + } + + @Test + public void testCreateProcessEnvironmentBuilder() { + final InfoBuilderFactory builder = new InfoBuilderFactoryImpl(); + final ProcessEnvironmentBuilder hib = builder.createProcessEnvironmentBuilder(); + assertNotNull(hib); + assertTrue(hib instanceof ProcessEnvironmentBuilderImpl); + } +} diff -r 006ac47d1506 -r cd5b08c32052 system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/ProcessEnvironmentBuilderTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/ProcessEnvironmentBuilderTest.java Mon Jan 30 10:30:19 2017 -0500 @@ -0,0 +1,105 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.backend.system.internal; + +import com.redhat.thermostat.common.portability.PortableProcess; +import com.redhat.thermostat.backend.system.internal.models.ProcessEnvironmentBuilder; +import com.redhat.thermostat.shared.config.OS; + +import org.junit.Assume; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.anyInt; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +/** + * test windows process env builder + */ +public class ProcessEnvironmentBuilderTest { + + private PortableProcess whelp; + + private static final int FAKE_PID = 4567; + private static final String PATH_KEY = "PATH"; + private static final String FAKE_PATH = "testpath"; + + private static final Map goodMap = new HashMap<>(); + + @Before + public void setup() { + whelp = mock(PortableProcess.class); + goodMap.put(PATH_KEY, FAKE_PATH); + when(whelp.getEnvironment(anyInt())).thenReturn(null); + when(whelp.getEnvironment(eq(FAKE_PID))).thenReturn(goodMap); + } + + // TODO - This test currently fails on Windows because the helper DLL isn't on the execution path + @Test + @Ignore + public void testSimpleBuild() { + Assume.assumeTrue(OS.IS_WINDOWS); + final Map info = new ProcessEnvironmentBuilderImpl().build(FAKE_PID); + assertNotNull(info); + } + + @Test + public void testGetInfoFromGoodPid() { + final ProcessEnvironmentBuilder ib = new ProcessEnvironmentBuilderImpl(whelp); + final Map info = ib.build(FAKE_PID); + assertFalse(info.isEmpty()); + assertTrue(info.containsKey(PATH_KEY)); + assertEquals(FAKE_PATH, info.get(PATH_KEY)); + } + + @Test + public void testGetInfoFromBadPid() { + final ProcessEnvironmentBuilder ib = new ProcessEnvironmentBuilderImpl(whelp); + final Map info = ib.build(FAKE_PID+1); + assertTrue(info == null || info.isEmpty()); + } +} diff -r 006ac47d1506 -r cd5b08c32052 system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/linux/DistributionInformationTest.java --- a/system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/linux/DistributionInformationTest.java Thu Jan 26 12:14:51 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,179 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.backend.system.internal.linux; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import java.io.IOException; -import java.util.logging.Handler; -import java.util.logging.Logger; - -import com.redhat.thermostat.shared.config.OS; -import org.junit.After; -import org.junit.Assume; -import org.junit.Before; -import org.junit.Test; - -public class DistributionInformationTest { - - private Logger logger; - private TestLogHandler handler; - - @Before - public void setup() { - setupTestLogger(); - } - - @After - public void tearDown() { - if (handler != null) { - logger.removeHandler(handler); - handler = null; - } - } - - private void setupTestLogger() { - logger = Logger.getLogger("com.redhat.thermostat"); - handler = new TestLogHandler(); - logger.addHandler(handler); - } - - /* - * Verifies that no warning gets logged if EtcOsRelease fails, but - * LsbRelease works. Since LsbRelease is the fallback, all is well. - * - * see: http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=1628 - */ - @Test - public void testNoWarningLoggedOnFallback() { - // verify preconditions - assertFalse(handler.isEtcOsReleaseLogged()); - assertTestHandlerRegistered(); - - // Default LSB release - LsbRelease lsbRelease = new LsbRelease(); - // EtcOsRelease with non existent file - EtcOsRelease etcOsRelease = new EtcOsRelease(EtcOsReleaseTest.NOT_EXISTING_OS_RELEASE_FILE); - DistributionInformation.get(etcOsRelease, lsbRelease); - assertFalse(handler.isEtcOsReleaseLogged()); - } - - /* - * Verifies that a warning gets logged if os-release and lsb_release both - * fail. - * - * see: http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=1628 - */ - @Test - public void testWarningLoggedIfBothFail() { - // verify preconditions - assertFalse(handler.isEtcOsReleaseLogged()); - assertFalse(handler.isLsbReleaseLogged()); - assertTestHandlerRegistered(); - - // both etc-os-release and lsb-release don't exist for this test - EtcOsRelease etcOsRelease = new EtcOsRelease(EtcOsReleaseTest.NOT_EXISTING_OS_RELEASE_FILE); - LsbRelease lsbRelease = new LsbRelease(LsbReleaseTest.NOT_EXISTING_LSB_RELEASE); - - DistributionInformation info = DistributionInformation.get(etcOsRelease, lsbRelease); - assertFalse(handler.isEtcOsReleaseLogged()); - assertTrue(handler.isLsbReleaseLogged()); - assertNotNull(info); - assertEquals(DistributionInformation.UNKNOWN_NAME, info.getName()); - assertEquals(DistributionInformation.UNKNOWN_VERSION, info.getVersion()); - } - - @Test - public void verifyFallbackToLsbWhenEtcOsReturnsUnknown() throws IOException { - EtcOsRelease mockEtcOsRelease = mock(EtcOsRelease.class); - DistributionInformation mockDistro = mock(DistributionInformation.class); - when(mockEtcOsRelease.getDistributionInformation()).thenReturn(mockDistro); - when(mockDistro.getName()).thenReturn(DistributionInformation.UNKNOWN_NAME); - when(mockDistro.getVersion()).thenReturn(DistributionInformation.UNKNOWN_VERSION); - - LsbRelease mockLsbRelease = mock(LsbRelease.class); - DistributionInformation mockLsbDistro = mock(DistributionInformation.class); - when(mockLsbRelease.getDistributionInformation()).thenReturn(mockLsbDistro); - - DistributionInformation info = DistributionInformation.get(mockEtcOsRelease, mockLsbRelease); - assertSame("Expected lsb info to be used since etc returns unknown", - mockLsbDistro, info); - } - - private void assertTestHandlerRegistered() { - assertNotNull(logger); - boolean testLogHandlerRegistered = false; - for (Handler h: logger.getHandlers()) { - if (h instanceof TestLogHandler) { - testLogHandlerRegistered = true; - } - } - assertTrue(testLogHandlerRegistered); - } - - @Test - public void testName() { - if (OS.IS_LINUX) { - DistributionInformation info = DistributionInformation.get(); - String name = info.getName(); - assertNotNull(name); - assertTrue(name.length() > 0); - assertFalse(name.startsWith(":")); - assertFalse(name.equals(DistributionInformation.UNKNOWN_NAME)); - } - } - - @Test - public void testVersion() { - if (OS.IS_LINUX) { - DistributionInformation info = DistributionInformation.get(); - String version = info.getVersion(); - assertNotNull(version); - assertTrue(version.length()> 0); - assertFalse(version.startsWith(":")); - assertFalse(version.equals(DistributionInformation.UNKNOWN_VERSION)); - } - } - -} - diff -r 006ac47d1506 -r cd5b08c32052 system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/linux/EtcOsReleaseTest.java --- a/system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/linux/EtcOsReleaseTest.java Thu Jan 26 12:14:51 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,127 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.backend.system.internal.linux; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.StringReader; -import java.util.UUID; - -import com.redhat.thermostat.backend.system.internal.linux.DistributionInformation; -import com.redhat.thermostat.backend.system.internal.linux.EtcOsRelease; -import com.redhat.thermostat.shared.config.OS; -import org.junit.Assume; -import org.junit.Test; - -import com.redhat.thermostat.common.internal.test.Bug; - -public class EtcOsReleaseTest { - - static final String NOT_EXISTING_OS_RELEASE_FILE = "/thermostat-os-release-testing-" - + UUID.randomUUID(); - - @Test - public void testName() throws IOException, InterruptedException { - BufferedReader reader = new BufferedReader(new StringReader("NAME=\"Name\"\n")); - DistributionInformation info = new EtcOsRelease().getFromOsRelease(reader); - assertEquals("Name", info.getName()); - } - - - @Test - public void testVersion() throws IOException { - BufferedReader reader = new BufferedReader(new StringReader("VERSION=\"Version\"\n")); - DistributionInformation info = new EtcOsRelease().getFromOsRelease(reader); - assertEquals("Version", info.getVersion()); - } - - @Bug(id="981", - summary="DistributionInformationTest fails on OpenSUSE Linux 12.1", - url="http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=981") - @Test - public void testFormattedOutput() throws IOException { - String output = - "NAME=openSUSE\n" + - "VERSION = 12.1 (Asparagus)\n" + - "VERSION_ID=\"12.1\"\n" + - "PRETTY_NAME=\"openSUSE 12.1 (Asparagus) (x86_64)\"\n" + - "ID=opensuse"; - BufferedReader reader = new BufferedReader(new StringReader(output)); - DistributionInformation info = new EtcOsRelease().getFromOsRelease(reader); - - assertEquals("openSUSE", info.getName()); - assertEquals("12.1 (Asparagus)", info.getVersion()); - } - - /** - * DistributionInformation falls back on LSB when /etc/os-release contains - * inconclusive content (empty in this case). It should not return some - * info as "Linux". - * - * @throws IOException - */ - @Test - public void testEmpty() throws IOException { - String output = ""; - BufferedReader reader = new BufferedReader(new StringReader(output)); - - DistributionInformation info = new EtcOsRelease().getFromOsRelease(reader); - assertEquals(DistributionInformation.UNKNOWN_NAME, info.getName()); - assertEquals(DistributionInformation.UNKNOWN_VERSION, info.getVersion()); - } - - @Test - public void getDistributionInformationThrowsIOExceptionIfFileNotThere() { - Assume.assumeTrue(OS.IS_UNIX); - EtcOsRelease etcOsRelease = new EtcOsRelease(NOT_EXISTING_OS_RELEASE_FILE); - try { - etcOsRelease.getDistributionInformation(); - fail("Should have thrown IOException, since file is not there!"); - } catch (IOException e) { - // pass - String message = e.getMessage(); - assertTrue(message.contains("/thermostat-os-release-testing-")); - assertTrue(message.contains("(No such file or directory)")); - } - } - -} - diff -r 006ac47d1506 -r cd5b08c32052 system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/linux/HostInfoBuilderTest.java --- a/system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/linux/HostInfoBuilderTest.java Thu Jan 26 12:14:51 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,136 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.backend.system.internal.linux; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import java.io.IOException; -import java.io.StringReader; -import java.net.InetAddress; - -import com.redhat.thermostat.shared.config.OS; -import org.junit.Assume; -import org.junit.Before; -import org.junit.Test; - -import com.redhat.thermostat.common.portability.linux.ProcDataSource; -import com.redhat.thermostat.backend.system.internal.linux.HostInfoBuilderImpl.HostCpuInfo; -import com.redhat.thermostat.backend.system.internal.linux.HostInfoBuilderImpl.HostMemoryInfo; -import com.redhat.thermostat.backend.system.internal.linux.HostInfoBuilderImpl.HostOsInfo; -import com.redhat.thermostat.common.Size; -import com.redhat.thermostat.storage.core.WriterID; -import com.redhat.thermostat.storage.model.HostInfo; - -public class HostInfoBuilderTest { - - final int KILOBYTES_TO_BYTES = 1024; - private WriterID writerId; - - @Before - public void setup() { - writerId = mock(WriterID.class); - } - - @Test - public void testSimpleBuild() { - Assume.assumeTrue(OS.IS_UNIX); - HostInfo info = new HostInfoBuilderImpl(new ProcDataSource(), writerId).build(); - assertNotNull(info); - } - - @Test - public void testCpuInfo() throws IOException { - String cpuInfoString = - "processor: 1\n" + - "model name: Test Model\n" + - "processor: 0\n" + - "model name: Test Model\n"; - - StringReader cpuInfoReader = new StringReader(cpuInfoString); - - ProcDataSource dataSource = mock(ProcDataSource.class); - when(dataSource.getCpuInfoReader()).thenReturn(cpuInfoReader); - - HostCpuInfo cpuInfo = new HostInfoBuilderImpl(dataSource, writerId).getCpuInfo(); - assertEquals(2, cpuInfo.count); - assertEquals("Test Model", cpuInfo.model); - verify(dataSource).getCpuInfoReader(); - } - - @Test - public void testMemoryInfo() throws IOException { - String memoryInfoString = - "MemTotal: 12345 kB"; - - StringReader memoryInfoReader = new StringReader(memoryInfoString); - ProcDataSource dataSource = mock(ProcDataSource.class); - when(dataSource.getMemInfoReader()).thenReturn(memoryInfoReader); - - HostMemoryInfo memoryInfo = new HostInfoBuilderImpl(dataSource, writerId).getMemoryInfo(); - assertNotNull(memoryInfo); - assertEquals(Size.bytes(12345 * KILOBYTES_TO_BYTES), memoryInfo.totalMemory); - verify(dataSource).getMemInfoReader(); - - } - - @Test - public void testOsInfo() { - DistributionInformation distroInfo = new DistributionInformation("distro-name", "distro-version"); - ProcDataSource dataSource = mock(ProcDataSource.class); - HostOsInfo osInfo = new HostInfoBuilderImpl(dataSource, writerId).getOsInfo(distroInfo); - assertEquals("distro-name distro-version", osInfo.distribution); - assertEquals(System.getProperty("os.name") + " " + System.getProperty("os.version"), osInfo.kernel); - } - - @Test - public void testHostname() { - - InetAddress address = mock(InetAddress.class); - when(address.getCanonicalHostName()).thenReturn("test-hostname"); - - ProcDataSource dataSource = mock(ProcDataSource.class); - - String name = new HostInfoBuilderImpl(dataSource, writerId).getHostName(address); - assertEquals("test-hostname", name); - } - -} - diff -r 006ac47d1506 -r cd5b08c32052 system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/linux/LsbReleaseTest.java --- a/system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/linux/LsbReleaseTest.java Thu Jan 26 12:14:51 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,91 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.backend.system.internal.linux; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.StringReader; -import java.util.UUID; - -import com.redhat.thermostat.backend.system.internal.linux.DistributionInformation; -import com.redhat.thermostat.backend.system.internal.linux.LsbRelease; -import com.redhat.thermostat.shared.config.OS; -import org.junit.Assume; -import org.junit.Test; - -public class LsbReleaseTest { - - static final String NOT_EXISTING_LSB_RELEASE = "lsb_release-" - + UUID.randomUUID(); - - @Test - public void testName() throws IOException, InterruptedException { - Assume.assumeTrue(OS.IS_UNIX); - BufferedReader reader = new BufferedReader(new StringReader("Distributor ID: Name")); - DistributionInformation info = new LsbRelease().getFromLsbRelease(reader); - assertEquals("Name", info.getName()); - } - - @Test - public void testVersion() throws IOException { - Assume.assumeTrue(OS.IS_UNIX); - BufferedReader reader = new BufferedReader(new StringReader("Release: Version")); - DistributionInformation info = new LsbRelease().getFromLsbRelease(reader); - assertEquals("Version", info.getVersion()); - } - - @Test - public void getDistributionInformationThrowsIOExceptionIfScriptNotThere() { - Assume.assumeTrue(OS.IS_UNIX); - LsbRelease lsbRelease = new LsbRelease(NOT_EXISTING_LSB_RELEASE); - try { - lsbRelease.getDistributionInformation(); - fail("Should have thrown IOException, since file is not there!"); - } catch (IOException e) { - // pass - String message = e.getMessage(); - assertTrue(message.contains("Cannot run program \"lsb_release-")); - assertTrue(message.contains("No such file or directory")); - } - } - -} - diff -r 006ac47d1506 -r cd5b08c32052 system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/linux/ProcessEnvironmentBuilderTest.java --- a/system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/linux/ProcessEnvironmentBuilderTest.java Thu Jan 26 12:14:51 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,138 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.backend.system.internal.linux; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.Reader; -import java.util.Map; -import java.util.Random; - -import com.redhat.thermostat.shared.config.OS; -import org.junit.Assume; -import org.junit.Test; - -import com.redhat.thermostat.common.portability.linux.ProcDataSource; -import com.redhat.thermostat.testutils.TestUtils; - -public class ProcessEnvironmentBuilderTest { - - private final Random r = new Random(); - - @Test - public void testBasicBuild() { - Assume.assumeTrue(OS.IS_UNIX); - ProcDataSource dataSource = new ProcDataSource(); - Map result = new ProcessEnvironmentBuilderImpl(dataSource).build(TestUtils.getProcessId()); - assertNotNull(result); - assertFalse(result.isEmpty()); - assertTrue(result.containsKey("USER")); - } - - @Test - public void testCustomEnvironment() throws IOException { - byte[] data = ("USER=test\000HOME=house\000").getBytes(); - - Reader r = new InputStreamReader(new ByteArrayInputStream(data)); - ProcDataSource dataSource = mock(ProcDataSource.class); - when(dataSource.getEnvironReader(any(Integer.class))).thenReturn(r); - - Map result = new ProcessEnvironmentBuilderImpl(dataSource).build(0); - - verify(dataSource).getEnvironReader(eq(0)); - assertEquals("test", result.get("USER")); - assertEquals("house", result.get("HOME")); - } - - @Test - public void testLargeRandomEnvironment() throws IOException { - int TEST_ENV_SIZE = 1024 * 1024; - byte[] data = new byte[TEST_ENV_SIZE]; - int currentPosition = 0; - do { - byte[] key = generateRandomBytes(); - byte[] value = generateRandomBytes(); - if (currentPosition + key.length + value.length + 2 >= data.length) { - break; - } - System.arraycopy(key, 0, data, currentPosition, key.length); - currentPosition += key.length; - data[currentPosition] = (byte) '='; - currentPosition++; - System.arraycopy(value, 0, data, currentPosition, value.length); - currentPosition += value.length; - data[currentPosition] = 0x00; - currentPosition++; - } while (true); - Reader r = new InputStreamReader(new ByteArrayInputStream(data, 0, currentPosition)); - ProcDataSource dataSource = mock(ProcDataSource.class); - when(dataSource.getEnvironReader(any(Integer.class))).thenReturn(r); - - Map result = new ProcessEnvironmentBuilderImpl(dataSource).build(0); - - verify(dataSource).getEnvironReader(eq(0)); - assertNotNull(result); - } - - private byte[] generateRandomBytes() { - byte start = (byte) 'a'; - byte end = (byte) 'z' + 1; - - byte[] alphabet = new byte[end - start]; - for (int i = 0; i < (end-start); i++) { - alphabet[i] = (byte) (i + start); - } - int size = r.nextInt(15) + 10; - byte[] result = new byte[size]; - for (int i = 0; i < result.length; i++) { - result[i] = alphabet[r.nextInt(alphabet.length)]; - } - return result; - } -} - diff -r 006ac47d1506 -r cd5b08c32052 system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/linux/TestLogHandler.java --- a/system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/linux/TestLogHandler.java Thu Jan 26 12:14:51 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,87 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.backend.system.internal.linux; - -import java.util.logging.Handler; -import java.util.logging.Level; -import java.util.logging.LogRecord; - -/* - * Test log handler used for DistributionInformation log testing. - */ -public class TestLogHandler extends Handler { - - private boolean etcOsReleaseLogged; - private boolean lsbReleaseLogged; - private static final String EXPECTED_OS_RELEASE_FAIL_MSG = - "unable to use os-release"; - private static final String EXPECTED_LSB_RELEASE_FAIL_MSG = - "unable to use os-release AND lsb_release"; - - @Override - public void publish(LogRecord record) { - String logMessage = record.getMessage(); - if (record.getLevel().intValue() >= Level.WARNING.intValue() && - logMessage.equals(EXPECTED_OS_RELEASE_FAIL_MSG)) { - etcOsReleaseLogged = true; - }; - if (record.getLevel().intValue() >= Level.WARNING.intValue() && - logMessage.equals(EXPECTED_LSB_RELEASE_FAIL_MSG)) { - lsbReleaseLogged = true; - } - } - - @Override - public void flush() { - // nothing - } - - @Override - public void close() throws SecurityException { - // nothing - } - - boolean isEtcOsReleaseLogged() { - return etcOsReleaseLogged; - } - - boolean isLsbReleaseLogged() { - return lsbReleaseLogged; - } - -} - diff -r 006ac47d1506 -r cd5b08c32052 system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/windows/WindowsHostInfoBuilderTest.java --- a/system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/windows/WindowsHostInfoBuilderTest.java Thu Jan 26 12:14:51 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,92 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.backend.system.internal.windows; - -import com.redhat.thermostat.common.portability.PortableHost; -import com.redhat.thermostat.backend.system.internal.models.HostInfoBuilder; -import com.redhat.thermostat.shared.config.OS; -import com.redhat.thermostat.storage.core.WriterID; -import com.redhat.thermostat.storage.model.HostInfo; -import org.junit.Assume; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class WindowsHostInfoBuilderTest { - - private WriterID writerId; - private PortableHost helper; - - @Before - public void setup() { - writerId = mock(WriterID.class); - helper = mock(PortableHost.class); - when(helper.getHostName()).thenReturn("testhost"); - when(helper.getOSName()).thenReturn("testos"); - when(helper.getOSVersion()).thenReturn("testversion"); - when(helper.getCPUModel()).thenReturn("testcpu"); - when(helper.getCPUCount()).thenReturn(4567); - when(helper.getTotalMemory()).thenReturn(9876L); - } - - // TODO - This test currently fails on Windows because the helper DLL isn't on the execution path - @Test - @Ignore - public void testSimpleBuild() { - Assume.assumeTrue(OS.IS_WINDOWS); - HostInfo info = new WindowsHostInfoBuilderImpl(writerId).build(); - assertNotNull(info); - } - - @Test - public void testGetInfo() { - final HostInfoBuilder ib = new WindowsHostInfoBuilderImpl(writerId, helper); - final HostInfo hi = ib.build(); - assertEquals("testhost",hi.getHostname()); - assertEquals("testos", hi.getOsName()); - assertEquals("testcpu", hi.getCpuModel()); - assertEquals("testversion", hi.getOsKernel()); - assertEquals(4567, hi.getCpuCount()); - assertEquals(9876L, hi.getTotalMemory()); - } -} - diff -r 006ac47d1506 -r cd5b08c32052 system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/windows/WindowsInfoBuilderFactoryTest.java --- a/system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/windows/WindowsInfoBuilderFactoryTest.java Thu Jan 26 12:14:51 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,64 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.backend.system.internal.windows; - -import com.redhat.thermostat.backend.system.internal.models.HostInfoBuilder; -import com.redhat.thermostat.backend.system.internal.models.InfoBuilderFactory; -import com.redhat.thermostat.backend.system.internal.models.ProcessEnvironmentBuilder; -import org.junit.Test; - -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -public class WindowsInfoBuilderFactoryTest { - - @Test - public void testCreateHostInfoBuilder() { - final InfoBuilderFactory builder = new WindowsInfoBuilderFactory(); - final HostInfoBuilder hib = builder.createHostInfoBuilder(null); - assertNotNull(hib); - assertTrue(hib instanceof WindowsHostInfoBuilderImpl); - } - - @Test - public void testCreateProcessEnvironmentBuilder() { - final InfoBuilderFactory builder = new WindowsInfoBuilderFactory(); - final ProcessEnvironmentBuilder hib = builder.createProcessEnvironmentBuilder(); - assertNotNull(hib); - assertTrue(hib instanceof WindowsProcessEnvironmentBuilderImpl); - } -} diff -r 006ac47d1506 -r cd5b08c32052 system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/windows/WindowsProcessEnvironmentBuilderTest.java --- a/system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/windows/WindowsProcessEnvironmentBuilderTest.java Thu Jan 26 12:14:51 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,105 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.backend.system.internal.windows; - -import com.redhat.thermostat.common.portability.PortableProcess; -import com.redhat.thermostat.backend.system.internal.models.ProcessEnvironmentBuilder; -import com.redhat.thermostat.shared.config.OS; - -import org.junit.Assume; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; - -import java.util.HashMap; -import java.util.Map; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -/** - * test windows process env builder - */ -public class WindowsProcessEnvironmentBuilderTest { - - private PortableProcess whelp; - - private static final int FAKE_PID = 4567; - private static final String PATH_KEY = "PATH"; - private static final String FAKE_PATH = "testpath"; - - private static final Map goodMap = new HashMap<>(); - - @Before - public void setup() { - whelp = mock(PortableProcess.class); - goodMap.put(PATH_KEY, FAKE_PATH); - when(whelp.getEnvironment(anyInt())).thenReturn(null); - when(whelp.getEnvironment(eq(FAKE_PID))).thenReturn(goodMap); - } - - // TODO - This test currently fails on Windows because the helper DLL isn't on the execution path - @Test - @Ignore - public void testSimpleBuild() { - Assume.assumeTrue(OS.IS_WINDOWS); - final Map info = new WindowsProcessEnvironmentBuilderImpl().build(FAKE_PID); - assertNotNull(info); - } - - @Test - public void testGetInfoFromGoodPid() { - final ProcessEnvironmentBuilder ib = new WindowsProcessEnvironmentBuilderImpl(whelp); - final Map info = ib.build(FAKE_PID); - assertFalse(info.isEmpty()); - assertTrue(info.containsKey(PATH_KEY)); - assertEquals(FAKE_PATH, info.get(PATH_KEY)); - } - - @Test - public void testGetInfoFromBadPid() { - final ProcessEnvironmentBuilder ib = new WindowsProcessEnvironmentBuilderImpl(whelp); - final Map info = ib.build(FAKE_PID+1); - assertTrue(info == null || info.isEmpty()); - } -} diff -r 006ac47d1506 -r cd5b08c32052 vm-cpu/agent/src/main/java/com/redhat/thermostat/vm/cpu/agent/internal/LinuxProcessStatusInfoBuilderImpl.java --- a/vm-cpu/agent/src/main/java/com/redhat/thermostat/vm/cpu/agent/internal/LinuxProcessStatusInfoBuilderImpl.java Thu Jan 26 12:14:51 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,120 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.vm.cpu.agent.internal; - -import com.redhat.thermostat.common.portability.linux.ProcDataSource; -import com.redhat.thermostat.common.utils.LoggingUtils; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.Reader; -import java.util.Scanner; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * Extract status information about the process from /proc/. This is what tools - * like {@code ps} and {@code top} use. - * - * @see {@code proc(5)} - */ -public class LinuxProcessStatusInfoBuilderImpl implements ProcessStatusInfoBuilder{ - - private static final Logger logger = LoggingUtils.getLogger(LinuxProcessStatusInfoBuilderImpl.class); - - private final ProcDataSource dataSource; - - public LinuxProcessStatusInfoBuilderImpl(ProcDataSource dataSource) { - this.dataSource = dataSource; - } - - public ProcessStatusInfo build(int pid) { - try (BufferedReader reader = new BufferedReader(dataSource.getStatReader(pid))) { - return build(reader); - } catch (IOException e) { - logger.log(Level.FINE, "Unable to read stat info for: " + pid); - } - - return null; - } - - private ProcessStatusInfo build(Reader r) throws IOException { - - int pid = -1; - long utime = -1; - long stime = -1; - - Scanner scanner = null; - - /* TODO map these (effectively c) data types to java types more sanely */ - - try (BufferedReader reader = new BufferedReader(r)) { - String statusLine = reader.readLine(); - - /* be prepared for process names like '1 ) 2 3 4 foo 5' */ - - scanner = new Scanner(statusLine); - pid = scanner.nextInt(); - scanner.close(); - - int execEndNamePos = statusLine.lastIndexOf(')'); - - String cleanStatusLine = statusLine.substring(execEndNamePos + 1); - - scanner = new Scanner(cleanStatusLine); - /* state = */scanner.next(); - /* ppid = */scanner.nextInt(); - /* pgrp = */scanner.nextInt(); - /* session = */scanner.nextInt(); - /* tty_nr = */scanner.nextInt(); - /* tpgid = */scanner.nextInt(); - /* flags = */scanner.nextInt(); - /* minflt = */scanner.nextLong(); - /* cminflt = */scanner.nextLong(); - /* majflt = */scanner.nextLong(); - /* cmajflt = */scanner.nextLong(); - utime = scanner.nextLong(); - stime = scanner.nextLong(); - scanner.close(); - } - - return new ProcessStatusInfo(pid, utime, stime); - - } - -} - diff -r 006ac47d1506 -r cd5b08c32052 vm-cpu/agent/src/main/java/com/redhat/thermostat/vm/cpu/agent/internal/ProcessStatusInfoBuilderImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-cpu/agent/src/main/java/com/redhat/thermostat/vm/cpu/agent/internal/ProcessStatusInfoBuilderImpl.java Mon Jan 30 10:30:19 2017 -0500 @@ -0,0 +1,58 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.cpu.agent.internal; + +import com.redhat.thermostat.common.portability.PortableProcessImpl; +import com.redhat.thermostat.common.portability.PortableProcessStat; + +/** + * Extract status information about the process + */ +public class ProcessStatusInfoBuilderImpl implements ProcessStatusInfoBuilder { + + ProcessStatusInfoBuilderImpl() { + } + + public ProcessStatusInfo build(int pid) { + + final PortableProcessStat info = PortableProcessImpl.getInstance().getProcessStat(pid); + + return info != null ? new ProcessStatusInfo(pid, info.getUserTime(), info.getKernelTime()) : null; + } + +} + diff -r 006ac47d1506 -r cd5b08c32052 vm-cpu/agent/src/main/java/com/redhat/thermostat/vm/cpu/agent/internal/VmCpuBackend.java --- a/vm-cpu/agent/src/main/java/com/redhat/thermostat/vm/cpu/agent/internal/VmCpuBackend.java Thu Jan 26 12:14:51 2017 -0500 +++ b/vm-cpu/agent/src/main/java/com/redhat/thermostat/vm/cpu/agent/internal/VmCpuBackend.java Mon Jan 30 10:30:19 2017 -0500 @@ -89,12 +89,9 @@ long ticksPerSecond = SysConf.getClockTicksPerSecond(); ProcDataSource source = new ProcDataSource(); int numCpus = getCpuCount(source); - ProcessStatusInfoBuilder PSIBuilder = OS.IS_LINUX ? new LinuxProcessStatusInfoBuilderImpl(source) : new WindowsProcessStatusInfoBuilderImpl(); + ProcessStatusInfoBuilder PSIBuilder = new ProcessStatusInfoBuilderImpl(); builder = new VmCpuStatBuilder(clock, numCpus, ticksPerSecond, PSIBuilder, id); this.dao = dao; - if (OS.IS_WINDOWS) { - LOGGER.log(Level.WARNING, "VmCpu backend is not yet ported to Windows"); - } } @Override @@ -110,18 +107,18 @@ } private int getCpuCount(ProcDataSource dataSource) { - return OS.IS_WINDOWS ? getWindowsCpuCount() : getLinuxCpuCount(dataSource); + return OS.IS_LINUX ? getLinuxCpuCount(dataSource) : getCpuCount(); } - private int getWindowsCpuCount() { - return PortableHostImpl.INSTANCE.getCPUCount(); + private int getCpuCount() { + return PortableHostImpl.getInstance().getCPUCount(); } private int getLinuxCpuCount(ProcDataSource dataSource) { final String KEY_PROCESSOR_ID = "processor"; int cpuCount = 0; try (BufferedReader bufferedReader = new BufferedReader(dataSource.getCpuInfoReader())) { - String line = null; + String line; while ((line = bufferedReader.readLine()) != null) { if (line.startsWith(KEY_PROCESSOR_ID)) { cpuCount++; diff -r 006ac47d1506 -r cd5b08c32052 vm-cpu/agent/src/main/java/com/redhat/thermostat/vm/cpu/agent/internal/WindowsProcessStatusInfoBuilderImpl.java --- a/vm-cpu/agent/src/main/java/com/redhat/thermostat/vm/cpu/agent/internal/WindowsProcessStatusInfoBuilderImpl.java Thu Jan 26 12:14:51 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,58 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.vm.cpu.agent.internal; - -import com.redhat.thermostat.common.portability.PortableProcessImpl; -import com.redhat.thermostat.common.portability.PortableProcessStat; - -/** - * Extract status information about the process - */ -public class WindowsProcessStatusInfoBuilderImpl implements ProcessStatusInfoBuilder { - - WindowsProcessStatusInfoBuilderImpl() { - } - - public ProcessStatusInfo build(int pid) { - - final PortableProcessStat info = PortableProcessImpl.INSTANCE.getProcessStat(pid); - - return new ProcessStatusInfo(pid, info.getUserTime(), info.getKernelTime()); - } - -} - diff -r 006ac47d1506 -r cd5b08c32052 vm-cpu/agent/src/test/java/com/redhat/thermostat/vm/cpu/agent/internal/LinuxProcessStatusInfoBuilderTest.java --- a/vm-cpu/agent/src/test/java/com/redhat/thermostat/vm/cpu/agent/internal/LinuxProcessStatusInfoBuilderTest.java Thu Jan 26 12:14:51 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,143 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.vm.cpu.agent.internal; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import java.io.IOException; -import java.io.StringReader; - -import org.junit.Test; - -import com.redhat.thermostat.common.portability.linux.ProcDataSource; - -public class LinuxProcessStatusInfoBuilderTest { - - @Test - public void testSimpleProcessStatus() { - ProcDataSource dataSource = new ProcDataSource(); - ProcessStatusInfo stat = new LinuxProcessStatusInfoBuilderImpl(dataSource).build(1); - assertNotNull(stat); - } - - @Test - public void testKnownProcessStatus() throws IOException { - final int PID = 10363; - String PROCESS_NAME = "(bash)"; - String STATE = "S"; - String PPID = "1737"; - String PROCESS_GROUP_ID = "10363"; - String SESSION_ID = "10363"; - String TTY_NUMBER = "34817"; - String TTY_PROCESS_GROUP_ID = "11404"; - String FLAGS_WORD = "4202496"; - String MINOR_FAULTS = "8093"; - String MINOR_FAULTS_CHILDREN = "607263"; - String MAJOR_FAULTS = "1"; - String MAJOR_FAULTS_CHILDREN = "251"; - final long USER_TIME_TICKS = 21; - final long KERNEL_TIME_TICKS = 7; - final long USER_TIME_CHILDREN = 10; - String KERNEL_TIME_CHILDREN = "1000"; - String PRIORITY = "20"; - String statString = "" + - PID + " " + PROCESS_NAME + " " + STATE + " " + PPID + " " - + PROCESS_GROUP_ID + " " + SESSION_ID + " " + TTY_NUMBER + " " - + TTY_PROCESS_GROUP_ID + " " + FLAGS_WORD + " " + MINOR_FAULTS + " " - + MINOR_FAULTS_CHILDREN + " " + MAJOR_FAULTS + " " + MAJOR_FAULTS_CHILDREN + " " + - USER_TIME_TICKS + " " + KERNEL_TIME_TICKS + " " + USER_TIME_CHILDREN + " " + - KERNEL_TIME_CHILDREN + " " + PRIORITY; - - ProcDataSource dataSource = mock(ProcDataSource.class); - when(dataSource.getStatReader(any(Integer.class))).thenReturn(new StringReader(statString)); - ProcessStatusInfoBuilder builder = new LinuxProcessStatusInfoBuilderImpl(dataSource); - ProcessStatusInfo stat = builder.build(PID); - - verify(dataSource).getStatReader(PID); - assertNotNull(stat); - assertEquals(PID, stat.getPid()); - assertEquals(USER_TIME_TICKS, stat.getUserTime()); - assertEquals(KERNEL_TIME_TICKS, stat.getKernelTime()); - } - - @Test - public void testBadProcessName() throws IOException { - final int PID = 10363; - String PROCESS_NAME = "(secretly-bad process sleep 10 20 ) 6)"; - String STATE = "S"; - String PPID = "1737"; - String PROCESS_GROUP_ID = "10363"; - String SESSION_ID = "10363"; - String TTY_NUMBER = "34817"; - String TTY_PROCESS_GROUP_ID = "11404"; - String FLAGS_WORD = "4202496"; - String MINOR_FAULTS = "8093"; - String MINOR_FAULTS_CHILDREN = "607263"; - String MAJOR_FAULTS = "1"; - String MAJOR_FAULTS_CHILDREN = "251"; - final long USER_TIME_TICKS = 21; - final long KERNEL_TIME_TICKS = 7; - final long USER_TIME_CHILDREN = 10; - String KERNEL_TIME_CHILDREN = "1000"; - String PRIORITY = "20"; - String statString = "" + - PID + " " + PROCESS_NAME + " " + STATE + " " + PPID + " " - + PROCESS_GROUP_ID + " " + SESSION_ID + " " + TTY_NUMBER + " " - + TTY_PROCESS_GROUP_ID + " " + FLAGS_WORD + " " + MINOR_FAULTS + " " - + MINOR_FAULTS_CHILDREN + " " + MAJOR_FAULTS + " " + MAJOR_FAULTS_CHILDREN + " " + - USER_TIME_TICKS + " " + KERNEL_TIME_TICKS + " " + USER_TIME_CHILDREN + " " + - KERNEL_TIME_CHILDREN + " " + PRIORITY; - - ProcDataSource dataSource = mock(ProcDataSource.class); - when(dataSource.getStatReader(any(Integer.class))).thenReturn(new StringReader(statString)); - ProcessStatusInfoBuilder builder = new LinuxProcessStatusInfoBuilderImpl(dataSource); - ProcessStatusInfo stat = builder.build(PID); - - verify(dataSource).getStatReader(PID); - assertNotNull(stat); - assertEquals(PID, stat.getPid()); - assertEquals(USER_TIME_TICKS, stat.getUserTime()); - assertEquals(KERNEL_TIME_TICKS, stat.getKernelTime()); - } - -} - diff -r 006ac47d1506 -r cd5b08c32052 vm-io/agent/src/main/java/com/redhat/thermostat/vm/io/agent/internal/LinuxVmIoStatBuilder.java --- a/vm-io/agent/src/main/java/com/redhat/thermostat/vm/io/agent/internal/LinuxVmIoStatBuilder.java Thu Jan 26 12:14:51 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,65 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.vm.io.agent.internal; - -import com.redhat.thermostat.common.Clock; -import com.redhat.thermostat.storage.core.WriterID; -import com.redhat.thermostat.vm.io.common.VmIoStat; - -public class LinuxVmIoStatBuilder implements VmIoStatBuilder { - - private final Clock clock; - private final ProcIoDataReader ioReader; - private final String writerId; - - LinuxVmIoStatBuilder(Clock clock, ProcIoDataReader ioReader, WriterID writerId) { - this.clock = clock; - this.ioReader = ioReader; - - this.writerId = writerId.getWriterID(); - } - - public synchronized VmIoStat build(String vmId, Integer pid) { - ProcIoData data = ioReader.read(pid); - if (data == null) { - return null; - } - long miliTime = clock.getRealTimeMillis(); - return new VmIoStat(writerId, vmId, miliTime, data.rchar, data.wchar, data.syscr, data.syscw); - } - -} diff -r 006ac47d1506 -r cd5b08c32052 vm-io/agent/src/main/java/com/redhat/thermostat/vm/io/agent/internal/ProcIoData.java --- a/vm-io/agent/src/main/java/com/redhat/thermostat/vm/io/agent/internal/ProcIoData.java Thu Jan 26 12:14:51 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,66 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.vm.io.agent.internal; - -public class ProcIoData { - - // This matches the proc file format. The file format is described at: - // http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/filesystems/proc.txt - - public final long rchar; - public final long wchar; - public final long syscr; - public final long syscw; - public final long read_bytes; - public final long write_bytes; - public final long cancelled_write_bytes; - - public ProcIoData(long rchar, long wchar, - long syscr, long syscw, - long read_bytes, long write_bytes, - long cancelled_write_bytes) { - this.rchar = rchar; - this.wchar = wchar; - this.syscr = syscr; - this.syscw = syscw; - this.read_bytes = read_bytes; - this.write_bytes = write_bytes; - this.cancelled_write_bytes = cancelled_write_bytes; - } - -} - diff -r 006ac47d1506 -r cd5b08c32052 vm-io/agent/src/main/java/com/redhat/thermostat/vm/io/agent/internal/ProcIoDataReader.java --- a/vm-io/agent/src/main/java/com/redhat/thermostat/vm/io/agent/internal/ProcIoDataReader.java Thu Jan 26 12:14:51 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,117 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.vm.io.agent.internal; - -import java.io.BufferedReader; -import java.io.IOException; -import java.util.logging.Level; -import java.util.logging.Logger; - -import com.redhat.thermostat.common.portability.linux.ProcDataSource; -import com.redhat.thermostat.common.utils.LoggingUtils; - -/** - * Extract information from {@code /proc//io}. - */ -public class ProcIoDataReader { - - private static final Logger logger = LoggingUtils.getLogger(ProcIoDataReader.class); - - private final ProcDataSource dataSource; - - public ProcIoDataReader(ProcDataSource dataSource) { - this.dataSource = dataSource; - } - - public ProcIoData read(int pid) { - try (BufferedReader reader = new BufferedReader(dataSource.getIoReader(pid))) { - return read(reader); - } catch (IOException e) { - logger.log(Level.FINE, "Unable to read io info for: " + pid); - } - - return null; - } - - private ProcIoData read(BufferedReader r) throws IOException { - // The file format is described at: - // http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/filesystems/proc.txt - - final int UNKNOWN_VALUE = -1; - long rchar = UNKNOWN_VALUE; - long wchar = UNKNOWN_VALUE; - long syscr = UNKNOWN_VALUE; - long syscw = UNKNOWN_VALUE; - long read_bytes = UNKNOWN_VALUE; - long write_bytes = UNKNOWN_VALUE; - long cancelled_write_bytes = UNKNOWN_VALUE; - - String line; - while ((line = r.readLine()) != null) { - String[] parts = line.split(":"); - String key = parts[0].trim(); - String value = parts[1].trim(); - switch (key) { - case "rchar": - rchar = Long.valueOf(value); - break; - case "wchar": - wchar = Long.valueOf(value); - break; - case "syscr": - syscr = Long.valueOf(value); - break; - case "syscw": - syscw = Long.valueOf(value); - break; - case "read_bytes": - read_bytes = Long.valueOf(value); - break; - case "write_bytes": - write_bytes = Long.valueOf(value); - break; - case "cancelled_write_bytes": - cancelled_write_bytes = Long.valueOf(value); - break; - } - } - - return new ProcIoData(rchar, wchar, syscr, syscw, read_bytes, write_bytes, cancelled_write_bytes); - } - -} - diff -r 006ac47d1506 -r cd5b08c32052 vm-io/agent/src/main/java/com/redhat/thermostat/vm/io/agent/internal/VmIoBackend.java --- a/vm-io/agent/src/main/java/com/redhat/thermostat/vm/io/agent/internal/VmIoBackend.java Thu Jan 26 12:14:51 2017 -0500 +++ b/vm-io/agent/src/main/java/com/redhat/thermostat/vm/io/agent/internal/VmIoBackend.java Mon Jan 30 10:30:19 2017 -0500 @@ -37,13 +37,11 @@ package com.redhat.thermostat.vm.io.agent.internal; import com.redhat.thermostat.agent.VmStatusListenerRegistrar; -import com.redhat.thermostat.common.portability.linux.ProcDataSource; import com.redhat.thermostat.backend.VmListenerBackend; import com.redhat.thermostat.backend.VmUpdate; import com.redhat.thermostat.backend.VmUpdateListener; import com.redhat.thermostat.common.Clock; import com.redhat.thermostat.common.Version; -import com.redhat.thermostat.shared.config.OS; import com.redhat.thermostat.storage.core.WriterID; import com.redhat.thermostat.vm.io.common.Constants; import com.redhat.thermostat.vm.io.common.VmIoStat; @@ -59,8 +57,7 @@ VmStatusListenerRegistrar registrar, WriterID writerId) { this(version, vmIoStatDao, - OS.IS_LINUX ? new LinuxVmIoStatBuilder(clock, new ProcIoDataReader(new ProcDataSource()), writerId) - : new WindowsVmIoStatBuilder(clock, writerId), + new VmIoStatBuilderImpl(clock, writerId), registrar, writerId); } diff -r 006ac47d1506 -r cd5b08c32052 vm-io/agent/src/main/java/com/redhat/thermostat/vm/io/agent/internal/VmIoStatBuilderImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-io/agent/src/main/java/com/redhat/thermostat/vm/io/agent/internal/VmIoStatBuilderImpl.java Mon Jan 30 10:30:19 2017 -0500 @@ -0,0 +1,60 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.io.agent.internal; + +import com.redhat.thermostat.common.Clock; +import com.redhat.thermostat.common.portability.PortableVmIoStat; +import com.redhat.thermostat.storage.core.WriterID; +import com.redhat.thermostat.vm.io.common.VmIoStat; + +public class VmIoStatBuilderImpl implements VmIoStatBuilder { + + private final Clock clock; + private final String writerId; + + VmIoStatBuilderImpl(Clock clock, WriterID writerId) { + this.clock = clock; + this.writerId = writerId.getWriterID(); + } + + public synchronized VmIoStat build(String vmId, Integer pid) { + + PortableVmIoStat data = PortableVmIoStat.build(clock, pid); + return (data != null) ? new VmIoStat(writerId, vmId, data.getTimeStamp(), data.getCharactersRead(), data.getCharactersWritten(), data.getReadSyscalls(), data.getWriteSyscalls()) : null; + } + +} diff -r 006ac47d1506 -r cd5b08c32052 vm-io/agent/src/main/java/com/redhat/thermostat/vm/io/agent/internal/WindowsVmIoStatBuilder.java --- a/vm-io/agent/src/main/java/com/redhat/thermostat/vm/io/agent/internal/WindowsVmIoStatBuilder.java Thu Jan 26 12:14:51 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,60 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.vm.io.agent.internal; - -import com.redhat.thermostat.common.Clock; -import com.redhat.thermostat.common.portability.PortableVmIoStat; -import com.redhat.thermostat.storage.core.WriterID; -import com.redhat.thermostat.vm.io.common.VmIoStat; - -public class WindowsVmIoStatBuilder implements VmIoStatBuilder { - - private final Clock clock; - private final String writerId; - - WindowsVmIoStatBuilder(Clock clock, WriterID writerId) { - this.clock = clock; - this.writerId = writerId.getWriterID(); - } - - public synchronized VmIoStat build(String vmId, Integer pid) { - - PortableVmIoStat data = PortableVmIoStat.build(clock, pid); - return new VmIoStat(writerId, vmId, data.getTimeStamp(), data.getCharactersRead(), data.getCharactersWritten(), data.getReadSyscalls(), data.getWriteSyscalls()); - } - -} diff -r 006ac47d1506 -r cd5b08c32052 vm-io/agent/src/test/java/com/redhat/thermostat/vm/io/agent/internal/LinuxVmIoStatBuilderTest.java --- a/vm-io/agent/src/test/java/com/redhat/thermostat/vm/io/agent/internal/LinuxVmIoStatBuilderTest.java Thu Jan 26 12:14:51 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,100 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.vm.io.agent.internal; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import org.junit.Before; -import org.junit.Test; - -import com.redhat.thermostat.common.Clock; -import com.redhat.thermostat.storage.core.WriterID; -import com.redhat.thermostat.vm.io.common.VmIoStat; - -public class LinuxVmIoStatBuilderTest { - - private WriterID writerID; - - @Before - public void setup() { - writerID = mock(WriterID.class); - } - - @Test - public void testBuilderBuildsNullForUnknownPid() { - Clock clock = mock(Clock.class); - ProcIoDataReader procDataReader = mock(ProcIoDataReader.class); - LinuxVmIoStatBuilder builder = new LinuxVmIoStatBuilder(clock, procDataReader, writerID); - VmIoStat result = builder.build("vmId", 0); - assertNull(result); - } - - @Test - public void testBuildWithSufficientInformation() { - final int PID = 0; - - int rchar = 1; - int wchar = 2; - int syscr = 3; - int syscw = 4; - int read_bytes = 5; - int write_bytes = 6; - int cancelled_write_bytes = 7; - - final ProcIoData data = new ProcIoData(rchar, wchar, syscr, syscw, - read_bytes, write_bytes, cancelled_write_bytes); - - ProcIoDataReader ioReader = mock(ProcIoDataReader.class); - when(ioReader.read(PID)).thenReturn(data); - Clock clock = mock(Clock.class); - - LinuxVmIoStatBuilder builder = new LinuxVmIoStatBuilder(clock, ioReader, writerID); - - VmIoStat ioData = builder.build("vmId", PID); - assertNotNull(ioData); - assertEquals(rchar, ioData.getCharactersRead()); - assertEquals(wchar, ioData.getCharactersWritten()); - assertEquals(syscr, ioData.getReadSyscalls()); - assertEquals(syscw, ioData.getWriteSyscalls()); - } - -} - diff -r 006ac47d1506 -r cd5b08c32052 vm-io/agent/src/test/java/com/redhat/thermostat/vm/io/agent/internal/ProcIoDataReaderTest.java --- a/vm-io/agent/src/test/java/com/redhat/thermostat/vm/io/agent/internal/ProcIoDataReaderTest.java Thu Jan 26 12:14:51 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,76 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.vm.io.agent.internal; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import java.io.StringReader; - -import org.junit.Test; - -import com.redhat.thermostat.common.portability.linux.ProcDataSource; - -public class ProcIoDataReaderTest { - - @Test - public void verifyIsParsedCorrectly() throws Exception { - final int SOME_PID = 0; - String fileContents = "" + - "rchar: 19961133\n" + - "wchar: 2451715\n" + - "syscr: 17880\n" + - "syscw: 13870\n" + - "read_bytes: 21004288\n" + - "write_bytes: 811008\n" + - "cancelled_write_bytes: 16384\n"; - ProcDataSource dataSource = mock(ProcDataSource.class); - when(dataSource.getIoReader(SOME_PID)).thenReturn(new StringReader(fileContents)); - - ProcIoData parsedData = new ProcIoDataReader(dataSource).read(SOME_PID); - - assertEquals(19961133, parsedData.rchar); - assertEquals(2451715, parsedData.wchar); - assertEquals(17880, parsedData.syscr); - assertEquals(13870, parsedData.syscw); - assertEquals(21004288, parsedData.read_bytes); - assertEquals(811008, parsedData.write_bytes); - assertEquals(16384, parsedData.cancelled_write_bytes); - - } -} diff -r 006ac47d1506 -r cd5b08c32052 vm-io/agent/src/test/java/com/redhat/thermostat/vm/io/agent/internal/VmIoBackendTest.java --- a/vm-io/agent/src/test/java/com/redhat/thermostat/vm/io/agent/internal/VmIoBackendTest.java Thu Jan 26 12:14:51 2017 -0500 +++ b/vm-io/agent/src/test/java/com/redhat/thermostat/vm/io/agent/internal/VmIoBackendTest.java Mon Jan 30 10:30:19 2017 -0500 @@ -44,7 +44,6 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import com.redhat.thermostat.shared.config.OS; import org.junit.Before; import org.junit.Test; @@ -71,7 +70,7 @@ registrar = mock(VmStatusListenerRegistrar.class); WriterID id = mock(WriterID.class); - ioStatBuilder = OS.IS_LINUX ? mock(LinuxVmIoStatBuilder.class) : mock(WindowsVmIoStatBuilder.class); + ioStatBuilder = mock(VmIoStatBuilderImpl.class); backend = new VmIoBackend(version, vmIoStatDao, ioStatBuilder, registrar, id); } diff -r 006ac47d1506 -r cd5b08c32052 vm-io/agent/src/test/java/com/redhat/thermostat/vm/io/agent/internal/VmIoStatBuilderTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-io/agent/src/test/java/com/redhat/thermostat/vm/io/agent/internal/VmIoStatBuilderTest.java Mon Jan 30 10:30:19 2017 -0500 @@ -0,0 +1,67 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.io.agent.internal; + +import com.redhat.thermostat.common.Clock; +import com.redhat.thermostat.storage.core.WriterID; +import com.redhat.thermostat.vm.io.common.VmIoStat; +import org.junit.Assume; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertNull; +import static org.mockito.Mockito.mock; + +public class VmIoStatBuilderTest { + + private WriterID writerID; + + @Before + public void setup() { + writerID = mock(WriterID.class); + } + + @Test + public void testBuilderBuildsNullForUnknownPid() { + Clock clock = mock(Clock.class); + VmIoStatBuilder builder = new VmIoStatBuilderImpl(clock, writerID); + VmIoStat result = builder.build("vmId", 0); + assertNull(result); + } + +} + diff -r 006ac47d1506 -r cd5b08c32052 vm-io/agent/src/test/java/com/redhat/thermostat/vm/io/agent/internal/WindowsVmIoStatBuilderTest.java --- a/vm-io/agent/src/test/java/com/redhat/thermostat/vm/io/agent/internal/WindowsVmIoStatBuilderTest.java Thu Jan 26 12:14:51 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,72 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.vm.io.agent.internal; - -import com.redhat.thermostat.common.Clock; -import com.redhat.thermostat.shared.config.OS; -import com.redhat.thermostat.storage.core.WriterID; -import com.redhat.thermostat.vm.io.common.VmIoStat; -import org.junit.Assume; -import org.junit.Before; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class WindowsVmIoStatBuilderTest { - - private WriterID writerID; - - @Before - public void setup() { - writerID = mock(WriterID.class); - } - - @Test - public void testBuilderBuildsNullForUnknownPid() { - Assume.assumeTrue(OS.IS_WINDOWS); - Clock clock = mock(Clock.class); - VmIoStatBuilder builder = new WindowsVmIoStatBuilder(clock, writerID); - VmIoStat result = builder.build("vmId", 0); - assertNull(result); - } - -} -