Repository: xataio/pgstream
Pull request #175 (2025-03-14 12:48:21)

Do not use int64 as yaml parameters
Use int instead of int64 as it's not supported in yaml format.
This will cause us to accept 4 byte integers for integer transformers. We should find a way to support int64.
For unix transformers, the input type will be string, which will be parsed into int64 internally.

github-actions[bot]: ### Merging this branch will **decrease** overall coverage

| Impacted Packages | Coverage Δ | :robot: |
|-------------------|------------|---------|
| github.com/xataio/pgstream/pkg/transformers/greenmask | 93.38% (**-0.37%**) | :thumbsdown: |

---

<details>

<summary>Coverage by file</summary>

### Changed files (no unit tests)

| Changed File | Coverage Δ | Total | Covered | Missed | :robot: |
|--------------|------------|-------|---------|--------|---------|
| github.com/xataio/pgstream/pkg/transformers/greenmask/greenmask_integer_transformer.go | 95.35% (**-0.11%**) | 43 (-1) | 41 (-1) | 2 | :thumbsdown: |
| github.com/xataio/pgstream/pkg/transformers/greenmask/greenmask_unix_timestamp_transformer.go | 100.00% (ø) | 12 | 12 | 0 |  |
| github.com/xataio/pgstream/pkg/transformers/greenmask/greenmask_uuid_transformer.go | 88.89% (**-5.23%**) | 18 (+1) | 16 | 2 (+1) | :thumbsdown: |

_Please note that the "Total", "Covered", and "Missed" counts above refer to ***code statements*** instead of lines of code. The value in brackets refers to the test coverage of that file in the old version of the code._

### Changed unit test files

- github.com/xataio/pgstream/pkg/transformers/greenmask/greenmask_integer_transformer_test.go
- github.com/xataio/pgstream/pkg/transformers/greenmask/greenmask_unix_timestamp_transformer_test.go

</details>

github-actions[bot]: ### Merging this branch will **decrease** overall coverage

| Impacted Packages | Coverage Δ | :robot: |
|-------------------|------------|---------|
| github.com/xataio/pgstream/pkg/transformers/greenmask | 92.58% (**-1.17%**) | :thumbsdown: |

---

<details>

<summary>Coverage by file</summary>

### Changed files (no unit tests)

| Changed File | Coverage Δ | Total | Covered | Missed | :robot: |
|--------------|------------|-------|---------|--------|---------|
| github.com/xataio/pgstream/pkg/transformers/greenmask/greenmask_integer_transformer.go | 95.35% (**-0.11%**) | 43 (-1) | 41 (-1) | 2 | :thumbsdown: |
| github.com/xataio/pgstream/pkg/transformers/greenmask/greenmask_unix_timestamp_transformer.go | 86.96% (**-13.04%**) | 23 (+11) | 20 (+8) | 3 (+3) | :skull:  |
| github.com/xataio/pgstream/pkg/transformers/greenmask/greenmask_uuid_transformer.go | 88.89% (**-5.23%**) | 18 (+1) | 16 | 2 (+1) | :thumbsdown: |

_Please note that the "Total", "Covered", and "Missed" counts above refer to ***code statements*** instead of lines of code. The value in brackets refers to the test coverage of that file in the old version of the code._

### Changed unit test files

- github.com/xataio/pgstream/pkg/transformers/greenmask/greenmask_integer_transformer_test.go
- github.com/xataio/pgstream/pkg/transformers/greenmask/greenmask_unix_timestamp_transformer_test.go

</details>

github-actions[bot]: ### Merging this branch will **decrease** overall coverage

| Impacted Packages | Coverage Δ | :robot: |
|-------------------|------------|---------|
| github.com/xataio/pgstream/pkg/transformers/greenmask | 92.58% (**-1.17%**) | :thumbsdown: |

---

<details>

<summary>Coverage by file</summary>

### Changed files (no unit tests)

| Changed File | Coverage Δ | Total | Covered | Missed | :robot: |
|--------------|------------|-------|---------|--------|---------|
| github.com/xataio/pgstream/pkg/transformers/greenmask/greenmask_integer_transformer.go | 95.35% (**-0.11%**) | 43 (-1) | 41 (-1) | 2 | :thumbsdown: |
| github.com/xataio/pgstream/pkg/transformers/greenmask/greenmask_unix_timestamp_transformer.go | 86.96% (**-13.04%**) | 23 (+11) | 20 (+8) | 3 (+3) | :skull:  |
| github.com/xataio/pgstream/pkg/transformers/greenmask/greenmask_uuid_transformer.go | 88.89% (**-5.23%**) | 18 (+1) | 16 | 2 (+1) | :thumbsdown: |

_Please note that the "Total", "Covered", and "Missed" counts above refer to ***code statements*** instead of lines of code. The value in brackets refers to the test coverage of that file in the old version of the code._

### Changed unit test files

- github.com/xataio/pgstream/pkg/transformers/greenmask/greenmask_integer_transformer_test.go
- github.com/xataio/pgstream/pkg/transformers/greenmask/greenmask_unix_timestamp_transformer_test.go

</details>


Patch:
diff --git a/pkg/transformers/greenmask/greenmask_integer_transformer.go b/pkg/transformers/greenmask/greenmask_integer_transformer.go
index 19f6bb0..0f53112 100644
--- a/pkg/transformers/greenmask/greenmask_integer_transformer.go
+++ b/pkg/transformers/greenmask/greenmask_integer_transformer.go
@@ -20,7 +20,7 @@ type IntegerTransformer struct {
 	transformer *greenmasktransformers.RandomInt64Transformer
 }
 
-var errUnsupportedSizeError = errors.New("greenmask_integer: size must be 2, 4 or 8")
+var errUnsupportedSizeError = errors.New("greenmask_integer: size must be 2 or 4")
 
 // NewIntegerTransformer creates a new IntegerTransformer with the specified generator and parameters.
 // The size parameter must be 2, 4 or 8, and the min_value and max_value parameters
@@ -44,7 +44,7 @@ func NewIntegerTransformer(generatorType transformers.GeneratorType, params tran
 	if err != nil {
 		return nil, fmt.Errorf("greenmask_integer: max_value must be an integer: %w", err)
 	}
-	limiter, err := greenmasktransformers.NewInt64Limiter(minValue, maxValue)
+	limiter, err := greenmasktransformers.NewInt64Limiter(int64(minValue), int64(maxValue))
 	if err != nil {
 		return nil, err
 	}
@@ -105,14 +105,12 @@ func (t *IntegerTransformer) Transform(value any) (any, error) {
 	return int64(ret), nil
 }
 
-func minMaxValueForSize(size int) (int64, int64, error) {
+func minMaxValueForSize(size int) (int, int, error) {
 	switch size {
 	case 2:
 		return math.MinInt16, math.MaxInt16, nil
 	case 4:
 		return math.MinInt32, math.MaxInt32, nil
-	case 8:
-		return math.MinInt64, math.MaxInt64, nil
 	}
 	return 0, 0, errUnsupportedSizeError
 }
diff --git a/pkg/transformers/greenmask/greenmask_unix_timestamp_transformer.go b/pkg/transformers/greenmask/greenmask_unix_timestamp_transformer.go
index ea252a0..5db2657 100644
--- a/pkg/transformers/greenmask/greenmask_unix_timestamp_transformer.go
+++ b/pkg/transformers/greenmask/greenmask_unix_timestamp_transformer.go
@@ -5,35 +5,54 @@ package greenmask
 import (
 	"errors"
 	"fmt"
+	"strconv"
 
+	greenmasktransformers "github.com/eminano/greenmask/pkg/generators/transformers"
 	"github.com/xataio/pgstream/pkg/transformers"
 )
 
 var errMinMaxValueNotSpecified = errors.New("min_value and max_value must be specified")
 
 func NewUnixTimestampTransformer(generatorType transformers.GeneratorType, params transformers.Parameters) (*IntegerTransformer, error) {
-	minValue, foundMin, err := transformers.FindParameter[int64](params, "min_value")
+	minValueStr, foundMin, err := transformers.FindParameter[string](params, "min_value")
 	if err != nil {
-		return nil, fmt.Errorf("greenmask_unix_timestamp: min_value must be an int64: %w", err)
+		return nil, fmt.Errorf("greenmask_unix_timestamp: min_value must be a string: %w", err)
 	}
 
-	maxValue, foundMax, err := transformers.FindParameter[int64](params, "max_value")
+	maxValueStr, foundMax, err := transformers.FindParameter[string](params, "max_value")
 	if err != nil {
-		return nil, fmt.Errorf("greenmask_unix_timestamp: max_value must be an int64: %w", err)
+		return nil, fmt.Errorf("greenmask_unix_timestamp: max_value must be a string: %w", err)
 	}
 
 	if !foundMin || !foundMax {
 		return nil, errMinMaxValueNotSpecified
 	}
 
-	transformer, err := NewIntegerTransformer(generatorType, transformers.Parameters{
-		"size":      8,
-		"min_value": minValue,
-		"max_value": maxValue,
-	})
+	minValue, err := strconv.ParseInt(minValueStr, 10, 64)
 	if err != nil {
+		return nil, fmt.Errorf("greenmask_unix_timestamp: min_value cannot be parsed into int64: %w", err)
+	}
+
+	maxValue, err := strconv.ParseInt(maxValueStr, 10, 64)
+	if err != nil {
+		return nil, fmt.Errorf("greenmask_unix_timestamp: max_value cannot be parsed into int64: %w", err)
+	}
+
+	limiter, err := greenmasktransformers.NewInt64Limiter(int64(minValue), int64(maxValue))
+	if err != nil {
+		return nil, err
+	}
+
+	t, err := greenmasktransformers.NewRandomInt64Transformer(limiter, 8)
+	if err != nil {
+		return nil, err
+	}
+
+	if err := setGenerator(t, generatorType); err != nil {
 		return nil, err
 	}
 
-	return transformer, nil
+	return &IntegerTransformer{
+		transformer: t,
+	}, nil
 }
diff --git a/pkg/transformers/greenmask/greenmask_uuid_transformer.go b/pkg/transformers/greenmask/greenmask_uuid_transformer.go
index 6ca6b64..9cc63d5 100644
--- a/pkg/transformers/greenmask/greenmask_uuid_transformer.go
+++ b/pkg/transformers/greenmask/greenmask_uuid_transformer.go
@@ -35,6 +35,8 @@ func (ut *UUIDTransformer) Transform(value any) (any, error) {
 		toTransform = val[:]
 	case []byte:
 		toTransform = val
+	case [16]uint8:
+		toTransform = val[:]
 	default:
 		return nil, transformers.ErrUnsupportedValueType
 	}


Test patch:
diff --git a/pkg/transformers/greenmask/greenmask_integer_transformer_test.go b/pkg/transformers/greenmask/greenmask_integer_transformer_test.go
index caa9dc4..26d56dc 100644
--- a/pkg/transformers/greenmask/greenmask_integer_transformer_test.go
+++ b/pkg/transformers/greenmask/greenmask_integer_transformer_test.go
@@ -30,8 +30,8 @@ func TestNewIntegerTransformer(t *testing.T) {
 			generator: transformers.Deterministic,
 			params: transformers.Parameters{
 				"size":      4,
-				"min_value": int64(-100),
-				"max_value": int64(100),
+				"min_value": -100,
+				"max_value": 100,
 			},
 			wantErr: nil,
 		},
@@ -60,8 +60,8 @@ func TestNewIntegerTransformer(t *testing.T) {
 			name:      "error - wrong limits",
 			generator: transformers.Random,
 			params: transformers.Parameters{
-				"min_value": int64(100),
-				"max_value": int64(99),
+				"min_value": 100,
+				"max_value": 99,
 			},
 			wantErr: greenmasktransformers.ErrWrongLimits,
 		},
@@ -69,8 +69,8 @@ func TestNewIntegerTransformer(t *testing.T) {
 			name:      "error - wrong limits not fitting size",
 			generator: transformers.Random,
 			params: transformers.Parameters{
-				"min_value": int64(math.MaxInt32),
-				"size":      4,
+				"min_value": math.MaxInt,
+				"size":      2,
 			},
 			wantErr: greenmasktransformers.ErrWrongLimits,
 		},
@@ -129,9 +129,9 @@ func TestIntegerTransformer_Transform(t *testing.T) {
 			generatorType: transformers.Random,
 			input:         int8(120),
 			params: map[string]any{
-				"size":      8,
-				"min_value": int64(-100),
-				"max_value": int64(100),
+				"size":      4,
+				"min_value": -100,
+				"max_value": 100,
 			},
 		},
 		{
@@ -140,8 +140,8 @@ func TestIntegerTransformer_Transform(t *testing.T) {
 			input:         uint8(120),
 			params: map[string]any{
 				"size":      2,
-				"min_value": int64(-100),
-				"max_value": int64(100),
+				"min_value": -100,
+				"max_value": 100,
 			},
 		},
 		{
@@ -150,8 +150,8 @@ func TestIntegerTransformer_Transform(t *testing.T) {
 			input:         []byte{0, 0, 0, 50},
 			params: map[string]any{
 				"size":      4,
-				"min_value": int64(-100),
-				"max_value": int64(500),
+				"min_value": -100,
+				"max_value": 500,
 			},
 		},
 		{
@@ -159,9 +159,8 @@ func TestIntegerTransformer_Transform(t *testing.T) {
 			generatorType: transformers.Random,
 			input:         int16(500),
 			params: map[string]any{
-				"size":      8,
-				"min_value": int64(-400),
-				"max_value": int64(100),
+				"min_value": -400,
+				"max_value": 100,
 			},
 		},
 		{
@@ -191,7 +190,7 @@ func TestIntegerTransformer_Transform(t *testing.T) {
 			input:         int32(45000),
 			params: map[string]any{
 				"size":      2,
-				"min_value": int64(-100),
+				"min_value": -100,
 			},
 		},
 		{
@@ -200,7 +199,7 @@ func TestIntegerTransformer_Transform(t *testing.T) {
 			input:         uint16(0),
 			params: map[string]any{
 				"size":      2,
-				"min_value": int64(-100),
+				"min_value": -100,
 			},
 		},
 		{
@@ -208,8 +207,8 @@ func TestIntegerTransformer_Transform(t *testing.T) {
 			generatorType: transformers.Deterministic,
 			input:         uint64(1000000000000000000),
 			params: map[string]any{
-				"size":      8,
-				"min_value": int64(math.MaxInt64 - 1),
+				"size":      4,
+				"min_value": math.MaxInt32 - 2,
 			},
 		},
 		{
@@ -218,7 +217,7 @@ func TestIntegerTransformer_Transform(t *testing.T) {
 			input:         []byte{0, 1, 2, 3, 0, 0, 50, 0, 0, 0},
 			params: map[string]any{
 				"size":      2,
-				"min_value": int64(-100),
+				"min_value": -100,
 			},
 		},
 		{
@@ -233,9 +232,9 @@ func TestIntegerTransformer_Transform(t *testing.T) {
 			generatorType: transformers.Random,
 			input:         "invalid",
 			params: map[string]any{
-				"size":      8,
-				"min_value": int64(-100),
-				"max_value": int64(100),
+				"size":      4,
+				"min_value": -100,
+				"max_value": 100,
 			},
 			wantErr: transformers.ErrUnsupportedValueType,
 		},
@@ -253,17 +252,18 @@ func TestIntegerTransformer_Transform(t *testing.T) {
 				return
 			}
 
-			result, ok := got.(int64)
+			result64, ok := got.(int64)
 			require.True(t, ok, "expected got to be of type int64")
+			result := int(result64)
 
 			// check if the result is within the specified range
-			minVal, found, err := transformers.FindParameter[int64](tt.params, "min_value")
+			minVal, found, err := transformers.FindParameter[int](tt.params, "min_value")
 			require.NoError(t, err)
 			if found {
 				require.True(t, result >= minVal)
 			}
 
-			maxVal, found, err := transformers.FindParameter[int64](tt.params, "max_value")
+			maxVal, found, err := transformers.FindParameter[int](tt.params, "max_value")
 			require.NoError(t, err)
 			if found {
 				require.True(t, result <= maxVal)
diff --git a/pkg/transformers/greenmask/greenmask_unix_timestamp_transformer_test.go b/pkg/transformers/greenmask/greenmask_unix_timestamp_transformer_test.go
index f8cc3c2..d86c5c9 100644
--- a/pkg/transformers/greenmask/greenmask_unix_timestamp_transformer_test.go
+++ b/pkg/transformers/greenmask/greenmask_unix_timestamp_transformer_test.go
@@ -3,6 +3,7 @@
 package greenmask
 
 import (
+	"strconv"
 	"testing"
 
 	greenmasktransformers "github.com/eminano/greenmask/pkg/generators/transformers"
@@ -22,11 +23,20 @@ func TestNewUnixTimestampTransformer(t *testing.T) {
 			name:      "ok - valid random",
 			generator: transformers.Random,
 			params: transformers.Parameters{
-				"min_value": int64(-2734919135000),
-				"max_value": int64(72438947289300),
+				"min_value": "-1741957250",
+				"max_value": "1741957250",
 			},
 			wantErr: nil,
 		},
+		{
+			name:      "error - invalid generator",
+			generator: "invalid",
+			params: transformers.Parameters{
+				"min_value": "-1741957250",
+				"max_value": "1741957250",
+			},
+			wantErr: transformers.ErrUnsupportedGenerator,
+		},
 		{
 			name:      "error - invalid min_value",
 			generator: transformers.Deterministic,
@@ -39,8 +49,8 @@ func TestNewUnixTimestampTransformer(t *testing.T) {
 			name:      "error - invalid max_value",
 			generator: transformers.Deterministic,
 			params: transformers.Parameters{
-				"min_value": int64(1380002000000),
-				"max_value": "invalid",
+				"min_value": "1741957250",
+				"max_value": 3,
 			},
 			wantErr: transformers.ErrInvalidParameters,
 		},
@@ -48,7 +58,7 @@ func TestNewUnixTimestampTransformer(t *testing.T) {
 			name:      "error - min_value missing",
 			generator: transformers.Deterministic,
 			params: transformers.Parameters{
-				"max_value": int64(72438947289300),
+				"max_value": "1741957250",
 			},
 			wantErr: errMinMaxValueNotSpecified,
 		},
@@ -56,8 +66,8 @@ func TestNewUnixTimestampTransformer(t *testing.T) {
 			name:      "error - invalid limits",
 			generator: transformers.Random,
 			params: transformers.Parameters{
-				"min_value": int64(72438947289300),
-				"max_value": int64(-72438947289300),
+				"min_value": "1741957250",
+				"max_value": "1741957250",
 			},
 			wantErr: greenmasktransformers.ErrWrongLimits,
 		},
@@ -88,8 +98,8 @@ func TestUnixTimestampTransformer_Transform(t *testing.T) {
 			name:      "ok - random",
 			generator: transformers.Random,
 			params: transformers.Parameters{
-				"min_value": int64(1625097600),
-				"max_value": int64(1625184000),
+				"min_value": "1625097600",
+				"max_value": "1625184000",
 			},
 			input: int64(0),
 		},
@@ -97,8 +107,8 @@ func TestUnixTimestampTransformer_Transform(t *testing.T) {
 			name:      "ok - deterministic",
 			generator: transformers.Deterministic,
 			params: transformers.Parameters{
-				"min_value": int64(1625097600),
-				"max_value": int64(1625184000),
+				"min_value": "1625097600",
+				"max_value": "1625184000",
 			},
 			input: int64(-1),
 		},
@@ -114,10 +124,14 @@ func TestUnixTimestampTransformer_Transform(t *testing.T) {
 
 			v, ok := got.(int64)
 			require.True(t, ok)
-			minVal, ok := tt.params["min_value"].(int64)
+			minValStr, ok := tt.params["min_value"].(string)
 			require.True(t, ok)
-			maxVal, ok := tt.params["max_value"].(int64)
+			minVal, err := strconv.ParseInt(minValStr, 10, 64)
+			require.NoError(t, err)
+			maxValStr, ok := tt.params["max_value"].(string)
 			require.True(t, ok)
+			maxVal, err := strconv.ParseInt(maxValStr, 10, 64)
+			require.NoError(t, err)
 			require.GreaterOrEqual(t, v, minVal)
 			require.LessOrEqual(t, v, maxVal)