1   /**
2    * Copyright 2010, CSIRO Australia.
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  
17  package au.csiro.netcdf;
18  
19  import java.io.ByteArrayOutputStream;
20  import java.io.File;
21  import java.io.PrintStream;
22  
23  import org.apache.commons.cli.Options;
24  
25  import ucar.nc2.Dimension;
26  import ucar.nc2.NetcdfFile;
27  
28  import au.csiro.netcdf.cli.Command;
29  
30  import junit.framework.TestCase;
31  
32  /**
33   * This class is a unit test suite to verify that the NcDefineDimension command operates correctly.
34   * <p>
35   * Copyright 2010, CSIRO Australia All rights reserved.
36   * 
37   * @author Rita Chen on 19/03/2010
38   * @version $Revision: 78 $ $Date: 2010-07-24 16:23:13 +1000 (Sat, 24 Jul 2010) $
39   */
40  public class TestNcDefineDimension extends TestCase
41  {
42      /**
43       * Used to capture standard output
44       */
45      private final ByteArrayOutputStream outContent = new ByteArrayOutputStream();
46  
47      /**
48       * The name of the command line option used for specifying the output netCDF file name.
49       */
50      private static final String OUTPUT_FILE = "outputFileName";
51  
52      /**
53       * The name of the command line option used for specifying the size of the dimension.
54       */
55      private static final String DIMENSION_SIZE = "dimensionSize";
56  
57      /**
58       * The name of the command line option used for specifying the name of the dimension.
59       */
60      private static final String DIMENSION_NAME = "dimensionName";
61  
62      /**
63       * The name of the netCDF file to write to.
64       */
65      private static final String NC_FILE_NAME = System.getProperty("user.dir") + "\\ABC.nc";
66  
67      /**
68       * The testing value for the dimension option.
69       */
70      private static final String DIM_NAME = "myDimension";
71  
72      /**
73       * The testing value for the dimension size.
74       */
75      private static final String DIM_SIZE = "40907";
76  
77      /**
78       * An instance of the NcDefineDimension command that we want to test.
79       */
80      private Command ncDefineDimension = new NcDefineDimension();
81  
82      /*
83       * (non-Javadoc)
84       * 
85       * @see junit.framework.TestCase#setUp()
86       */
87      @Override
88      protected void setUp() throws Exception
89      {
90          super.setUp();
91  
92          // write standard output to a stream we can examine.
93          System.setOut(new PrintStream(outContent));
94      }
95  
96      /*
97       * (non-Javadoc)
98       * 
99       * @see junit.framework.TestCase#tearDown()
100      */
101     @Override
102     protected void tearDown() throws Exception
103     {
104         super.tearDown();
105 
106         File ncFile = new File(NC_FILE_NAME);
107         if (ncFile.exists())
108         {
109             ncFile.delete();
110         }
111         System.setOut(null);
112     }
113 
114     /**
115      * Test that the commands options are used.
116      */
117     public final void testCreateOptions()
118     {
119         Options options = ncDefineDimension.createOptions();
120 
121         assertTrue("The following option is not recognised by the command: " + OUTPUT_FILE, 
122                 options.hasOption(OUTPUT_FILE));
123         assertTrue("The following option is not recognised by the command: " + DIMENSION_SIZE, 
124                 options.hasOption(DIMENSION_SIZE));
125         assertTrue("The following option is not recognised by the command: " + DIMENSION_NAME, 
126                 options.hasOption(DIMENSION_NAME));
127 
128     }
129 
130     /**
131      * Test a valid command creates a netCDF file with the specified Dimension name and size
132      */
133     public final void testExecuteValidCommand() throws Exception
134     {
135         String[] args = new String[] { ncDefineDimension.getCommandName(), 
136                 "-" + OUTPUT_FILE, NC_FILE_NAME,
137                 "-" + DIMENSION_SIZE, DIM_SIZE, 
138                 "-" + DIMENSION_NAME, DIM_NAME };
139 
140         File ncFile = new File(NC_FILE_NAME);
141         if (ncFile.exists())
142         {
143             ncFile.delete();
144         }
145 
146         ncDefineDimension.execute(args);
147         assertTrue("The nc file was not created: " + NC_FILE_NAME, ncFile.exists());
148 
149         NetcdfFile netcdfFile = NetcdfFile.open(NC_FILE_NAME);
150         Dimension dim = netcdfFile.findDimension(DIM_NAME);
151         assertNotNull("The Dimension was not defined: " + DIM_NAME, dim);
152 
153         assertEquals("The Dimension Size was not defined correctly: " + DIM_NAME, 
154                 Integer.valueOf(dim.getLength()), Integer.valueOf(DIM_SIZE));
155 
156         netcdfFile.close();
157         ncFile.delete();
158     }
159 
160 
161     /**
162      * Test an invalid command
163      */
164 //    public final void testInvalidCommand()
165 //    {
166 //        String[] args = new String[] { ncDefineDimension.getCommandName() + "abc", 
167 //                "-" + OUTPUT_FILE, NC_FILE_NAME,
168 //                "-" + DIMENSION_SIZE, DIM_SIZE, "-" + DIMENSION_NAME, DIM_NAME };
169 //
170 //        String errors = ncDefineDimension.validCommand(args);
171 //        assertTrue("Command without dimensionName option should return an error", !errors.isEmpty());
172 //    }
173 
174     /**
175      * Test required option
176      */
177     public final void testMissingRequiredOption()
178     {
179         String[] args = new String[] { ncDefineDimension.getCommandName(), 
180                 "-" + OUTPUT_FILE, NC_FILE_NAME,
181                 "-" + DIMENSION_SIZE, DIM_SIZE };
182 
183         String errors = ncDefineDimension.validCommand(args);
184         assertTrue("Command without dimensionName option should return an error", !errors.isEmpty());
185 
186     }
187 
188     /**
189      * Test invalid dimension size
190      */
191     public final void testInvalidSizeOption()
192     {
193         String[] args = new String[] { ncDefineDimension.getCommandName(), 
194                 "-" + OUTPUT_FILE, NC_FILE_NAME,
195                 "-" + DIMENSION_SIZE, "abc", 
196                 "-" + DIMENSION_NAME, DIM_NAME };
197 
198         String errors = ncDefineDimension.validCommand(args);
199         assertTrue("Command with character type dimensionSize option should return an error", !errors.isEmpty());
200 
201     }
202     
203     /**
204      * Test missing optional Dimension Size option
205      */
206     public final void testMissingDimSizeOption()
207     {
208         String[] args = new String[] { ncDefineDimension.getCommandName(), 
209                 "-" + OUTPUT_FILE, NC_FILE_NAME,
210                 "-" + DIMENSION_NAME, DIM_NAME};
211 
212         String errors = ncDefineDimension.validCommand(args);
213         assertTrue("Command without dimensionSize option shouldn't return an error", errors.isEmpty());
214 
215     }
216     
217     /**
218      * Test Dimension size is set to unlimited
219      */
220     public final void testUnlimitedDimSize() throws Exception
221     {
222         String[] args = new String[] { ncDefineDimension.getCommandName(), 
223                 "-" + DIMENSION_NAME, DIM_NAME,
224                 "-" + OUTPUT_FILE, NC_FILE_NAME };
225 
226         File ncFile = new File(NC_FILE_NAME);
227         if (ncFile.exists())
228         {
229             ncFile.delete();
230         }
231 
232         ncDefineDimension.execute(args);
233         assertTrue("The nc file was not created: " + NC_FILE_NAME, ncFile.exists());
234 
235         NetcdfFile netcdfFile = NetcdfFile.open(NC_FILE_NAME);
236         Dimension dim = netcdfFile.findDimension(DIM_NAME);
237         assertTrue("The Dimension Size was not unlimited: " + DIM_NAME, (dim.isUnlimited()));
238 
239         netcdfFile.close();
240         ncFile.delete();
241     }
242     
243     /**
244      * Test Dimension size is set to unlimited
245      */
246     public final void testMultipleUnlimitedDimSize() throws Exception
247     {
248         String[] args1 = new String[] { ncDefineDimension.getCommandName(), 
249                 "-" + DIMENSION_NAME, DIM_NAME,
250                 "-" + OUTPUT_FILE, NC_FILE_NAME };
251         
252         String[] args2 = new String[] { ncDefineDimension.getCommandName(), 
253                 "-" + DIMENSION_NAME, DIM_NAME + "2",
254                 "-" + OUTPUT_FILE, NC_FILE_NAME };
255 
256         File ncFile = new File(NC_FILE_NAME);
257         if (ncFile.exists())
258         {
259             ncFile.delete();
260         }
261 
262         ncDefineDimension.execute(args1);
263         assertTrue("The nc file was not created: " + NC_FILE_NAME, ncFile.exists());
264 
265         NetcdfFile netcdfFile = NetcdfFile.open(NC_FILE_NAME);
266         Dimension dim = netcdfFile.findDimension(DIM_NAME);
267         assertTrue("The Dimension Size was not unlimited: " + DIM_NAME, (dim.isUnlimited()));
268 
269         // test adding second unlimited dimension
270         try
271         {
272             ncDefineDimension.execute(args2);
273             fail("adding second unlimited dimension should have failed");
274         }
275         catch (IllegalStateException expected)
276         {
277             //expected.printStackTrace();
278         }
279         
280         netcdfFile.close();
281         ncFile.delete();
282     }
283     
284     /**
285      * Test execute command with an existing file
286      */
287     public final void testExecuteCmdWithExistingFile() throws Exception
288     {
289         String[] args = new String[] { ncDefineDimension.getCommandName(), 
290                 "-" + OUTPUT_FILE, NC_FILE_NAME,
291                 "-" + DIMENSION_SIZE, DIM_SIZE, 
292                 "-" + DIMENSION_NAME, DIM_NAME };
293         
294         String[] argsWithNewDim = new String[] { ncDefineDimension.getCommandName(), 
295                 "-" + OUTPUT_FILE, NC_FILE_NAME,
296                 "-" + DIMENSION_SIZE, DIM_SIZE, 
297                 "-" + DIMENSION_NAME, DIM_NAME + "new" };
298 
299         try
300         {
301             File ncFile = new File(NC_FILE_NAME);
302             if (ncFile.exists())
303             {
304                 ncFile.delete();
305             }
306 
307             ncDefineDimension.execute(args);
308             assertTrue("The nc file was not created: " + NC_FILE_NAME, ncFile.exists());
309             
310             ncDefineDimension.execute(args);
311             // expecting command execution failed due to existing Dimension in file
312             fail("Define same Dimension in an existing file should have failed");
313             
314             ncDefineDimension.execute(argsWithNewDim);
315             assertTrue("The nc file was not created: " + NC_FILE_NAME, ncFile.exists());
316             NetcdfFile netcdfFile = NetcdfFile.open(NC_FILE_NAME);
317             Dimension dim = netcdfFile.findDimension(DIM_NAME);
318             assertNotNull("The Dimension was not defined: " + DIM_NAME, dim);
319             dim = netcdfFile.findDimension(DIM_NAME + "new" );
320             assertNotNull("The Dimension was not defined: " + DIM_NAME + "new", dim);
321             netcdfFile.close();
322         }
323         catch (java.lang.IllegalArgumentException ie)
324         {
325             // expected exception
326         }
327         catch (Exception e)
328         {            
329             throw e;
330         }
331         finally
332         {
333             File ncFile = new File(NC_FILE_NAME);
334             if (ncFile.exists())
335             {
336                 ncFile.delete();
337             }
338         }
339     }
340     
341 }