changeset 2274:b75660003f22

Ensure non-null note content Reviewed-by: neugens Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2016-April/018579.html
author Andrew Azores <aazores@redhat.com>
date Thu, 21 Apr 2016 11:23:26 -0400
parents 8197dcb387ff
children 135bd0d327cb
files notes/client-cli/src/main/java/com/redhat/thermostat/notes/client/cli/internal/AbstractNotesCommand.java notes/client-cli/src/main/java/com/redhat/thermostat/notes/client/cli/locale/LocaleResources.java notes/client-cli/src/main/resources/com/redhat/thermostat/notes/client/cli/locale/strings.properties notes/client-cli/src/test/java/com/redhat/thermostat/notes/client/cli/internal/AbstractNotesCommandTest.java notes/client-core/src/main/java/com/redhat/thermostat/notes/client/core/NotesController.java notes/client-core/src/test/java/com/redhat/thermostat/notes/client/core/VmNotesControllerTest.java notes/common/src/main/java/com/redhat/thermostat/notes/common/HostNote.java notes/common/src/main/java/com/redhat/thermostat/notes/common/VmNote.java notes/common/src/main/java/com/redhat/thermostat/notes/common/internal/AbstractNote.java notes/common/src/test/java/com/redhat/thermostat/notes/common/HostNoteTest.java notes/common/src/test/java/com/redhat/thermostat/notes/common/VmNoteTest.java notes/common/src/test/java/com/redhat/thermostat/notes/common/internal/AbstractNoteTest.java
diffstat 12 files changed, 667 insertions(+), 110 deletions(-) [+]
line wrap: on
line diff
--- a/notes/client-cli/src/main/java/com/redhat/thermostat/notes/client/cli/internal/AbstractNotesCommand.java	Fri Apr 08 13:18:48 2016 +0200
+++ b/notes/client-cli/src/main/java/com/redhat/thermostat/notes/client/cli/internal/AbstractNotesCommand.java	Thu Apr 21 11:23:26 2016 -0400
@@ -126,15 +126,23 @@
         return args.getArgument(NOTE_ID_ARGUMENT);
     }
 
-    protected static String getNoteContent(Arguments args) {
+    protected static String getNoteContent(Arguments args) throws CommandException {
         if (args.hasArgument(NOTE_CONTENT_ARGUMENT)) {
-            return args.getArgument(NOTE_CONTENT_ARGUMENT);
+            String content = args.getArgument(NOTE_CONTENT_ARGUMENT);
+            if (content == null) {
+                content = "";
+            }
+            return content;
         } else { // assume all non-option arguments are together meant to be the note content
             StringBuilder sb = new StringBuilder();
             for (String word : args.getNonOptionArguments()) {
                 sb.append(word).append(' ');
             }
-            return sb.toString().trim();
+            String content = sb.toString().trim();
+            if (content.isEmpty()) {
+                throw new CommandException(translator.localize(LocaleResources.NOTE_CONTENT_ARG_REQUIRED));
+            }
+            return content;
         }
     }
 
--- a/notes/client-cli/src/main/java/com/redhat/thermostat/notes/client/cli/locale/LocaleResources.java	Fri Apr 08 13:18:48 2016 +0200
+++ b/notes/client-cli/src/main/java/com/redhat/thermostat/notes/client/cli/locale/LocaleResources.java	Thu Apr 21 11:23:26 2016 -0400
@@ -58,6 +58,7 @@
     CONTENT_COLUMN,
 
     TRIMMED_NOTE_CONTENT,
+    NOTE_CONTENT_ARG_REQUIRED,
     NO_SUCH_AGENT_NOTE,
     NO_SUCH_VM_NOTE,
 
--- a/notes/client-cli/src/main/resources/com/redhat/thermostat/notes/client/cli/locale/strings.properties	Fri Apr 08 13:18:48 2016 +0200
+++ b/notes/client-cli/src/main/resources/com/redhat/thermostat/notes/client/cli/locale/strings.properties	Thu Apr 21 11:23:26 2016 -0400
@@ -16,5 +16,6 @@
 CONTENT_COLUMN=content
 
 TRIMMED_NOTE_CONTENT={0}...
+NOTE_CONTENT_ARG_REQUIRED=Note content argument must be provided
 NO_SUCH_VM_NOTE=No Note with ID {0} found for VM {1}
 NO_SUCH_AGENT_NOTE=No Note with ID {0} found for Agent {1}
\ No newline at end of file
--- a/notes/client-cli/src/test/java/com/redhat/thermostat/notes/client/cli/internal/AbstractNotesCommandTest.java	Fri Apr 08 13:18:48 2016 +0200
+++ b/notes/client-cli/src/test/java/com/redhat/thermostat/notes/client/cli/internal/AbstractNotesCommandTest.java	Thu Apr 21 11:23:26 2016 -0400
@@ -304,16 +304,20 @@
     }
 
     @Test
-    public void testGetNoteContentWithNoFlagAndNoNonOptionArgs() {
+    public void testGetNoteContentWithNoFlagAndNoNonOptionArgs() throws CommandException {
         Arguments args = mock(Arguments.class);
         when(args.hasArgument(NotesCommand.NOTE_CONTENT_ARGUMENT)).thenReturn(false);
         when(args.getNonOptionArguments()).thenReturn(Collections.<String>emptyList());
-        String result = AbstractNotesCommand.getNoteContent(args);
-        assertThat(result, is(""));
+        try {
+            AbstractNotesCommand.getNoteContent(args);
+            fail();
+        } catch (CommandException ex) {
+            // pass
+        }
     }
 
     @Test
-    public void testGetNoteContentWithNonOptionArgs() {
+    public void testGetNoteContentWithNonOptionArgs() throws CommandException {
         Arguments args = mock(Arguments.class);
         when(args.hasArgument(NotesCommand.NOTE_CONTENT_ARGUMENT)).thenReturn(false);
         when(args.getNonOptionArguments()).thenReturn(Arrays.asList("this", "is", "a", "note"));
@@ -322,7 +326,7 @@
     }
 
     @Test
-    public void testGetNoteContentWithFlag() {
+    public void testGetNoteContentWithFlag() throws CommandException {
         Arguments args = mock(Arguments.class);
         when(args.hasArgument(NotesCommand.NOTE_CONTENT_ARGUMENT)).thenReturn(true);
         when(args.getArgument(NotesCommand.NOTE_CONTENT_ARGUMENT)).thenReturn("this is a note");
@@ -332,7 +336,7 @@
     }
 
     @Test
-    public void testGetNoteContentWithFlagAndNonOptionArgs() {
+    public void testGetNoteContentWithFlagAndNonOptionArgs() throws CommandException {
         Arguments args = mock(Arguments.class);
         when(args.hasArgument(NotesCommand.NOTE_CONTENT_ARGUMENT)).thenReturn(true);
         when(args.getArgument(NotesCommand.NOTE_CONTENT_ARGUMENT)).thenReturn("this is a note");
@@ -342,7 +346,7 @@
     }
 
     @Test
-    public void testGetNoteContentWithStrangeInput() {
+    public void testGetNoteContentWithStrangeInput() throws CommandException {
         Arguments args = mock(Arguments.class);
         when(args.hasArgument(NotesCommand.NOTE_CONTENT_ARGUMENT)).thenReturn(true);
         when(args.getArgument(NotesCommand.NOTE_CONTENT_ARGUMENT)).thenReturn("this is a note");
@@ -351,6 +355,15 @@
         assertThat(result, is("this is a note"));
     }
 
+    @Test
+    public void testGetNoteContentDoesNotReturnNull() throws CommandException {
+        Arguments args = mock(Arguments.class);
+        when(args.hasArgument(NotesCommand.NOTE_CONTENT_ARGUMENT)).thenReturn(true);
+        when(args.getArgument(NotesCommand.NOTE_CONTENT_ARGUMENT)).thenReturn(null);
+        String result = AbstractNotesCommand.getNoteContent(args);
+        assertThat(result, is(""));
+    }
+
     public void doInvalidAgentIdTest(Arguments args) {
         doInvalidIdTest(args, INVALID_AGENTID_MSG);
     }
--- a/notes/client-core/src/main/java/com/redhat/thermostat/notes/client/core/NotesController.java	Fri Apr 08 13:18:48 2016 +0200
+++ b/notes/client-core/src/main/java/com/redhat/thermostat/notes/client/core/NotesController.java	Thu Apr 21 11:23:26 2016 -0400
@@ -350,6 +350,9 @@
         updatedSet.add(note);
         String oldContent = note.getContent();
         String newContent = view.getContent(noteId);
+        if (newContent == null) {
+            newContent = "";
+        }
         long oldTimestamp = note.getTimeStamp();
         long newTimestamp = view.getTimeStamp(noteId);
         if (!oldContent.equals(newContent)
--- a/notes/client-core/src/test/java/com/redhat/thermostat/notes/client/core/VmNotesControllerTest.java	Fri Apr 08 13:18:48 2016 +0200
+++ b/notes/client-core/src/test/java/com/redhat/thermostat/notes/client/core/VmNotesControllerTest.java	Thu Apr 21 11:23:26 2016 -0400
@@ -81,6 +81,7 @@
         when(hostRef.getAgentId()).thenReturn("foo-agent");
         ref = mock(VmRef.class);
         when(ref.getHostRef()).thenReturn(hostRef);
+        when(ref.getVmId()).thenReturn("vmId");
     }
 
     @Test
--- a/notes/common/src/main/java/com/redhat/thermostat/notes/common/HostNote.java	Fri Apr 08 13:18:48 2016 +0200
+++ b/notes/common/src/main/java/com/redhat/thermostat/notes/common/HostNote.java	Thu Apr 21 11:23:26 2016 -0400
@@ -36,60 +36,13 @@
 
 package com.redhat.thermostat.notes.common;
 
-import java.util.Objects;
-
+import com.redhat.thermostat.notes.common.internal.AbstractNote;
 import com.redhat.thermostat.storage.core.Entity;
-import com.redhat.thermostat.storage.core.Persist;
-import com.redhat.thermostat.storage.model.BasePojo;
-import com.redhat.thermostat.storage.model.TimeStampedPojo;
+
+import java.util.Objects;
 
 @Entity
-public class HostNote extends BasePojo implements TimeStampedPojo, Note {
-
-    /** a GUID */
-    private String id;
-    private long timeStamp;
-    private String content;
-
-    public HostNote() {
-        super(null);
-        this.content = "";
-    }
-
-    @Override
-    @Persist
-    public String getId() {
-        return id;
-    }
-
-    @Persist
-    public void setId(String id) {
-        this.id = id;
-    }
-
-    @Persist
-    @Override
-    public long getTimeStamp() {
-        return timeStamp;
-    }
-
-    @Persist
-    @Override
-    public void setTimeStamp(long timeStamp) {
-        this.timeStamp = timeStamp;
-    }
-
-    @Persist
-    @Override
-    public void setContent(String content) {
-        this.content = content;
-    }
-
-    @Persist
-    @Override
-    public String getContent() {
-        return this.content;
-    }
+public class HostNote extends AbstractNote {
 
     @Override
     public int hashCode() {
@@ -108,7 +61,7 @@
         return super.equals(obj)
                 && Objects.equals(this.id, other.id)
                 && Objects.equals(this.timeStamp, other.timeStamp)
-                && Objects.equals(this.content,  other.content);
+                && Objects.equals(this.content, other.content);
     }
 
 }
--- a/notes/common/src/main/java/com/redhat/thermostat/notes/common/VmNote.java	Fri Apr 08 13:18:48 2016 +0200
+++ b/notes/common/src/main/java/com/redhat/thermostat/notes/common/VmNote.java	Thu Apr 21 11:23:26 2016 -0400
@@ -36,25 +36,22 @@
 
 package com.redhat.thermostat.notes.common;
 
+import com.redhat.thermostat.notes.common.internal.AbstractNote;
+import com.redhat.thermostat.storage.core.Entity;
+import com.redhat.thermostat.storage.core.Persist;
+
 import java.util.Objects;
 
-import com.redhat.thermostat.storage.core.Entity;
-import com.redhat.thermostat.storage.core.Persist;
-import com.redhat.thermostat.storage.model.BasePojo;
-import com.redhat.thermostat.storage.model.TimeStampedPojo;
+import static java.util.Objects.requireNonNull;
 
 @Entity
-public class VmNote extends BasePojo implements TimeStampedPojo, Note {
+public class VmNote extends AbstractNote {
 
-    /** a GUID */
-    private String id;
-    private long timeStamp;
     private String vmId;
-    private String content;
 
     public VmNote() {
-        super(null);
-        this.content = "";
+        super();
+        setVmId("");
     }
 
     @Persist
@@ -64,47 +61,12 @@
 
     @Persist
     public void setVmId(String vmId) {
-        this.vmId = vmId;
-    }
-
-    @Persist
-    @Override
-    public String getId() {
-        return id;
-    }
-
-    @Persist
-    public void setId(String id) {
-        this.id = id;
-    }
-
-    @Persist
-    @Override
-    public long getTimeStamp() {
-        return timeStamp;
-    }
-
-    @Persist
-    @Override
-    public void setTimeStamp(long timeStamp) {
-        this.timeStamp = timeStamp;
-    }
-
-    @Persist
-    @Override
-    public void setContent(String content) {
-        this.content = content;
-    }
-
-    @Persist
-    @Override
-    public String getContent() {
-        return this.content;
+        this.vmId = requireNonNull(vmId);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(getAgentId(), vmId, id);
+        return Objects.hash(getAgentId(), vmId, id, content);
     }
 
     @Override
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/notes/common/src/main/java/com/redhat/thermostat/notes/common/internal/AbstractNote.java	Thu Apr 21 11:23:26 2016 -0400
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2012-2016 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.notes.common.internal;
+
+import com.redhat.thermostat.notes.common.Note;
+import com.redhat.thermostat.storage.core.Persist;
+import com.redhat.thermostat.storage.model.BasePojo;
+import com.redhat.thermostat.storage.model.TimeStampedPojo;
+
+import static java.util.Objects.requireNonNull;
+
+public abstract class AbstractNote extends BasePojo implements TimeStampedPojo, Note {
+
+    protected String id;
+    protected long timeStamp;
+    protected String content;
+
+    protected AbstractNote() {
+        super(null);
+        setId("");
+        setContent("");
+    }
+
+    @Override
+    @Persist
+    public String getId() {
+        return id;
+    }
+
+    @Persist
+    public void setId(String id) {
+        this.id = requireNonNull(id);
+    }
+
+    @Persist
+    @Override
+    public long getTimeStamp() {
+        return timeStamp;
+    }
+
+    @Persist
+    @Override
+    public void setTimeStamp(long timeStamp) {
+        this.timeStamp = timeStamp;
+    }
+
+    @Persist
+    @Override
+    public void setContent(String content) {
+        this.content = requireNonNull(content);
+    }
+
+    @Persist
+    @Override
+    public String getContent() {
+        return this.content;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/notes/common/src/test/java/com/redhat/thermostat/notes/common/HostNoteTest.java	Thu Apr 21 11:23:26 2016 -0400
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2012-2016 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.notes.common;
+
+import com.redhat.thermostat.notes.common.internal.AbstractNoteTest;
+import org.junit.Test;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.not;
+import static org.junit.Assert.assertThat;
+
+public class HostNoteTest extends AbstractNoteTest<HostNote> {
+
+    @Override
+    protected HostNote createNewNote() {
+        return new HostNote();
+    }
+
+    @Test
+    public void testEquals() {
+        HostNote note2 = new HostNote();
+        assertThat(note, is(equalTo(note2)));
+    }
+
+    @Test
+    public void testEquals2() {
+        note.setId("id");
+        note.setTimeStamp(100L);
+        note.setContent("content");
+        HostNote note2 = new HostNote();
+        assertThat(note, is(not(equalTo(note2))));
+    }
+
+    @Test
+    public void testEquals3() {
+        note.setId("id");
+        note.setTimeStamp(100L);
+        note.setContent("content");
+        HostNote note2 = new HostNote();
+        note.setId(note.getId());
+        assertThat(note, is(not(equalTo(note2))));
+    }
+
+    @Test
+    public void testEquals4() {
+        note.setId("id");
+        note.setTimeStamp(100L);
+        note.setContent("content");
+        HostNote note2 = new HostNote();
+        note2.setTimeStamp(note.getTimeStamp());
+        assertThat(note, is(not(equalTo(note2))));
+    }
+
+    @Test
+    public void testEquals5() {
+        note.setId("id");
+        note.setTimeStamp(100L);
+        note.setContent("content");
+        HostNote note2 = new HostNote();
+        note2.setContent(note.getContent());
+        assertThat(note, is(not(equalTo(note2))));
+    }
+
+    @Test
+    public void testEquals6() {
+        note.setId("id");
+        note.setTimeStamp(100L);
+        note.setContent("content");
+        HostNote note2 = new HostNote();
+        note2.setId(note.getId());
+        note2.setTimeStamp(note.getTimeStamp());
+        assertThat(note, is(not(equalTo(note2))));
+    }
+
+    @Test
+    public void testEquals7() {
+        note.setId("id");
+        note.setTimeStamp(100L);
+        note.setContent("content");
+        HostNote note2 = new HostNote();
+        note2.setId(note.getId());
+        note2.setContent(note.getContent());
+        assertThat(note, is(not(equalTo(note2))));
+    }
+
+    @Test
+    public void testEquals8() {
+        note.setId("id");
+        note.setTimeStamp(100L);
+        note.setContent("content");
+        HostNote note2 = new HostNote();
+        note2.setTimeStamp(note.getTimeStamp());
+        note2.setContent(note.getContent());
+        assertThat(note, is(not(equalTo(note2))));
+    }
+
+    @Test
+    public void testEquals9() {
+        note.setId("id");
+        note.setTimeStamp(100L);
+        note.setContent("content");
+        HostNote note2 = new HostNote();
+        note2.setId(note.getId());
+        note2.setTimeStamp(note.getTimeStamp());
+        note2.setContent(note.getContent());
+        assertThat(note, is(equalTo(note2)));
+        assertThat(note.hashCode(), is(note2.hashCode()));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/notes/common/src/test/java/com/redhat/thermostat/notes/common/VmNoteTest.java	Thu Apr 21 11:23:26 2016 -0400
@@ -0,0 +1,270 @@
+/*
+ * Copyright 2012-2016 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.notes.common;
+
+import com.redhat.thermostat.notes.common.internal.AbstractNoteTest;
+import org.junit.Test;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.not;
+import static org.junit.Assert.assertThat;
+
+public class VmNoteTest extends AbstractNoteTest<VmNote> {
+
+    @Override
+    protected VmNote createNewNote() {
+        return new VmNote();
+    }
+
+    @Test
+    public void testInitialVmIdIsEmptyString() {
+        assertThat(note.getVmId(), is(""));
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testNullVmIdNotAccepted() {
+        note.setVmId(null);
+    }
+
+    @Test
+    public void testGetSetVmId() {
+        String vmId = "vmId";
+        note.setVmId(vmId);
+        assertThat(note.getVmId(), is(vmId));
+    }
+
+    @Test
+    public void testEquals() {
+        VmNote note2 = new VmNote();
+        assertThat(note, is(equalTo(note2)));
+    }
+
+    @Test
+    public void testEquals2() {
+        note.setVmId("vmId");
+        note.setId("id");
+        note.setTimeStamp(100L);
+        note.setContent("content");
+        VmNote note2 = new VmNote();
+        assertThat(note, is(not(equalTo(note2))));
+    }
+
+    @Test
+    public void testEquals3() {
+        note.setVmId("vmId");
+        note.setId("id");
+        note.setTimeStamp(100L);
+        note.setContent("content");
+        VmNote note2 = new VmNote();
+        note.setVmId(note.getVmId());
+        assertThat(note, is(not(equalTo(note2))));
+    }
+
+    @Test
+    public void testEquals4() {
+        note.setVmId("vmId");
+        note.setId("id");
+        note.setTimeStamp(100L);
+        note.setContent("content");
+        VmNote note2 = new VmNote();
+        note.setId(note.getId());
+        assertThat(note, is(not(equalTo(note2))));
+    }
+
+    @Test
+    public void testEquals5() {
+        note.setVmId("vmId");
+        note.setId("id");
+        note.setTimeStamp(100L);
+        note.setContent("content");
+        VmNote note2 = new VmNote();
+        note2.setTimeStamp(note.getTimeStamp());
+        assertThat(note, is(not(equalTo(note2))));
+    }
+
+    @Test
+    public void testEquals6() {
+        note.setVmId("vmId");
+        note.setId("id");
+        note.setTimeStamp(100L);
+        note.setContent("content");
+        VmNote note2 = new VmNote();
+        note2.setContent(note.getContent());
+        assertThat(note, is(not(equalTo(note2))));
+    }
+
+    @Test
+    public void testEquals7() {
+        note.setVmId("vmId");
+        note.setId("id");
+        note.setTimeStamp(100L);
+        note.setContent("content");
+        VmNote note2 = new VmNote();
+        note2.setVmId(note.getVmId());
+        note2.setId(note.getId());
+        assertThat(note, is(not(equalTo(note2))));
+    }
+
+    @Test
+    public void testEquals8() {
+        note.setVmId("vmId");
+        note.setId("id");
+        note.setTimeStamp(100L);
+        note.setContent("content");
+        VmNote note2 = new VmNote();
+        note2.setVmId(note.getVmId());
+        note2.setTimeStamp(note.getTimeStamp());
+        assertThat(note, is(not(equalTo(note2))));
+    }
+
+    @Test
+    public void testEquals9() {
+        note.setVmId("vmId");
+        note.setId("id");
+        note.setTimeStamp(100L);
+        note.setContent("content");
+        VmNote note2 = new VmNote();
+        note2.setVmId(note.getVmId());
+        note2.setContent(note.getContent());
+        assertThat(note, is(not(equalTo(note2))));
+    }
+
+    @Test
+    public void testEquals10() {
+        note.setVmId("vmId");
+        note.setId("id");
+        note.setTimeStamp(100L);
+        note.setContent("content");
+        VmNote note2 = new VmNote();
+        note2.setId(note.getId());
+        note2.setTimeStamp(note.getTimeStamp());
+        assertThat(note, is(not(equalTo(note2))));
+    }
+
+    @Test
+    public void testEquals11() {
+        note.setVmId("vmId");
+        note.setId("id");
+        note.setTimeStamp(100L);
+        note.setContent("content");
+        VmNote note2 = new VmNote();
+        note2.setId(note.getId());
+        note2.setContent(note.getContent());
+        assertThat(note, is(not(equalTo(note2))));
+    }
+
+    @Test
+    public void testEquals12() {
+        note.setVmId("vmId");
+        note.setId("id");
+        note.setTimeStamp(100L);
+        note.setContent("content");
+        VmNote note2 = new VmNote();
+        note2.setVmId(note.getVmId());
+        note2.setId(note.getId());
+        note2.setTimeStamp(note.getTimeStamp());
+        assertThat(note, is(not(equalTo(note2))));
+    }
+
+    @Test
+    public void testEquals13() {
+        note.setVmId("vmId");
+        note.setId("id");
+        note.setTimeStamp(100L);
+        note.setContent("content");
+        VmNote note2 = new VmNote();
+        note2.setVmId(note.getVmId());
+        note2.setTimeStamp(note.getTimeStamp());
+        note2.setContent(note.getContent());
+        assertThat(note, is(not(equalTo(note2))));
+    }
+
+    @Test
+    public void testEquals14() {
+        note.setVmId("vmId");
+        note.setId("id");
+        note.setTimeStamp(100L);
+        note.setContent("content");
+        VmNote note2 = new VmNote();
+        note2.setVmId(note.getVmId());
+        note2.setId(note.getId());
+        note2.setContent(note.getContent());
+        assertThat(note, is(not(equalTo(note2))));
+    }
+
+    @Test
+    public void testEquals15() {
+        note.setVmId("vmId");
+        note.setId("id");
+        note.setTimeStamp(100L);
+        note.setContent("content");
+        VmNote note2 = new VmNote();
+        note2.setId(note.getId());
+        note2.setTimeStamp(note.getTimeStamp());
+        note2.setContent(note.getContent());
+        assertThat(note, is(not(equalTo(note2))));
+    }
+
+    @Test
+    public void testEquals16() {
+        note.setVmId("vmId");
+        note.setId("id");
+        note.setTimeStamp(100L);
+        note.setContent("content");
+        VmNote note2 = new VmNote();
+        note2.setTimeStamp(note.getTimeStamp());
+        note2.setContent(note.getContent());
+        assertThat(note, is(not(equalTo(note2))));
+    }
+
+    @Test
+    public void testEquals20() {
+        note.setVmId("vmId");
+        note.setId("id");
+        note.setTimeStamp(100L);
+        note.setContent("content");
+        VmNote note2 = new VmNote();
+        note2.setVmId(note.getVmId());
+        note2.setId(note.getId());
+        note2.setTimeStamp(note.getTimeStamp());
+        note2.setContent(note.getContent());
+        assertThat(note, is(equalTo(note2)));
+        assertThat(note.hashCode(), is(note2.hashCode()));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/notes/common/src/test/java/com/redhat/thermostat/notes/common/internal/AbstractNoteTest.java	Thu Apr 21 11:23:26 2016 -0400
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2012-2016 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.notes.common.internal;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+public class AbstractNoteTest<T extends AbstractNote> {
+
+    protected T note;
+
+    @Before
+    public void setup() {
+        note = createNewNote();
+    }
+
+    protected T createNewNote() {
+        return (T) new TestNote();
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testNullContentNotAccepted() {
+        note.setContent(null);
+    }
+
+    @Test
+    public void testInitialContentIsEmptyString() {
+        assertThat(note.getContent(), is(""));
+    }
+
+    @Test
+    public void testSetGetContent() {
+        String content = "content";
+        note.setContent(content);
+        assertThat(note.getContent(), is(content));
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testNullIdNotAccepted() {
+        note.setId(null);
+    }
+
+    @Test
+    public void testInitialIdIsEmptyString() {
+        assertThat(note.getId(), is(""));
+    }
+
+    @Test
+    public void testSetGetId() {
+        String id = "id";
+        note.setId(id);
+        assertThat(note.getId(), is(id));
+    }
+
+    @Test
+    public void testInitialTimestampIsZero() {
+        assertThat(note.getTimeStamp(), is(0L));
+    }
+
+    @Test
+    public void testSetGetTimestamp() {
+        long timestmap = 100L;
+        note.setTimeStamp(timestmap);
+        assertThat(note.getTimeStamp(), is(timestmap));
+    }
+
+    private static class TestNote extends AbstractNote {
+    }
+
+}