1e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin/* 2e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin * Copyright (C) 2010 Google Inc. 3e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin * 4e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin * Licensed under the Apache License, Version 2.0 (the "License"); 5e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin * you may not use this file except in compliance with the License. 6e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin * You may obtain a copy of the License at 7e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin * 8e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin * http://www.apache.org/licenses/LICENSE-2.0 9e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin * 10e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin * Unless required by applicable law or agreed to in writing, software 11e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin * distributed under the License is distributed on an "AS IS" BASIS, 12e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin * See the License for the specific language governing permissions and 14e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin * limitations under the License. 15e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin */ 16e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin 17e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffinpackage com.google.caliper.runner; 18e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin 19e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffinimport com.google.caliper.model.Host; 20e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffinimport com.google.common.collect.ImmutableMultimap; 21e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffinimport com.google.common.collect.ImmutableMultiset; 22e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffinimport com.google.common.collect.Maps; 23e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffinimport com.google.common.collect.Multimap; 24e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffinimport com.google.common.io.Files; 25e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin 26e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffinimport java.io.File; 27e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffinimport java.io.IOException; 28e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffinimport java.nio.charset.Charset; 29e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffinimport java.util.Collection; 30e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffinimport java.util.List; 31e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffinimport java.util.Map; 32e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffinimport java.util.TreeMap; 33e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin 34e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin/** 35e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin * An instance of this class is responsible for returning a Map that describes the environment: 36e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin * JVM version, os details, etc. 37e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin */ 38e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffinfinal class EnvironmentGetter { 39e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin Host getHost() { 40e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin return new Host.Builder() 41e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin .addAllProperies(getProperties()) 42e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin .build(); 43e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin } 44e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin 45e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin private Map<String, String> getProperties() { 46e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin TreeMap<String, String> propertyMap = Maps.newTreeMap(); 47e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin 48e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin Map<String, String> sysProps = Maps.fromProperties(System.getProperties()); 49e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin 50e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin // Sometimes java.runtime.version is more descriptive than java.version 51e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin String version = sysProps.get("java.version"); 52e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin String alternateVersion = sysProps.get("java.runtime.version"); 53e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin if (alternateVersion != null && alternateVersion.length() > version.length()) { 54e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin version = alternateVersion; 55e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin } 56e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin propertyMap.put("host.availableProcessors", 57e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin Integer.toString(Runtime.getRuntime().availableProcessors())); 58e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin 59e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin String osName = sysProps.get("os.name"); 60e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin propertyMap.put("os.name", osName); 61e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin propertyMap.put("os.version", sysProps.get("os.version")); 62e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin propertyMap.put("os.arch", sysProps.get("os.arch")); 63e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin 64e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin if (osName.equals("Linux")) { 65e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin getLinuxEnvironment(propertyMap); 66e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin } 67e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin 68e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin return propertyMap; 69e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin } 70e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin 71e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin private void getLinuxEnvironment(Map<String, String> propertyMap) { 72e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin // the following probably doesn't work on ALL linux 73e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin Multimap<String, String> cpuInfo = propertiesFromLinuxFile("/proc/cpuinfo"); 74e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin propertyMap.put("host.cpus", Integer.toString(cpuInfo.get("processor").size())); 75e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin String s = "cpu cores"; 76e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin propertyMap.put("host.cpu.cores", describe(cpuInfo, s)); 77e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin propertyMap.put("host.cpu.names", describe(cpuInfo, "model name")); 78e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin propertyMap.put("host.cpu.cachesize", describe(cpuInfo, "cache size")); 79e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin 80e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin Multimap<String, String> memInfo = propertiesFromLinuxFile("/proc/meminfo"); 81e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin // TODO redo memInfo.toString() so we don't get square brackets 82e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin propertyMap.put("host.memory.physical", memInfo.get("MemTotal").toString()); 83e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin propertyMap.put("host.memory.swap", memInfo.get("SwapTotal").toString()); 84e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin } 85e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin 86e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin private static String describe(Multimap<String, String> cpuInfo, String s) { 87e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin Collection<String> strings = cpuInfo.get(s); 88e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin // TODO redo the ImmutableMultiset.toString() call so we don't get square brackets 89e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin return (strings.size() == 1) 90e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin ? strings.iterator().next() 91e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin : ImmutableMultiset.copyOf(strings).toString(); 92e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin } 93e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin 94e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin /** 95e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin * Returns the key/value pairs from the specified properties-file like file. 96e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin * Unlike standard Java properties files, {@code reader} is allowed to list 97e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin * the same property multiple times. Comments etc. are unsupported. 98e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin * 99e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin * <p>If there's any problem reading the file's contents, we'll return an 100e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin * empty Multimap. 101e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin */ 102e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin private static Multimap<String, String> propertiesFromLinuxFile(String file) { 103e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin try { 104e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin List<String> lines = Files.readLines(new File(file), Charset.defaultCharset()); 105e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin ImmutableMultimap.Builder<String, String> result = ImmutableMultimap.builder(); 106e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin for (String line : lines) { 107e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin // TODO(schmoe): replace with Splitter (in Guava release 10) 108e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin String[] parts = line.split("\\s*\\:\\s*", 2); 109e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin if (parts.length == 2) { 110e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin result.put(parts[0], parts[1]); 111e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin } 112e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin } 113e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin return result.build(); 114e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin } catch (IOException e) { 115e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin // If there's any problem reading the file, just return an empty multimap. 116e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin return ImmutableMultimap.of(); 117e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin } 118e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin } 119e236301e5fc778bffe1748ed80d7936e6c807012Paul Duffin} 120