mirror of
https://github.com/hanzoai/o11y-foundry.git
synced 2026-10-30 18:26:45 +00:00
220 lines
5.8 KiB
Go
220 lines
5.8 KiB
Go
package jsonpatch
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
"github.com/hanzoai/o11y-foundry/api/v1alpha1"
|
|
"github.com/hanzoai/o11y-foundry/internal/domain"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func newYAMLMaterial(t *testing.T, yamlContent string, path string) domain.Material {
|
|
t.Helper()
|
|
mat, err := domain.NewYAMLMaterial([]byte(yamlContent), path)
|
|
require.NoError(t, err)
|
|
return mat
|
|
}
|
|
|
|
func structuredMaterial(t *testing.T, material domain.Material) domain.StructuredMaterial {
|
|
t.Helper()
|
|
structured, ok := material.(domain.StructuredMaterial)
|
|
require.True(t, ok, "expected structured material")
|
|
return structured
|
|
}
|
|
|
|
func TestApply_ReplaceOperation(t *testing.T) {
|
|
p := New()
|
|
mat := newYAMLMaterial(t, `
|
|
services:
|
|
clickhouse:
|
|
mem_limit: "2G"
|
|
`, "docker-compose.yaml")
|
|
|
|
pe := v1alpha1.PatchEntry{
|
|
Target: "docker-compose.yaml",
|
|
Operations: []v1alpha1.PatchOperation{
|
|
{Op: "replace", Path: "/services/clickhouse/mem_limit", Value: "4G"},
|
|
},
|
|
}
|
|
|
|
result, err := p.Apply(context.Background(), []domain.Material{mat}, pe)
|
|
require.NoError(t, err)
|
|
require.Len(t, result, 1)
|
|
|
|
contents := structuredMaterial(t, result[0]).FmtContents()
|
|
assert.Contains(t, string(contents), "4G")
|
|
assert.NotContains(t, string(contents), "2G")
|
|
}
|
|
|
|
func TestApply_AddOperation(t *testing.T) {
|
|
p := New()
|
|
mat := newYAMLMaterial(t, `
|
|
services:
|
|
signoz:
|
|
environment:
|
|
- "EXISTING=true"
|
|
`, "docker-compose.yaml")
|
|
|
|
pe := v1alpha1.PatchEntry{
|
|
Target: "docker-compose.yaml",
|
|
Operations: []v1alpha1.PatchOperation{
|
|
{Op: "add", Path: "/services/signoz/environment/-", Value: "CUSTOM_VAR=value"},
|
|
},
|
|
}
|
|
|
|
result, err := p.Apply(context.Background(), []domain.Material{mat}, pe)
|
|
require.NoError(t, err)
|
|
|
|
contents := structuredMaterial(t, result[0]).FmtContents()
|
|
assert.Contains(t, string(contents), "CUSTOM_VAR=value")
|
|
assert.Contains(t, string(contents), "EXISTING=true")
|
|
}
|
|
|
|
func TestApply_RemoveOperation(t *testing.T) {
|
|
p := New()
|
|
mat := newYAMLMaterial(t, `
|
|
services:
|
|
clickhouse:
|
|
mem_limit: "2G"
|
|
cpu_count: 4
|
|
`, "docker-compose.yaml")
|
|
|
|
pe := v1alpha1.PatchEntry{
|
|
Target: "docker-compose.yaml",
|
|
Operations: []v1alpha1.PatchOperation{
|
|
{Op: "remove", Path: "/services/clickhouse/cpu_count"},
|
|
},
|
|
}
|
|
|
|
result, err := p.Apply(context.Background(), []domain.Material{mat}, pe)
|
|
require.NoError(t, err)
|
|
|
|
contents := structuredMaterial(t, result[0]).FmtContents()
|
|
assert.NotContains(t, string(contents), "cpu_count")
|
|
assert.Contains(t, string(contents), "mem_limit")
|
|
}
|
|
|
|
func TestApply_GlobTarget(t *testing.T) {
|
|
p := New()
|
|
mat1 := newYAMLMaterial(t, `replicas: 1`, "clickhouse-shard-0.yaml")
|
|
mat2 := newYAMLMaterial(t, `replicas: 1`, "clickhouse-shard-1.yaml")
|
|
mat3 := newYAMLMaterial(t, `replicas: 1`, "signoz.yaml")
|
|
|
|
pe := v1alpha1.PatchEntry{
|
|
Target: "clickhouse-shard-*.yaml",
|
|
Operations: []v1alpha1.PatchOperation{
|
|
{Op: "replace", Path: "/replicas", Value: 3},
|
|
},
|
|
}
|
|
|
|
result, err := p.Apply(context.Background(), []domain.Material{mat1, mat2, mat3}, pe)
|
|
require.NoError(t, err)
|
|
require.Len(t, result, 3)
|
|
|
|
for _, i := range []int{0, 1} {
|
|
contents := structuredMaterial(t, result[i]).FmtContents()
|
|
assert.Contains(t, string(contents), "3")
|
|
}
|
|
|
|
contents := structuredMaterial(t, result[2]).FmtContents()
|
|
assert.Contains(t, string(contents), "1")
|
|
}
|
|
|
|
func TestApply_FullPathMatch(t *testing.T) {
|
|
p := New()
|
|
mat := newYAMLMaterial(t, `name: test`, "deployment/compose.yaml")
|
|
|
|
pe := v1alpha1.PatchEntry{
|
|
Target: "deployment/compose.yaml",
|
|
Operations: []v1alpha1.PatchOperation{
|
|
{Op: "replace", Path: "/name", Value: "patched"},
|
|
},
|
|
}
|
|
|
|
result, err := p.Apply(context.Background(), []domain.Material{mat}, pe)
|
|
require.NoError(t, err)
|
|
|
|
contents := structuredMaterial(t, result[0]).FmtContents()
|
|
assert.Contains(t, string(contents), "patched")
|
|
}
|
|
|
|
func TestApply_UnmatchedTargetReturnsError(t *testing.T) {
|
|
p := New()
|
|
mat := newYAMLMaterial(t, `name: test`, "test.yaml")
|
|
|
|
pe := v1alpha1.PatchEntry{
|
|
Target: "nonexistent.yaml",
|
|
Operations: []v1alpha1.PatchOperation{
|
|
{Op: "replace", Path: "/name", Value: "patched"},
|
|
},
|
|
}
|
|
|
|
_, err := p.Apply(context.Background(), []domain.Material{mat}, pe)
|
|
assert.Error(t, err)
|
|
assert.Contains(t, err.Error(), "did not match any generated material")
|
|
}
|
|
|
|
func TestApply_InvalidPathReturnsError(t *testing.T) {
|
|
p := New()
|
|
mat := newYAMLMaterial(t, `name: test`, "test.yaml")
|
|
|
|
pe := v1alpha1.PatchEntry{
|
|
Target: "test.yaml",
|
|
Operations: []v1alpha1.PatchOperation{
|
|
{Op: "replace", Path: "/nonexistent/path", Value: "value"},
|
|
},
|
|
}
|
|
|
|
_, err := p.Apply(context.Background(), []domain.Material{mat}, pe)
|
|
assert.Error(t, err)
|
|
assert.Contains(t, err.Error(), "failed to apply")
|
|
}
|
|
|
|
func TestApply_BlobMaterialReturnsError(t *testing.T) {
|
|
p := New()
|
|
mat := domain.NewBlobMaterial([]byte("FROM alpine\n"), "Dockerfile")
|
|
|
|
pe := v1alpha1.PatchEntry{
|
|
Target: "Dockerfile",
|
|
Operations: []v1alpha1.PatchOperation{
|
|
{Op: "replace", Path: "/from", Value: "ubuntu"},
|
|
},
|
|
}
|
|
|
|
_, err := p.Apply(context.Background(), []domain.Material{mat}, pe)
|
|
require.Error(t, err)
|
|
assert.Contains(t, err.Error(), "json patch on blob material")
|
|
}
|
|
|
|
func TestApply_StructuredValue(t *testing.T) {
|
|
p := New()
|
|
mat := newYAMLMaterial(t, `
|
|
spec:
|
|
template:
|
|
spec:
|
|
containers: []
|
|
`, "deployment.yaml")
|
|
|
|
pe := v1alpha1.PatchEntry{
|
|
Target: "deployment.yaml",
|
|
Operations: []v1alpha1.PatchOperation{
|
|
{
|
|
Op: "add",
|
|
Path: "/spec/template/spec/tolerations",
|
|
Value: []map[string]string{
|
|
{"key": "dedicated", "value": "signoz", "effect": "NoSchedule"},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
result, err := p.Apply(context.Background(), []domain.Material{mat}, pe)
|
|
require.NoError(t, err)
|
|
|
|
contents := structuredMaterial(t, result[0]).FmtContents()
|
|
assert.Contains(t, string(contents), "dedicated")
|
|
assert.Contains(t, string(contents), "NoSchedule")
|
|
}
|