1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
package scala.tools
package partest
package io
import java.io.{ StringWriter, PrintWriter, Writer }
import scala.tools.nsc.io._
import scala.util.control.ControlThrowable
trait Logging {
universe: Universe =>
class PartestANSIWriter extends ANSIWriter(Console.out) {
override def colorful: Int = ANSIWriter(universe.isAnsi)
private def printIf(cond: Boolean, msg: String) =
if (cond) { outline("debug: ") ; println(msg) }
val verbose = printIf(isVerbose || isDebug, _: String)
val debug = printIf(isDebug, _: String)
}
lazy val NestUI = new PartestANSIWriter()
import NestUI.{ _outline, _success, _failure, _warning, _default }
def markOutline(msg: String) = _outline + msg + _default
def markSuccess(msg: String) = _success + msg + _default
def markFailure(msg: String) = _failure + msg + _default
def markWarning(msg: String) = _warning + msg + _default
def markNormal(msg: String) = _default + msg
def outline(msg: String) = NestUI outline msg
def success(msg: String) = NestUI success msg
def failure(msg: String) = NestUI failure msg
def warning(msg: String) = NestUI warning msg
def normal(msg: String) = NestUI normal msg
def verbose(msg: String) = NestUI verbose msg
def debug(msg: String) = NestUI debug msg
trait EntityLogging {
self: TestEntity =>
lazy val logWriter = new LogWriter(logFile)
/** Redirect stdout and stderr to logFile, run body, return result.
*/
def loggingOutAndErr[T](body: => T): T = {
val log = logFile.printStream(append = true)
try Console.withOut(log) {
Console.withErr(log) {
body
}
}
finally log.close()
}
/** What to print in a failure summary.
*/
def failureMessage() = if (diffOutput != "") diffOutput else safeSlurp(logFile)
/** For tracing. Outputs a line describing the next action. tracePath
* is a path wrapper which prints name or full path depending on verbosity.
*/
def trace(msg: String) = if (isTrace || isDryRun) System.err.println(">> [%s] %s".format(label, msg))
def tracePath(path: Path): String = if (isVerbose) path.path else path.name
def tracePath(path: String): String = tracePath(Path(path))
/** v == verbose.
*/
def vtrace(msg: String) = if (isVerbose) trace(msg)
/** Run body, writes result to logFile. Any throwable is
* caught, stringified, and written to the log.
*/
def loggingResult(body: => String) =
try returning(true)(_ => logFile writeAll body)
catch {
case x: ControlThrowable => throw x
case x: InterruptedException => debug(this + " received interrupt, failing.\n") ; false
case x: Throwable => logException(x)
}
def throwableToString(x: Throwable): String = {
val w = new StringWriter
x.printStackTrace(new PrintWriter(w))
w.toString
}
def warnAndLog(str: String) = {
warning(toStringTrunc(str, 800))
logWriter append str
}
def warnAndLogException(msg: String, ex: Throwable) =
warnAndLog(msg + throwableToString(ex))
def deleteLog(force: Boolean = false) =
if (universe.isNoCleanup && !force) debug("Not cleaning up " + logFile)
else logFile.deleteIfExists()
def onException(x: Throwable) { logException(x) }
def logException(x: Throwable) = {
val msg = throwableToString(x)
if (!isTerse)
normal(msg)
logWriter append msg
false
}
}
/** A writer which doesn't create the file until a write comes in.
*/
class LazilyCreatedWriter(log: File) extends Writer {
@volatile private var isCreated = false
private lazy val underlying = {
isCreated = true
log.bufferedWriter()
}
def flush() = if (isCreated) underlying.flush()
def close() = if (isCreated) underlying.close()
def write(chars: Array[Char], off: Int, len: Int) = {
underlying.write(chars, off, len)
underlying.flush()
}
}
class LogWriter(log: File) extends PrintWriter(new LazilyCreatedWriter(log), true) {
override def print(s: String) = {
super.print(s)
flush()
}
}
}
|