Cross-Language Compatibility Testing¶
This document describes how to run and verify cross-language compatibility between the Python soup CLI and the Go soup-go harness, ensuring that data structures (CTY values, HCL, wire protocol) can be correctly exchanged between implementations.
Prerequisites¶
1. Build the Go Harness¶
The soup-go binary must be built before running tests:
The binary will be placed in /Users/tim/code/gh/provide-io/tofusoup/bin/soup-go.
2. Python Environment¶
Ensure the Python environment is activated with all dependencies:
Running Cross-Language Tests¶
CTY Compatibility Tests¶
The primary cross-language compatibility tests are in conformance/cty/souptest_cty_interop.py.
Run all CTY compatibility tests:¶
Run specific test cases:¶
# Test a specific case (e.g., string handling)
pytest conformance/cty/souptest_cty_interop.py -k "string_simple" -v
# Test unknown value handling (will be skipped for JSON input)
pytest conformance/cty/souptest_cty_interop.py -k "unknown" -v
Test Architecture¶
Test Flow¶
The cross-language tests verify bidirectional compatibility:
- Python → Go → Python: Python creates fixtures, Go processes them, Python validates
- Go → Python → Go: Go creates fixtures, Python processes them, Go validates
Test Cases¶
The test suite covers: - Basic types: strings, numbers, booleans - Null values: Proper null handling across languages - Unknown values: MessagePack-only (JSON not supported by go-cty) - Collections: Lists, sets, maps - Complex types: Objects, tuples, nested structures - Dynamic types: Dynamic pseudo-type wrapping
Important Limitations¶
Unknown Values and JSON¶
go-cty (and Terraform) CANNOT handle unknown values in JSON format. This is a fundamental limitation:
- ❌ JSON → Unknown → Go: Will fail with "value is not known"
- ✅ MessagePack → Unknown → Go: Works correctly
- ✅ Go → Unknown → MessagePack: Works correctly
- ❌ Go → Unknown → JSON: Will fail with "value is not known"
Tests involving unknown values through JSON are automatically skipped.
Manual Verification¶
CTY Operations¶
Test basic conversion:¶
# JSON to MessagePack
echo '"hello"' | soup-go cty convert - - \
--input-format json \
--output-format msgpack \
--type '"string"' | xxd
# MessagePack roundtrip
echo '"test"' | soup-go cty convert - - \
--input-format json \
--output-format msgpack \
--type '"string"' | \
soup-go cty convert - - \
--input-format msgpack \
--output-format json \
--type '"string"'
Test validation:¶
# Validate a value
soup-go cty validate-value '"hello"' --type '"string"'
# Should output: "Validation Succeeded"
HCL Parsing¶
Create a test HCL file:¶
Parse with soup-go:¶
Expected output:
{
"body": {
"blocks": [
{
"body": {
"count": 42,
"name": "hello"
},
"labels": ["example", "test"],
"type": "resource"
}
]
},
"success": true
}
Validate HCL syntax:¶
Wire Protocol¶
Test encoding/decoding:¶
# JSON to MessagePack wire format
echo '{"key": "value"}' | soup-go wire encode - - \
--input-format json \
--output-format msgpack | xxd
# With CTY type awareness
echo '"hello"' | soup-go wire encode - - \
--input-format json \
--output-format msgpack \
--type '"string"' | xxd
Debugging Failed Tests¶
1. Check Binary Version¶
Ensure soup-go is up to date:
2. Verbose Logging¶
Run soup-go with verbose logging:
soup-go --log-level debug cty convert - - \
--input-format json \
--output-format msgpack \
--type '"string"' <<< '"test"'
3. Check MessagePack Formats¶
Python and Go use slightly different MessagePack extension formats for unknown values:
- Python: c70000 (fixext2)
- Go: d40000 (fixext1)
Both formats are interoperable and correctly handled by both implementations.
4. Common Issues¶
"value is not known" Error¶
This occurs when trying to convert unknown values through JSON. This is expected behavior matching Terraform. Use MessagePack for unknown values.
"unknown flag" Error¶
The soup-go binary is outdated. Rebuild it:
Continuous Integration¶
For CI/CD pipelines, ensure:
- Go is installed (version 1.21+)
- Build soup-go before running tests:
- Run the test suite:
Reference Implementation¶
The Go implementation (soup-go) serves as the reference implementation that exactly matches Terraform's behavior. No workarounds or Python-specific accommodations should be made in the Go code. Instead, Python tests should adapt to Go/Terraform's limitations (e.g., skipping unknown value tests for JSON input).