2011-05-07 01:29:10 +02:00
package ftp
2013-07-08 07:21:43 +02:00
import (
2018-01-04 13:03:09 +01:00
"strings"
2013-07-08 07:21:43 +02:00
"testing"
2013-07-08 20:06:16 +02:00
"time"
2013-07-08 07:21:43 +02:00
)
2018-01-04 13:03:09 +01:00
var (
// now is the current time for all tests
now = time . Date ( 2017 , time . March , 10 , 23 , 0 , 0 , 0 , time . UTC )
thisYear , _ , _ = now . Date ( )
previousYear = thisYear - 1
)
2011-05-07 01:29:10 +02:00
type line struct {
2013-02-17 10:31:56 +01:00
line string
name string
size uint64
2011-09-05 23:36:14 +02:00
entryType EntryType
2013-07-08 07:21:43 +02:00
time time . Time
2011-05-07 01:29:10 +02:00
}
2015-08-20 10:32:28 +02:00
type unsupportedLine struct {
line string
err string
}
2013-02-17 10:31:56 +01:00
var listTests = [ ] line {
2011-05-07 01:29:10 +02:00
// UNIX ls -l style
2015-03-05 11:45:33 +01:00
{ "drwxr-xr-x 3 110 1002 3 Dec 02 2009 pub" , "pub" , 0 , EntryTypeFolder , time . Date ( 2009 , time . December , 2 , 0 , 0 , 0 , 0 , time . UTC ) } ,
{ "drwxr-xr-x 3 110 1002 3 Dec 02 2009 p u b" , "p u b" , 0 , EntryTypeFolder , time . Date ( 2009 , time . December , 2 , 0 , 0 , 0 , 0 , time . UTC ) } ,
2016-12-29 01:37:08 +01:00
{ "-rw-r--r-- 1 marketwired marketwired 12016 Mar 16 2016 2016031611G087802-001.newsml" , "2016031611G087802-001.newsml" , 12016 , EntryTypeFile , time . Date ( 2016 , time . March , 16 , 0 , 0 , 0 , 0 , time . UTC ) } ,
2015-03-05 11:45:33 +01:00
{ "-rwxr-xr-x 3 110 1002 1234567 Dec 02 2009 fileName" , "fileName" , 1234567 , EntryTypeFile , time . Date ( 2009 , time . December , 2 , 0 , 0 , 0 , 0 , time . UTC ) } ,
{ "lrwxrwxrwx 1 root other 7 Jan 25 00:17 bin -> usr/bin" , "bin -> usr/bin" , 0 , EntryTypeLink , time . Date ( thisYear , time . January , 25 , 0 , 17 , 0 , 0 , time . UTC ) } ,
2015-08-18 22:33:04 +02:00
2015-08-15 13:28:47 +02:00
// Another ls style
{ "drwxr-xr-x folder 0 Aug 15 05:49 !!!-Tipp des Haus!" , "!!!-Tipp des Haus!" , 0 , EntryTypeFolder , time . Date ( thisYear , time . August , 15 , 5 , 49 , 0 , 0 , time . UTC ) } ,
{ "drwxrwxrwx folder 0 Aug 11 20:32 P0RN" , "P0RN" , 0 , EntryTypeFolder , time . Date ( thisYear , time . August , 11 , 20 , 32 , 0 , 0 , time . UTC ) } ,
2015-08-18 23:16:40 +02:00
{ "-rw-r--r-- 0 18446744073709551615 18446744073709551615 Nov 16 2006 VIDEO_TS.VOB" , "VIDEO_TS.VOB" , 18446744073709551615 , EntryTypeFile , time . Date ( 2006 , time . November , 16 , 0 , 0 , 0 , 0 , time . UTC ) } ,
2015-08-18 22:33:04 +02:00
2011-05-07 01:29:10 +02:00
// Microsoft's FTP servers for Windows
2015-03-05 11:45:33 +01:00
{ "---------- 1 owner group 1803128 Jul 10 10:18 ls-lR.Z" , "ls-lR.Z" , 1803128 , EntryTypeFile , time . Date ( thisYear , time . July , 10 , 10 , 18 , 0 , 0 , time . UTC ) } ,
2018-01-04 13:03:09 +01:00
{ "d--------- 1 owner group 0 Nov 9 19:45 Softlib" , "Softlib" , 0 , EntryTypeFolder , time . Date ( previousYear , time . November , 9 , 19 , 45 , 0 , 0 , time . UTC ) } ,
2015-08-18 22:33:04 +02:00
2011-05-07 01:29:10 +02:00
// WFTPD for MSDOS
2015-03-05 11:45:33 +01:00
{ "-rwxrwxrwx 1 noone nogroup 322 Aug 19 1996 message.ftp" , "message.ftp" , 322 , EntryTypeFile , time . Date ( 1996 , time . August , 19 , 0 , 0 , 0 , 0 , time . UTC ) } ,
2015-08-18 22:33:04 +02:00
// RFC3659 format: https://tools.ietf.org/html/rfc3659#section-7
2015-08-15 13:28:07 +02:00
{ "modify=20150813224845;perm=fle;type=cdir;unique=119FBB87U4;UNIX.group=0;UNIX.mode=0755;UNIX.owner=0; ." , "." , 0 , EntryTypeFolder , time . Date ( 2015 , time . August , 13 , 22 , 48 , 45 , 0 , time . UTC ) } ,
{ "modify=20150813224845;perm=fle;type=pdir;unique=119FBB87U4;UNIX.group=0;UNIX.mode=0755;UNIX.owner=0; .." , ".." , 0 , EntryTypeFolder , time . Date ( 2015 , time . August , 13 , 22 , 48 , 45 , 0 , time . UTC ) } ,
{ "modify=20150806235817;perm=fle;type=dir;unique=1B20F360U4;UNIX.group=0;UNIX.mode=0755;UNIX.owner=0; movies" , "movies" , 0 , EntryTypeFolder , time . Date ( 2015 , time . August , 6 , 23 , 58 , 17 , 0 , time . UTC ) } ,
{ "modify=20150814172949;perm=flcdmpe;type=dir;unique=85A0C168U4;UNIX.group=0;UNIX.mode=0777;UNIX.owner=0; _upload" , "_upload" , 0 , EntryTypeFolder , time . Date ( 2015 , time . August , 14 , 17 , 29 , 49 , 0 , time . UTC ) } ,
{ "modify=20150813175250;perm=adfr;size=951;type=file;unique=119FBB87UE;UNIX.group=0;UNIX.mode=0644;UNIX.owner=0; welcome.msg" , "welcome.msg" , 951 , EntryTypeFile , time . Date ( 2015 , time . August , 13 , 17 , 52 , 50 , 0 , time . UTC ) } ,
2017-09-27 01:33:03 +02:00
// Format and types have first letter UpperCase
{ "Modify=20150813175250;Perm=adfr;Size=951;Type=file;Unique=119FBB87UE;UNIX.group=0;UNIX.mode=0644;UNIX.owner=0; welcome.msg" , "welcome.msg" , 951 , EntryTypeFile , time . Date ( 2015 , time . August , 13 , 17 , 52 , 50 , 0 , time . UTC ) } ,
2015-08-25 01:03:52 +02:00
// DOS DIR command output
{ "08-07-15 07:50PM 718 Post_PRR_20150901_1166_265118_13049.dat" , "Post_PRR_20150901_1166_265118_13049.dat" , 718 , EntryTypeFile , time . Date ( 2015 , time . August , 7 , 19 , 50 , 0 , 0 , time . UTC ) } ,
{ "08-10-15 02:04PM <DIR> Billing" , "Billing" , 0 , EntryTypeFolder , time . Date ( 2015 , time . August , 10 , 14 , 4 , 0 , 0 , time . UTC ) } ,
2016-03-16 06:41:20 +01:00
// dir and file names that contain multiple spaces
{ "drwxr-xr-x 3 110 1002 3 Dec 02 2009 spaces dir name" , "spaces dir name" , 0 , EntryTypeFolder , time . Date ( 2009 , time . December , 2 , 0 , 0 , 0 , 0 , time . UTC ) } ,
{ "-rwxr-xr-x 3 110 1002 1234567 Dec 02 2009 file name" , "file name" , 1234567 , EntryTypeFile , time . Date ( 2009 , time . December , 2 , 0 , 0 , 0 , 0 , time . UTC ) } ,
2016-12-31 18:11:23 +01:00
{ "-rwxr-xr-x 3 110 1002 1234567 Dec 02 2009 foo bar " , " foo bar " , 1234567 , EntryTypeFile , time . Date ( 2009 , time . December , 2 , 0 , 0 , 0 , 0 , time . UTC ) } ,
2017-07-06 02:55:11 +02:00
// Odd link count from hostedftp.com
{ "-r-------- 0 user group 65222236 Feb 24 00:39 RegularFile" , "RegularFile" , 65222236 , EntryTypeFile , time . Date ( thisYear , time . February , 24 , 0 , 39 , 0 , 0 , time . UTC ) } ,
2011-05-07 01:29:10 +02:00
}
2015-08-20 10:32:28 +02:00
// Not supported, we expect a specific error message
var listTestsFail = [ ] unsupportedLine {
{ "d [R----F--] supervisor 512 Jan 16 18:53 login" , "Unsupported LIST line" } ,
{ "- [R----F--] rhesus 214059 Oct 20 15:27 cx.exe" , "Unsupported LIST line" } ,
{ "drwxr-xr-x 3 110 1002 3 Dec 02 209 pub" , "Invalid year format in time string" } ,
{ "modify=20150806235817;invalid;UNIX.owner=0; movies" , "Unsupported LIST line" } ,
{ "Zrwxrwxrwx 1 root other 7 Jan 25 00:17 bin -> usr/bin" , "Unknown entry type" } ,
2015-12-28 00:09:00 +01:00
{ "total 1" , "Unsupported LIST line" } ,
2017-07-20 21:09:00 +02:00
{ "000000000x " , "Unsupported LIST line" } , // see https://github.com/jlaffaye/ftp/issues/97
2015-12-28 12:17:09 +01:00
{ "" , "Unsupported LIST line" } ,
2011-05-07 01:29:10 +02:00
}
2015-08-20 10:32:28 +02:00
func TestParseValidListLine ( t * testing . T ) {
2011-05-07 01:29:10 +02:00
for _ , lt := range listTests {
2018-01-04 13:03:09 +01:00
entry , err := parseListLine ( lt . line , now )
2011-05-07 01:29:10 +02:00
if err != nil {
t . Errorf ( "parseListLine(%v) returned err = %v" , lt . line , err )
continue
}
if entry . Name != lt . name {
t . Errorf ( "parseListLine(%v).Name = '%v', want '%v'" , lt . line , entry . Name , lt . name )
}
2011-09-05 23:36:14 +02:00
if entry . Type != lt . entryType {
2013-02-17 10:31:56 +01:00
t . Errorf ( "parseListLine(%v).EntryType = %v, want %v" , lt . line , entry . Type , lt . entryType )
2011-05-07 01:29:10 +02:00
}
2013-02-17 10:03:46 +01:00
if entry . Size != lt . size {
t . Errorf ( "parseListLine(%v).Size = %v, want %v" , lt . line , entry . Size , lt . size )
}
2018-01-04 13:03:09 +01:00
if ! entry . Time . Equal ( lt . time ) {
2013-07-08 07:21:43 +02:00
t . Errorf ( "parseListLine(%v).Time = %v, want %v" , lt . line , entry . Time , lt . time )
}
2011-05-07 01:29:10 +02:00
}
2015-08-20 10:32:28 +02:00
}
func TestParseUnsupportedListLine ( t * testing . T ) {
2011-05-07 01:29:10 +02:00
for _ , lt := range listTestsFail {
2018-01-04 13:03:09 +01:00
_ , err := parseListLine ( lt . line , now )
2011-05-07 01:29:10 +02:00
if err == nil {
t . Errorf ( "parseListLine(%v) expected to fail" , lt . line )
}
2015-08-20 10:32:28 +02:00
if err . Error ( ) != lt . err {
t . Errorf ( "parseListLine(%v) expected to fail with error: '%s'; was: '%s'" , lt . line , lt . err , err . Error ( ) )
}
2011-05-07 01:29:10 +02:00
}
}
2018-01-04 13:03:09 +01:00
func TestSettime ( t * testing . T ) {
tests := [ ] struct {
line string
expected time . Time
} {
// this year, in the past
{ "Feb 10 23:00" , time . Date ( thisYear , time . February , 10 , 23 , 0 , 0 , 0 , time . UTC ) } ,
// this year, less than six months in the future
{ "Sep 10 22:59" , time . Date ( thisYear , time . September , 10 , 22 , 59 , 0 , 0 , time . UTC ) } ,
// previous year, otherwise it would be more than 6 months in the future
{ "Sep 10 23:00" , time . Date ( previousYear , time . September , 10 , 23 , 0 , 0 , 0 , time . UTC ) } ,
}
for _ , test := range tests {
entry := & Entry { }
entry . setTime ( strings . Fields ( test . line ) , now )
if ! entry . Time . Equal ( test . expected ) {
t . Errorf ( "setTime(%v).Time = %v, want %v" , test . line , entry . Time , test . expected )
}
}
}