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

Revision 2453, 11.2 KB checked in by philmoz, 5 months ago (diff)

Merge philmoz-reorg branch back into trunk.

  • 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 tutime(name,mtime,atime)
413        log('os.utime("',tostring(name),'",',tostring(mtime),',',tostring(atime),'): ')
414        local r,msg = os.utime(name,mtime,atime)
415        if r then
416                logok()
417        else
418                logfail(tostring(msg))
419        end
420end
421
422function os_test()
423        tstart("os")
424        if type(os) ~= "table" then
425                log("missing os aborting!\n")
426                return
427        end
428        if do_time then
429                local s=os.date()
430                log("current date ",tostring(s),"\n");
431                if not s then
432                        logfail("nil value\n")
433                end
434                ttime()
435                local t={year=1980,month=1,day=1}
436                local tm=ttime(t)
437                if tm ~= 315576000 then
438                        logfail("want ",315576000," got ",tostring(tm))
439                end
440                want_ok=false
441                t={year=1066,month=1,day=1}
442                ttime(t)
443                if do_fmtdump then
444                        dump_date_fmts()
445                end
446        end
447        if do_dir then
448                want_ok=true
449                local tdir0,tdat0,tdat1="A/MDTST0","/TEST0.DAT","/TEST1.DAT"
450                tmd(tdir0)
451                local tf=tfproto:new(tdir0..tdat0,"wb")
452                tf:write("data")
453                tf:close()
454                local fn=tdir0..tdat0
455                tstat(fn,{is_file=true,is_dir=false})
456                tutime(fn) -- utime, current
457                tstat(fn)
458                tutime(fn,os.time({year=1984,month=1,day=1,hour=0}),os.time({year=1984,month=12,day=25,hour=0}))
459                tstat(fn,{mtime=os.time({year=1984,month=1,day=1,hour=0})})
460                tstat(tdir0,{is_file=false,is_dir=true})
461                tren(tdir0..tdat0,tdir0..tdat1)
462                tlistdir(tdir0)
463                tlistdir(tdir0,true)
464-- NOTE invalid operations frequently leave the filesystem in a corrupt state
465--              trename(tdir0,tdir1)
466                want_ok=false
467                trem(tdir0) --fail, not empty
468                trem("A/bogus") --fail missing
469                tlistdir("A/bogus") -- missing
470                -- dryos returns success for listdir on a file
471                if get_buildinfo().os == "dryos" then
472                        no_rec = true
473                end
474                tlistdir("A/llibtst.log") -- not a directory
475                no_rec = false
476                tstat("A/bogus") -- fail missing
477                tutime("A/bogus") -- fail missing
478                tren("A/bogus","A/blah")--fail missing
479                tmd("A/CHDK")--fail, exists
480                want_ok=true
481                trem(tdir0..tdat1)
482                trem(tdir0)
483                no_rec=true
484                trem(iotfnam)--try to clean up from io
485        end
486        tend("os")
487        log("\n")
488end
489
490function string_test()
491        tstart("string")
492        if type(string) ~= "table" then
493                log("missing string aborting!\n")
494                return
495        end
496        log('string.byte("test",2): ')
497        local v=string.byte("test",2)
498        logres(v==101,tostring(v))
499        log('string.char(116,101,115,116): ')
500        v=string.char(116,101,115,116)
501        logres(v=="test",tostring(v))
502        log('dump/load: ')
503        v=string.dump(function(a) return 'test' .. tostring(a) end)
504        v=loadstring(v)(123)
505        logres(v=="test123",tostring(v))
506        log('string.find("test 1 2 3F!?","t%s(%d) 2 (%x%x%p%p)$"): ')
507        local mstart,mend,cap1,cap2=string.find("test 1 2 3F!?","t%s(%d) 2 (%x%x%p%p)$")
508        logres((mstart == 4 and mend == 13 and cap1 == '1' and cap2 == '3F!?'),
509                    tostring(mstart) .. " " ..
510                        tostring(mend) .. " " ..
511                        tostring(cap1) .. " " .. tostring(cap2) )
512        log('string.format("%c %d %x %s",100,100,100,"test"): ')
513        v=string.format("%c %d %x %s",100,100,100,"test")
514        logres(v=="d 100 64 test",v)
515        -- not testing gmatch or gsub for now, pattern matching exercised above
516        log('string.len("\\000test"): ')
517        v=string.len("\000test")
518        logres(v==5,v)
519        log('string.lower("TESTtest"): ')
520        v=string.lower("TESTtest")
521        logres(v=="testtest",v)
522        log('string.upper("TESTtest"): ')
523        v=string.upper("TESTtest")
524        logres(v=="TESTTEST",v)
525        -- not testing string.match
526        log('string.rep("test",2): ')
527        v=string.rep("test",2)
528        logres(v=="testtest",v)
529        log('string.reverse("123"): ')
530        v=string.reverse("123")
531        logres(v=="321",v)
532        log('string.sub("test",-3): ')
533        v=string.sub("test",-3)
534        logres(v=="est",v)
535        tend("string")
536        log("\n")
537end
538
539testlog,msg=io.open("A/llibtst.log","wb")
540if not testlog then
541        error("open test log fail:"..tostring(msg))
542end
543
544io.output(testlog)
545bi=get_buildinfo()
546log("test log opened\n");
547log("platform: ",bi.platform," ",bi.platsub,"\n")
548log("version: ",bi.version," ",bi.build_number," built on ",bi.build_date," ",bi.build_time,"\n")
549log("os: ",bi.os," platformid: ",bi.platformid,"\n")
550if do_io then
551        io_test()
552end
553
554if do_os then
555        os_test()
556end
557
558if do_string then
559        string_test()
560end
561log("close test log\n");
562io.close(testlog)
563sleep(2000)
Note: See TracBrowser for help on using the repository browser.