228 } |
228 } |
229 case _ => log_file.err("cannot detect log header format") |
229 case _ => log_file.err("cannot detect log header format") |
230 } |
230 } |
231 } |
231 } |
232 |
232 |
|
233 |
|
234 /* build info: produced by isabelle build */ |
|
235 |
233 object Session_Status extends Enumeration |
236 object Session_Status extends Enumeration |
234 { |
237 { |
235 val UNKNOWN = Value("unknown") |
238 val EXISTING = Value("existing") |
236 val FINISHED = Value("finished") |
239 val FINISHED = Value("finished") |
237 val FAILED = Value("failed") |
240 val FAILED = Value("failed") |
238 val CANCELLED = Value("cancelled") |
241 val CANCELLED = Value("cancelled") |
239 } |
242 } |
240 |
243 |
241 |
244 sealed case class Session_Entry( |
242 /* main log: produced by isatest, afp-test, jenkins etc. */ |
245 chapter: String, |
243 |
246 groups: List[String], |
244 sealed case class Info( |
247 threads: Option[Int], |
245 settings: List[(String, String)], |
248 timing: Option[Timing], |
246 finished: Map[String, Timing], |
249 ml_timing: Option[Timing], |
247 timing: Map[String, Timing], |
250 status: Session_Status.Value) |
248 threads: Map[String, Int]) |
251 { |
249 { |
252 def ok: Boolean = status == Session_Status.EXISTING || status == Session_Status.FINISHED |
250 val sessions: Set[String] = finished.keySet ++ timing.keySet |
253 def finished: Boolean = status == Session_Status.FINISHED |
251 |
254 } |
252 override def toString: String = |
255 |
253 sessions.toList.sorted.mkString("Build_Log.Info(", ", ", ")") |
256 sealed case class Build_Info(sessions: Map[String, Session_Entry]) |
254 } |
257 { |
255 |
258 def session(name: String): Session_Entry = sessions(name) |
256 private val Session_Finished1 = |
259 def get_session(name: String): Option[Session_Entry] = sessions.get(name) |
257 new Regex("""^Finished (\S+) \((\d+):(\d+):(\d+) elapsed time, (\d+):(\d+):(\d+) cpu time.*$""") |
260 |
258 private val Session_Finished2 = |
261 def finished(name: String): Boolean = |
259 new Regex("""^Finished (\S+) \((\d+):(\d+):(\d+) elapsed time.*$""") |
262 get_session(name) match { |
260 private val Session_Timing = |
263 case Some(entry) => entry.finished |
261 new Regex("""^Timing (\S+) \((\d) threads, (\d+\.\d+)s elapsed time, (\d+\.\d+)s cpu time, (\d+\.\d+)s GC time.*$""") |
264 case None => false |
262 |
265 } |
263 private def parse_info(log_file: Log_File): Info = |
266 |
264 { |
267 def timing(name: String): Timing = |
265 val settings = new mutable.ListBuffer[(String, String)] |
268 (for (entry <- get_session(name); t <- entry.timing) yield t) getOrElse Timing.zero |
266 var finished = Map.empty[String, Timing] |
269 |
|
270 def ml_timing(name: String): Timing = |
|
271 (for (entry <- get_session(name); t <- entry.ml_timing) yield t) getOrElse Timing.zero |
|
272 } |
|
273 |
|
274 private def parse_build_info(log_file: Log_File): Build_Info = |
|
275 { |
|
276 object Chapter_Name |
|
277 { |
|
278 def unapply(s: String): Some[(String, String)] = |
|
279 space_explode('/', s) match { |
|
280 case List(chapter, name) => Some((chapter, name)) |
|
281 case _ => Some(("", s)) |
|
282 } |
|
283 } |
|
284 |
|
285 val Session_No_Groups = new Regex("""^Session (\S+)$""") |
|
286 val Session_Groups = new Regex("""^Session (\S+) \((.*)\)$""") |
|
287 val Session_Finished1 = |
|
288 new Regex("""^Finished (\S+) \((\d+):(\d+):(\d+) elapsed time, (\d+):(\d+):(\d+) cpu time.*$""") |
|
289 val Session_Finished2 = |
|
290 new Regex("""^Finished (\S+) \((\d+):(\d+):(\d+) elapsed time.*$""") |
|
291 val Session_Timing = |
|
292 new Regex("""^Timing (\S+) \((\d) threads, (\d+\.\d+)s elapsed time, (\d+\.\d+)s cpu time, (\d+\.\d+)s GC time.*$""") |
|
293 val Session_Failed = new Regex("""^(\S+) FAILED""") |
|
294 val Session_Cancelled = new Regex("""^(\S+) CANCELLED""") |
|
295 |
|
296 var chapter = Map.empty[String, String] |
|
297 var groups = Map.empty[String, List[String]] |
|
298 var threads = Map.empty[String, Int] |
267 var timing = Map.empty[String, Timing] |
299 var timing = Map.empty[String, Timing] |
268 var threads = Map.empty[String, Int] |
300 var ml_timing = Map.empty[String, Timing] |
|
301 var failed = Set.empty[String] |
|
302 var cancelled = Set.empty[String] |
|
303 def all_sessions: Set[String] = |
|
304 chapter.keySet ++ groups.keySet ++ threads.keySet ++ |
|
305 timing.keySet ++ ml_timing.keySet ++ failed ++ cancelled |
|
306 |
269 |
307 |
270 for (line <- log_file.lines) { |
308 for (line <- log_file.lines) { |
271 line match { |
309 line match { |
|
310 case Session_No_Groups(Chapter_Name(chapt, name)) => |
|
311 chapter += (name -> chapt) |
|
312 groups += (name -> Nil) |
|
313 case Session_Groups(Chapter_Name(chapt, name), grps) => |
|
314 chapter += (name -> chapt) |
|
315 groups += (name -> Word.explode(grps)) |
272 case Session_Finished1(name, |
316 case Session_Finished1(name, |
273 Value.Int(e1), Value.Int(e2), Value.Int(e3), |
317 Value.Int(e1), Value.Int(e2), Value.Int(e3), |
274 Value.Int(c1), Value.Int(c2), Value.Int(c3)) => |
318 Value.Int(c1), Value.Int(c2), Value.Int(c3)) => |
275 val elapsed = Time.hms(e1, e2, e3) |
319 val elapsed = Time.hms(e1, e2, e3) |
276 val cpu = Time.hms(c1, c2, c3) |
320 val cpu = Time.hms(c1, c2, c3) |
277 finished += (name -> Timing(elapsed, cpu, Time.zero)) |
321 timing += (name -> Timing(elapsed, cpu, Time.zero)) |
278 case Session_Finished2(name, |
322 case Session_Finished2(name, |
279 Value.Int(e1), Value.Int(e2), Value.Int(e3)) => |
323 Value.Int(e1), Value.Int(e2), Value.Int(e3)) => |
280 val elapsed = Time.hms(e1, e2, e3) |
324 val elapsed = Time.hms(e1, e2, e3) |
281 finished += (name -> Timing(elapsed, Time.zero, Time.zero)) |
325 timing += (name -> Timing(elapsed, Time.zero, Time.zero)) |
282 case Session_Timing(name, |
326 case Session_Timing(name, |
283 Value.Int(t), Value.Double(e), Value.Double(c), Value.Double(g)) => |
327 Value.Int(t), Value.Double(e), Value.Double(c), Value.Double(g)) => |
284 val elapsed = Time.seconds(e) |
328 val elapsed = Time.seconds(e) |
285 val cpu = Time.seconds(c) |
329 val cpu = Time.seconds(c) |
286 val gc = Time.seconds(g) |
330 val gc = Time.seconds(g) |
287 timing += (name -> Timing(elapsed, cpu, gc)) |
331 ml_timing += (name -> Timing(elapsed, cpu, gc)) |
288 threads += (name -> t) |
332 threads += (name -> t) |
289 case Settings.Entry(a, b) if Settings.all_settings.contains(a) => |
|
290 settings += (a -> b) |
|
291 case _ => |
333 case _ => |
292 } |
334 } |
293 } |
335 } |
294 |
336 |
295 Info(settings.toList, finished, timing, threads) |
337 val sessions = |
|
338 Map( |
|
339 (for (name <- all_sessions.toList) yield { |
|
340 val status = |
|
341 if (failed(name)) Session_Status.FAILED |
|
342 else if (cancelled(name)) Session_Status.CANCELLED |
|
343 else if (timing.isDefinedAt(name)) Session_Status.FINISHED |
|
344 else Session_Status.EXISTING |
|
345 val entry = |
|
346 Session_Entry( |
|
347 chapter.getOrElse(name, ""), |
|
348 groups.getOrElse(name, Nil), |
|
349 threads.get(name), |
|
350 timing.get(name), |
|
351 ml_timing.get(name), |
|
352 status) |
|
353 (name -> entry) |
|
354 }):_*) |
|
355 Build_Info(sessions) |
296 } |
356 } |
297 } |
357 } |