mirror of
https://github.com/j3ssie/osmedeus.git
synced 2026-08-26 09:32:28 +02:00
- Add platform variables (PlatformOS, PlatformArch, PlatformInDocker, PlatformInKubernetes, PlatformCloudProvider) to linter's built-in variables list - Extract checkStepFieldsForUndefinedVars and collectReferencedVarsFromStep helper functions to support comprehensive scanning of all template-renderable fields including parallel_functions, speed_args, config_args, agent fields, HTTP headers, LLM messages, decision cases/conditions, and memory paths - Add recursion for nested steps (foreach inner steps and parallel_steps) with proper variable scoping and support for loop-specific variables (_id_, foreach variable) - Enhance message formatting with highlightQuoted() to make quoted terms bold+yellow in error output - Enable UndefinedVariableRule by default in GetDefaultRules() - Add comprehensive test coverage for newly supported fields and nested step types (TestUndefinedVariableRule_*, TestUnusedVariableRule_ReferencedInNewFields) - Add test fixture and E2E test (TestWorkflow_Validate_UndefinedVarsComprehensive) validating detection across functions and foreach
186 lines
5.7 KiB
Go
186 lines
5.7 KiB
Go
package e2e
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestWorkflow_DefaultToList(t *testing.T) {
|
|
log := NewTestLogger(t)
|
|
log.Step("Testing workflow default to list command")
|
|
|
|
workflowPath := getTestdataPath(t)
|
|
log.Info("Using workflow path: %s", workflowPath)
|
|
|
|
stdout, _, err := runCLIWithLog(t, log, "workflow", "-F", workflowPath)
|
|
require.NoError(t, err)
|
|
|
|
log.Info("Asserting stdout contains Total")
|
|
assert.Contains(t, stdout, "Total:")
|
|
|
|
log.Success("workflow default lists workflows")
|
|
}
|
|
|
|
func TestWorkflow_List(t *testing.T) {
|
|
log := NewTestLogger(t)
|
|
log.Step("Testing workflow list command")
|
|
|
|
workflowPath := getTestdataPath(t)
|
|
log.Info("Using workflow path: %s", workflowPath)
|
|
|
|
stdout, _, err := runCLIWithLog(t, log, "workflow", "list", "-F", workflowPath)
|
|
require.NoError(t, err)
|
|
|
|
log.Info("Asserting stdout contains Total and test-bash")
|
|
assert.Contains(t, stdout, "Total:")
|
|
assert.Contains(t, stdout, "test-bash")
|
|
|
|
log.Success("workflow list displays workflows correctly")
|
|
}
|
|
|
|
func TestWorkflow_Show(t *testing.T) {
|
|
log := NewTestLogger(t)
|
|
log.Step("Testing workflow show command")
|
|
|
|
workflowPath := getTestdataPath(t)
|
|
log.Info("Showing workflow: test-bash")
|
|
|
|
stdout, _, err := runCLIWithLog(t, log, "workflow", "show", "test-bash", "-F", workflowPath)
|
|
require.NoError(t, err)
|
|
|
|
log.Info("Asserting stdout contains Metadata and Steps (table format is default)")
|
|
assert.Contains(t, stdout, "Metadata:")
|
|
assert.Contains(t, stdout, "Steps:")
|
|
|
|
log.Success("workflow show displays workflow details")
|
|
}
|
|
|
|
func TestWorkflow_Show_Verbose(t *testing.T) {
|
|
log := NewTestLogger(t)
|
|
log.Step("Testing workflow show verbose command")
|
|
|
|
workflowPath := getTestdataPath(t)
|
|
log.Info("Showing workflow with verbose flag: test-bash")
|
|
|
|
stdout, _, err := runCLIWithLog(t, log, "workflow", "show", "test-bash", "-v", "-F", workflowPath)
|
|
require.NoError(t, err)
|
|
|
|
log.Info("Asserting stdout contains Variable and Description (table format with verbose)")
|
|
assert.Contains(t, stdout, "Variable")
|
|
assert.Contains(t, stdout, "Description")
|
|
|
|
log.Success("workflow show verbose displays extra details")
|
|
}
|
|
|
|
func TestWorkflow_Show_Yaml(t *testing.T) {
|
|
log := NewTestLogger(t)
|
|
log.Step("Testing workflow show YAML output")
|
|
|
|
workflowPath := getTestdataPath(t)
|
|
log.Info("Showing workflow as YAML: test-bash")
|
|
|
|
stdout, _, err := runCLIWithLog(t, log, "workflow", "show", "test-bash", "--yaml", "-F", workflowPath)
|
|
require.NoError(t, err)
|
|
|
|
log.Info("Asserting stdout contains YAML fields (requires --yaml flag)")
|
|
assert.Contains(t, stdout, "name:")
|
|
assert.Contains(t, stdout, "kind:")
|
|
assert.Contains(t, stdout, "steps:")
|
|
|
|
log.Success("workflow show YAML outputs valid YAML")
|
|
}
|
|
|
|
func TestWorkflow_Show_NotFound(t *testing.T) {
|
|
log := NewTestLogger(t)
|
|
log.Step("Testing workflow show with nonexistent workflow")
|
|
|
|
workflowPath := getTestdataPath(t)
|
|
log.Info("Attempting to show nonexistent workflow")
|
|
|
|
_, stderr, err := runCLIWithLog(t, log, "workflow", "show", "nonexistent-workflow", "-F", workflowPath)
|
|
|
|
log.Info("Asserting command returns error")
|
|
assert.Error(t, err)
|
|
|
|
log.Info("Asserting stderr contains failure message")
|
|
assert.Contains(t, stderr, "Failed")
|
|
|
|
log.Success("workflow show correctly reports not found error")
|
|
}
|
|
|
|
func TestWorkflow_Validate_Success(t *testing.T) {
|
|
log := NewTestLogger(t)
|
|
log.Step("Testing workflow validate with valid workflow")
|
|
|
|
workflowPath := getTestdataPath(t)
|
|
log.Info("Validating workflow: test-bash")
|
|
|
|
stdout, _, err := runCLIWithLog(t, log, "workflow", "validate", "test-bash", "-F", workflowPath)
|
|
require.NoError(t, err)
|
|
|
|
log.Info("Asserting stdout contains validation success")
|
|
// Accept either old "is valid" or new "passed all lint checks" message
|
|
assert.True(t, strings.Contains(stdout, "is valid") || strings.Contains(stdout, "passed all lint checks"),
|
|
"Expected success message in output: %s", stdout)
|
|
|
|
log.Success("workflow validate reports valid workflow")
|
|
}
|
|
|
|
func TestWorkflow_Validate_UndefinedVarsComprehensive(t *testing.T) {
|
|
log := NewTestLogger(t)
|
|
log.Step("Testing workflow validate catches undefined vars in functions and foreach")
|
|
|
|
fixturePath := filepath.Join(getTestdataPath(t), "linter", "undefined-vars-comprehensive.yaml")
|
|
log.Info("Validating fixture: %s", fixturePath)
|
|
|
|
stdout, _, err := runCLIWithLog(t, log, "workflow", "validate", fixturePath)
|
|
require.NoError(t, err) // warnings don't cause error exit
|
|
|
|
log.Info("Asserting each undefined variable is reported")
|
|
assert.Contains(t, stdout, "funcUndef")
|
|
assert.Contains(t, stdout, "foreachCmdUndef")
|
|
assert.Contains(t, stdout, "foreachFuncUndef")
|
|
|
|
// Verify valid vars are NOT flagged
|
|
assert.NotContains(t, stdout, "'target' is not defined")
|
|
assert.NotContains(t, stdout, "'line' is not defined")
|
|
assert.NotContains(t, stdout, "'item' is not defined")
|
|
assert.NotContains(t, stdout, "'Output' is not defined")
|
|
|
|
log.Success("All undefined variables detected correctly")
|
|
}
|
|
|
|
func TestWorkflow_Validate_Fail(t *testing.T) {
|
|
log := NewTestLogger(t)
|
|
log.Step("Testing workflow validate with invalid workflow")
|
|
|
|
tmpDir := t.TempDir()
|
|
log.Info("Creating invalid workflow in temp dir: %s", tmpDir)
|
|
|
|
// Create invalid workflow YAML
|
|
invalidYAML := `name: invalid-workflow
|
|
kind: module
|
|
steps:
|
|
- name: missing-type
|
|
command: echo hello
|
|
`
|
|
err := os.WriteFile(filepath.Join(tmpDir, "invalid.yaml"), []byte(invalidYAML), 0644)
|
|
require.NoError(t, err)
|
|
|
|
log.Info("Validating invalid workflow")
|
|
_, stderr, err := runCLIWithLog(t, log, "workflow", "validate", "invalid", "-F", tmpDir)
|
|
|
|
log.Info("Asserting command returns error")
|
|
assert.Error(t, err)
|
|
|
|
log.Info("Asserting stderr mentions type error")
|
|
assert.Contains(t, stderr, "type")
|
|
|
|
log.Success("workflow validate correctly reports invalid workflow")
|
|
}
|