001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.apache.commons.net.ftp.parser; 018 019 import java.util.Calendar; 020 021 import junit.framework.TestSuite; 022 023 import org.apache.commons.net.ftp.FTPFile; 024 import org.apache.commons.net.ftp.FTPFileEntryParser; 025 026 /** 027 * @author <a href="mailto:scohen@apache.org">Steve Cohen</a> 028 * @version $Id: UnixFTPEntryParserTest.java 629276 2008-02-19 23:31:25Z rwinston $ 029 */ 030 public class UnixFTPEntryParserTest extends FTPParseTestFramework { 031 032 private static final String[] badsamples = { 033 "zrwxr-xr-x 2 root root 4096 Mar 2 15:13 zxbox", 034 "dxrwr-xr-x 2 root root 4096 Aug 24 2001 zxjdbc", 035 "drwxr-xr-x 2 root root 4096 Jam 4 00:03 zziplib", 036 "drwxr-xr-x 2 root 99 4096 Feb 23 30:01 zzplayer", 037 "drwxr-xr-x 2 root root 4096 Aug 36 2001 zztpp", 038 "-rw-r--r-- 1 14 staff 80284 Aug 22 zxJDBC-1.2.3.tar.gz", 039 "-rw-r--r-- 1 14 staff 119:26 Aug 22 2000 zxJDBC-1.2.3.zip", 040 /*"-rw-r--r-- 1 ftp no group 83853 Jan 22 2001 zxJDBC-1.2.4.tar.gz",*/ 041 "-rw-r--r-- 1ftp nogroup 126552 Jan 22 2001 zxJDBC-1.2.4.zip", 042 "-rw-r--r-- 1 root root 190144 2001-04-27 zxJDBC-2.0.1b1.zip", 043 "-rw-r--r-- 1 root root 111325 Apr -7 18:79 zxJDBC-2.0.1b1.tar.gz" }; 044 045 private static final String[] goodsamples = 046 { 047 "-rw-r--r-- 1 500 500 21 Aug 8 14:14 JB3-TES1.gz", 048 "-rwxr-xr-x 2 root root 4096 Mar 2 15:13 zxbox", 049 "drwxr-xr-x 2 root root 4096 Aug 24 2001 zxjdbc", 050 "drwxr-xr-x 2 root root 4096 Jan 4 00:03 zziplib", 051 "drwxr-xr-x 2 root 99 4096 Feb 23 2001 zzplayer", 052 "drwxr-xr-x 2 root root 4096 Aug 6 2001 zztpp", 053 "drwxr-xr-x 1 usernameftp 512 Jan 29 23:32 prog", 054 "lrw-r--r-- 1 14 14 80284 Aug 22 2000 zxJDBC-1.2.3.tar.gz", 055 "frw-r--r-- 1 14 staff 119926 Aug 22 2000 zxJDBC-1.2.3.zip", 056 "crw-r--r-- 1 ftp nogroup 83853 Jan 22 2001 zxJDBC-1.2.4.tar.gz", 057 "brw-r--r-- 1 ftp nogroup 126552 Jan 22 2001 zxJDBC-1.2.4.zip", 058 "-rw-r--r-- 1 root root 111325 Apr 27 2001 zxJDBC-2.0.1b1.tar.gz", 059 "-rw-r--r-- 1 root root 190144 Apr 27 2001 zxJDBC-2.0.1b1.zip", 060 "-rwxr-xr-x 2 500 500 166 Nov 2 2001 73131-testtes1.afp", 061 "-rw-r--r-- 1 500 500 166 Nov 9 2001 73131-testtes1.AFP", 062 "-rw-r--r-- 1 500 500 166 Nov 12 2001 73131-testtes2.afp", 063 "-rw-r--r-- 1 500 500 166 Nov 12 2001 73131-testtes2.AFP", 064 "-rw-r--r-- 1 500 500 2040000 Aug 5 07:35 testRemoteUPCopyNIX", 065 "-rw-r--r-- 1 500 500 2040000 Aug 5 07:31 testRemoteUPDCopyNIX", 066 "-rw-r--r-- 1 500 500 2040000 Aug 5 07:31 testRemoteUPVCopyNIX", 067 "-rw-r--r-T 1 500 500 0 Mar 25 08:20 testSticky", 068 "-rwxr-xr-t 1 500 500 0 Mar 25 08:21 testStickyExec", 069 "-rwSr-Sr-- 1 500 500 0 Mar 25 08:22 testSuid", 070 "-rwsr-sr-- 1 500 500 0 Mar 25 08:23 testSuidExec", 071 "-rwsr-sr-- 1 500 500 0 Mar 25 0:23 testSuidExec2", 072 "drwxrwx---+ 23 500 500 0 Jan 10 13:09 testACL", 073 "-rw-r--r-- 1 1 3518644 May 25 12:12 std", 074 "lrwxrwxrwx 1 neeme neeme 23 Mar 2 18:06 macros -> ./../../global/macros/.", 075 "-rw-r--r-- 1 ftp group with spaces in it as allowed in cygwin see bug 38634 83853 Jan 22 2001 zxJDBC-1.2.4.tar.gz", 076 "crw-r----- 1 root kmem 0, 27 Jan 30 11:42 kmem", //FreeBSD device 077 "crw------- 1 root sys 109,767 Jul 2 2004 pci@1c,600000:devctl" //Solaris device 078 079 080 }; 081 082 /** 083 * @see junit.framework.TestCase#TestCase(String) 084 */ 085 public UnixFTPEntryParserTest(String name) { 086 super(name); 087 } 088 089 /** 090 * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#getBadListing() 091 */ 092 @Override 093 protected String[] getBadListing() { 094 return (badsamples); 095 } 096 097 /** 098 * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#getGoodListing() 099 */ 100 @Override 101 protected String[] getGoodListing() { 102 return (goodsamples); 103 } 104 105 /** 106 */ 107 public void testNumericDateFormat() 108 { 109 String testNumericDF = 110 "-rw-r----- 1 neeme neeme 346 2005-04-08 11:22 services.vsp"; 111 String testNumericDF2 = 112 "lrwxrwxrwx 1 neeme neeme 23 2005-03-02 18:06 macros -> ./../../global/macros/."; 113 114 UnixFTPEntryParser parser = 115 new UnixFTPEntryParser(UnixFTPEntryParser.NUMERIC_DATE_CONFIG); 116 117 FTPFile f = parser.parseFTPEntry(testNumericDF); 118 assertNotNull("Failed to parse " + testNumericDF, 119 f); 120 121 122 Calendar cal = Calendar.getInstance(); 123 cal.clear(); 124 cal.set(Calendar.YEAR, 2005); 125 cal.set(Calendar.MONTH, Calendar.APRIL); 126 127 cal.set(Calendar.DATE, 8); 128 cal.set(Calendar.HOUR_OF_DAY, 11); 129 cal.set(Calendar.MINUTE, 22); 130 assertEquals(cal.getTime(), f.getTimestamp().getTime()); 131 132 FTPFile f2 = parser.parseFTPEntry(testNumericDF2); 133 assertNotNull("Failed to parse " + testNumericDF2, 134 f2); 135 assertEquals("symbolic link", "./../../global/macros/.", f2.getLink()); 136 137 } 138 139 140 /** 141 * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#getParser() 142 */ 143 @Override 144 protected FTPFileEntryParser getParser() { 145 return (new UnixFTPEntryParser()); 146 } 147 148 public void testOwnerNameWithSpaces() { 149 FTPFile f = getParser().parseFTPEntry("drwxr-xr-x 2 john smith group 4096 Mar 2 15:13 zxbox"); 150 assertNotNull(f); 151 assertEquals("john smith", f.getUser()); 152 } 153 154 public void testOwnerANdGroupNameWithSpaces() { 155 FTPFile f = getParser().parseFTPEntry("drwxr-xr-x 2 john smith test group 4096 Mar 2 15:13 zxbox"); 156 assertNotNull(f); 157 assertEquals("john smith", f.getUser()); 158 assertEquals("test group", f.getGroup()); 159 } 160 161 public void testGroupNameWithSpaces() { 162 FTPFile f = getParser().parseFTPEntry("drwx------ 4 maxm Domain Users 512 Oct 2 10:59 .metadata"); 163 assertNotNull(f); 164 assertEquals("maxm", f.getUser()); 165 assertEquals("Domain Users", f.getGroup()); 166 } 167 168 public void testTrailingSpaces() { 169 FTPFile f = getParser().parseFTPEntry("drwxr-xr-x 2 john smith group 4096 Mar 2 15:13 zxbox "); 170 assertNotNull(f); 171 assertEquals(f.getName(), "zxbox "); 172 } 173 174 public void testNameWIthPunctuation() { 175 FTPFile f = getParser().parseFTPEntry("drwx------ 4 maxm Domain Users 512 Oct 2 10:59 abc(test)123.pdf"); 176 assertNotNull(f); 177 assertEquals(f.getName(), "abc(test)123.pdf"); 178 179 } 180 181 /** 182 * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#testParseFieldsOnDirectory() 183 */ 184 @Override 185 public void testParseFieldsOnDirectory() throws Exception { 186 FTPFile f = getParser().parseFTPEntry("drwxr-xr-x 2 user group 4096 Mar 2 15:13 zxbox"); 187 assertNotNull("Could not parse entry.", f); 188 assertTrue("Should have been a directory.", f.isDirectory()); 189 checkPermissions(f); 190 assertEquals(2, f.getHardLinkCount()); 191 assertEquals("user", f.getUser()); 192 assertEquals("group", f.getGroup()); 193 assertEquals("zxbox", f.getName()); 194 assertEquals(4096, f.getSize()); 195 196 Calendar cal = Calendar.getInstance(); 197 cal.set(Calendar.MONTH, Calendar.MARCH); 198 199 cal.set(Calendar.DATE, 1); 200 cal.set(Calendar.HOUR_OF_DAY, 0); 201 cal.set(Calendar.MINUTE, 0); 202 cal.set(Calendar.SECOND, 0); 203 if (f.getTimestamp().getTime().before(cal.getTime())) { 204 cal.add(Calendar.YEAR, -1); 205 } 206 cal.set(Calendar.DATE, 2); 207 cal.set(Calendar.HOUR_OF_DAY, 15); 208 cal.set(Calendar.MINUTE, 13); 209 210 assertEquals(df.format(cal.getTime()), df.format(f.getTimestamp() 211 .getTime())); 212 } 213 214 215 /** 216 * Method checkPermissions. 217 * Verify that the persmissions were properly set. 218 * @param f 219 */ 220 private void checkPermissions(FTPFile f) { 221 assertTrue("Should have user read permission.", f.hasPermission( 222 FTPFile.USER_ACCESS, FTPFile.READ_PERMISSION)); 223 assertTrue("Should have user write permission.", f.hasPermission( 224 FTPFile.USER_ACCESS, FTPFile.WRITE_PERMISSION)); 225 assertTrue("Should have user execute permission.", f.hasPermission( 226 FTPFile.USER_ACCESS, FTPFile.EXECUTE_PERMISSION)); 227 assertTrue("Should have group read permission.", f.hasPermission( 228 FTPFile.GROUP_ACCESS, FTPFile.READ_PERMISSION)); 229 assertTrue("Should NOT have group write permission.", !f.hasPermission( 230 FTPFile.GROUP_ACCESS, FTPFile.WRITE_PERMISSION)); 231 assertTrue("Should have group execute permission.", f.hasPermission( 232 FTPFile.GROUP_ACCESS, FTPFile.EXECUTE_PERMISSION)); 233 assertTrue("Should have world read permission.", f.hasPermission( 234 FTPFile.WORLD_ACCESS, FTPFile.READ_PERMISSION)); 235 assertTrue("Should NOT have world write permission.", !f.hasPermission( 236 FTPFile.WORLD_ACCESS, FTPFile.WRITE_PERMISSION)); 237 assertTrue("Should have world execute permission.", f.hasPermission( 238 FTPFile.WORLD_ACCESS, FTPFile.EXECUTE_PERMISSION)); 239 } 240 241 /** 242 * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#testParseFieldsOnFile() 243 */ 244 @Override 245 public void testParseFieldsOnFile() throws Exception { 246 FTPFile f = getParser() 247 .parseFTPEntry( 248 "-rwxr-xr-x 2 user my group 500 5000000000 Mar 2 15:13 zxbox"); 249 assertNotNull("Could not parse entry.", f); 250 assertTrue("Should have been a file.", f.isFile()); 251 checkPermissions(f); 252 assertEquals(2, f.getHardLinkCount()); 253 assertEquals("user", f.getUser()); 254 assertEquals("my group 500", f.getGroup()); 255 assertEquals("zxbox", f.getName()); 256 assertEquals(5000000000L, f.getSize()); 257 258 Calendar cal = Calendar.getInstance(); 259 cal.set(Calendar.MONTH, Calendar.MARCH); 260 261 cal.set(Calendar.DATE, 1); 262 cal.set(Calendar.HOUR_OF_DAY, 0); 263 cal.set(Calendar.MINUTE, 0); 264 cal.set(Calendar.SECOND, 0); 265 if (f.getTimestamp().getTime().before(cal.getTime())) { 266 cal.add(Calendar.YEAR, -1); 267 } 268 cal.set(Calendar.DATE, 2); 269 cal.set(Calendar.HOUR_OF_DAY, 15); 270 cal.set(Calendar.MINUTE, 13); 271 assertEquals(df.format(cal.getTime()), df.format(f.getTimestamp().getTime())); 272 } 273 274 275 /** 276 * Method suite. 277 * @return TestSuite 278 */ 279 public static TestSuite suite() { 280 return (new TestSuite(UnixFTPEntryParserTest.class)); 281 } 282 283 284 /* 285 * @param test 286 * @param f 287 */ 288 @Override 289 protected void doAdditionalGoodTests(String test, FTPFile f) { 290 String link = f.getLink(); 291 if (null != link) { 292 int linklen = link.length(); 293 if (linklen > 0) { 294 assertEquals(link, test.substring(test.length() - linklen)); 295 assertEquals(f.getType(), FTPFile.SYMBOLIC_LINK_TYPE); 296 } 297 } 298 int type = f.getType(); 299 switch (test.charAt(0)) 300 { 301 case 'd': 302 assertEquals("Type of "+ test, type, FTPFile.DIRECTORY_TYPE); 303 break; 304 case 'l': 305 assertEquals("Type of "+ test, type, FTPFile.SYMBOLIC_LINK_TYPE); 306 break; 307 case 'b': 308 case 'c': 309 assertEquals(0, f.getHardLinkCount()); 310 case 'f': 311 case '-': 312 assertEquals("Type of "+ test, type, FTPFile.FILE_TYPE); 313 break; 314 default: 315 assertEquals("Type of "+ test, type, FTPFile.UNKNOWN_TYPE); 316 } 317 318 for (int access = FTPFile.USER_ACCESS; 319 access <= FTPFile.WORLD_ACCESS; access++) 320 { 321 for (int perm = FTPFile.READ_PERMISSION; 322 perm <= FTPFile.EXECUTE_PERMISSION; perm++) 323 { 324 int pos = 3*access + perm + 1; 325 char permchar = test.charAt(pos); 326 assertEquals("Permission " + test.substring(1,10), 327 Boolean.valueOf(f.hasPermission(access, perm)), 328 Boolean.valueOf(permchar != '-' && !Character.isUpperCase(permchar))); 329 } 330 } 331 332 } 333 }