Skip to content

Commit

Permalink
test: add unit tests (#41)
Browse files Browse the repository at this point in the history
and a small refactor
  • Loading branch information
aabouzaid authored Sep 18, 2023
1 parent c040f6d commit 389c1b1
Show file tree
Hide file tree
Showing 13 changed files with 617 additions and 24 deletions.
15 changes: 11 additions & 4 deletions .github/workflows/go-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,35 @@ permissions:
contents: read

jobs:
lint:
name: Lint Code
lint-and-test:
name: Lint And Test Code
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4
- uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4
with:
go-version-file: go.mod
cache: false
- name: Run GolangCI Linter
- name: Run GolangCI linter
uses: golangci/golangci-lint-action@3a919529898de77ec3da873e3063ca4b10e7f5cc # v3
with:
version: v1.54
args: '--timeout=5m'
- name: Run Go test coverage
run: go test -race -coverprofile=coverage.out -covermode=atomic ./...
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

build:
name: Build Artifacts
needs: ["lint-and-test"]
permissions:
id-token: write
contents: write
packages: write
pull-requests: write
needs: ["lint"]
uses: ./.github/workflows/tpl-packaging.yml
secrets: inherit
with:
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
[![OpenSSF Best Practices](https://www.bestpractices.dev/projects/7815/badge)](https://www.bestpractices.dev/projects/7815)
[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/aabouzaid/kustomize-plugin-merger/badge)](https://securityscorecards.dev/viewer/?uri=github.com/aabouzaid/kustomize-plugin-merger)
[![Go Report Card](https://goreportcard.com/badge/github.com/aabouzaid/kustomize-plugin-merger)](https://goreportcard.com/report/github.com/aabouzaid/kustomize-plugin-merger)
[![codecov](https://codecov.io/github/aabouzaid/kustomize-plugin-merger/graph/badge.svg?token=BUFRT7BO2I)](https://codecov.io/github/aabouzaid/kustomize-plugin-merger)
[![GitHub Release](https://img.shields.io/github/v/release/aabouzaid/kustomize-plugin-merger?logo=github)](https://github.com/aabouzaid/kustomize-plugin-merger/releases)
[![Docker](https://img.shields.io/badge/Docker-available-blue?logo=docker&logoColor=white)](https://github.com/aabouzaid/kustomize-plugin-merger/pkgs/container/kustomize-generator-merger)
[![Go Reference](https://pkg.go.dev/badge/github.com/aabouzaid/kustomize-plugin-merger.svg)](https://pkg.go.dev/github.com/aabouzaid/kustomize-plugin-merger)
[![Renovatebot](https://img.shields.io/badge/Renovate-enabled-blue?logo=renovatebot)](https://github.com/aabouzaid/kustomize-plugin-merger/issues/7)
[![Renovate](https://img.shields.io/badge/Renovate-enabled-blue?logo=renovatebot)](https://github.com/aabouzaid/kustomize-plugin-merger/issues/7)
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/aabouzaid/kustomize-plugin-merger/pulls)

<!-- omit in toc -->
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ require (
github.com/knadh/koanf/parsers/yaml v0.1.0
github.com/knadh/koanf/providers/file v0.1.0
github.com/knadh/koanf/v2 v2.0.1
github.com/stretchr/testify v1.8.2
k8s.io/apimachinery v0.28.2
k8s.io/kube-openapi v0.0.0-20230918164632-68afd615200d
sigs.k8s.io/kustomize/kyaml v0.14.3
Expand Down Expand Up @@ -36,6 +37,7 @@ require (
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/xlab/treeprint v1.2.0 // indirect
golang.org/x/net v0.13.0 // indirect
golang.org/x/sys v0.10.0 // indirect
Expand Down
4 changes: 2 additions & 2 deletions pkg/merger/fn.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ func (m *Merger) Schema() (*spec.Schema, error) {
func (m *Merger) Default() error {
for index := range m.Spec.Resources {
//
m.Spec.Resources[index].setInputFilesRoot()
m.Spec.Resources[index].Input.Files.setRoot()
// Defaults merge strategy.
m.Spec.Resources[index].setMergeStrategy()
m.Spec.Resources[index].Merge.setStrategy()
// Create empty map for staged data.
m.Spec.Resources[index].Output.items = make(map[string]string)
}
Expand Down
83 changes: 83 additions & 0 deletions pkg/merger/fn_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package merger

import (
"testing"

"github.com/stretchr/testify/assert"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/kustomize/kyaml/yaml"
)

func TestMerger(t *testing.T) {
// Create a Merger resource.
merger := &Merger{
ObjectMeta: metav1.ObjectMeta{
Name: "my-merger",
},
Spec: mergerSpec{
Resources: []mergerResource{
{
Name: "my-resource",
Input: resourceInput{
Method: Overlay,
Files: resourceInputFiles{
Root: "../../examples/testdata",
Sources: []string{
"input/dev.yaml",
"input/stage.yaml",
},
Destination: "input/base.yaml",
},
},
Merge: resourceMerge{
Strategy: Append,
},
Output: resourceOutput{
Format: Raw,
},
},
},
},
}

//
// Schema.
_, err := merger.Schema()
if err != nil {
t.Errorf("Failed to load schema: %v", err)
}

//
// Default.
err = merger.Default()
if err != nil {
t.Errorf("Failed to set defaults: %v", err)
}
// The trailing slash should be added to the root.
assert.Equal(t, "../../examples/testdata/", merger.Spec.Resources[0].Input.Files.Root)
// Create the output items as an empty map.
assert.Equal(t, map[string]string{}, merger.Spec.Resources[0].Output.items)

//
// Validate.
err = merger.Validate()
if err != nil {
t.Errorf("Failed to validate: %v", err)
}

//
// Filter.
rlItemsIn := []*yaml.RNode{}
var rlItemsOut []*yaml.RNode

rlItemsOut, err = merger.Filter(rlItemsIn)
if err != nil {
t.Errorf("Failed to filter resource list: %v", err)
}
// Output items should be two since the input method is "overlay".
assert.Len(t, rlItemsOut, 2)

// Verify that the filtered resource list contains the merged resource.
// NOTE: Since the items are generated from a Map; hence the output order is no preserved.
assert.Equal(t, "Pod", rlItemsOut[0].GetKind())
}
38 changes: 21 additions & 17 deletions pkg/merger/merge.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,29 +13,27 @@ import (
"sigs.k8s.io/kustomize/kyaml/yaml"
)

// setMergeStrategy sets "mergo" merging strategy, mainly for merging arrays.
func (r *mergerResource) setMergeStrategy() {
switch r.Merge.Strategy {
// setStrategy sets "mergo" merging strategy, mainly for merging arrays.
func (rm *resourceMerge) setStrategy() {
switch rm.Strategy {
case Replace:
r.Merge.config = mergo.WithOverride
rm.config = mergo.WithOverride
case Append:
r.Merge.config = mergo.WithAppendSlice
rm.config = mergo.WithAppendSlice
case Combine:
r.Merge.config = mergo.WithSliceDeepCopy
default:
r.Merge.config = func(*mergo.Config) {}
rm.config = mergo.WithSliceDeepCopy
}
}

func (r *mergerResource) setInputFilesRoot() {
if r.Input.Files.Root != "" {
r.Input.Files.Root = strings.TrimSuffix(r.Input.Files.Root, "/") + "/"
func (rif *resourceInputFiles) setRoot() {
if rif.Root != "" {
rif.Root = strings.TrimSuffix(rif.Root, "/") + "/"
}
}

func (r *mergerResource) loadDestinationFile() *koanf.Koanf {
func (rif *resourceInputFiles) loadDestinationFile() *koanf.Koanf {
k := koanf.New(".")
dstFile := r.Input.Files.Root + r.Input.Files.Destination
dstFile := rif.Root + rif.Destination
if err := k.Load(koanfFile.Provider(dstFile), koanfYaml.Parser()); err != nil {
log.Fatalf("Error loading config: %v", err)
}
Expand All @@ -45,14 +43,14 @@ func (r *mergerResource) loadDestinationFile() *koanf.Koanf {
// merge performs the actual merging of configuration files from resourceInputFiles sources.
func (r *mergerResource) merge() {
// TODO: Simplify/split the logic in merge method.
k := r.loadDestinationFile()
k := r.Input.Files.loadDestinationFile()
fileKey := r.Name

for _, srcFile := range r.Input.Files.Sources {
srcFile = r.Input.Files.Root + srcFile

if r.Input.Method == Overlay {
k = r.loadDestinationFile()
k = r.Input.Files.loadDestinationFile()
fileKey = filepath.Base(srcFile)
}

Expand Down Expand Up @@ -84,26 +82,32 @@ func (r *mergerResource) export() []*yaml.RNode {
}

case ConfigMap:
rNode, _ := yaml.FromMap(map[string]interface{}{
rNode, err := yaml.FromMap(map[string]interface{}{
"apiVersion": "v1",
"kind": "ConfigMap",
"metadata": map[string]string{
"name": r.Name,
},
})
if err != nil {
log.Fatalf("Error creating ConfigMap: %v", err)
}
if err := rNode.LoadMapIntoConfigMapData(r.Output.items); err != nil {
log.Fatalf("Error creating ConfigMap data: %v", err)
}
rlItems = append(rlItems, rNode)

case Secret:
rNode, _ := yaml.FromMap(map[string]interface{}{
rNode, err := yaml.FromMap(map[string]interface{}{
"apiVersion": "v1",
"kind": "Secret",
"metadata": map[string]string{
"name": r.Name,
},
})
if err != nil {
log.Fatalf("Error creating Secret: %v", err)
}
if err := rNode.LoadMapIntoSecretData(r.Output.items); err != nil {
log.Fatalf("Error creating Secret data: %v", err)
}
Expand Down
Loading

0 comments on commit 389c1b1

Please sign in to comment.