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

Revision 555, 9.3 KB checked in by reyalp, 5 years ago (diff)

+ add os.listdir to lua oslib, updated llibtst.lua

syntax t=os.listdir("name",[showall])
returns array of filenames, or nil, strerror, errno
if showall is true, t includes ".", ".." and deleted entries
NOTE except for the root directory, names ending in / will not work

  • 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]]
14
15do_io=a==0
16do_os=b==0
17do_time=c==0
18do_fmtdump=d==0
19do_dir=e==0
20
21nfail=0
22want_ok=true
23no_rec=false
24
25iotfnam="A/iotest0.txt"
26
27-- we require minimal io functionality to run the test
28if type(io) ~= "table" then
29        error("missing io, aborting!")
30end
31
32function log(...)
33        io.write(...)
34-- most crashes leave no log even if we flush, and it's really slow :(
35--      io.output():flush()
36end
37-- record result
38function rec(r)
39        local f
40        if no_rec then
41                return "NA"
42        end
43        if want_ok then
44                f=not r
45        else
46                f=r
47        end
48        if f then
49                nfail=nfail+1
50                return "FAIL"
51        end
52        return "PASS"
53end
54function logrec(s,r,...)
55        log(s)
56        if ... then
57                log(" ",...)
58        end
59        log(" ",rec(r))
60        log("\n")
61end
62function logok(...)
63        logrec("OK",true,...)
64end
65function logfail(...)
66        logrec("ERR",false,...)
67end
68function logres(r)
69        if r then
70                logok()
71        else
72                logfail()
73        end
74        return r
75end
76
77function fpinfo(f,name)
78        if type(name) ~= "string" then
79                name="<unk>"
80        end
81        log("file info for ",name,": ")
82        local t=io.type(f)
83        if not t then
84                log("not a file!\n")
85        elseif t == "file" then
86                log("valid file\n")
87                log(" ptr: ",f:_getfptr())
88                local fpv={}
89                for i=0,8 do
90                        fpv[i]=peek(f:_getfptr() + i*4)
91                end
92                log(" fd: ",fpv[0])
93                log(" len: ",fpv[1])
94                log(" pos: ",fpv[3],"\n")
95                log(" raw vals:")
96                for i=0,8 do
97                        log(" ",i*4,":",fpv[i])
98                end
99                log("\n")
100        else
101                log("closed file!\n")
102        end
103end
104
105-- wrap file obj with logging
106tfproto={
107        fpinfo=function(self)
108                fpinfo(self.f,self.name)
109        end,
110        open=function(self,name,mode)
111                log('io.open("',tostring(name),'","',tostring(mode),'"): ')
112                self.f,msg=io.open(name,mode)
113                if self.f then
114                        self.name=name
115                        logok()
116                else
117                        logfail('msg=',tostring(msg))
118                end
119                return self.f,msg
120        end,
121        rawtell=function(self)
122                return peek(self.f:_getfptr() + 12)
123        end,
124        seek=function(self,whence,offset)
125                log(self.name,':seek("',tostring(whence),'",',tostring(offset),'): ')
126                if io.type(self.f) ~= "file" then
127                        log("not an open file!\n")
128                        return
129                end
130                local r=self.f:seek(whence,offset)
131                if r then
132                        if r == self:rawtell() then
133                                logok(tostring(r))
134                        else
135                                logfail("\n position mismatch r ",tostring(r)," != ", tostring(self:rawtell()))
136                        end
137                else
138                        logfail(tostring(r))
139                end
140                return r
141        end,
142        write=function(self,...)
143                log(self.name,":write(...): ")
144                return logres(self.f:write(...))
145        end,
146        read=function(self,...)
147                log(self.name,":read(",...,"): ")
148                local r={self.f:read(...)}
149                if table.maxn(r) == 0 then
150                        log("<no results>")
151                else
152                        for i=1,table.maxn(r) do
153                                log(type(r[i])," [",tostring(r[i]),"] ")
154                        end
155                end
156                log("\n")
157                rec(r[1]) -- only useful if you use a single format in tests
158                return unpack(r)
159        end,
160        flush=function(self)
161                log(self.name,":flush(): ");
162                return logres(self.f:flush())
163        end,
164        close=function(self)
165                log(self.name,":close(): ");
166                local r=self.f:close()
167                self.f=nil
168                self.name=nil
169                return logres(r)
170        end,
171        new=function(self,name,mode)
172                local tf={}
173                for k,v in pairs(tfproto) do
174                        tf[k]=v
175                end
176                if name then
177                        tf:open(name,mode)
178                end
179                return tf
180        end,
181}
182
183function test_readn(tf)
184        local done
185        local ns={}
186        local want={1,2,3,1234567890}
187        local c=1
188        log('testing file:read("*n")\n')
189        no_rec=true -- too complicated
190        while not done do
191                local t=tf:read("*n")
192                tf:seek() -- report pos
193                if t then
194                        ns[c]=t
195                        c=c+1
196                else
197                        t=tf:read(1)
198                        tf:seek()
199                        if not t then
200                                done=true
201                        end
202                end
203        end
204        no_rec=false
205        for i=1,c-1 do
206                if ns[i] ~= want[i] then
207                        logfail(ns[i], " != ",want[i])
208                end
209        end
210        if c ~= 5 then
211                logfail("want 5 got ",c)
212        end
213end
214
215function tstart(n)
216        nfail=0
217        want_ok=true
218        no_rec=false
219        log("***test ",n,"***\n")
220end
221
222function tend(n)
223        s="***end "..n
224        if nfail > 0 then
225                s=s.." FAIL "..tostring(nfail)
226        else
227                s=s.." OK"
228        end
229        s=s.."***"
230        log(s,"\n")
231        print(s)
232end
233
234function io_test()
235        tstart("io")
236        fpinfo(io.input(),"io.input") -- expect closed
237        fpinfo(io.output(),"io.output") -- expect open
238
239        local tf=tfproto:new(iotfnam,"w+b")
240        if not tf.f then
241                log("aborting\n")
242                return
243        end
244        tf:write("the slick brown fox jumps over the lazy dog\n")
245        tf:seek("set",4)
246        local s=tf:read(5)
247        if s ~= "slick" then
248                logfail("want [slick] got [",tostring(s),"]")
249        end
250        tf:seek() -- report pos
251        tf:seek("cur",-5)
252        tf:write("qu")
253        tf:seek("end")
254        tf:write(1,"\n",2,"a","   3"," 1234567890","       b");
255        tf:flush()
256        tf:seek("set")
257        log("test file:lines()\n")
258        local lnum=0
259        for line in tf.f:lines() do
260                log(lnum,": [",line,"]\n")
261                lnum=lnum + 1
262        end
263        tf:seek("set")
264        tf:write("                                           \n")
265        tf:seek("set")
266        log('test file:read("*a")\n')
267        tf:read("*a")
268        tf:seek("set")
269        test_readn(tf)
270        tf:close();
271        log('test open missing file\n')
272        want_ok=false
273        tf:open("A/bogus","r")
274        if tf.f then
275                tf:close()
276        end
277        log('test open dir\n')
278        tf:open("A/CHDK","r")
279        if tf.f then
280                tf:close()
281        end
282        want_ok=true
283        tf:open(iotfnam,"r")
284        want_ok=false
285        log('test invalid seeks\n')
286        tf:seek("set",-1)
287        tf:seek("end",100)
288-- on a540 write succeeds, close fails
289--      log('testinvalid write\n')
290--      tf:write("whee!")
291        want_ok=true
292        tf:close()
293        tend("io")
294        log("\n")
295end
296
297function ttime(t)
298        log('os.time(')
299        if type(t) == "table" then
300                log('{')
301                for k,v in pairs(t) do
302                        log(tostring(k),'=',tostring(v),",")
303                end
304                log('}')
305        elseif type(t) ~= "nil" then
306                log(type(t),"[",tostring(t),"]")
307        end
308        log('): ')
309        local r=os.time(t)
310        if r then
311                logok(tostring(r))
312        else
313                logfail()
314        end
315        return r
316end
317
318function dump_date_fmts()
319        local tm=os.time()
320        -- fmts in vx docs
321        -- dryos (sx100) seems to support all but Z
322        -- dryos returns the partern if it isn't supported, vx returns ""
323        local fdsc={
324                "a","A","b","B","c","d","H","I","j","m","M",
325                "p", -- vxworks docs say P but only p works
326                "S","U","w","W","x","X","y","Y","Z","%",
327        }
328        local s
329        for _,v in ipairs(fdsc) do
330                s="%"..v
331                log(s," [",os.date(s,tm),"]\n");
332        end
333end
334
335function tren(from,to)
336        log('os.rename("',tostring(from),'","',tostring(to),"): ")
337        local r,msg = os.rename(from,to)
338        if r then
339                logok()
340        else
341                logfail(tostring(msg))
342        end
343end
344
345function trem(name)
346        log('os.remove("',tostring(name),"): ")
347        local r,msg = os.remove(name)
348        if r then
349                logok()
350        else
351                logfail(tostring(msg))
352        end
353end
354
355function tmd(name)
356        log('os.mkdir("',tostring(name),'"): ')
357        local r,msg = os.mkdir(name)
358        if r then
359                logok()
360        else
361                logfail(tostring(msg))
362        end
363end
364
365function tstat(name)
366        log('os.stat("',tostring(name),'"): ')
367        local r,msg = os.stat(name)
368        if r then
369--              local keys={ "dev", "ino", "mode", "nlink", "uid", "gid", "rdev", "size", "atime", "mtime", "ctime", "blksize", "blocks", "attrib", "reserved1", "reserved2", "reserved3", "reserved4", "reserved5", "reserved6",}
370                local keys={ "dev", "mode", "size", "atime", "mtime", "ctime", "blksize", "blocks", "attrib","is_dir","is_file",}
371                logok()
372                log("{\n")
373                for _,v in ipairs(keys) do
374                        log(" ",tostring(v),"=",tostring(r[v]),"\n")
375                end
376                log("}\n")
377        else
378                logfail(tostring(msg))
379        end
380        return r
381end
382
383function tlistdir(name,showall)
384        log('os.listdir("',tostring(name),'",',tostring(showall),'): ')
385        local r,msg = os.listdir(name,showall)
386        if r then
387                logok()
388                log("{\n")
389                for k,v in ipairs(r) do
390                        log(' ',k,'="',tostring(v),'"\n')
391                end
392                log("}\n")
393        else
394                logfail(tostring(msg))
395        end
396        return r
397end
398
399function tutime(name,mtime,atime)
400        log('os.utime("',tostring(name),'",',tostring(mtime),',',tostring(atime),'): ')
401        local r,msg = os.utime(name,mtime,atime)
402        if r then
403                logok()
404        else
405                logfail(tostring(msg))
406        end
407end
408
409function os_test()
410        tstart("os")
411        if type(os) ~= "table" then
412                log("missing os aborting!\n")
413                return
414        end
415        if do_time then
416                local s=os.date()
417                log("current date ",tostring(s),"\n");
418                if not s then
419                        logfail("nil value\n")
420                end
421                ttime()
422                local t={year=1980,month=1,day=1}
423                local tm=ttime(t)
424                if tm ~= 315576000 then
425                        logfail("want ",315576000," got ",tostring(tm))
426                end
427                want_ok=false
428                t={year=1066,month=1,day=1}
429                ttime(t)
430                if do_fmtdump then
431                        dump_date_fmts()
432                end
433        end
434        if do_dir then
435                want_ok=true
436                local tdir0,tdat0,tdat1="A/MDTST0","/TEST0.DAT","/TEST1.DAT"
437                tmd(tdir0)
438                local tf=tfproto:new(tdir0..tdat0,"wb")
439                tf:write("data")
440                tf:close()
441                local fn=tdir0..tdat0
442                tstat(fn)
443                tutime(fn) -- utime, current
444                tstat(fn)
445                tutime(fn,os.time({year=1984,month=1,day=1}),os.time({year=1984,month=12,day=25}))
446                tstat(fn)
447                tstat(tdir0)
448                tren(tdir0..tdat0,tdir0..tdat1)
449                tlistdir(tdir0)
450                tlistdir(tdir0,true)
451-- NOTE invalid operations frequently leave the filesystem in a corrupt state
452--              trename(tdir0,tdir1)
453                want_ok=false
454                trem(tdir0) --fail, not empty
455                trem("A/bogus") --fail missing
456                tlistdir("A/bogus") -- missing
457                tlistdir("A/llibtst.log") -- not a directory
458                tstat("A/bogus") -- fail missing
459                tutime("A/bogus") -- fail missing
460                tren("A/bogus","A/blah")--fail missing
461                tmd("A/CHDK")--fail, exists
462                want_ok=true
463                trem(tdir0..tdat1)
464                trem(tdir0)
465                no_rec=true
466                trem(iotfnam)--try to clean up from io
467        end
468        tend("os")
469        log("\n")
470end
471
472testlog,msg=io.open("A/llibtst.log","wb")
473if not testlog then
474        error("open test log fail:"..tostring(msg))
475end
476
477io.output(testlog)
478bi=get_buildinfo()
479log("test log opened\n");
480log("platform: ",bi.platform," ",bi.platsub,"\n")
481log("version: ",bi.version," ",bi.build_number," built on ",bi.build_date," ",bi.build_time,"\n")
482if do_io then
483        io_test()
484end
485
486if do_os then
487        os_test()
488end
489log("close test log\n");
490io.close(testlog)
491sleep(2000)
Note: See TracBrowser for help on using the repository browser.