View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.net.ftp.parser;
18  
19  import java.text.SimpleDateFormat;
20  import java.time.Instant;
21  import java.util.Calendar;
22  import java.util.Locale;
23  
24  import org.apache.commons.net.ftp.FTPFile;
25  import org.apache.commons.net.ftp.FTPFileEntryParser;
26  
27  import junit.framework.TestCase;
28  
29  /**
30   */
31  public abstract class AbstractFTPParseTest extends TestCase {
32      // associate Calendar unit ints with a readable string
33      // MUST be listed least significant first, as the routine needs to
34      // find the previous - less significant - entry
35      protected enum CalendarUnit {
36          MILLISECOND(Calendar.MILLISECOND), SECOND(Calendar.SECOND), MINUTE(Calendar.MINUTE), HOUR_OF_DAY(Calendar.HOUR_OF_DAY),
37          DAY_OF_MONTH(Calendar.DAY_OF_MONTH), MONTH(Calendar.MONTH), YEAR(Calendar.YEAR);
38  
39          final int unit;
40  
41          CalendarUnit(final int calUnit) {
42              unit = calUnit;
43          }
44      }
45  
46      private FTPFileEntryParser parser;
47  
48      protected SimpleDateFormat df;
49  
50      /**
51       * @see junit.framework.TestCase#TestCase(String)
52       */
53      public AbstractFTPParseTest(final String name) {
54          super(name);
55      }
56  
57      /**
58       * during processing you could hook here to do additional tests
59       *
60       * @param test raw entry
61       * @param f    parsed entry
62       */
63      protected void doAdditionalBadTests(final String test, final FTPFile f) {
64      }
65  
66      /**
67       * during processing you could hook here to do additional tests
68       *
69       * @param test raw entry
70       * @param f    parsed entry
71       */
72      protected void doAdditionalGoodTests(final String test, final FTPFile f) {
73      }
74  
75      /**
76       * Method getBadListing. Implementors must provide a listing that contains failures.
77       *
78       * @return String[]
79       */
80      protected abstract String[] getBadListing();
81  
82      /**
83       * Method getGoodListing. Implementors must provide a listing that passes.
84       *
85       * @return String[]
86       */
87      protected abstract String[] getGoodListing();
88  
89      /**
90       * Method getParser. Provide the parser to use for testing.
91       *
92       * @return FTPFileEntryParser
93       */
94      protected abstract FTPFileEntryParser getParser();
95  
96      /**
97       * Check if FTPFile entry parsing failed; i.e. if entry is null or date is null.
98       *
99       * @param f FTPFile entry - may be null
100      * @return null if f is null or the date is null
101      */
102     protected FTPFile nullFileOrNullDate(final FTPFile f) {
103         if (f == null) {
104             return null;
105         }
106         if (f.getTimestamp() == null) {
107             return null;
108         }
109         return f;
110     }
111 
112     @Override
113     protected void setUp() throws Exception {
114         super.setUp();
115         parser = getParser();
116         df = new SimpleDateFormat("EEE MMM dd HH:mm:ss yyyy", Locale.US);
117     }
118 
119     public void testBadListing() {
120 
121         final String[] badsamples = getBadListing();
122         for (final String test : badsamples) {
123 
124             final FTPFile f = parser.parseFTPEntry(test);
125             assertNull("Should have Failed to parse <" + test + ">", nullFileOrNullDate(f));
126 
127             doAdditionalBadTests(test, f);
128         }
129     }
130 
131     // Force subclasses to test precision
132     public abstract void testDefaultPrecision();
133 
134     public void testGoodListing() {
135 
136         final String[] goodsamples = getGoodListing();
137         for (final String test : goodsamples) {
138 
139             final FTPFile f = parser.parseFTPEntry(test);
140             assertNotNull("Failed to parse " + test, f);
141 
142             doAdditionalGoodTests(test, f);
143         }
144     }
145 
146     /**
147      * Method testParseFieldsOnDirectory. Provide a test to show that fields on a directory entry are parsed correctly.
148      *
149      * @throws Exception on error
150      */
151     public abstract void testParseFieldsOnDirectory() throws Exception;
152 
153     /**
154      * Method testParseFieldsOnFile. Provide a test to show that fields on a file entry are parsed correctly.
155      *
156      * @throws Exception on error
157      */
158     public abstract void testParseFieldsOnFile() throws Exception;
159 
160     protected void testPrecision(final String listEntry, final CalendarUnit expectedPrecision) {
161         final FTPFile file = getParser().parseFTPEntry(listEntry);
162         assertNotNull("Could not parse " + listEntry, file);
163         final Calendar stamp = file.getTimestamp();
164         assertNotNull("Failed to parse time in " + listEntry, stamp);
165         final Instant instant = file.getTimestampInstant();
166         assertNotNull("Failed to parse time in " + listEntry, instant);
167         final int ordinal = expectedPrecision.ordinal();
168         final CalendarUnit[] values = CalendarUnit.values();
169         // Check expected unit and all more significant ones are set
170         // This is needed for FTPFile.toFormattedString() to work correctly
171         for (int i = ordinal; i < values.length; i++) {
172             final CalendarUnit unit = values[i];
173             assertTrue("Expected set " + unit + " in " + listEntry, stamp.isSet(unit.unit));
174         }
175         // Check previous entry (if any) is not set
176         // This is also needed for FTPFile.toFormattedString() to work correctly
177         if (ordinal > 0) {
178             final CalendarUnit prevUnit = values[ordinal - 1];
179             assertFalse("Expected not set " + prevUnit + " in " + listEntry, stamp.isSet(prevUnit.unit));
180         }
181     }
182 
183     public abstract void testRecentPrecision();
184 }