Koncur - A test harness for Konveyor tools that "concurs with your expected results!"
Koncur is a declarative test harness for running and validating end-to-end tests for Konveyor tools (Kantra, Tackle, Kai). Define what you want to analyze, not how to run commands.
- Declarative test definitions - Specify application, label selector, and analysis mode
- Multiple execution targets - Kantra CLI, Tackle Hub API, Tackle UI, Kai RPC, VSCode extension
- Flexible target configuration - Separate target config from test definitions
- Exact match validation - Compare actual output against expected RuleSets
- Clear diff output - See exactly what differs when tests fail
- Multiple input formats - Support for inline expected results or file references
- Built on Konveyor types - Uses analyzer-lsp RuleSet structures directly
- Automatic output filtering - Filters empty rulesets for cleaner expected outputs
- Test output management - Clean up old test runs with the
cleancommand
go build -o koncur ./cmd/koncur# my-test.yaml
name: "Sample Kantra Test"
description: "Test cloud-readiness analysis"
analysis:
application: /path/to/application/source
labelSelector: "konveyor.io/target=quarkus"
analysisMode: source-only
expect:
exitCode: 0
output:
result:
- name: cloud-readiness
violations:
session-00001:
description: "Avoid use of HttpSession"
category: mandatory
incidents:
- uri: "file:///src/main/java/MyServlet.java"
lineNumber: 42# Use default target (kantra)
koncur run my-test.yaml
# Specify target type
koncur run my-test.yaml --target kantra
# Use a target configuration file
koncur run my-test.yaml --target-config target-tackle-hub.yamlname: "Test Name"
description: "Optional description"
analysis:
# Application to analyze (file path or git URL)
application: /path/to/source
# Optional: Label selector expression
labelSelector: "konveyor.io/target=quarkus"
# Analysis mode: source-only | full
analysisMode: source-only
# Optional: Execution timeout (default: 5m)
timeout: 10m
# Optional: Work directory (default: .koncur/output)
workDir: /tmp/my-tests
expect:
exitCode: 0
output:
# Option 1: Inline expected RuleSets
result:
- name: ruleset-name
violations: {...}
# Option 2: Reference to external file
file: /absolute/path/to/expected.yamlTarget configuration is separate from test definitions, allowing the same test to run against different targets/environments.
type: kantra
kantra:
binaryPath: /usr/local/bin/kantra # Optionaltype: tackle-hub
tackleHub:
url: https://tackle-hub.example.com
username: admin
password: secret
# Or use token:
# token: your-api-tokenNot Implemented
type: tackle-ui
tackleUI:
url: https://tackle.example.com
username: admin
password: secret
browser: chrome # chrome or firefox
headless: trueNot Implemented
type: kai-rpc
kaiRPC:
host: localhost
port: 8080** Not Implemented **
type: vscode
vscode:
binaryPath: /usr/local/bin/code # Optional
extensionId: konveyor.konveyor-analyzer
workspaceDir: /path/to/workspace # OptionalExecute a test and validate output against expected results.
koncur run testdata/examples/sample_test.yamlValidate a test definition without running it.
koncur validate testdata/examples/sample_test.yamlGenerate expected outputs by running tests and capturing their results. This command:
- Finds all
test.yamlfiles in the specified directory - Executes each test using the specified target
- Filters out empty rulesets (no violations, insights, or tags)
- Saves the filtered output as
expected-output.yamlin each test directory - Updates test definitions to use file-based expectations
# Generate expected outputs for all tests
koncur generate -d ./tests
# Generate for a specific test
koncur generate -d ./tests/my-test
# Filter by test name pattern
koncur generate -d ./tests --filter "tackle"
# Dry run (show what would be done)
koncur generate -d ./tests --dry-run
# Use a specific target
koncur generate -d ./tests --target kantraFlags:
-d, --test-dir- Directory containing test definitions (default:./tests)-f, --filter- Filter tests by name pattern--dry-run- Show what would be done without executing-t, --target- Target type to use (default:kantra)
Clean up old test run outputs from the .koncur/output directory.
By default, keeps the most recent run for each test and deletes older ones.
# Clean old test runs (keeps latest for each test)
koncur clean
# Preview what would be deleted
koncur clean --dry-run
# Remove all output directories
koncur clean --all
# Preview removing everything
koncur clean --all --dry-runFlags:
--all- Remove all output directories (not just old ones)--dry-run- Show what would be deleted without actually deleting
-v, --verbose- Enable verbose logging
See testdata/examples/ for sample test definitions.
pkg/config/- Test definition types and loadingpkg/targets/- Target executors (Kantra, Tackle, Kai)pkg/parser/- Output parsing (RuleSets)pkg/validator/- Exact match validation with diffpkg/cli/- CLI commands
# Build
go build -o koncur ./cmd/koncur
# Run tests
go test ./...
# Validate a test definition
./koncur validate testdata/examples/sample_test.yamlKoncur includes a Makefile for quickly setting up and testing against a local Tackle Hub instance running in Kind (Kubernetes in Docker).
# Complete setup: create cluster, install hub, build binary
make setup
# This runs:
# 1. make kind-create - Creates Kind cluster with ingress
# 2. make hub-install - Installs Tackle Hub with OLM
# 3. make build - Builds the koncur binaryOnce setup is complete, Tackle Hub is accessible via:
Ingress (recommended):
- Hub API:
http://localhost:8080/hub - Hub UI:
http://localhost:8080/hub
Port-forward (alternative):
make hub-forward
# Hub will be available at http://localhost:8081# Run a test against Tackle Hub
make test-hub
# Or run manually with koncur
./koncur run tests/tackle-testapp-with-deps/test.yaml \
--target-config .koncur/config/target-tackle-hub.yamlSetup & Teardown:
make setup- Complete setup (cluster + hub + build)make teardown- Complete teardown (uninstall hub + delete cluster)
Cluster Management:
make kind-create- Create Kind cluster with ingress-nginxmake kind-delete- Delete the Kind cluster
Tackle Hub:
make hub-install- Install Tackle Hub (OLM + operator + CR)make hub-uninstall- Uninstall Tackle Hubmake hub-status- Check Tackle Hub statusmake hub-forward- Port-forward to access Hub at :8081
Build & Test:
make build- Build koncur binarymake test-hub- Run tackle-testapp test against Hubmake clean- Clean build artifacts and test outputs
The Makefile uses these configurable variables:
# Cluster Configuration
KIND_CLUSTER_NAME ?= koncur-test
KONVEYOR_NAMESPACE ?= konveyor-tackle
KUBECTL ?= kubectl
# Image Overrides (optional)
# Override any image by setting environment variables:
HUB ?= quay.io/konveyor/tackle2-hub:latest
ANALYZER_ADDON ?= quay.io/konveyor/tackle2-addon-analyzer:latest
CSHARP_PROVIDER_IMG ?= quay.io/konveyor/c-sharp-provider:latest
GENERIC_PROVIDER_IMG ?= quay.io/konveyor/generic-external-provider:latest
JAVA_PROVIDER_IMG ?= quay.io/konveyor/java-external-provider:latest
RUNNER_IMG ?= quay.io/konveyor/kantra:latest
DISCOVERY_ADDON ?= quay.io/konveyor/tackle2-addon-discovery:latest
PLATFORM_ADDON ?= quay.io/konveyor/tackle2-addon-platform:latestTo use custom or locally-built images, set environment variables:
# Use a custom Hub image
HUB=localhost:5000/tackle2-hub:dev make hub-install
# Use multiple custom images
HUB=quay.io/myorg/tackle2-hub:v1.2.3 \
ANALYZER_ADDON=quay.io/myorg/analyzer:latest \
make hub-install
# Use latest from a different registry
HUB=ghcr.io/konveyor/tackle2-hub:main make hub-installThe default Tackle Hub target config (.koncur/config/target-tackle-hub.yaml):
type: tackle-hub
tackleHub:
url: http://localhost:8080/hub
token: ""
mavenSettings: settings.xmlThe make hub-install target automatically:
- Installs OLM (Operator Lifecycle Manager)
- Installs Tackle Operator from main branch
- Creates Tackle CR with:
- Authentication disabled (
feature_auth_required: "false") - Cache storage configured (10Gi RWX PV)
- Resource limits optimized for testing (100m CPU for providers)
- All component images configurable via environment variables
- Authentication disabled (
- Patches ingress to disable SSL redirect (allows HTTP access at
http://localhost:8080) - Waits for readiness with automatic health checks
Ingress redirecting to HTTPS:
- The Makefile automatically patches the ingress to disable SSL redirect
- If you see 308 redirects, run:
kubectl annotate ingress tackle -n konveyor-tackle nginx.ingress.kubernetes.io/ssl-redirect="false" --overwrite
Ingress not working:
- Ensure Kind cluster was created with ingress support:
kubectl get pods -n ingress-nginx - Verify ingress controller is running and ready
- Check ingress resource:
kubectl get ingress -n konveyor-tackle
Operator not ready:
- Check operator logs:
kubectl logs -n konveyor-tackle -l name=tackle-operator - Verify CRD installed:
kubectl get crd tackles.tackle.konveyor.io
Hub pods not starting:
- Check pod status:
make hub-status - View pod logs:
kubectl logs -n konveyor-tackle -l app.kubernetes.io/name=tackle-hub
Apache 2.0