proti
ProTI is an automated unit testing tool for Infrastructure as Code (IaC) programs. ProTI implements Automated Configuration Testing (ACT) for Pulumi TypeScript, minimizing the development effort for unit testing Pulumi TypeScript IaC programs.
Science Score: 49.0%
This score indicates how likely this project is to be science-related based on various indicators:
-
○CITATION.cff file
-
✓codemeta.json file
Found codemeta.json file -
✓.zenodo.json file
Found .zenodo.json file -
✓DOI references
Found 1 DOI reference(s) in README -
✓Academic publication links
Links to: zenodo.org -
○Committers with academic emails
-
○Institutional organization owner
-
○JOSS paper metadata
-
○Scientific vocabulary similarity
Low similarity (12.1%) to scientific vocabulary
Keywords
Repository
ProTI is an automated unit testing tool for Infrastructure as Code (IaC) programs. ProTI implements Automated Configuration Testing (ACT) for Pulumi TypeScript, minimizing the development effort for unit testing Pulumi TypeScript IaC programs.
Basic Info
- Host: GitHub
- Owner: proti-iac
- License: apache-2.0
- Language: TypeScript
- Default Branch: main
- Homepage: https://proti-iac.github.io
- Size: 6.51 MB
Statistics
- Stars: 9
- Watchers: 0
- Forks: 0
- Open Issues: 2
- Releases: 7
Topics
Metadata Files
README.md
ProTI is an automated unit testing tool for Infrastructure as Code (IaC) programs. ProTI implements Automated Configuration Testing (ACT) for Pulumi TypeScript, minimizing the development effort for unit testing Pulumi TypeScript IaC programs. ProTI is extensible through test generator and oracle plugins and leverages ideas from fuzzing and property-based testing.
ProTI builds upon Jest, implementing the Jest runner @proti-iac/runner, the Jest test-runner @proti-iac/test-runner, and the Jest reporter @proti-iac/reporter. @proti-iac/core and @proti-iac/spec implement the core abstractions and the inline specification syntax, leveraging fast-check for random-based testing abstractions. @proti-iac/pulumi-packages-schema implements the first type-based generator and oracle plugins. @proti-iac/plugins-demo demonstrates the setup of an NPM package of configurable ProTI generator and oracle plugins, serving as a blueprint for new ProTI plugins.
Getting Started
To work with ProTI you require an installation of NodeJS with NPM. ProTI is developed with and supports NodeJS 18 LTS.
Using ProTI to Test a Pulumi TypeScript IaC Program
- Set up Jest in the project. Using NPM and
ts-jestfor the transpilation, you can run these commands in the project directory:
bash
npm install --save-dev jest ts-jest
- Install
@proti-iac/runnerand@proti-iac/test-runner:
bash
npm install --save-dev @proti-iac/runner @proti-iac/test-runner
- Configure Jest to invoke ProTI. The easiest way to do so is to inherit the ProTI configuration preset from
@proti-iac/test-runner. You can configure Jest by creating ajest.config.jsfile in the root of your project with this content:
```js /** * For a detailed explanation regarding each configuration property, visit: * https://jestjs.io/docs/configuration */
/** @type {import('jest').Config} */ const config = { preset: "@proti-iac/test-runner", }; module.exports = config; ```
Add further configuration to the file to augment Jest's, ts-jest's, and ProTI's default configuration. The default configuration configures a simple empty state test generator and an oracle that only checks URN uniqueness across all resources, which are implemented in @proti-iac/core. Most likely, you want to configure more sophisticated generator and generator plugins. The next section describes how. Concretely, @proti-iac/pulumi-packages-schema's README describes how to install and configure our first type-based plugins.
- Run ProTI by running Jest on the project:
bash
npx jest
Configuring ProTI
@proti-iac/test-runner exports ProTI's Jest configuration preset. ProTI exposes all configuration options through Jest's configuration interface under the path globals.proti. The type of globals.proti and thus ProTI's configuration options are defined and documented in ProTI's core Config type.
The generator plugin and the set of oracle plugins are configured in the test coordinator configuration. The generator plugin is configured as a NodeJS module resolution string in globals.proti.testCoordinator.generator, and the oracle plugins as an array of NodeJS module resolution strings in globals.proti.testCoordinator.oracles.
The test runner configuration object under globals.proti.testRunner is passed as a whole to fast-check's runner in ProTI's test runner, inheriting all configuration options of fast-check. For instance, you can configure the test runner's verbosity level in globals.proti.testRunner.verbose. 0 only shows the final error result, 1 all failing tests, 2 the full tree of passing and failing tests.
ProTI plugins are configured through globals.proti.plugins.[PLUGIN NAME]. For instance, the schema registry's schema cache of @proti-iac/pulumi-packages-schema can be disabled by setting globals.proti.plugins.pulumi-packages-schema.registry.cacheDownloadedSchemas to false.
Using ProTI's Inline Specifications
To use ProTI's inline specification syntax, additionally, install the @proti-iac/spec package as a dependency (not only as a development dependency):
bash
npm install --save @proti-iac/spec
Simply import the package in your IaC program's code and use the syntax it exports:
ts
import * as ps from "@proti-iac/spec";
As an example of its use, you can have a look at the correct random word website example with ProTI inline specifications.
Detailed Reporting
For detailed reporting in CSV format, additionally install the @proti-iac/reporter package, and configure it as Jest reporter.
Developing ProTI Plugins
ProTI is extended through generator and oracle plugins. Implementing either is simple and demonstrated in @proti-iac/plugins-demo. This package serves as a blueprint for new plugins. Please refer to its code and documentation for further details. Once developed, configure your IaC program to load your plugin as described above under Configuring ProTI.
Developers Guide
This project uses yarn. Initialize all dependencies by running yarn. Further, some end-to-end tests use the example Pulumi TypesScript projects under examples/. To install their dependencies, first, run yarn pack:all in the root directory of this repository and then pnpm install in examples/.
All ProTI packages implement the following commands. Running the respective command in the root directory of this repository executes it for all packages.
yarn buildbuilds the package incrementally.yarn cleandeletes the build.yarn lintruns eslint to indicate simple errors and formatting.yarn testbuilds the package and runs all tests.yarn prepackdeletes the build and rebuilds the package. This is also run duringyarn npm publish.
@proti-iac/test-runner and the plugin packages @proti-iac/plugins-demo and @proti-iac/pulumi-packages-schema further feature yarn dev for development, running Jest configured with the configuration preset of @proti-iac/test-runner and the respective generator and oracle plugins.
Known Issues
Resolving Pulumi Package Schemas
Problem: With Pulumi versions 3.72.0 and 3.73.0 retrieving package schemas of Pulumi packages that are not installed yet leads to a panic in Pulumi's CLI. In ProTI, this means such schemas cannot be resolved. This was fixed in 3.74.0.
Workaround: Use another Pulumi version than 3.72.0 or 3.73.0.
Parallel Test Runner
We use our own Jest runner @proti-iac/runner to pass down the resolver to the test runner @proti-iac/test-runner. This works well in single-worker execution. However, currently, parallel multi-worker execution is broken, most likely because serialization and deserialization of the resolver fails when Jest passes the resolver to the separate test runner.
Workaround: Only use single-worker execution. If multiple projects are tested, this can be enforced with --runInBand or -i.
Jest Memory Leak
Problem: When testing multiple projects, the memory consumption is growing rapidly and the process runs quickly out of memory. Maybe there is a memory leak in the module loading or monkey patching. However, this seems to be a known unsolved issue that has to be fixed by NodeJS or WebKit: https://github.com/jestjs/jest/issues/7874 https://github.com/jestjs/jest/issues/11956
Workarounds: Run ProTI only individually on programs. Fix the "Parallel Test Runner" bug and use --workerIdleMemoryLimit.
Some Design Considerations
We aim to leverage some cool concepts in our code:
- Immutable types: Wherever possible we want to immutable
readonlytype definitions, i.e., throughReadonly<...>,ReadonlyArray<...>,ReadonlySet<...>, andReadonlyMap<..., ...>.@proti-iac/coreimplements aDeepReadonly<...>utility which makes this easier. More about immutable types in TypeScript: https://levelup.gitconnected.com/the-complete-guide-to-immutability-in-typescript-99154f859fdb - Stateless arbitraries: fast-check arbitraries are meant to be stateless, allowing safe re-use across tests. We embrace this and try to re-use instantiated arbitraries wherever possible for better run time and resource efficiency.
Owner
- Name: ProTI Infrastructure as Code Testing
- Login: proti-iac
- Kind: organization
- Email: proti-iac@d.sokolowski.org
- Location: Switzerland
- Website: proti-iac.github.io
- Repositories: 1
- Profile: https://github.com/proti-iac
The home of ProTI, an automated testing tool for Infrastructure as Code programs, and related projects.
GitHub Events
Total
- Release event: 1
- Watch event: 1
- Create event: 1
Last Year
- Release event: 1
- Watch event: 1
- Create event: 1
Committers
Last synced: 8 months ago
Top Committers
| Name | Commits | |
|---|---|---|
| Daniel Sokolowski | g****b@d****g | 327 |
Committer Domains (Top 20 + Academic)
Issues and Pull Requests
Last synced: 6 months ago
All Time
- Total issues: 5
- Total pull requests: 23
- Average time to close issues: 18 days
- Average time to close pull requests: about 2 hours
- Total issue authors: 1
- Total pull request authors: 1
- Average comments per issue: 0.4
- Average comments per pull request: 0.0
- Merged pull requests: 23
- Bot issues: 0
- Bot pull requests: 0
Past Year
- Issues: 0
- Pull requests: 0
- Average time to close issues: N/A
- Average time to close pull requests: N/A
- Issue authors: 0
- Pull request authors: 0
- Average comments per issue: 0
- Average comments per pull request: 0
- Merged pull requests: 0
- Bot issues: 0
- Bot pull requests: 0
Top Authors
Issue Authors
- DSoko2 (4)
Pull Request Authors
- DSoko2 (34)
Top Labels
Issue Labels
Pull Request Labels
Dependencies
- actions/cache v3 composite
- actions/setup-node v3 composite
- pulumi/actions v4 composite
- ./.github/actions/setup-env * composite
- actions/checkout v4 composite
- actions/download-artifact v3 composite
- actions/upload-artifact v3 composite
- ./.github/actions/setup-env * composite
- actions/checkout v4 composite
- softprops/action-gh-release v1 composite
- node latest build
- 304 dependencies
- @types/node ^20.8.10 development
- @proti-iac/spec file:../../../@proti-iac-spec@0.0.0.tgz
- @pulumi/aws ^6.7.0
- @pulumi/awsx ^2.1.0
- @pulumi/pulumi ^3.91.1
- @pulumi/random ^4.14.0
- fast-check ^3.13.2
- @types/node ^20.8.10 development
- @pulumi/aws ^6.7.0
- @pulumi/pulumi ^3.91.1
- @pulumi/random ^4.14.0
- @types/node ^20.8.10 development
- @pulumi/aws ^6.7.0
- @pulumi/pulumi ^3.91.1
- @pulumi/random ^4.14.0
- @types/node ^20.8.10 development
- @proti-iac/spec file:../../../@proti-iac-spec@0.0.0.tgz
- @pulumi/aws ^6.7.0
- @pulumi/pulumi ^3.91.1
- @pulumi/random ^4.14.0
- fast-check ^3.13.2
- @types/node ^20.8.10 development
- @pulumi/aws ^6.7.0
- @pulumi/pulumi ^3.91.1
- @pulumi/random ^4.14.0
- @types/node ^20.8.10 development
- @pulumi/aws ^6.7.0
- @pulumi/pulumi ^3.91.1
- @pulumi/random ^4.14.0
- @types/node ^20.8.10 development
- @pulumi/aws ^6.7.0
- @pulumi/pulumi ^3.91.1
- @pulumi/random ^4.14.0
- @types/node ^20.8.10 development
- @pulumi/aws ^6.7.0
- @pulumi/pulumi ^3.91.1
- @pulumi/random ^4.14.0
- @types/node ^20.8.10 development
- @pulumi/aws ^6.7.0
- @pulumi/pulumi ^3.91.1
- @pulumi/random ^4.14.0
- @types/node ^20.8.10 development
- @pulumi/aws ^6.7.0
- @pulumi/pulumi ^3.91.1
- @pulumi/random ^4.14.0
- @types/node ^20.8.10 development
- @pulumi/aws ^6.7.0
- @pulumi/awsx ^2.1.0
- @pulumi/pulumi ^3.91.1
- @types/node ^20.8.10 development
- @pulumi/aws ^6.7.0
- @pulumi/awsx ^2.1.0
- @pulumi/pulumi ^3.91.1
- @types/node ^20.8.10 development
- @pulumi/aws ^6.7.0
- @pulumi/awsx ^2.1.0
- @pulumi/pulumi ^3.91.1
- @types/node ^20.8.10 development
- @pulumi/aws ^6.7.0
- @pulumi/awsx ^2.1.0
- @pulumi/pulumi ^3.91.1
- @types/node ^20.8.10 development
- @pulumi/aws ^6.7.0
- @pulumi/awsx ^2.1.0
- @pulumi/pulumi ^3.91.1
- @types/node ^20.8.10 development
- @pulumi/aws ^6.7.0
- @pulumi/awsx ^2.1.0
- @pulumi/pulumi ^3.91.1
- @types/node ^20.8.10 development
- @pulumi/aws ^6.7.0
- @pulumi/awsx ^2.1.0
- @pulumi/pulumi ^3.91.1
- @types/node ^20.8.10 development
- @pulumi/aws ^6.7.0
- @pulumi/awsx ^2.1.0
- @pulumi/pulumi ^3.91.1
- @types/node ^20.8.10 development
- @pulumi/aws ^6.7.0
- @pulumi/awsx ^2.1.0
- @pulumi/pulumi ^3.91.1
- @types/node ^20.8.10 development
- @pulumi/aws ^6.7.0
- @pulumi/awsx ^2.1.0
- @pulumi/pulumi ^3.91.1
- @types/deasync ^0.1.4 development
- @types/node ^20.8.10 development
- @pulumi/aws ^6.7.0
- @pulumi/awsx ^2.1.0
- @pulumi/pulumi ^3.91.1
- deasync ^0.1.29
- @types/node ^20.8.10 development
- @pulumi/aws ^6.7.0
- @pulumi/awsx ^2.1.0
- @pulumi/pulumi ^3.91.1
- @types/node ^20.8.10 development
- @proti-iac/spec file:../../../@proti-iac-spec@0.0.0.tgz
- @pulumi/aws ^6.7.0
- @pulumi/awsx ^2.1.0
- @pulumi/pulumi ^3.91.1
- fast-check ^3.13.2
- @types/node ^20.8.10 development
- @proti-iac/spec file:../../../@proti-iac-spec@0.0.0.tgz
- @pulumi/aws ^6.7.0
- @pulumi/awsx ^2.1.0
- @pulumi/pulumi ^3.91.1
- fast-check ^3.13.2
- @types/node ^20.8.10 development
- @pulumi/aws ^6.7.0
- @pulumi/pulumi ^3.91.1
- @types/node ^20.8.10 development
- @pulumi/aws ^6.7.0
- @pulumi/pulumi ^3.91.1
- @types/node ^20.8.10 development
- @pulumi/aws ^6.7.0
- @pulumi/pulumi ^3.91.1
- @types/node ^20.8.10 development
- @pulumi/aws ^6.7.0
- @pulumi/pulumi ^3.91.1
- @types/node ^20.8.10 development
- @pulumi/aws ^6.7.0
- @pulumi/pulumi ^3.91.1
- @types/node ^20.8.10 development
- @pulumi/aws ^6.7.0
- @pulumi/pulumi ^3.91.1
- @types/node ^20.8.10 development
- @pulumi/aws ^6.7.0
- @pulumi/pulumi ^3.91.1
- @types/node ^20.8.10 development
- @pulumi/aws ^6.7.0
- @pulumi/pulumi ^3.91.1
- @proti-iac/runner workspace:^ development
- @proti-iac/test-runner workspace:^ development
- @types/jest ^29.5.7 development
- @types/node ^18.18.8 development
- @typescript-eslint/eslint-plugin ^6.9.1 development
- @typescript-eslint/parser ^6.9.1 development
- eslint ^8.52.0 development
- eslint-config-airbnb-base ^15.0.0 development
- eslint-config-airbnb-base-typescript ^1.1.0 development
- eslint-config-prettier ^9.0.0 development
- eslint-plugin-import ^2.29.0 development
- eslint-plugin-jsdoc ^46.8.2 development
- eslint-plugin-prettier ^5.0.1 development
- fast-check ^3.13.2 development
- jest ^29.7.0 development
- jest-config ^29.7.0 development
- prettier ^3.0.3 development
- ts-jest ^29.1.1 development
- ts-node ^10.9.1 development
- ts-patch 3.0.2 development
- typescript ^5.2.2 development
- typia ^5.2.4 development
- @jest/types ^29.6.3 development
- @types/jest ^29.5.7 development
- @types/js-yaml ^4.0.8 development
- @types/node ^18.18.8 development
- jest-haste-map ^29.7.0 development
- jest-resolve ^29.7.0 development
- jest-runtime ^29.7.0 development
- typescript ^5.2.2 development
- @proti-iac/spec workspace:^
- @pulumi/pulumi ^3.91.1
- fast-check ^3.13.2
- jest-resolve-dependencies ^29.7.0
- jest-snapshot ^29.7.0
- js-yaml ^4.1.0
- ts-patch 3.0.2
- typia ^5.2.4
- @jest/types ^29.6.3 development
- @types/jest ^29.5.7 development
- @types/node ^18.18.8 development
- jest ^29.7.0 development
- typescript ^5.2.2 development
- @proti-iac/core workspace:^
- @pulumi/pulumi ^3.91.1
- fast-check ^3.13.2
- ts-patch 3.0.2
- typia ^5.2.4
- @types/jest ^29.5.7 development
- @types/node ^18.18.8 development
- jest ^29.7.0 development
- pure-rand ^6.0.4 development
- typescript ^5.2.2 development
- @proti-iac/core workspace:^
- @pulumi/pulumi ^3.91.1
- fast-check ^3.13.2
- ts-patch 3.0.2
- typia ^5.2.4
- @proti-iac/core workspace:^ development
- @proti-iac/test-runner workspace:^ development
- @types/jest ^29.5.7 development
- @types/node ^18.18.8 development
- jest ^29.7.0 development
- ts-jest ^29.1.1 development
- typescript ^5.2.2 development
- @jest/reporters ^29.7.0
- @jest/test-result ^29.7.0
- csv-stringify ^6.4.4
- ts-patch 3.0.2
- typia ^5.2.4
- @types/jest ^29.5.7 development
- @types/node ^18.18.8 development
- jest ^29.7.0 development
- ts-jest ^29.1.1 development
- typescript ^5.2.2 development
- @jest/test-result ^29.7.0
- @proti-iac/core workspace:^
- jest-runner ^29.7.0
- jest-watcher ^29.7.0
- @pulumi/pulumi ^3.91.1 development
- @types/jest ^29.5.7 development
- @types/node ^18.18.8 development
- typescript ^5.2.2 development
- fast-check ^3.13.2
- @jest/environment ^29.7.0 development
- @jest/test-result ^29.7.0 development
- @jest/types ^29.6.3 development
- @proti-iac/runner workspace:^ development
- @types/jest ^29.5.7 development
- @types/node ^18.18.8 development
- jest-haste-map ^29.7.0 development
- jest-resolve ^29.7.0 development
- jest-runtime ^29.7.0 development
- typescript ^5.2.2 development
- @jest/expect ^29.7.0
- @proti-iac/core workspace:^
- @pulumi/pulumi ^3.91.1
- fast-check ^3.13.2
- jest ^29.7.0
- jest-config ^29.7.0
- ts-jest ^29.1.1
- ts-node ^10.9.1
- 747 dependencies