source: trunk/CHDK/SCRIPTS/TEST/llibtst.lua @ 3422

Revision 3416, 12.6 KB checked in by reyalp, 2 weeks ago (diff)

llibtst.lua update for os.idir

  • Property svn:eol-style set to LF
Line 
1--[[
2@title lua lib test
3@param a skip io
4@default a 0
5@param b skip all os
6@default b 0
7@param c skip os time
8@default c 0
9@param d skip os time fmt
10@default d 0
11@param e skip os filesystem
12@default e 0
13@param f skip string
14@default f 0
15]]
16
17do_io=a==0
18do_os=b==0
19do_time=c==0
20do_fmtdump=d==0
21do_dir=e==0
22do_string=f==0
23
24nfail=0
25want_ok=true
26no_rec=false
27
28iotfnam="A/iotest0.txt"
29
30-- we require minimal io functionality to run the test
31if type(io) ~= "table" then
32        error("missing io, aborting!")
33end
34
35function log(...)
36        io.write(...)
37-- most crashes leave no log even if we flush, and it's really slow :(
38--      io.output():flush()
39end
40-- record result
41function rec(r)
42        local f
43        if no_rec then
44                return "NA"
45        end
46        if want_ok then
47                f=not r
48        else
49                f=r
50        end
51        if f then
52                nfail=nfail+1
53                return "FAIL"
54        end
55        return "PASS"
56end
57function logrec(s,r,...)
58        log(s)
59        if ... then
60                log(" ",...)
61        end
62        log(" ",rec(r))
63        log("\n")
64end
65function logok(...)
66        logrec("OK",true,...)
67end
68function logfail(...)
69        logrec("ERR",false,...)
70end
71function logres(r,...)
72        if r then
73                logok(...)
74        else
75                logfail(...)
76        end
77        return r
78end
79
80function fpinfo(f,name)
81        if type(name) ~= "string" then
82                name="<unk>"
83        end
84        log("file info for ",name,": ")
85        local t=io.type(f)
86        if not t then
87                log("not a file!\n")
88        elseif t == "file" then
89                log("valid file\n")
90                log(" ptr: ",f:_getfptr())
91                local fpv={}
92                for i=0,8 do
93                        fpv[i]=peek(f:_getfptr() + i*4)
94                end
95                log(" fd: ",fpv[0])
96                log(" len: ",fpv[1])
97                log(" pos: ",fpv[3],"\n")
98                log(" raw vals:")
99                for i=0,8 do
100                        log(" ",i*4,":",fpv[i])
101                end
102                log("\n")
103        else
104                log("closed file!\n")
105        end
106end
107
108-- wrap file obj with logging
109tfproto={
110        fpinfo=function(self)
111                fpinfo(self.f,self.name)
112        end,
113        open=function(self,name,mode)
114                log('io.open("',tostring(name),'","',tostring(mode),'"): ')
115                self.f,msg=io.open(name,mode)
116                if self.f then
117                        self.name=name
118                        logok()
119                else
120                        logfail('msg=',tostring(msg))
121                end
122                return self.f,msg
123        end,
124        rawtell=function(self)
125                return peek(self.f:_getfptr() + 12)
126        end,
127        seek=function(self,whence,offset)
128                log(self.name,':seek("',tostring(whence),'",',tostring(offset),'): ')
129                if io.type(self.f) ~= "file" then
130                        log("not an open file!\n")
131                        return
132                end
133                local r=self.f:seek(whence,offset)
134                if r then
135                        if r == self:rawtell() then
136                                logok(tostring(r))
137                        else
138                                logfail("\n position mismatch r ",tostring(r)," != ", tostring(self:rawtell()))
139                        end
140                else
141                        logfail(tostring(r))
142                end
143                return r
144        end,
145        write=function(self,...)
146                log(self.name,":write(...): ")
147                return logres(self.f:write(...))
148        end,
149        read=function(self,...)
150                log(self.name,":read(",...,"): ")
151                local r={self.f:read(...)}
152                if table.maxn(r) == 0 then
153                        log("<no results>")
154                else
155                        for i=1,table.maxn(r) do
156                                log(type(r[i])," [",tostring(r[i]),"] ")
157                        end
158                end
159                log("\n")
160                rec(r[1]) -- only useful if you use a single format in tests
161                return unpack(r)
162        end,
163        flush=function(self)
164                log(self.name,":flush(): ");
165                return logres(self.f:flush())
166        end,
167        close=function(self)
168                log(self.name,":close(): ");
169                local r=self.f:close()
170                self.f=nil
171                self.name=nil
172                return logres(r)
173        end,
174        new=function(self,name,mode)
175                local tf={}
176                for k,v in pairs(tfproto) do
177                        tf[k]=v
178                end
179                if name then
180                        tf:open(name,mode)
181                end
182                return tf
183        end,
184}
185
186function test_readn(tf)
187        local done
188        local ns={}
189        local want={1,2,3,1234567890}
190        local c=1
191        log('testing file:read("*n")\n')
192        no_rec=true -- too complicated
193        while not done do
194                local t=tf:read("*n")
195                tf:seek() -- report pos
196                if t then
197                        ns[c]=t
198                        c=c+1
199                else
200                        t=tf:read(1)
201                        tf:seek()
202                        if not t then
203                                done=true
204                        end
205                end
206        end
207        no_rec=false
208        for i=1,c-1 do
209                if ns[i] ~= want[i] then
210                        logfail(ns[i], " != ",want[i])
211                end
212        end
213        if c ~= 5 then
214                logfail("want 5 got ",c)
215        end
216end
217
218function tstart(n)
219        nfail=0
220        want_ok=true
221        no_rec=false
222        log("***test ",n,"***\n")
223end
224
225function tend(n)
226        s="***end "..n
227        if nfail > 0 then
228                s=s.." FAIL "..tostring(nfail)
229        else
230                s=s.." OK"
231        end
232        s=s.."***"
233        log(s,"\n")
234        print(s)
235end
236
237function io_test()
238        tstart("io")
239        fpinfo(io.input(),"io.input") -- expect closed
240        fpinfo(io.output(),"io.output") -- expect open
241
242        local tf=tfproto:new(iotfnam,"w+b")
243        if not tf.f then
244                log("aborting\n")
245                return
246        end
247        tf:write("the slick brown fox jumps over the lazy dog\n")
248        tf:seek("set",4)
249        local s=tf:read(5)
250        if s ~= "slick" then
251                logfail("want [slick] got [",tostring(s),"]")
252        end
253        tf:seek() -- report pos
254        tf:seek("cur",-5)
255        tf:write("qu")
256        tf:seek("end")
257        tf:write(1,"\n",2,"a","   3"," 1234567890","       b");
258        tf:flush()
259        tf:seek("set")
260        log("test file:lines()\n")
261        local lnum=0
262        for line in tf.f:lines() do
263                log(lnum,": [",line,"]\n")
264                lnum=lnum + 1
265        end
266        tf:seek("set")
267        tf:write("                                           \n")
268        tf:seek("set")
269        log('test file:read("*a")\n')
270        tf:read("*a")
271        tf:seek("set")
272        test_readn(tf)
273        tf:close();
274        log('test open missing file\n')
275        want_ok=false
276        tf:open("A/bogus","r")
277        if tf.f then
278                tf:close()
279        end
280        log('test open dir\n')
281        tf:open("A/CHDK","r")
282        if tf.f then
283                tf:close()
284        end
285        want_ok=true
286        tf:open(iotfnam,"r")
287        want_ok=false
288        log('test invalid seeks\n')
289        tf:seek("set",-1)
290        tf:seek("end",100)
291-- on a540 write succeeds, close fails
292--      log('testinvalid write\n')
293--      tf:write("whee!")
294        want_ok=true
295        tf:close()
296        tend("io")
297        log("\n")
298end
299
300function ttime(t)
301        log('os.time(')
302        if type(t) == "table" then
303                log('{')
304                for k,v in pairs(t) do
305                        log(tostring(k),'=',tostring(v),",")
306                end
307                log('}')
308        elseif type(t) ~= "nil" then
309                log(type(t),"[",tostring(t),"]")
310        end
311        log('): ')
312        local r=os.time(t)
313        if r then
314                logok(tostring(r))
315        else
316                logfail()
317        end
318        return r
319end
320
321function dump_date_fmts()
322        local tm=os.time()
323        -- fmts in vx docs
324        -- dryos (sx100) seems to support all but Z
325        -- dryos returns the partern if it isn't supported, vx returns ""
326        local fdsc={
327                "a","A","b","B","c","d","H","I","j","m","M",
328                "p", -- vxworks docs say P but only p works
329                "S","U","w","W","x","X","y","Y","Z","%",
330        }
331        local s
332        for _,v in ipairs(fdsc) do
333                s="%"..v
334                log(s," [",os.date(s,tm),"]\n");
335        end
336end
337
338function tren(from,to)
339        log('os.rename("',tostring(from),'","',tostring(to),"): ")
340        local r,msg = os.rename(from,to)
341        if r then
342                logok()
343        else
344                logfail(tostring(msg))
345        end
346end
347
348function trem(name)
349        log('os.remove("',tostring(name),"): ")
350        local r,msg = os.remove(name)
351        if r then
352                logok()
353        else
354                logfail(tostring(msg))
355        end
356end
357
358function tmd(name)
359        log('os.mkdir("',tostring(name),'"): ')
360        local r,msg = os.mkdir(name)
361        if r then
362                logok()
363        else
364                logfail(tostring(msg))
365        end
366end
367
368function tstat(name,expect)
369        log('os.stat("',tostring(name),'"): ')
370        local r,msg = os.stat(name)
371        if r then
372                local fail
373                if type(expect) == 'table' then
374                        for k,v in pairs(expect) do
375                                if r[k] ~= v then
376                                        logfail("expected "..tostring(k).."="..tostring(v).." not "..tostring(r[k]))
377                                        fail = true
378                                end
379                        end
380                end
381                if not fail then
382                        logok()
383                end
384                local keys={ "size", "mtime", "ctime", "attrib","is_dir","is_file",}
385                log("{\n")
386                for _,v in ipairs(keys) do
387                        log(" ",tostring(v),"=",tostring(r[v]),"\n")
388                end
389                log("}\n")
390        else
391                logfail(tostring(msg))
392        end
393        return r
394end
395
396function tlistdir(name,showall)
397        log('os.listdir("',tostring(name),'",',tostring(showall),'): ')
398        local r,msg = os.listdir(name,showall)
399        if r then
400                logok()
401                log("{\n")
402                for k,v in ipairs(r) do
403                        log(' ',k,'="',tostring(v),'"\n')
404                end
405                log("}\n")
406        else
407                logfail(tostring(msg))
408        end
409        return r
410end
411
412function tidir(name,showall,expect)
413        log('os.idir("',tostring(name),'",',tostring(showall),'): ')
414        local r={}
415        local names={}
416        for fn in os.idir(name,showall) do
417                table.insert(r,fn)
418                names[fn]=true
419        end
420        local msg
421        if expect == 'empty' then
422                if #r ~= 0 then
423                        msg="expted empty"
424                end
425        else
426                -- only check that expected are present, vx may include deleted with all
427                for i,fn in ipairs(expect) do
428                        if not names[fn] then
429                                msg="missing expected file "..tostring(fn)
430                        end
431                end
432        end
433        if msg then
434                logfail(tostring(msg))
435        else
436                logok()
437                log("{\n")
438                for k,v in ipairs(r) do
439                        log(' ',k,'="',tostring(v),'"\n')
440                end
441                log("}\n")
442        end
443        return r
444end
445
446function tidirbreak(name,limit)
447        log('os.idir("',tostring(name),'"): ')
448        local n=0
449        local idir,ud = os.idir(name)
450        repeat
451                n = n+1
452                fn=idir(ud)
453                if n == limit then
454                        break
455                end
456        until not fn
457        local msg
458        if fn and n == limit then
459                idir(ud,false)
460                if idir(ud) ~= nil then
461                        msg="explicit close failed"
462                end
463        else
464                msg="limit not reached"
465        end
466        if msg then
467                logfail(tostring(msg))
468        else
469                logok()
470        end
471        return true
472end
473
474function tutime(name,mtime,atime)
475        log('os.utime("',tostring(name),'",',tostring(mtime),',',tostring(atime),'): ')
476        local r,msg = os.utime(name,mtime,atime)
477        if r then
478                logok()
479        else
480                logfail(tostring(msg))
481        end
482end
483
484function os_test()
485        tstart("os")
486        if type(os) ~= "table" then
487                log("missing os aborting!\n")
488                return
489        end
490        if do_time then
491                local s=os.date()
492                log("current date ",tostring(s),"\n");
493                if not s then
494                        logfail("nil value\n")
495                end
496                ttime()
497                local t={year=1980,month=1,day=1}
498                local tm=ttime(t)
499                if tm ~= 315576000 then
500                        logfail("want ",315576000," got ",tostring(tm))
501                end
502                want_ok=false
503                t={year=1066,month=1,day=1}
504                ttime(t)
505                if do_fmtdump then
506                        dump_date_fmts()
507                end
508        end
509        if do_dir then
510                want_ok=true
511                local tdir0,tdat0,tdat1="A/MDTST0","/TEST0.DAT","/TEST1.DAT"
512                tmd(tdir0)
513                local tf=tfproto:new(tdir0..tdat0,"wb")
514                tf:write("data")
515                tf:close()
516                local fn=tdir0..tdat0
517                tstat(fn,{is_file=true,is_dir=false})
518                tutime(fn) -- utime, current
519                tstat(fn)
520                tutime(fn,os.time({year=1984,month=1,day=1,hour=0}),os.time({year=1984,month=12,day=25,hour=0}))
521                tstat(fn,{mtime=os.time({year=1984,month=1,day=1,hour=0})})
522                tstat(tdir0,{is_file=false,is_dir=true})
523                tren(tdir0..tdat0,tdir0..tdat1)
524                tlistdir(tdir0)
525                tlistdir(tdir0,true)
526                if type(os.idir) == 'function' then
527                        tidir(tdir0,nil,{'TEST1.DAT'})
528                        tidir(tdir0,true,{'TEST1.DAT','.','..'})
529                        tidir(tdir0..tdat1,true,'empty') -- dir on a file should give empty
530                        tidir('A/BOGUS',true,'empty') -- dir on non-existent should give empty
531                        tidirbreak('A/',2) -- root should have more than 2 entries
532                else
533                        log('skipping idir, not implemented\n')
534                end
535-- NOTE invalid operations frequently leave the filesystem in a corrupt state
536--              trename(tdir0,tdir1)
537                want_ok=false
538                trem(tdir0) --fail, not empty
539                trem("A/bogus") --fail missing
540                tlistdir("A/bogus") -- missing
541                -- dryos returns success for listdir on a file
542                if get_buildinfo().os == "dryos" then
543                        no_rec = true
544                end
545                tlistdir("A/llibtst.log") -- not a directory
546                no_rec = false
547                tstat("A/bogus") -- fail missing
548                tutime("A/bogus") -- fail missing
549                tren("A/bogus","A/blah")--fail missing
550                tmd("A/CHDK")--fail, exists
551                want_ok=true
552                trem(tdir0..tdat1)
553                trem(tdir0)
554                no_rec=true
555                trem(iotfnam)--try to clean up from io
556        end
557        tend("os")
558        log("\n")
559end
560
561function string_test()
562        tstart("string")
563        if type(string) ~= "table" then
564                log("missing string aborting!\n")
565                return
566        end
567        log('string.byte("test",2): ')
568        local v=string.byte("test",2)
569        logres(v==101,tostring(v))
570        log('string.char(116,101,115,116): ')
571        v=string.char(116,101,115,116)
572        logres(v=="test",tostring(v))
573        log('dump/load: ')
574        v=string.dump(function(a) return 'test' .. tostring(a) end)
575        v=loadstring(v)(123)
576        logres(v=="test123",tostring(v))
577        log('string.find("test 1 2 3F!?","t%s(%d) 2 (%x%x%p%p)$"): ')
578        local mstart,mend,cap1,cap2=string.find("test 1 2 3F!?","t%s(%d) 2 (%x%x%p%p)$")
579        logres((mstart == 4 and mend == 13 and cap1 == '1' and cap2 == '3F!?'),
580                    tostring(mstart) .. " " ..
581                        tostring(mend) .. " " ..
582                        tostring(cap1) .. " " .. tostring(cap2) )
583        log('string.format("%c %d %x %s",100,100,100,"test"): ')
584        v=string.format("%c %d %x %s",100,100,100,"test")
585        logres(v=="d 100 64 test",v)
586        -- not testing gmatch or gsub for now, pattern matching exercised above
587        log('string.len("\\000test"): ')
588        v=string.len("\000test")
589        logres(v==5,v)
590        log('string.lower("TESTtest"): ')
591        v=string.lower("TESTtest")
592        logres(v=="testtest",v)
593        log('string.upper("TESTtest"): ')
594        v=string.upper("TESTtest")
595        logres(v=="TESTTEST",v)
596        -- not testing string.match
597        log('string.rep("test",2): ')
598        v=string.rep("test",2)
599        logres(v=="testtest",v)
600        log('string.reverse("123"): ')
601        v=string.reverse("123")
602        logres(v=="321",v)
603        log('string.sub("test",-3): ')
604        v=string.sub("test",-3)
605        logres(v=="est",v)
606        tend("string")
607        log("\n")
608end
609
610testlog,msg=io.open("A/llibtst.log","wb")
611if not testlog then
612        error("open test log fail:"..tostring(msg))
613end
614
615io.output(testlog)
616bi=get_buildinfo()
617log("test log opened\n");
618log("platform: ",bi.platform," ",bi.platsub,"\n")
619log("version: ",bi.version," ",bi.build_number," built on ",bi.build_date," ",bi.build_time,"\n")
620log("os: ",bi.os," platformid: ",bi.platformid,"\n")
621if do_io then
622        io_test()
623end
624
625if do_os then
626        os_test()
627end
628
629if do_string then
630        string_test()
631end
632log("close test log\n");
633io.close(testlog)
634sleep(2000)
Note: See TracBrowser for help on using the repository browser.