diff --git a/build.gradle b/build.gradle index f2bfcf4f..0072fb6d 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ apply plugin: 'eclipse' apply plugin: 'signing' group = 'org.numenta' -version = '0.6.10' +version = '0.6.11' archivesBaseName = 'htm.java' sourceCompatibility = 1.8 @@ -12,7 +12,7 @@ targetCompatibility = 1.8 jar { manifest { - attributes 'Implementation-Title': 'htm.java', 'Implementation-Version': '0.6.9-SNAPSHOT' + attributes 'Implementation-Title': 'htm.java', 'Implementation-Version': '0.6.11' } } diff --git a/pom.xml b/pom.xml index d1cc2ab1..cfc74f59 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.numenta htm.java - 0.6.10 + 0.6.11 htm.java The Java version of Numenta's HTM technology diff --git a/src/main/java/org/numenta/nupic/network/Layer.java b/src/main/java/org/numenta/nupic/network/Layer.java index 71458b78..e8fa3fb2 100644 --- a/src/main/java/org/numenta/nupic/network/Layer.java +++ b/src/main/java/org/numenta/nupic/network/Layer.java @@ -344,6 +344,14 @@ public Layer postDeSerialize() { public void setNetwork(Network network) { this.parentNetwork = network; } + + /** + * Returns the parent {@link Network} + * @return the parent Network; + */ + public Network getNetwork() { + return this.parentNetwork; + } /** * Creates a new {@code Layer} initialized with the specified algorithmic @@ -415,6 +423,15 @@ public CheckPointOp delegateCheckPointCall() { public void setRegion(Region r) { this.parentRegion = r; } + + /** + * Returns the parent {@link Region} + * + * @return the parent Region + */ + public Region getRegion() { + return this.parentRegion; + } /** * Finalizes the initialization in one method call so that side effect diff --git a/src/test/java/org/numenta/nupic/datagen/ResourceLocatorTest.java b/src/test/java/org/numenta/nupic/datagen/ResourceLocatorTest.java new file mode 100644 index 00000000..525c6bf8 --- /dev/null +++ b/src/test/java/org/numenta/nupic/datagen/ResourceLocatorTest.java @@ -0,0 +1,35 @@ +package org.numenta.nupic.datagen; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; + +import java.net.URI; + +import org.junit.Test; + + +public class ResourceLocatorTest { + + @Test + public void testURICreation() { + try { + ResourceLocator.uri("."); + fail(); + }catch(Exception e) { + assertEquals(IllegalStateException.class, e.getClass()); + assertEquals(java.net.MalformedURLException.class, e.getCause().getClass()); + } + + try { + URI uri = ResourceLocator.uri("file:///."); + assertNotNull(uri); + + assertFalse(uri.isOpaque()); + }catch(Exception e) { + fail(); + } + } + +} diff --git a/src/test/java/org/numenta/nupic/network/LayerTest.java b/src/test/java/org/numenta/nupic/network/LayerTest.java index 80436dea..313aadfe 100644 --- a/src/test/java/org/numenta/nupic/network/LayerTest.java +++ b/src/test/java/org/numenta/nupic/network/LayerTest.java @@ -48,6 +48,7 @@ import org.numenta.nupic.algorithms.TemporalMemory; import org.numenta.nupic.datagen.ResourceLocator; import org.numenta.nupic.encoders.MultiEncoder; +import org.numenta.nupic.model.Connections; import org.numenta.nupic.model.SDR; import org.numenta.nupic.network.Layer.FunctionFactory; import org.numenta.nupic.network.sensor.FileSensor; @@ -111,6 +112,108 @@ public void testMasking() { algo_content_mask ^= Layer.CLA_CLASSIFIER; assertEquals(0, algo_content_mask); } + + @Test + public void callsOnClosedLayer() { + Parameters p = NetworkTestHarness.getParameters().copy(); + p = p.union(NetworkTestHarness.getDayDemoTestEncoderParams()); + p.set(KEY.RANDOM, new UniversalRandom(42)); + + Network n = new Network("AlreadyClosed", p) + .add(Network.createRegion("AlreadyClosed") + .add(Network.createLayer("AlreadyClosed", p))); + + Layer l = n.lookup("AlreadyClosed").lookup("AlreadyClosed"); + l.using(new Connections()); + l.using(p); + + l.close(); + + try { + l.using(new Connections()); + + fail(); // Should fail here, disallowing "using" call on closed layer + }catch(Exception e) { + assertEquals(IllegalStateException.class, e.getClass()); + assertEquals("Layer already \"closed\"", e.getMessage()); + } + + try { + l.using(p); + + fail(); // Should fail here, disallowing "using" call on closed layer + }catch(Exception e) { + assertEquals(IllegalStateException.class, e.getClass()); + assertEquals("Layer already \"closed\"", e.getMessage()); + } + } + + @Test + public void testNoName() { + Parameters p = Parameters.getAllDefaultParameters(); + + try { + new Network("", p) + .add(Network.createRegion("") + .add(Network.createLayer("", p) + .add(Sensor.create( + FileSensor::create, + SensorParams.create( + Keys::path, "", ResourceLocator.path("rec-center-hourly-small.csv")))))); + + fail(); // Fails due to no name... + }catch(Exception e) { + assertEquals(IllegalStateException.class, e.getClass()); + assertEquals("All Networks must have a name. Increases digestion, and overall happiness!", + e.getMessage()); + } + + try { + new Network("Name", p) + .add(Network.createRegion("") + .add(Network.createLayer("", p) + .add(Sensor.create( + FileSensor::create, + SensorParams.create( + Keys::path, "", ResourceLocator.path("rec-center-hourly-small.csv")))))); + + fail(); // Fails due to no name on Region... + }catch(Exception e) { + assertEquals(IllegalArgumentException.class, e.getClass()); + assertEquals("Name may not be null or empty. ...not that anyone here advocates name calling!", + e.getMessage()); + } + } + + @Test + public void testAddSensor() { + Parameters p = NetworkTestHarness.getParameters().copy(); + p = p.union(NetworkTestHarness.getDayDemoTestEncoderParams()); + p.set(KEY.RANDOM, new UniversalRandom(42)); + + try { + PublisherSupplier supplier = PublisherSupplier.builder() + .addHeader("dayOfWeek") + .addHeader("int") + .addHeader("B").build(); + + Network n = new Network("Name", p) + .add(Network.createRegion("Name") + .add(Network.createLayer("Name", p))); + + Layer l = n.lookup("Name").lookup("Name"); + l.add(Sensor.create( + ObservableSensor::create, + SensorParams.create( + Keys::obs, "", supplier))); + + assertEquals(n, l.getNetwork()); + assertTrue(l.getRegion() != null); + + }catch(Exception e) { + e.printStackTrace(); + } + } @Test public void testGetAllValues() { diff --git a/src/test/java/org/numenta/nupic/network/NetworkTest.java b/src/test/java/org/numenta/nupic/network/NetworkTest.java index 0f4d4026..40880cda 100644 --- a/src/test/java/org/numenta/nupic/network/NetworkTest.java +++ b/src/test/java/org/numenta/nupic/network/NetworkTest.java @@ -450,7 +450,11 @@ public void onNext(Inference inf) { }); network.halt(); - try { network.lookup("r1").lookup("1").getLayerThread().join(3000); }catch(Exception e) { e.printStackTrace(); } + try { + network.lookup("r1").lookup("1").getLayerThread().join(3000); + // Add a little more wait time + Thread.sleep(3000); + }catch(Exception e) { e.printStackTrace(); } network.restart(); Publisher newPub = network.getPublisher(); diff --git a/src/test/java/org/numenta/nupic/util/ConditionTest.java b/src/test/java/org/numenta/nupic/util/ConditionTest.java new file mode 100644 index 00000000..17416f87 --- /dev/null +++ b/src/test/java/org/numenta/nupic/util/ConditionTest.java @@ -0,0 +1,18 @@ +package org.numenta.nupic.util; + +import static org.junit.Assert.*; + +import org.junit.Test; + + +public class ConditionTest { + + @Test + public void testRqwAdapterReturnsFalse() { + Condition.Adapter adapter = new Condition.Adapter<>(); + assertFalse(adapter.eval(1.0d)); + assertFalse(adapter.eval(1)); + assertFalse(adapter.eval(new Object())); + } + +}