2 # Copyright (C) 2007 Mark Seaborn
4 # chroot_build is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU Lesser General Public License as
6 # published by the Free Software Foundation; either version 2.1 of the
7 # License, or (at your option) any later version.
9 # chroot_build is distributed in the hope that it will be useful, but
10 # WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 # Lesser General Public License for more details.
14 # You should have received a copy of the GNU Lesser General Public
15 # License along with chroot_build; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19 import cStringIO
as StringIO
27 import lxml
.etree
as etree
29 from chroot_build
import run_cmd
36 class NodeStreamTest(unittest
.TestCase
):
39 stream
= StringIO
.StringIO()
40 node
= build_log
.NodeWriter(build_log
.NodeStream(stream
), "root")
41 node
.add_attr("attr", "attribute value")
42 node2
= node
.new_child("child_node")
43 node2
.add_attr("foo", "bar")
44 xml
= build_log
.get_xml_from_log(StringIO
.StringIO(stream
.getvalue()))
45 self
.assertEquals(etree
.tostring(xml
, pretty_print
=True),
47 <root attr="attribute value">
48 <child_node foo="bar"/>
53 def write_file(filename
, data
):
54 fh
= open(filename
, "w")
61 class TempDirTestCase(unittest
.TestCase
):
64 super(TempDirTestCase
, self
).setUp()
68 for temp_dir
in self
._temp
_dirs
:
69 shutil
.rmtree(temp_dir
)
70 super(TempDirTestCase
, self
).tearDown()
72 def make_temp_dir(self
):
73 temp_dir
= tempfile
.mkdtemp(prefix
="tmp-%s-" % self
.__class
__.__name
__)
74 self
._temp
_dirs
.append(temp_dir
)
78 class GoldenTestCase(unittest
.TestCase
):
82 # Copied from xjack/golden_test.py. TODO: share the code.
83 def assert_golden(self
, dir_got
, dir_expect
):
84 assert os
.path
.exists(dir_expect
), dir_expect
85 proc
= subprocess
.Popen(["diff", "--recursive", "-u", "-N",
86 "--exclude=.*", dir_expect
, dir_got
],
87 stdout
=subprocess
.PIPE
)
88 stdout
, stderr
= proc
.communicate()
91 # Put expected output on the right because that is the
92 # side we usually edit.
93 subprocess
.call(["meld", dir_got
, dir_expect
])
95 "Differences from golden files found.\n"
96 "Try running with --meld to update golden files.\n"
98 self
.assertEquals(proc
.wait(), 0)
101 class LogSetDirTest(TempDirTestCase
):
104 logset
= build_log
.LogSetDir(os
.path
.join(self
.make_temp_dir(), "logs"))
105 # It should work before the directory has been created.
106 self
.assertEquals(len(list(logset
.get_logs())), 0)
107 log
= logset
.make_logger()
108 log2
= logset
.make_logger()
109 self
.assertEquals(len(list(logset
.get_logs())), 2)
110 list(logset
.get_logs())[0].get_timestamp()
112 def test_start_times(self
):
113 class Example(object):
118 @action_tree.action_node
120 return [self
.step
] * 5
122 logset
= build_log
.LogSetDir(self
.make_temp_dir(),
123 get_time
=lambda: example
.count
)
124 log
= logset
.make_logger()
125 example
.all_steps(log
)
126 xml
= logset
.get_logs().next().get_xml()
127 self
.assertEquals(xml
.xpath(".//@start_time"),
128 ["0", "0", "1", "2", "3", "4"])
132 class DummyTarget(object):
134 def __init__(self
, logset
):
135 self
._logset
= logset
141 return self
._logset
.get_logs()
144 class FormattingTest(TempDirTestCase
, GoldenTestCase
):
146 def test_formatted_log_output(self
):
147 logs_parent_dir
= self
.make_temp_dir()
148 logs_dir
= os
.path
.join(logs_parent_dir
, "logs")
149 logset
= build_log
.LogSetDir(logs_dir
, get_time
=lambda: 0)
150 log
= logset
.make_logger()
151 sublog
= log
.child_log("foo")
155 fh
.write("hello world\n")
157 targets
= [DummyTarget(logset
)]
158 output_dir
= self
.make_temp_dir()
159 mapper
= build_log
.PathnameMapper(logs_parent_dir
)
160 build_log
.format_logs(
161 targets
, mapper
, os
.path
.join(output_dir
, "long.html"))
162 format_log
.main(["--short", logs_dir
,
163 os
.path
.join(output_dir
, "short.html")])
164 self
.assert_golden(output_dir
, os
.path
.join(os
.path
.dirname(__file__
),
166 warn_log
.main([logs_dir
])
168 def test_format_logs_tool(self
):
169 log_dir
= self
.make_temp_dir()
170 log
= build_log
.LogSetDir(log_dir
).make_logger()
172 html_file
= os
.path
.join(self
.make_temp_dir(), "log.html")
173 subprocess
.check_call(["python", os
.path
.join(os
.path
.dirname(__file__
),
176 assert os
.path
.exists(html_file
)
178 def test_time_duration_formatting(self
):
184 (60*60*2 + 60 + 3, "2h01m03s"),
185 (24*60*60, "1d00h00m00s")]
186 for seconds
, expect
in pairs
:
187 self
.assertEquals(expect
, build_log
.format_duration(seconds
))
190 # TODO: make into a unit test
193 if os
.path
.exists(log_dir
):
194 shutil
.rmtree(log_dir
)
196 maker
= build_log
.LogDir(log_dir
)
197 log
= maker
.make_logger()
198 run_cmd(log
, ["echo", "Hello world!"])
199 log2
= log
.child_log("child")
200 log2
.message("This is a message")
203 print etree
.tostring(maker
.get_xml(), pretty_print
=True)
204 html
= build_log
.wrap_body(build_log
.format_log(maker
.get_xml()))
205 write_file(os
.path
.join("out-log", "log.html"),
206 etree
.tostring(html
, pretty_print
=True))
209 if __name__
== "__main__":
210 if sys
.argv
[1:2] == ["--meld"]:
211 GoldenTestCase
.run_meld
= True