]> mj.ucw.cz Git - eval.git/blob - t/moe/batch.py
Batch task testing works (sort of)
[eval.git] / t / moe / batch.py
1 #!/usr/bin/env python
2
3 import os.path
4 import moe
5 import moe.box
6 import moe.eval
7 import moe.util
8 import moe.pipeline
9 import moe.testcase
10 import shutil
11
12 def normalize_ext(e, ext):
13     alias = e.cfgs["ALIAS_EXT_" + ext]
14     return alias if alias != "" else ext
15
16 def try_ext(e, ext):
17     for e in e.cfgs["EXTENSIONS"].split():
18         if e == ext:
19             return
20     raise moe.MoeErr, "Unknown extension: " + ext
21
22 def locate(e, filename=None):
23     e.log.progress("Locating source... ")
24     task = e.cfgs["TASK"]
25     if filename is None:
26         dir = ""
27         file = task
28     else:
29         dir, file = os.path.split(filename)
30     if dir == "":
31         dir = e.cfgs["SDIR"]
32
33     base, ext = os.path.splitext(file)
34     if ext != "":
35         if not os.path.exists(os.path.join(dir, file)):
36             raise moe.SolutionErr, "No solution of %s called %s found" % (task,file)
37         ext = ext[1:]
38         try_ext(e, ext)
39     else:
40         found = []
41         for ext in e.cfgs["EXTENSIONS"].split():
42             if os.path.exists(os.path.join(dir, base + "." + ext)):
43                 found.append(ext)
44         if len(found) == 0:
45             raise moe.SolutionErr, "No solution of %s found" % task
46         if len(found) > 1:
47             raise moe.SolutionErr, "Multiple solutions of %s found" % task
48         ext = found[0]
49         file = base + "." + ext
50
51     orig_path = os.path.join(dir, file)
52     norm_ext = normalize_ext(e, ext)
53     e.log.verbose("Found solution %s\n" % orig_path)
54
55     copy = e.cfgs["TASK"] + "." + norm_ext
56     copy_path = os.path.join(e.cfgs["TDIR"], copy)
57     if file != copy:
58         e.log.verbose("Renaming to %s\n" % copy)
59     moe.util.link_or_copy(orig_path, copy_path)
60
61     e.builtins.set("SRC", copy)
62     e.builtins.set("EXT", norm_ext)
63     e.cfgs.apply_overrides("EXT_" + norm_ext + "_")
64
65     e.stat["source"] = file
66     e.log.progress(file + "\n")
67
68 def compile_init(e):
69     e.log.progress("Compiling... ")
70     boxdir = moe.box.setup(e)
71     pdir = e.cfgs["PDIR"]
72     tdir = e.cfgs["TDIR"]
73     shutil.copyfile(os.path.join(tdir, e.cfgs["SRC"]), os.path.join(boxdir, e.cfgs["SRC"]))
74     for x in e.cfgs["EXTRAS"].split() + e.cfgs["COMP_EXTRAS"].split():
75         xx = os.path.join(tdir, x)
76         if not os.path.isfile(xx):
77             xx = os.path.join(pdir, x)
78         e.log.verbose("Copying extra file %s\n" % xx)
79         shutil.copyfile(xx, os.path.join(boxdir, x))
80
81 def compile_run(e):
82     moe.box.show(e, "compiler input")
83     cc = e.cfgs["COMP"]
84     e.log.verbose("Compilation command: %s\n" % cc)
85     rc = moe.box.run(e, e.cfgs["COMP_SANDBOX_OPTS"], cc)
86     if rc > 0:
87         e.log.progress("FAILED\n")
88         ## FIXME: status file
89         raise moe.pipeline.MoeAbortPipeline(200)
90     moe.box.show(e, "compiler output")
91
92 def compile_done(e):
93     try:
94         shutil.copyfile(os.path.join(e.cfgs["BOXDIR"], e.cfgs["EXE"]), os.path.join(e.cfgs["TDIR"], e.cfgs["EXE"]))
95     except IOError:
96         raise moe.MoeErr, "Compiler succeeded, but produced no output"
97     e.log.progress("OK\n")
98
99 def test_in(e):
100     tdir = e.cfgs["TDIR"]
101     boxdir = moe.box.setup(e)
102     inn = e.cfgs["TESTCASE_IN"]
103     in_type = e.cfgs["IN_TYPE"] or e.cfgs["IO_TYPE"]
104     out_type = e.cfgs["OUT_TYPE"] or e.cfgs["IO_TYPE"]
105     is_interactive = e.cfgs["TASK_TYPE"] == "interactive"
106     sandbox_opts = "-M" + os.path.join(tdir, e.cfgs["TEST"] + ".status")
107
108     if not os.path.exists(os.path.join(tdir, e.cfgs["EXE"])):
109         ## FIXME: status file
110         raise SolutionErr, "Compilation failed"
111     shutil.copyfile(os.path.join(tdir, e.cfgs["EXE"]), os.path.join(boxdir, e.cfgs["EXE"]))
112     os.chmod(os.path.join(boxdir, e.cfgs["EXE"]), 0555)
113
114     if in_type == "file":
115         in_name = e.cfgs["IN_NAME"]
116         e.log.verbose("Input file: %s (copied from %s)\n" % (in_name, os.path.join(e.cfgs["PDIR"], inn)))
117         shutil.copyfile(os.path.join(tdir, inn), os.path.join(boxdir, in_name))
118         if not is_interactive:
119             sandbox_opts = " -i/dev/null"
120     elif in_type == "stdio":
121         e.log.verbose("Input file: <stdin> (copied from %s)\n" % os.path.join(e.cfgs["PDIR"], inn))
122         shutil.copyfile(os.path.join(tdir, inn), os.path.join(boxdir, ".stdin"))
123         sandbox_opts = " -i.stdin"
124     elif in_type == "none":
125         e.log.verbose("Input file: <none>\n")
126         if not is_interactive:
127             sandbox_opts += " -i/dev/null"
128     elif in_type == "dir":
129         ## FIXME
130         raise MoeErr, "Directory input not yet implemented"
131     else:
132         raise MoeErr, "Unknown input type %s" % in_type
133
134     if out_type == "file":
135         out_name = e.cfgs["OUT_NAME"]
136         e.log.verbose("Output file: %s\n" % out_name)
137         if not is_interactive:
138             sandbox_opts += " -o/dev/null"
139     elif out_type == "stdio":
140         e.log.verbose("Output file: <stdout>\n")
141         sandbox_opts += " -o.stdout"
142     elif out_type == "none":
143         e.log.verbose("Output file: <none>\n")
144         if not is_interactive:
145             sandbox_opts += " -o/dev/null"
146     else:
147         raise MoeErr, "Unknown output type %s" % out_type
148
149     e.test_builtins.set("BOX_IO_OPTS", sandbox_opts)
150
151 def test_run(e):
152     e.log.verbose("Time limit: %s s\n" % e.cfgs["TIME_LIMIT"])
153     e.log.verbose("Memory limit: %s KB\n" % e.cfgs["MEM_LIMIT"])
154     moe.box.show(e, "test input")
155     e.log.progress("<run> ")
156     moe.box.run(e, e.cfgs["TEST_SANDBOX_OPTS"], e.cfgs["TEST_EXEC_CMD"])
157     moe.box.show(e, "test output")
158     ## FIXME: Parse the status file and delete it
159     ### Check for runtime errors reported by the box
160
161 def test_collect(e):
162     tdir = e.cfgs["TDIR"]
163     boxdir = e.cfgs["BOXDIR"]
164     out_type = e.cfgs["OUT_TYPE"] or e.cfgs["IO_TYPE"]
165     is_interactive = e.cfgs["TASK_TYPE"] == "interactive"
166
167     if out_type == "file":
168         out_path = e.cfgs["OUT_NAME"]
169     elif out_type == "stdio":
170         out_path = ".stdout"
171     if not os.path.exists(os.path.join(boxdir, out_path)):
172         raise moe.SolutionErr("No output file", "NO")
173     shutil.copyfile(os.path.join(boxdir, out_path), os.path.join(tdir, e.cfgs["TESTCASE_OUT"]))
174
175 def tests(e):
176     e.log.progress("\n")
177     e.test_pipe.insert(100, "prepare", test_in)
178     e.test_pipe.insert(200, "run", test_run)
179     e.test_pipe.insert(300, "collect", test_collect)
180     moe.testcase.run_tests(e)
181
182 def prepare_pipe(e):
183     e.main_pipe.insert(100, "compile-init", compile_init)
184     e.main_pipe.insert(150, "compile-run", compile_run)
185     e.main_pipe.insert(190, "compile-done", compile_done)
186     e.main_pipe.insert(200, "batch-tests", tests)