View Javadoc
1   /*
2    * Copyright 2007, 2008, 2009, 2010 Ange Optimization ApS
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package eu.simuline.octave;
17  
18  import java.io.StringWriter;
19  
20  import static org.junit.Assert.assertEquals;
21  import static org.junit.Assert.assertTrue;
22  import static org.junit.Assert.fail;
23  
24  import org.junit.Ignore;
25  import org.junit.Test;
26  
27  import eu.simuline.octave.exception.OctaveEvalException;
28  import eu.simuline.octave.exception.OctaveIOException;
29  import eu.simuline.octave.exception.OctaveNonrecoverableException;
30  import eu.simuline.octave.exception.OctaveParseException;
31  import eu.simuline.octave.exception.OctaveRecoverableException;
32  import eu.simuline.octave.type.Octave;
33  import eu.simuline.octave.type.OctaveDouble;
34  import eu.simuline.octave.type.OctaveString;
35  
36  /**
37   * Test
38   */
39  public class TestOctaveErrors {
40  
41      /**
42       * Test that error() in octave breaks the engine
43       */
44      @Test public void testError() {
45          final StringWriter stdout = new StringWriter();
46          final StringWriter stderr = new StringWriter();
47          final OctaveEngineFactory octaveEngineFactory = 
48  	    new OctaveEngineFactory();
49          octaveEngineFactory.setErrorWriter(stderr);
50          final OctaveEngine octave = octaveEngineFactory.getScriptEngine();
51          octave.setWriter(stdout);
52          try {
53              octave.unsafeEval("error('test usage of error');");
54              fail("error in octave should cause execute() " + 
55  		 "to throw an exception");
56          } catch (final OctaveIOException e) {
57              assertTrue(OctaveNonrecoverableException.class.isInstance(e));
58              assertTrue(!e.isDestroyed());
59          }
60          assertEquals("", stdout.toString());
61          /*
62           * 2008-05-08, Kim: Does this still fail? I haven't seen this error for a long time
63           * 
64           * 2010-01-10, Kim: I this this error is fixed. It used to fail because output to stderr from octave sometimes
65           * wasn't flushed to Java.
66           */
67          assertEquals("error: test usage of error\n", stderr.toString());
68          try {
69              octave.put("x", Octave.scalar(42));
70              fail("put should fail when the engine is broken");
71          } catch (final OctaveIOException e) {
72              assertTrue(OctaveNonrecoverableException.class.isInstance(e));
73              assertTrue(!e.isDestroyed());
74          }
75          try {
76              octave.close();
77              fail("close should fail when the engine is broken");
78          } catch (final OctaveIOException e) {
79              assertTrue(OctaveNonrecoverableException.class.isInstance(e));
80              assertTrue(!e.isDestroyed());
81          }
82          octave.destroy();
83          try {
84              octave.close();
85              fail("close should fail when the engine is destroyed");
86          } catch (final OctaveIOException e) {
87              assertTrue(OctaveNonrecoverableException.class.isInstance(e));
88              assertTrue(e.isDestroyed());
89          }
90      }
91  
92      /**
93       * Test that error() in try/catch does not break the engine
94       */
95      @Test public void testEvalWithTryCatch() {
96          final StringWriter stdout = new StringWriter();
97          final StringWriter stderr = new StringWriter();
98          final OctaveEngineFactory octaveEngineFactory = new OctaveEngineFactory();
99          octaveEngineFactory.setErrorWriter(stderr);
100         final OctaveEngine octave = octaveEngineFactory.getScriptEngine();
101         octave.setWriter(stdout);
102         octave.eval("" //
103                 + "try\n" //
104                 + "  error('test usage of error');\n" //
105                 + "catch\n" //
106                 + "  javaoctave_asdf_lasterr = lasterr();\n" //
107                 + "end_try_catch\n" //
108                 + "");
109         assertEquals("", stdout.toString());
110         assertEquals("", stderr.toString());
111         final OctaveString lastError = octave.get(OctaveString.class, 
112 						  "javaoctave_asdf_lasterr");
113         octave.eval("clear javaoctave_asdf_lasterr");
114         assertTrue(lastError.getString().contains("test usage of error"));
115         octave.put("x", Octave.scalar(42));
116         octave.close();
117         octave.destroy();
118         try {
119             octave.close();
120             fail("close should fail when the engine is destroyed");
121         } catch (final OctaveIOException e) {
122             assertTrue(OctaveNonrecoverableException.class.isInstance(e));
123             assertTrue(e.isDestroyed());
124         }
125     }
126 
127     /**
128      * Test that shows that try/catch does prevent a syntax error 
129      * from breaking the engine
130      */
131     @Test public void testSyntaxErrorInTryCatch() {
132         final StringWriter stdout = new StringWriter();
133         final StringWriter stderr = new StringWriter();
134         final OctaveEngineFactory octaveEngineFactory = new OctaveEngineFactory();
135         octaveEngineFactory.setErrorWriter(stderr);
136         final OctaveEngine octave = octaveEngineFactory.getScriptEngine();
137         octave.setWriter(stdout);
138         try {
139             octave.unsafeEval("" //
140                     + "try\n" //
141                     + "  x = linspace(0,6.3,10*);\n" //
142                     + "catch\n" //
143                     + "  javaoctave_asdf_lasterr = lasterr()\n" //
144                     + "end_try_catch\n" //
145                     + "");
146             fail();
147         } catch (final OctaveIOException e) {
148             assertTrue(OctaveNonrecoverableException.class.isInstance(e));
149             assertTrue(!e.isDestroyed());
150         }
151         assertEquals("", stdout.toString());
152         assertTrue(stderr.toString().contains("syntax error"));
153         try {
154             octave.put("x", Octave.scalar(42));
155             fail("put should fail when the engine is broken");
156         } catch (final OctaveIOException e) {
157             assertTrue(OctaveNonrecoverableException.class.isInstance(e));
158             assertTrue(!e.isDestroyed());
159         }
160         try {
161             octave.close();
162             fail("close should fail when the engine is broken");
163         } catch (final OctaveIOException e) {
164             assertTrue(OctaveNonrecoverableException.class.isInstance(e));
165             assertTrue(!e.isDestroyed());
166         }
167         octave.destroy();
168         try {
169             octave.close();
170             fail("close should fail when the engine is destroyed");
171         } catch (final OctaveIOException e) {
172             assertTrue(OctaveNonrecoverableException.class.isInstance(e));
173             assertTrue(e.isDestroyed());
174         }
175     }
176 
177     /**
178      * Test that syntax error in eval() does not break the engine
179      */
180     @Test public void testSyntaxErrorInEval() {
181         final StringWriter stdout = new StringWriter();
182         final StringWriter stderr = new StringWriter();
183         final OctaveEngineFactory octaveEngineFactory = new OctaveEngineFactory();
184         octaveEngineFactory.setErrorWriter(stderr);
185         final OctaveEngine octave = octaveEngineFactory.getScriptEngine();
186         octave.setWriter(stdout);
187         octave.put("javaoctave_asdf_eval", new OctaveString("x = linspace(0,6.3,10*);"));
188         octave.eval("eval(javaoctave_asdf_eval, 'javaoctave_asdf_lasterr = lasterr();')");
189         assertEquals("", stdout.toString());
190         assertEquals("", stderr.toString());
191         final OctaveString lastError = octave.get(OctaveString.class, "javaoctave_asdf_lasterr");
192         octave.eval("clear javaoctave_asdf_eval javaoctave_asdf_lasterr");
193         assertTrue(lastError.getString().contains("syntax error"));
194         octave.put("x", Octave.scalar(42));
195         octave.close();
196         octave.destroy();
197         try {
198             octave.close();
199             fail("close should fail when the engine is destroyed");
200         } catch (final OctaveIOException e) {
201             assertTrue(OctaveNonrecoverableException.class.isInstance(e));
202             assertTrue(e.isDestroyed());
203         }
204     }
205 
206     /**
207      * Test that syntax error in safeEval() does not break the engine
208      */
209     @Test public void testSyntaxErrorInSafeEval() {
210         final StringWriter stdout = new StringWriter();
211         final StringWriter stderr = new StringWriter();
212         final OctaveEngineFactory octaveEngineFactory = new OctaveEngineFactory();
213         octaveEngineFactory.setErrorWriter(stderr);
214         final OctaveEngine octave = octaveEngineFactory.getScriptEngine();
215         octave.setWriter(stdout);
216         try {
217             octave.eval("x = linspace(0,6.3,10*);");
218         } catch (final OctaveEvalException e) {
219             assertTrue(OctaveRecoverableException.class.isInstance(e));
220             assertTrue(!e.isDestroyed());
221             assertTrue(e.getMessage().contains("syntax error"));
222         }
223         assertEquals("", stdout.toString());
224         assertEquals("", stderr.toString());
225         octave.put("x", Octave.scalar(42));
226         octave.close();
227         octave.destroy();
228         try {
229             octave.close();
230             fail("close should fail when the engine is destroyed");
231         } catch (final OctaveIOException e) {
232             assertTrue(OctaveNonrecoverableException.class.isInstance(e));
233             assertTrue(e.isDestroyed());
234         }
235     }
236 
237     /** Test */
238     @Test public void testOk() {
239         final OctaveEngine octave = new OctaveEngineFactory().getScriptEngine();
240         octave.eval("ok=1;");
241         octave.close();
242     }
243 
244     /**
245      * Test that when an unknown type is read the OctaveParseException is thrown and the system will still work
246      */
247     @Test public void testParseException() {
248         final OctaveEngine octave = new OctaveEngineFactory().getScriptEngine();
249         octave.put("x", Octave.scalar(1));
250         octave.eval("y = uint16(42);");
251         assertEquals(1, octave.get(OctaveDouble.class, "x").get(1, 1), 0);
252         try {
253             octave.get("y");
254             fail();
255         } catch (final OctaveParseException e) {
256             assertTrue(OctaveRecoverableException.class.isInstance(e));
257         }
258         assertEquals(1, octave.get(OctaveDouble.class, "x").get(1, 1), 0);
259         octave.close();
260     }
261 
262 }