Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding array operations unit test WDL #25

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 91 additions & 0 deletions arrayOperations/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# ArrayOperations WDL Workflow

## Overview
A comprehensive test workflow that demonstrates array handling, scatter-gather functionality, and various array operations in WDL. The workflow performs multiple array tests including empty array handling, indexing, array functions, concatenation, and nested array processing, while maintaining its original uppercase conversion functionality.

## Workflow Components

### Workflow: `ArrayOperations`
The main workflow demonstrates various array operations and parallel processing capabilities.

**Inputs:**
- `strings`: Array[String] - Primary list of strings to be processed
- `additional_strings`: Array[String] - Secondary array for testing concatenation (optional, defaults to empty)
- `nested_arrays`: Array[Array[String]] - Array of arrays for testing nested operations (optional, defaults to empty)

**Outputs:**
- `uppercased`: Array[String] - List of input strings converted to uppercase
- `first_index`: Int? - First valid index of the input array (0)
- `last_index`: Int? - Last valid index of the input array
- `sorted_array`: Array[String] - Input array sorted alphabetically
- `processed_nested`: Array[Array[String]] - Processed nested arrays
- `concat_test_passed`: Boolean - Validation result of array concatenation
- `array_length`: Int - Length of the input array
- `flattened`: Array[String] - Flattened version of nested arrays

### Tasks

#### Task: `Uppercase`
Converts a single string to uppercase using the Unix `tr` command.

#### Task: `ValidateIndex`
Validates array indexing by returning first and last valid indices.

#### Task: `ArrayFunctions`
Tests various array operations including sorting, length calculation, and flattening.

#### Task: `ArrayConcat`
Tests array concatenation and validates the resulting length.

**Runtime Requirements:**
All tasks:
- CPU: 1 core
- Memory: 1 GB

## Usage
```bash
# Execute with cromwell
java -jar cromwell.jar run arrayOperations.wdl -i inputs.json

# Execute with miniwdl
miniwdl run arrayOperations.wdl \
strings='["hello", "world", "test"]' \
additional_strings='["foo", "bar"]' \
nested_arrays='[["nested1", "nested2"], ["nested3", "nested4"]]'
```

Example inputs.json:
```json
{
"ArrayOperations.strings": ["hello", "world", "test"],
"ArrayOperations.additional_strings": ["foo", "bar"],
"ArrayOperations.nested_arrays": [
["nested1", "nested2"],
["nested3", "nested4"]
]
}
```

## Purpose
This workflow serves as a comprehensive test case for:
- Array input/output handling
- Empty array processing
- Array indexing and bounds checking
- Array sorting and length calculations
- Array concatenation
- Nested array operations
- Scatter-gather operations
- Parallel task execution
- Basic string manipulation
- Output array collection

## Version
WDL 1.0

## Notes
- Useful for testing backend's ability to handle parallel task execution
- Demonstrates proper scatter-gather syntax
- Shows comprehensive array manipulation patterns
- Handles edge cases like empty arrays
- Tests multiple array operations in a single workflow
- Provides validation for array operations
148 changes: 148 additions & 0 deletions arrayOperations/arrayOperations.wdl
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
version 1.0

workflow ArrayOperations {
input {
Array[String] strings
Array[String] additional_strings = [] # For testing array concatenation
Array[Array[String]] nested_arrays = [] # For testing array of arrays
}

# Test empty arrays (original operation still works with empty input)
scatter (str in strings) {
call Uppercase { input: text = str }
}

# Test array indexing
if (length(strings) > 0) {
call ValidateIndex { input: arr = strings }
}

# Test array functions
call ArrayFunctions {
input:
arr = strings,
nested = nested_arrays
}

# Test array concatenation
Array[String] combined = flatten([strings, additional_strings])
call ArrayConcat {
input:
arr1 = strings,
arr2 = additional_strings,
expected_length = length(combined)
}

output {
Array[String] uppercased = Uppercase.out
Int? first_index = ValidateIndex.first_index
Int? last_index = ValidateIndex.last_index
Array[String] sorted_array = ArrayFunctions.sorted
Array[Array[String]] processed_nested = ArrayFunctions.processed_nested
Boolean concat_test_passed = ArrayConcat.test_passed
Int array_length = ArrayFunctions.arr_length
Array[String] flattened = ArrayFunctions.flattened
}

parameter_meta {
strings: "Primary array of input strings"
additional_strings: "Secondary array for testing concatenation"
nested_arrays: "Array of arrays for testing nested array operations"
}
}

task Uppercase {
input {
String text
}

command <<<
echo "~{text}" | tr '[:lower:]' '[:upper:]'
>>>

output {
String out = read_string(stdout())
}

runtime {
cpu: 1
memory: "1 GB"
}
}

task ValidateIndex {
input {
Array[String] arr
}

command <<<
echo "0" > first_index.txt # First index
echo "~{length(arr)-1}" > last_index.txt # Last index
>>>

output {
Int first_index = read_int("first_index.txt")
Int last_index = read_int("last_index.txt")
}

runtime {
cpu: 1
memory: "1 GB"
}
}

task ArrayFunctions {
input {
Array[String] arr
Array[Array[String]] nested
}

command <<<
# Sort the input array using bash
echo "~{sep='\n' arr}" | sort > sorted.txt

# Get array length
echo "~{length(arr)}" > length.txt

# Process nested arrays (flatten them)
echo "~{sep='\n' flatten(nested)}" > flattened.txt
>>>

output {
Array[String] sorted = read_lines("sorted.txt")
Int arr_length = read_int("length.txt")
Array[String] flattened = read_lines("flattened.txt")
Array[Array[String]] processed_nested = nested # Return the original nested array
}

runtime {
cpu: 1
memory: "1 GB"
}
}

task ArrayConcat {
input {
Array[String] arr1
Array[String] arr2
Int expected_length
}

command <<<
actual_length=$(( ~{length(arr1)} + ~{length(arr2)} ))
if [ "$actual_length" -eq ~{expected_length} ]; then
echo "true"
else
echo "false"
fi
>>>

output {
Boolean test_passed = read_boolean(stdout())
}

runtime {
cpu: 1
memory: "1 GB"
}
}
8 changes: 8 additions & 0 deletions arrayOperations/inputs.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"ArrayOperations.strings": ["hello", "world", "test"],
"ArrayOperations.additional_strings": ["foo", "bar"],
"ArrayOperations.nested_arrays": [
["nested1", "nested2"],
["nested3", "nested4"]
]
}
5 changes: 5 additions & 0 deletions arrayOperations/options.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"workflow_failure_mode": "ContinueWhilePossible",
"write_to_cache": false,
"read_from_cache": false
}
Loading