]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.history/test/org/simantics/history/test/TestHistory.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.history / test / org / simantics / history / test / TestHistory.java
diff --git a/bundles/org.simantics.history/test/org/simantics/history/test/TestHistory.java b/bundles/org.simantics.history/test/org/simantics/history/test/TestHistory.java
new file mode 100644 (file)
index 0000000..78e4bdf
--- /dev/null
@@ -0,0 +1,965 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.history.test;\r
+\r
+import java.io.ByteArrayInputStream;\r
+import java.io.ByteArrayOutputStream;\r
+import java.io.File;\r
+import java.io.IOException;\r
+\r
+import org.junit.After;\r
+import org.junit.Assert;\r
+import org.junit.Before;\r
+import org.junit.Test;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.databoard.Datatypes;\r
+import org.simantics.databoard.accessor.StreamAccessor;\r
+import org.simantics.databoard.accessor.error.AccessorException;\r
+import org.simantics.databoard.binding.Binding;\r
+import org.simantics.databoard.binding.impl.DoubleArrayBinding;\r
+import org.simantics.databoard.type.ArrayType;\r
+import org.simantics.databoard.type.RecordType;\r
+import org.simantics.databoard.util.Bean;\r
+import org.simantics.databoard.util.Limit;\r
+import org.simantics.databoard.util.Range;\r
+import org.simantics.history.Collector;\r
+import org.simantics.history.History;\r
+import org.simantics.history.HistoryException;\r
+import org.simantics.history.HistoryManager;\r
+import org.simantics.history.csv.CSVFormatter;\r
+import org.simantics.history.impl.CollectorImpl;\r
+import org.simantics.history.impl.CollectorState;\r
+import org.simantics.history.util.ProgressMonitor;\r
+import org.simantics.history.util.StreamIterator;\r
+import org.simantics.history.util.Stream;\r
+import org.simantics.history.util.ValueBand;\r
+import org.simantics.history.util.subscription.SubscriptionItem;\r
+import org.simantics.history.util.subscription.SamplingFormat;\r
+import org.simantics.utils.FileUtils;\r
+\r
+public class TestHistory {\r
+       \r
+       static final double NaN = Double.NaN;\r
+       \r
+       // Time            0.0  0.1  0.2  0.3  0.4  0.5  0.6  0.7  0.8  0.9  1.0  1.1  1.2  1.3  1.4\r
+       double[] data1 = { 5.0, 5.0, 5.0, 5.0, 6.0, 6.0, 6.0, 7.0, 8.0, 9.0, NaN,10.0, NaN, NaN, NaN }; \r
+       double[] data2 = { 5.0, 5.0, 5.0, 5.0, 6.0, 6.0, 6.0, 7.0, 8.0, 9.0,10.0, 9.0, 5.0, 4.0, 3.0 };\r
+       byte[] data3 = { 5, 6, 7, 8, 9, 10, 9, 5, 4, 3 };\r
+       \r
+       // Subscription formats\r
+       SamplingFormat simple, allfields, vector, minmax, byteformat, string;\r
+\r
+       // History\r
+       HistoryManager historian;\r
+       File workarea;\r
+       Collector collector;\r
+\r
+       @Before \r
+       public void initSubscriptionFormats()\r
+       {\r
+               simple = new SamplingFormat();\r
+               simple.formatId = "simple";\r
+               RecordType format;\r
+               format = (RecordType) (simple.format = new RecordType());\r
+               format.addComponent("time", Datatypes.FLOAT);\r
+               format.addComponent("endTime", Datatypes.FLOAT);\r
+               format.addComponent("value", Datatypes.DOUBLE );\r
+               format.addComponent("quality", Datatypes.BYTE );\r
+               simple.interval = NaN;\r
+               simple.deadband = NaN;\r
+\r
+               string = new SamplingFormat();\r
+               string.formatId = "string";\r
+               format = (RecordType) (string.format = new RecordType());\r
+               format.addComponent("time", Datatypes.FLOAT);\r
+               format.addComponent("endTime", Datatypes.FLOAT);\r
+               format.addComponent("value", Datatypes.STRING );\r
+               format.addComponent("quality", Datatypes.BYTE );\r
+               string.interval = NaN;\r
+               string.deadband = NaN;\r
+               \r
+               allfields = new SamplingFormat();\r
+               allfields.formatId = "alldata"; \r
+               format = (RecordType) (allfields.format = new RecordType());\r
+               format.addComponent("time", Datatypes.DOUBLE);\r
+               format.addComponent("endTime", Datatypes.DOUBLE);\r
+               format.addComponent("value", Datatypes.DOUBLE );\r
+               format.addComponent("lastValue", Datatypes.DOUBLE);             \r
+               format.addComponent("min", Datatypes.DOUBLE);\r
+               format.addComponent("max", Datatypes.DOUBLE);\r
+               format.addComponent("avg", Datatypes.DOUBLE);\r
+               format.addComponent("median", Datatypes.DOUBLE);\r
+               format.addComponent("quality", Datatypes.BYTE );\r
+               format.addComponent("count", Datatypes.INTEGER);\r
+               allfields.interval = NaN;\r
+               allfields.deadband = NaN;               \r
+\r
+               byteformat = new SamplingFormat();\r
+               byteformat.formatId = "byte";\r
+               byteformat.format = new RecordType();\r
+               format = (RecordType) (byteformat.format = new RecordType());\r
+               format.addComponent("time", Datatypes.DOUBLE);\r
+               format.addComponent("endTime", Datatypes.DOUBLE);\r
+               format.addComponent("value", Datatypes.BYTE);\r
+               format.addComponent("lastValue", Datatypes.BYTE);               \r
+               format.addComponent("min", Datatypes.BYTE);\r
+               format.addComponent("max", Datatypes.BYTE);\r
+               format.addComponent("avg", Datatypes.DOUBLE);\r
+               format.addComponent("median", Datatypes.BYTE);\r
+               format.addComponent("quality", Datatypes.BYTE);\r
+               format.addComponent("count", Datatypes.INTEGER);\r
+               byteformat.interval = NaN;\r
+               byteformat.deadband = NaN;              \r
+               \r
+               vector = new SamplingFormat();\r
+               vector.formatId = "vector";\r
+               vector.format = new RecordType();\r
+               format = (RecordType) (vector.format = new RecordType());\r
+               format.addComponent("time", Datatypes.FLOAT);\r
+               format.addComponent("endTime", Datatypes.FLOAT);\r
+               format.addComponent("value", new ArrayType( Datatypes.DOUBLE, Range.between(Limit.inclusive(3), Limit.inclusive(3)) ));\r
+               format.addComponent("count", Datatypes.INTEGER);\r
+               vector.interval = NaN;\r
+               vector.deadband = NaN;\r
+               \r
+               minmax = new SamplingFormat();\r
+               minmax.formatId = "minmax";\r
+               minmax.format = new RecordType();\r
+               format = (RecordType) (minmax.format = new RecordType());\r
+               format.addComponent("time", Datatypes.FLOAT);\r
+               format.addComponent("endTime", Datatypes.FLOAT);\r
+               format.addComponent("value", Datatypes.DOUBLE );\r
+               format.addComponent("min", Datatypes.DOUBLE );\r
+               format.addComponent("max", Datatypes.DOUBLE );\r
+               minmax.interval = Double.MAX_VALUE;\r
+               minmax.deadband = Double.MAX_VALUE;             \r
+       }\r
+\r
+       @Before\r
+       public void initHistory() {\r
+               CollectorState cs = new CollectorState();\r
+               workarea = FileUtils.createTmpDir();\r
+               System.out.println(workarea);\r
+               historian = History.openFileHistory( workarea );\r
+//             historian = History.createMemoryHistory();\r
+               collector = new CollectorImpl( historian );\r
+       }\r
+       \r
+       @After \r
+       public void uninitHistory() {\r
+               if ( collector != null ) {\r
+                       collector.close();                      \r
+               }\r
+               if ( historian != null ) {\r
+                       historian.close();\r
+               }\r
+               if ( workarea != null) {\r
+                       try {\r
+                               FileUtils.deleteAll(workarea);\r
+                       } catch (IOException e) {\r
+                               e.printStackTrace();\r
+                       }\r
+               }\r
+       }\r
+       \r
+       @Test\r
+       public void testGetModifySubscription() throws Exception\r
+       {\r
+               // 1. Create Item and Collector\r
+               SubscriptionItem hi = SubscriptionItem.createItem("NotMyVariable", "MySubscription", allfields);\r
+               historian.create(hi);\r
+               collector.addItem(hi);\r
+               \r
+               // 2. Get Item\r
+               SubscriptionItem[] items = collector.getItems();                \r
+               Assert.assertEquals(1, items.length);\r
+               SubscriptionItem hii = new SubscriptionItem();\r
+               hii.readAvailableFields( items[0] );\r
+               Assert.assertTrue( hii.equalContents( hi ) );\r
+               \r
+               // 3. Modify Item\r
+               hi.variableId = "MyVariable";\r
+               collector.setItem(hi);\r
+               items = collector.getItems();           \r
+               Assert.assertEquals(1, items.length);\r
+               hii.readAvailableFields( items[0] );\r
+               Assert.assertTrue( hii.equalContents( hi ) );\r
+               \r
+               // 4. Remove & Add\r
+               collector.removeItem(hi.id);\r
+               Assert.assertEquals(0, collector.getItems().length);\r
+               collector.addItem(hi);\r
+               \r
+               // 5. Open & Modify subscription\r
+               collector.beginStep(Bindings.DOUBLE, 5.0);\r
+               hi.interval = 1.2;\r
+               collector.setItem(hi);\r
+               collector.endStep();\r
+               collector.close();\r
+\r
+               // 6. Read from history\r
+               Bean bean = historian.getItem(hi.id);\r
+               hi.interval = 0.0;\r
+               hi.readAvailableFields(bean);\r
+               Assert.assertEquals(1.2, hi.interval, 0.1);\r
+       }\r
+\r
+       @Test\r
+       public void failtestRecreateSubscription() throws HistoryException\r
+       {\r
+               Collector collector2;\r
+               SubscriptionItem hi = SubscriptionItem.createItem("MyVariable", "MySubscription", allfields);\r
+               historian.create(hi);\r
+               \r
+               collector.addItem( hi );\r
+               collector2 = new CollectorImpl( historian );\r
+               collector2.addItem( hi );\r
+               \r
+               try {\r
+                       collector.beginStep(Bindings.DOUBLE, 0.0);\r
+                       collector2.beginStep(Bindings.DOUBLE, 0.0);\r
+                       Assert.fail("Recreate subscription should have failed");\r
+               } catch (HistoryException e) {\r
+                       // expected exception\r
+               }\r
+       \r
+               collector2.close();\r
+       }\r
+\r
+       @Test\r
+       public void failtestReopenStream() throws HistoryException\r
+       {\r
+               // 1. Create history and collector item\r
+               SamplingFormat format = allfields.clone();\r
+               format.deadband = 2.5;\r
+               SubscriptionItem[] his = SubscriptionItem.createItems("MyVariable", "MySubscription", allfields, minmax);\r
+               historian.create(his);\r
+               StreamAccessor sa1=null, sa2=null;\r
+               try {\r
+                       sa1 = historian.openStream(his[0].id, "r");\r
+                       sa2 = historian.openStream(his[1].id, "r");\r
+                       Assert.fail("HistoryManager must not allow to open two handles to same subscription");\r
+               } catch (HistoryException he) {\r
+                       // Expected exception\r
+               }\r
+               try {\r
+               if (sa1!=null)sa1.close();\r
+               if (sa2!=null) sa2.close();\r
+               } catch (AccessorException e) {\r
+                       throw new HistoryException(e);\r
+               }\r
+               \r
+               historian.delete( his[0].id, his[1].id );\r
+       }\r
+       \r
+       @Test\r
+       public void testDisableItem() throws Exception {\r
+               // 1. Create history and collector item\r
+               SamplingFormat format = allfields.clone();\r
+               format.deadband = 2.5;\r
+               SubscriptionItem[] hi = SubscriptionItem.createItems("MyVariable", "MySubscription", allfields, minmax);\r
+               historian.create(hi);           \r
+               \r
+               // 2. Create collector\r
+               collector.addItems(hi);\r
+               \r
+               // Write data\r
+               try {\r
+                       // Simulate\r
+                       double[] data = data1;\r
+                       for (int i=0; i<4; i++) \r
+                       {\r
+                               collector.beginStep(Bindings.DOUBLE, i * 0.1);\r
+                               collector.setValue("MyVariable", Bindings.DOUBLE, data[i]);\r
+                               collector.endStep();\r
+                       }\r
+                       \r
+                       // Disable item\r
+                       hi[0].enabled = false;\r
+                       collector.setItem(hi[0]);\r
+                       for (int i=4; i<12; i++) \r
+                       {\r
+                               collector.beginStep(Bindings.DOUBLE, i * 0.1);\r
+                               collector.setValue("MyVariable", Bindings.DOUBLE, data[i]);\r
+                               collector.endStep();\r
+                       }\r
+                       \r
+                       // Enable item\r
+                       hi[0].enabled = true;\r
+                       collector.setItem(hi[0]);\r
+                       for (int i=12; i<data.length; i++) \r
+                       {\r
+                               collector.beginStep(Bindings.DOUBLE, i * 0.1);\r
+                               collector.setValue("MyVariable", Bindings.DOUBLE, data[i]);\r
+                               collector.endStep();\r
+                       }                       \r
+                       \r
+               } finally {\r
+                       collector.close();\r
+               }\r
+               \r
+               \r
+               // 3. Verify data\r
+               StreamAccessor aa = historian.openStream(hi[0].id, "r");\r
+               try {\r
+                       Binding sampleBinding = Bindings.getBinding( allfields.format );\r
+                       \r
+                       // Read and assert the sample\r
+                       Object sample = aa.get(0, sampleBinding);\r
+                       ValueBand se = new ValueBand( sampleBinding, sample );\r
+                       if (se.supportsNullValue()) { \r
+                               Assert.assertEquals(0.0, (Double) se.getTime( Bindings.DOUBLE ), 0.01);\r
+                               Assert.assertEquals(0.3, (Double) se.getEndTime( Bindings.DOUBLE ), 0.01);\r
+                               Assert.assertFalse( se.isNullValue() );\r
+                               \r
+                               aa.get(1, sampleBinding, sample);\r
+                               Assert.assertEquals(0.4, (Double) se.getTime( Bindings.DOUBLE ), 0.01);\r
+                               Assert.assertEquals(1.1, (Double) se.getEndTime( Bindings.DOUBLE ), 0.01);\r
+                               Assert.assertTrue( se.isNullValue() );\r
+       \r
+                               aa.get(2, sampleBinding, sample);                       \r
+                               Assert.assertEquals(1.2, (Double) se.getTime( Bindings.DOUBLE ), 0.01);\r
+                       }\r
+                       \r
+               } finally {\r
+                       aa.close();\r
+               }\r
+\r
+               // 4. Verify min-max has only 1 sample\r
+               aa = historian.openStream(hi[1].id, "r");\r
+               try {\r
+                       Assert.assertEquals(1, aa.size());\r
+                       Binding sampleBinding = Bindings.getBinding( minmax.format );\r
+                       \r
+                       // Read and assert the sample\r
+                       Object sample = aa.get(0, sampleBinding);\r
+                       ValueBand se = new ValueBand( sampleBinding, sample );\r
+                       Assert.assertEquals(0.0, (Double) se.getTime( Bindings.DOUBLE ), 0.01);\r
+                       Assert.assertEquals(1.4, (Double) se.getEndTime( Bindings.DOUBLE ), 0.01);\r
+                       Assert.assertEquals(5.0, (Double) se.getMin( Bindings.DOUBLE ), 0.01);\r
+                       Assert.assertEquals(10.0, (Double) se.getMax( Bindings.DOUBLE ), 0.01);\r
+                       \r
+               } finally {\r
+                       aa.close();\r
+               }\r
+       }\r
+\r
+       \r
+       @Test\r
+       public void testDeadband() throws Exception {\r
+               // 1. Create history and collector item\r
+               SamplingFormat format = allfields.clone();\r
+               format.deadband = 2.5;\r
+               SubscriptionItem hi = SubscriptionItem.createItem("MyVariable", "MySubscription", format);\r
+               historian.create(hi);           \r
+               \r
+               // 2. Create collector\r
+               collector.addItem(hi);          \r
+               try {\r
+                       // Add values, dt=0.1\r
+                       double[] data = data2;\r
+                       for (int i=0; i<data.length; i++) \r
+                       {\r
+                               collector.beginStep(Bindings.DOUBLE, i * 0.1);\r
+                               collector.setValue("MyVariable", Bindings.DOUBLE, data[i]);\r
+                               collector.endStep();\r
+                       }                       \r
+               } finally {\r
+                       collector.close();\r
+               }\r
+\r
+               // 3. Verify data\r
+               StreamAccessor aa = historian.openStream(hi.id, "r");           \r
+               try {\r
+                       Binding sampleBinding = Bindings.getBinding( format.format );\r
+                       // Read and assert the sample\r
+                       Object sample = aa.get(0, sampleBinding);\r
+                       ValueBand se = new ValueBand( sampleBinding, sample );\r
+                       Assert.assertEquals(0.0, (Double) se.getTime( Bindings.DOUBLE ), 0.01);\r
+                       Assert.assertEquals(0.7, (Double) se.getEndTime( Bindings.DOUBLE ), 0.01);\r
+                       Assert.assertEquals(5.0, (Double) se.getValue( Bindings.DOUBLE ), 0.01);\r
+                       Assert.assertEquals(5.0, (Double) se.getMedian( Bindings.DOUBLE ), 0.01);\r
+                       Assert.assertEquals(5.0, (Double) se.getMin( Bindings.DOUBLE ), 0.01);\r
+                       Assert.assertEquals(7.0, (Double) se.getMax( Bindings.DOUBLE ), 0.01);\r
+                       Assert.assertEquals(8, se.getCount());\r
+                       \r
+                       aa.get(1, sampleBinding, sample);\r
+                       Assert.assertEquals(0.8, (Double) se.getTime( Bindings.DOUBLE ), 0.01);\r
+                       Assert.assertEquals(1.1, (Double) se.getEndTime( Bindings.DOUBLE ), 0.01);\r
+                       Assert.assertEquals(8.0, (Double) se.getValue( Bindings.DOUBLE ), 0.01);\r
+                       Assert.assertEquals(9.0, (Double) se.getMedian( Bindings.DOUBLE ), 0.01);\r
+                       Assert.assertEquals(8.0, (Double) se.getMin( Bindings.DOUBLE ), 0.01);\r
+                       Assert.assertEquals(10.0, (Double) se.getMax( Bindings.DOUBLE ), 0.01);\r
+                       Assert.assertEquals(4, se.getCount());\r
+\r
+                       aa.get(2, sampleBinding, sample);\r
+                       Assert.assertEquals(1.2, (Double) se.getTime( Bindings.DOUBLE ), 0.01);\r
+                       Assert.assertEquals(1.4, (Double) se.getEndTime( Bindings.DOUBLE ), 0.01);                      \r
+                       Assert.assertEquals(5.0, (Double) se.getValue( Bindings.DOUBLE ), 0.01);\r
+                       Assert.assertEquals(4.0, (Double) se.getMedian( Bindings.DOUBLE ), 0.01);\r
+                       Assert.assertEquals(3.0, (Double) se.getMin( Bindings.DOUBLE ), 0.01);\r
+                       Assert.assertEquals(5.0, (Double) se.getMax( Bindings.DOUBLE ), 0.01);\r
+                       Assert.assertEquals(3, se.getCount());\r
+               } finally {\r
+                       aa.close();\r
+               }\r
+       }\r
+\r
+       \r
+       @Test\r
+       public void testMedianAndInterval() throws Exception {\r
+\r
+               // 1. Create history and collector item\r
+               SamplingFormat format = allfields.clone();\r
+               format.interval = 1.0;\r
+               SubscriptionItem hi = SubscriptionItem.createItem("MyVariable", "MySubscription", format);\r
+               historian.create(hi);\r
+               // Create binding for the sample format\r
+               Binding sampleBinding = Bindings.getBinding( format.format );\r
+               \r
+               \r
+               // 2. Create collector\r
+               collector.addItem( hi );\r
+\r
+               // Write data\r
+               try {\r
+                       // Add values, dt=0.1\r
+                       double[] data = data2;\r
+                       for (int i=0; i<data.length; i++) \r
+                       {\r
+                               collector.beginStep(Bindings.DOUBLE, i * 0.1);\r
+                               collector.setValue("MyVariable", Bindings.DOUBLE, data[i]);\r
+                               collector.endStep();\r
+                       }                       \r
+               } finally {\r
+                       collector.close();\r
+               }\r
+               \r
+               // Verify data\r
+               StreamAccessor aa = historian.openStream(hi.id, "r");           \r
+               try {\r
+                       // 10s interval. There should be only one entry\r
+                       Assert.assertEquals(2, aa.size());\r
+                       \r
+                       // Read and assert the sample\r
+                       Object sample = aa.get(0, sampleBinding);\r
+                       ValueBand se = new ValueBand( sampleBinding, sample );\r
+                       Assert.assertEquals(0.0, (Double) se.getTime( Bindings.DOUBLE ), 0.01);\r
+                       Assert.assertEquals(0.9, (Double) se.getEndTime( Bindings.DOUBLE ), 0.01);\r
+                       Assert.assertEquals(6.0, (Double) se.getMedian( Bindings.DOUBLE ), 0.01);\r
+                       \r
+                       aa.get(1, sampleBinding, sample);\r
+                       Assert.assertEquals(1.0, (Double) se.getTime( Bindings.DOUBLE ), 0.01);\r
+                       Assert.assertEquals(1.4, (Double) se.getEndTime( Bindings.DOUBLE ), 0.01);\r
+                       Assert.assertEquals(5.0, (Double) se.getMedian( Bindings.DOUBLE ), 0.01);\r
+                       \r
+               } finally {\r
+                       aa.close();\r
+               }\r
+               \r
+               // Reopen subscription\r
+               // Write data\r
+               collector = new CollectorImpl( historian );                             \r
+               try {\r
+                       // Add values, dt=0.1\r
+                       double[] data = data2;\r
+                       for (int i=0; i<data.length; i++) \r
+                       {\r
+                               collector.beginStep(Bindings.DOUBLE, (i+data.length) * 0.1);\r
+                               collector.setValue("MyVariable", Bindings.DOUBLE, data[i]);\r
+                               collector.endStep();\r
+                       }                       \r
+               } finally {\r
+                       collector.close();\r
+               }\r
+               \r
+               // Verify data\r
+               aa = historian.openStream(hi.id, "r");          \r
+               try {\r
+                       Assert.assertEquals(3, aa.size());\r
+                       \r
+                       // Read and assert the sample\r
+                       Object sample = aa.get(0, sampleBinding);\r
+                       ValueBand se = new ValueBand( sampleBinding, sample );\r
+                       Assert.assertEquals(0.0, (Double) se.getTime( Bindings.DOUBLE ), 0.01);\r
+                       Assert.assertEquals(0.9, (Double) se.getEndTime( Bindings.DOUBLE ), 0.01);\r
+                       Assert.assertEquals(6.0, (Double) se.getMedian( Bindings.DOUBLE ), 0.01);\r
+                       \r
+                       aa.get(1, sampleBinding, sample);\r
+                       Assert.assertEquals(1.0, (Double) se.getTime( Bindings.DOUBLE ), 0.01);\r
+                       Assert.assertEquals(2.1, (Double) se.getEndTime( Bindings.DOUBLE ), 0.01);\r
+                       Assert.assertEquals(5.0, (Double) se.getMedian( Bindings.DOUBLE ), 0.01);\r
+                       \r
+                       aa.get(2, sampleBinding, sample);\r
+                       Assert.assertEquals(2.2, (Double) se.getTime( Bindings.DOUBLE ), 0.01);\r
+                       Assert.assertEquals(2.9, (Double) se.getEndTime( Bindings.DOUBLE ), 0.01);\r
+                       Assert.assertEquals(7.0, (Double) se.getMedian( Bindings.DOUBLE ), 0.01);\r
+                       \r
+               } finally {\r
+                       aa.close();\r
+               }\r
+                               \r
+               historian.delete(hi.id);\r
+       }\r
+\r
+       @Test\r
+       public void testAccessor() throws Exception\r
+       {\r
+               // 1. Create history and collector item\r
+               SamplingFormat format = allfields.clone();\r
+               SubscriptionItem hi = SubscriptionItem.createItem("MyVariable", "MySubscription", format);\r
+               historian.create(hi);\r
+               \r
+               // 2. Create collector\r
+               collector.addItem(hi);\r
+               StreamAccessor aa = historian.openStream(hi.id, "r");           \r
+               try {\r
+                       // Write data\r
+                       double[] data = data2;\r
+                       for (int i=0; i<data.length; i++) \r
+                       {\r
+                               collector.beginStep(Bindings.DOUBLE, i * 0.1);\r
+                               collector.setValue("MyVariable", Bindings.DOUBLE, data[i]);\r
+                               collector.endStep();\r
+                       }                       \r
+\r
+                       // Assert data\r
+                       aa.reset();\r
+                       Assert.assertEquals(10, aa.size());\r
+                       \r
+                       // Write some more\r
+                       for (int i=0; i<data.length; i++) \r
+                       {\r
+                               collector.beginStep(Bindings.DOUBLE, (i + data.length) * 0.1);\r
+                               collector.setValue("MyVariable", Bindings.DOUBLE, data[i]);\r
+                               collector.endStep();\r
+                       }                       \r
+                       \r
+                       // Assert data\r
+                       aa.reset();\r
+                       Assert.assertEquals(20, aa.size());\r
+\r
+                       // Print\r
+                       Binding sampleBinding = Bindings.getBinding( format.format );                   \r
+                       for (int i=0; i<aa.size(); i++) {\r
+                               System.out.println( i+": "+sampleBinding.toString( aa.get(i, sampleBinding) ) );\r
+                       }\r
+                       \r
+                       \r
+               } finally {\r
+                       aa.close();\r
+                       collector.close();\r
+               }\r
+               \r
+       }\r
+\r
+       @Test\r
+       public void testArrayData() throws Exception\r
+       {\r
+               // 1. Create history and collector item\r
+               SamplingFormat format = vector.clone();\r
+               SubscriptionItem hi = SubscriptionItem.createItem("MyVariable", "MySubscription", format);\r
+               historian.create(hi);\r
+               \r
+               // 2. Create collector\r
+               collector.addItem( hi );\r
+               ArrayType vectorType = (ArrayType) ((RecordType)format.format).getComponent("value").type;\r
+               Binding vectorBinding = DoubleArrayBinding.createFrom( vectorType );\r
+               \r
+               // Write data\r
+               int count = 20;\r
+               try {\r
+                       // Simulate\r
+                       double[] vector = new double[] { 1.0, 2.0, 3.0 };\r
+                       \r
+                       for (int i=0; i<count; i++) \r
+                       {\r
+                               collector.beginStep(Bindings.DOUBLE, i * 0.1);\r
+                               \r
+                               vector[0] = i;\r
+                               vector[1] = i*1.5+1;\r
+                               vector[2] = i*-2.4+5;\r
+                               \r
+                               collector.setValue("MyVariable", vectorBinding, vector);\r
+                               collector.endStep();\r
+                       }\r
+                       \r
+               } finally {\r
+                       collector.close();\r
+               }\r
+               \r
+               StreamAccessor aa = historian.openStream(hi.id, "r");\r
+               try {\r
+                       Assert.assertEquals(count, aa.size());\r
+               } finally {\r
+                       aa.close();\r
+               }\r
+               \r
+               historian.delete(hi.id);\r
+       }\r
+\r
+       @Test\r
+       public void testStringData() throws Exception\r
+       {\r
+               // 1. Create history and collector item\r
+               SamplingFormat format = string.clone();\r
+               SubscriptionItem hi = SubscriptionItem.createItem("MyVariable", "MySubscription", format);\r
+               historian.create(hi);\r
+               \r
+               // 2. Create collector\r
+               collector.addItem( hi );\r
+               Binding lineBinding = Bindings.STRING;\r
+               \r
+               // Write data\r
+               int count = 20;\r
+               try {\r
+                       // Simulate\r
+                       for (int i=0; i<count; i++) \r
+                       {\r
+                               collector.beginStep(Bindings.DOUBLE, i * 0.1);\r
+                               collector.setValue("MyVariable", lineBinding, "Line: "+i);\r
+                               collector.endStep();\r
+                       }\r
+                       \r
+               } finally {\r
+                       collector.close();\r
+               }\r
+               \r
+               StreamAccessor aa = historian.openStream(hi.id, "rw");\r
+               try {\r
+                       // Assert data ok\r
+                       Binding beanBinding = Bindings.getBeanBinding(hi.format);\r
+                       Assert.assertEquals(count, aa.size());\r
+                       for (int i=0; i<count; i++) {\r
+                               Bean bean = (Bean) aa.get(i, beanBinding);\r
+                               String line = (String) bean.getField("value");\r
+                               Assert.assertEquals("Line: "+i, line);\r
+                       }\r
+                       \r
+                       // Delete entries\r
+                       aa.remove(10, 2);\r
+                       Assert.assertEquals(count-2, aa.size());\r
+                       for (int i=0; i<10; i++) {\r
+                               Bean bean = (Bean) aa.get(i, beanBinding);\r
+                               String line = (String) bean.getField("value");\r
+                               Assert.assertEquals("Line: "+i, line);\r
+                       }\r
+                       for (int i=10; i<18; i++) {\r
+                               Bean bean = (Bean) aa.get(i, beanBinding);\r
+                               String line = (String) bean.getField("value");\r
+                               Assert.assertEquals("Line: "+(i+2), line);\r
+                       }\r
+                       \r
+               } finally {\r
+                       aa.close();\r
+               }\r
+               \r
+               historian.delete(hi.id);\r
+       }\r
+       \r
+\r
+       @Test\r
+       public void testMinMax() throws Exception {\r
+               // 1. Create history and collector item\r
+               SamplingFormat format = minmax.clone();\r
+               SubscriptionItem hi = SubscriptionItem.createItem("MyVariable", "MySubscription", format);\r
+               historian.create(hi);\r
+               \r
+               // 2. Create collector\r
+               collector.addItem( hi );\r
+\r
+               // 3. Write data\r
+               try {\r
+                       // Add values, dt=0.1\r
+                       double[] data = data1;\r
+                       for (int i=0; i<data.length; i++) \r
+                       {\r
+                               collector.beginStep(Bindings.DOUBLE, i * 0.1);\r
+                               collector.setValue("MyVariable", Bindings.DOUBLE, data[i]);\r
+                               collector.endStep();\r
+                       }                       \r
+               } finally {\r
+                       collector.close();\r
+               }\r
+\r
+               // 3. Verify data\r
+               StreamAccessor aa = historian.openStream(hi.id, "r");\r
+               try {\r
+                       Assert.assertEquals(1, aa.size());\r
+                       Binding sampleBinding = Bindings.getBinding( format.format );\r
+                       // Read and assert the sample\r
+                       Object sample = aa.get(0, sampleBinding);\r
+                       ValueBand se = new ValueBand( sampleBinding, sample );\r
+                       Assert.assertEquals(0.0, (Double) se.getTime( Bindings.DOUBLE ), 0.01);\r
+                       Assert.assertEquals(1.4, (Double) se.getEndTime( Bindings.DOUBLE ), 0.01);\r
+                       Assert.assertEquals(5.0, (Double) se.getMin( Bindings.DOUBLE ), 0.01);\r
+                       Assert.assertEquals(10.0, (Double) se.getMax( Bindings.DOUBLE ), 0.01);\r
+               } finally {\r
+                       aa.close();\r
+               }\r
+               \r
+       }\r
+       \r
+       \r
+       public @Test void testStream() throws Exception {\r
+               // 1. Create history and collector item\r
+               SubscriptionItem hi = SubscriptionItem.createItem("MyVariable", "MySubscription", SamplingFormat.allfields);\r
+               historian.create(hi);\r
+               \r
+               // 2. Create collector\r
+               collector.addItem( hi );\r
+\r
+               // 3. Write and assert data\r
+               StreamAccessor aa = historian.openStream(hi.id, "r");\r
+               try {\r
+                       // Write data\r
+                       double[] data = data2;\r
+                       for (int i=0; i<data.length; i++) \r
+                       {\r
+                               collector.beginStep(Bindings.DOUBLE, i * 0.1);\r
+                               collector.setValue("MyVariable", Bindings.DOUBLE, data[i]);\r
+                               collector.endStep();\r
+                       }                       \r
+                       \r
+                       // Assert data\r
+                       aa.reset();\r
+                       Stream stream = new Stream(aa);\r
+                       \r
+                       Object sample0 = aa.get(0, stream.sampleBinding);\r
+                       Object sample1 = aa.get(1, stream.sampleBinding);\r
+                       Object sample;\r
+                       \r
+                       sample = stream.getLowerSample(Bindings.DOUBLE, 0.0);\r
+                       Assert.assertNull(sample);\r
+                       \r
+                       sample = stream.getLowerSample(Bindings.DOUBLE, 0.05);\r
+                       Assert.assertTrue( stream.sampleBinding.equals(sample, sample0) );\r
+\r
+                       sample = stream.getFloorSample(Bindings.DOUBLE, 0.05);\r
+                       Assert.assertTrue( stream.sampleBinding.equals(sample, sample0) );\r
+\r
+                       sample = stream.getFloorSample(Bindings.DOUBLE, 0.00);\r
+                       Assert.assertTrue( stream.sampleBinding.equals(sample, sample0) );\r
+                       \r
+                       sample = stream.getSample(Bindings.DOUBLE, 0.05);\r
+                       Assert.assertNull(sample);\r
+\r
+                       sample = stream.getSample(Bindings.DOUBLE, 0.00);\r
+                       Assert.assertTrue( stream.sampleBinding.equals(sample, sample0) );\r
+\r
+                       sample = stream.getCeilingSample(Bindings.DOUBLE, -0.10);\r
+                       Assert.assertTrue( stream.sampleBinding.equals(sample, sample0) );\r
+                       \r
+                       sample = stream.getCeilingSample(Bindings.DOUBLE, 0.00);\r
+                       Assert.assertTrue( stream.sampleBinding.equals(sample, sample0) );\r
+\r
+                       sample = stream.getCeilingSample(Bindings.DOUBLE, 0.05);\r
+                       Assert.assertTrue( stream.sampleBinding.equals(sample, sample1) );\r
+\r
+                       sample = stream.getHigherSample(Bindings.DOUBLE, -0.05);\r
+                       Assert.assertTrue( stream.sampleBinding.equals(sample, sample0) );\r
+\r
+                       sample = stream.getHigherSample(Bindings.DOUBLE, 0.00);\r
+                       Assert.assertTrue( stream.sampleBinding.equals(sample, sample1) );\r
+                       \r
+                       sample = stream.getHigherSample(Bindings.DOUBLE, 0.05);\r
+                       Assert.assertTrue( stream.sampleBinding.equals(sample, sample1) );\r
+                       \r
+                       sample = stream.getHigherSample(Bindings.DOUBLE, 1.45);\r
+                       Assert.assertNull( sample );\r
+               } finally {\r
+                       aa.close();\r
+                       collector.close();\r
+               }\r
+       }\r
+       \r
+\r
+       @Test\r
+       public void testByteData() throws Exception {\r
+               // 1. Create stream\r
+               SamplingFormat format = byteformat.clone();\r
+               format.formatId = "test";\r
+               SubscriptionItem hi = SubscriptionItem.createItem("MyVariable", "MySubscription", format);\r
+               historian.create( hi );\r
+               \r
+               // 2. Create collector\r
+               collector.addItem(hi);\r
+\r
+               // 3. Write and assert data\r
+               try {\r
+                       // Write data\r
+                       double[] data = data2;\r
+                       for (int i=0; i<data.length; i++) \r
+                       {\r
+                               collector.beginStep(Bindings.DOUBLE, i * 0.1);\r
+                               collector.setValue("MyVariable", Bindings.DOUBLE, data[i]);\r
+                               collector.endStep();\r
+                       }                       \r
+       \r
+                       // Verify data\r
+                       StreamAccessor aa = historian.openStream(hi.id, "r");                           \r
+                       try {\r
+                               Assert.assertEquals(data3.length, aa.size());\r
+                               Binding sampleBinding = Bindings.getBinding( format.format );\r
+                               // Read and assert the sample\r
+                               Object sample = aa.get(0, sampleBinding);\r
+                               ValueBand se = new ValueBand( sampleBinding, sample );\r
+                               for (int i=0; i<data3.length; i++) {\r
+                                       aa.get(i, sampleBinding, se.getSample());\r
+                                       Assert.assertEquals(data3[i], se.getValue(Bindings.BYTE));\r
+                               }\r
+                       } finally {\r
+                               aa.close();\r
+                       }                       \r
+                       \r
+               } finally {\r
+                       collector.close();\r
+               }\r
+               \r
+       }\r
+       \r
+       @Test\r
+       public void testCSVData() throws Exception {\r
+               SamplingFormat format = simple.clone();\r
+               SubscriptionItem hi = SubscriptionItem.createItem("MyVariable", "MySubscription", format );\r
+               historian.create( hi );\r
+               collector.addItem( hi );\r
+               try {\r
+                       // Write data\r
+                       double[] data = data1;\r
+                       for (int i=0; i<data.length; i++) \r
+                       {\r
+                               collector.beginStep(Bindings.DOUBLE, i * 0.1);\r
+                               collector.setValue("MyVariable", Bindings.DOUBLE, data[i]);\r
+                               collector.endStep();\r
+                       }                       \r
+               } finally {\r
+                       collector.close();\r
+               }\r
+               \r
+               CSVFormatter csv = new CSVFormatter();\r
+               csv.addItem(historian, hi.id, "MyVariable", "MyVariable", "m");\r
+               csv.setTimeRange(0.9, 1.5);\r
+               csv.setTimeStep(0.1);\r
+               StringBuilder sb = new StringBuilder();\r
+//             csv.formulate1(new ProgressMonitor.Stub(), sb);\r
+//             sb.append("\n----\n");\r
+               csv.formulate2(new ProgressMonitor.Stub(), sb);\r
+               System.out.println(sb);\r
+               \r
+       }\r
+       \r
+       @Test\r
+       public void testExport() throws Exception {\r
+               SamplingFormat format = byteformat.clone();\r
+               \r
+               // 2. Write data\r
+               SubscriptionItem hi = SubscriptionItem.createItem("MyVariable", "MySubscription", byteformat );\r
+               historian.create( hi );\r
+               collector.addItem( hi );\r
+               try {\r
+                       // Write data\r
+                       double[] data = data2;\r
+                       for (int i=0; i<data.length; i++) \r
+                       {\r
+                               collector.beginStep(Bindings.DOUBLE, i * 0.1);\r
+                               collector.setValue("MyVariable", Bindings.DOUBLE, data[i]);\r
+                               collector.endStep();\r
+                       }                       \r
+               } finally {\r
+                       collector.close();\r
+               }\r
+               \r
+               // Export data\r
+               ByteArrayOutputStream os = new ByteArrayOutputStream(1024);\r
+               History.exportHistory(historian, Bindings.DOUBLE, -Double.MAX_VALUE, Double.MAX_VALUE, os);\r
+       \r
+               // Create another historian\r
+               HistoryManager historian2 = History.createMemoryHistory();\r
+               ByteArrayInputStream is = new ByteArrayInputStream( os.toByteArray() );\r
+               History.importHistory(historian2, is);\r
+               \r
+               // Verify data\r
+               StreamAccessor aa = historian2.openStream(hi.id, "r");                          \r
+               try {\r
+                       Assert.assertEquals(data3.length, aa.size());\r
+                       Binding sampleBinding = Bindings.getBinding( format.format );\r
+                       // Read and assert the sample\r
+                       Object sample = aa.get(0, sampleBinding);\r
+                       ValueBand se = new ValueBand( sampleBinding, sample );\r
+                       for (int i=0; i<data3.length; i++) {\r
+                               aa.get(i, sampleBinding, se.getSample());\r
+                               Assert.assertEquals(data3[i], se.getValue(Bindings.BYTE));\r
+                       }\r
+               } finally {\r
+                       aa.close();\r
+               }                       \r
+       }\r
+       \r
+       \r
+       @Test\r
+       public void testStreamIterator() throws Exception {\r
+               // 1. Create history and collector item\r
+               SamplingFormat format = allfields.clone();\r
+               format.deadband = 0.05;\r
+               SubscriptionItem hi = SubscriptionItem.createItem("MyVariable", "MySubscription", format);\r
+               historian.create(hi);           \r
+               \r
+               // 2. Create collector\r
+               collector.addItem(hi);          \r
+               try {\r
+                       // Add values, dt=0.1\r
+                       double[] data = data1;\r
+                       for (int i=0; i<data.length; i++) \r
+                       {\r
+                               collector.beginStep(Bindings.DOUBLE, i * 0.1);\r
+                               collector.setValue("MyVariable", Bindings.DOUBLE, data[i]);\r
+                               collector.endStep();\r
+                       }                       \r
+               } finally {\r
+                       collector.close();\r
+               }\r
+\r
+               // 3. Verify data\r
+               StreamAccessor aa = historian.openStream(hi.id, "r");           \r
+               try {\r
+                       StreamIterator si = new StreamIterator( aa );\r
+                       while (si.hasNext()) {\r
+                               si.next();\r
+                               System.out.println( si );\r
+                       }\r
+                       \r
+                       si.gotoTime( -1 );\r
+                       System.out.println( si );\r
+                       \r
+                       si.gotoTime( 0.55 );\r
+                       System.out.println( si );\r
+                       \r
+                       si.proceedToTime( 0.6 );\r
+                       System.out.println( si );\r
+                       \r
+                       si.proceedToTime( 1.11 );\r
+                       System.out.println( si );\r
+\r
+                       si.gotoTime( 1.4 );\r
+                       System.out.println( si );\r
+                       \r
+                       si.gotoTime( 1.5 );\r
+                       System.out.println( si );\r
+                       \r
+                       \r
+               } finally {\r
+                       aa.close();\r
+               }\r
+       }\r
+       \r
+}\r