uttk 0.3.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/AUTHORS +36 -0
- data/COPYING +18 -0
- data/ChangeLog +7673 -0
- data/GUIDELINES +86 -0
- data/LGPL +504 -0
- data/NEWS +158 -0
- data/NORM +137 -0
- data/README +180 -0
- data/Rakefile +8 -0
- data/SPEC.gemspec +15 -0
- data/SPEC.yml +60 -0
- data/TODO +23 -0
- data/TODO.old +31 -0
- data/VERSION +5 -0
- data/bin/getopts/uttk.rb +390 -0
- data/bin/uttk +188 -0
- data/bin/uttk-unit +125 -0
- data/lib/uttk.rb +288 -0
- data/lib/uttk/dumpers/Basic.rb +23 -0
- data/lib/uttk/dumpers/BasicColor.rb +35 -0
- data/lib/uttk/dumpers/Dumper.rb +77 -0
- data/lib/uttk/dumpers/Html.rb +271 -0
- data/lib/uttk/dumpers/Path.rb +24 -0
- data/lib/uttk/dumpers/Xml.rb +88 -0
- data/lib/uttk/dumpers/Yaml.rb +138 -0
- data/lib/uttk/filters.rb +128 -0
- data/lib/uttk/filters/Buffer.rb +119 -0
- data/lib/uttk/filters/Compact.rb +75 -0
- data/lib/uttk/filters/Default.rb +27 -0
- data/lib/uttk/filters/DefaultColor.rb +27 -0
- data/lib/uttk/filters/Filter.rb +53 -0
- data/lib/uttk/filters/Id.rb +30 -0
- data/lib/uttk/filters/JustStatus.rb +25 -0
- data/lib/uttk/filters/KeepSkipBased.rb +38 -0
- data/lib/uttk/filters/NodeCut.rb +97 -0
- data/lib/uttk/filters/RPathFilter.rb +134 -0
- data/lib/uttk/filters/Saver.rb +53 -0
- data/lib/uttk/filters/TextFilter.rb +69 -0
- data/lib/uttk/generators/dumper_generator.rb +28 -0
- data/lib/uttk/generators/filter_generator.rb +28 -0
- data/lib/uttk/generators/generator.rb +86 -0
- data/lib/uttk/generators/generator_generator.rb +26 -0
- data/lib/uttk/generators/loader_generator.rb +28 -0
- data/lib/uttk/generators/path_filter_generator.rb +28 -0
- data/lib/uttk/generators/strategy_generator.rb +28 -0
- data/lib/uttk/generators/templates/dumper.rb +50 -0
- data/lib/uttk/generators/templates/filter.rb +50 -0
- data/lib/uttk/generators/templates/generator.rb +28 -0
- data/lib/uttk/generators/templates/loader.rb +26 -0
- data/lib/uttk/generators/templates/path_filter.rb +28 -0
- data/lib/uttk/generators/templates/strategy.rb +59 -0
- data/lib/uttk/generators/templates/strategy.yml +28 -0
- data/lib/uttk/generators/templates/unit_test.rb +46 -0
- data/lib/uttk/loaders/Loader.rb +180 -0
- data/lib/uttk/loaders/Ruby.rb +28 -0
- data/lib/uttk/loaders/Yaml.rb +98 -0
- data/lib/uttk/logger.rb +306 -0
- data/lib/uttk/logger/backend.rb +170 -0
- data/lib/uttk/logger/path.rb +202 -0
- data/lib/uttk/logger/section_node.rb +214 -0
- data/lib/uttk/logger/severity.rb +63 -0
- data/lib/uttk/logger/to_uttk_log.rb +127 -0
- data/lib/uttk/logger/verbosity.rb +61 -0
- data/lib/uttk/logger_factory.rb +55 -0
- data/lib/uttk/path_filters/ColorStatus.rb +57 -0
- data/lib/uttk/path_filters/PathFilter.rb +27 -0
- data/lib/uttk/path_filters/RemoveTypes.rb +25 -0
- data/lib/uttk/status.rb +146 -0
- data/lib/uttk/strategies/Abort.rb +24 -0
- data/lib/uttk/strategies/Assert.rb +44 -0
- data/lib/uttk/strategies/Authors.rb +45 -0
- data/lib/uttk/strategies/Block.rb +113 -0
- data/lib/uttk/strategies/Bootstrap.rb +55 -0
- data/lib/uttk/strategies/Checkout.rb +64 -0
- data/lib/uttk/strategies/Clean.rb +29 -0
- data/lib/uttk/strategies/Cmd.rb +60 -0
- data/lib/uttk/strategies/CmdBase.rb +130 -0
- data/lib/uttk/strategies/Collection.rb +158 -0
- data/lib/uttk/strategies/Compile.rb +59 -0
- data/lib/uttk/strategies/Composite.rb +201 -0
- data/lib/uttk/strategies/Composite/contents_eval.rb +40 -0
- data/lib/uttk/strategies/Configure.rb +66 -0
- data/lib/uttk/strategies/Error.rb +23 -0
- data/lib/uttk/strategies/Fail.rb +26 -0
- data/lib/uttk/strategies/IOBased.rb +159 -0
- data/lib/uttk/strategies/Import.rb +60 -0
- data/lib/uttk/strategies/Iterate.rb +139 -0
- data/lib/uttk/strategies/JUnit.rb +205 -0
- data/lib/uttk/strategies/KillAll.rb +62 -0
- data/lib/uttk/strategies/Make.rb +94 -0
- data/lib/uttk/strategies/Package.rb +129 -0
- data/lib/uttk/strategies/PackageCollection.rb +78 -0
- data/lib/uttk/strategies/Pass.rb +24 -0
- data/lib/uttk/strategies/Pool.rb +104 -0
- data/lib/uttk/strategies/ProbabilityThreshold.rb +46 -0
- data/lib/uttk/strategies/Proxy.rb +42 -0
- data/lib/uttk/strategies/RMatch.rb +92 -0
- data/lib/uttk/strategies/RUnit.rb +132 -0
- data/lib/uttk/strategies/SignalCmd.rb +85 -0
- data/lib/uttk/strategies/Sleep.rb +36 -0
- data/lib/uttk/strategies/SqlQuery.rb +120 -0
- data/lib/uttk/strategies/Strategy.rb +683 -0
- data/lib/uttk/strategies/Stub.rb +37 -0
- data/lib/uttk/strategies/SubCmd.rb +77 -0
- data/lib/uttk/strategies/Suite.rb +71 -0
- data/lib/uttk/strategies/Test.rb +89 -0
- data/lib/uttk/streams.rb +69 -0
- data/lib/uttk/streams/Diff.rb +60 -0
- data/lib/uttk/streams/HexaDiff.rb +35 -0
- data/lib/uttk/streams/Stream.rb +76 -0
- data/lib/uttk/weights.rb +17 -0
- data/lib/uttk/weights/WExpr.rb +68 -0
- data/lib/uttk/weights/WFloat.rb +23 -0
- data/lib/uttk/weights/WMin.rb +22 -0
- data/lib/uttk/weights/Weight.rb +105 -0
- data/lib/www/javascripts/uttk.js +185 -0
- data/misc/expandtab.rb +29 -0
- data/misc/header.rb +44 -0
- data/misc/renaming +57 -0
- data/misc/textile_compiler +194 -0
- data/misc/uttk-grep.sh +8 -0
- data/misc/uttk-line-count.rb +143 -0
- data/test/examples-suite.yml +8 -0
- data/test/examples/README +68 -0
- data/test/examples/basic.rb +10 -0
- data/test/examples/basic.yml +9 -0
- data/test/examples/cache/cache_and_fatal.yml +5 -0
- data/test/examples/cache/simple.yml +30 -0
- data/test/examples/sql/basic.yml +24 -0
- data/test/examples/students-suite.yml +9 -0
- data/test/examples/students/ball.yml +11 -0
- data/test/examples/students/glob_stud.yml +20 -0
- data/test/examples/students/mini-lib.yml +61 -0
- data/test/examples/students/pool_stud.yml +31 -0
- data/test/examples/students/stud.yml +21 -0
- data/test/fixtures/ball/20040804-exam_a1-zapngo-tessar_m.tar.gz +0 -0
- data/test/fixtures/ball/Makefile +24 -0
- data/test/fixtures/ball/bar_p-mini-lib.tar.bz2 +0 -0
- data/test/fixtures/ball/bar_p-mini-lib/Makefile +20 -0
- data/test/fixtures/ball/bar_p-mini-lib/my_strlen.c +13 -0
- data/test/fixtures/ball/foo_s-mini-lib.tar.bz2 +0 -0
- data/test/fixtures/ball/foo_s-mini-lib/Makefile +20 -0
- data/test/fixtures/ball/foo_s-mini-lib/configure +2 -0
- data/test/fixtures/ball/foo_s-mini-lib/my_strlen.c +10 -0
- data/test/fixtures/ball/hello.tar.bz2 +0 -0
- data/test/fixtures/ball/hello.tar.gz +0 -0
- data/test/fixtures/ball/hello/Makefile +14 -0
- data/test/fixtures/ball/hello/hello.c +7 -0
- data/test/fixtures/ball/jack-exit.tar.bz2 +0 -0
- data/test/fixtures/ball/jack-exit/Makefile +14 -0
- data/test/fixtures/ball/jack-exit/exit.c +16 -0
- data/test/fixtures/ball/joe-exit.tar.bz2 +0 -0
- data/test/fixtures/ball/joe-exit/Makefile +14 -0
- data/test/fixtures/ball/joe-exit/exit.c +8 -0
- data/test/fixtures/ball/joe_i-mini-lib.tar.bz2 +0 -0
- data/test/fixtures/ball/joe_i-mini-lib/Makefile +20 -0
- data/test/fixtures/ball/joe_i-mini-lib/configure +2 -0
- data/test/fixtures/ball/joe_i-mini-lib/my_strlen.c +10 -0
- data/test/fixtures/ball/john-exit.tar.bz2 +0 -0
- data/test/fixtures/ball/john-exit/Makefile +14 -0
- data/test/fixtures/ball/john-exit/exit.c +6 -0
- data/test/fixtures/ball/qux_j-mini-lib.tar.bz2 +0 -0
- data/test/fixtures/ball/qux_j-mini-lib/Makefile +20 -0
- data/test/fixtures/ball/qux_j-mini-lib/my_strlen.c +12 -0
- data/test/fixtures/binaries/segv +0 -0
- data/test/fixtures/binaries/segv.c +10 -0
- data/test/fixtures/binaries/segv.rb +2 -0
- data/test/fixtures/demo/command-tutorial/steps/1/check.yml +5 -0
- data/test/fixtures/demo/command-tutorial/steps/1/pluralizer.rb +10 -0
- data/test/fixtures/demo/command-tutorial/steps/2/bad_check.yml +7 -0
- data/test/fixtures/demo/command-tutorial/steps/2/check.yml +7 -0
- data/test/fixtures/demo/command-tutorial/steps/2/pluralizer.rb +10 -0
- data/test/fixtures/demo/command-tutorial/steps/3.1/check.yml +12 -0
- data/test/fixtures/demo/command-tutorial/steps/3/check.yml +14 -0
- data/test/fixtures/demo/command-tutorial/steps/4.1/bird.txt +1 -0
- data/test/fixtures/demo/command-tutorial/steps/4.1/check.yml +12 -0
- data/test/fixtures/demo/command-tutorial/steps/4/check.yml +12 -0
- data/test/fixtures/demo/command-tutorial/steps/4/pluralizer.rb +12 -0
- data/test/fixtures/demo/command-tutorial/steps/5.1/bird.txt +1 -0
- data/test/fixtures/demo/command-tutorial/steps/5.1/check.yml +17 -0
- data/test/fixtures/demo/command-tutorial/steps/5.1/pluralizer.rb +17 -0
- data/test/fixtures/demo/command-tutorial/steps/5/bird.txt +1 -0
- data/test/fixtures/demo/command-tutorial/steps/5/check.yml +16 -0
- data/test/fixtures/demo/command-tutorial/steps/5/pluralizer.rb +16 -0
- data/test/fixtures/demo/command-tutorial/steps/6.1/bird.txt +1 -0
- data/test/fixtures/demo/command-tutorial/steps/6.1/check.yml +22 -0
- data/test/fixtures/demo/command-tutorial/steps/6.1/pluralizer.rb +17 -0
- data/test/fixtures/demo/command-tutorial/steps/6/bird.txt +1 -0
- data/test/fixtures/demo/command-tutorial/steps/6/check.yml +21 -0
- data/test/fixtures/demo/command-tutorial/steps/6/pluralizer.rb +17 -0
- data/test/fixtures/demo/command-tutorial/steps/7/bird.txt +1 -0
- data/test/fixtures/demo/command-tutorial/steps/7/check.yml +22 -0
- data/test/fixtures/demo/command-tutorial/steps/7/pluralizer.rb +17 -0
- data/test/fixtures/demo/filter-tutorial/check.yml +20 -0
- data/test/fixtures/demo/filter-tutorial/filters/CutSkip100.rb +19 -0
- data/test/fixtures/demo/filter-tutorial/pluralizer.rb +17 -0
- data/test/fixtures/java/unit/MultiRight/Foo/Foo.java +11 -0
- data/test/fixtures/java/unit/MultiRight/Foo/FooTest.java +15 -0
- data/test/fixtures/java/unit/MultiRight/MultiRight.java +13 -0
- data/test/fixtures/java/unit/MultiRight/MultiRightTest.java +12 -0
- data/test/fixtures/java/unit/MultiRight/bar/Bar.java +11 -0
- data/test/fixtures/java/unit/MultiRight/bar/BarTest.java +21 -0
- data/test/fixtures/java/unit/MultiRight/build.sh +7 -0
- data/test/fixtures/java/unit/SimpleException/SimpleExceptionTest.java +11 -0
- data/test/fixtures/java/unit/SimpleException/build.sh +4 -0
- data/test/fixtures/java/unit/build.sh +9 -0
- data/test/fixtures/java/unit/multibar.yml +6 -0
- data/test/fixtures/java/unit/multifoo.yml +6 -0
- data/test/fixtures/java/unit/multiright.yml +8 -0
- data/test/fixtures/java/unit/simple_exception.yml +6 -0
- data/test/fixtures/mini-lib/Makefile +9 -0
- data/test/fixtures/mini-lib/strlen.c +15 -0
- data/test/fixtures/package/pkg_foo.tar.gz +0 -0
- data/test/fixtures/package/pkg_foo/Makefile +20 -0
- data/test/fixtures/package/pkg_foo/bootstrap +3 -0
- data/test/fixtures/package/pkg_foo/configure +3 -0
- data/test/fixtures/package/pkg_foo/foo.sh +2 -0
- data/test/fixtures/text/1.txt +4 -0
- data/test/fixtures/unit/bad.rb +26 -0
- data/test/fixtures/unit/error.rb +6 -0
- data/test/fixtures/unit/good.rb +26 -0
- data/test/functional-suite.yml +10 -0
- data/test/functional/author.yml +11 -0
- data/test/functional/base.yml +119 -0
- data/test/functional/base_pool.yml +13 -0
- data/test/functional/block.yml +13 -0
- data/test/functional/cat.yml +16 -0
- data/test/functional/cmd.yml +17 -0
- data/test/functional/diff.yml +27 -0
- data/test/functional/env_cmd.yml +53 -0
- data/test/functional/exit.yml +15 -0
- data/test/functional/fatal.yml +23 -0
- data/test/functional/glob.yml +11 -0
- data/test/functional/hexa-diff.yml +25 -0
- data/test/functional/import.yml +41 -0
- data/test/functional/iterate.yml +99 -0
- data/test/functional/killall.yml +31 -0
- data/test/functional/pkg.yml +14 -0
- data/test/functional/probability_threshold.yml +35 -0
- data/test/functional/r_unit.yml +26 -0
- data/test/functional/rmatch.yml +122 -0
- data/test/functional/signal_cmd.yml +22 -0
- data/test/functional/sub.yml +15 -0
- data/test/functional/test.yml +25 -0
- data/test/functional/timeout.yml +20 -0
- data/test/functional/wc.yml +26 -0
- data/test/functional/weight.yml +152 -0
- data/test/pkg-suite.yml +8 -0
- data/test/pkg/cmdline.yml +80 -0
- data/test/pool-suite.yml +8 -0
- data/test/pool/base.yml +12 -0
- data/test/pool/pool.yml +25 -0
- data/test/ruby-suite.rb +10 -0
- data/test/ruby-suite.yml +5 -0
- data/test/ruby/base.rb +119 -0
- data/test/ruby/iterate.rb +21 -0
- data/test/ruby/wc.rb +43 -0
- data/test/unit-suite.yml +10 -0
- data/test/unit/dumpers/path_test.rb +46 -0
- data/test/unit/dumpers/xml_test.rb +65 -0
- data/test/unit/dumpers/yaml_test.rb +65 -0
- data/test/unit/filters/buffer_test.rb +168 -0
- data/test/unit/filters/keep_skip_based_test.rb +46 -0
- data/test/unit/filters/node_cut_test.rb +72 -0
- data/test/unit/filters/rpath_filter_test.rb +191 -0
- data/test/unit/filters/text_filter_test.rb +46 -0
- data/test/unit/filters_test.rb +119 -0
- data/test/unit/logger/section_node_test.rb +120 -0
- data/test/unit/logger/severity_test.rb +37 -0
- data/test/unit/logger/to_uttk_log_test.rb +113 -0
- data/test/unit/logger/verbosity_test.rb +44 -0
- data/test/unit/logger_test.rb +203 -0
- data/test/unit/strategies/suite_test.rb +151 -0
- data/test/uttk-check.yml +8 -0
- data/test/uttk-distcheck.yml +18 -0
- metadata +399 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Author:: Vincent CUISSARD <cuissa_v@epita.fr>.
|
|
2
|
+
# Copyright:: Copyright (c) 2005 Uttk Team. All rights reserved.
|
|
3
|
+
# License:: LGPL
|
|
4
|
+
# $Id: /fey/uttk/trunk/lib/uttk/strategies/SignalCmd.rb 8789 2005-09-27T14:49:49.088376Z ertai $
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
module Uttk
|
|
8
|
+
|
|
9
|
+
module Strategies
|
|
10
|
+
|
|
11
|
+
class SignalCmd < Cmd
|
|
12
|
+
include Concrete
|
|
13
|
+
|
|
14
|
+
@@signal_names = nil
|
|
15
|
+
|
|
16
|
+
#
|
|
17
|
+
# Methods
|
|
18
|
+
#
|
|
19
|
+
|
|
20
|
+
def run_impl
|
|
21
|
+
super
|
|
22
|
+
|
|
23
|
+
# Check if command has exited normaly
|
|
24
|
+
case
|
|
25
|
+
when @my_status.exited?
|
|
26
|
+
# Process run successfully
|
|
27
|
+
@my_signaled = false
|
|
28
|
+
when @my_status.signaled?
|
|
29
|
+
# Process was signaled
|
|
30
|
+
@my_signaled = true
|
|
31
|
+
@my_exit = 128 + @my_status.termsig
|
|
32
|
+
else
|
|
33
|
+
# Problem on process
|
|
34
|
+
fail('process may be ill')
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
protected :run_impl
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def assertion
|
|
41
|
+
case
|
|
42
|
+
when (@my_signaled and not @signaled)
|
|
43
|
+
fail("command was signaled by #{SignalCmd.signal_name(@my_exit)}")
|
|
44
|
+
when (not @my_signaled and @signaled)
|
|
45
|
+
fail("command wasn't signaled by #@signal")
|
|
46
|
+
when (@my_signaled == @signaled and @signaled)
|
|
47
|
+
sig_name = SignalCmd.signal_name(@my_exit)
|
|
48
|
+
unless sig_name == signal
|
|
49
|
+
err = "command signaled by #{sig_name}, "
|
|
50
|
+
err << "must be signaled by #@signal"
|
|
51
|
+
fail(err)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
super
|
|
55
|
+
end
|
|
56
|
+
protected :assertion
|
|
57
|
+
|
|
58
|
+
def SignalCmd.signal_name ( status )
|
|
59
|
+
signal = status - 128
|
|
60
|
+
if @@signal_names.nil?
|
|
61
|
+
@@signal_names = { }
|
|
62
|
+
Signal.list.each do |key, value|
|
|
63
|
+
@@signal_names[value] = key
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
@@signal_names[signal]
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def signal= ( signal_name )
|
|
70
|
+
@signal = signal_name
|
|
71
|
+
@signaled = true
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
#
|
|
75
|
+
# Attributes
|
|
76
|
+
#
|
|
77
|
+
|
|
78
|
+
attribute :signal, 'the signal name', nil
|
|
79
|
+
attribute :signaled, 'process must be signaled', false
|
|
80
|
+
|
|
81
|
+
end # class SignalCmd
|
|
82
|
+
|
|
83
|
+
end # module Strategies
|
|
84
|
+
|
|
85
|
+
end # module Uttk
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Author:: Nicolas Despres <nicolas.despres@gmail.com>.
|
|
2
|
+
# Copyright:: Copyright (c) 2004, 2005 Uttk team. All rights reserved.
|
|
3
|
+
# License:: LGPL
|
|
4
|
+
# $Id: /fey/uttk/trunk/lib/uttk/strategies/Sleep.rb 8789 2005-09-27T14:49:49.088376Z ertai $
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
module Uttk
|
|
8
|
+
|
|
9
|
+
module Strategies
|
|
10
|
+
|
|
11
|
+
# A test strategy class that only sleep for a moment before to pass.
|
|
12
|
+
class Sleep < Strategy
|
|
13
|
+
include Concrete
|
|
14
|
+
|
|
15
|
+
def delay=(other)
|
|
16
|
+
other = other.to_f
|
|
17
|
+
if other >= 0
|
|
18
|
+
@delay = other
|
|
19
|
+
else
|
|
20
|
+
raise(ArgumentError, "`#{other}' - sleep delay must be >= 0")
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
protected
|
|
25
|
+
def run_impl
|
|
26
|
+
sleep(@delay)
|
|
27
|
+
pass
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
attribute :delay, 'Delay in second to sleep', 0
|
|
31
|
+
|
|
32
|
+
end # class Sleep
|
|
33
|
+
|
|
34
|
+
end # module Strategies
|
|
35
|
+
|
|
36
|
+
end # module Uttk
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# Author:: Vincent Cuissard <cuissa_v@epita.fr>
|
|
2
|
+
# Copyright:: Copyright (c) 2004, 2005 Uttk team. All rights reserved.
|
|
3
|
+
# License:: LGPL
|
|
4
|
+
# $Id: /fey/uttk/trunk/lib/uttk/strategies/SqlQuery.rb 8789 2005-09-27T14:49:49.088376Z ertai $
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
module Uttk
|
|
8
|
+
|
|
9
|
+
module Strategies
|
|
10
|
+
|
|
11
|
+
#
|
|
12
|
+
# This strategy manage _SQL_ base tests.
|
|
13
|
+
# It use unit testing (EXCEPT ALL query) for checking results.
|
|
14
|
+
# To use it, you need to have _dbi_ installed on your test system
|
|
15
|
+
# and have a database with these things:
|
|
16
|
+
# * a test schema (MY)
|
|
17
|
+
# * a reference schema (REF)
|
|
18
|
+
#
|
|
19
|
+
# After that you have just to write all queries that you want to test.
|
|
20
|
+
# Queries will be called on each schema by applying a delta operation:
|
|
21
|
+
# (REF ` MY) U (MY ` REF).
|
|
22
|
+
#
|
|
23
|
+
# In queries, %s will be replaced by given schemas.
|
|
24
|
+
#
|
|
25
|
+
|
|
26
|
+
class SqlQuery < Strategy
|
|
27
|
+
include Concrete
|
|
28
|
+
|
|
29
|
+
@@db = nil
|
|
30
|
+
|
|
31
|
+
#
|
|
32
|
+
# Methods
|
|
33
|
+
#
|
|
34
|
+
|
|
35
|
+
def prologue
|
|
36
|
+
super
|
|
37
|
+
if @@db.nil?
|
|
38
|
+
require 'dbi'
|
|
39
|
+
# Check if driver is available
|
|
40
|
+
if DBI.available_drivers.to_s !~ /#@driver/
|
|
41
|
+
raise_error("Unknown driver: #@driver")
|
|
42
|
+
else
|
|
43
|
+
# Start DB connection
|
|
44
|
+
@@db = DBI.connect("DBI:#@driver:host=#@host;database=#@database",
|
|
45
|
+
@user, @passwd)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
protected :prologue
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def run_impl
|
|
53
|
+
@delta = nil
|
|
54
|
+
begin
|
|
55
|
+
@delta = perform_delta
|
|
56
|
+
rescue DBI::DatabaseError => ex
|
|
57
|
+
fail(ex)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
protected :run_impl
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def assertion
|
|
64
|
+
unless @delta.nil?
|
|
65
|
+
@log.diff_output = @delta
|
|
66
|
+
fail('Delta not empty')
|
|
67
|
+
end
|
|
68
|
+
super
|
|
69
|
+
end
|
|
70
|
+
protected :assertion
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def perform_delta
|
|
74
|
+
output_a = []
|
|
75
|
+
output_b = []
|
|
76
|
+
|
|
77
|
+
# Make queries
|
|
78
|
+
ref_query = @query.gsub(/%s/, @ref_schema)
|
|
79
|
+
my_query = @query.gsub(/%s/, @my_schema)
|
|
80
|
+
|
|
81
|
+
# Perform REF ` MY
|
|
82
|
+
@@db.execute("#{ref_query} EXCEPT ALL #{my_query}").fetch do |row|
|
|
83
|
+
output_a << row.join(' | ')
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Perform MY ` REF
|
|
87
|
+
@@db.execute("#{my_query} EXCEPT ALL #{ref_query}").fetch do |row|
|
|
88
|
+
output_b << row.join(' | ')
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# REF DELTA MY => (REF ` MY) U (MY ` REF) = {}
|
|
92
|
+
# Check this
|
|
93
|
+
return nil if output_a.empty? and output_b.empty?
|
|
94
|
+
|
|
95
|
+
# Make report
|
|
96
|
+
{ :'REF ` MY' => output_a.join("\n"),
|
|
97
|
+
:'MY ` REF' => output_b.join("\n") }
|
|
98
|
+
end
|
|
99
|
+
private :perform_delta
|
|
100
|
+
|
|
101
|
+
#
|
|
102
|
+
# Attributes
|
|
103
|
+
#
|
|
104
|
+
|
|
105
|
+
attribute :my_schema, 'Test schema', 'my'
|
|
106
|
+
attribute :ref_schema, 'Reference schema', 'ref'
|
|
107
|
+
attribute :query, 'SQL query (%s for the schema)', :mandatory
|
|
108
|
+
attribute :driver, 'SQL server driver', :mandatory
|
|
109
|
+
attribute :database, 'SQL database name', :mandatory
|
|
110
|
+
attribute :host, 'SQL server host', :mandatory
|
|
111
|
+
attribute :user, 'SQL user', :mandatory
|
|
112
|
+
attribute :passwd, 'SQL pass', :mandatory
|
|
113
|
+
|
|
114
|
+
end # class SqlQuery
|
|
115
|
+
|
|
116
|
+
end # module Strategies
|
|
117
|
+
|
|
118
|
+
end # module Uttk
|
|
119
|
+
|
|
120
|
+
|
|
@@ -0,0 +1,683 @@
|
|
|
1
|
+
# Author:: The Uttk Team.
|
|
2
|
+
# Copyright:: Copyright (c) 2004, 2005 Uttk team. All rights reserved.
|
|
3
|
+
# License:: LGPL
|
|
4
|
+
# $Id: /w/fey/uttk/trunk/lib/uttk/strategies/Strategy.rb 22184 2006-02-23T16:12:25.225774Z pouillar $
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
require 'set'
|
|
8
|
+
require 'timeout'
|
|
9
|
+
|
|
10
|
+
module Uttk
|
|
11
|
+
|
|
12
|
+
# A tutorial introduces how to create new strategies at
|
|
13
|
+
# http://uttk.org/shelf/documentation
|
|
14
|
+
module Strategies
|
|
15
|
+
|
|
16
|
+
# This is the base class for anything _testable_. It provides some basics
|
|
17
|
+
# attributes like the name of the test.
|
|
18
|
+
class Strategy
|
|
19
|
+
include Abstract
|
|
20
|
+
include AttributedClass
|
|
21
|
+
|
|
22
|
+
class AttributedClass::Attribute
|
|
23
|
+
alias :initialize_without_expand :initialize
|
|
24
|
+
def initialize ( name, desc, *a, &b )
|
|
25
|
+
my, our = a.partition { |x| x == :dont_expand }
|
|
26
|
+
@expand = my.empty?
|
|
27
|
+
initialize_without_expand(name, desc, *our, &b)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def expand?
|
|
31
|
+
@expand
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
#
|
|
36
|
+
# Accessors
|
|
37
|
+
#
|
|
38
|
+
|
|
39
|
+
attr_reader :status
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
#
|
|
43
|
+
# Constructor
|
|
44
|
+
#
|
|
45
|
+
|
|
46
|
+
# Create a new Strategy with the given optional document.
|
|
47
|
+
def initialize ( name=nil, &block )
|
|
48
|
+
@status = StartStatus.new
|
|
49
|
+
@symbols = {}
|
|
50
|
+
@symtbl = nil
|
|
51
|
+
initialize_attributes
|
|
52
|
+
@save = nil
|
|
53
|
+
@reject = Set.new
|
|
54
|
+
self.name = name
|
|
55
|
+
if block
|
|
56
|
+
if block.arity == -1
|
|
57
|
+
instance_eval(&block)
|
|
58
|
+
else
|
|
59
|
+
block[self]
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
module UttkTimeout
|
|
65
|
+
module_function
|
|
66
|
+
def timeout(sec, flow, exception=Error, &block)
|
|
67
|
+
return block[] if sec == nil or sec.zero?
|
|
68
|
+
begin
|
|
69
|
+
x = Thread.current
|
|
70
|
+
y = Thread.start do
|
|
71
|
+
sleep sec
|
|
72
|
+
if x.alive?
|
|
73
|
+
flow << :abort
|
|
74
|
+
x.raise exception, "execution expired"
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
block[sec]
|
|
78
|
+
ensure
|
|
79
|
+
y.kill if y and y.alive?
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end # module UttkTimeout
|
|
83
|
+
|
|
84
|
+
#
|
|
85
|
+
# Methods
|
|
86
|
+
#
|
|
87
|
+
|
|
88
|
+
# Runs this test, proceding like this:
|
|
89
|
+
# - check_pre_assertion
|
|
90
|
+
# - prologue
|
|
91
|
+
# - run_impl
|
|
92
|
+
# - assertion
|
|
93
|
+
# - check_post_assertion
|
|
94
|
+
# - epilogue
|
|
95
|
+
def run ( log=@symtbl[:log] )
|
|
96
|
+
unless @status.is_a? StartStatus
|
|
97
|
+
raise_error("This test was already run (#{self} : #{self.class})")
|
|
98
|
+
end
|
|
99
|
+
@log = log
|
|
100
|
+
@benchmark = []
|
|
101
|
+
initialize_flow_factory if @symtbl[:flow_factory].nil?
|
|
102
|
+
flow = @symtbl[:flow]
|
|
103
|
+
flow << :prologue
|
|
104
|
+
|
|
105
|
+
@status = RunningStatus.new
|
|
106
|
+
@thread = Thread.current
|
|
107
|
+
|
|
108
|
+
aborted = nil
|
|
109
|
+
weight_copy = nil
|
|
110
|
+
|
|
111
|
+
@upper = @log.upper
|
|
112
|
+
begin
|
|
113
|
+
begin
|
|
114
|
+
|
|
115
|
+
# Pre assertion
|
|
116
|
+
pre_assertion_failed = nil
|
|
117
|
+
begin
|
|
118
|
+
unless r = check_pre_assertion()
|
|
119
|
+
pre_assertion_failed = "Pre assertion failed (#{r.inspect})"
|
|
120
|
+
end
|
|
121
|
+
rescue Exception => ex
|
|
122
|
+
pre_assertion_failed = "Pre assertion failed (#{ex})"
|
|
123
|
+
end
|
|
124
|
+
if pre_assertion_failed
|
|
125
|
+
@log.new_node(to_s)
|
|
126
|
+
@symtbl[:flow] << :error
|
|
127
|
+
skip(pre_assertion_failed)
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
begin
|
|
131
|
+
@benchmark << Benchmark.measure('prologue') do
|
|
132
|
+
prologue()
|
|
133
|
+
weight_copy = @weight
|
|
134
|
+
end
|
|
135
|
+
# @log.flow_id = flow.i
|
|
136
|
+
|
|
137
|
+
# Catch all other exceptions and wrapped them in an error.
|
|
138
|
+
rescue Exception => ex
|
|
139
|
+
raise_error(ex)
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
msg = "abort '%name' with timeout #{@timeout}s"
|
|
143
|
+
specific_abort = TimeoutAbortStatus.new(msg)
|
|
144
|
+
|
|
145
|
+
begin
|
|
146
|
+
flow << :begin_run_impl
|
|
147
|
+
skip_if_cached
|
|
148
|
+
skip_wrt_rpath_and_rpath_exclude
|
|
149
|
+
UttkTimeout.timeout(@timeout, flow, specific_abort) do
|
|
150
|
+
@benchmark << Benchmark.measure('run') do
|
|
151
|
+
run_impl()
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
ensure
|
|
155
|
+
flow << :end_run_impl
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
# Post assertion
|
|
159
|
+
post_assertion_failed = nil
|
|
160
|
+
begin
|
|
161
|
+
unless r = check_post_assertion()
|
|
162
|
+
post_assertion_failed = "Post assertion failed (#{r.inspect})"
|
|
163
|
+
end
|
|
164
|
+
rescue Exception => ex
|
|
165
|
+
post_assertion_failed = "Post assertion failed (#{ex})"
|
|
166
|
+
end
|
|
167
|
+
fail(post_assertion_failed) if post_assertion_failed
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
# Assertion
|
|
171
|
+
assertion()
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
raise_error('no status given')
|
|
175
|
+
|
|
176
|
+
# Forward StatusException
|
|
177
|
+
rescue Status => ex
|
|
178
|
+
# Put the exception in `aborted' if it dosen't concern me and abort.
|
|
179
|
+
if ex.is_a? TimeoutAbortStatus
|
|
180
|
+
aborted = ex if ex != specific_abort
|
|
181
|
+
ex.reason.gsub!('%name', @name.to_s)
|
|
182
|
+
end
|
|
183
|
+
raise ex
|
|
184
|
+
|
|
185
|
+
# Catch all others exceptions and wrapped them in an error.
|
|
186
|
+
rescue Exception => ex
|
|
187
|
+
raise_error(ex)
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
# Threat Status exceptions
|
|
191
|
+
rescue Status => ex
|
|
192
|
+
begin
|
|
193
|
+
|
|
194
|
+
flow << :epilogue
|
|
195
|
+
@status = ex
|
|
196
|
+
# Call the specific hook (pass_hook, failed_hook...).
|
|
197
|
+
send(ex.hook_name)
|
|
198
|
+
unless pre_assertion_failed
|
|
199
|
+
@benchmark << Benchmark.measure('epilogue') do
|
|
200
|
+
epilogue()
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
rescue SynFlow::Error => ex
|
|
204
|
+
display_unexpected_synflow_exc ex, :epilogue
|
|
205
|
+
|
|
206
|
+
rescue Exception => ex
|
|
207
|
+
display_unexpected_exc ex
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
rescue Exception => ex
|
|
211
|
+
display_unexpected_exc ex
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
begin
|
|
215
|
+
if @symtbl[:benchmark] and (not @reject.include?(:benchmark))
|
|
216
|
+
@log.new_node(:benchmark, :ordered => true) do
|
|
217
|
+
@benchmark.each { |b| @log << b }
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
@log << status unless @reject.include?(:status)
|
|
221
|
+
@status.weight *= weight_copy
|
|
222
|
+
@upper.up
|
|
223
|
+
if cache = @symtbl[:cache]
|
|
224
|
+
cache[@symtbl[:pathname]] =
|
|
225
|
+
{
|
|
226
|
+
:status => @status,
|
|
227
|
+
:symtbl => @symtbl.local
|
|
228
|
+
}
|
|
229
|
+
end
|
|
230
|
+
@reject.clear if defined? @reject
|
|
231
|
+
clean_instance_variables
|
|
232
|
+
flow << :finish
|
|
233
|
+
rescue SynFlow::Error => ex
|
|
234
|
+
display_unexpected_synflow_exc ex, :finish
|
|
235
|
+
rescue Exception => ex
|
|
236
|
+
display_unexpected_exc ex
|
|
237
|
+
end
|
|
238
|
+
raise aborted unless aborted.nil?
|
|
239
|
+
return @status
|
|
240
|
+
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
alias call run
|
|
244
|
+
|
|
245
|
+
#
|
|
246
|
+
# Custom accessors
|
|
247
|
+
#
|
|
248
|
+
|
|
249
|
+
def wclass=(other)
|
|
250
|
+
if other.is_a?(Class)
|
|
251
|
+
@wclass = other
|
|
252
|
+
else
|
|
253
|
+
@wclass = Uttk::Weights.const_get(other.to_s)
|
|
254
|
+
end
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
#
|
|
258
|
+
# Assign
|
|
259
|
+
#
|
|
260
|
+
|
|
261
|
+
# Assign an attribute safely from a key:String and a value.
|
|
262
|
+
def assign_one(key, val, silent=false)
|
|
263
|
+
return if [:strategy].include? key.to_sym
|
|
264
|
+
meth = key.to_s + '='
|
|
265
|
+
if !val.nil?
|
|
266
|
+
if respond_to?(meth) or respond_to?(:method_missing)
|
|
267
|
+
send(meth, val)
|
|
268
|
+
elsif not silent
|
|
269
|
+
@log.warn { "Attribute #{key} not found for #{self.class}" }
|
|
270
|
+
end
|
|
271
|
+
end
|
|
272
|
+
end
|
|
273
|
+
protected :assign_one
|
|
274
|
+
|
|
275
|
+
# This can be overrided to specify which attribute is assign at last.
|
|
276
|
+
def assign_at_last
|
|
277
|
+
nil
|
|
278
|
+
end
|
|
279
|
+
protected :assign_at_last
|
|
280
|
+
|
|
281
|
+
# Assign a +hsh+ keeping at last the attribute referenced by
|
|
282
|
+
# _assign_at_last_.
|
|
283
|
+
def assign(hsh)
|
|
284
|
+
last = assign_at_last
|
|
285
|
+
hsh.each_pair { |key, val| assign_one(key, val) if key.to_sym != last }
|
|
286
|
+
assign_one(last, hsh[last]) if hsh.has_key? last
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
#
|
|
290
|
+
# Reject
|
|
291
|
+
#
|
|
292
|
+
|
|
293
|
+
def reject ( *att )
|
|
294
|
+
@reject += att.map! { |a| a.to_sym }
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
def initialize_flow_factory
|
|
298
|
+
factory = SynFlowFactory.new
|
|
299
|
+
factory <<
|
|
300
|
+
{
|
|
301
|
+
:start_st => {
|
|
302
|
+
:prologue => :prologue_st,
|
|
303
|
+
:not_running? => :start_st,
|
|
304
|
+
:end_run_impl => :after_run_st,
|
|
305
|
+
# :abort => :start_st,
|
|
306
|
+
:error => :error_st
|
|
307
|
+
},
|
|
308
|
+
|
|
309
|
+
:prologue_st => {
|
|
310
|
+
:begin_run_impl => :run_impl_st,
|
|
311
|
+
:error => :error_st
|
|
312
|
+
},
|
|
313
|
+
|
|
314
|
+
:run_impl_st => {
|
|
315
|
+
:prologue => :prologue_st,
|
|
316
|
+
:end_run_impl => :after_run_st,
|
|
317
|
+
:abort => :abort_st,
|
|
318
|
+
:error => :error_st
|
|
319
|
+
},
|
|
320
|
+
|
|
321
|
+
:after_run_st => {
|
|
322
|
+
:epilogue => :epilogue_st,
|
|
323
|
+
:error => :error_st
|
|
324
|
+
},
|
|
325
|
+
|
|
326
|
+
:epilogue_st => {
|
|
327
|
+
:finish => :start_st,
|
|
328
|
+
:error => :error_st
|
|
329
|
+
},
|
|
330
|
+
|
|
331
|
+
:abort_st => {
|
|
332
|
+
:end_run_impl => :after_run_abort_st,
|
|
333
|
+
:abort => :abort_st,
|
|
334
|
+
:error => :error_st
|
|
335
|
+
},
|
|
336
|
+
|
|
337
|
+
:after_run_abort_st => {
|
|
338
|
+
:epilogue => :epilogue_abort_st,
|
|
339
|
+
:abort => :after_run_abort_st,
|
|
340
|
+
:error => :error_st
|
|
341
|
+
},
|
|
342
|
+
|
|
343
|
+
:epilogue_abort_st => {
|
|
344
|
+
:finish => :start_st,
|
|
345
|
+
:error => :error_st
|
|
346
|
+
},
|
|
347
|
+
|
|
348
|
+
:error_st => {
|
|
349
|
+
:prologue => :prologue_st,
|
|
350
|
+
:begin_run_impl => :run_impl_st,
|
|
351
|
+
:end_run_impl => :after_run_st,
|
|
352
|
+
:epilogue => :epilogue_st,
|
|
353
|
+
:finish => :start_st,
|
|
354
|
+
:no_running? => :error_st,
|
|
355
|
+
:error => :error_st,
|
|
356
|
+
:abort => :abort_st
|
|
357
|
+
},
|
|
358
|
+
}
|
|
359
|
+
factory.initial = :start_st
|
|
360
|
+
@symtbl[:flow_factory] = factory
|
|
361
|
+
@symtbl[:flow] = factory.new_flow
|
|
362
|
+
end
|
|
363
|
+
|
|
364
|
+
def skip_if_cached
|
|
365
|
+
if cache = @symtbl[:use_cache]
|
|
366
|
+
me = cache[@symtbl[:pathname].to_sym]
|
|
367
|
+
if me and @symtbl[:cache_proc][self, me[:status]]
|
|
368
|
+
@symtbl.local.merge!(me[:symtbl])
|
|
369
|
+
skip(@wclass.new(me[:status].weight))
|
|
370
|
+
end
|
|
371
|
+
end
|
|
372
|
+
end
|
|
373
|
+
|
|
374
|
+
def skip_wrt_rpath_and_rpath_exclude
|
|
375
|
+
re = @symtbl[:rpath]
|
|
376
|
+
re_ex = @symtbl[:rpath_exclude]
|
|
377
|
+
lpath = @log.path
|
|
378
|
+
if re and not lpath.lpath_prefix re
|
|
379
|
+
skip(@wclass.new(:PASS))
|
|
380
|
+
end
|
|
381
|
+
if re_ex and lpath.rpath_prefix re_ex
|
|
382
|
+
skip(@wclass.new(:PASS))
|
|
383
|
+
end
|
|
384
|
+
end
|
|
385
|
+
|
|
386
|
+
def clean_instance_variables
|
|
387
|
+
attrs = Set.new(self.class.attributes.map { |a| "@#{a.name}" })
|
|
388
|
+
vars = Set.new(instance_variables)
|
|
389
|
+
exceptions = Set.new(%w[ @status @thread @symtbl ])
|
|
390
|
+
(vars - attrs - exceptions).each do |var|
|
|
391
|
+
remove_instance_variable var
|
|
392
|
+
end
|
|
393
|
+
end
|
|
394
|
+
|
|
395
|
+
def check_assertion ( header, assertion )
|
|
396
|
+
if assertion.is_a?(Proc)
|
|
397
|
+
instance_eval(&assertion)
|
|
398
|
+
else
|
|
399
|
+
instance_eval(assertion.to_s)
|
|
400
|
+
end
|
|
401
|
+
end
|
|
402
|
+
protected :check_assertion
|
|
403
|
+
|
|
404
|
+
def check_pre_assertion
|
|
405
|
+
check_assertion('pre-assertion', @pre_assertion)
|
|
406
|
+
end
|
|
407
|
+
protected :check_pre_assertion
|
|
408
|
+
|
|
409
|
+
|
|
410
|
+
# Display test attributes. Attributes displayed and their order is
|
|
411
|
+
# specified by the class attribute _attributes_.
|
|
412
|
+
def prologue
|
|
413
|
+
if @symtbl[:loader].nil?
|
|
414
|
+
raise ArgumentError, 'no loader in the symtbl'
|
|
415
|
+
end
|
|
416
|
+
@save = {}
|
|
417
|
+
res = OHash.new
|
|
418
|
+
|
|
419
|
+
check_attributes
|
|
420
|
+
each_attribute do |attr, val|
|
|
421
|
+
next if val.nil?
|
|
422
|
+
name = attr.name
|
|
423
|
+
if attr.expand? and new_val = val.symtbl_gsub(@symtbl)
|
|
424
|
+
@save[name] = val
|
|
425
|
+
val = new_val
|
|
426
|
+
send("#{name}=", val)
|
|
427
|
+
end
|
|
428
|
+
if attr.visible? and not @reject.include? name
|
|
429
|
+
res[name] = val unless val == attr.default or name == :name
|
|
430
|
+
end
|
|
431
|
+
end
|
|
432
|
+
@symbols.each do |k, v|
|
|
433
|
+
@symtbl[k] = v
|
|
434
|
+
end
|
|
435
|
+
unless self.name.nil? or @reject.include? :name
|
|
436
|
+
if @symtbl[:pathname].nil?
|
|
437
|
+
@symtbl[:pathname] = ('/' + self.name).to_sym
|
|
438
|
+
else
|
|
439
|
+
@symtbl[:pathname] = :"#{@symtbl[:pathname]}/#{self.name}"
|
|
440
|
+
end
|
|
441
|
+
@log.new_node(self.name, :type => self.class)
|
|
442
|
+
end
|
|
443
|
+
@log << res
|
|
444
|
+
end
|
|
445
|
+
protected :prologue
|
|
446
|
+
|
|
447
|
+
|
|
448
|
+
# Compute really the test, only this method can be time checked.
|
|
449
|
+
def run_impl
|
|
450
|
+
end
|
|
451
|
+
protected :run_impl
|
|
452
|
+
|
|
453
|
+
|
|
454
|
+
# Exploit the results and assert when you want
|
|
455
|
+
def assertion
|
|
456
|
+
end
|
|
457
|
+
protected :assertion
|
|
458
|
+
|
|
459
|
+
|
|
460
|
+
def check_post_assertion
|
|
461
|
+
check_assertion('post-assertions', @post_assertion)
|
|
462
|
+
end
|
|
463
|
+
protected :check_post_assertion
|
|
464
|
+
|
|
465
|
+
|
|
466
|
+
# Display conclusions.
|
|
467
|
+
# Here you can finish some tasks even when the test fails.
|
|
468
|
+
# Exceptions are absolutly forbidden in this method.
|
|
469
|
+
def epilogue
|
|
470
|
+
unless @save.nil?
|
|
471
|
+
@save.each { |k,v| send("#{k}=", v) }
|
|
472
|
+
@save.clear
|
|
473
|
+
end
|
|
474
|
+
end
|
|
475
|
+
protected :epilogue
|
|
476
|
+
|
|
477
|
+
# Here you can do some tasks when the test failed.
|
|
478
|
+
def failed_hook
|
|
479
|
+
end
|
|
480
|
+
protected :failed_hook
|
|
481
|
+
|
|
482
|
+
# Here you can do some tasks when an error occur during the test.
|
|
483
|
+
def error_hook
|
|
484
|
+
end
|
|
485
|
+
protected :error_hook
|
|
486
|
+
|
|
487
|
+
# Here you can do some tasks when the test is aborted.
|
|
488
|
+
def abort_hook
|
|
489
|
+
end
|
|
490
|
+
protected :abort_hook
|
|
491
|
+
|
|
492
|
+
# Here you can do some task when the test is skiped.
|
|
493
|
+
def skip_hook
|
|
494
|
+
end
|
|
495
|
+
protected :skip_hook
|
|
496
|
+
|
|
497
|
+
# Here you can do some tasks when the test is passed.
|
|
498
|
+
def pass_hook
|
|
499
|
+
end
|
|
500
|
+
protected :pass_hook
|
|
501
|
+
|
|
502
|
+
|
|
503
|
+
|
|
504
|
+
#
|
|
505
|
+
# Assertions
|
|
506
|
+
#
|
|
507
|
+
|
|
508
|
+
def raise_status ( status )
|
|
509
|
+
@thread.raise(status)
|
|
510
|
+
end
|
|
511
|
+
protected :raise_status
|
|
512
|
+
|
|
513
|
+
def raise_status_custom ( status_class, *args )
|
|
514
|
+
weight, message = args.partition { |x| x.is_a? Weights::Weight }
|
|
515
|
+
if weight.size > 1 or message.size > 1
|
|
516
|
+
raise ArgumentError, 'too much arguments'
|
|
517
|
+
end
|
|
518
|
+
raise_status status_class.new(weight[0], message[0])
|
|
519
|
+
end
|
|
520
|
+
protected :raise_status_custom
|
|
521
|
+
|
|
522
|
+
# Force the test to pass
|
|
523
|
+
def pass
|
|
524
|
+
raise_status PassStatus.new
|
|
525
|
+
end
|
|
526
|
+
|
|
527
|
+
# Skip the test
|
|
528
|
+
def skip ( *args )
|
|
529
|
+
raise_status_custom SkipStatus, *args
|
|
530
|
+
end
|
|
531
|
+
|
|
532
|
+
# Force an Error status
|
|
533
|
+
def raise_error ( message=nil )
|
|
534
|
+
@symtbl[:flow] << :error
|
|
535
|
+
raise_status ErrorStatus.new(message)
|
|
536
|
+
end
|
|
537
|
+
|
|
538
|
+
# Force the test to fail
|
|
539
|
+
def fail ( *args )
|
|
540
|
+
raise_status_custom FailStatus, *args
|
|
541
|
+
end
|
|
542
|
+
|
|
543
|
+
# Abort the test explicitly.
|
|
544
|
+
def abort ( message='abort explicitly' )
|
|
545
|
+
@symtbl[:flow] << :abort
|
|
546
|
+
raise_status AbortStatus.new(message)
|
|
547
|
+
end
|
|
548
|
+
|
|
549
|
+
|
|
550
|
+
#
|
|
551
|
+
# Build methods
|
|
552
|
+
#
|
|
553
|
+
|
|
554
|
+
def testify ( symtbl, &block )
|
|
555
|
+
test = dup
|
|
556
|
+
test.symtbl ||= symtbl
|
|
557
|
+
block[test] if block
|
|
558
|
+
test
|
|
559
|
+
end
|
|
560
|
+
|
|
561
|
+
def to_s
|
|
562
|
+
@name || @log.path.to_s || super
|
|
563
|
+
end
|
|
564
|
+
|
|
565
|
+
def name= ( anObject )
|
|
566
|
+
case anObject
|
|
567
|
+
when nil, ''
|
|
568
|
+
@name = nil
|
|
569
|
+
else
|
|
570
|
+
@name = anObject.to_s
|
|
571
|
+
end
|
|
572
|
+
end
|
|
573
|
+
|
|
574
|
+
|
|
575
|
+
def timeout=(other)
|
|
576
|
+
if other >= 0
|
|
577
|
+
@timeout = other
|
|
578
|
+
else
|
|
579
|
+
raise(ArgumentError, "`#{other}' - timeout delay must be >= 0")
|
|
580
|
+
end
|
|
581
|
+
end
|
|
582
|
+
|
|
583
|
+
def running?
|
|
584
|
+
defined? @status and @status.is_a? RunningStatus
|
|
585
|
+
end
|
|
586
|
+
|
|
587
|
+
def display_unexpected_exc ( exc )
|
|
588
|
+
@log.error_unexpected_exception = exc
|
|
589
|
+
end
|
|
590
|
+
|
|
591
|
+
def display_unexpected_synflow_exc ( exc, arg )
|
|
592
|
+
@log.error_unexpected_synflow_exception = arg
|
|
593
|
+
end
|
|
594
|
+
|
|
595
|
+
# FIXME: I'm not well dumped
|
|
596
|
+
def symbols= ( symbols )
|
|
597
|
+
symbols.each do |k, v|
|
|
598
|
+
@symbols[k] = v
|
|
599
|
+
end
|
|
600
|
+
end
|
|
601
|
+
|
|
602
|
+
def strategy
|
|
603
|
+
self.class
|
|
604
|
+
end
|
|
605
|
+
|
|
606
|
+
def strategy= ( aClass )
|
|
607
|
+
if aClass != Strategy and aClass != self.class
|
|
608
|
+
raise ArgumentError, "Cannot change the strategy class " +
|
|
609
|
+
"of a test (#{aClass} != #{self.class})"
|
|
610
|
+
end
|
|
611
|
+
end
|
|
612
|
+
|
|
613
|
+
def symtbl= ( aSymtbl )
|
|
614
|
+
@symtbl = aSymtbl
|
|
615
|
+
@log ||= @symtbl[:log]
|
|
616
|
+
end
|
|
617
|
+
|
|
618
|
+
def symtbl (aSymtbl=nil)
|
|
619
|
+
if aSymtbl.nil?
|
|
620
|
+
@symtbl
|
|
621
|
+
else
|
|
622
|
+
self.symtbl = aSymtbl
|
|
623
|
+
end
|
|
624
|
+
end
|
|
625
|
+
|
|
626
|
+
def self.to_yaml_type
|
|
627
|
+
name.sub(/^Uttk::Strategies/, '!S')
|
|
628
|
+
end
|
|
629
|
+
|
|
630
|
+
def self.to_form ( b )
|
|
631
|
+
b.form_tag do
|
|
632
|
+
b.table :class => 'uttk_attributes' do
|
|
633
|
+
attributes.each do |attribute|
|
|
634
|
+
b.tr :class => 'uttk_attribute' do
|
|
635
|
+
b.td(:class => 'uttk_attribute_description') do
|
|
636
|
+
b.itext! "#{attribute.name} (#{attribute.descr}): "
|
|
637
|
+
end
|
|
638
|
+
b.td(:class => 'uttk_attribute_field') do
|
|
639
|
+
attribute.to_form(b)
|
|
640
|
+
end
|
|
641
|
+
end
|
|
642
|
+
end
|
|
643
|
+
end
|
|
644
|
+
end
|
|
645
|
+
end
|
|
646
|
+
|
|
647
|
+
attribute :name, 'test name', :invisible, String
|
|
648
|
+
attribute :strategy, 'the strategy class',
|
|
649
|
+
Class, Strategy, :mandatory, :invisible
|
|
650
|
+
attribute :wclass, 'a class to control weights', Class, Weights::Default
|
|
651
|
+
attribute :weight, 'a sort of coefficient. See wclass', 1
|
|
652
|
+
attribute :fatal, 'if the test fail all the suite fail', false
|
|
653
|
+
attribute :timeout, 'a duration (in seconds) before failure', 0
|
|
654
|
+
attribute :symbols, 'some user defined symbols', Hash do {} end
|
|
655
|
+
|
|
656
|
+
assertions_classes = [String, Proc, TrueClass, FalseClass]
|
|
657
|
+
attribute :pre_assertion, 'ruby code to assert environment condition ' +
|
|
658
|
+
'which must return true/false',
|
|
659
|
+
:invisible, assertions_classes do true end
|
|
660
|
+
attribute :post_assertion, 'ruby code to assert environment condition ' +
|
|
661
|
+
'which must return true/false',
|
|
662
|
+
:invisible, assertions_classes do true end
|
|
663
|
+
|
|
664
|
+
end # class Strategy
|
|
665
|
+
|
|
666
|
+
each_module_name do |name|
|
|
667
|
+
YAML.add_builtin_type("S::#{name}") do |type, val|
|
|
668
|
+
unless val.is_a? Hash
|
|
669
|
+
raise ArgumentError, "#{type}: needs a Hash not a #{val.class} (#{val.inspect})"
|
|
670
|
+
end
|
|
671
|
+
if val.has_key? :strategy and val[:strategy].to_s != to_s
|
|
672
|
+
raise ArgumentError, "type conflict #{type} != #{val[:strategy]}"
|
|
673
|
+
end
|
|
674
|
+
val[:strategy] = Strategies.const_get(type.sub(/^.*S::/, ''))
|
|
675
|
+
val
|
|
676
|
+
end
|
|
677
|
+
end
|
|
678
|
+
|
|
679
|
+
end # module Strategies
|
|
680
|
+
|
|
681
|
+
end # module Uttk
|
|
682
|
+
|
|
683
|
+
|