Mercurial > hg > release > thermostat-1.4
changeset 1708:4cf9650b8bb1
Merge.
author | Jon VanAlten <jon.vanalten@redhat.com> |
---|---|
date | Tue, 23 Jun 2015 09:57:32 -0600 |
parents | 911fc6601c4d (current diff) 512f81ecb539 (diff) |
children | 0f4eb944e00b |
files | common/pom.xml dev/perflog-analyzer/pom.xml distribution/config/commands/add-mongodb-user.properties pom.xml storage/mongo/src/main/java/com/redhat/thermostat/storage/mongodb/internal/AddUserCommand.java storage/mongo/src/main/java/com/redhat/thermostat/storage/mongodb/internal/AddUserCommandDispatcher.java storage/mongo/src/main/java/com/redhat/thermostat/storage/mongodb/internal/BaseAddUserCommand.java storage/mongo/src/main/java/com/redhat/thermostat/storage/mongodb/internal/StartStopAddUserCommandDecorator.java storage/mongo/src/test/java/com/redhat/thermostat/storage/mongodb/internal/AddUserCommandDispatcherTest.java storage/mongo/src/test/java/com/redhat/thermostat/storage/mongodb/internal/AddUserCommandTest.java storage/mongo/src/test/java/com/redhat/thermostat/storage/mongodb/internal/BaseAddUserCommandTest.java vm-profiler/jvm-agent/pom.xml |
diffstat | 74 files changed, 839 insertions(+), 1277 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/annotations/src/main/java/com/redhat/thermostat/annotations/internal/CacioTest.java Tue Jun 23 09:57:32 2015 -0600 @@ -0,0 +1,44 @@ +/* + * Copyright 2012-2015 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.annotations.internal; + +/** + * Temporary workaround for PR2282: Caciocavallo tests fail with JDK 8 u40 + * Use this annotation on test classes to exclude them from being run by the maven-surefire-plugin + */ +public interface CacioTest { +}
--- a/client/living-vm-filter/swing/src/test/java/com/redhat/thermostat/client/filter/host/swing/DeadHostIconDecoratorTest.java Thu Jun 04 00:38:59 2015 -0500 +++ b/client/living-vm-filter/swing/src/test/java/com/redhat/thermostat/client/filter/host/swing/DeadHostIconDecoratorTest.java Tue Jun 23 09:57:32 2015 -0600 @@ -43,13 +43,16 @@ import org.junit.Before; import org.junit.Test; +import org.junit.experimental.categories.Category; +import com.redhat.thermostat.annotations.internal.CacioTest; import com.redhat.thermostat.client.swing.UIDefaults; import com.redhat.thermostat.client.ui.PlatformIcon; import com.redhat.thermostat.storage.core.HostRef; import com.redhat.thermostat.storage.core.VmRef; import com.redhat.thermostat.storage.dao.HostInfoDAO; +@Category(CacioTest.class) public class DeadHostIconDecoratorTest { private DeadHostIconDecorator decorator;
--- a/client/living-vm-filter/swing/src/test/java/com/redhat/thermostat/client/filter/host/swing/HostIconDecoratorTest.java Thu Jun 04 00:38:59 2015 -0500 +++ b/client/living-vm-filter/swing/src/test/java/com/redhat/thermostat/client/filter/host/swing/HostIconDecoratorTest.java Tue Jun 23 09:57:32 2015 -0600 @@ -45,12 +45,15 @@ import org.junit.Before; import org.junit.Test; +import org.junit.experimental.categories.Category; +import com.redhat.thermostat.annotations.internal.CacioTest; import com.redhat.thermostat.client.swing.UIDefaults; import com.redhat.thermostat.client.ui.PlatformIcon; import com.redhat.thermostat.storage.core.HostRef; import com.redhat.thermostat.storage.core.VmRef; +@Category(CacioTest.class) public class HostIconDecoratorTest { private HostIconDecorator decorator;
--- a/client/living-vm-filter/swing/src/test/java/com/redhat/thermostat/client/filter/vm/swing/VMFilterActivatorTest.java Thu Jun 04 00:38:59 2015 -0500 +++ b/client/living-vm-filter/swing/src/test/java/com/redhat/thermostat/client/filter/vm/swing/VMFilterActivatorTest.java Tue Jun 23 09:57:32 2015 -0600 @@ -41,9 +41,10 @@ import static org.mockito.Mockito.when; import org.junit.Test; +import org.junit.experimental.categories.Category; +import com.redhat.thermostat.annotations.internal.CacioTest; import com.redhat.thermostat.client.filter.host.swing.DeadHostIconDecorator; -import com.redhat.thermostat.client.filter.host.swing.HostIconDecorator; import com.redhat.thermostat.client.filter.host.swing.HostInfoLabelDecorator; import com.redhat.thermostat.client.swing.UIDefaults; import com.redhat.thermostat.client.ui.ReferenceFieldIconDecorator; @@ -53,6 +54,7 @@ import com.redhat.thermostat.storage.dao.VmInfoDAO; import com.redhat.thermostat.testutils.StubBundleContext; +@Category(CacioTest.class) public class VMFilterActivatorTest { @Test
--- a/client/swing/src/test/java/com/redhat/thermostat/client/swing/MenuHelperTest.java Thu Jun 04 00:38:59 2015 -0500 +++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/MenuHelperTest.java Tue Jun 23 09:57:32 2015 -0600 @@ -63,9 +63,11 @@ import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; +import com.redhat.thermostat.annotations.internal.CacioTest; import com.redhat.thermostat.client.ui.MenuAction; import com.redhat.thermostat.shared.locale.LocalizedString; +@Category(CacioTest.class) @RunWith(CacioFESTRunner.class) public class MenuHelperTest {
--- a/client/swing/src/test/java/com/redhat/thermostat/client/swing/components/ActionButtonTest.java Thu Jun 04 00:38:59 2015 -0500 +++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/components/ActionButtonTest.java Tue Jun 23 09:57:32 2015 -0600 @@ -57,10 +57,13 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; +import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; +import com.redhat.thermostat.annotations.internal.CacioTest; import com.redhat.thermostat.shared.locale.LocalizedString; +@Category(CacioTest.class) @RunWith(CacioFESTRunner.class) public class ActionButtonTest {
--- a/client/swing/src/test/java/com/redhat/thermostat/client/swing/components/FontAwesomeIconTest.java Thu Jun 04 00:38:59 2015 -0500 +++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/components/FontAwesomeIconTest.java Tue Jun 23 09:57:32 2015 -0600 @@ -43,7 +43,11 @@ import java.awt.image.BufferedImage; import org.junit.Test; +import org.junit.experimental.categories.Category; +import com.redhat.thermostat.annotations.internal.CacioTest; + +@Category(CacioTest.class) public class FontAwesomeIconTest { @Test
--- a/client/swing/src/test/java/com/redhat/thermostat/client/swing/components/HeaderPanelTest.java Thu Jun 04 00:38:59 2015 -0500 +++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/components/HeaderPanelTest.java Tue Jun 23 09:57:32 2015 -0600 @@ -57,14 +57,17 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; +import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; +import com.redhat.thermostat.annotations.internal.CacioTest; import com.redhat.thermostat.shared.locale.LocalizedString; import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertEquals; +@Category(CacioTest.class) @RunWith(CacioFESTRunner.class) public class HeaderPanelTest {
--- a/client/swing/src/test/java/com/redhat/thermostat/client/swing/components/RecentTimeSeriesChartPanelTest.java Thu Jun 04 00:38:59 2015 -0500 +++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/components/RecentTimeSeriesChartPanelTest.java Tue Jun 23 09:57:32 2015 -0600 @@ -41,6 +41,7 @@ import java.util.concurrent.TimeUnit; import javax.swing.JFrame; +import com.redhat.thermostat.annotations.internal.CacioTest; import com.redhat.thermostat.client.ui.RecentTimeSeriesChartController; import net.java.openjdk.cacio.ctc.junit.CacioFESTRunner; import org.fest.swing.annotation.GUITest; @@ -55,8 +56,10 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; +import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; +@Category(CacioTest.class) @RunWith(CacioFESTRunner.class) public class RecentTimeSeriesChartPanelTest {
--- a/client/swing/src/test/java/com/redhat/thermostat/client/swing/components/SearchFieldTest.java Thu Jun 04 00:38:59 2015 -0500 +++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/components/SearchFieldTest.java Tue Jun 23 09:57:32 2015 -0600 @@ -62,11 +62,12 @@ import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; -import com.redhat.thermostat.client.swing.components.SearchField; +import com.redhat.thermostat.annotations.internal.CacioTest; import com.redhat.thermostat.common.ActionEvent; import com.redhat.thermostat.common.ActionListener; import com.redhat.thermostat.shared.locale.LocalizedString; +@Category(CacioTest.class) @RunWith(CacioFESTRunner.class) public class SearchFieldTest {
--- a/client/swing/src/test/java/com/redhat/thermostat/client/swing/components/experimental/RecentTimeControlPanelTest.java Thu Jun 04 00:38:59 2015 -0500 +++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/components/experimental/RecentTimeControlPanelTest.java Tue Jun 23 09:57:32 2015 -0600 @@ -46,6 +46,7 @@ import javax.swing.JFrame; import javax.swing.JComboBox; +import com.redhat.thermostat.annotations.internal.CacioTest; import com.redhat.thermostat.client.core.experimental.Duration; import net.java.openjdk.cacio.ctc.junit.CacioFESTRunner; import org.fest.swing.annotation.GUITest; @@ -58,8 +59,10 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; +import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; +@Category(CacioTest.class) @RunWith(CacioFESTRunner.class) public class RecentTimeControlPanelTest {
--- a/client/swing/src/test/java/com/redhat/thermostat/client/swing/components/experimental/SingleValueChartPanelTest.java Thu Jun 04 00:38:59 2015 -0500 +++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/components/experimental/SingleValueChartPanelTest.java Tue Jun 23 09:57:32 2015 -0600 @@ -44,6 +44,7 @@ import java.util.concurrent.TimeUnit; import javax.swing.JFrame; +import com.redhat.thermostat.annotations.internal.CacioTest; import com.redhat.thermostat.client.core.experimental.Duration; import net.java.openjdk.cacio.ctc.junit.CacioFESTRunner; import org.fest.swing.annotation.GUITest; @@ -58,8 +59,10 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; +import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; +@Category(CacioTest.class) @RunWith(CacioFESTRunner.class) public class SingleValueChartPanelTest {
--- a/client/swing/src/test/java/com/redhat/thermostat/client/swing/components/models/NullSelectionModelTest.java Thu Jun 04 00:38:59 2015 -0500 +++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/components/models/NullSelectionModelTest.java Tue Jun 23 09:57:32 2015 -0600 @@ -53,8 +53,12 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; +import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; +import com.redhat.thermostat.annotations.internal.CacioTest; + +@Category(CacioTest.class) @RunWith(CacioFESTRunner.class) public class NullSelectionModelTest {
--- a/client/swing/src/test/java/com/redhat/thermostat/client/swing/experimental/ComponentVisibilityNotifierTest.java Thu Jun 04 00:38:59 2015 -0500 +++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/experimental/ComponentVisibilityNotifierTest.java Tue Jun 23 09:57:32 2015 -0600 @@ -55,13 +55,13 @@ import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; +import com.redhat.thermostat.annotations.internal.CacioTest; import com.redhat.thermostat.client.core.views.BasicView; import com.redhat.thermostat.client.core.views.BasicView.Action; -import com.redhat.thermostat.client.swing.experimental.ComponentVisibilityNotifier; import com.redhat.thermostat.common.ActionNotifier; @GUITest -@Category(GUITest.class) +@Category(CacioTest.class) @RunWith(CacioFESTRunner.class) public class ComponentVisibilityNotifierTest {
--- a/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/MainWindowTest.java Thu Jun 04 00:38:59 2015 -0500 +++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/MainWindowTest.java Tue Jun 23 09:57:32 2015 -0600 @@ -61,12 +61,14 @@ import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; +import com.redhat.thermostat.annotations.internal.CacioTest; import com.redhat.thermostat.client.core.views.BasicView; import com.redhat.thermostat.client.ui.MenuAction; import com.redhat.thermostat.common.ActionEvent; import com.redhat.thermostat.common.ActionListener; import com.redhat.thermostat.shared.locale.LocalizedString; +@Category(CacioTest.class) @RunWith(CacioFESTRunner.class) public class MainWindowTest {
--- a/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/StatusBarTest.java Thu Jun 04 00:38:59 2015 -0500 +++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/StatusBarTest.java Tue Jun 23 09:57:32 2015 -0600 @@ -58,10 +58,13 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; +import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; +import com.redhat.thermostat.annotations.internal.CacioTest; import com.redhat.thermostat.shared.locale.LocalizedString; +@Category(CacioTest.class) @RunWith(CacioFESTRunner.class) public class StatusBarTest {
--- a/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/accordion/AccordionTest.java Thu Jun 04 00:38:59 2015 -0500 +++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/accordion/AccordionTest.java Tue Jun 23 09:57:32 2015 -0600 @@ -67,8 +67,10 @@ import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; +import com.redhat.thermostat.annotations.internal.CacioTest; import com.redhat.thermostat.client.swing.components.EmptyIcon; +@Category(CacioTest.class) @RunWith(CacioFESTRunner.class) public class AccordionTest {
--- a/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/accordion/TitledPaneTest.java Thu Jun 04 00:38:59 2015 -0500 +++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/accordion/TitledPaneTest.java Tue Jun 23 09:57:32 2015 -0600 @@ -57,10 +57,13 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; +import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; +import com.redhat.thermostat.annotations.internal.CacioTest; import com.redhat.thermostat.client.swing.components.VerticalLayout; +@Category(CacioTest.class) @RunWith(CacioFESTRunner.class) public class TitledPaneTest {
--- a/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/views/AgentInformationDisplayFrameTest.java Thu Jun 04 00:38:59 2015 -0500 +++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/views/AgentInformationDisplayFrameTest.java Tue Jun 23 09:57:32 2015 -0600 @@ -66,12 +66,13 @@ import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; +import com.redhat.thermostat.annotations.internal.CacioTest; import com.redhat.thermostat.client.core.views.AgentInformationDisplayView; import com.redhat.thermostat.client.core.views.AgentInformationDisplayView.ConfigurationAction; -import com.redhat.thermostat.client.swing.internal.views.AgentInformationDisplayFrame; import com.redhat.thermostat.common.ActionEvent; import com.redhat.thermostat.common.ActionListener; +@Category(CacioTest.class) @RunWith(CacioFESTRunner.class) public class AgentInformationDisplayFrameTest {
--- a/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/views/ClientConfigurationSwingTest.java Thu Jun 04 00:38:59 2015 -0500 +++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/views/ClientConfigurationSwingTest.java Tue Jun 23 09:57:32 2015 -0600 @@ -62,12 +62,13 @@ import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; +import com.redhat.thermostat.annotations.internal.CacioTest; import com.redhat.thermostat.client.core.views.ClientConfigurationView; -import com.redhat.thermostat.client.swing.internal.views.ClientConfigurationSwing; import com.redhat.thermostat.common.ActionEvent; import com.redhat.thermostat.common.ActionListener; import com.redhat.thermostat.test.Bug; +@Category(CacioTest.class) @RunWith(CacioFESTRunner.class) public class ClientConfigurationSwingTest {
--- a/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/views/HostInformationPanelTest.java Thu Jun 04 00:38:59 2015 -0500 +++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/views/HostInformationPanelTest.java Tue Jun 23 09:57:32 2015 -0600 @@ -48,13 +48,16 @@ import org.fest.swing.edt.GuiActionRunner; import org.fest.swing.edt.GuiQuery; import org.junit.Test; +import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; +import com.redhat.thermostat.annotations.internal.CacioTest; import com.redhat.thermostat.client.core.views.UIComponent; import com.redhat.thermostat.client.swing.FrameWithPanelTest; import com.redhat.thermostat.client.swing.TabbedPaneMatcher; import com.redhat.thermostat.shared.locale.LocalizedString; +@Category(CacioTest.class) @RunWith(CacioFESTRunner.class) public class HostInformationPanelTest extends FrameWithPanelTest<HostInformationPanel> {
--- a/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/views/VmInformationPanelTest.java Thu Jun 04 00:38:59 2015 -0500 +++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/views/VmInformationPanelTest.java Tue Jun 23 09:57:32 2015 -0600 @@ -43,12 +43,15 @@ import org.fest.swing.edt.GuiActionRunner; import org.fest.swing.edt.GuiQuery; import org.junit.Test; +import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; +import com.redhat.thermostat.annotations.internal.CacioTest; import com.redhat.thermostat.client.core.views.UIComponent; import com.redhat.thermostat.client.swing.FrameWithPanelTest; import com.redhat.thermostat.shared.locale.LocalizedString; +@Category(CacioTest.class) @RunWith(CacioFESTRunner.class) public class VmInformationPanelTest extends FrameWithPanelTest<VmInformationPanel> {
--- a/common/pom.xml Thu Jun 04 00:38:59 2015 -0500 +++ b/common/pom.xml Tue Jun 23 09:57:32 2015 -0600 @@ -56,6 +56,12 @@ <artifactId>junit</artifactId> <scope>test</scope> </dependency> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-annotations</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> </dependencies> <modules>
--- a/dev/perflog-analyzer/pom.xml Thu Jun 04 00:38:59 2015 -0500 +++ b/dev/perflog-analyzer/pom.xml Tue Jun 23 09:57:32 2015 -0600 @@ -62,6 +62,13 @@ <artifactId>mockito-core</artifactId> <scope>test</scope> </dependency> + + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-annotations</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> </dependencies> <build>
--- a/distribution/config/commands/add-mongodb-user.properties Thu Jun 04 00:38:59 2015 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,25 +0,0 @@ -bundles = com.redhat.thermostat.storage.mongodb=${project.version}, \ - org.mongodb.mongo-java-driver=${mongo-driver.osgi-version}, \ - org.apache.commons.beanutils=${commons-beanutils.version}, \ - org.apache.commons.codec=${commons-codec.osgi-version}, \ - org.apache.commons.collections=${commons-collections.version}, \ - org.apache.commons.logging=${commons-logging.version} - -summary = add a new mongodb user to the thermostat DB - -description = Add a new mongodb user to the thermostat DB, reading credentials \ - from standard input. - -usage = add-mongodb-user -d <dbUrl> |\ - add-mongodb-user -s - -options = AUTO_LOG_OPTION, AUTO_DB_OPTIONS, startStorage - -startStorage.short = s -startStorage.long = startStorage -startStorage.description = start storage with appropriate options before \ - running the command and stop the storage when the command finishes -startStorage.required = false -startStorage.hasarg = false - -environments = cli
--- a/distribution/scripts/thermostat-devsetup Thu Jun 04 00:38:59 2015 -0500 +++ b/distribution/scripts/thermostat-devsetup Tue Jun 23 09:57:32 2015 -0600 @@ -54,10 +54,11 @@ # Call the setup script $THERMOSTAT_SETUP < $DEV_INPUT +retval=$? -if [ $? -ne 0 ]; then +if [ $retval -ne 0 ]; then echo "Development setup failed." 1>&2 - exit $? + exit $retval fi # Copy the agent.auth file into USER_THERMOSTAT_HOME
--- a/distribution/scripts/thermostat-setup Thu Jun 04 00:38:59 2015 -0500 +++ b/distribution/scripts/thermostat-setup Tue Jun 23 09:57:32 2015 -0600 @@ -270,15 +270,43 @@ echo -e "connections.\n" readUsername "$defaultName" readPassword - setupCmdName="add-mongodb-user -s" - output="$(echo -e $USERNAME\\n$PASSWORD\\n | $THERMOSTAT $setupCmdName 2>&1)" - # The above should have created the mongodb stamp file - monogdbSetupStampFile="$USER_THERMOSTAT_HOME/data/mongodb-user-done.stamp" - if [ ! -e "$monogdbSetupStampFile" ] || - ! echo $output | grep -s "setup complete" > /dev/null; then + $THERMOSTAT_HOME/bin/thermostat storage --start --permitLocalhostException + MONGOD_RETVAL="$?" + if [ "$MONGOD_RETVAL" -ne 0 ] ; then + echo -e "\nMongodb user setup failed. Error starting storage." 1>&2 + exitFail + fi + sleep 3 + mongo 127.0.0.1:27518 << EOF +use thermostat +var v = db.version(); +var minorMicro = v.substr(v.indexOf('.') + 1) +var minorVersion = minorMicro.substr(0, minorMicro.indexOf('.')) +if ( minorVersion <= 2 ) { + // mongodb version 2.2 and below don't have the third argument. + // this should create the user as read + write. + db.addUser("$USERNAME","$PASSWORD") +} else { + if ( minorVersion <= 4 ) { + db.addUser({ user: "$USERNAME", pwd: "$PASSWORD", roles: [ "readWrite" ] }) + } else { + db.createUser({ user: "$USERNAME", pwd: "$PASSWORD", roles: [ "readWrite" ] }) + } +} +quit() +EOF + MONGO_SETUP_RETVAL="$?" + if [ "$MONGO_SETUP_RETVAL" -ne 0 ] ; then echo -e "\nMongodb user setup failed." 1>&2 exitFail fi + $THERMOSTAT_HOME/bin/thermostat storage --stop + MONGO_SETUP_RETVAL="$?" + if [ "$MONGO_SETUP_RETVAL" -ne 0 ] ; then + echo -e "\nMongodb user setup failed." 1>&2 + exitFail + fi + touch "$USER_THERMOSTAT_HOME"/data/mongodb-user-done.stamp } doProceedLoop() {
--- a/distribution/tools/verify-archetype-functions.sh Thu Jun 04 00:38:59 2015 -0500 +++ b/distribution/tools/verify-archetype-functions.sh Tue Jun 23 09:57:32 2015 -0600 @@ -77,7 +77,7 @@ if [ "x$KEEPTEMP" != "x--keepTemp" ]; then cleanup_tempdirs $TMP_DIR \ $PLUGIN_INSTALL_LOCATION \ - $THERMOSTAT_HOME/webapp/WEB-INF/lib/"$ARTIFACT_ID"-storage-common-0.0.1-SNAPSHOT.jar + $THERMOSTAT_HOME/webapp/WEB-INF/lib/"$ARTIFACT_ID"-storage-common*.jar fi } @@ -96,13 +96,32 @@ } function exit_if_bad_return_value() { - RVAL=$1 - if [ $RVAL -ne 0 ]; then + local rval="" + local debugFile="" + local errorMsg="" + + # Check if we got passed a third argument which is a file with + # details about the failure that happened. + if [ $# -eq 3 ]; then + rval=$1 + debugFile=$2 + errorMsg=$3 + else + rval=$1 + debugFile="" + errorMsg=$2 + fi + + if [ $rval -ne 0 ]; then + # Only print debug info if we actually have one + if [ "_$debugFile" != "_" ]; then + echo "------------------- Debug info start ---------------------" + cat "$debugFile" + echo "------------------- Debug info end ---------------------" + fi cleanup - shift - echo $@ + echo "$errorMsg" output_fail_information - exit $RVAL + exit $rval fi } -
--- a/distribution/tools/verify-archetype-multimodule.sh Thu Jun 04 00:38:59 2015 -0500 +++ b/distribution/tools/verify-archetype-multimodule.sh Tue Jun 23 09:57:32 2015 -0600 @@ -53,6 +53,8 @@ WSS_PID="$TMP_DIR/web-storage-service.pid" WSS_OUTPUT="$TMP_DIR/wss_output.txt" +EXAMPLE_CMD_OUTPUT="$TMP_DIR/example_cmd_output.txt" + function launch_and_wait_for_web_storage() { $THERMOSTAT_EXE -Tbg $WSS_PID web-storage-service > $WSS_OUTPUT 2>&1 @@ -124,7 +126,7 @@ exit_if_bad_return_value $? "Error configuring Thermostat (devsetup)" launch_and_wait_for_web_storage -exit_if_bad_return_value $? "Web Storage Service not coming up" +exit_if_bad_return_value $? "$WSS_OUTPUT" "Web Storage Service not coming up" # Why head -n4? Output looks like the following: # @@ -142,8 +144,10 @@ exit_if_bad_return_value $? "Plugin command not appearing in Thermostat help" # verify "example-command" works as expected -echo -e "client-tester\ntester" | $THERMOSTAT_EXE example-command -a $AGENT_ID | grep 'Message: Hello World!' -exit_if_bad_return_value $? "Plugin command not working" +example_cmd="echo -e \"client-tester\ntester\" | $THERMOSTAT_EXE example-command -a $AGENT_ID | grep 'Message: Hello World!'" +echo $example_cmd >> $EXAMPLE_CMD_OUTPUT 2>&1 +$example_cmd >> $EXAMPLE_CMD_OUTPUT 2>&1 +exit_if_bad_return_value $? "$EXAMPLE_CMD_OUTPUT" "Plugin command not working" kill_and_wait_for_webstorage
--- a/host-memory/client-swing/src/main/java/com/redhat/thermostat/host/memory/client/swing/internal/HostMemoryPanel.java Thu Jun 04 00:38:59 2015 -0500 +++ b/host-memory/client-swing/src/main/java/com/redhat/thermostat/host/memory/client/swing/internal/HostMemoryPanel.java Tue Jun 23 09:57:32 2015 -0600 @@ -58,6 +58,7 @@ import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.NumberAxis; import org.jfree.chart.renderer.xy.XYItemRenderer; +import org.jfree.data.RangeType; import org.jfree.data.time.FixedMillisecond; import org.jfree.data.time.RegularTimePeriod; import org.jfree.data.time.TimeSeries; @@ -315,6 +316,7 @@ NumberAxis rangeAxis = (NumberAxis) chart.getXYPlot().getRangeAxis(); rangeAxis.setAutoRangeMinimumSize(100); + rangeAxis.setRangeType(RangeType.POSITIVE); return chart; }
--- a/integration-tests/itest-run/src/test/java/com/redhat/thermostat/itest/IntegrationTest.java Thu Jun 04 00:38:59 2015 -0500 +++ b/integration-tests/itest-run/src/test/java/com/redhat/thermostat/itest/IntegrationTest.java Tue Jun 23 09:57:32 2015 -0600 @@ -146,6 +146,21 @@ } } + protected static void createFakeUserSetupDoneFile() { + String userHome = getUserThermostatHome(); + File fUserHome = new File(userHome); + fUserHome.mkdir(); + File dataDir = new File(fUserHome, "data"); + dataDir.mkdir(); + + File mongodbUserDoneFile = new File(dataDir, "mongodb-user-done.stamp"); + try { + // creates the file only if not yet existing + mongodbUserDoneFile.createNewFile(); + } catch (IOException e) { + throw new RuntimeException(e.getMessage(), e); + } + } /** * Utility method for removing stamp files which may get created by certain @@ -245,8 +260,6 @@ } public static Spawn startStorage() throws Exception { - clearStorageDataDirectory(); - Spawn storage = spawnThermostat("storage", "--start", "--permitLocalhostException"); try { storage.expect("pid:");
--- a/integration-tests/itest-run/src/test/java/com/redhat/thermostat/itest/MongoQueriesTest.java Thu Jun 04 00:38:59 2015 -0500 +++ b/integration-tests/itest-run/src/test/java/com/redhat/thermostat/itest/MongoQueriesTest.java Tue Jun 23 09:57:32 2015 -0600 @@ -68,9 +68,9 @@ import com.redhat.thermostat.storage.core.Cursor; import com.redhat.thermostat.storage.core.Key; import com.redhat.thermostat.storage.core.Query; -import com.redhat.thermostat.storage.core.StorageCredentials; import com.redhat.thermostat.storage.core.Query.SortDirection; import com.redhat.thermostat.storage.core.Storage; +import com.redhat.thermostat.storage.core.StorageCredentials; import com.redhat.thermostat.storage.mongodb.internal.MongoStorage; import com.redhat.thermostat.storage.query.Expression; import com.redhat.thermostat.storage.query.ExpressionFactory; @@ -123,6 +123,7 @@ @BeforeClass public static void setUpOnce() throws Exception { createFakeSetupCompleteFile(); + clearStorageDataDirectory(); startStorage(); addCpuData(4);
--- a/integration-tests/itest-run/src/test/java/com/redhat/thermostat/itest/StorageConnectionTest.java Thu Jun 04 00:38:59 2015 -0500 +++ b/integration-tests/itest-run/src/test/java/com/redhat/thermostat/itest/StorageConnectionTest.java Tue Jun 23 09:57:32 2015 -0600 @@ -51,6 +51,7 @@ // @BeforeClass // reinstate once we actually need storage running (see ignored tests) public static void setUpOnce() throws Exception { + clearStorageDataDirectory(); startStorage(); }
--- a/integration-tests/itest-run/src/test/java/com/redhat/thermostat/itest/StorageTest.java Thu Jun 04 00:38:59 2015 -0500 +++ b/integration-tests/itest-run/src/test/java/com/redhat/thermostat/itest/StorageTest.java Tue Jun 23 09:57:32 2015 -0600 @@ -59,8 +59,9 @@ @Test public void startAndStopStorage() throws Exception { + clearStorageDataDirectory(); + Spawn storage; - storage = startStorage(); storage = spawnThermostat("storage", "--status");
--- a/integration-tests/itest-run/src/test/java/com/redhat/thermostat/itest/VmCommandsTest.java Thu Jun 04 00:38:59 2015 -0500 +++ b/integration-tests/itest-run/src/test/java/com/redhat/thermostat/itest/VmCommandsTest.java Tue Jun 23 09:57:32 2015 -0600 @@ -54,6 +54,7 @@ @BeforeClass public static void setUpOnce() throws Exception { createFakeSetupCompleteFile(); + clearStorageDataDirectory(); startStorage(); // TODO insert actual data into the database and test that
--- a/integration-tests/itest-run/src/test/java/com/redhat/thermostat/itest/WebAppTest.java Thu Jun 04 00:38:59 2015 -0500 +++ b/integration-tests/itest-run/src/test/java/com/redhat/thermostat/itest/WebAppTest.java Tue Jun 23 09:57:32 2015 -0600 @@ -50,6 +50,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardCopyOption; @@ -60,10 +61,12 @@ import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.NoSuchElementException; import java.util.Properties; import java.util.Set; import java.util.UUID; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import org.eclipse.jetty.server.Server; @@ -101,6 +104,7 @@ import com.redhat.thermostat.storage.model.AgentInformation; import com.redhat.thermostat.storage.model.AggregateCount; import com.redhat.thermostat.storage.model.HostInfo; +import com.redhat.thermostat.storage.model.Pojo; import com.redhat.thermostat.storage.mongodb.internal.MongoStorage; import com.redhat.thermostat.storage.query.Expression; import com.redhat.thermostat.storage.query.ExpressionFactory; @@ -113,6 +117,7 @@ import com.redhat.thermostat.web.client.internal.WebStorage; import com.redhat.thermostat.web.server.auth.Roles; +import expectj.ExpectJ; import expectj.Spawn; import expectj.TimeoutException; @@ -237,11 +242,10 @@ private static final String TEST_USER = "testuser"; private static final String TEST_PASSWORD = "testpassword"; - private static final String PREP_USER = "prepuser"; - private static final String PREP_PASSWORD = "preppassword"; private static final double EQUALS_DELTA = 0.00000000000001; private static final String THERMOSTAT_USERS_FILE = getConfigurationDir() + "/thermostat-users.properties"; private static final String THERMOSTAT_ROLES_FILE = getConfigurationDir() + "/thermostat-roles.properties"; + private static final String THERMOSTAT_WEB_AUTH_FILE = getConfigurationDir() + "/web.auth"; private static final String VM_ID1 = "vmId1"; private static final String VM_ID2 = "vmId2"; private static final String VM_ID3 = "vmId3"; @@ -250,25 +254,41 @@ private static int port; private static Path backupUsers; private static Path backupRoles; + private static Path backupWebAuth; @BeforeClass public static void setUpOnce() throws Exception { - - // This starts storage with the permit localhost exception option. - // It's important to start storage with that exception. Otherwise the - // mongodb user creds setup will fail. - createFakeSetupCompleteFile(); - startStorage(); - - setupMongodbUser(); + clearStorageDataDirectory(); backupUsers = Files.createTempFile("itest-backup-thermostat-users", ""); backupRoles = Files.createTempFile("itest-backup-thermostat-roles", ""); + backupWebAuth = Files.createTempFile("itest-backup-webapp-auth", ""); backupRoles.toFile().deleteOnExit(); backupUsers.toFile().deleteOnExit(); + backupWebAuth.toFile().deleteOnExit(); Files.copy(new File(THERMOSTAT_USERS_FILE).toPath(), backupUsers, StandardCopyOption.REPLACE_EXISTING); Files.copy(new File(THERMOSTAT_ROLES_FILE).toPath(), backupRoles, StandardCopyOption.REPLACE_EXISTING); + Files.copy(new File(THERMOSTAT_WEB_AUTH_FILE).toPath(), backupWebAuth, StandardCopyOption.REPLACE_EXISTING); + createFakeSetupCompleteFile(); + createFakeUserSetupDoneFile(); + + setupMongodbUser(); + + startStorage(); + + ExpectJ mongo = new ExpectJ(TIMEOUT_IN_SECONDS); + Spawn mongoSpawn = mongo.spawn("mongo 127.0.0.1:27518"); + mongoSpawn.send("use thermostat\n"); + mongoSpawn.expect("switched to db thermostat"); + mongoSpawn.send(String.format("db.auth(\"%s\", \"%s\")\n", getMongodbUsername(), getMongodbPassword())); + mongoSpawn.expect("1"); + mongoSpawn.send("db[\"fake\"].insert({foo:\"bar\", baz: 1})\n"); + mongoSpawn.send("db[\"fake\"].findOne()\n"); + mongoSpawn.send("show collections\n"); + mongoSpawn.send("show users\n"); + + createWebAuthFile(); // start the server, deploy the war port = FreePortFinder.findFreePort(new TryPort() { @@ -284,62 +304,121 @@ @AfterClass public static void tearDownOnce() throws Exception { - deleteCpuData(); + try { + deleteCpuData(); + } catch (Exception e) { + System.out.println("AN ERROR OCCURRED DELETING CPU DATA!"); + e.printStackTrace(); + throw e; + } finally { + try { + server.stop(); + server.join(); + } catch (Exception e) { + System.out.println("AN ERROR OCCURRED STOPPING JETTY!"); + e.printStackTrace(); + throw e; + } finally { + try { + stopStorage(); + } catch (Exception e) { + System.out.println("AN ERROR OCCURRED STOPPING STORAGE!"); + e.printStackTrace(); + throw e; + } finally { + removeSetupCompleteStampFiles(); + Files.copy(backupUsers, new File(THERMOSTAT_USERS_FILE).toPath(), StandardCopyOption.REPLACE_EXISTING); + Files.copy(backupRoles, new File(THERMOSTAT_ROLES_FILE).toPath(), StandardCopyOption.REPLACE_EXISTING); + Files.copy(backupWebAuth, new File(THERMOSTAT_WEB_AUTH_FILE).toPath(), StandardCopyOption.REPLACE_EXISTING); + System.out.println("RESTORED backed-up files!"); + } + } + } + } - server.stop(); - server.join(); - - stopStorage(); - removeSetupCompleteStampFiles(); - - Files.copy(backupUsers, new File(THERMOSTAT_USERS_FILE).toPath(), StandardCopyOption.REPLACE_EXISTING); - Files.copy(backupRoles, new File(THERMOSTAT_ROLES_FILE).toPath(), StandardCopyOption.REPLACE_EXISTING); + private static long countAllData(BackingStorage storage, Category<AggregateCount> cat) { + try { + String countAllDataDesc = "QUERY-COUNT " + cat.getName(); + StatementDescriptor<AggregateCount> desc = new StatementDescriptor<>(cat, countAllDataDesc); + PreparedStatement<AggregateCount> statement = storage.prepareStatement(desc); + Cursor<AggregateCount> cursor = statement.executeQuery(); + assert cursor.hasNext(); + AggregateCount aggregate = cursor.next(); + long count = aggregate.getCount(); + return count; + } catch (StatementExecutionException | DescriptorParsingException e) { + throw new AssertionError(e); + } } // PRE: storage started with --permitLocalhostException private static void setupMongodbUser() throws Exception { - // The actual setup is only required for devel builds. - // Release builds won't have a web.xml with actual username/passwords - // in it, so starting backing storage (i.e. mongodb) with the - // --permitLocalhostException option is sufficient. - if (isDevelopmentBuild()) { - - // Remove the mongodb-user-added.stamp file, - // but keep the main setup file around so as to be able to - // actually launch thermostat. - removeSetupCompleteStampFiles(); - createFakeSetupCompleteFile(); + String mongodbUsername = getMongodbUsername(); + String mongodbPassword = getMongodbPassword(); + + final String HOST = "127.0.0.1"; + final String PORT = "27518"; + + try { + System.out.println("THERMOSTAT_HOME: " + getThermostatHome()); + System.out.println("USER_THERMOSTAT_HOME: " + getUserThermostatHome()); + + // start mongod + startStorage(); + + System.out.println("Started mongod"); + TimeUnit.SECONDS.sleep(3); + + ExpectJ mongo = new ExpectJ(TIMEOUT_IN_SECONDS); + Spawn mongoSpawn = mongo.spawn("mongo " + HOST + ":" + PORT); + mongoSpawn.send("use thermostat\n"); + mongoSpawn.send("var v = db.version()\n"); + mongoSpawn.send("var minorMicro = v.substr(v.indexOf('.') + 1)\n"); + mongoSpawn.send("var minorVersion = minorMicro.substr(0, minorMicro.indexOf('.'))\n"); + mongoSpawn.send("if ( minorVersion <= 2 ) {"); + mongoSpawn.send(String.format("db.addUser(\"%s\", \"%s\")", mongodbUsername, mongodbPassword)); + mongoSpawn.send("} else {"); + mongoSpawn.send("if ( minorVersion <= 4 ) {"); + mongoSpawn.send(String.format("db.addUser({ user: \"%s\", pwd: \"%s\", roles: [ \"readWrite\" ] })", + mongodbUsername, mongodbPassword)); + mongoSpawn.send("} else {"); + mongoSpawn.send(String.format("db.createUser({ user: \"%s\", pwd: \"%s\", roles: [ \"readWrite\" ] })", + mongodbUsername, mongodbPassword)); + mongoSpawn.send("}\n"); + mongoSpawn.send("}\n"); + mongoSpawn.send("quit()\n"); + mongoSpawn.expectClose(); + + mongo = new ExpectJ(TIMEOUT_IN_SECONDS); + mongoSpawn = mongo.spawn("mongo " + HOST + ":" + PORT); + mongoSpawn.send("use thermostat\n"); + mongoSpawn.expect("switched to db thermostat"); + mongoSpawn.send(String.format("db.auth(\"%s\", \"%s\")\n", mongodbUsername, mongodbPassword)); + mongoSpawn.expect("1"); + + // now insert some fake data and display some information that + // might be useful for post-mortem analysis if this test fails + mongoSpawn.send("db[\"fake\"].insert({foo:\"bar\", baz: 1})\n"); + mongoSpawn.send("db[\"fake\"].findOne()\n"); + mongoSpawn.send("show collections\n"); + mongoSpawn.send("show users\n"); - String mongodbUsername = getMongodbUsername(); - String mongodbPassword = getMongodbPassword(); - String creds = String.format("%s\n%s\n", mongodbUsername, - mongodbPassword); - String[] addUserArgs = new String[] { - "add-mongodb-user", - "-d", "mongodb://127.0.0.1:27518" - }; - - // This should be an equivalent of: - // $ echo -e "mongodbUsername\nmongodbPassword\n" | \ - // thermostat add-mongodb-user -d mongodb://127.0.0.1:27518 - Spawn addUser = spawnThermostat(addUserArgs); - addUser.send(creds); - try { - addUser.expect("mongodb user setup complete"); - } catch (TimeoutException | IOException e) { - // failed to set up mongodb user, stop storage and bail. - stopStorage(); - throw e; - } - addUser.expectClose(); - } else { - System.out.println("Not a development build. Skipping mongodb setup."); + } catch (TimeoutException | IOException e) { + throw e; + } finally { + stopStorage(); } } + private static void createWebAuthFile() throws IOException { + System.out.println("WRITING auth file: " + getMongodbUsername() + "/" + getMongodbPassword()); + List<String> lines = new ArrayList<String>(); + lines.add("storage.username = " + getMongodbUsername()); + lines.add("storage.password = " + getMongodbPassword()); + Files.write(new File(THERMOSTAT_WEB_AUTH_FILE).toPath(), lines, StandardCharsets.UTF_8); + } + private static String getMongodbUsername() { - assertTrue(isDevelopmentBuild()); - // Define this default in order for IDE based runs to require fewer // properties to be set. String defaultDevUser = "mongodevuser"; @@ -348,8 +427,6 @@ } private static String getMongodbPassword() { - assertTrue(isDevelopmentBuild()); - // Define this default in order for IDE based runs to require fewer // properties to be set. String defaultDevPassword = "mongodevpassword"; @@ -368,12 +445,12 @@ @Override public String getUsername() { - return null; + return getMongodbUsername(); } @Override public char[] getPassword() { - return null; + return getMongodbPassword().toCharArray(); } }; @@ -523,7 +600,7 @@ private static void addCpuData(int numberOfItems) throws IOException { BackingStorage storage = getAndConnectBackingStorage(); - storage.registerCategory(CpuStatDAO.cpuStatCategory); + Category<AggregateCount> cat = registerCatoriesForWrite(storage, CpuStatDAO.cpuStatCategory); for (int i = 0; i < numberOfItems; i++) { CpuStat pojo = new CpuStat("test-agent-id", i, new double[] {i, i*2}); @@ -533,13 +610,33 @@ add.set(Key.TIMESTAMP.getName(), pojo.getTimeStamp()); add.apply(); } + waitForDataCount(numberOfItems, storage, cat); + storage.getConnection().disconnect(); + } + + private static void waitForDataCount(int expectedCount, BackingStorage storage, Category<AggregateCount> cat) { + long count = countAllData(storage, cat); + int currCount = 0; + final int MAX_CYCLES = 5; + while (count != expectedCount && currCount < MAX_CYCLES) { + try { + Thread.sleep(250); + } catch (InterruptedException ignored) {} + count = countAllData(storage, cat); + } + + } - storage.getConnection().disconnect(); + private static <T extends Pojo> Category<AggregateCount> registerCatoriesForWrite(BackingStorage storage, Category<T> cat) { + storage.registerCategory(cat); + Category<AggregateCount> adaptedCategory = new CategoryAdapter<T, AggregateCount>(cat).getAdapted(AggregateCount.class); + storage.registerCategory(adaptedCategory); + return adaptedCategory; } private static void addHostInfoData(int numberOfItems) throws IOException { BackingStorage storage = getAndConnectBackingStorage(); - storage.registerCategory(HostInfoDAO.hostInfoCategory); + Category<AggregateCount> cat = registerCatoriesForWrite(storage, HostInfoDAO.hostInfoCategory); for (int i = 0; i < numberOfItems; i++) { HostInfo hostInfo = new HostInfo("test-host-agent-id", "foo " + i, "linux " + i, "kernel", "t8", i, i * 1000); @@ -553,13 +650,13 @@ add.set(HostInfoDAO.osNameKey.getName(), hostInfo.getOsName()); add.apply(); } - + waitForDataCount(numberOfItems, storage, cat); storage.getConnection().disconnect(); } private static void addAgentConfigData(List<AgentInformation> items) throws IOException { BackingStorage storage = getAndConnectBackingStorage(); - storage.registerCategory(AgentInfoDAO.CATEGORY); + Category<AggregateCount> cat = registerCatoriesForWrite(storage, AgentInfoDAO.CATEGORY); for (AgentInformation info: items) { Add<AgentInformation> add = storage.createAdd(AgentInfoDAO.CATEGORY); @@ -570,7 +667,7 @@ add.set(AgentInfoDAO.STOP_TIME_KEY.getName(), info.getStopTime()); add.apply(); } - + waitForDataCount(items.size(), storage, cat); storage.getConnection().disconnect(); } @@ -582,22 +679,23 @@ doDeleteData(HostInfoDAO.hostInfoCategory, "test-host-agent-id"); } - private static void doDeleteData(Category<?> category, String agentId) throws IOException { - String[] roleNames = new String[] { - Roles.REGISTER_CATEGORY, - Roles.ACCESS_REALM, - Roles.LOGIN, - Roles.PURGE - }; - Storage storage = getAndConnectStorage(PREP_USER, PREP_PASSWORD, roleNames); - storage.registerCategory(category); + private static <T extends Pojo> void doDeleteData(Category<T> category, String agentId) throws IOException { + BackingStorage storage = getAndConnectBackingStorage(); + Category<AggregateCount> cat = registerCatoriesForWrite(storage, category); + // FIXME: The method signature suggests it deletes data for the given agent + // in the given category. But it actually deletes any records in + // any category matching the agentId parameter. This should get + // changed from purge to a remove operation. storage.purge(agentId); + waitForDataCount(0, storage, cat); storage.getConnection().disconnect(); } private static void deleteAgentConfigData(List<AgentInformation> items) throws IOException { BackingStorage storage = getAndConnectBackingStorage(); - storage.registerCategory(AgentInfoDAO.CATEGORY); + Category<AggregateCount> cat = registerCatoriesForWrite(storage, AgentInfoDAO.CATEGORY); + + long countPriorRemove = countAllData(storage, cat); ExpressionFactory factory = new ExpressionFactory(); Remove<AgentInformation> remove = storage.createRemove(AgentInfoDAO.CATEGORY); Set<String> agentIds = new HashSet<>(); @@ -607,6 +705,7 @@ Expression expression = factory.in(Key.AGENT_ID, agentIds, String.class); remove.where(expression); remove.apply(); + waitForDataCount((int)(countPriorRemove - items.size()), storage, cat); storage.getConnection().disconnect(); }
--- a/launcher/src/main/java/com/redhat/thermostat/launcher/internal/LauncherImpl.java Thu Jun 04 00:38:59 2015 -0500 +++ b/launcher/src/main/java/com/redhat/thermostat/launcher/internal/LauncherImpl.java Tue Jun 23 09:57:32 2015 -0600 @@ -91,7 +91,7 @@ private static final String SETUP_SCRIPT_NAME = "thermostat-setup"; private static final Translate<LocaleResources> t = LocaleResources.createLocalizer(); - private Logger logger; + private static final Logger logger = LoggingUtils.getLogger(LauncherImpl.class); private final AtomicInteger usageCount = new AtomicInteger(0); private final BundleContext context; @@ -130,7 +130,10 @@ this.paths = Objects.requireNonNull(paths); loggingInitializer.initialize(); - logger = LoggingUtils.getLogger(LauncherImpl.class); + // We log this in the constructor so as to not log it multiple times when a command invokes + // run() multiple times. This works since it is a singleton service. + logger.log(Level.CONFIG, "THERMOSTAT_HOME=" + paths.getSystemThermostatHome().getAbsolutePath()); + logger.log(Level.CONFIG, "USER_THERMOSTAT_HOME=" + paths.getUserThermostatHome().getAbsolutePath()); } @Override
--- a/launcher/src/test/java/com/redhat/thermostat/launcher/internal/ActivatorTest.java Thu Jun 04 00:38:59 2015 -0500 +++ b/launcher/src/test/java/com/redhat/thermostat/launcher/internal/ActivatorTest.java Tue Jun 23 09:57:32 2015 -0600 @@ -197,6 +197,8 @@ assertNotNull(action); Keyring keyringService = mock(Keyring.class); CommonPaths paths = mock(CommonPaths.class); + when(paths.getSystemThermostatHome()).thenReturn(mock(File.class)); + when(paths.getUserThermostatHome()).thenReturn(mock(File.class)); when(paths.getSystemLibRoot()).thenReturn(new File("")); when(paths.getSystemPluginRoot()).thenReturn(new File("")); when(paths.getUserPluginRoot()).thenReturn(new File(""));
--- a/launcher/src/test/java/com/redhat/thermostat/launcher/internal/LauncherImplTest.java Thu Jun 04 00:38:59 2015 -0500 +++ b/launcher/src/test/java/com/redhat/thermostat/launcher/internal/LauncherImplTest.java Tue Jun 23 09:57:32 2015 -0600 @@ -37,6 +37,7 @@ package com.redhat.thermostat.launcher.internal; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.Matchers.anyString; @@ -50,7 +51,9 @@ import java.util.Collection; import java.util.EnumSet; import java.util.concurrent.ExecutorService; +import java.util.logging.Handler; import java.util.logging.Level; +import java.util.logging.LogRecord; import java.util.logging.Logger; import org.apache.commons.cli.Option; @@ -96,7 +99,7 @@ private static final String name3 = "test3"; private static final String name4 = "test4"; private static SecurityManager secMan; - + @BeforeClass public static void beforeClassSetUp() { // Launcher calls System.exit(). This causes issues for unit testing. @@ -273,6 +276,8 @@ when(paths.getUserSetupCompleteStampFile()).thenReturn(setupFile); ClientPreferences prefs = new ClientPreferences(paths); + when(paths.getSystemThermostatHome()).thenReturn(mock(File.class)); + when(paths.getUserThermostatHome()).thenReturn(mock(File.class)); launcher = new LauncherImpl(bundleContext, ctxFactory, registry, infos, new CommandSource(bundleContext), environment, dbServiceFactory, version, prefs, keyring, paths, loggingInitializer); } @@ -558,6 +563,44 @@ assertEquals(expectedVersionInfo, ctxFactory.getOutput()); assertTrue(timerFactory.isShutdown()); } + + /** + * Tests if USER_THERMOSTAT_HOME and THERMOSTAT_HOME gets logged correctly + * on instantiation. + */ + @Test + public void verifyLogsUserHomeThermostatHomeOnInstantiation() { + Logger logger = Logger.getLogger("com.redhat.thermostat"); + logger.setLevel(Level.ALL); + assertTrue(logger.getLevel() == Level.ALL); + TestLogHandler handler = new TestLogHandler(); + logger.addHandler(handler); + ClientPreferences prefs = mock(ClientPreferences.class); + Keyring keyring = mock(Keyring.class); + CommonPaths logPaths = mock(CommonPaths.class); + when(logPaths.getUserThermostatHome()).thenReturn(mock(File.class)); + when(logPaths.getSystemThermostatHome()).thenReturn(mock(File.class)); + + try { + assertFalse(handler.loggedThermostatHome); + assertFalse(handler.loggedUserHome); + // this should trigger logging + new LauncherImpl(bundleContext, ctxFactory, registry, + infos, new CommandSource(bundleContext), + environment, dbServiceFactory, + version, prefs, keyring, logPaths, + loggingInitializer); + assertTrue(handler.loggedThermostatHome); + assertTrue(handler.loggedUserHome); + verify(logPaths).getUserThermostatHome(); + verify(logPaths).getSystemThermostatHome(); + } finally { + // clean-up in order to avoid logs for other tests. + logger.removeHandler(handler); + handler = null; + logger.setLevel(Level.INFO); + } + } @Test public void verifyListenersAdded() { @@ -637,6 +680,35 @@ ctxFactory.getCommandRegistry().registerCommand(cmdName, mockCmd); runAndVerifyCommand(new String[] { cmdName }, expected, isInShell); - } + } + + private static class TestLogHandler extends Handler { + + private boolean loggedThermostatHome; + private boolean loggedUserHome; + + @Override + public void close() throws SecurityException { + // nothing + } + + @Override + public void flush() { + // nothing + } + + @Override + public void publish(LogRecord record) { + String logMessage = record.getMessage(); + System.out.println(logMessage); + if (record.getLevel() == Level.CONFIG && logMessage.startsWith("THERMOSTAT_HOME")) { + loggedThermostatHome = true; + } + if (record.getLevel() == Level.CONFIG && logMessage.startsWith("USER_THERMOSTAT_HOME")) { + loggedUserHome = true; + } + } + + } }
--- a/numa/client-swing/src/test/java/com/redhat/thermostat/numa/client/swing/internal/NumaPanelTest.java Thu Jun 04 00:38:59 2015 -0500 +++ b/numa/client-swing/src/test/java/com/redhat/thermostat/numa/client/swing/internal/NumaPanelTest.java Tue Jun 23 09:57:32 2015 -0600 @@ -46,12 +46,15 @@ import org.fest.swing.fixture.Containers; import org.fest.swing.fixture.FrameFixture; import org.junit.Test; +import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; +import com.redhat.thermostat.annotations.internal.CacioTest; import com.redhat.thermostat.client.core.views.BasicView; import com.redhat.thermostat.common.ActionEvent; import com.redhat.thermostat.common.ActionListener; +@Category(CacioTest.class) @RunWith(CacioFESTRunner.class) public class NumaPanelTest {
--- a/pom.xml Thu Jun 04 00:38:59 2015 -0500 +++ b/pom.xml Tue Jun 23 09:57:32 2015 -0600 @@ -78,6 +78,25 @@ <surefire-argline>-XX:-UseSplitVerifier -XX:MaxPermSize=300m</surefire-argline> </properties> </profile> + <profile> + <!-- Temporary workaround for PR2282: Caciocavallo tests fail with JDK 8 u40 --> + <id>java-8-skip-cacio-tests</id> + <activation> + <jdk>1.8</jdk> + </activation> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <excludedGroups>com.redhat.thermostat.annotations.internal.CacioTest</excludedGroups> + </configuration> + </plugin> + </plugins> + </build> + + </profile> <!-- Development settings for web.xml. Release builds should have the "environment.type=release" property. --> <profile>
--- a/storage/mongo/src/main/java/com/redhat/thermostat/storage/mongodb/internal/Activator.java Thu Jun 04 00:38:59 2015 -0500 +++ b/storage/mongo/src/main/java/com/redhat/thermostat/storage/mongodb/internal/Activator.java Tue Jun 23 09:57:32 2015 -0600 @@ -40,8 +40,6 @@ import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceRegistration; -import com.redhat.thermostat.common.cli.CommandRegistry; -import com.redhat.thermostat.common.cli.CommandRegistryImpl; import com.redhat.thermostat.storage.core.StorageProvider; import com.redhat.thermostat.storage.mongodb.MongoStorageProvider; @@ -49,20 +47,16 @@ @SuppressWarnings("rawtypes") private ServiceRegistration reg; - private CommandRegistry cmdReg; @Override public void start(BundleContext context) throws Exception { StorageProvider prov = new MongoStorageProvider(); reg = context.registerService(StorageProvider.class.getName(), prov, null); - cmdReg = new CommandRegistryImpl(context); - cmdReg.registerCommand(AddUserCommandDispatcher.COMMAND_NAME, new AddUserCommandDispatcher(context)); } @Override public void stop(BundleContext context) throws Exception { reg.unregister(); - cmdReg.unregisterCommands(); } }
--- a/storage/mongo/src/main/java/com/redhat/thermostat/storage/mongodb/internal/AddUserCommand.java Thu Jun 04 00:38:59 2015 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,198 +0,0 @@ -/* - * Copyright 2012-2015 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.storage.mongodb.internal; - -import java.io.File; -import java.io.IOException; -import java.lang.reflect.Field; -import java.util.Arrays; -import java.util.Objects; - -import org.osgi.framework.BundleContext; -import org.osgi.framework.ServiceReference; -import org.osgi.framework.ServiceRegistration; - -import com.redhat.thermostat.common.cli.CommandContext; -import com.redhat.thermostat.common.cli.CommandException; -import com.redhat.thermostat.common.tools.StorageAuthInfoGetter; -import com.redhat.thermostat.shared.config.CommonPaths; -import com.redhat.thermostat.shared.locale.LocalizedString; -import com.redhat.thermostat.shared.locale.Translate; -import com.redhat.thermostat.storage.core.DbService; -import com.redhat.thermostat.storage.core.DbServiceFactory; -import com.redhat.thermostat.storage.core.QueuedStorage; -import com.redhat.thermostat.storage.core.Storage; -import com.redhat.thermostat.storage.core.StorageCredentials; - -/** - * This command needs to be in the mongodb storage bundle since it - * uses MongoStorage directly (casts to it). - * - */ -public class AddUserCommand extends BaseAddUserCommand { - - private static final Translate<LocaleResources> t = LocaleResources.createLocalizer(); - static final String DB_URL_ARG = "dbUrl"; - private final BundleContext context; - private final StorageCredentials emptyCredentials; - - AddUserCommand(BundleContext context) { - this.context = context; - // These are empty credentials we'll use for the initial connect. We - // connect with them when the local host exception is turned off. - emptyCredentials = new StorageCredentials() { - - @Override - public String getUsername() { - return null; - } - - @Override - public char[] getPassword() { - return null; - } - }; - } - - // PRE: storage started with --permitLocalHostException. - // FIXME: Is there anything we can do to ensure this precondition? - @Override - public void run(CommandContext ctx) throws CommandException { - // Check if mongodb stamp file exists. - ServiceReference commonPathRef = context.getServiceReference(CommonPaths.class.getName()); - requireNonNull(commonPathRef, t.localize(LocaleResources.COMMON_PATHS_SERVICE_UNAVAILABLE)); - CommonPaths commonPath = (CommonPaths)context.getService(commonPathRef); - File dataDir = commonPath.getUserPersistentDataDirectory(); - // Since this is backing storage specific, it's most likely not a good - // candidate for CommonPaths - File mongodbSetupStamp = new File(dataDir, BaseAddUserCommand.MONGODB_STAMP_FILE_NAME); - if (mongodbSetupStamp.exists()) { - String msg = t.localize(LocaleResources.MONGODB_SETUP_FILE_EXISTS, - mongodbSetupStamp.getAbsolutePath()).getContents(); - ctx.getConsole().getOutput().println(msg); - return; - } - - ServiceReference dbServiceRef = context.getServiceReference(DbService.class); - if (dbServiceRef != null) { - // Already connected, bail out - throw new CommandException(t.localize(LocaleResources.ALREADY_CONNECTED_TO_STORAGE_WARNING)); - } - String dbUrl = ctx.getArguments().getArgument(DB_URL_ARG); - // dbUrl is a required argument. This should never happen - Objects.requireNonNull(dbUrl); - // we only understand "mongodb://" URLs - if (!dbUrl.startsWith("mongodb://")) { - throw new CommandException(t.localize(LocaleResources.UNKNOWN_STORAGE_URL)); - } - - // Register empty credentials so that connection succeeds - ServiceRegistration reg = context.registerService(StorageCredentials.class.getName(), emptyCredentials, null); - DbServiceFactory factory = new DbServiceFactory(); - DbService service = factory.createDbService(dbUrl); - // this synchronously connects to storage - service.connect(); - // Unregister empty credentials - reg.unregister(); - - ServiceReference storageRef = context.getServiceReference(Storage.class.getName()); - requireNonNull(storageRef, t.localize(LocaleResources.STORAGE_SERVICE_UNAVAILABLE)); - @SuppressWarnings("unchecked") - // FIXME: Hack alarm. We use knowledge that via MongoStorageProvider we - // have a MongoStorage instance wrapped in QueuedStorage. What's - // more, we use the "delegate" field name in order to get at the - // MongoStorage instance, which we cast to. I'm not sure if adding - // method in BackingStorage (the interface) directly would be - // any better than this. After all, this is very backing storage - // impl specific. For now do this hack :-/ - QueuedStorage storage = (QueuedStorage)context.getService(storageRef); - MongoStorage mongoStorage = getDelegate(storage); - requireNonNull(mongoStorage, t.localize(LocaleResources.MONGOSTORAGE_RETRIEVAL_FAILED)); - StorageAuthInfoGetter getter = null; - try { - LocalizedString userPrompt = new LocalizedString("Please enter the username you'd like to add to mongodb storage at " + dbUrl + ": "); - LocalizedString passWordPrompt = new LocalizedString("Please enter the desired password of this user: "); - getter = new StorageAuthInfoGetter(ctx.getConsole(), userPrompt, passWordPrompt); - } catch (IOException e) { - throw new CommandException(t.localize(LocaleResources.ADDING_USER_FAILED)); - } - ConsoleStorageCredentials creds = new ConsoleStorageCredentials(getter); - addUser(mongoStorage, creds); - - // create the STAMP file - try { - mongodbSetupStamp.createNewFile(); - } catch (IOException e) { - String msg = t.localize(LocaleResources.STAMP_FILE_CREATION_FAILED, - mongodbSetupStamp.getAbsolutePath()).getContents(); - ctx.getConsole().getError().println(msg); - throw new CommandException(new LocalizedString(msg)); - } - - String msg = t.localize(LocaleResources.MONGODB_USER_SETUP_COMPLETE).getContents(); - ctx.getConsole().getOutput().println(msg); - } - - // package-private for testing - void addUser(MongoStorage mongoStorage, StorageCredentials creds) { - // It's important that getUsername is called prior getPassword. - // otherwise prompts don't make much sense. - String username = creds.getUsername(); - char[] pwd = creds.getPassword(); - mongoStorage.addUser(username, pwd); - // zero out password. We no longer use it. - Arrays.fill(pwd, '\0'); - } - - // package-private for testing - MongoStorage getDelegate(QueuedStorage storage) { - try { - Field field = storage.getClass().getDeclaredField("delegate"); - field.setAccessible(true); - MongoStorage mongo = (MongoStorage)field.get(storage); - return mongo; - } catch (Exception e) { - return null; - } - } - - @Override - public boolean isStorageRequired() { - return false; - } - -}
--- a/storage/mongo/src/main/java/com/redhat/thermostat/storage/mongodb/internal/AddUserCommandDispatcher.java Thu Jun 04 00:38:59 2015 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,78 +0,0 @@ -/* - * Copyright 2012-2015 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.storage.mongodb.internal; - -import org.osgi.framework.BundleContext; - -import com.redhat.thermostat.common.cli.CommandContext; -import com.redhat.thermostat.common.cli.CommandException; -import com.redhat.thermostat.shared.locale.Translate; - -/** - * Dispatcher making sure either -d or -s has been provided. - * - */ -class AddUserCommandDispatcher extends BaseAddUserCommand { - - private static final Translate<LocaleResources> t = LocaleResources.createLocalizer(); - private static final String START_STORAGE_ARG = "startStorage"; - private static final String DB_URL_ARG = "dbUrl"; - static final String COMMAND_NAME = "add-mongodb-user"; - private final BundleContext context; - private BaseAddUserCommand command; - - AddUserCommandDispatcher(BundleContext context, BaseAddUserCommand cmd) { - this.context = context; - this.command = cmd; - } - - AddUserCommandDispatcher(BundleContext context) { - this(context, new AddUserCommand(context)); - } - - @Override - public void run(CommandContext ctx) throws CommandException { - if (ctx.getArguments().hasArgument(START_STORAGE_ARG)) { - // decorate and run - command = new StartStopAddUserCommandDecorator(context, command); - } else if (!ctx.getArguments().hasArgument(DB_URL_ARG)) { - throw new CommandException(t.localize(LocaleResources.DISPATCHER_WRONG_OPTION)); - } - command.run(ctx); - } - -}
--- a/storage/mongo/src/main/java/com/redhat/thermostat/storage/mongodb/internal/BaseAddUserCommand.java Thu Jun 04 00:38:59 2015 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,62 +0,0 @@ -/* - * Copyright 2012-2015 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.storage.mongodb.internal; - -import com.redhat.thermostat.common.cli.AbstractCommand; -import com.redhat.thermostat.common.cli.CommandContext; -import com.redhat.thermostat.common.cli.CommandException; - -/** - * - * Base class for user setup decorators. - * - * @see AddUserCommand - * @see StartStopAddUserCommandDecorator - * - */ -abstract class BaseAddUserCommand extends AbstractCommand { - - static final String MONGODB_STAMP_FILE_NAME = "mongodb-user-done.stamp"; - - @Override - abstract public void run(CommandContext ctx) throws CommandException; - - @Override - public boolean isStorageRequired() { - return false; - } -}
--- a/storage/mongo/src/main/java/com/redhat/thermostat/storage/mongodb/internal/MongoConnection.java Thu Jun 04 00:38:59 2015 -0500 +++ b/storage/mongo/src/main/java/com/redhat/thermostat/storage/mongodb/internal/MongoConnection.java Tue Jun 23 09:57:32 2015 -0600 @@ -113,7 +113,7 @@ private void authenticate(String username, char[] password) { if (! db.authenticate(username, password)) { - throw new MongoException("Invalid username/password"); + throw new MongoException("Invalid username/password: " + username + "/" + new String(password)); } }
--- a/storage/mongo/src/main/java/com/redhat/thermostat/storage/mongodb/internal/MongoStorage.java Thu Jun 04 00:38:59 2015 -0500 +++ b/storage/mongo/src/main/java/com/redhat/thermostat/storage/mongodb/internal/MongoStorage.java Tue Jun 23 09:57:32 2015 -0600 @@ -701,18 +701,6 @@ categoryInfo, true, false); } - - /* - * Used by add-user command. - * - * Pre: must be connected to storage already - */ - void addUser(String username, char[] password) { - // only create user if not already existing - if (!db.authenticate(username, password)) { - db.addUser(username, password); - } - } }
--- a/storage/mongo/src/main/java/com/redhat/thermostat/storage/mongodb/internal/StartStopAddUserCommandDecorator.java Thu Jun 04 00:38:59 2015 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,268 +0,0 @@ -/* - * Copyright 2012-2015 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.storage.mongodb.internal; - -import java.io.File; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.concurrent.CountDownLatch; - -import org.osgi.framework.BundleContext; -import org.osgi.framework.ServiceReference; - -import com.redhat.thermostat.common.ActionEvent; -import com.redhat.thermostat.common.ActionListener; -import com.redhat.thermostat.common.cli.AbstractStateNotifyingCommand; -import com.redhat.thermostat.common.cli.Arguments; -import com.redhat.thermostat.common.cli.CommandContext; -import com.redhat.thermostat.common.cli.CommandContextFactory; -import com.redhat.thermostat.common.cli.CommandException; -import com.redhat.thermostat.common.tools.ApplicationState; -import com.redhat.thermostat.launcher.Launcher; -import com.redhat.thermostat.shared.config.CommonPaths; -import com.redhat.thermostat.shared.locale.Translate; - -/* - * A command which adds a mongdb user by using AddUserCommand. It has been - * introduced in order to aid boot-strapping of thermostat deployments. In order - * to set up a user in mongodb, storage needs to be started with the - * --permitLocalhostException option first. Then the credentials need to be - * injected and storage stopped again. This command performs all three - * required steps. - */ -public class StartStopAddUserCommandDecorator extends BaseAddUserCommand { - - public static final String COMMAND_NAME = "admin-mongodb-creds-setup"; - private static final Translate<LocaleResources> t = LocaleResources.createLocalizer(); - private final BundleContext context; - private final List<ActionListener<ApplicationState>> listeners; - private final CountDownLatch setupFinishedBarrier; - private final BaseAddUserCommand decoratee; - private boolean setupSuccessful; - private Launcher launcher; - private CommandContext cmdCtx; - - StartStopAddUserCommandDecorator(BundleContext context, BaseAddUserCommand command) { - this.context = context; - this.listeners = new ArrayList<>(1); - this.setupFinishedBarrier = new CountDownLatch(1); - this.setupSuccessful = true; - this.decoratee = command; - } - - @Override - public void run(CommandContext ctx) throws CommandException { - cmdCtx = ctx; - if (!stampFileExists()) { - startStorageAndRunDecoratee(); - stopStorage(); - } - // if stamp file exists, there is nothing to do. - String msg; - if (setupSuccessful) { - msg = t.localize(LocaleResources.USER_SETUP_COMPLETE).getContents(); - cmdCtx.getConsole().getOutput().println(msg); - } else { - msg = t.localize(LocaleResources.USER_SETUP_FAILED).getContents(); - cmdCtx.getConsole().getOutput().println(msg); - } - } - - private void stopStorage() throws CommandException { - listeners.clear(); - CountDownLatch storageStoppedlatch = new CountDownLatch(1); - StorageStoppedListener listener = new StorageStoppedListener(storageStoppedlatch); - String[] storageStopArgs = new String[] { - "storage", "--stop" - }; - listeners.add(listener); - launcher.run(storageStopArgs, listeners, false); - try { - storageStoppedlatch.await(); - } catch (InterruptedException e) { - setupSuccessful = false; - throw new CommandException(t.localize(LocaleResources.INTERRUPTED_WAITING_FOR_STORAGE_STOP), e); - } - if (!listener.storageStopPassed) { - setupSuccessful = false; - String msg = t.localize(LocaleResources.STORAGE_STOP_FAILED).getContents(); - cmdCtx.getConsole().getError().println(msg); - } - } - - private void startStorageAndRunDecoratee() throws CommandException { - ServiceReference launcherRef = context.getServiceReference(Launcher.class); - if (launcherRef == null) { - throw new CommandException(t.localize(LocaleResources.LAUNCHER_SERVICE_UNAVAILABLE)); - } - launcher = (Launcher) context.getService(launcherRef); - StorageStartedListener listener = new StorageStartedListener(); - listeners.add(listener); - String[] storageStartArgs = new String[] { "storage", "--start", "--permitLocalhostException"}; - launcher.run(storageStartArgs, listeners, false); - try { - setupFinishedBarrier.await(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - - private boolean stampFileExists() throws CommandException { - ServiceReference commonPathRef = context.getServiceReference(CommonPaths.class.getName()); - if (commonPathRef == null) { - throw new CommandException(t.localize(LocaleResources.COMMON_PATHS_SERVICE_UNAVAILABLE)); - } - CommonPaths commonPath = (CommonPaths)context.getService(commonPathRef); - File dataDir = commonPath.getUserPersistentDataDirectory(); - // Since this is backing storage specific, it's most likely not a good - // candidate for CommonPaths - File mongodbSetupStamp = new File(dataDir, BaseAddUserCommand.MONGODB_STAMP_FILE_NAME); - if (mongodbSetupStamp.exists()) { - String msg = t.localize(LocaleResources.MONGODB_SETUP_FILE_EXISTS, - mongodbSetupStamp.getAbsolutePath()).getContents(); - cmdCtx.getConsole().getOutput().println(msg); - return true; - } else { - return false; - } - } - - private class StorageStartedListener implements ActionListener<ApplicationState> { - - @Override - public void actionPerformed(ActionEvent<ApplicationState> actionEvent) { - if (actionEvent.getSource() instanceof AbstractStateNotifyingCommand) { - AbstractStateNotifyingCommand storage = (AbstractStateNotifyingCommand) actionEvent.getSource(); - // Implementation detail: there is a single StorageCommand instance registered - // as an OSGi service. We remove ourselves as listener so that we don't get - // notified in the case that the command is invoked by some other means later. - storage.getNotifier().removeActionListener(this); - - try { - switch (actionEvent.getActionId()) { - case START: - // Payload is connection URL - Object payload = actionEvent.getPayload(); - if (payload == null || !(payload instanceof String)) { - setupSuccessful = false; - throw new CommandException(t.localize(LocaleResources.UNRECOGNIZED_PAYLOAD_FROM_STORAGE_CMD)); - } - final String dbUrl = (String)payload; - try { - CommandContext ctx = getAddUserCommandContext(dbUrl); - decoratee.run(ctx); - } catch (CommandException e) { - cmdCtx.getConsole().getError().println(e.getMessage()); - String msg = t.localize(LocaleResources.ADDING_USER_FAILED).getContents(); - cmdCtx.getConsole().getError().println(msg); - } - break; - case FAIL: - // nothing - break; - default: - // nothing - break; - } - } catch (CommandException e) { - cmdCtx.getConsole().getError().println(e.getMessage()); - } finally { - setupFinishedBarrier.countDown(); - } - } - - } - - private CommandContext getAddUserCommandContext(final String dbUrl) { - CommandContextFactory factory = new CommandContextFactory(context); - CommandContext ctx = factory.createContext(new Arguments() { - - @Override - public boolean hasArgument(String name) { - if (name.equals(AddUserCommand.DB_URL_ARG)) { - return true; - } - return false; - } - - @Override - public List<String> getNonOptionArguments() { - return Collections.emptyList(); - } - - @Override - public String getArgument(String name) { - if (name.equals(AddUserCommand.DB_URL_ARG)) { - return dbUrl; - } - return null; - } - }); - return ctx; - } - } - - private static class StorageStoppedListener implements ActionListener<ApplicationState> { - - private boolean storageStopPassed; - private final CountDownLatch storageStoppedLatch; - private StorageStoppedListener(CountDownLatch latch) { - storageStoppedLatch = latch; - } - - @Override - public void actionPerformed(ActionEvent<ApplicationState> actionEvent) { - if (actionEvent.getSource() instanceof AbstractStateNotifyingCommand) { - AbstractStateNotifyingCommand storage = (AbstractStateNotifyingCommand) actionEvent.getSource(); - // remove ourselves so that we get called more than once. - storage.getNotifier().removeActionListener(this); - switch(actionEvent.getActionId()) { - case STOP: - storageStopPassed = true; - storageStoppedLatch.countDown(); - break; - default: - storageStoppedLatch.countDown(); - break; - - } - } - } - - } -}
--- a/storage/mongo/src/test/java/com/redhat/thermostat/storage/mongodb/internal/AddUserCommandDispatcherTest.java Thu Jun 04 00:38:59 2015 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,119 +0,0 @@ -/* - * Copyright 2012-2015 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.storage.mongodb.internal; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.Matchers.eq; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import org.junit.Test; -import org.osgi.framework.BundleContext; - -import com.redhat.thermostat.common.cli.Arguments; -import com.redhat.thermostat.common.cli.CommandContext; -import com.redhat.thermostat.common.cli.CommandContextFactory; -import com.redhat.thermostat.common.cli.CommandException; - -public class AddUserCommandDispatcherTest { - - @Test - public void canRunUndecorated() { - BundleContext context = mock(BundleContext.class); - BaseAddUserCommand mockCmd = mock(BaseAddUserCommand.class); - AddUserCommandDispatcher dispatcher = new AddUserCommandDispatcher(context, mockCmd); - CommandContextFactory factory = new CommandContextFactory(context); - Arguments args = mock(Arguments.class); - when(args.hasArgument(eq("dbUrl"))).thenReturn(true); - CommandContext ctx = factory.createContext(args); - - // This should not throw any exception - try { - dispatcher.run(ctx); - } catch (CommandException e) { - fail(e.getMessage()); - } - } - - @Test(expected = CommandException.class ) - public void failsToRunWithNoArguments() throws CommandException { - BundleContext context = mock(BundleContext.class); - BaseAddUserCommand mockCmd = mock(BaseAddUserCommand.class); - AddUserCommandDispatcher dispatcher = new AddUserCommandDispatcher(context, mockCmd); - CommandContextFactory factory = new CommandContextFactory(context); - Arguments args = mock(Arguments.class); - when(args.hasArgument(any(String.class))).thenReturn(false); - CommandContext ctx = factory.createContext(args); - - // this throws CommandException - dispatcher.run(ctx); - } - - @Test - public void decoratesIfStorageStartOptionGiven() { - BundleContext context = mock(BundleContext.class); - BaseAddUserCommand mockCmd = mock(BaseAddUserCommand.class); - AddUserCommandDispatcher dispatcher = new AddUserCommandDispatcher(context, mockCmd); - CommandContextFactory factory = new CommandContextFactory(context); - Arguments args = mock(Arguments.class); - when(args.hasArgument(eq("startStorage"))).thenReturn(true); - CommandContext ctx = factory.createContext(args); - - try { - dispatcher.run(ctx); - fail("CommonPaths not available, should have thrown exception"); - } catch (CommandException e) { - boolean passed = false; - for( StackTraceElement elmt: e.getStackTrace()) { - // StartStopAddUserCommandDecorator should be in stack trace - if (elmt.getClassName().equals(StartStopAddUserCommandDecorator.class.getName())) { - passed = true; - break; - } - } - assertTrue("Expected mocked BaseAddUserCommand to be decorated", passed); - } - } - - @Test - public void testCommandName() { - assertEquals("add-mongodb-user", AddUserCommandDispatcher.COMMAND_NAME); - } -}
--- a/storage/mongo/src/test/java/com/redhat/thermostat/storage/mongodb/internal/AddUserCommandTest.java Thu Jun 04 00:38:59 2015 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,116 +0,0 @@ -/* - * Copyright 2012-2015 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.storage.mongodb.internal; - -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.inOrder; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import java.util.Arrays; -import java.util.concurrent.CountDownLatch; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.InOrder; -import org.powermock.api.mockito.PowerMockito; -import org.powermock.core.classloader.annotations.PowerMockIgnore; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; - -import com.mongodb.DB; -import com.redhat.thermostat.storage.core.QueuedStorage; -import com.redhat.thermostat.storage.core.Storage; -import com.redhat.thermostat.storage.core.StorageCredentials; - -//There is a bug (resolved as wontfix) in powermock which results in -//java.lang.LinkageError if javax.management.* classes aren't ignored by -//Powermock. More here: http://code.google.com/p/powermock/issues/detail?id=277 -//SSL tests need this and having that annotation on method level doesn't seem -//to solve the issue. -@PowerMockIgnore( {"javax.management.*"}) -@RunWith(PowerMockRunner.class) -@PrepareForTest({ DB.class }) -public class AddUserCommandTest { - - /* - * Verifies that credentials' methods are called in the right order and - * the password array is filled with zeros after use. - */ - @Test - public void verifyAddUser() { - DB db = PowerMockito.mock(DB.class); - CountDownLatch latch = new CountDownLatch(1); - MongoStorage storage = new MongoStorage(db, latch); - - StorageCredentials creds = mock(StorageCredentials.class); - String username = "fooUser"; - char[] password = new char[] { 'f', 'o', 'o' }; - when(creds.getUsername()).thenReturn(username); - when(creds.getPassword()).thenReturn(password); - InOrder inOrder = inOrder(creds); - - AddUserCommand command = new AddUserCommand(null /* unused */); - command.addUser(storage, creds); - - // password should have been zero-filled - assertTrue(Arrays.equals(new char[] { '\0', '\0', '\0' }, password)); - // First username, then password should get called. - inOrder.verify(creds).getUsername(); - inOrder.verify(creds).getPassword(); - } - - /* - * Verifies if the delegate can be retrieved from QueuedStorage since - * AddUserCommand relies on this. In particular the delegate needs to be - * a MongoStorage instance. - */ - @Test - public void verifyGettingDelegateWorks() { - DB db = PowerMockito.mock(DB.class); - CountDownLatch latch = new CountDownLatch(1); - // Delegate must be mongostorage - MongoStorage storage = new MongoStorage(db, latch); - - QueuedStorage qStorage = new QueuedStorage(storage); - AddUserCommand command = new AddUserCommand(null /* unused */); - Storage actual = command.getDelegate(qStorage); - - assertSame(storage, actual); - } -}
--- a/storage/mongo/src/test/java/com/redhat/thermostat/storage/mongodb/internal/BaseAddUserCommandTest.java Thu Jun 04 00:38:59 2015 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,62 +0,0 @@ -/* - * Copyright 2012-2015 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.storage.mongodb.internal; - -import static org.junit.Assert.assertFalse; - -import org.junit.Test; - -import com.redhat.thermostat.common.cli.CommandContext; -import com.redhat.thermostat.common.cli.CommandException; - -public class BaseAddUserCommandTest { - - @Test - public void storageRequiredFalse() { - TestAddUserCommand cmd = new TestAddUserCommand(); - assertFalse(cmd.isStorageRequired()); - } - - private static class TestAddUserCommand extends BaseAddUserCommand { - - @Override - public void run(CommandContext ctx) throws CommandException { - // no-op - } - - } -}
--- a/storage/mongo/src/test/java/com/redhat/thermostat/storage/mongodb/internal/MongoStorageTest.java Thu Jun 04 00:38:59 2015 -0500 +++ b/storage/mongo/src/test/java/com/redhat/thermostat/storage/mongodb/internal/MongoStorageTest.java Tue Jun 23 09:57:32 2015 -0600 @@ -871,48 +871,6 @@ assertFalse(bool2.getValue()); } - /* - * AddUserCommand family use this API. Tests that working - * credentials don't get recreated, since this would fail - * anyway. - */ - @Test - public void verifyExistingUserIsNotAdded() throws Exception { - DB db = PowerMockito.mock(DB.class); - CountDownLatch latch = new CountDownLatch(1); - MongoStorage storage = new MongoStorage(db, latch); - - String username = "testUser"; - char password[] = new char[] { 'f', 'o', 'o' }; - when(db.authenticate(eq(username), eq(password))).thenReturn(true); - - // This should not have called db.addUser() - storage.addUser(username, password); - - verify(db, times(0)).addUser(any(String.class), any(char[].class)); - } - - /* - * AddUserCommand family use this API. Tests that working - * credentials don't get recreated, since this would fail - * anyway. - */ - @Test - public void verifyNotExistingUserAdded() throws Exception { - DB db = PowerMockito.mock(DB.class); - CountDownLatch latch = new CountDownLatch(1); - MongoStorage storage = new MongoStorage(db, latch); - - String username = "testUser"; - char password[] = new char[] { 'f', 'o', 'o' }; - when(db.authenticate(eq(username), eq(password))).thenReturn(false); - - // This should not have called db.addUser() - storage.addUser(username, password); - - verify(db).addUser(eq(username), eq(password)); - } - private static class FakeDataClass implements Pojo {}; }
--- a/system-backend/src/main/java/com/redhat/thermostat/backend/system/DistributionInformation.java Thu Jun 04 00:38:59 2015 -0500 +++ b/system-backend/src/main/java/com/redhat/thermostat/backend/system/DistributionInformation.java Tue Jun 23 09:57:32 2015 -0600 @@ -66,7 +66,13 @@ // package-private for testing static DistributionInformation get(EtcOsRelease etcOsRelease, LsbRelease lsbRelease) { try { - return etcOsRelease.getDistributionInformation(); + DistributionInformation etcOsDistroInfo = etcOsRelease.getDistributionInformation(); + // if both name and version are unknown defer to lsb fallback + if (!DistributionInformation.UNKNOWN_NAME.equals(etcOsDistroInfo.getName()) && + !DistributionInformation.UNKNOWN_VERSION.equals(etcOsDistroInfo.getVersion())) { + return etcOsDistroInfo; + } + logger.log(Level.FINE, "/etc/os-release existing, but does not contain useful info"); } catch (IOException e) { // Log only at level FINE, since we have the LSB fallback logger.log(Level.FINE, "unable to use os-release", e);
--- a/system-backend/src/main/java/com/redhat/thermostat/backend/system/EtcOsRelease.java Thu Jun 04 00:38:59 2015 -0500 +++ b/system-backend/src/main/java/com/redhat/thermostat/backend/system/EtcOsRelease.java Tue Jun 23 09:57:32 2015 -0600 @@ -44,6 +44,7 @@ public class EtcOsRelease implements DistributionInformationSource { + private static final String EMPTY_STRING = ""; private static final String OS_RELEASE = "/etc/os-release"; private final String osReleaseFile; @@ -72,10 +73,15 @@ } public DistributionInformation getFromOsRelease(BufferedReader reader) throws IOException { - String name = "Linux"; String version = DistributionInformation.UNKNOWN_VERSION; + String name = DistributionInformation.UNKNOWN_NAME; String line = null; while ((line = reader.readLine()) != null) { + // skip whitespace only lines + line = line.trim(); + if (line.equals(EMPTY_STRING)) { + continue; + } if (line.matches("^NAME *=.*")) { name = readShellVariable(line); }
--- a/system-backend/src/test/java/com/redhat/thermostat/backend/system/DistributionInformationTest.java Thu Jun 04 00:38:59 2015 -0500 +++ b/system-backend/src/test/java/com/redhat/thermostat/backend/system/DistributionInformationTest.java Tue Jun 23 09:57:32 2015 -0600 @@ -37,7 +37,10 @@ package com.redhat.thermostat.backend.system; import static org.junit.Assert.*; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import java.io.IOException; import java.util.logging.Handler; import java.util.logging.Logger; @@ -115,6 +118,23 @@ assertEquals(DistributionInformation.UNKNOWN_NAME, info.getName()); assertEquals(DistributionInformation.UNKNOWN_VERSION, info.getVersion()); } + + @Test + public void verifyFallbackToLsbWhenEtcOsReturnsUnknown() throws IOException { + EtcOsRelease mockEtcOsRelease = mock(EtcOsRelease.class); + DistributionInformation mockDistro = mock(DistributionInformation.class); + when(mockEtcOsRelease.getDistributionInformation()).thenReturn(mockDistro); + when(mockDistro.getName()).thenReturn(DistributionInformation.UNKNOWN_NAME); + when(mockDistro.getVersion()).thenReturn(DistributionInformation.UNKNOWN_VERSION); + + LsbRelease mockLsbRelease = mock(LsbRelease.class); + DistributionInformation mockLsbDistro = mock(DistributionInformation.class); + when(mockLsbRelease.getDistributionInformation()).thenReturn(mockLsbDistro); + + DistributionInformation info = DistributionInformation.get(mockEtcOsRelease, mockLsbRelease); + assertSame("Expected lsb info to be used since etc returns unknown", + mockLsbDistro, info); + } private void assertTestHandlerRegistered() { assertNotNull(logger);
--- a/system-backend/src/test/java/com/redhat/thermostat/backend/system/EtcOsReleaseTest.java Thu Jun 04 00:38:59 2015 -0500 +++ b/system-backend/src/test/java/com/redhat/thermostat/backend/system/EtcOsReleaseTest.java Tue Jun 23 09:57:32 2015 -0600 @@ -87,6 +87,23 @@ assertEquals("12.1 (Asparagus)", info.getVersion()); } + /** + * DistributionInformation falls back on LSB when /etc/os-release contains + * inconclusive content (empty in this case). It should not return some + * info as "Linux". + * + * @throws IOException + */ + @Test + public void testEmpty() throws IOException { + String output = ""; + BufferedReader reader = new BufferedReader(new StringReader(output)); + + DistributionInformation info = new EtcOsRelease().getFromOsRelease(reader); + assertEquals(DistributionInformation.UNKNOWN_NAME, info.getName()); + assertEquals(DistributionInformation.UNKNOWN_VERSION, info.getVersion()); + } + @Test public void getDistributionInformationThrowsIOExceptionIfFileNotThere() { EtcOsRelease etcOsRelease = new EtcOsRelease(NOT_EXISTING_OS_RELEASE_FILE);
--- a/thread/client-swing/src/test/java/com/redhat/thermostat/thread/client/swing/impl/SwingThreadViewTest.java Thu Jun 04 00:38:59 2015 -0500 +++ b/thread/client-swing/src/test/java/com/redhat/thermostat/thread/client/swing/impl/SwingThreadViewTest.java Tue Jun 23 09:57:32 2015 -0600 @@ -36,6 +36,7 @@ package com.redhat.thermostat.thread.client.swing.impl; +import com.redhat.thermostat.annotations.internal.CacioTest; import com.redhat.thermostat.client.swing.UIDefaults; import com.redhat.thermostat.shared.locale.Translate; import com.redhat.thermostat.thread.client.common.locale.LocaleResources; @@ -61,6 +62,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +@Category(CacioTest.class) @RunWith(CacioFESTRunner.class) public class SwingThreadViewTest {
--- a/vm-classstat/client-swing/src/test/java/com/redhat/thermostat/vm/classstat/client/swing/VmClassStatPanelTest.java Thu Jun 04 00:38:59 2015 -0500 +++ b/vm-classstat/client-swing/src/test/java/com/redhat/thermostat/vm/classstat/client/swing/VmClassStatPanelTest.java Tue Jun 23 09:57:32 2015 -0600 @@ -51,10 +51,13 @@ import org.fest.swing.edt.GuiTask; import org.junit.BeforeClass; import org.junit.Test; +import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; +import com.redhat.thermostat.annotations.internal.CacioTest; import com.redhat.thermostat.storage.model.DiscreteTimeData; +@Category(CacioTest.class) @RunWith(CacioFESTRunner.class) public class VmClassStatPanelTest {
--- a/vm-gc/remote-collector-client-swing/src/test/java/com/redhat/thermostat/gc/remote/client/swing/ToolbarGCButtonTest.java Thu Jun 04 00:38:59 2015 -0500 +++ b/vm-gc/remote-collector-client-swing/src/test/java/com/redhat/thermostat/gc/remote/client/swing/ToolbarGCButtonTest.java Tue Jun 23 09:57:32 2015 -0600 @@ -57,12 +57,15 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; +import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; +import com.redhat.thermostat.annotations.internal.CacioTest; import com.redhat.thermostat.client.swing.components.HeaderPanel; import com.redhat.thermostat.shared.locale.LocalizedString; import com.redhat.thermostat.gc.remote.client.common.RequestGCAction; +@Category(CacioTest.class) @RunWith(CacioFESTRunner.class) public class ToolbarGCButtonTest {
--- a/vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/HeapDetailsSwingTest.java Thu Jun 04 00:38:59 2015 -0500 +++ b/vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/HeapDetailsSwingTest.java Tue Jun 23 09:57:32 2015 -0600 @@ -58,14 +58,14 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; +import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; +import com.redhat.thermostat.annotations.internal.CacioTest; import com.redhat.thermostat.client.swing.EdtHelper; import com.redhat.thermostat.shared.locale.LocalizedString; -import com.redhat.thermostat.vm.heap.analysis.client.swing.internal.HeapDetailsSwing; -import com.redhat.thermostat.vm.heap.analysis.client.swing.internal.HistogramPanel; -import com.redhat.thermostat.vm.heap.analysis.client.swing.internal.ObjectDetailsPanel; +@Category(CacioTest.class) @RunWith(CacioFESTRunner.class) public class HeapDetailsSwingTest {
--- a/vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/HeapDumpListViewTest.java Thu Jun 04 00:38:59 2015 -0500 +++ b/vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/HeapDumpListViewTest.java Tue Jun 23 09:57:32 2015 -0600 @@ -59,8 +59,10 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; +import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; +import com.redhat.thermostat.annotations.internal.CacioTest; import com.redhat.thermostat.common.ActionEvent; import com.redhat.thermostat.common.ActionListener; import com.redhat.thermostat.vm.heap.analysis.client.core.HeapDumpListView; @@ -68,6 +70,7 @@ import net.java.openjdk.cacio.ctc.junit.CacioFESTRunner; +@Category(CacioTest.class) @RunWith(CacioFESTRunner.class) public class HeapDumpListViewTest {
--- a/vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/HeapSwingViewTest.java Thu Jun 04 00:38:59 2015 -0500 +++ b/vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/HeapSwingViewTest.java Tue Jun 23 09:57:32 2015 -0600 @@ -48,7 +48,6 @@ import net.java.openjdk.cacio.ctc.junit.CacioFESTRunner; import org.fest.swing.annotation.GUITest; -import org.fest.swing.core.Robot; import org.fest.swing.edt.FailOnThreadViolationRepaintManager; import org.fest.swing.edt.GuiActionRunner; import org.fest.swing.edt.GuiTask; @@ -65,8 +64,10 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; +import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; +import com.redhat.thermostat.annotations.internal.CacioTest; import com.redhat.thermostat.client.swing.components.OverlayPanel; import com.redhat.thermostat.common.ActionEvent; import com.redhat.thermostat.common.ActionListener; @@ -79,6 +80,7 @@ import com.redhat.thermostat.vm.heap.analysis.common.HeapDump; import com.redhat.thermostat.vm.heap.analysis.common.model.HeapInfo; +@Category(CacioTest.class) @RunWith(CacioFESTRunner.class) public class HeapSwingViewTest {
--- a/vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/ObjectDetailsPanelTest.java Thu Jun 04 00:38:59 2015 -0500 +++ b/vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/ObjectDetailsPanelTest.java Tue Jun 23 09:57:32 2015 -0600 @@ -64,17 +64,19 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; +import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; +import com.redhat.thermostat.annotations.internal.CacioTest; import com.redhat.thermostat.client.swing.components.SearchField; import com.redhat.thermostat.common.ActionEvent; import com.redhat.thermostat.common.ActionListener; import com.redhat.thermostat.vm.heap.analysis.client.core.HeapObjectUI; import com.redhat.thermostat.vm.heap.analysis.client.core.ObjectDetailsView.ObjectAction; -import com.redhat.thermostat.vm.heap.analysis.client.swing.internal.ObjectDetailsPanel; import com.sun.tools.hat.internal.model.JavaClass; import com.sun.tools.hat.internal.model.JavaHeapObject; +@Category(CacioTest.class) @RunWith(CacioFESTRunner.class) public class ObjectDetailsPanelTest {
--- a/vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/ObjectRootsFrameTest.java Thu Jun 04 00:38:59 2015 -0500 +++ b/vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/ObjectRootsFrameTest.java Tue Jun 23 09:57:32 2015 -0600 @@ -60,16 +60,18 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; +import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; +import com.redhat.thermostat.annotations.internal.CacioTest; import com.redhat.thermostat.common.ActionEvent; import com.redhat.thermostat.common.ActionListener; import com.redhat.thermostat.vm.heap.analysis.client.core.HeapObjectUI; import com.redhat.thermostat.vm.heap.analysis.client.core.ObjectRootsView; import com.redhat.thermostat.vm.heap.analysis.client.core.ObjectRootsView.Action; -import com.redhat.thermostat.vm.heap.analysis.client.swing.internal.ObjectRootsFrame; +@Category(CacioTest.class) @RunWith(CacioFESTRunner.class) public class ObjectRootsFrameTest {
--- a/vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/stats/OverlayComponentTest.java Thu Jun 04 00:38:59 2015 -0500 +++ b/vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/stats/OverlayComponentTest.java Tue Jun 23 09:57:32 2015 -0600 @@ -60,10 +60,13 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; +import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; +import com.redhat.thermostat.annotations.internal.CacioTest; import com.redhat.thermostat.vm.heap.analysis.common.HeapDump; +@Category(CacioTest.class) @RunWith(CacioFESTRunner.class) public class OverlayComponentTest {
--- a/vm-jmx/client-swing/src/test/java/com/redhat/thermostat/vm/jmx/client/swing/internal/JmxNotificationsSwingViewProviderTest.java Thu Jun 04 00:38:59 2015 -0500 +++ b/vm-jmx/client-swing/src/test/java/com/redhat/thermostat/vm/jmx/client/swing/internal/JmxNotificationsSwingViewProviderTest.java Tue Jun 23 09:57:32 2015 -0600 @@ -39,7 +39,11 @@ import static org.junit.Assert.assertTrue; import org.junit.Test; +import org.junit.experimental.categories.Category; +import com.redhat.thermostat.annotations.internal.CacioTest; + +@Category(CacioTest.class) public class JmxNotificationsSwingViewProviderTest { @Test
--- a/vm-memory/client-swing/src/test/java/com/redhat/thermostat/vm/memory/client/swing/internal/MemoryStatsViewImplTest.java Thu Jun 04 00:38:59 2015 -0500 +++ b/vm-memory/client-swing/src/test/java/com/redhat/thermostat/vm/memory/client/swing/internal/MemoryStatsViewImplTest.java Tue Jun 23 09:57:32 2015 -0600 @@ -54,10 +54,12 @@ import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; +import com.redhat.thermostat.annotations.internal.CacioTest; import com.redhat.thermostat.vm.memory.client.core.MemoryStatsView; import net.java.openjdk.cacio.ctc.junit.CacioFESTRunner; +@Category(CacioTest.class) @RunWith(CacioFESTRunner.class) public class MemoryStatsViewImplTest {
--- a/vm-profiler/jvm-agent/pom.xml Thu Jun 04 00:38:59 2015 -0500 +++ b/vm-profiler/jvm-agent/pom.xml Tue Jun 23 09:57:32 2015 -0600 @@ -96,5 +96,11 @@ <artifactId>asm-all</artifactId> <version>${asm.version}</version> </dependency> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-annotations</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> </dependencies> </project>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/web/server/src/main/java/com/redhat/thermostat/web/server/ConfigurationFinder.java Tue Jun 23 09:57:32 2015 -0600 @@ -0,0 +1,72 @@ +/* + * Copyright 2012-2015 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.web.server; + +import java.io.File; + +import com.redhat.thermostat.shared.config.CommonPaths; + +public class ConfigurationFinder { + + private final CommonPaths paths; + + public ConfigurationFinder(CommonPaths paths) { + this.paths = paths; + } + + /** Finds the best configuration file, accessible to the process */ + public File getConfiguration(String name) { + File systemFile = getConfigurationFile(paths.getSystemConfigurationDirectory(), name); + if (isUsable(systemFile)) { + return systemFile; + } + File userFile = getConfigurationFile(paths.getUserConfigurationDirectory(), name); + if (isUsable(userFile)) { + return userFile; + } + return null; + } + + /** package-private for testing only */ + File getConfigurationFile(File directory, String name) { + return new File(directory, name); + } + + private boolean isUsable(File file) { + return file.isFile() && file.canRead(); + } +}
--- a/web/server/src/main/java/com/redhat/thermostat/web/server/WebStorageEndPoint.java Thu Jun 04 00:38:59 2015 -0500 +++ b/web/server/src/main/java/com/redhat/thermostat/web/server/WebStorageEndPoint.java Tue Jun 23 09:57:32 2015 -0600 @@ -148,6 +148,7 @@ private Storage storage; private Gson gson; private CommonPaths paths; + private ConfigurationFinder finder; public static final String STORAGE_ENDPOINT = "storage.endpoint"; public static final String STORAGE_CLASS = "storage.class"; @@ -167,8 +168,10 @@ } // Package private for testing - WebStorageEndPoint(TimerRegistry timerRegistry) { + WebStorageEndPoint(TimerRegistry timerRegistry, CommonPaths paths, ConfigurationFinder finder) { this.timerRegistry = timerRegistry; + this.paths = paths; + this.finder = finder; } @Override @@ -244,7 +247,7 @@ @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { if (storage == null) { - StorageCredentials creds = getStorageCredentials(paths); + StorageCredentials creds = getStorageCredentials(); // if creds are null there is no point to continue, fail prominently. if (creds == null) { String errorMsg = "No backing storage credentials file (" + CREDENTIALS_FILE + ") available"; @@ -283,44 +286,41 @@ } // package private for testing - StorageCredentials getStorageCredentials(CommonPaths commonPaths) throws IOException { - File systemFile = getStorageCredentialsFile(commonPaths.getSystemConfigurationDirectory()); - if (systemFile.exists() && systemFile.canRead()) { - logger.log(Level.CONFIG, "Loading authentication data from " + systemFile); - return createStorageCredentials(systemFile); + StorageCredentials getStorageCredentials() throws IOException { + File credentialsFile = finder.getConfiguration(CREDENTIALS_FILE); + if (credentialsFile != null) { + logger.log(Level.CONFIG, "Loading authentication data from " + credentialsFile); + return createStorageCredentials(credentialsFile); } else { - File userCredentials = getStorageCredentialsFile(commonPaths.getUserConfigurationDirectory()); - logger.log(Level.CONFIG, "Loading authentication data from " + userCredentials); - if (userCredentials.isFile() && userCredentials.canRead()) { - return createStorageCredentials(userCredentials); - } else { - logger.warning("Unable to read database credentials from " + userCredentials); - return null; - } + logger.warning("Unable to read database credentials."); + return null; } } // package private for testing - File getStorageCredentialsFile(File parent) { - return new File(parent, CREDENTIALS_FILE); - } - - // package private for testing StorageCredentials createStorageCredentials(File underlyingFile) { return new FileBasedStorageCredentials(underlyingFile); } // Side effect: sets this.paths private void sanityCheckNecessaryFiles() { - try { - // Throws config exception if basic sanity checks for - // THERMOSTAT_HOME don't pass. - paths = new CommonPathsImpl(); - } catch (InvalidConfigurationException e) { - logger.log(Level.SEVERE, e.getMessage()); - throw new RuntimeException(e); + if (paths == null) { // for unit tests, we inject this instance + try { + // Throws config exception if basic sanity checks for + // THERMOSTAT_HOME don't pass. + paths = new CommonPathsImpl(); + } catch (InvalidConfigurationException e) { + logger.log(Level.SEVERE, e.getMessage()); + throw new RuntimeException(e); + } } + + if (finder == null) { // for unit tests, we inject this instance + finder = new ConfigurationFinder(paths); + } + File thermostatHomeFile = getThermostatHome(); + String notReadableMsg = " is not readable or does not exist!"; // we need to be able to read ssl config for backing storage // paths got set in isThermostatHomeSet() @@ -331,7 +331,7 @@ logger.log(Level.SEVERE, msg); throw new RuntimeException(msg); } - // Thermost home looks OK and seems usable + // Thermostat home looks OK and seems usable logger.log(Level.FINEST, "THERMOSTAT_HOME == " + thermostatHomeFile.getAbsolutePath()); }
--- a/web/server/src/main/java/com/redhat/thermostat/web/server/auth/spi/PropertiesUserValidator.java Thu Jun 04 00:38:59 2015 -0500 +++ b/web/server/src/main/java/com/redhat/thermostat/web/server/auth/spi/PropertiesUserValidator.java Tue Jun 23 09:57:32 2015 -0600 @@ -48,6 +48,7 @@ import com.redhat.thermostat.common.utils.LoggingUtils; import com.redhat.thermostat.shared.config.InvalidConfigurationException; import com.redhat.thermostat.shared.config.internal.CommonPathsImpl; +import com.redhat.thermostat.web.server.ConfigurationFinder; /** * @@ -63,11 +64,15 @@ PropertiesUserValidator() { // this is the default configuration. it should be overriden through different means // see javadoc of PropertiesUsernameRolesLoginModule - this((new CommonPathsImpl().getSystemConfigurationDirectory() + File.separator + DEFAULT_USERS_FILE)); + this(new ConfigurationFinder(new CommonPathsImpl()).getConfiguration(DEFAULT_USERS_FILE)); } PropertiesUserValidator(String usersFile) { - loadUsers(new File(usersFile)); + this(new File(usersFile)); + } + + PropertiesUserValidator(File file) { + loadUsers(file); } @Override
--- a/web/server/src/main/java/com/redhat/thermostat/web/server/auth/spi/RolesAmender.java Thu Jun 04 00:38:59 2015 -0500 +++ b/web/server/src/main/java/com/redhat/thermostat/web/server/auth/spi/RolesAmender.java Tue Jun 23 09:57:32 2015 -0600 @@ -53,6 +53,7 @@ import com.redhat.thermostat.common.utils.LoggingUtils; import com.redhat.thermostat.shared.config.InvalidConfigurationException; import com.redhat.thermostat.shared.config.internal.CommonPathsImpl; +import com.redhat.thermostat.web.server.ConfigurationFinder; import com.redhat.thermostat.web.server.auth.BasicRole; import com.redhat.thermostat.web.server.auth.RolePrincipal; @@ -75,12 +76,16 @@ // this is the default configuration supplied with thermostat // it should not be overriden by editing this configuraton file // see javadocs of PropertiesUsernameRolesLoginModule - this((new CommonPathsImpl().getSystemConfigurationDirectory() + File.separator + DEFAULT_ROLES_FILE), users); + this(new ConfigurationFinder(new CommonPathsImpl()).getConfiguration(DEFAULT_ROLES_FILE), users); } RolesAmender(String rolesFile, Set<Object> users) { + this(new File(rolesFile), users); + } + + RolesAmender(File rolesFile, Set<Object> users) { this.users = Objects.requireNonNull(users); - loadRoles(new File(rolesFile)); + loadRoles(rolesFile); } /**
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/web/server/src/test/java/com/redhat/thermostat/web/server/ConfigurationFinderTest.java Tue Jun 23 09:57:32 2015 -0600 @@ -0,0 +1,139 @@ +/* + * Copyright 2012-2015 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.web.server; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.redhat.thermostat.shared.config.CommonPaths; + +public class ConfigurationFinderTest { + + private File systemConfigDir = mock(File.class); + private File userConfigDir = mock(File.class); + + private File realFile1; + private File realFile2; + + private CommonPaths paths; + + @Before + public void setUp() throws IOException { + realFile1 = Files.createTempFile("configfinder-unit-test", null).toFile(); + realFile1.createNewFile(); + + realFile2 = Files.createTempFile("configfinder-unit-test", null).toFile(); + realFile2.createNewFile(); + + paths = mock(CommonPaths.class); + when(paths.getSystemConfigurationDirectory()).thenReturn(systemConfigDir); + when(paths.getUserConfigurationDirectory()).thenReturn(userConfigDir); + } + + @After + public void tearDown() { + realFile1.delete(); + realFile2.delete(); + } + + @Test + public void verifyFileFromUserHomeIsUsedIfSystemHomeIsNotUsable() throws Exception { + ConfigurationFinder finder = new ConfigurationFinder(paths) { + @Override + File getConfigurationFile(File directory, String name) { + if (directory == systemConfigDir) { + return new File("/does-not-exist/really-it-doesn't"); + } else if (directory == userConfigDir) { + return realFile1; + } + throw new AssertionError("Unknown test case"); + }; + }; + + File config = finder.getConfiguration("web.auth"); + assertEquals(realFile1, config); + } + + @Test + public void verifyFileFromSystemHomeIsUsedIfBothAreUsable() throws IOException { + final File systemFile = realFile1; + final File userFile = realFile2; + + ConfigurationFinder finder = new ConfigurationFinder(paths) { + @Override + File getConfigurationFile(File directory, String name) { + if (directory == systemConfigDir) { + return systemFile; + } else if (directory == userConfigDir) { + return userFile; + } + throw new AssertionError("Unknown test case"); + }; + }; + + File config = finder.getConfiguration("web.auth"); + assertEquals(systemFile, config); + } + + @Test + public void verifyFileFromSystemHomeIsUsedIfUserHomeNotUsable() throws IOException { + ConfigurationFinder finder = new ConfigurationFinder(paths) { + @Override + File getConfigurationFile(File directory, String name) { + if (directory == systemConfigDir) { + return realFile1; + } else if (directory == userConfigDir) { + return new File("/does-not-exist/really-it-doesn't"); + } + throw new AssertionError("Unknown test case"); + }; + }; + + File config = finder.getConfiguration("web.auth"); + assertEquals(realFile1, config); + } + +}
--- a/web/server/src/test/java/com/redhat/thermostat/web/server/WebStorageEndPointUnitTest.java Thu Jun 04 00:38:59 2015 -0500 +++ b/web/server/src/test/java/com/redhat/thermostat/web/server/WebStorageEndPointUnitTest.java Tue Jun 23 09:57:32 2015 -0600 @@ -248,116 +248,24 @@ @Test public void testShutDownCancelsTimers() { TimerRegistry registry = mock(TimerRegistry.class); - WebStorageEndPoint endpoint = new WebStorageEndPoint(registry); + WebStorageEndPoint endpoint = new WebStorageEndPoint(registry, null, null); endpoint.destroy(); verify(registry).shutDown(); } /** - * Storage credentials should be read from USER_THERMOSTAT_HOME if - * relevant credentials file is not readable or does not exist in - * THERMOSTAT_HOME. - * - * Only the user file is readable. - * - * @throws IOException - */ - @Test - public void canGetUserStorageCredentials() throws IOException { - StorageCredsTestSetupResult setupResult = setupForStorageCredentialsTest(false, true); - WebStorageEndPoint endPoint = setupResult.endpoint; - CommonPaths paths = setupResult.commonPaths; - StorageCredentials creds = endPoint.getStorageCredentials(paths); - assertNotNull(creds); - assertTrue(creds instanceof TestStorageCredentials); - TestStorageCredentials testCreds = (TestStorageCredentials)creds; - assertTrue(setupResult.userCredsFile == testCreds.underlyingFile); - } - - /** - * If Storage credentials file exists and is readable it should - * get used over USER_THERMOSTAT_HOME's version. In this test *both* - * files are present and readable. - * - * @throws IOException - */ - @Test - public void canGetSystemStorageCredentialsBothReadable() throws IOException { - StorageCredsTestSetupResult setupResult = setupForStorageCredentialsTest(true, true); - WebStorageEndPoint endPoint = setupResult.endpoint; - CommonPaths paths = setupResult.commonPaths; - StorageCredentials creds = endPoint.getStorageCredentials(paths); - assertNotNull(creds); - assertTrue(creds instanceof TestStorageCredentials); - TestStorageCredentials testCreds = (TestStorageCredentials)creds; - assertTrue(setupResult.systemCredsFile == testCreds.underlyingFile); - } - - /** - * If Storage credentials file exists and is readable it should - * get used over USER_THERMOSTAT_HOME's version. In this test only the - * system version is readable. - * - * @throws IOException - */ - @Test - public void canGetSystemStorageCredentialsOnlySystemReadable() throws IOException { - StorageCredsTestSetupResult setupResult = setupForStorageCredentialsTest(true, false); - WebStorageEndPoint endPoint = setupResult.endpoint; - CommonPaths paths = setupResult.commonPaths; - StorageCredentials creds = endPoint.getStorageCredentials(paths); - assertNotNull(creds); - assertTrue(creds instanceof TestStorageCredentials); - TestStorageCredentials testCreds = (TestStorageCredentials)creds; - assertTrue(setupResult.systemCredsFile == testCreds.underlyingFile); - } - - private StorageCredsTestSetupResult setupForStorageCredentialsTest(boolean systemCanRead, boolean userCanRead) { - final File systemCredsFile = mock(File.class); - when(systemCredsFile.canRead()).thenReturn(systemCanRead); - when(systemCredsFile.exists()).thenReturn(true); - when(systemCredsFile.getPath()).thenReturn("system_creds_file"); - final File systemCredsDirectory = mock(File.class); - final File userCredsDirectory = mock(File.class); - final File userCredsFile = mock(File.class); - when(userCredsFile.canRead()).thenReturn(userCanRead); - when(userCredsFile.isFile()).thenReturn(true); - when(userCredsFile.getPath()).thenReturn("user_creds_file"); - CommonPaths paths = mock(CommonPaths.class); - when(paths.getSystemConfigurationDirectory()).thenReturn(systemCredsDirectory); - when(paths.getUserConfigurationDirectory()).thenReturn(userCredsDirectory); - @SuppressWarnings("serial") - WebStorageEndPoint endpoint = new WebStorageEndPoint() { - @Override - File getStorageCredentialsFile(File parent) { - // intentionally compare exact instances - if (systemCredsDirectory == parent) { - return systemCredsFile; - } - // intentionally compare exact instances - if (userCredsDirectory == parent) { - return userCredsFile; - } - return null; - } - - @Override - StorageCredentials createStorageCredentials(File underlyingFile) { - return new TestStorageCredentials(underlyingFile); - } - }; - return new StorageCredsTestSetupResult(endpoint, paths, systemCredsFile, userCredsFile); - } - - /** - * If neither storage credentials exist (none in USER_THERMOSTAT_HOME *and* - * in THERMOSTAT_HOME) then null is expected to get returned. - * @throws IOException + * If storage credentials are not found then null is expected to get returned. */ @Test public void storageCredentialsNull() throws IOException { - StorageCredsTestSetupResult setupResult = setupForStorageCredentialsTest(false, false); - StorageCredentials creds = setupResult.endpoint.getStorageCredentials(setupResult.commonPaths); + CommonPaths paths = mock(CommonPaths.class); + TimerRegistry registry = mock(TimerRegistry.class); + ConfigurationFinder finder = mock(ConfigurationFinder.class); + when(finder.getConfiguration("web.auth")).thenReturn(null); + + WebStorageEndPoint endpoint = new WebStorageEndPoint(registry, paths, finder); + StorageCredentials creds = endpoint.getStorageCredentials(); + assertNull(creds); } @@ -387,42 +295,4 @@ } } - private static class StorageCredsTestSetupResult { - private WebStorageEndPoint endpoint; - private CommonPaths commonPaths; - private File systemCredsFile; - private File userCredsFile; - - private StorageCredsTestSetupResult(WebStorageEndPoint endpoint, - CommonPaths commonPaths, - File systemCredsFile, - File userCredsFile) { - this.endpoint = endpoint; - this.commonPaths = commonPaths; - this.systemCredsFile = systemCredsFile; - this.userCredsFile = userCredsFile; - } - - } - - private static class TestStorageCredentials implements StorageCredentials { - - private File underlyingFile; - - private TestStorageCredentials(File underlyingFile) { - this.underlyingFile = underlyingFile; - } - - @Override - public String getUsername() { - throw new AssertionError("not implemented"); - } - - @Override - public char[] getPassword() { - throw new AssertionError("not implemented"); - } - - } - }