Mercurial > hg > release > thermostat-0.4
changeset 589:f7953e6ce321
Separate api for querying
Introduce a new type, Query, for representing queries (SELECT in
sql-speak). This limits the Chunk type to just representing data
rather than both data and queries.
Reviewed-by: neugens, rkennke
Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2012-August/002662.html
line wrap: on
line diff
--- a/common/core/src/main/java/com/redhat/thermostat/common/dao/HeapDAOImpl.java Fri Sep 07 17:22:36 2012 +0200 +++ b/common/core/src/main/java/com/redhat/thermostat/common/dao/HeapDAOImpl.java Fri Sep 07 11:42:51 2012 -0400 @@ -55,13 +55,15 @@ import com.redhat.thermostat.common.storage.Chunk; import com.redhat.thermostat.common.storage.Cursor; import com.redhat.thermostat.common.storage.Key; +import com.redhat.thermostat.common.storage.Query; +import com.redhat.thermostat.common.storage.Query.Criteria; import com.redhat.thermostat.common.storage.Storage; class HeapDAOImpl implements HeapDAO { private static final Logger log = Logger.getLogger(HeapDAOImpl.class.getName()); - private Storage storage; + private final Storage storage; HeapDAOImpl(Storage storage) { this.storage = storage; @@ -73,6 +75,8 @@ int vmId = heapInfo.getVmId(); Chunk chunk = new Chunk(heapInfoCategory, false); + // We dont add a Key.AGENT_ID here explicitly. Storage takes care of that. + chunk.put(Key.VM_ID, vmId); chunk.put(Key.TIMESTAMP, heapInfo.getTimestamp()); String id = heapInfo.getHeapId(); @@ -103,16 +107,27 @@ } } - Chunk entry = storage.find(chunk); + Query justInsertedHeap = storage.createQuery() + .from(heapInfoCategory) + .where(Key.VM_ID, Criteria.EQUALS, vmId) + .where(Key.TIMESTAMP, Criteria.EQUALS, heapInfo.getTimestamp()); + if (heapDumpData != null) { + justInsertedHeap.where(heapDumpIdKey, Criteria.EQUALS, heapDumpId); + } + if (histogramData != null) { + justInsertedHeap.where(histogramIdKey, Criteria.EQUALS, histogramId); + } + + Chunk entry = storage.find(justInsertedHeap); heapInfo.setHeapId(entry.get(Key.ID)); } @Override public Collection<HeapInfo> getAllHeapInfo(VmRef vm) { - - Chunk query = new Chunk(heapInfoCategory, false); - query.put(Key.AGENT_ID, vm.getAgent().getAgentId()); - query.put(Key.VM_ID, vm.getId()); + Query query = storage.createQuery() + .from(heapInfoCategory) + .where(Key.AGENT_ID, Criteria.EQUALS, vm.getAgent().getAgentId()) + .where(Key.VM_ID, Criteria.EQUALS, vm.getId()); Cursor cursor = storage.findAll(query); Collection<HeapInfo> heapInfos = new ArrayList<>(); while (cursor.hasNext()) { @@ -149,8 +164,9 @@ @Override public HeapInfo getHeapInfo(String heapId) { - Chunk query = new Chunk(heapInfoCategory, false); - query.put(Key.ID, heapId); + Query query = storage.createQuery() + .from(heapInfoCategory) + .where(Key.ID, Criteria.EQUALS, heapId); Chunk found = null; try { found = storage.find(query);
--- a/common/core/src/main/java/com/redhat/thermostat/common/dao/HostInfoDAOImpl.java Fri Sep 07 17:22:36 2012 +0200 +++ b/common/core/src/main/java/com/redhat/thermostat/common/dao/HostInfoDAOImpl.java Fri Sep 07 11:42:51 2012 -0400 @@ -44,10 +44,13 @@ import com.redhat.thermostat.common.storage.Chunk; import com.redhat.thermostat.common.storage.Cursor; import com.redhat.thermostat.common.storage.Key; +import com.redhat.thermostat.common.storage.Query; import com.redhat.thermostat.common.storage.Storage; +import com.redhat.thermostat.common.storage.Query.Criteria; class HostInfoDAOImpl implements HostInfoDAO { private Storage storage; + private HostInfoConverter converter; public HostInfoDAOImpl(Storage storage) { @@ -57,8 +60,9 @@ @Override public HostInfo getHostInfo(HostRef ref) { - Chunk query = new Chunk(hostInfoCategory, false); - query.put(Key.AGENT_ID, ref.getAgentId()); + Query query = storage.createQuery() + .from(hostInfoCategory) + .where(Key.AGENT_ID, Criteria.EQUALS, ref.getAgentId()); Chunk result = storage.find(query); return result == null ? null : converter.fromChunk(result); } @@ -70,10 +74,11 @@ @Override public Collection<HostRef> getHosts() { - return getHosts(new Chunk(hostInfoCategory, false)); + Query allHosts = storage.createQuery().from(hostInfoCategory); + return getHosts(allHosts); } - private Collection<HostRef> getHosts(Chunk filter) { + private Collection<HostRef> getHosts(Query filter) { Collection<HostRef> hosts = new ArrayList<HostRef>(); Cursor hostsCursor = storage.findAll(filter); @@ -91,14 +96,17 @@ Collection<HostRef> hosts = new ArrayList<HostRef>(); - Chunk agents = new Chunk(AgentInformation.AGENT_INFO_CATEGORY, false); - agents.put(AgentInformation.AGENT_ALIVE_KEY, true); - Cursor agentCursor = storage.findAll(agents); + Query aliveAgents = storage.createQuery() + .from(AgentInformation.AGENT_INFO_CATEGORY) + .where(AgentInformation.AGENT_ALIVE_KEY, Criteria.EQUALS, true); + + Cursor agentCursor = storage.findAll(aliveAgents); while(agentCursor.hasNext()) { Chunk chunk = agentCursor.next(); - Chunk filter = new Chunk(hostInfoCategory, false); - filter.put(Key.AGENT_ID, chunk.get(Key.AGENT_ID)); + Query filter = storage.createQuery() + .from(hostInfoCategory) + .where(Key.AGENT_ID, Criteria.EQUALS, chunk.get(Key.AGENT_ID)); hosts.addAll(getHosts(filter)); }
--- a/common/core/src/main/java/com/redhat/thermostat/common/dao/HostLatestPojoListGetter.java Fri Sep 07 17:22:36 2012 +0200 +++ b/common/core/src/main/java/com/redhat/thermostat/common/dao/HostLatestPojoListGetter.java Fri Sep 07 11:42:51 2012 -0400 @@ -46,8 +46,10 @@ import com.redhat.thermostat.common.storage.Chunk; import com.redhat.thermostat.common.storage.Cursor; import com.redhat.thermostat.common.storage.Key; +import com.redhat.thermostat.common.storage.Query; import com.redhat.thermostat.common.storage.Storage; import com.redhat.thermostat.common.storage.Cursor.SortDirection; +import com.redhat.thermostat.common.storage.Query.Criteria; class HostLatestPojoListGetter<T extends TimeStampedPojo> implements LatestPojoListGetter<T> { @@ -74,11 +76,11 @@ @Override public List<T> getLatest() { - Chunk query = buildQuery(); + Query query = buildQuery(); return getLatest(query); } - private List<T> getLatest(Chunk query) { + private List<T> getLatest(Query query) { // TODO if multiple threads will be using this utility class, there may be some issues // with the updateTimes Long lastUpdate = lastUpdateTimes.get(ref); @@ -94,14 +96,13 @@ return result; } - protected Chunk buildQuery() { - Chunk query = new Chunk(cat, false); - query.put(Key.AGENT_ID, ref.getAgentId()); + protected Query buildQuery() { + Query query = storage.createQuery() + .from(cat) + .where(Key.AGENT_ID, Criteria.EQUALS, ref.getAgentId()); Long lastUpdate = lastUpdateTimes.get(ref); if (lastUpdate != null) { - // TODO once we have an index and the 'column' is of type long, use - // a query which can utilize an index. this one doesn't - query.put(Key.WHERE, "this.timestamp > " + lastUpdate); + query.where(Key.TIMESTAMP, Criteria.GREATER_THAN, lastUpdate); } else { lastUpdateTimes.put(ref, Long.MIN_VALUE); }
--- a/common/core/src/main/java/com/redhat/thermostat/common/dao/NetworkInterfaceInfoDAOImpl.java Fri Sep 07 17:22:36 2012 +0200 +++ b/common/core/src/main/java/com/redhat/thermostat/common/dao/NetworkInterfaceInfoDAOImpl.java Fri Sep 07 11:42:51 2012 -0400 @@ -43,7 +43,9 @@ import com.redhat.thermostat.common.storage.Chunk; import com.redhat.thermostat.common.storage.Cursor; import com.redhat.thermostat.common.storage.Key; +import com.redhat.thermostat.common.storage.Query; import com.redhat.thermostat.common.storage.Storage; +import com.redhat.thermostat.common.storage.Query.Criteria; class NetworkInterfaceInfoDAOImpl implements NetworkInterfaceInfoDAO { @@ -57,10 +59,11 @@ @Override public List<NetworkInterfaceInfo> getNetworkInterfaces(HostRef ref) { - Chunk query = new Chunk(networkInfoCategory, false); - query.put(Key.AGENT_ID, ref.getAgentId()); + Query allHostNetworkInterfaces = storage.createQuery() + .from(networkInfoCategory) + .where(Key.AGENT_ID, Criteria.EQUALS, ref.getAgentId()); - Cursor cursor = storage.findAll(query); + Cursor cursor = storage.findAll(allHostNetworkInterfaces); List<NetworkInterfaceInfo> result = new ArrayList<>(); while (cursor.hasNext()) { Chunk chunk = cursor.next();
--- a/common/core/src/main/java/com/redhat/thermostat/common/dao/VmInfoDAOImpl.java Fri Sep 07 17:22:36 2012 +0200 +++ b/common/core/src/main/java/com/redhat/thermostat/common/dao/VmInfoDAOImpl.java Fri Sep 07 11:42:51 2012 -0400 @@ -44,7 +44,9 @@ import com.redhat.thermostat.common.storage.Chunk; import com.redhat.thermostat.common.storage.Cursor; import com.redhat.thermostat.common.storage.Key; +import com.redhat.thermostat.common.storage.Query; import com.redhat.thermostat.common.storage.Storage; +import com.redhat.thermostat.common.storage.Query.Criteria; class VmInfoDAOImpl implements VmInfoDAO { @@ -58,10 +60,11 @@ @Override public VmInfo getVmInfo(VmRef ref) { - Chunk query = new Chunk(vmInfoCategory, false); - query.put(Key.AGENT_ID, ref.getAgent().getAgentId()); - query.put(vmIdKey, ref.getId()); - Chunk result = storage.find(query); + Query findMatchingVm = storage.createQuery() + .from(vmInfoCategory) + .where(Key.AGENT_ID, Criteria.EQUALS, ref.getAgent().getAgentId()) + .where(vmIdKey, Criteria.EQUALS, ref.getId()); + Chunk result = storage.find(findMatchingVm); if (result == null) { throw new DAOException("Unknown VM: host:" + ref.getAgent().getAgentId() + ";vm:" + ref.getId()); } @@ -71,14 +74,15 @@ @Override public Collection<VmRef> getVMs(HostRef host) { - Chunk query = buildQuery(host); + Query query = buildQuery(host); Cursor cursor = storage.findAll(query); return buildVMsFromQuery(cursor, host); } - private Chunk buildQuery(HostRef host) { - Chunk query = new Chunk(vmInfoCategory, false); - query.put(Key.AGENT_ID, host.getAgentId()); + private Query buildQuery(HostRef host) { + Query query = storage.createQuery() + .from(vmInfoCategory) + .where(Key.AGENT_ID, Criteria.EQUALS, host.getAgentId()); return query; }
--- a/common/core/src/main/java/com/redhat/thermostat/common/dao/VmLatestPojoListGetter.java Fri Sep 07 17:22:36 2012 +0200 +++ b/common/core/src/main/java/com/redhat/thermostat/common/dao/VmLatestPojoListGetter.java Fri Sep 07 11:42:51 2012 -0400 @@ -38,8 +38,9 @@ import com.redhat.thermostat.common.model.TimeStampedPojo; import com.redhat.thermostat.common.storage.Category; -import com.redhat.thermostat.common.storage.Chunk; import com.redhat.thermostat.common.storage.Key; +import com.redhat.thermostat.common.storage.Query; +import com.redhat.thermostat.common.storage.Query.Criteria; import com.redhat.thermostat.common.storage.Storage; class VmLatestPojoListGetter<T extends TimeStampedPojo> extends HostLatestPojoListGetter<T> { @@ -56,9 +57,9 @@ } @Override - protected Chunk buildQuery() { - Chunk query = super.buildQuery(); - query.put(Key.VM_ID, vmRef.getId()); + protected Query buildQuery() { + Query query = super.buildQuery(); + query.where(Key.VM_ID, Criteria.EQUALS, vmRef.getId()); return query; } }
--- a/common/core/src/main/java/com/redhat/thermostat/common/dao/VmMemoryStatDAOImpl.java Fri Sep 07 17:22:36 2012 +0200 +++ b/common/core/src/main/java/com/redhat/thermostat/common/dao/VmMemoryStatDAOImpl.java Fri Sep 07 11:42:51 2012 -0400 @@ -41,10 +41,11 @@ import java.util.Map; import com.redhat.thermostat.common.model.VmMemoryStat; -import com.redhat.thermostat.common.storage.Chunk; import com.redhat.thermostat.common.storage.Cursor; import com.redhat.thermostat.common.storage.Key; +import com.redhat.thermostat.common.storage.Query; import com.redhat.thermostat.common.storage.Storage; +import com.redhat.thermostat.common.storage.Query.Criteria; class VmMemoryStatDAOImpl implements VmMemoryStatDAO { @@ -60,9 +61,10 @@ @Override public VmMemoryStat getLatestMemoryStat(VmRef ref) { - Chunk query = new Chunk(vmMemoryStatsCategory, false); - query.put(Key.AGENT_ID, ref.getAgent().getAgentId()); - query.put(Key.VM_ID, ref.getId()); + Query query = storage.createQuery() + .from(vmMemoryStatsCategory) + .where(Key.AGENT_ID, Criteria.EQUALS, ref.getAgent().getAgentId()) + .where(Key.VM_ID, Criteria.EQUALS, ref.getId()); Cursor cursor = storage.findAll(query).sort(Key.TIMESTAMP, Cursor.SortDirection.DESCENDING).limit(1); if (cursor.hasNext()) { return converter.fromChunk(cursor.next());
--- a/common/core/src/main/java/com/redhat/thermostat/common/storage/Key.java Fri Sep 07 17:22:36 2012 +0200 +++ b/common/core/src/main/java/com/redhat/thermostat/common/storage/Key.java Fri Sep 07 11:42:51 2012 -0400 @@ -46,7 +46,6 @@ public static final Key<Long> TIMESTAMP = new Key<>("timestamp", false); public static final Key<String> AGENT_ID = new Key<>("agent-id", true); public static final Key<Integer> VM_ID = new Key<>("vm-id", true); - public static final Key<String> WHERE = new Key<>("$where", false); public static final Key<String> ID = new Key<>("_id", false); private String name;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/core/src/main/java/com/redhat/thermostat/common/storage/MongoQuery.java Fri Sep 07 11:42:51 2012 -0400 @@ -0,0 +1,122 @@ +/* + * Copyright 2012 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 + * <http://www.gnu.org/licenses/>. + * + * 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.storage; + +import java.util.Objects; + +import com.mongodb.BasicDBObject; +import com.mongodb.DBObject; + +public class MongoQuery implements Query { + + private Category category; + private BasicDBObject query = new BasicDBObject(); + + @Override + public MongoQuery from(Category category) { + this.category = category; + return this; + } + + @Override + public <T> MongoQuery where(Key<T> key, Criteria operator, T value) { + return where(key.getName(), operator, value); + } + + public MongoQuery where(String key, Criteria operator, Object value) { + switch (operator) { + case EQUALS: + query.put(key, value); + break; + + case NOT_EQUAL_TO: + query.put(key, new BasicDBObject("$ne", value)); + break; + + case LESS_THAN: + query.put(key, new BasicDBObject("$lt", value)); + break; + + case LESS_THAN_OR_EQUAL_TO: + query.put(key, new BasicDBObject("$lte", value)); + break; + case GREATER_THAN: + query.put(key, new BasicDBObject("$gt", value)); + break; + + case GREATER_THAN_OR_EQUAL_TO: + query.put(key, new BasicDBObject("$gte", value)); + break; + default: + throw new IllegalArgumentException("MongoQuery can not handle " + operator); + } + + return this; + } + + String getCollectionName() { + return category.getName(); + } + + DBObject getGeneratedQuery() { + return query; + } + + Category getCategory() { + return category; + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof MongoQuery)) { + return false; + } + MongoQuery other = (MongoQuery) obj; + return Objects.equals(this.category, other.category) && Objects.equals(this.query, other.query); + } + + @Override + public int hashCode() { + return Objects.hash(this.category, this.query); + } +}
--- a/common/core/src/main/java/com/redhat/thermostat/common/storage/MongoStorage.java Fri Sep 07 17:22:36 2012 +0200 +++ b/common/core/src/main/java/com/redhat/thermostat/common/storage/MongoStorage.java Fri Sep 07 11:42:51 2012 -0400 @@ -255,6 +255,14 @@ return coll; } + // TODO: This method is only temporary to enable tests, until we come up with a better design, + // in particular, the collection should be stored in the category itself. It must not be called + // from production code. + void mapCategoryToDBCollection(Category category, DBCollection coll) { + collectionCache.put(category.getName(), coll); + } + + private DBObject createConfigDBObject(AgentInformation agentInfo) { BasicDBObject result = getAgentQueryKeyFromGlobalAgent(); result.put(StorageConstants.KEY_AGENT_CONFIG_AGENT_START_TIME, agentInfo.getStartTime()); @@ -312,29 +320,34 @@ } @Override - public Cursor findAll(Chunk query) { - Category cat = query.getCategory(); - DBCollection coll = getCachedCollection(cat.getName()); - ChunkConverter converter = new ChunkConverter(); - DBObject obj = converter.chunkToDBObject(query); - DBCursor dbCursor = coll.find(obj); - return new MongoCursor(dbCursor, query.getCategory()); + public Query createQuery() { + return new MongoQuery(); } - // TODO: This method is only temporary to enable tests, until we come up with a better design, - // in particular, the collection should be stored in the category itself. It must not be called - // from production code. - void mapCategoryToDBCollection(Category category, DBCollection coll) { - collectionCache.put(category.getName(), coll); + @Override + public Cursor findAll(Query query) { + MongoQuery mongoQuery = checkAndCastQuery(query); + DBCollection coll = getCachedCollection(mongoQuery.getCollectionName()); + DBCursor dbCursor = coll.find(mongoQuery.getGeneratedQuery()); + return new MongoCursor(dbCursor, mongoQuery.getCategory()); } @Override - public Chunk find(Chunk query) { - Category cat = query.getCategory(); - DBCollection coll = getCachedCollection(cat.getName()); + public Chunk find(Query query) { + MongoQuery mongoQuery = checkAndCastQuery(query); + DBCollection coll = getCachedCollection(mongoQuery.getCollectionName()); + DBObject dbResult = coll.findOne(mongoQuery.getGeneratedQuery()); ChunkConverter converter = new ChunkConverter(); - DBObject dbResult = coll.findOne(converter.chunkToDBObject(query)); - return dbResult == null ? null : converter.dbObjectToChunk(dbResult, cat); + return dbResult == null ? null : converter.dbObjectToChunk(dbResult, mongoQuery.getCategory()); + } + + private MongoQuery checkAndCastQuery(Query query) { + if (!(query instanceof MongoQuery)) { + throw new IllegalArgumentException("MongoStorage can only handle MongoQuery"); + } + + return (MongoQuery) query; + } @Override
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/core/src/main/java/com/redhat/thermostat/common/storage/Query.java Fri Sep 07 11:42:51 2012 -0400 @@ -0,0 +1,54 @@ +/* + * Copyright 2012 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 + * <http://www.gnu.org/licenses/>. + * + * 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.storage; + +public interface Query { + + enum Criteria { + EQUALS, + NOT_EQUAL_TO, + GREATER_THAN, + GREATER_THAN_OR_EQUAL_TO, + LESS_THAN, + LESS_THAN_OR_EQUAL_TO, + } + + Query from(Category category); + + <T> Query where(Key<T> key, Criteria criteria, T value); + +}
--- a/common/core/src/main/java/com/redhat/thermostat/common/storage/Storage.java Fri Sep 07 17:22:36 2012 +0200 +++ b/common/core/src/main/java/com/redhat/thermostat/common/storage/Storage.java Fri Sep 07 11:42:51 2012 -0400 @@ -67,9 +67,9 @@ */ public abstract void purge(); - public abstract Cursor findAll(Chunk query); + public abstract Cursor findAll(Query query); - public abstract Chunk find(Chunk query); + public abstract Chunk find(Query query); public abstract Cursor findAllFromCategory(Category category); @@ -93,4 +93,6 @@ public abstract InputStream loadFile(String filename); + public abstract Query createQuery(); + }
--- a/common/core/src/main/java/com/redhat/thermostat/common/storage/StorageProvider.java Fri Sep 07 17:22:36 2012 +0200 +++ b/common/core/src/main/java/com/redhat/thermostat/common/storage/StorageProvider.java Fri Sep 07 11:42:51 2012 -0400 @@ -39,4 +39,5 @@ public interface StorageProvider { Storage createStorage(); + }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/core/src/main/java/com/redhat/thermostat/test/MockQuery.java Fri Sep 07 11:42:51 2012 -0400 @@ -0,0 +1,146 @@ +/* + * Copyright 2012 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 + * <http://www.gnu.org/licenses/>. + * + * 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.test; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +import com.redhat.thermostat.common.storage.Category; +import com.redhat.thermostat.common.storage.Key; +import com.redhat.thermostat.common.storage.Query; + +public class MockQuery implements Query { + + public static class WhereClause <T> { + public final Key<T> key; + public final Criteria criteria; + public final T value; + + public WhereClause(Key<T> key, Criteria criteria, T value) { + this.key = key; + this.criteria = criteria; + this.value = value; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (obj == this) { + return true; + } + if (!(obj instanceof WhereClause)) { + return false; + } + WhereClause<?> other = (WhereClause<?>) obj; + return Objects.equals(key, other.key) && Objects.equals(criteria, other.criteria) && Objects.equals(value, other.value); + } + + @Override + public int hashCode() { + return Objects.hash(key, criteria, value); + } + } + + private final List<WhereClause<?>> whereClauses = new ArrayList<>(); + private Category category; + + @Override + public MockQuery from(Category category) { + this.category = category; + return this; + } + + @Override + public <T> MockQuery where(Key<T> key, Criteria criteria, T value) { + whereClauses.add(new WhereClause<>(key, criteria, value)); + return this; + } + + public Category getCategory() { + return category; + } + + public List<WhereClause<?>> getWhereClauses() { + return whereClauses; + } + + public int getWhereClausesCount() { + return whereClauses.size(); + } + + public <T> boolean hasWhereClause(Key<T> key, Criteria criteria, T value) { + for (WhereClause<?> whereClause: whereClauses) { + if (whereClause.equals(new WhereClause<T>(key, criteria, value))) { + return true; + } + } + return false; + } + + public boolean hasWhereClauseFor(Key<?> key) { + for (WhereClause<?> where : whereClauses) { + if (where.key.equals(key)) { + return true; + } + } + return false; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (obj == this) { + return true; + } + if (!(obj instanceof MockQuery)) { + return false; + } + MockQuery other = (MockQuery) obj; + return Objects.equals(category, other.category) && Objects.equals(whereClauses, other.whereClauses); + } + + @Override + public int hashCode() { + return Objects.hash(category, whereClauses); + } + +}
--- a/common/core/src/test/java/com/redhat/thermostat/common/dao/CpuStatDAOTest.java Fri Sep 07 17:22:36 2012 +0200 +++ b/common/core/src/test/java/com/redhat/thermostat/common/dao/CpuStatDAOTest.java Fri Sep 07 11:42:51 2012 -0400 @@ -38,9 +38,12 @@ import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.any; +import static org.mockito.Mockito.eq; +import static org.mockito.Mockito.isA; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -58,8 +61,10 @@ import com.redhat.thermostat.common.storage.Chunk; import com.redhat.thermostat.common.storage.Cursor; import com.redhat.thermostat.common.storage.Key; +import com.redhat.thermostat.common.storage.Query; import com.redhat.thermostat.common.storage.Storage; import com.redhat.thermostat.common.utils.ArrayUtils; +import com.redhat.thermostat.test.MockQuery; public class CpuStatDAOTest { @@ -79,6 +84,7 @@ Cursor cursor = mock(Cursor.class); Storage storage = mock(Storage.class); + MockQuery query = new MockQuery(); HostRef hostRef = mock(HostRef.class); CpuStatDAO dao = new CpuStatDAOImpl(storage); @@ -90,14 +96,13 @@ when(cursor.hasNext()).thenReturn(true).thenReturn(false); when(cursor.next()).thenReturn(chunk); - when(storage.findAll(any(Chunk.class))).thenReturn(cursor); + when(storage.createQuery()).thenReturn(query); + when(storage.findAll(query)).thenReturn(cursor); when(hostRef.getAgentId()).thenReturn("system"); List<CpuStat> cpuStats = dao.getLatestCpuStats(hostRef); - ArgumentCaptor<Chunk> arg = ArgumentCaptor.forClass(Chunk.class); - verify(storage).findAll(arg.capture()); - assertNull(arg.getValue().get(new Key<String>("$where", false))); + assertFalse(query.hasWhereClauseFor(Key.TIMESTAMP)); assertEquals(1, cpuStats.size()); CpuStat stat = cpuStats.get(0); @@ -111,6 +116,7 @@ Cursor cursor = mock(Cursor.class); Storage storage = mock(Storage.class); + MockQuery query = new MockQuery(); HostRef hostRef = mock(HostRef.class); CpuStatDAO dao = new CpuStatDAOImpl(storage); @@ -119,18 +125,18 @@ chunk.put(Key.TIMESTAMP, 1234L); chunk.put(CpuStatDAO.cpuLoadKey, Arrays.asList(5.0)); - when(cursor.hasNext()).thenReturn(true).thenReturn(false); when(cursor.next()).thenReturn(chunk); - when(storage.findAll(any(Chunk.class))).thenReturn(cursor); + when(storage.createQuery()).thenReturn(query); + when(storage.findAll(any(Query.class))).thenReturn(cursor); when(hostRef.getAgentId()).thenReturn("system"); dao.getLatestCpuStats(hostRef); dao.getLatestCpuStats(hostRef); - ArgumentCaptor<Chunk> arg = ArgumentCaptor.forClass(Chunk.class); - verify(storage, times(2)).findAll(arg.capture()); - assertEquals("this.timestamp > 1234", arg.getValue().get(Key.WHERE)); + verify(storage, times(2)).findAll(query); + + query.hasWhereClauseFor(Key.TIMESTAMP); } @Test
--- a/common/core/src/test/java/com/redhat/thermostat/common/dao/HeapDAOTest.java Fri Sep 07 17:22:36 2012 +0200 +++ b/common/core/src/test/java/com/redhat/thermostat/common/dao/HeapDAOTest.java Fri Sep 07 11:42:51 2012 -0400 @@ -61,6 +61,8 @@ import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; import com.redhat.thermostat.common.heap.HistogramRecord; import com.redhat.thermostat.common.heap.ObjectHistogram; @@ -69,7 +71,10 @@ import com.redhat.thermostat.common.storage.Chunk; import com.redhat.thermostat.common.storage.Cursor; import com.redhat.thermostat.common.storage.Key; +import com.redhat.thermostat.common.storage.Query; import com.redhat.thermostat.common.storage.Storage; +import com.redhat.thermostat.common.storage.Query.Criteria; +import com.redhat.thermostat.test.MockQuery; import com.sun.tools.hat.internal.model.JavaClass; import com.sun.tools.hat.internal.model.JavaHeapObject; @@ -86,6 +91,13 @@ @Before public void setUp() throws IOException { storage = mock(Storage.class); + when(storage.createQuery()).then(new Answer<Query>() { + @Override + public Query answer(InvocationOnMock invocation) throws Throwable { + return new MockQuery(); + } + }); + dao = new HeapDAOImpl(storage); heapInfo = new HeapInfo(123, 12345); @@ -98,9 +110,11 @@ histogramData = createHistogramData(); // Setup for reading data from DB. - Chunk findAllQuery = new Chunk(HeapDAO.heapInfoCategory, false); - findAllQuery.put(Key.AGENT_ID, "123"); - findAllQuery.put(Key.VM_ID, 234); + MockQuery findAllQuery = new MockQuery() + .from(HeapDAO.heapInfoCategory) + .where(Key.AGENT_ID, Criteria.EQUALS, "123") + .where(Key.VM_ID, Criteria.EQUALS, 234); + Cursor cursor = mock(Cursor.class); Chunk info1 = new Chunk(HeapDAO.heapInfoCategory, false); info1.put(Key.AGENT_ID, "123"); @@ -124,19 +138,24 @@ when(storage.loadFile("test-heap")).thenReturn(new ByteArrayInputStream(data)); when(storage.loadFile("test-histo")).thenReturn(histogramData); + // We dont check for AGENT_ID. That's enforced/added/checked by Storage + // Prepare queries for read-back of _id in putHeapInfo() tests. - Chunk heap1query = new Chunk(HeapDAO.heapInfoCategory, false); - heap1query.put(Key.VM_ID, 123); - heap1query.put(Key.TIMESTAMP, 12345l); - heap1query.put(HeapDAO.heapDumpIdKey, "heapdump-987-123-12345"); - heap1query.put(HeapDAO.histogramIdKey, "histogram-987-123-12345"); + MockQuery heap1query = new MockQuery() + .from(HeapDAO.heapInfoCategory) + .where(Key.VM_ID, Criteria.EQUALS, 123) + .where(Key.TIMESTAMP, Criteria.EQUALS, 12345l) + .where(HeapDAO.heapDumpIdKey, Criteria.EQUALS, "heapdump-987-123-12345") + .where(HeapDAO.histogramIdKey, Criteria.EQUALS, "histogram-987-123-12345"); Chunk heap1 = new Chunk(HeapDAO.heapInfoCategory, false); heap1.put(Key.ID, "id1"); when(storage.find(heap1query)).thenReturn(heap1); - Chunk heap2query = new Chunk(HeapDAO.heapInfoCategory, false); - heap2query.put(Key.VM_ID, 123); - heap2query.put(Key.TIMESTAMP, 12345l); + MockQuery heap2query = new MockQuery() + .from(HeapDAO.heapInfoCategory) + .where(Key.VM_ID, Criteria.EQUALS, 123) + .where(Key.TIMESTAMP, Criteria.EQUALS, 12345l); + Chunk heap2 = new Chunk(HeapDAO.heapInfoCategory, false); heap2.put(Key.ID, "id2"); when(storage.find(heap2query)).thenReturn(heap2); @@ -286,7 +305,8 @@ @Test public void testInvalidHeapId() throws IOException { storage = mock(Storage.class); - when(storage.find(isA(Chunk.class))).thenThrow(new IllegalArgumentException("invalid ObjectId")); + when(storage.createQuery()).thenReturn(new MockQuery()); + when(storage.find(isA(Query.class))).thenThrow(new IllegalArgumentException("invalid ObjectId")); dao = new HeapDAOImpl(storage); heapInfo = dao.getHeapInfo("some-random-heap-id"); assertTrue(heapInfo == null);
--- a/common/core/src/test/java/com/redhat/thermostat/common/dao/HostInfoDAOTest.java Fri Sep 07 17:22:36 2012 +0200 +++ b/common/core/src/test/java/com/redhat/thermostat/common/dao/HostInfoDAOTest.java Fri Sep 07 11:42:51 2012 -0400 @@ -44,6 +44,8 @@ import org.junit.Test; import org.mockito.ArgumentCaptor; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; import static org.mockito.Mockito.any; import static org.mockito.Mockito.mock; @@ -57,7 +59,9 @@ import com.redhat.thermostat.common.storage.Chunk; import com.redhat.thermostat.common.storage.Cursor; import com.redhat.thermostat.common.storage.Key; +import com.redhat.thermostat.common.storage.Query; import com.redhat.thermostat.common.storage.Storage; +import com.redhat.thermostat.test.MockQuery; public class HostInfoDAOTest { @@ -94,7 +98,8 @@ chunk.put(HostInfoDAO.hostMemoryTotalKey, MEMORY_TOTAL); Storage storage = mock(Storage.class); - when(storage.find(any(Chunk.class))).thenReturn(chunk); + when(storage.createQuery()).thenReturn(new MockQuery()); + when(storage.find(any(Query.class))).thenReturn(chunk); HostInfo info = new HostInfoDAOImpl(storage).getHostInfo(new HostRef("some uid", HOST_NAME)); assertNotNull(info); @@ -129,8 +134,14 @@ when(cursor.next()).thenReturn(hostConfig); Storage storage = mock(Storage.class); + when(storage.createQuery()).then(new Answer<Query>() { + @Override + public Query answer(InvocationOnMock invocation) throws Throwable { + return new MockQuery(); + } + }); when(storage.findAllFromCategory(HostInfoDAO.hostInfoCategory)).thenReturn(cursor); - when(storage.findAll(any(Chunk.class))).thenReturn(cursor); + when(storage.findAll(any(Query.class))).thenReturn(cursor); return storage; } @@ -166,8 +177,14 @@ when(cursor.next()).thenReturn(hostConfig1).thenReturn(hostConfig2).thenReturn(hostConfig3); Storage storage = mock(Storage.class); + when(storage.createQuery()).then(new Answer<Query>() { + @Override + public Query answer(InvocationOnMock invocation) throws Throwable { + return new MockQuery(); + } + }); when(storage.findAllFromCategory(HostInfoDAO.hostInfoCategory)).thenReturn(cursor); - when(storage.findAll(any(Chunk.class))).thenReturn(cursor); + when(storage.findAll(any(Query.class))).thenReturn(cursor); return storage; } @@ -211,7 +228,7 @@ // cursor 3 from the above storage should not be used assertEquals(1, hosts.size()); assertTrue(hosts.contains(new HostRef("123", "fluffhost1"))); - verify(storage, times(2)).findAll(any(Chunk.class)); + verify(storage, times(2)).findAll(any(Query.class)); } private Storage setupStorageForSingleAliveHost() { @@ -247,7 +264,13 @@ // storage Storage storage = mock(Storage.class); - when(storage.findAll(any(Chunk.class))).thenReturn(cursor1).thenReturn(cursor2).thenReturn(cursor3); + when(storage.createQuery()).then(new Answer<Query>() { + @Override + public Query answer(InvocationOnMock invocation) throws Throwable { + return new MockQuery(); + } + }); + when(storage.findAll(any(Query.class))).thenReturn(cursor1).thenReturn(cursor2).thenReturn(cursor3); return storage; } @@ -264,7 +287,7 @@ assertTrue(hosts.contains(new HostRef("123", "fluffhost1"))); assertTrue(hosts.contains(new HostRef("456", "fluffhost2"))); assertTrue(hosts.contains(new HostRef("678", "fluffhost3"))); - verify(storage, times(4)).findAll(any(Chunk.class)); + verify(storage, times(4)).findAll(any(Query.class)); } private Storage setupStorageForSingleAliveHost3() { @@ -316,7 +339,13 @@ // storage Storage storage = mock(Storage.class); - when(storage.findAll(any(Chunk.class))).thenReturn(cursor1). + when(storage.createQuery()).then(new Answer<Query>() { + @Override + public Query answer(InvocationOnMock invocation) throws Throwable { + return new MockQuery(); + } + }); + when(storage.findAll(any(Query.class))).thenReturn(cursor1). thenReturn(cursor2). thenReturn(cursor3). thenReturn(cursor4);
--- a/common/core/src/test/java/com/redhat/thermostat/common/dao/HostLatestPojoListGetterTest.java Fri Sep 07 17:22:36 2012 +0200 +++ b/common/core/src/test/java/com/redhat/thermostat/common/dao/HostLatestPojoListGetterTest.java Fri Sep 07 11:42:51 2012 -0400 @@ -49,18 +49,22 @@ import com.redhat.thermostat.common.storage.Chunk; import com.redhat.thermostat.common.storage.Cursor; import com.redhat.thermostat.common.storage.Key; +import com.redhat.thermostat.common.storage.Query; import com.redhat.thermostat.common.storage.Storage; +import com.redhat.thermostat.common.storage.Query.Criteria; +import com.redhat.thermostat.test.MockQuery; import static org.junit.Assert.assertArrayEquals; 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.Mockito.any; +import static org.mockito.Mockito.isA; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import static org.mockito.Mockito.any; public class HostLatestPojoListGetterTest { private static final String AGENT_ID = "agentid"; @@ -111,44 +115,52 @@ @Test public void testBuildQuery() { Storage storage = mock(Storage.class); + MockQuery query = new MockQuery(); + when (storage.createQuery()).thenReturn(query); + HostLatestPojoListGetter<CpuStat> getter = new HostLatestPojoListGetter<>(storage, cat, converter, ref); - Chunk query = getter.buildQuery(); + query = (MockQuery) getter.buildQuery(); assertNotNull(query); assertEquals(cat, query.getCategory()); - assertEquals(1, query.getKeys().size()); - assertTrue(query.getKeys().contains(Key.AGENT_ID)); - assertFalse(query.getKeys().contains(Key.WHERE)); - assertEquals(AGENT_ID, query.get(Key.AGENT_ID)); + assertEquals(1, query.getWhereClausesCount()); + assertFalse(query.hasWhereClauseFor(Key.TIMESTAMP)); + assertTrue(query.hasWhereClause(Key.AGENT_ID, Criteria.EQUALS, AGENT_ID)); } @Test public void testBuildQueryWithSince() { Storage storage = mock(Storage.class); + MockQuery query = new MockQuery(); + when (storage.createQuery()).thenReturn(query); + HostLatestPojoListGetter<CpuStat> getter = new HostLatestPojoListGetter<>(storage, cat, converter, ref, 123); - Chunk query = getter.buildQuery(); + query = (MockQuery) getter.buildQuery(); assertNotNull(query); assertEquals(cat, query.getCategory()); - assertEquals(2, query.getKeys().size()); - assertTrue(query.getKeys().contains(Key.AGENT_ID)); - assertEquals("this.timestamp > 123", query.get(Key.WHERE)); - assertEquals(AGENT_ID, query.get(Key.AGENT_ID)); + assertEquals(2, query.getWhereClausesCount()); + assertTrue(query.hasWhereClause(Key.TIMESTAMP, Criteria.GREATER_THAN, 123l)); + assertTrue(query.hasWhereClause(Key.AGENT_ID, Criteria.EQUALS, AGENT_ID)); } @Test public void testBuildQueryPopulatesUpdateTimes() { Storage storage = mock(Storage.class); + MockQuery ignored = new MockQuery(); + MockQuery query = new MockQuery(); + when(storage.createQuery()).thenReturn(ignored).thenReturn(query); + HostLatestPojoListGetter<CpuStat> getter = new HostLatestPojoListGetter<>(storage, cat, converter, ref); - getter.buildQuery(); // Ignore first return value. - Chunk query = getter.buildQuery(); + ignored = (MockQuery) getter.buildQuery(); // Ignore first return value. + + query = (MockQuery) getter.buildQuery(); assertNotNull(query); assertEquals(cat, query.getCategory()); - assertEquals(2, query.getKeys().size()); - assertTrue(query.getKeys().contains(Key.AGENT_ID)); - assertTrue(query.getKeys().contains(Key.WHERE)); - assertEquals("this.timestamp > " + Long.MIN_VALUE, query.get(Key.WHERE)); + assertEquals(2, query.getWhereClausesCount()); + assertTrue(query.hasWhereClause(Key.AGENT_ID, Criteria.EQUALS, AGENT_ID)); + assertTrue(query.hasWhereClause(Key.TIMESTAMP, Criteria.GREATER_THAN, Long.MIN_VALUE)); } @Test @@ -158,7 +170,9 @@ when(cursor.next()).thenReturn(result1).thenReturn(result2).thenReturn(null); Storage storage = mock(Storage.class); - when(storage.findAll(any(Chunk.class))).thenReturn(cursor); + Query query = new MockQuery(); + when(storage.createQuery()).thenReturn(query); + when(storage.findAll(query)).thenReturn(cursor); HostLatestPojoListGetter<CpuStat> getter = new HostLatestPojoListGetter<>(storage, cat, converter, ref); @@ -185,21 +199,20 @@ when(cursor2.next()).thenReturn(result3); Storage storage = mock(Storage.class); - when(storage.findAll(any(Chunk.class))).thenReturn(cursor1); + MockQuery firstQuery = new MockQuery(); + MockQuery secondQuery = new MockQuery(); + when(storage.createQuery()).thenReturn(firstQuery).thenReturn(secondQuery); + + when(storage.findAll(isA(Query.class))).thenReturn(cursor1); HostLatestPojoListGetter<CpuStat> getter = new HostLatestPojoListGetter<>(storage, cat, converter, ref); getter.getLatest(); getter.getLatest(); - ArgumentCaptor<Chunk> arg = ArgumentCaptor.forClass(Chunk.class); - verify(storage, times(2)).findAll(arg.capture()); - List<Chunk> queries = arg.getAllValues(); + verify(storage, times(2)).findAll(isA(Query.class)); - assertEquals(2, queries.size()); - Chunk query = queries.get(1); - assertNotNull(query); - assertEquals(AGENT_ID, query.get(Key.AGENT_ID)); - assertEquals("this.timestamp > " + t2, query.get(Key.WHERE)); + assertTrue(secondQuery.hasWhereClause(Key.AGENT_ID, Criteria.EQUALS, AGENT_ID)); + assertTrue(secondQuery.hasWhereClause(Key.TIMESTAMP, Criteria.GREATER_THAN, t2)); } @After
--- a/common/core/src/test/java/com/redhat/thermostat/common/dao/MemoryStatDAOTest.java Fri Sep 07 17:22:36 2012 +0200 +++ b/common/core/src/test/java/com/redhat/thermostat/common/dao/MemoryStatDAOTest.java Fri Sep 07 11:42:51 2012 -0400 @@ -37,6 +37,7 @@ package com.redhat.thermostat.common.dao; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; @@ -50,13 +51,18 @@ import org.junit.Test; import org.mockito.ArgumentCaptor; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; import com.redhat.thermostat.common.model.MemoryStat; import com.redhat.thermostat.common.storage.Category; import com.redhat.thermostat.common.storage.Chunk; import com.redhat.thermostat.common.storage.Cursor; import com.redhat.thermostat.common.storage.Key; +import com.redhat.thermostat.common.storage.Query; +import com.redhat.thermostat.common.storage.Query.Criteria; import com.redhat.thermostat.common.storage.Storage; +import com.redhat.thermostat.test.MockQuery; public class MemoryStatDAOTest { @@ -105,7 +111,13 @@ when(cursor.next()).thenReturn(chunk); Storage storage = mock(Storage.class); - when(storage.findAll(any(Chunk.class))).thenReturn(cursor); + when(storage.createQuery()).then(new Answer<Query>() { + @Override + public Query answer(InvocationOnMock invocation) throws Throwable { + return new MockQuery(); + } + }); + when(storage.findAll(any(Query.class))).thenReturn(cursor); HostRef hostRef = mock(HostRef.class); when(hostRef.getAgentId()).thenReturn("system"); @@ -113,9 +125,9 @@ MemoryStatDAO dao = new MemoryStatDAOImpl(storage); List<MemoryStat> memoryStats = dao.getLatestMemoryStats(hostRef); - ArgumentCaptor<Chunk> arg = ArgumentCaptor.forClass(Chunk.class); + ArgumentCaptor<MockQuery> arg = ArgumentCaptor.forClass(MockQuery.class); verify(storage).findAll(arg.capture()); - assertNull(arg.getValue().get(new Key<String>("$where", false))); + assertFalse(arg.getValue().hasWhereClauseFor(Key.TIMESTAMP)); assertEquals(1, memoryStats.size()); MemoryStat stat = memoryStats.get(0); @@ -148,7 +160,13 @@ when(cursor.next()).thenReturn(chunk); Storage storage = mock(Storage.class); - when(storage.findAll(any(Chunk.class))).thenReturn(cursor); + when(storage.createQuery()).then(new Answer<Query>() { + @Override + public Query answer(InvocationOnMock invocation) throws Throwable { + return new MockQuery(); + } + }); + when(storage.findAll(any(Query.class))).thenReturn(cursor); HostRef hostRef = mock(HostRef.class); when(hostRef.getAgentId()).thenReturn("system"); @@ -157,9 +175,9 @@ dao.getLatestMemoryStats(hostRef); dao.getLatestMemoryStats(hostRef); - ArgumentCaptor<Chunk> arg = ArgumentCaptor.forClass(Chunk.class); + ArgumentCaptor<MockQuery> arg = ArgumentCaptor.forClass(MockQuery.class); verify(storage, times(2)).findAll(arg.capture()); - assertEquals("this.timestamp > 1", arg.getValue().get(new Key<String>("$where", false))); + assertTrue(arg.getValue().hasWhereClause(Key.TIMESTAMP, Criteria.GREATER_THAN, 1l)); } @Test
--- a/common/core/src/test/java/com/redhat/thermostat/common/dao/NetworkInterfaceInfoDAOTest.java Fri Sep 07 17:22:36 2012 +0200 +++ b/common/core/src/test/java/com/redhat/thermostat/common/dao/NetworkInterfaceInfoDAOTest.java Fri Sep 07 11:42:51 2012 -0400 @@ -37,6 +37,7 @@ package com.redhat.thermostat.common.dao; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; @@ -56,6 +57,7 @@ import com.redhat.thermostat.common.storage.Cursor; import com.redhat.thermostat.common.storage.Key; import com.redhat.thermostat.common.storage.Storage; +import com.redhat.thermostat.test.MockQuery; public class NetworkInterfaceInfoDAOTest { @@ -90,7 +92,9 @@ when(cursor.next()).thenReturn(chunk); Storage storage = mock(Storage.class); - when(storage.findAll(any(Chunk.class))).thenReturn(cursor); + MockQuery query = new MockQuery(); + when(storage.createQuery()).thenReturn(query); + when(storage.findAll(query)).thenReturn(cursor); HostRef hostRef = mock(HostRef.class); when(hostRef.getAgentId()).thenReturn("system"); @@ -98,9 +102,7 @@ NetworkInterfaceInfoDAO dao = new NetworkInterfaceInfoDAOImpl(storage); List<NetworkInterfaceInfo> netInfo = dao.getNetworkInterfaces(hostRef); - ArgumentCaptor<Chunk> arg = ArgumentCaptor.forClass(Chunk.class); - verify(storage).findAll(arg.capture()); - assertNull(arg.getValue().get(new Key<String>("$where", false))); + assertFalse(query.hasWhereClauseFor(Key.TIMESTAMP)); assertEquals(1, netInfo.size());
--- a/common/core/src/test/java/com/redhat/thermostat/common/dao/VmClassStatDAOTest.java Fri Sep 07 17:22:36 2012 +0200 +++ b/common/core/src/test/java/com/redhat/thermostat/common/dao/VmClassStatDAOTest.java Fri Sep 07 11:42:51 2012 -0400 @@ -37,6 +37,7 @@ package com.redhat.thermostat.common.dao; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.any; @@ -50,12 +51,17 @@ import org.junit.Test; import org.mockito.ArgumentCaptor; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; import com.redhat.thermostat.common.model.VmClassStat; import com.redhat.thermostat.common.storage.Chunk; import com.redhat.thermostat.common.storage.Cursor; import com.redhat.thermostat.common.storage.Key; +import com.redhat.thermostat.common.storage.Query; +import com.redhat.thermostat.common.storage.Query.Criteria; import com.redhat.thermostat.common.storage.Storage; +import com.redhat.thermostat.test.MockQuery; public class VmClassStatDAOTest { @@ -85,7 +91,13 @@ when(cursor.next()).thenReturn(chunk); Storage storage = mock(Storage.class); - when(storage.findAll(any(Chunk.class))).thenReturn(cursor); + when(storage.createQuery()).then(new Answer<Query>() { + @Override + public Query answer(InvocationOnMock invocation) throws Throwable { + return new MockQuery(); + } + }); + when(storage.findAll(any(Query.class))).thenReturn(cursor); HostRef hostRef = mock(HostRef.class); when(hostRef.getAgentId()).thenReturn("system"); @@ -98,9 +110,9 @@ VmClassStatDAO dao = new VmClassStatDAOImpl(storage); List<VmClassStat> vmClassStats = dao.getLatestClassStats(vmRef); - ArgumentCaptor<Chunk> arg = ArgumentCaptor.forClass(Chunk.class); + ArgumentCaptor<MockQuery> arg = ArgumentCaptor.forClass(MockQuery.class); verify(storage).findAll(arg.capture()); - assertNull(arg.getValue().get(new Key<String>("$where", false))); + assertFalse(arg.getValue().hasWhereClauseFor(Key.TIMESTAMP)); assertEquals(1, vmClassStats.size()); VmClassStat stat = vmClassStats.get(0); @@ -119,7 +131,13 @@ when(cursor.next()).thenReturn(chunk); Storage storage = mock(Storage.class); - when(storage.findAll(any(Chunk.class))).thenReturn(cursor); + when(storage.createQuery()).then(new Answer<Query>() { + @Override + public Query answer(InvocationOnMock invocation) throws Throwable { + return new MockQuery(); + } + }); + when(storage.findAll(any(Query.class))).thenReturn(cursor); HostRef hostRef = mock(HostRef.class); when(hostRef.getAgentId()).thenReturn("system"); @@ -133,9 +151,9 @@ dao.getLatestClassStats(vmRef); dao.getLatestClassStats(vmRef); - ArgumentCaptor<Chunk> arg = ArgumentCaptor.forClass(Chunk.class); + ArgumentCaptor<MockQuery> arg = ArgumentCaptor.forClass(MockQuery.class); verify(storage, times(2)).findAll(arg.capture()); - assertEquals("this.timestamp > 1234", arg.getValue().get(new Key<String>("$where", false))); + assertTrue(arg.getValue().hasWhereClause(Key.TIMESTAMP, Criteria.GREATER_THAN, 1234l)); } private Chunk getChunk() { @@ -159,8 +177,8 @@ Chunk chunk = arg.getValue(); assertEquals(VmClassStatDAO.vmClassStatsCategory, chunk.getCategory()); - assertEquals((Long) TIMESTAMP, chunk.get(Key.TIMESTAMP)); - assertEquals((Integer) VM_ID, chunk.get(Key.VM_ID)); - assertEquals((Long) LOADED_CLASSES, chunk.get(VmClassStatDAO.loadedClassesKey)); + assertEquals(TIMESTAMP, chunk.get(Key.TIMESTAMP)); + assertEquals(VM_ID, chunk.get(Key.VM_ID)); + assertEquals(LOADED_CLASSES, chunk.get(VmClassStatDAO.loadedClassesKey)); } }
--- a/common/core/src/test/java/com/redhat/thermostat/common/dao/VmCpuStatDAOTest.java Fri Sep 07 17:22:36 2012 +0200 +++ b/common/core/src/test/java/com/redhat/thermostat/common/dao/VmCpuStatDAOTest.java Fri Sep 07 11:42:51 2012 -0400 @@ -37,6 +37,7 @@ package com.redhat.thermostat.common.dao; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.any; @@ -51,12 +52,17 @@ import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; import com.redhat.thermostat.common.model.VmCpuStat; import com.redhat.thermostat.common.storage.Chunk; import com.redhat.thermostat.common.storage.Cursor; import com.redhat.thermostat.common.storage.Key; +import com.redhat.thermostat.common.storage.Query; import com.redhat.thermostat.common.storage.Storage; +import com.redhat.thermostat.common.storage.Query.Criteria; +import com.redhat.thermostat.test.MockQuery; public class VmCpuStatDAOTest { @@ -95,7 +101,13 @@ when(cursor.next()).thenReturn(chunk); Storage storage = mock(Storage.class); - when(storage.findAll(any(Chunk.class))).thenReturn(cursor); + when(storage.createQuery()).then(new Answer<Query>() { + @Override + public Query answer(InvocationOnMock invocation) throws Throwable { + return new MockQuery(); + } + }); + when(storage.findAll(any(Query.class))).thenReturn(cursor); HostRef hostRef = mock(HostRef.class); when(hostRef.getAgentId()).thenReturn("system"); @@ -108,9 +120,9 @@ VmCpuStatDAO dao = new VmCpuStatDAOImpl(storage); List<VmCpuStat> vmCpuStats = dao.getLatestVmCpuStats(vmRef); - ArgumentCaptor<Chunk> arg = ArgumentCaptor.forClass(Chunk.class); + ArgumentCaptor<MockQuery> arg = ArgumentCaptor.forClass(MockQuery.class); verify(storage).findAll(arg.capture()); - assertNull(arg.getValue().get(new Key<String>("$where", false))); + assertFalse(arg.getValue().hasWhereClauseFor(Key.TIMESTAMP)); assertEquals(1, vmCpuStats.size()); VmCpuStat stat = vmCpuStats.get(0); @@ -127,7 +139,13 @@ when(cursor.next()).thenReturn(chunk); Storage storage = mock(Storage.class); - when(storage.findAll(any(Chunk.class))).thenReturn(cursor); + when(storage.createQuery()).then(new Answer<Query>() { + @Override + public Query answer(InvocationOnMock invocation) throws Throwable { + return new MockQuery(); + } + }); + when(storage.findAll(any(Query.class))).thenReturn(cursor); HostRef hostRef = mock(HostRef.class); when(hostRef.getAgentId()).thenReturn("system"); @@ -140,9 +158,9 @@ dao.getLatestVmCpuStats(vmRef); dao.getLatestVmCpuStats(vmRef); - ArgumentCaptor<Chunk> arg = ArgumentCaptor.forClass(Chunk.class); + ArgumentCaptor<MockQuery> arg = ArgumentCaptor.forClass(MockQuery.class); verify(storage, times(2)).findAll(arg.capture()); - assertEquals("this.timestamp > 1234", arg.getValue().get(new Key<String>("$where", false))); + assertTrue(arg.getValue().hasWhereClause(Key.TIMESTAMP, Criteria.GREATER_THAN, 1234l)); } @Test
--- a/common/core/src/test/java/com/redhat/thermostat/common/dao/VmGcStatDAOTest.java Fri Sep 07 17:22:36 2012 +0200 +++ b/common/core/src/test/java/com/redhat/thermostat/common/dao/VmGcStatDAOTest.java Fri Sep 07 11:42:51 2012 -0400 @@ -37,6 +37,7 @@ package com.redhat.thermostat.common.dao; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.any; @@ -51,12 +52,17 @@ import org.junit.Test; import org.mockito.ArgumentCaptor; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; import com.redhat.thermostat.common.model.VmGcStat; import com.redhat.thermostat.common.storage.Chunk; import com.redhat.thermostat.common.storage.Cursor; import com.redhat.thermostat.common.storage.Key; +import com.redhat.thermostat.common.storage.Query; import com.redhat.thermostat.common.storage.Storage; +import com.redhat.thermostat.common.storage.Query.Criteria; +import com.redhat.thermostat.test.MockQuery; public class VmGcStatDAOTest { @@ -94,7 +100,8 @@ when(cursor.next()).thenReturn(chunk); Storage storage = mock(Storage.class); - when(storage.findAll(any(Chunk.class))).thenReturn(cursor); + when(storage.createQuery()).thenReturn(new MockQuery()); + when(storage.findAll(any(Query.class))).thenReturn(cursor); HostRef hostRef = mock(HostRef.class); when(hostRef.getAgentId()).thenReturn("system"); @@ -107,9 +114,9 @@ VmGcStatDAO dao = new VmGcStatDAOImpl(storage); List<VmGcStat> vmGcStats = dao.getLatestVmGcStats(vmRef); - ArgumentCaptor<Chunk> arg = ArgumentCaptor.forClass(Chunk.class); + ArgumentCaptor<MockQuery> arg = ArgumentCaptor.forClass(MockQuery.class); verify(storage).findAll(arg.capture()); - assertNull(arg.getValue().get(new Key<String>("$where", false))); + assertFalse(arg.getValue().hasWhereClauseFor(Key.TIMESTAMP)); assertEquals(1, vmGcStats.size()); VmGcStat stat = vmGcStats.get(0); @@ -135,7 +142,14 @@ when(cursor.next()).thenReturn(chunk); Storage storage = mock(Storage.class); - when(storage.findAll(any(Chunk.class))).thenReturn(cursor); + + when(storage.createQuery()).then(new Answer<MockQuery>() { + @Override + public MockQuery answer(InvocationOnMock invocation) throws Throwable { + return new MockQuery(); + } + }); + when(storage.findAll(any(Query.class))).thenReturn(cursor); HostRef hostRef = mock(HostRef.class); when(hostRef.getAgentId()).thenReturn("system"); @@ -148,9 +162,10 @@ dao.getLatestVmGcStats(vmRef); dao.getLatestVmGcStats(vmRef); - ArgumentCaptor<Chunk> arg = ArgumentCaptor.forClass(Chunk.class); + ArgumentCaptor<MockQuery> arg = ArgumentCaptor.forClass(MockQuery.class); verify(storage, times(2)).findAll(arg.capture()); - assertEquals("this.timestamp > 456", arg.getValue().get(new Key<String>("$where", false))); + MockQuery query = arg.getValue(); + assertTrue(query.hasWhereClause(Key.TIMESTAMP, Criteria.GREATER_THAN, 456l)); } @Test
--- a/common/core/src/test/java/com/redhat/thermostat/common/dao/VmInfoDAOTest.java Fri Sep 07 17:22:36 2012 +0200 +++ b/common/core/src/test/java/com/redhat/thermostat/common/dao/VmInfoDAOTest.java Fri Sep 07 11:42:51 2012 -0400 @@ -37,8 +37,6 @@ package com.redhat.thermostat.common.dao; import static org.junit.Assert.*; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -50,7 +48,6 @@ import java.util.List; import java.util.Map; -import org.junit.After; import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; @@ -60,7 +57,10 @@ import com.redhat.thermostat.common.storage.Chunk; import com.redhat.thermostat.common.storage.Cursor; import com.redhat.thermostat.common.storage.Key; +import com.redhat.thermostat.common.storage.Query; +import com.redhat.thermostat.common.storage.Query.Criteria; import com.redhat.thermostat.common.storage.Storage; +import com.redhat.thermostat.test.MockQuery; public class VmInfoDAOTest { @@ -78,7 +78,6 @@ private Map<String, String> props; private Map<String, String> env; private List<String> libs; - private VmInfoDAO dao; @Before public void setUp() { @@ -96,13 +95,6 @@ props = new HashMap<>(); env = new HashMap<>(); libs = new ArrayList<>(); - Storage storage = setupStorageForSingleVM(); - dao = new VmInfoDAOImpl(storage); - } - - @After - public void tearDown() { - dao = null; } @Test @@ -148,7 +140,9 @@ chunk.put(VmInfoDAO.librariesKey, libs); Storage storage = mock(Storage.class); - when(storage.find(any(Chunk.class))).thenReturn(chunk); + Query query = new MockQuery(); + when(storage.createQuery()).thenReturn(query); + when(storage.find(query)).thenReturn(chunk); HostRef hostRef = mock(HostRef.class); when(hostRef.getAgentId()).thenReturn("system"); @@ -181,6 +175,8 @@ public void testGetVmInfoUnknownVM() { Storage storage = mock(Storage.class); + Query query = new MockQuery(); + when(storage.createQuery()).thenReturn(query); HostRef hostRef = mock(HostRef.class); when(hostRef.getAgentId()).thenReturn("system"); @@ -199,37 +195,10 @@ } - private Storage setupStorageForSingleVM() { - Chunk query1 = new Chunk(VmInfoDAO.vmInfoCategory, false); - query1.put(Key.AGENT_ID, "123"); - - Chunk query2 = new Chunk(VmInfoDAO.vmInfoCategory, false); - query2.put(Key.AGENT_ID, "456"); - - Chunk vm1 = new Chunk(VmInfoDAO.vmInfoCategory, false); - vm1.put(VmInfoDAO.vmIdKey, 123); - vm1.put(VmInfoDAO.mainClassKey, "mainClass1"); - - Chunk vm2 = new Chunk(VmInfoDAO.vmInfoCategory, false); - vm2.put(VmInfoDAO.vmIdKey, 456); - vm2.put(VmInfoDAO.mainClassKey, "mainClass2"); - - Cursor singleVMCursor = mock(Cursor.class); - when(singleVMCursor.hasNext()).thenReturn(true).thenReturn(false); - when(singleVMCursor.next()).thenReturn(vm1); - - Cursor multiVMsCursor = mock(Cursor.class); - when(multiVMsCursor.hasNext()).thenReturn(true).thenReturn(true).thenReturn(false); - when(multiVMsCursor.next()).thenReturn(vm1).thenReturn(vm2); - - Storage storage = mock(Storage.class); - when(storage.findAll(query1)).thenReturn(singleVMCursor); - when(storage.findAll(query2)).thenReturn(multiVMsCursor); - return storage; - } - @Test public void testSingleVM() { + Storage storage = setupStorageForSingleVM(); + VmInfoDAO dao = new VmInfoDAOImpl(storage); HostRef host = new HostRef("123", "fluffhost"); Collection<VmRef> vms = dao.getVMs(host); @@ -237,8 +206,30 @@ assertCollection(vms, new VmRef(host, 123, "mainClass1")); } + private Storage setupStorageForSingleVM() { + Query expectedQuery = new MockQuery() + .from(VmInfoDAO.vmInfoCategory) + .where(Key.AGENT_ID, Criteria.EQUALS, "123"); + + Chunk vm1 = new Chunk(VmInfoDAO.vmInfoCategory, false); + vm1.put(VmInfoDAO.vmIdKey, 123); + vm1.put(VmInfoDAO.mainClassKey, "mainClass1"); + + Cursor singleVMCursor = mock(Cursor.class); + when(singleVMCursor.hasNext()).thenReturn(true).thenReturn(false); + when(singleVMCursor.next()).thenReturn(vm1); + + Storage storage = mock(Storage.class); + when(storage.createQuery()).thenReturn(new MockQuery()); + when(storage.findAll(expectedQuery)).thenReturn(singleVMCursor); + return storage; + } + @Test public void testMultiVMs() { + Storage storage = setupStorageForMultiVM(); + VmInfoDAO dao = new VmInfoDAOImpl(storage); + HostRef host = new HostRef("456", "fluffhost"); Collection<VmRef> vms = dao.getVMs(host); @@ -246,6 +237,29 @@ assertCollection(vms, new VmRef(host, 123, "mainClass1"), new VmRef(host, 456, "mainClass2")); } + private Storage setupStorageForMultiVM() { + Query expectedQuery = new MockQuery() + .from(VmInfoDAO.vmInfoCategory) + .where(Key.AGENT_ID, Criteria.EQUALS, "456"); + + Chunk vm1 = new Chunk(VmInfoDAO.vmInfoCategory, false); + vm1.put(VmInfoDAO.vmIdKey, 123); + vm1.put(VmInfoDAO.mainClassKey, "mainClass1"); + + Chunk vm2 = new Chunk(VmInfoDAO.vmInfoCategory, false); + vm2.put(VmInfoDAO.vmIdKey, 456); + vm2.put(VmInfoDAO.mainClassKey, "mainClass2"); + + Cursor multiVMsCursor = mock(Cursor.class); + when(multiVMsCursor.hasNext()).thenReturn(true).thenReturn(true).thenReturn(false); + when(multiVMsCursor.next()).thenReturn(vm1).thenReturn(vm2); + + Storage storage = mock(Storage.class); + when(storage.createQuery()).thenReturn(new MockQuery()); + when(storage.findAll(expectedQuery)).thenReturn(multiVMsCursor); + return storage; + } + private void assertCollection(Collection<VmRef> vms, VmRef... expectedVMs) { assertEquals(expectedVMs.length, vms.size()); for (VmRef expectedVM : expectedVMs) {
--- a/common/core/src/test/java/com/redhat/thermostat/common/dao/VmLatestPojoListGetterTest.java Fri Sep 07 17:22:36 2012 +0200 +++ b/common/core/src/test/java/com/redhat/thermostat/common/dao/VmLatestPojoListGetterTest.java Fri Sep 07 11:42:51 2012 -0400 @@ -47,13 +47,17 @@ import com.redhat.thermostat.common.storage.Chunk; import com.redhat.thermostat.common.storage.Cursor; import com.redhat.thermostat.common.storage.Key; +import com.redhat.thermostat.common.storage.Query; +import com.redhat.thermostat.common.storage.Query.Criteria; import com.redhat.thermostat.common.storage.Storage; +import com.redhat.thermostat.test.MockQuery; 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.Mockito.any; +import static org.mockito.Mockito.isA; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -107,49 +111,53 @@ @Test public void testBuildQuery() { Storage storage = mock(Storage.class); + MockQuery query = new MockQuery(); + when(storage.createQuery()).thenReturn(query); + VmLatestPojoListGetter<VmClassStat> getter = new VmLatestPojoListGetter<>(storage, cat, converter, vmRef); - Chunk query = getter.buildQuery(); + query = (MockQuery) getter.buildQuery(); assertNotNull(query); assertEquals(cat, query.getCategory()); - assertEquals(2, query.getKeys().size()); - assertTrue(query.getKeys().contains(Key.AGENT_ID)); - assertTrue(query.getKeys().contains(Key.VM_ID)); - assertFalse(query.getKeys().contains(Key.WHERE)); - assertEquals(AGENT_ID, query.get(Key.AGENT_ID)); - assertEquals((Integer) VM_PID, query.get(Key.VM_ID)); + assertEquals(2, query.getWhereClausesCount()); + assertTrue(query.hasWhereClause(Key.AGENT_ID, Criteria.EQUALS, AGENT_ID)); + assertTrue(query.hasWhereClause(Key.VM_ID, Criteria.EQUALS, VM_PID)); } @Test public void testBuildQueryWithSince() { Storage storage = mock(Storage.class); + MockQuery query = new MockQuery(); + when(storage.createQuery()).thenReturn(query); + VmLatestPojoListGetter<VmClassStat> getter = new VmLatestPojoListGetter<>(storage, cat, converter, vmRef, 123); - Chunk query = getter.buildQuery(); + query = (MockQuery) getter.buildQuery(); assertNotNull(query); assertEquals(cat, query.getCategory()); - assertEquals(3, query.getKeys().size()); - assertTrue(query.getKeys().contains(Key.AGENT_ID)); - assertTrue(query.getKeys().contains(Key.VM_ID)); - assertEquals("this.timestamp > 123" , query.get(Key.WHERE)); - assertEquals(AGENT_ID, query.get(Key.AGENT_ID)); - assertEquals((Integer) VM_PID, query.get(Key.VM_ID)); + assertEquals(3, query.getWhereClausesCount()); + assertTrue(query.hasWhereClause(Key.AGENT_ID, Criteria.EQUALS, AGENT_ID)); + assertTrue(query.hasWhereClause(Key.VM_ID, Criteria.EQUALS, VM_PID)); + assertTrue(query.hasWhereClause(Key.TIMESTAMP, Criteria.GREATER_THAN, 123l)); } @Test public void testBuildQueryPopulatesUpdateTimes() { Storage storage = mock(Storage.class); + MockQuery ignored = new MockQuery(); + MockQuery query = new MockQuery(); + when(storage.createQuery()).thenReturn(ignored).thenReturn(query); + VmLatestPojoListGetter<VmClassStat> getter = new VmLatestPojoListGetter<>(storage, cat, converter, vmRef); getter.buildQuery(); // Ignore first return value. - Chunk query = getter.buildQuery(); + query = (MockQuery) getter.buildQuery(); assertNotNull(query); assertEquals(cat, query.getCategory()); - assertEquals(3, query.getKeys().size()); - assertTrue(query.getKeys().contains(Key.AGENT_ID)); - assertTrue(query.getKeys().contains(Key.VM_ID)); - assertTrue(query.getKeys().contains(Key.WHERE)); - assertEquals("this.timestamp > " + Long.MIN_VALUE, query.get(Key.WHERE)); + assertEquals(3, query.getWhereClausesCount()); + assertTrue(query.hasWhereClauseFor(Key.AGENT_ID)); + assertTrue(query.hasWhereClauseFor(Key.VM_ID)); + assertTrue(query.hasWhereClause(Key.TIMESTAMP, Criteria.GREATER_THAN, Long.MIN_VALUE)); } @Test @@ -159,7 +167,8 @@ when(cursor.next()).thenReturn(result1).thenReturn(result2).thenReturn(null); Storage storage = mock(Storage.class); - when(storage.findAll(any(Chunk.class))).thenReturn(cursor); + when(storage.createQuery()).thenReturn(new MockQuery()); + when(storage.findAll(any(Query.class))).thenReturn(cursor); VmLatestPojoListGetter<VmClassStat> getter = new VmLatestPojoListGetter<>(storage, cat, converter, vmRef); @@ -186,21 +195,20 @@ when(cursor2.next()).thenReturn(result3); Storage storage = mock(Storage.class); - when(storage.findAll(any(Chunk.class))).thenReturn(cursor1); + MockQuery firstQuery = new MockQuery(); + MockQuery secondQuery = new MockQuery(); + when(storage.createQuery()).thenReturn(firstQuery).thenReturn(secondQuery); + + when(storage.findAll(any(Query.class))).thenReturn(cursor1); VmLatestPojoListGetter<VmClassStat> getter = new VmLatestPojoListGetter<>(storage, cat, converter, vmRef); getter.getLatest(); getter.getLatest(); - ArgumentCaptor<Chunk> arg = ArgumentCaptor.forClass(Chunk.class); - verify(storage, times(2)).findAll(arg.capture()); - List<Chunk> queries = arg.getAllValues(); + verify(storage, times(2)).findAll(isA(Query.class)); - assertEquals(2, queries.size()); - Chunk query = queries.get(1); - assertNotNull(query); - assertEquals(AGENT_ID, query.get(Key.AGENT_ID)); - assertEquals((Integer) VM_PID, query.get(Key.VM_ID)); - assertEquals("this.timestamp > " + t2, query.get(Key.WHERE)); + assertTrue(secondQuery.hasWhereClause(Key.AGENT_ID, Criteria.EQUALS, AGENT_ID)); + assertTrue(secondQuery.hasWhereClause(Key.VM_ID, Criteria.EQUALS, VM_PID)); + assertTrue(secondQuery.hasWhereClause(Key.TIMESTAMP, Criteria.GREATER_THAN, t2)); } }
--- a/common/core/src/test/java/com/redhat/thermostat/common/dao/VmMemoryStatDAOTest.java Fri Sep 07 17:22:36 2012 +0200 +++ b/common/core/src/test/java/com/redhat/thermostat/common/dao/VmMemoryStatDAOTest.java Fri Sep 07 11:42:51 2012 -0400 @@ -51,8 +51,6 @@ import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; import com.redhat.thermostat.common.model.VmMemoryStat; import com.redhat.thermostat.common.model.VmMemoryStat.Generation; @@ -60,8 +58,11 @@ import com.redhat.thermostat.common.storage.Chunk; import com.redhat.thermostat.common.storage.Cursor; import com.redhat.thermostat.common.storage.Cursor.SortDirection; +import com.redhat.thermostat.common.storage.Query.Criteria; import com.redhat.thermostat.common.storage.Key; +import com.redhat.thermostat.common.storage.Query; import com.redhat.thermostat.common.storage.Storage; +import com.redhat.thermostat.test.MockQuery; public class VmMemoryStatDAOTest { @@ -71,7 +72,7 @@ private Storage storage; private VmRef vmRef; - private Chunk query; + private MockQuery query; private Cursor cursor; @Before @@ -86,16 +87,12 @@ when(vmRef.getId()).thenReturn(VM_ID); storage = mock(Storage.class); + query = new MockQuery(); + when(storage.createQuery()).thenReturn(query); cursor = mock(Cursor.class); - when(storage.findAll(any(Chunk.class))).thenAnswer(new Answer<Cursor>() { - @Override - public Cursor answer(InvocationOnMock invocation) throws Throwable { - query = (Chunk) invocation.getArguments()[0]; - return cursor; - } + when(storage.findAll(any(Query.class))).thenReturn(cursor); - }); when(cursor.sort(any(Key.class), any(SortDirection.class))).thenReturn(cursor); when(cursor.limit(any(Integer.class))).thenReturn(cursor); when(cursor.hasNext()).thenReturn(false); @@ -162,7 +159,7 @@ verifyQuery(); - assertEquals("this.timestamp > 123", query.get(Key.WHERE)); + assertTrue(query.hasWhereClause(Key.TIMESTAMP, Criteria.GREATER_THAN, 123l)); } private void verifyQuery() { @@ -171,8 +168,8 @@ ArgumentCaptor<SortDirection> sortDirection = ArgumentCaptor.forClass(SortDirection.class); verify(cursor).sort(sortKey.capture(), sortDirection.capture()); - assertEquals(AGENT_ID, query.get(Key.AGENT_ID)); - assertEquals((Integer)VM_ID, query.get(Key.VM_ID)); + assertTrue(query.hasWhereClause(Key.AGENT_ID, Criteria.EQUALS, AGENT_ID)); + assertTrue(query.hasWhereClause(Key.VM_ID, Criteria.EQUALS, VM_ID)); assertTrue(sortKey.getValue().equals(Key.TIMESTAMP)); assertTrue(sortDirection.getValue().equals(SortDirection.DESCENDING)); @@ -184,7 +181,8 @@ when(cursor.next()).thenReturn(null); Storage storage = mock(Storage.class); - when(storage.findAll(any(Chunk.class))).thenReturn(cursor); + when(storage.createQuery()).thenReturn(new MockQuery()); + when(storage.findAll(any(Query.class))).thenReturn(cursor); VmMemoryStatDAO impl = new VmMemoryStatDAOImpl(storage); VmMemoryStat latest = impl.getLatestMemoryStat(vmRef);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/core/src/test/java/com/redhat/thermostat/common/storage/MongoQueryTest.java Fri Sep 07 11:42:51 2012 -0400 @@ -0,0 +1,104 @@ +/* + * Copyright 2012 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 + * <http://www.gnu.org/licenses/>. + * + * 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.storage; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import com.mongodb.BasicDBObject; +import com.mongodb.DBObject; +import com.redhat.thermostat.common.storage.Query.Criteria; + +public class MongoQueryTest { + + @Test + public void testEmptyQuery() { + MongoQuery query = new MongoQuery(); + DBObject mongoQuery = query.getGeneratedQuery(); + assertTrue(mongoQuery.keySet().isEmpty()); + } + + @Test + public void testCollectionName() { + MongoQuery query = new MongoQuery().from(new Category("some-collection")); + assertEquals("some-collection", query.getCollectionName()); + } + + @Test + public void testWhereEquals() { + DBObject generatedQuery = generateSimpleWhereQuery("key", Criteria.EQUALS, "value"); + assertEquals("value", generatedQuery.get("key")); + } + + @Test + public void testWhereNotEquals() { + DBObject generatedQuery = generateSimpleWhereQuery("key", Criteria.NOT_EQUAL_TO, "value"); + assertEquals(new BasicDBObject("$ne", "value"), generatedQuery.get("key")); + } + + @Test + public void testWhereGreaterThan() { + DBObject generatedQuery = generateSimpleWhereQuery("key", Criteria.GREATER_THAN, "value"); + assertEquals(new BasicDBObject("$gt", "value"), generatedQuery.get("key")); + } + + @Test + public void testWhereGreaterThanOrEqualTo() { + DBObject generatedQuery = generateSimpleWhereQuery("key", Criteria.GREATER_THAN_OR_EQUAL_TO, "value"); + assertEquals(new BasicDBObject("$gte", "value"), generatedQuery.get("key")); + } + + @Test + public void testWhereLessThan() { + DBObject generatedQuery = generateSimpleWhereQuery("key", Criteria.LESS_THAN, "value"); + assertEquals(new BasicDBObject("$lt", "value"), generatedQuery.get("key")); + } + + @Test + public void testWhereLessThanOrEqualTo() { + DBObject generatedQuery = generateSimpleWhereQuery("key", Criteria.LESS_THAN_OR_EQUAL_TO, "value"); + assertEquals(new BasicDBObject("$lte", "value"), generatedQuery.get("key")); + } + + private DBObject generateSimpleWhereQuery(String key, Criteria criteria, Object value) { + MongoQuery query = new MongoQuery().where(key, criteria, value); + return query.getGeneratedQuery(); + } + +}
--- a/common/core/src/test/java/com/redhat/thermostat/common/storage/MongoStorageTest.java Fri Sep 07 17:22:36 2012 +0200 +++ b/common/core/src/test/java/com/redhat/thermostat/common/storage/MongoStorageTest.java Fri Sep 07 11:42:51 2012 -0400 @@ -75,6 +75,7 @@ import com.mongodb.gridfs.GridFSDBFile; import com.mongodb.gridfs.GridFSInputFile; import com.redhat.thermostat.common.config.StartupConfiguration; +import com.redhat.thermostat.common.storage.Query.Criteria; @RunWith(PowerMockRunner.class) @PrepareForTest({ DBCollection.class, DB.class, Mongo.class, MongoStorage.class, MongoConnection.class }) @@ -94,7 +95,7 @@ private DB db; private DBCollection testCollection, emptyTestCollection, mockedCollection; - private MongoStorage makeStorage() throws Exception { + private MongoStorage makeStorage() { MongoStorage storage = new MongoStorage(conf); storage.mapCategoryToDBCollection(testCategory, testCollection); storage.mapCategoryToDBCollection(emptyTestCategory, emptyTestCollection); @@ -161,11 +162,25 @@ assertNotNull(connKey); } - @Test + @Test (expected=IllegalArgumentException.class) + public void verifyFindOnlyAcceptsMongoQuery() { + MongoStorage storage = makeStorage(); + Query query = mock(Query.class); + storage.find(query); + } + + @Test (expected=IllegalArgumentException.class) + public void veirfyFindAllOnlyAcceptsMongoQuery() { + MongoStorage storage = makeStorage(); + Query query = mock(Query.class); + storage.findAll(query); + } + + @Test public void verifyFindAllReturnsCursor() throws Exception { PowerMockito.whenNew(Mongo.class).withParameterTypes(MongoURI.class).withArguments(any(MongoURI.class)).thenReturn(m); MongoStorage storage = makeStorage(); - Chunk query = new Chunk(testCategory, false); + Query query = storage.createQuery().from(testCategory); Cursor cursor = storage.findAll(query); assertNotNull(cursor); } @@ -174,8 +189,7 @@ public void verifyFindReturnsChunk() throws Exception { PowerMockito.whenNew(Mongo.class).withParameterTypes(MongoURI.class).withArguments(any(MongoURI.class)).thenReturn(m); MongoStorage storage = makeStorage(); - Chunk query = new Chunk(testCategory, false); - query.put(key1, "test1"); + Query query = storage.createQuery().from(testCategory).where(key1, Criteria.EQUALS, "test1"); Chunk result = storage.find(query); assertNotNull(result); } @@ -184,7 +198,7 @@ public void verifyFindAllCallsDBCollectionFind() throws Exception { PowerMockito.whenNew(Mongo.class).withParameterTypes(MongoURI.class).withArguments(any(MongoURI.class)).thenReturn(m); MongoStorage storage = makeStorage(); - Chunk query = new Chunk(testCategory, false); + Query query = storage.createQuery().from(testCategory); storage.findAll(query); verify(testCollection).find(any(DBObject.class)); } @@ -193,7 +207,7 @@ public void verifyFindCallsDBCollectionFindOne() throws Exception { PowerMockito.whenNew(Mongo.class).withParameterTypes(MongoURI.class).withArguments(any(MongoURI.class)).thenReturn(m); MongoStorage storage = makeStorage(); - Chunk query = new Chunk(testCategory, false); + Query query = storage.createQuery().from(testCategory); storage.find(query); verify(testCollection).findOne(any(DBObject.class)); } @@ -202,60 +216,37 @@ public void verifyFindAllCallsDBCollectionFindWithCorrectQuery() throws Exception { PowerMockito.whenNew(Mongo.class).withParameterTypes(MongoURI.class).withArguments(any(MongoURI.class)).thenReturn(m); MongoStorage storage = makeStorage(); - Chunk query = new Chunk(testCategory, false); - query.put(key1, "test"); + + MongoQuery query = mock(MongoQuery.class); + DBObject generatedQuery = mock(DBObject.class); + when(query.getGeneratedQuery()).thenReturn(generatedQuery); + when(query.getCollectionName()).thenReturn(testCategory.getName()); + when(query.getCategory()).thenReturn(testCategory); + ArgumentCaptor<DBObject> findArg = ArgumentCaptor.forClass(DBObject.class); + storage.findAll(query); - ArgumentCaptor<DBObject> findArg = ArgumentCaptor.forClass(DBObject.class); verify(testCollection).find(findArg.capture()); - - DBObject arg = findArg.getValue(); - assertEquals(1, arg.keySet().size()); - assertTrue(arg.keySet().contains("key1")); - assertEquals("test", arg.get("key1")); + assertSame(generatedQuery, findArg.getValue()); } @Test public void verifyFindCallsDBCollectionFindOneWithCorrectQuery() throws Exception { PowerMockito.whenNew(Mongo.class).withParameterTypes(MongoURI.class).withArguments(any(MongoURI.class)).thenReturn(m); MongoStorage storage = makeStorage(); - Chunk query = new Chunk(testCategory, false); - query.put(key1, "test"); - storage.find(query); + + MongoQuery query = mock(MongoQuery.class); + DBObject generatedQuery = mock(DBObject.class); + when(query.getGeneratedQuery()).thenReturn(generatedQuery); + when(query.getCollectionName()).thenReturn(testCategory.getName()); + when(query.getCategory()).thenReturn(testCategory); ArgumentCaptor<DBObject> findArg = ArgumentCaptor.forClass(DBObject.class); - verify(testCollection).findOne(findArg.capture()); - DBObject arg = findArg.getValue(); - assertEquals(1, arg.keySet().size()); - assertTrue(arg.keySet().contains("key1")); - assertEquals("test", arg.get("key1")); - } - - @Test - public void verifyFindAllWithMultiKeys() throws Exception { - PowerMockito.whenNew(Mongo.class).withParameterTypes(MongoURI.class).withArguments(any(MongoURI.class)).thenReturn(m); - MongoStorage storage = makeStorage(); - storage.findAll(multiKeyQuery); + storage.find(query); - ArgumentCaptor<DBObject> findArg = ArgumentCaptor.forClass(DBObject.class); - verify(testCollection).find(findArg.capture()); - - DBObject arg = findArg.getValue(); - assertArrayEquals(new String[]{ "key5", "key4", "key3", "key2", "key1" }, arg.keySet().toArray()); - } - - @Test - public void verifyFindWithMultiKeys() throws Exception { - PowerMockito.whenNew(Mongo.class).withParameterTypes(MongoURI.class).withArguments(any(MongoURI.class)).thenReturn(m); - MongoStorage storage = makeStorage(); - storage.find(multiKeyQuery); - - ArgumentCaptor<DBObject> findArg = ArgumentCaptor.forClass(DBObject.class); verify(testCollection).findOne(findArg.capture()); - - DBObject arg = findArg.getValue(); - assertArrayEquals(new String[]{ "key5", "key4", "key3", "key2", "key1" }, arg.keySet().toArray()); + assertSame(generatedQuery, findArg.getValue()); } @Test @@ -263,9 +254,8 @@ PowerMockito.whenNew(Mongo.class).withParameterTypes(MongoURI.class).withArguments(any(MongoURI.class)).thenReturn(m); MongoStorage storage = makeStorage(); // TODO find a way to test this that isn't just testing mock and converters - Chunk query = new Chunk(testCategory, false); // Because we mock the DBCollection, the contents of this query don't actually determine the result. - query.put(key5, "test1"); + MongoQuery query = new MongoQuery().from(testCategory); Chunk result = storage.find(query); @@ -280,9 +270,8 @@ PowerMockito.whenNew(Mongo.class).withParameterTypes(MongoURI.class).withArguments(any(MongoURI.class)).thenReturn(m); MongoStorage storage = makeStorage(); // TODO find a way to test this that isn't just testing MongoCursor - Chunk query = new Chunk(testCategory, false); // Because we mock the DBCollection, the contents of this query don't actually determine the result. - query.put(key5, "test1"); + MongoQuery query = new MongoQuery().from(testCategory); Cursor cursor = storage.findAll(query);
--- a/thread/collector/src/main/java/com/redhat/thermostat/thread/dao/impl/ThreadDaoImpl.java Fri Sep 07 17:22:36 2012 +0200 +++ b/thread/collector/src/main/java/com/redhat/thermostat/thread/dao/impl/ThreadDaoImpl.java Fri Sep 07 11:42:51 2012 -0400 @@ -44,6 +44,8 @@ import com.redhat.thermostat.common.storage.Chunk; import com.redhat.thermostat.common.storage.Cursor; import com.redhat.thermostat.common.storage.Key; +import com.redhat.thermostat.common.storage.Query; +import com.redhat.thermostat.common.storage.Query.Criteria; import com.redhat.thermostat.common.storage.Storage; import com.redhat.thermostat.thread.dao.ThreadDao; import com.redhat.thermostat.thread.model.ThreadInfoData; @@ -65,9 +67,10 @@ VMThreadCapabilities caps = null; - Chunk query = new Chunk(THREAD_CAPABILITIES, false); - query.put(Key.VM_ID, vm.getId()); - query.put(Key.AGENT_ID, vm.getAgent().getAgentId()); + Query query = storage.createQuery() + .from(THREAD_CAPABILITIES) + .where(Key.VM_ID, Query.Criteria.EQUALS, vm.getId()) + .where(Key.AGENT_ID, Query.Criteria.EQUALS, vm.getAgent().getAgentId()); Chunk found = storage.find(query); if (found != null) { @@ -106,7 +109,7 @@ public ThreadSummary loadLastestSummary(VmRef ref) { ThreadSummary summary = null; - Chunk query = prepareChunk(THREAD_SUMMARY, false, ref); + Query query = prepareQuery(THREAD_SUMMARY, ref); Cursor cursor = storage.findAll(query).sort(Key.TIMESTAMP, Cursor.SortDirection.DESCENDING).limit(1); if (cursor.hasNext()) { Chunk found = cursor.next(); @@ -124,8 +127,8 @@ List<ThreadSummary> result = new ArrayList<>(); - Chunk query = prepareChunk(THREAD_SUMMARY, false, ref); - query.put(Key.WHERE, "this.timestamp > " + since); + Query query = prepareQuery(THREAD_SUMMARY, ref); + query.where(Key.TIMESTAMP, Criteria.GREATER_THAN, since); Cursor cursor = storage.findAll(query).sort(Key.TIMESTAMP, Cursor.SortDirection.DESCENDING); while (cursor.hasNext()) { @@ -163,8 +166,8 @@ public List<ThreadInfoData> loadThreadInfo(VmRef ref, long since) { List<ThreadInfoData> result = new ArrayList<>(); - Chunk query = prepareChunk(THREAD_INFO, false, ref); - query.put(Key.WHERE, "this.timestamp > " + since); + Query query = prepareQuery(THREAD_INFO, ref) + .where(Key.TIMESTAMP, Criteria.GREATER_THAN, since); Cursor cursor = storage.findAll(query).sort(Key.TIMESTAMP, Cursor.SortDirection.DESCENDING); while (cursor.hasNext()) { @@ -198,6 +201,18 @@ private Chunk prepareChunk(Category category, boolean replace, VmRef vm) { return prepareChunk(category, replace, vm.getIdString(), vm.getAgent().getAgentId()); } + + private Query prepareQuery(Category category, VmRef vm) { + return prepareQuery(category, vm.getIdString(), vm.getAgent().getAgentId()); + } + + private Query prepareQuery(Category category, String vmId, String agentId) { + Query query = storage.createQuery() + .from(category) + .where(Key.AGENT_ID, Query.Criteria.EQUALS, agentId) + .where(Key.VM_ID, Query.Criteria.EQUALS, Integer.valueOf(vmId)); + return query; + } @Override public Storage getStorage() {
--- a/thread/collector/src/test/java/com/redhat/thermostat/thread/dao/impl/ThreadDaoImplTest.java Fri Sep 07 17:22:36 2012 +0200 +++ b/thread/collector/src/test/java/com/redhat/thermostat/thread/dao/impl/ThreadDaoImplTest.java Fri Sep 07 11:42:51 2012 -0400 @@ -51,7 +51,10 @@ import com.redhat.thermostat.common.dao.VmRef; import com.redhat.thermostat.common.storage.Chunk; import com.redhat.thermostat.common.storage.Key; +import com.redhat.thermostat.common.storage.Query; import com.redhat.thermostat.common.storage.Storage; +import com.redhat.thermostat.common.storage.Query.Criteria; +import com.redhat.thermostat.test.MockQuery; import com.redhat.thermostat.thread.dao.ThreadDao; import com.redhat.thermostat.thread.model.VMThreadCapabilities; @@ -71,7 +74,9 @@ @Test public void testLoadVMCapabilities() { + MockQuery query = new MockQuery(); Storage storage = mock(Storage.class); + when(storage.createQuery()).thenReturn(query); VmRef ref = mock(VmRef.class); when(ref.getId()).thenReturn(42); @@ -85,15 +90,13 @@ when(answer.get(ThreadDao.CPU_TIME_KEY)).thenReturn(true); when(answer.get(ThreadDao.THREAD_ALLOCATED_MEMORY_KEY)).thenReturn(true); - ArgumentCaptor<Chunk> queryCaptor = ArgumentCaptor.forClass(Chunk.class); - when(storage.find(queryCaptor.capture())).thenReturn(answer); + when(storage.find(query)).thenReturn(answer); ThreadDaoImpl dao = new ThreadDaoImpl(storage); VMThreadCapabilities caps = dao.loadCapabilities(ref); - Chunk query = queryCaptor.getValue(); - assertEquals(42, (int) query.get(Key.VM_ID)); - assertEquals("0xcafe", query.get(Key.AGENT_ID)); + assertTrue(query.hasWhereClause(Key.VM_ID, Criteria.EQUALS, 42)); + assertTrue(query.hasWhereClause(Key.AGENT_ID, Criteria.EQUALS, "0xcafe")); assertFalse(caps.supportContentionMonitor()); assertTrue(caps.supportCPUTime());