tla-sbuilder 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +328 -0
- data/VERSION +1 -0
- data/bin/sbuilder.rb +5 -0
- data/lib/cli/cli-customer.rb +420 -0
- data/lib/cli/cli-example.rb +92 -0
- data/lib/cli/cli-pet.rb +767 -0
- data/lib/cli/cli-text.rb +226 -0
- data/lib/cli/cli.rb +298 -0
- data/lib/sbuilder.rb +52 -0
- data/lib/sbuilder/constants.rb +72 -0
- data/lib/sbuilder/controller.rb +798 -0
- data/lib/sbuilder/default-sbuilder.yaml +372 -0
- data/lib/sbuilder/domain.rb +124 -0
- data/lib/sbuilder/domain_cardinality.rb +37 -0
- data/lib/sbuilder/domain_value.rb +81 -0
- data/lib/sbuilder/exception.rb +27 -0
- data/lib/sbuilder/extension_loader.rb +721 -0
- data/lib/sbuilder/factory.rb +234 -0
- data/lib/sbuilder/model.rb +356 -0
- data/lib/sbuilder/mustache/template.rb +125 -0
- data/lib/sbuilder/mustache/template_reader.rb +206 -0
- data/lib/sbuilder/mustache/template_reader_context.rb +371 -0
- data/lib/sbuilder/param_set.rb +132 -0
- data/lib/sbuilder/param_set_db.rb +20 -0
- data/lib/sbuilder/param_set_def.rb +57 -0
- data/lib/sbuilder/param_set_if.rb +68 -0
- data/lib/sbuilder/param_set_loader.rb +77 -0
- data/lib/sbuilder/param_set_loader_swagger.rb +424 -0
- data/lib/sbuilder/param_set_step.rb +62 -0
- data/lib/sbuilder/param_sets.rb +54 -0
- data/lib/sbuilder/parameter.rb +97 -0
- data/lib/sbuilder/parameter_container.rb +72 -0
- data/lib/sbuilder/parameter_dom.rb +70 -0
- data/lib/sbuilder/parameter_ref.rb +71 -0
- data/lib/sbuilder/resolver.rb +78 -0
- data/lib/sbuilder/resolver_loader.rb +79 -0
- data/lib/sbuilder/resolver_loader_yaml.rb +103 -0
- data/lib/sbuilder/resolver_rule.rb +36 -0
- data/lib/sbuilder/resolver_rule_match.rb +55 -0
- data/lib/sbuilder/resolver_rule_ref.rb +37 -0
- data/lib/utils/hash_inject.rb +12 -0
- data/lib/utils/logger.rb +80 -0
- data/lib/utils/netio.rb +58 -0
- data/lib/utils/string_inject.rb +10 -0
- data/lib/utils/version.rb +13 -0
- data/mustache/cfg/const_def.mustache +8 -0
- data/mustache/cfg/const_run.mustache +3 -0
- data/mustache/cfg/invariant-infrastructure-service.mustache +4 -0
- data/mustache/cfg/macro_run.mustache +6 -0
- data/mustache/cfg/module_footer.mustache +0 -0
- data/mustache/cfg/module_header.mustache +7 -0
- data/mustache/data-model-dump.mustache +19 -0
- data/mustache/data-model-footer.mustache +5 -0
- data/mustache/data-model-header.mustache +16 -0
- data/mustache/definition_types.mustache +40 -0
- data/mustache/domains.mustache +20 -0
- data/mustache/domains_assign.mustache +22 -0
- data/mustache/domains_run.mustache +21 -0
- data/mustache/extend/extend_assumptions.mustache +7 -0
- data/mustache/extend/extend_const.mustache +5 -0
- data/mustache/extend/extend_implementation.mustache +9 -0
- data/mustache/extend/extend_invariant.mustache +7 -0
- data/mustache/extend/extend_invariant_cfg.mustache +7 -0
- data/mustache/extend/extend_macros.mustache +19 -0
- data/mustache/extend/extend_operations.mustache +9 -0
- data/mustache/extend/extend_state.mustache +9 -0
- data/mustache/infrastructure-service-init.mustache +36 -0
- data/mustache/infrastructure-service-variables.mustache +10 -0
- data/mustache/interface_processes.mustache +38 -0
- data/mustache/interface_stubs_dummy.mustache +13 -0
- data/mustache/interface_types.mustache +52 -0
- data/mustache/markdown-header.mustache +24 -0
- data/mustache/markdown-toc.mustache +13 -0
- data/mustache/name_definition_type.mustache +5 -0
- data/mustache/name_domain.mustache +5 -0
- data/mustache/name_domain_value.mustache +5 -0
- data/mustache/name_domain_value_prefix.mustache +5 -0
- data/mustache/name_interface_response_type.mustache +6 -0
- data/mustache/name_interface_type.mustache +6 -0
- data/mustache/name_parameter_definition.mustache +5 -0
- data/mustache/name_parameter_type.mustache +6 -0
- data/mustache/name_process.mustache +6 -0
- data/mustache/name_type_invariant.mustache +5 -0
- data/mustache/name_variable.mustache +6 -0
- data/mustache/operator-infrastructure-service.mustache +13 -0
- data/mustache/possibility/module_extends.mustache +1 -0
- data/mustache/possibility/module_footer.mustache +1 -0
- data/mustache/possibility/module_header.mustache +8 -0
- data/mustache/possibility/possibility_definition.mustache +12 -0
- data/mustache/possibility/possibility_directive.mustache +1 -0
- data/mustache/possibility/possility_setup.mustache +28 -0
- data/mustache/setup/module_footer.mustache +1 -0
- data/mustache/setup/module_header.mustache +9 -0
- data/mustache/setup/operator_run.mustache +7 -0
- data/mustache/setup/operator_tick.mustache +2 -0
- data/mustache/setup/steps_run.mustache +22 -0
- data/mustache/setup/steps_run_bind_rule.mustache +51 -0
- data/mustache/setup/steps_run_bind_set.mustache +37 -0
- data/mustache/setup/steps_run_parameterBind.mustache +80 -0
- data/mustache/setup/steps_run_parameterExact.mustache +79 -0
- data/mustache/state_type_invariant-infrastructure-service.mustache +49 -0
- data/mustache/state_type_invariant.mustache +17 -0
- data/mustache/state_type_invariant_cfg.mustache +18 -0
- data/mustache/state_variables.mustache +20 -0
- data/mustache/tla/const_def.mustache +5 -0
- data/mustache/tla/const_run.mustache +3 -0
- data/mustache/tla/macro-infrastructure-service.mustache +14 -0
- data/mustache/tla/macro_run.mustache +40 -0
- data/mustache/tla/module_footer.mustache +2 -0
- data/mustache/tla/module_header.mustache +9 -0
- data/mustache/tla/operator_run.mustache +8 -0
- data/mustache/tla/operators-infrastructure-service.mustache +12 -0
- data/mustache/tla/plc_define_footer.mustache +1 -0
- data/mustache/tla/plc_define_header.mustache +1 -0
- data/mustache/tla/plc_define_run.mustache +59 -0
- data/mustache/tla/plc_footer.mustache +2 -0
- data/mustache/tla/plc_header.mustache +2 -0
- data/mustache/tla/plc_run_state.mustache +12 -0
- data/mustache/tla/plc_tail.mustache +8 -0
- data/mustache/tla/plc_translation.mustache +2 -0
- data/resources/schema/json_schema/draft-04.json +150 -0
- data/resources/schema/swagger/2.0/schema.json +1591 -0
- data/src-extend/README +2 -0
- data/src-extend/extend/extend_assumptions.mustache +7 -0
- data/src-extend/extend/extend_const.mustache +5 -0
- data/src-extend/extend/extend_implementation.mustache +9 -0
- data/src-extend/extend/extend_invariant.mustache +11 -0
- data/src-extend/extend/extend_invariant_cfg.mustache +7 -0
- data/src-extend/extend/extend_macros.mustache +19 -0
- data/src-extend/extend/extend_operations.mustache +9 -0
- data/src-extend/extend/extend_state.mustache +9 -0
- data/src-extend/extend_app/assumption +20 -0
- data/src-extend/extend_app/correctness +19 -0
- data/src-extend/extend_app/correctness.cfg +9 -0
- data/src-extend/extend_app/infrastructure +25 -0
- data/src-extend/extend_app/interface +11 -0
- data/src-extend/extend_app/operator +18 -0
- data/src-extend/extend_app/possibility +16 -0
- data/src-extend/extend_app/service +33 -0
- data/src-extend/extend_app/state +16 -0
- data/src-extend/extend_app/transaction +22 -0
- data/src/pet/assumption +29 -0
- data/src/pet/assumption_address_domains.tla +12 -0
- data/src/pet/assumption_domains.tla +16 -0
- data/src/pet/assumption_generic.tla +8 -0
- data/src/pet/assumption_id_domains.tla +2 -0
- data/src/pet/assumption_owner_domains.tla +14 -0
- data/src/pet/assumption_pet_domains.tla +16 -0
- data/src/pet/assumption_tag_domains.tla +13 -0
- data/src/pet/correctness +24 -0
- data/src/pet/correctness.cfg +9 -0
- data/src/pet/correctness_coherent_owner_address.tla +6 -0
- data/src/pet/correctness_pet_name.tla +4 -0
- data/src/pet/correctness_ref_tag.tla +13 -0
- data/src/pet/correctness_type_invariants.tla +12 -0
- data/src/pet/correctness_unique_pet.tla +3 -0
- data/src/pet/correctness_unique_tag.tla +3 -0
- data/src/pet/docs/Petstore.md +117 -0
- data/src/pet/extend/extend_assumptions.mustache +7 -0
- data/src/pet/extend/extend_implementation.mustache +9 -0
- data/src/pet/extend/extend_invariant.mustache +11 -0
- data/src/pet/extend/extend_invariant_cfg.mustache +7 -0
- data/src/pet/extend/extend_macros.mustache +19 -0
- data/src/pet/extend/extend_operations.mustache +9 -0
- data/src/pet/extend/extend_state.mustache +9 -0
- data/src/pet/infrastructure +25 -0
- data/src/pet/infrastructure_id_get.tla +24 -0
- data/src/pet/interface +12 -0
- data/src/pet/interface_delete_pet.tla +5 -0
- data/src/pet/interface_get_pet.tla +4 -0
- data/src/pet/interface_post_pet.tla +5 -0
- data/src/pet/interface_post_tag.tla +5 -0
- data/src/pet/interface_put_tag.tla +3 -0
- data/src/pet/operator +30 -0
- data/src/pet/operator_find_tag_by_owner_name.tla +1 -0
- data/src/pet/operator_get_pet.tla +4 -0
- data/src/pet/operator_get_pet_by_tag.tla +4 -0
- data/src/pet/operator_get_tag.tla +10 -0
- data/src/pet/operator_new_owner.tla +3 -0
- data/src/pet/operator_new_pet.tla +13 -0
- data/src/pet/operator_new_tag.tla +3 -0
- data/src/pet/operator_next_pet_id.tla +3 -0
- data/src/pet/operator_responses.tla +8 -0
- data/src/pet/operator_tag_exists.tla +2 -0
- data/src/pet/operator_tag_owner_validated.tla +2 -0
- data/src/pet/operator_tag_referenced.tla +4 -0
- data/src/pet/operator_valid_owner.tla +17 -0
- data/src/pet/operator_valid_pet.tla +6 -0
- data/src/pet/operator_valid_tag.tla +5 -0
- data/src/pet/possibility +18 -0
- data/src/pet/possibility_at_least_two_tags.tla +12 -0
- data/src/pet/possibility_invalid_tag_address.tla +8 -0
- data/src/pet/service +35 -0
- data/src/pet/service_pet_delete.tla +11 -0
- data/src/pet/service_pet_get.tla +27 -0
- data/src/pet/service_pet_post.tla +78 -0
- data/src/pet/service_tag_post.tla +53 -0
- data/src/pet/service_tag_put.tla +82 -0
- data/src/pet/state +16 -0
- data/src/pet/state_infra.tla +6 -0
- data/src/pet/state_pet.tla +5 -0
- data/src/pet/state_tag_id.tla +2 -0
- data/src/pet/transaction +23 -0
- data/src/pet/transaction_delete_pet.tla +13 -0
- data/src/pet/transaction_enter_pet.tla +13 -0
- data/src/pet/transaction_enter_tag.tla +56 -0
- data/src/pet/transaction_error.tla +23 -0
- data/tla-sbuilder.gemspec +43 -0
- metadata +353 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c7c59bc7c8ccd8cc4c991d487f793208c1234bab
|
4
|
+
data.tar.gz: 564a18b8c901b8714dfb32c7c70d0a78b5a8f7ac
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 208032b65aff58ad9a32ae7f4197da74b24979defcf30886bcbcd32974571b34da94c80f027dddea217bfea2a7d71c254aa8b93b06f7f94d80433960818c90dd
|
7
|
+
data.tar.gz: 667f6dd2647f7e60cb1bfde14f28d55703c57b1b16f3dc33e2fbf1ca7c61d320feb9d51ea89856d544ba48da6f295f2e35b21547e20d9beed63c11ff9985007a
|
data/README.md
ADDED
@@ -0,0 +1,328 @@
|
|
1
|
+
<link href="../site.css" rel="stylesheet"></link>
|
2
|
+
[Up](../index.php) [Readme](README.html) [Releases](RELEASES.html) [Todo](TODO.html)
|
3
|
+
|
4
|
+
|
5
|
+
# Sbuilder - A Specification Builder for TLA+ Tools - $Release:0.1.0$
|
6
|
+
|
7
|
+
A tool to generate runnable specification models in
|
8
|
+
[TLA+ language](http://research.microsoft.com/en-us/um/people/lamport/tla/book.html)
|
9
|
+
for [target systems](#TARGET-SYSTEM). Specification model can be
|
10
|
+
verified using
|
11
|
+
[TLA+ Tools](http://research.microsoft.com/en-us/um/people/lamport/tla/tools.html),
|
12
|
+
and parts of it can be presented as
|
13
|
+
[implementation blueprints](#BLUEPRINT) to developers.
|
14
|
+
|
15
|
+
See [live documentation](features.html) for more details.
|
16
|
+
|
17
|
+
## <a id="TARGET-SYSTEM">Target Systems</a>
|
18
|
+
|
19
|
+
Sbuilder supports modeling typical business IT systems, where a system
|
20
|
+
architecture identifies
|
21
|
+
|
22
|
+
* **interfaces**: entry point providing access to services within the
|
23
|
+
system. **Application interface** is the public entry point, and
|
24
|
+
**infrastructure interface** is the internal entry point allowing
|
25
|
+
aggregation of (application) services from smaller units.
|
26
|
+
|
27
|
+
* **services**: unit of functionality accessible over
|
28
|
+
interfaces. **Infrastructure service** is not directly accessible over
|
29
|
+
_application interface_, as opposed to **application services**
|
30
|
+
|
31
|
+
* **database**: persistent data store, which services may access, and
|
32
|
+
modify.
|
33
|
+
|
34
|
+
## <a id="ELEMENTS-OF">Runnable Specification Code</a>
|
35
|
+
|
36
|
+
Sbuilder combines three main elements to create runnable TLA+
|
37
|
+
specification code:
|
38
|
+
|
39
|
+
1. **Interface specification**: Sbuilder accepts
|
40
|
+
[RESTfull](https://en.wikipedia.org/wiki/Representational_state_transfer)
|
41
|
+
interface api specification expressed in
|
42
|
+
[Swagger](http://swagger.io/)
|
43
|
+
[v2.0](http://swagger.io/specification/) format.
|
44
|
+
|
45
|
+
2. **Specification extension**: Sbuilder tangles manually crafted code
|
46
|
+
snippets from Sbuilder *code repository* with the code generated
|
47
|
+
using *inteterface specifications*. The manual code snippets use
|
48
|
+
TLA+ language to model behavior and correctness criteria of the
|
49
|
+
target system.
|
50
|
+
|
51
|
+
3. **Setups**: To complete runnable code, Sbuilder uses setups. A
|
52
|
+
setup is a sequence of interface operations, and their input
|
53
|
+
parameters. In addition, a setup may define domain cardinalities,
|
54
|
+
or domain values. The tools allows defining multiple setups, each
|
55
|
+
setup resulting to a complete, runnable TLA+ code, allowing system
|
56
|
+
model to be run in various environment context
|
57
|
+
|
58
|
+
Sbuilder uses following categories to organize *specification
|
59
|
+
snippets* in its **code repository**:
|
60
|
+
|
61
|
+
* **state**: TLA+ variables modeling *database*
|
62
|
+
|
63
|
+
* **operator**: TLA+ language constructs, which enable "to define all
|
64
|
+
the data structures and operations that occur in the specification"
|
65
|
+
|
66
|
+
* **transaction**: pseudo code implementation of common behavior in
|
67
|
+
modifying system state
|
68
|
+
|
69
|
+
* **service**: pseudo code implementation of target system
|
70
|
+
*application services* using PlusCal procedures in TLA+ language
|
71
|
+
|
72
|
+
* **infrastructure**: pseudo code implementation of target system
|
73
|
+
*infrastructure services* using PlusCal procedures in TLA+ language
|
74
|
+
|
75
|
+
* **interface**: implementation of *application interface* extension
|
76
|
+
points using PlusCal macros in TLA+ language
|
77
|
+
|
78
|
+
* **correctness**: operator definitions, and INVARIANT directives in
|
79
|
+
TLA+ language specifying properties, which must be not violated in
|
80
|
+
specification executions
|
81
|
+
|
82
|
+
* **possibility**: optional operator definitions to increase
|
83
|
+
confidence in correctness invariants
|
84
|
+
|
85
|
+
* **assumption**: operator definitions, and ASSUME directive in TLA+
|
86
|
+
language specifying properties, which must be not violated in the
|
87
|
+
specification code
|
88
|
+
|
89
|
+
In order to support IT system application development, as depicted in
|
90
|
+
section [modeling pipeline](#MODELING-PIPELINE) below, Sbuilder
|
91
|
+
can generate <a id="BLUEPRINT">**implementation
|
92
|
+
blueprints**</a>. *Implementation blueprints* are html-pages including
|
93
|
+
code snippets from Sbuilder *code repository*, or code generated
|
94
|
+
based on *interface specifications*.
|
95
|
+
|
96
|
+
|
97
|
+
## <a id="MODELING-PIPELINE">Modeling Pipeline</a>
|
98
|
+
|
99
|
+
The picture below gives an overview, how Sbuilder -tool can be
|
100
|
+
deployed in an "mainstream" software development process.
|
101
|
+
|
102
|
+
The objective for creating a specification model is to get better
|
103
|
+
understanding, to get the design right, and to write better code for
|
104
|
+
the system being built - and thereby to justify the extra effort
|
105
|
+
needed in modeling.
|
106
|
+
|
107
|
+
|
108
|
+
![process](pics/process.svg)
|
109
|
+
|
110
|
+
We assume that services are currently implemented based on informal
|
111
|
+
service specification documents written in English. We also assume
|
112
|
+
that service interface is available in a machine readable format.
|
113
|
+
|
114
|
+
In the picture, process enhancements are highlighted in a box labeled
|
115
|
+
"Pseudo code modeling". The output of the process enhancement are
|
116
|
+
implementation blueprints, which are made available for developers at
|
117
|
+
the side of current service implementation documentation. An
|
118
|
+
implementation blueprint for a service contains pseudo code snippets
|
119
|
+
extracted from specification model, relevant for implementing a
|
120
|
+
particular service.
|
121
|
+
|
122
|
+
Pseudo code modeling includes following tasks:
|
123
|
+
|
124
|
+
- **accept API specification input**: Machine readable interface
|
125
|
+
specification is translated to TLA+ language.
|
126
|
+
|
127
|
+
- **create domain model**: Interface parameters are mapped to
|
128
|
+
domains. In this task, we define domain resolvers in Sbuilder -tool,
|
129
|
+
and add TLA+ operators, and assumptions to verify that the resulting
|
130
|
+
domain model conforms to service specification. In practice,
|
131
|
+
creating a formal domain model results in "Gaining better
|
132
|
+
understanding" of the informal specification.
|
133
|
+
|
134
|
+
- **specify correctness**: In the spirit of Test Driven Development,
|
135
|
+
specifying correctness precedes specifying behavior. In this task,
|
136
|
+
we interpret test cases, (hopefully) presented in the informal
|
137
|
+
service specification, as TLA+ language operators and invariants.
|
138
|
+
|
139
|
+
- **model behavior**: Modeling behavior includes creating pseudo code
|
140
|
+
service implementation in TLA+ language. In this task, when we have
|
141
|
+
formal correctness criteria expressed in TLA+, running model checker
|
142
|
+
points out traces leading to violations any of the criteria, and
|
143
|
+
helps us in "Getting design right".
|
144
|
+
|
145
|
+
- **create implementation blueprint**: In the final task, modeler
|
146
|
+
defines web pages for implementation blueprints. A blueprint
|
147
|
+
collects relevant TLA+ snippets in Sbuilder code repository,
|
148
|
+
together with any other useful documentation, to help in
|
149
|
+
implementing a specific service. Web pages are made available for
|
150
|
+
service implementation to help developers to "Write better
|
151
|
+
code". Competent developers may understand TLA+ language, but, like
|
152
|
+
in software engineering generally, good comments in pseudo code
|
153
|
+
snippets will make blueprints more approachable.
|
154
|
+
|
155
|
+
|
156
|
+
The picture above defines following roles:
|
157
|
+
|
158
|
+
* **architect**: expert role specifying services, and defining
|
159
|
+
interfaces
|
160
|
+
|
161
|
+
* **modeler**: expert role crafting specification extensions, and
|
162
|
+
using Sbuilder, and TLA+ tools to generate specification code, and
|
163
|
+
to verify its correctness
|
164
|
+
|
165
|
+
* **developer**: expert role implementing IT system interface and
|
166
|
+
service according to the service specification, interface definition,
|
167
|
+
and Sbuilder blueprint.
|
168
|
+
|
169
|
+
|
170
|
+
## <a id="USAGE">Usage</a>
|
171
|
+
|
172
|
+
### Pre-requisites
|
173
|
+
|
174
|
+
`Sbuilder` -tool requires Ruby 2.
|
175
|
+
|
176
|
+
To run the specification model created by Sbuilder -tool, you must
|
177
|
+
have Java and
|
178
|
+
[TLA+ Tools](http://research.microsoft.com/en-us/um/people/lamport/tla/tools.html)
|
179
|
+
installed.
|
180
|
+
|
181
|
+
|
182
|
+
### Installation
|
183
|
+
|
184
|
+
To install `Sbuilder` Gem, create a `Gemfile` -file with the
|
185
|
+
content
|
186
|
+
|
187
|
+
```
|
188
|
+
source "https://rubygems.org"
|
189
|
+
gem 'tla-sbuilder'
|
190
|
+
```
|
191
|
+
|
192
|
+
and run
|
193
|
+
|
194
|
+
bundle install
|
195
|
+
|
196
|
+
TLA+ Tools jar can be obtained from
|
197
|
+
[download page](https://tla.msr-inria.inria.fr/tlatoolbox/dist), see
|
198
|
+
[TLA+ Tools](http://research.microsoft.com/en-us/um/people/lamport/tla/tools.html)
|
199
|
+
for more instructions on installation.
|
200
|
+
|
201
|
+
### To Use Pet Store Example Application
|
202
|
+
|
203
|
+
Create default directories used by `sbuilder` in current working directory
|
204
|
+
|
205
|
+
bundle exec sbuilder.rb init
|
206
|
+
|
207
|
+
Create example configuration
|
208
|
+
|
209
|
+
bundle exec sbuilder.rb example pet
|
210
|
+
|
211
|
+
To list configuration files created for pet store example
|
212
|
+
|
213
|
+
ls cnf
|
214
|
+
|
215
|
+
|
216
|
+
To list specification extensions in TLA-sbuilder code repository
|
217
|
+
|
218
|
+
ls src/pet
|
219
|
+
|
220
|
+
|
221
|
+
To generate all setups in petstore example
|
222
|
+
|
223
|
+
bundle exec sbuilder.rb generate -t src/pet/
|
224
|
+
|
225
|
+
To run model checking for setup `pet1` using TLA+tools jar in
|
226
|
+
`~/java/tla/tla2tools.jar`
|
227
|
+
|
228
|
+
export CP=~/java/tla/tla2tools.jar
|
229
|
+
(cd gen/pet1/tla; java -cp $CP pcal.trans model)
|
230
|
+
(cd gen/pet1/tla; java -cp $CP tlc2.TLC setup)
|
231
|
+
|
232
|
+
and observe **Model checking completed. No error has been found.** to
|
233
|
+
conclude that **correctness invariants** for the model are not
|
234
|
+
violated.
|
235
|
+
|
236
|
+
|
237
|
+
In setup `pet1`, it is **NOT possible** to reach a state where
|
238
|
+
predicate
|
239
|
+
|
240
|
+
at_least_two_tags == Cardinality( v_tags ) > 1
|
241
|
+
|
242
|
+
holds. This is because setup steps in `cnf/extend_petstore_run1.yaml`
|
243
|
+
do not call interface operation `/tags(post)`.
|
244
|
+
|
245
|
+
To show that it is **NOT possible** to reach a state, where
|
246
|
+
`at_least_two_tags` holds, run
|
247
|
+
|
248
|
+
(cd gen/pet1/tla; java -cp $CP tlc2.TLC possible_tag_with_invalid_address)
|
249
|
+
|
250
|
+
and observe **Model checking completed. No error has been found.**.
|
251
|
+
|
252
|
+
However, steps for setup `pet3`, defined in
|
253
|
+
`cnf/extend_petstore_run3.yaml`, do call `/tags(post)` twice, making
|
254
|
+
it possible to reach a state where predicate `at_least_two_tags`
|
255
|
+
holds.
|
256
|
+
|
257
|
+
The **possibility** to reach this state can be demonstrated running
|
258
|
+
|
259
|
+
(cd gen/pet3/tla; java -cp $CP pcal.trans model)
|
260
|
+
(cd gen/pet3/tla; java -cp $CP tlc2.TLC possible_tag_with_invalid_address)
|
261
|
+
|
262
|
+
and observing **Error: Evaluating invariant** `possible_tag_with_invalid_address` **failed.**
|
263
|
+
|
264
|
+
|
265
|
+
### Create Own Model
|
266
|
+
|
267
|
+
See [live documentation](features.html) for more details.
|
268
|
+
|
269
|
+
Create default directories used by `sbuilder` in current working directory
|
270
|
+
|
271
|
+
bundle exec sbuilder.rb init
|
272
|
+
|
273
|
+
|
274
|
+
Create extension templates for including *specification extensions* in
|
275
|
+
default in TLA-sbuilder *code repository* into specification model.
|
276
|
+
|
277
|
+
bundle exec sbuilder.rb extend
|
278
|
+
|
279
|
+
|
280
|
+
Remove `.example` from all files in `cnf` directory
|
281
|
+
|
282
|
+
Generate example setups:
|
283
|
+
|
284
|
+
bundle exec sbuilder.rb generate
|
285
|
+
|
286
|
+
To run the model checking for setup `default` using TLA+tools jar in
|
287
|
+
`~/java/tla/tla2tools.jar`
|
288
|
+
|
289
|
+
export CP=~/java/tla/tla2tools.jar
|
290
|
+
(cd gen/default/tla; java -cp $CP pcal.trans model)
|
291
|
+
(cd gen/default/tla; java -cp $CP tlc2.TLC setup)
|
292
|
+
|
293
|
+
|
294
|
+
## Manage State Space Explosion, and Allow Scaling
|
295
|
+
|
296
|
+
[State space explosion](https://www.google.fi/search?q=state+space+explosion)
|
297
|
+
is inherent problem in
|
298
|
+
[model checking](https://en.wikipedia.org/wiki/Model_checking), the
|
299
|
+
theory behind TLA+ tool.
|
300
|
+
|
301
|
+
Sbuilder tries to avoid problems due to state space explosion by
|
302
|
+
|
303
|
+
* allowing controlling, how environment invokes interface operations,
|
304
|
+
and in effect, throttling number of states generated during model
|
305
|
+
checking.
|
306
|
+
|
307
|
+
* allowing to fix input parameter bindings in an interface
|
308
|
+
operation. In cases, where domain sizes are not a problem, SBuilder
|
309
|
+
can allow TLA+ tool to explore all possible, or partial, input
|
310
|
+
parameter combinations during model checking.
|
311
|
+
|
312
|
+
|
313
|
+
In TLA+tools, number of states/sec decreases as specification code
|
314
|
+
volume increases (see a [benchmark](BENCHMARK.html) results for more
|
315
|
+
details).
|
316
|
+
|
317
|
+
SBuilder tries to avoid problems due to increase in specification code
|
318
|
+
by offering run time option `--filter-src`, which parses TLA+ snippets
|
319
|
+
and runs static call flow analysis to prune off unused snippets from
|
320
|
+
specification model. Parser is in alpha phase, in case of error, use
|
321
|
+
option `--filter-list` to continue after parser error, and to
|
322
|
+
configure manually modules call flow analyzer would otherwise omit
|
323
|
+
from the specification code.
|
324
|
+
|
325
|
+
|
326
|
+
## License
|
327
|
+
|
328
|
+
MIT
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
data/bin/sbuilder.rb
ADDED
@@ -0,0 +1,420 @@
|
|
1
|
+
module Sbuilder
|
2
|
+
|
3
|
+
require_relative 'cli-text'
|
4
|
+
|
5
|
+
class CliCustomer
|
6
|
+
|
7
|
+
# ------------------------------------------------------------------
|
8
|
+
# Local constsants
|
9
|
+
# PETSTORE_URL="https://rawgit.com/swagger-api/swagger-spec/master/examples/v2.0/yaml/petstore-expanded.yaml"
|
10
|
+
# file names
|
11
|
+
FILE_RESOLVER_CUSTOMER="resolver_customer.yaml"
|
12
|
+
FILE_INTERFACE_CUSTOMER="interface_customer.yaml"
|
13
|
+
|
14
|
+
|
15
|
+
FILE_EXTENSIONS_CUSTOMER_COMMON="extend_customer_doms.yaml"
|
16
|
+
FILE_EXTENSIONS_CUSTOMER_RUN1="extend_customer_run1.yaml"
|
17
|
+
FILE_EXTENSIONS_CUSTOMER_RUN2="extend_customer_run2.yaml"
|
18
|
+
|
19
|
+
SBUILDER_YAML_CUSTOMER= <<-EOS
|
20
|
+
|
21
|
+
# ------------------------------------------------------------------
|
22
|
+
#{Sbuilder::CliText::SBUILBER_INTERFACES}
|
23
|
+
|
24
|
+
interfaces:
|
25
|
+
- type: swagger
|
26
|
+
file: #{FILE_INTERFACE_CUSTOMER}
|
27
|
+
|
28
|
+
|
29
|
+
# ------------------------------------------------------------------
|
30
|
+
#{Sbuilder::CliText::SBUILDER_RESOLVERS}
|
31
|
+
resolvers:
|
32
|
+
- type: resolver_yaml
|
33
|
+
file: #{FILE_RESOLVER_CUSTOMER}
|
34
|
+
|
35
|
+
# ------------------------------------------------------------------
|
36
|
+
#{Sbuilder::CliText::SBUILER_SETUPS}
|
37
|
+
setups:
|
38
|
+
- setupDirectory: default
|
39
|
+
|
40
|
+
- setupDirectory: customer1
|
41
|
+
extensions:
|
42
|
+
- type: default-yaml
|
43
|
+
url: cnf/#{FILE_EXTENSIONS_CUSTOMER_COMMON}
|
44
|
+
- type: default-yaml
|
45
|
+
url: cnf/#{FILE_EXTENSIONS_CUSTOMER_RUN1}
|
46
|
+
|
47
|
+
- setupDirectory: customer2
|
48
|
+
extensions:
|
49
|
+
- type: default-yaml
|
50
|
+
url: cnf/#{FILE_EXTENSIONS_CUSTOMER_COMMON}
|
51
|
+
- type: default-yaml
|
52
|
+
url: cnf/#{FILE_EXTENSIONS_CUSTOMER_RUN2}
|
53
|
+
|
54
|
+
# ------------------------------------------------------------------
|
55
|
+
#{Sbuilder::CliText::SBUILDER_PREFERENCES}
|
56
|
+
preferences:
|
57
|
+
debug-output: true
|
58
|
+
|
59
|
+
# ------------------------------------------------------------------
|
60
|
+
#{Sbuilder::CliText::SBUILDER_GENERATE}
|
61
|
+
|
62
|
+
|
63
|
+
EOS
|
64
|
+
|
65
|
+
|
66
|
+
|
67
|
+
|
68
|
+
|
69
|
+
EXTENSIONS_CUSTOMER_COMMON = <<-EOS
|
70
|
+
#{Sbuilder::CliText::EXTENSION_HEADER_DOM}
|
71
|
+
#
|
72
|
+
#
|
73
|
+
-
|
74
|
+
domain-extension:
|
75
|
+
- domain: customer_id
|
76
|
+
cardinality: 2
|
77
|
+
- domain: customer_type
|
78
|
+
values:
|
79
|
+
- business
|
80
|
+
- consumer
|
81
|
+
- domain: customer_name
|
82
|
+
cardinality: 2
|
83
|
+
- domain: customer_street
|
84
|
+
cardinality: 1
|
85
|
+
- domain: customer_city
|
86
|
+
cardinality: 1
|
87
|
+
|
88
|
+
EOS
|
89
|
+
|
90
|
+
EXTENSIONS_CUSTOMER_RUN1 = <<-EOS
|
91
|
+
#{Sbuilder::CliText::EXTENSION_HEADER_SETUP}
|
92
|
+
#
|
93
|
+
# Extend domain resolved in #{FILE_RESOLVER_CUSTOMER}
|
94
|
+
#
|
95
|
+
- step-extension:
|
96
|
+
|
97
|
+
- interface: /customers(post)
|
98
|
+
bindExact: true
|
99
|
+
inputs:
|
100
|
+
- input:
|
101
|
+
customers:
|
102
|
+
-
|
103
|
+
id: 1
|
104
|
+
type: business
|
105
|
+
_default: 1
|
106
|
+
address:
|
107
|
+
_default: 1
|
108
|
+
-
|
109
|
+
id: 2
|
110
|
+
_default: 1
|
111
|
+
address:
|
112
|
+
_default: Nil
|
113
|
+
|
114
|
+
- input:
|
115
|
+
customers:
|
116
|
+
-
|
117
|
+
id: 1
|
118
|
+
type: consumer
|
119
|
+
_default: 1
|
120
|
+
address:
|
121
|
+
_default: 1
|
122
|
+
-
|
123
|
+
id: 2
|
124
|
+
_default: 1
|
125
|
+
address:
|
126
|
+
_default: 1
|
127
|
+
|
128
|
+
- input:
|
129
|
+
customers:
|
130
|
+
-
|
131
|
+
id: 1
|
132
|
+
type: business
|
133
|
+
_default: 1
|
134
|
+
address:
|
135
|
+
_default: 1
|
136
|
+
-
|
137
|
+
id: 2
|
138
|
+
_default: 1
|
139
|
+
address:
|
140
|
+
_default: 1
|
141
|
+
|
142
|
+
# - interface: /customers(post)
|
143
|
+
# bindExact: true
|
144
|
+
# input:
|
145
|
+
# customers:
|
146
|
+
# - id: 1
|
147
|
+
# _default: 1
|
148
|
+
# address:
|
149
|
+
# _default: Nil
|
150
|
+
|
151
|
+
# - interface: /customers(post)
|
152
|
+
# bindExact: true
|
153
|
+
# input:
|
154
|
+
# customers:
|
155
|
+
# - id: 1
|
156
|
+
# _default: Nil
|
157
|
+
# address:
|
158
|
+
# _default: Nil
|
159
|
+
# - id: 1
|
160
|
+
# _default: Nil
|
161
|
+
# address:
|
162
|
+
# _default: 1
|
163
|
+
|
164
|
+
|
165
|
+
# - interface: /customers(post)
|
166
|
+
# input:
|
167
|
+
# # _default: 1
|
168
|
+
# customers:
|
169
|
+
# - id: 1
|
170
|
+
# # name: 1
|
171
|
+
# - id: 2
|
172
|
+
# # name: 2
|
173
|
+
# # - id: 3
|
174
|
+
# # name: 1
|
175
|
+
|
176
|
+
EOS
|
177
|
+
|
178
|
+
EXTENSIONS_CUSTOMER_RUN2 = <<-EOS
|
179
|
+
#{Sbuilder::CliText::EXTENSION_HEADER_SETUP}
|
180
|
+
#
|
181
|
+
#
|
182
|
+
- step-extension:
|
183
|
+
|
184
|
+
- interface: /customer(post)
|
185
|
+
input:
|
186
|
+
customer:
|
187
|
+
# name: 2
|
188
|
+
_default: 2
|
189
|
+
address:
|
190
|
+
_default: Nil
|
191
|
+
# street: 1
|
192
|
+
# city: 1
|
193
|
+
|
194
|
+
# - interface: /customers(post)
|
195
|
+
# input:
|
196
|
+
# # _default: 1
|
197
|
+
# customers:
|
198
|
+
# - id: 1
|
199
|
+
# # name: 1
|
200
|
+
# - id: 2
|
201
|
+
|
202
|
+
|
203
|
+
|
204
|
+
EOS
|
205
|
+
|
206
|
+
|
207
|
+
|
208
|
+
RESOLVER_CUSTOMER = <<-EOS
|
209
|
+
#{Sbuilder::CliText::RESOLVER_HEADER}
|
210
|
+
#
|
211
|
+
# Example mapper for customer interface
|
212
|
+
|
213
|
+
- Name: Customer
|
214
|
+
Matcher: Customer
|
215
|
+
Rules:
|
216
|
+
- Matcher: name
|
217
|
+
Domain: customer_name
|
218
|
+
|
219
|
+
- Matcher: id
|
220
|
+
Domain: customer_id
|
221
|
+
|
222
|
+
- Matcher: type
|
223
|
+
Domain: customer_type
|
224
|
+
|
225
|
+
- Name: Address
|
226
|
+
Matcher: Address
|
227
|
+
Rules:
|
228
|
+
- Matcher: street
|
229
|
+
Domain: customer_street
|
230
|
+
|
231
|
+
- Matcher: city
|
232
|
+
Domain: customer_city
|
233
|
+
|
234
|
+
|
235
|
+
- Name: Default
|
236
|
+
Rules:
|
237
|
+
- Matcher: !ruby/regexp /.*/
|
238
|
+
Domain: default
|
239
|
+
|
240
|
+
- Name: Customers
|
241
|
+
Matcher: Customers
|
242
|
+
Rules:
|
243
|
+
- Ref: Customer
|
244
|
+
|
245
|
+
|
246
|
+
|
247
|
+
- Name: customers_post
|
248
|
+
Matcher: /customers(post)
|
249
|
+
Rules:
|
250
|
+
- Ref: Customer
|
251
|
+
|
252
|
+
- Name: Error
|
253
|
+
Matcher: Error
|
254
|
+
Rules:
|
255
|
+
- Matcher: code
|
256
|
+
Domain: error_codes
|
257
|
+
- Matcher: !ruby/regexp /.*/
|
258
|
+
Domain: default
|
259
|
+
|
260
|
+
|
261
|
+
- Name: customer_get
|
262
|
+
Matcher: /customer(get)
|
263
|
+
Rules:
|
264
|
+
- Ref: Customer
|
265
|
+
- Ref: Default
|
266
|
+
|
267
|
+
- Name: customer_post
|
268
|
+
Matcher: /customer(post)
|
269
|
+
Rules:
|
270
|
+
- Ref: Customer
|
271
|
+
- Ref: Default
|
272
|
+
|
273
|
+
- Name: customers_get
|
274
|
+
Matcher: /customers(get)
|
275
|
+
Rules:
|
276
|
+
- Matcher: names
|
277
|
+
Domain: customer_name
|
278
|
+
- Ref: Default
|
279
|
+
|
280
|
+
|
281
|
+
EOS
|
282
|
+
|
283
|
+
|
284
|
+
INTERFACE_CUSTOMER_SWAGGER = <<-EOS
|
285
|
+
# Example YAML configuration file
|
286
|
+
#
|
287
|
+
swagger: "2.0"
|
288
|
+
info:
|
289
|
+
version: 1.0.0
|
290
|
+
title: Sbuild demo customer
|
291
|
+
description: A simple Customer API
|
292
|
+
termsOfService: http://swagger.io/terms/
|
293
|
+
contact:
|
294
|
+
name: TLA Sbuilder team
|
295
|
+
email: foo@example.com
|
296
|
+
url: http://localhost
|
297
|
+
license:
|
298
|
+
name: MIT
|
299
|
+
url: http://github.com/gruntjs/grunt/blob/master/LICENSE-MIT
|
300
|
+
host: locahost
|
301
|
+
basePath: /api
|
302
|
+
schemes:
|
303
|
+
- http
|
304
|
+
consumes:
|
305
|
+
- application/json
|
306
|
+
produces:
|
307
|
+
- application/json
|
308
|
+
paths:
|
309
|
+
/customer:
|
310
|
+
get:
|
311
|
+
operationId: findCustomers by id
|
312
|
+
parameters:
|
313
|
+
- name: id
|
314
|
+
in: query
|
315
|
+
description: tags to filter by
|
316
|
+
required: false
|
317
|
+
type: array
|
318
|
+
collectionFormat: csv
|
319
|
+
items:
|
320
|
+
type: string
|
321
|
+
- name: limit
|
322
|
+
in: query
|
323
|
+
description: maximum number of results to return
|
324
|
+
required: false
|
325
|
+
type: integer
|
326
|
+
format: int32
|
327
|
+
responses:
|
328
|
+
200:
|
329
|
+
description: OK
|
330
|
+
post:
|
331
|
+
operationId: postCustomer
|
332
|
+
parameters:
|
333
|
+
- name: customer
|
334
|
+
in: body
|
335
|
+
description: Customers to enter
|
336
|
+
required: true
|
337
|
+
schema:
|
338
|
+
$ref: '#/definitions/Customer'
|
339
|
+
responses:
|
340
|
+
200:
|
341
|
+
description: OK
|
342
|
+
/customers:
|
343
|
+
post:
|
344
|
+
operationId: postCustomers
|
345
|
+
parameters:
|
346
|
+
- name: customers
|
347
|
+
in: body
|
348
|
+
description: Customers to enter
|
349
|
+
required: true
|
350
|
+
schema:
|
351
|
+
$ref: '#/definitions/Customers'
|
352
|
+
responses:
|
353
|
+
200:
|
354
|
+
description: OK
|
355
|
+
get:
|
356
|
+
operationId: findCustomers by tag
|
357
|
+
parameters:
|
358
|
+
- name: names
|
359
|
+
in: query
|
360
|
+
description: query by names
|
361
|
+
required: false
|
362
|
+
type: array
|
363
|
+
collectionFormat: csv
|
364
|
+
items:
|
365
|
+
type: string
|
366
|
+
- name: limit
|
367
|
+
in: query
|
368
|
+
description: maximum number of results to return
|
369
|
+
required: false
|
370
|
+
type: integer
|
371
|
+
format: int32
|
372
|
+
responses:
|
373
|
+
200:
|
374
|
+
description: customer response
|
375
|
+
schema:
|
376
|
+
type: array
|
377
|
+
items:
|
378
|
+
$ref: '#/definitions/Customer'
|
379
|
+
default:
|
380
|
+
description: unexpected error
|
381
|
+
schema:
|
382
|
+
$ref: '#/definitions/Error'
|
383
|
+
definitions:
|
384
|
+
Address:
|
385
|
+
properties:
|
386
|
+
street:
|
387
|
+
type: string
|
388
|
+
city:
|
389
|
+
type: string
|
390
|
+
Customers:
|
391
|
+
type: array
|
392
|
+
allOf:
|
393
|
+
- $ref: '#/definitions/Customer'
|
394
|
+
Customer:
|
395
|
+
properties:
|
396
|
+
id:
|
397
|
+
type: string
|
398
|
+
type:
|
399
|
+
type: string
|
400
|
+
name:
|
401
|
+
type: string
|
402
|
+
address:
|
403
|
+
$ref: '#/definitions/Address'
|
404
|
+
|
405
|
+
Error:
|
406
|
+
required:
|
407
|
+
- code
|
408
|
+
- message
|
409
|
+
properties:
|
410
|
+
code:
|
411
|
+
type: integer
|
412
|
+
format: int32
|
413
|
+
message:
|
414
|
+
type: string
|
415
|
+
EOS
|
416
|
+
|
417
|
+
|
418
|
+
|
419
|
+
end
|
420
|
+
end
|