tla-sbuilder 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.
- 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
|
+

|
|
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
|