adsl 0.0.3 → 0.1.0

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.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -20
  3. data/README.md +14 -21
  4. data/bin/adsl-verify +8 -8
  5. data/lib/adsl.rb +3 -0
  6. data/lib/adsl/adsl.rb +3 -0
  7. data/lib/adsl/ds/data_store_spec.rb +339 -0
  8. data/lib/adsl/extract/instrumenter.rb +206 -0
  9. data/lib/adsl/extract/meta.rb +33 -0
  10. data/lib/adsl/extract/rails/action_block_builder.rb +233 -0
  11. data/lib/adsl/extract/rails/action_instrumenter.rb +400 -0
  12. data/lib/adsl/extract/rails/action_runner.rb +57 -0
  13. data/lib/adsl/extract/rails/active_record_metaclass_generator.rb +555 -0
  14. data/lib/adsl/extract/rails/callback_chain_simulator.rb +135 -0
  15. data/lib/adsl/extract/rails/invariant_extractor.rb +48 -0
  16. data/lib/adsl/extract/rails/invariant_instrumenter.rb +70 -0
  17. data/lib/adsl/extract/rails/other_meta.rb +57 -0
  18. data/lib/adsl/extract/rails/rails_extractor.rb +211 -0
  19. data/lib/adsl/extract/rails/rails_instrumentation_test_case.rb +34 -0
  20. data/lib/adsl/extract/rails/rails_special_gem_instrumentation.rb +120 -0
  21. data/lib/adsl/extract/rails/rails_test_helper.rb +140 -0
  22. data/lib/adsl/extract/sexp_utils.rb +54 -0
  23. data/lib/adsl/fol/first_order_logic.rb +261 -0
  24. data/lib/adsl/parser/adsl_parser.racc +159 -0
  25. data/lib/{parser → adsl/parser}/adsl_parser.rex +4 -4
  26. data/lib/{parser → adsl/parser}/adsl_parser.rex.rb +6 -6
  27. data/lib/adsl/parser/adsl_parser.tab.rb +1031 -0
  28. data/lib/adsl/parser/ast_nodes.rb +1410 -0
  29. data/lib/adsl/railtie.rb +67 -0
  30. data/lib/adsl/spass/bin.rb +230 -0
  31. data/lib/{spass → adsl/spass}/ruby_extensions.rb +0 -0
  32. data/lib/adsl/spass/spass_ds_extensions.rb +931 -0
  33. data/lib/adsl/spass/spass_translator.rb +393 -0
  34. data/lib/adsl/spass/util.rb +13 -0
  35. data/lib/adsl/util/csv_hash_formatter.rb +94 -0
  36. data/lib/adsl/util/general.rb +228 -0
  37. data/lib/adsl/util/test_helper.rb +71 -0
  38. data/lib/adsl/verification/formula_generators.rb +231 -0
  39. data/lib/adsl/verification/instrumentation_filter.rb +50 -0
  40. data/lib/adsl/verification/invariant.rb +19 -0
  41. data/lib/adsl/verification/rails_verification.rb +33 -0
  42. data/lib/adsl/verification/utils.rb +20 -0
  43. data/lib/adsl/verification/verification_case.rb +13 -0
  44. data/test/integration/rails/rails_branch_verification_test.rb +112 -0
  45. data/test/integration/rails/rails_verification_test.rb +253 -0
  46. data/test/integration/spass/basic_translation_test.rb +563 -0
  47. data/test/integration/spass/control_flow_translation_test.rb +421 -0
  48. data/test/unit/adsl/ds/data_store_spec_test.rb +54 -0
  49. data/test/unit/adsl/extract/instrumenter_test.rb +103 -0
  50. data/test/unit/adsl/extract/meta_test.rb +142 -0
  51. data/test/unit/adsl/extract/rails/action_block_builder_test.rb +178 -0
  52. data/test/unit/adsl/extract/rails/action_instrumenter_test.rb +68 -0
  53. data/test/unit/adsl/extract/rails/active_record_metaclass_generator_test.rb +336 -0
  54. data/test/unit/adsl/extract/rails/callback_chain_simulator_test.rb +76 -0
  55. data/test/unit/adsl/extract/rails/invariant_extractor_test.rb +92 -0
  56. data/test/unit/adsl/extract/rails/rails_extractor_test.rb +1380 -0
  57. data/test/unit/adsl/extract/rails/rails_test_helper_test.rb +25 -0
  58. data/test/unit/adsl/extract/sexp_utils_test.rb +100 -0
  59. data/test/unit/adsl/fol/first_order_logic_test.rb +227 -0
  60. data/test/unit/adsl/parser/action_parser_test.rb +1040 -0
  61. data/test/unit/adsl/parser/ast_nodes_test.rb +359 -0
  62. data/test/unit/adsl/parser/class_parser_test.rb +288 -0
  63. data/test/unit/adsl/parser/general_parser_test.rb +67 -0
  64. data/test/unit/adsl/parser/invariant_parser_test.rb +432 -0
  65. data/test/unit/adsl/parser/parser_util_test.rb +126 -0
  66. data/test/unit/adsl/spass/bin_test.rb +65 -0
  67. data/test/unit/adsl/spass/ruby_extensions_test.rb +39 -0
  68. data/test/unit/adsl/spass/spass_ds_extensions_test.rb +7 -0
  69. data/test/unit/adsl/spass/spass_translator_test.rb +342 -0
  70. data/test/unit/adsl/util/csv_hash_formatter_test.rb +68 -0
  71. data/test/unit/adsl/util/general_test.rb +303 -0
  72. data/test/unit/adsl/util/test_helper_test.rb +120 -0
  73. data/test/unit/adsl/verification/formula_generators_test.rb +200 -0
  74. data/test/unit/adsl/verification/instrumentation_filter_test.rb +39 -0
  75. data/test/unit/adsl/verification/utils_test.rb +39 -0
  76. data/test/unit/adsl/verification/verification_case_test.rb +8 -0
  77. metadata +229 -29
  78. data/lib/ds/data_store_spec.rb +0 -292
  79. data/lib/fol/first_order_logic.rb +0 -260
  80. data/lib/parser/adsl_ast.rb +0 -779
  81. data/lib/parser/adsl_parser.racc +0 -151
  82. data/lib/parser/adsl_parser.tab.rb +0 -976
  83. data/lib/parser/dsdl_parser.rex.rb +0 -196
  84. data/lib/parser/dsdl_parser.tab.rb +0 -976
  85. data/lib/spass/bin.rb +0 -164
  86. data/lib/spass/spass_ds_extensions.rb +0 -870
  87. data/lib/spass/spass_translator.rb +0 -388
  88. data/lib/spass/util.rb +0 -11
  89. data/lib/util/csv_hash_formatter.rb +0 -47
  90. data/lib/util/test_helper.rb +0 -33
  91. data/lib/util/util.rb +0 -114
@@ -0,0 +1,50 @@
1
+ module ADSL
2
+ module Verification
3
+ class InstrumentationFilter
4
+
5
+ def initialize(options = {})
6
+ options.keys.each do |key|
7
+ options[key] = options[key].to_s if options[key].is_a? Symbol
8
+ end
9
+ @options = options
10
+ end
11
+
12
+ def applies_to?(object, method_name)
13
+ unless @options[:method_name].nil?
14
+ return false unless @options[:method_name] === method_name.to_s
15
+ end
16
+ unless @options[:method_owner].nil?
17
+ return false if object.is_a?(Fixnum) or object.is_a?(Symbol)
18
+ method = object.singleton_class.instance_method method_name
19
+ return false unless method.owner == @options[:method_owner]
20
+ end
21
+ unless @options[:if].nil?
22
+ subcondition = InstrumentationFilter.new(@options[:if])
23
+ return false if subcondition.applies_to? object, method_name
24
+ end
25
+ unless @options[:unless].nil?
26
+ subcondition = InstrumentationFilter.new(@options[:unless])
27
+ return false unless subcondition.applies_to? object, method_name
28
+ end
29
+ true
30
+ end
31
+
32
+ def allow_instrumentation?(object, method_name)
33
+ !applies_to? object, method_name
34
+ end
35
+
36
+ end
37
+
38
+ module InstrumentationFilterGenerators
39
+ def blacklist(method_name = nil, options = {})
40
+ options[:method_name] = method_name unless method_name.nil?
41
+ @instrumentation_filters ||= []
42
+ @instrumentation_filters << InstrumentationFilter.new(options)
43
+ end
44
+
45
+ def instrumentation_filters
46
+ @instrumentation_filters || []
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,19 @@
1
+ require 'adsl/parser/ast_nodes'
2
+
3
+ module ADSL
4
+ module Verification
5
+ class Invariant
6
+ attr_accessor :description, :formula
7
+
8
+ def initialize(options = {})
9
+ @description = options[:description]
10
+ @formula = options[:formula]
11
+ @formula = @formula.adsl_ast if @formula.respond_to?(:adsl_ast)
12
+ end
13
+
14
+ def adsl_ast
15
+ ADSL::Parser::ASTInvariant.new :name => ADSL::Parser::ASTIdent.new(:text => @description), :formula => @formula
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,33 @@
1
+ require 'adsl/extract/rails/rails_extractor'
2
+
3
+ module ADSL
4
+ module Verification
5
+ module RailsVerification
6
+
7
+ def verify_spass(options = {})
8
+ ast = extract_ast options
9
+
10
+ require 'adsl/spass/bin'
11
+ self.class.send :include, ::ADSL::Spass::Bin
12
+
13
+ return verify(ast, options[:verify_options])
14
+ end
15
+
16
+ def extract_ast(options = {})
17
+ options = {
18
+ :verify_options => {},
19
+ :extract_options => {}
20
+ }.merge options
21
+ ast = options[:ast]
22
+ ast = ADSL::Extract::Rails::RailsExtractor.new(options[:extract_options]).adsl_ast if ast.nil?
23
+ ast
24
+ end
25
+
26
+ def adsl_translate(options = {})
27
+ ast = extract_ast options
28
+ puts ast.to_adsl
29
+ end
30
+
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,20 @@
1
+ require 'adsl/parser/ast_nodes'
2
+
3
+ module ADSL
4
+ module Verification
5
+ module Utils
6
+
7
+ def t(text)
8
+ ADSL::Parser::ASTIdent.new :text => text.to_s
9
+ end
10
+
11
+ def infer_classname_from_varname(varname)
12
+ varname.to_s.match(/^(\w+?)(?:_*\d+)?$/)[1].camelize
13
+ end
14
+
15
+ def classname_for_classname(klass)
16
+ klass.is_a?(Module) ? klass.name : klass.to_s.camelize
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,13 @@
1
+ require 'test/unit'
2
+ require 'adsl/parser/ast_nodes'
3
+ require 'adsl/verification/utils'
4
+ require 'adsl/verification/formula_generators'
5
+
6
+ module ADSL
7
+ module Verification
8
+ class VerificationCase < Test::Unit::TestCase
9
+ include ::ADSL::Verification::Utils
10
+ include ::ADSL::Verification::FormulaGenerators
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,112 @@
1
+ require 'test/unit'
2
+ require 'adsl/verification/rails_verification'
3
+ require 'adsl/extract/rails/rails_instrumentation_test_case'
4
+ require 'adsl/util/test_helper'
5
+
6
+ class ADSL::Verification::RailsVerificationTest < ADSL::Extract::Rails::RailsInstrumentationTestCase
7
+ include ADSL::Verification::RailsVerification
8
+
9
+ def verify_options_for(action)
10
+ {
11
+ :output => :silent,
12
+ :check_satisfiability => false,
13
+ :halt_on_error => true,
14
+ :timeout => 120,
15
+ :actions => [action.to_s]
16
+ }
17
+ end
18
+
19
+ def test_verify_spass__branch_no_return
20
+ AsdsController.class_exec do
21
+ def nothing
22
+ if true
23
+ Asd.new
24
+ else
25
+ Asd.build
26
+ end
27
+ end
28
+ end
29
+
30
+ ast = create_rails_extractor(<<-ruby).adsl_ast
31
+ invariant(self.not.exists{ |asd| })
32
+ ruby
33
+
34
+ assert_false verify_spass :ast => ast, :verify_options => verify_options_for(:AsdsController__nothing)
35
+ end
36
+
37
+ def test_verify_spass__branch_with_return__matters
38
+ AsdsController.class_exec do
39
+ def nothing
40
+ if true
41
+ return Asd.new
42
+ else
43
+ return Asd.build
44
+ end
45
+ Asd.find.destroy!
46
+ end
47
+ end
48
+
49
+ ast = create_rails_extractor(<<-ruby).adsl_ast
50
+ invariant(self.not.exists{ |asd| })
51
+ ruby
52
+
53
+ assert_false verify_spass :ast => ast, :verify_options => verify_options_for(:AsdsController__nothing)
54
+ end
55
+
56
+ def test_verify_spass__branch_with_return__may_create_but_will_delete
57
+ AsdsController.class_exec do
58
+ def nothing
59
+ if true
60
+ else
61
+ Asd.build
62
+ end
63
+ Asd.find.destroy!
64
+ end
65
+ end
66
+
67
+ ast = create_rails_extractor(<<-ruby).adsl_ast
68
+ invariant(self.not.exists{ |asd| })
69
+ ruby
70
+
71
+ assert verify_spass :ast => ast, :verify_options => verify_options_for(:AsdsController__nothing)
72
+ end
73
+
74
+ def test_verify_spass__branch_with_return__may_create_or_delete
75
+ AsdsController.class_exec do
76
+ def nothing
77
+ if true
78
+ else
79
+ return Asd.build
80
+ end
81
+ Asd.find.destroy!
82
+ end
83
+ end
84
+
85
+ ast = create_rails_extractor(<<-ruby).adsl_ast
86
+ invariant(self.not.exists{ |asd| })
87
+ ruby
88
+
89
+ assert_false verify_spass :ast => ast, :verify_options => verify_options_for(:AsdsController__nothing)
90
+ end
91
+
92
+ def test_verify_spass__variable_assignments
93
+ AsdsController.class_exec do
94
+ def nothing
95
+ a = nil
96
+ if true
97
+ a = Asd.new
98
+ else
99
+ a = Asd.build
100
+ end
101
+ a.destroy!
102
+ end
103
+ end
104
+
105
+ ast = create_rails_extractor(<<-ruby).adsl_ast
106
+ invariant(self.not.exists{ |asd| })
107
+ ruby
108
+
109
+ assert verify_spass :ast => ast, :verify_options => verify_options_for(:AsdsController__nothing)
110
+ end
111
+
112
+ end
@@ -0,0 +1,253 @@
1
+ require 'test/unit'
2
+ require 'adsl/verification/rails_verification'
3
+ require 'adsl/extract/rails/rails_instrumentation_test_case'
4
+ require 'adsl/util/test_helper'
5
+
6
+ class ADSL::Verification::RailsVerificationTest < ADSL::Extract::Rails::RailsInstrumentationTestCase
7
+ include ADSL::Verification::RailsVerification
8
+
9
+ def verify_options_for(action)
10
+ {
11
+ :output => :silent,
12
+ :check_satisfiability => false,
13
+ :halt_on_error => true,
14
+ :timeout => 120,
15
+ :actions => [action.to_s]
16
+ }
17
+ end
18
+
19
+ def test_verify_spass__true
20
+ ast = create_rails_extractor(<<-ruby).adsl_ast
21
+ invariant self.true
22
+ ruby
23
+
24
+ assert verify_spass :ast => ast, :verify_options => verify_options_for(:AsdsController__create)
25
+ end
26
+
27
+ def test_verify_spass__false
28
+ AsdsController.class_exec do
29
+ def create
30
+ Asd.new
31
+ end
32
+ end
33
+
34
+ ast = create_rails_extractor(<<-ruby).adsl_ast
35
+ invariant self.not(exists{|asd|})
36
+ ruby
37
+
38
+ assert_false verify_spass :ast => ast, :verify_options => verify_options_for('AsdsController__create')
39
+ end
40
+
41
+ def test_verify_spass__one_asd
42
+ AsdsController.class_exec do
43
+ def nothing
44
+ Asd.new
45
+ Asd.find.destroy!
46
+ end
47
+ end
48
+
49
+ ast = create_rails_extractor(<<-ruby).adsl_ast
50
+ invariant self.not(exists{|asd|})
51
+ ruby
52
+
53
+ assert verify_spass :ast => ast, :verify_options => verify_options_for('AsdsController__nothing')
54
+ end
55
+
56
+ def test_verify_spass__one_asd_again
57
+ AsdsController.class_exec do
58
+ def nothing
59
+ Asd.new.destroy!
60
+ end
61
+ end
62
+
63
+ ast = create_rails_extractor(<<-ruby).adsl_ast
64
+ invariant self.not(exists{|asd|})
65
+ ruby
66
+
67
+ assert verify_spass :ast => ast, :verify_options => verify_options_for('AsdsController__nothing')
68
+ end
69
+
70
+ def test_verify_spass__one_asd_through_method_calls
71
+ Asd.class_exec do
72
+ def self.create_new_instance
73
+ Asd.new
74
+ end
75
+
76
+ def alias_to_kill
77
+ destroy
78
+ end
79
+ end
80
+
81
+ AsdsController.class_exec do
82
+ def nothing
83
+ Asd.create_new_instance
84
+ end
85
+ end
86
+
87
+ ast = create_rails_extractor(<<-ruby).adsl_ast
88
+ invariant self.not(exists{|asd|})
89
+ ruby
90
+
91
+ assert_false verify_spass :ast => ast, :verify_options => verify_options_for('AsdsController__nothing')
92
+ end
93
+
94
+ def test_verify_spass__foreach
95
+ AsdsController.class_exec do
96
+ def nothing
97
+ Asd.all.each do |asd|
98
+ asd.blahs.each do |blah|
99
+ blah.delete
100
+ end
101
+ end
102
+ end
103
+ end
104
+
105
+ ast = create_rails_extractor(<<-ruby).adsl_ast
106
+ invariant forall{ |asd| asd.blahs.empty? }
107
+ ruby
108
+
109
+ assert verify_spass :ast => ast, :verify_options => verify_options_for('AsdsController__nothing')
110
+ end
111
+
112
+ def test_verify_spass__foreach_through
113
+ AsdsController.class_exec do
114
+ def nothing
115
+ Asd.all.each do |asd|
116
+ asd.kmes.each do |kme|
117
+ kme.delete
118
+ end
119
+ end
120
+ end
121
+ end
122
+
123
+ ast = create_rails_extractor(<<-ruby).adsl_ast
124
+ invariant forall{ |asd| asd.kmes.empty? }
125
+ ruby
126
+
127
+ assert verify_spass :ast => ast, :verify_options => verify_options_for('AsdsController__nothing')
128
+ end
129
+
130
+ def test_verify_spass__association_build__simple
131
+ AsdsController.class_exec do
132
+ def nothing
133
+ Asd.find.blahs.build
134
+ end
135
+ end
136
+
137
+ ast = create_rails_extractor(<<-ruby).adsl_ast
138
+ invariant forall{ |asd| not asd.blahs.empty? }
139
+ ruby
140
+
141
+ assert verify_spass :ast => ast, :verify_options => verify_options_for('AsdsController__nothing')
142
+ end
143
+
144
+ def test_verify_spass__association_build__inverse
145
+ AsdsController.class_exec do
146
+ def nothing
147
+ b = Mod::Blah.new
148
+ Asd.find.blahs << b
149
+ end
150
+ end
151
+
152
+ ast = create_rails_extractor(<<-ruby).adsl_ast
153
+ invariant forall(:blah => Mod::Blah){ |blah| not blah.asd.empty? }
154
+ invariant exists{ |asd| }
155
+ ruby
156
+
157
+ assert verify_spass :ast => ast, :verify_options => verify_options_for('AsdsController__nothing')
158
+ end
159
+
160
+ def test_verify_spass__association_build__can_be_used
161
+ AsdsController.class_exec do
162
+ def nothing
163
+ Asd.find.blahs.build.delete
164
+ end
165
+ end
166
+
167
+ ast = create_rails_extractor(<<-ruby).adsl_ast
168
+ invariant forall{ |asd| asd.blahs.empty? }
169
+ ruby
170
+
171
+ assert verify_spass :ast => ast, :verify_options => verify_options_for('AsdsController__nothing')
172
+ end
173
+
174
+ def test_verify_spass__association_build__can_be_used_2
175
+ AsdsController.class_exec do
176
+ def nothing
177
+ Asd.find.blahs.build.delete
178
+ end
179
+ end
180
+
181
+ ast = create_rails_extractor(<<-ruby).adsl_ast
182
+ invariant Mod::Blah.all.empty?
183
+ ruby
184
+
185
+ assert verify_spass :ast => ast, :verify_options => verify_options_for('AsdsController__nothing')
186
+ end
187
+
188
+ def test_verify_spass__association_build__through_creates_join_objects
189
+ AsdsController.class_exec do
190
+ def nothing
191
+ Asd.find.kmes.build
192
+ end
193
+ end
194
+
195
+ ast = create_rails_extractor(<<-ruby).adsl_ast
196
+ invariant forall{ |asd| asd.blahs.empty? }
197
+ ruby
198
+
199
+ assert_false verify_spass :ast => ast, :verify_options => verify_options_for('AsdsController__nothing')
200
+ end
201
+
202
+ def test_verify_spass__union_of_objsets_overestimate
203
+ AsdsController.class_exec do
204
+ def nothing
205
+ a = Asd.find
206
+ a.blahs = Mod::Blah.new + Mod::Blah.new
207
+ Mod::Blah.find.delete
208
+ Mod::Blah.find.delete
209
+ end
210
+ end
211
+
212
+ ast = create_rails_extractor(<<-ruby).adsl_ast
213
+ invariant Mod::Blah.all.empty?
214
+ ruby
215
+
216
+ assert verify_spass :ast => ast, :verify_options => verify_options_for('AsdsController__nothing')
217
+ end
218
+
219
+ def test_verify_spass__union_of_objsets_underestimate
220
+ AsdsController.class_exec do
221
+ def nothing
222
+ a = Asd.find
223
+ a.blahs = Mod::Blah.new + Mod::Blah.new
224
+ Mod::Blah.find.delete
225
+ Mod::Blah.find.delete
226
+ end
227
+ end
228
+
229
+ ast = create_rails_extractor(<<-ruby).adsl_ast
230
+ invariant !Mod::Blah.all.empty?
231
+ ruby
232
+
233
+ assert verify_spass :ast => ast, :verify_options => verify_options_for('AsdsController__nothing')
234
+ end
235
+
236
+ def test_verify_spass__call_of_optional_assignment
237
+ AsdsController.class_exec do
238
+ def asd
239
+ @asd ||= Asd.find
240
+ end
241
+
242
+ def nothing
243
+ asd.blahs.build
244
+ end
245
+ end
246
+
247
+ ast = create_rails_extractor(<<-ruby).adsl_ast
248
+ invariant forall(:blah => Mod::Blah){ |blah| !blah.asd.empty? }
249
+ ruby
250
+
251
+ assert_false verify_spass :ast => ast, :verify_options => verify_options_for('AsdsController__nothing')
252
+ end
253
+ end