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

Implement checkImageChange and tests #5333

Merged
merged 2 commits into from
Nov 14, 2024
Merged
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
23 changes: 23 additions & 0 deletions pkg/app/pipedv1/plugin/kubernetes/deployment/determine.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/pipe-cd/pipecd/pkg/app/pipedv1/plugin/kubernetes/config"
"github.com/pipe-cd/pipecd/pkg/app/pipedv1/plugin/kubernetes/provider"
"github.com/pipe-cd/pipecd/pkg/model"
"github.com/pipe-cd/pipecd/pkg/plugin/diff"
)

type containerImage struct {
Expand Down Expand Up @@ -170,3 +171,25 @@ func findConfigsAndSecrets(manifests []provider.Manifest) map[provider.ResourceK
}
return configs
}

func checkImageChange(ns diff.Nodes) (string, bool) {
const containerImageQuery = `^spec\.template\.spec\.containers\.\d+.image$`
nodes, _ := ns.Find(containerImageQuery)
if len(nodes) == 0 {
return "", false
}

images := make([]string, 0, len(ns))
for _, n := range nodes {
beforeImg := parseContainerImage(n.StringX())
afterImg := parseContainerImage(n.StringY())

if beforeImg.name == afterImg.name {
images = append(images, fmt.Sprintf("image %s from %s to %s", beforeImg.name, beforeImg.tag, afterImg.tag))
} else {
images = append(images, fmt.Sprintf("image %s:%s to %s:%s", beforeImg.name, beforeImg.tag, afterImg.name, afterImg.tag))
}
}
desc := fmt.Sprintf("Sync progressively because of updating %s", strings.Join(images, ", "))
return desc, true
}
179 changes: 179 additions & 0 deletions pkg/app/pipedv1/plugin/kubernetes/deployment/determine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.uber.org/zap"
"sigs.k8s.io/yaml"

"github.com/pipe-cd/pipecd/pkg/app/pipedv1/plugin/kubernetes/config"
Expand Down Expand Up @@ -1064,3 +1065,181 @@ data:
})
}
}

func TestCheckImageChange(t *testing.T) {
tests := []struct {
name string
old string
new string
want string
wantOk bool
}{
{
name: "image updated",
old: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
template:
spec:
containers:
- name: nginx
image: nginx:1.19.3
`,
new: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
template:
spec:
containers:
- name: nginx
image: nginx:1.19.4
`,
want: "Sync progressively because of updating image nginx from 1.19.3 to 1.19.4",
wantOk: true,
},
{
name: "image name changed",
old: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
template:
spec:
containers:
- name: nginx
image: nginx:1.19.3
`,
new: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
template:
spec:
containers:
- name: redis
image: redis:6.0.9
`,
want: "Sync progressively because of updating image nginx:1.19.3 to redis:6.0.9",
wantOk: true,
},
{
name: "no image change",
old: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
template:
spec:
containers:
- name: nginx
image: nginx:1.19.3
`,
new: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
template:
spec:
containers:
- name: nginx
image: nginx:1.19.3
`,
want: "",
wantOk: false,
},
{
name: "multiple image updates",
old: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-deployment
spec:
template:
spec:
containers:
- name: nginx
image: nginx:1.19.3
- name: redis
image: redis:6.0.9
`,
new: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-deployment
spec:
template:
spec:
containers:
- name: nginx
image: nginx:1.19.4
- name: redis
image: redis:6.0.10
`,
want: "Sync progressively because of updating image nginx from 1.19.3 to 1.19.4, image redis from 6.0.9 to 6.0.10",
wantOk: true,
},
Copy link
Member

@khanhtc1202 khanhtc1202 Nov 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nits, Could you add a test case to show that the order of the image matters to this checkImageChange function 👀

{
			name: "change the order cause multi-image update",
			old: `
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-deployment
spec:
  template:
    spec:
      containers:
      - name: nginx
        image: nginx:1.19.3
      - name: redis
        image: redis:6.0.9
`,
			new: `
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-deployment
spec:
  template:
    spec:
      containers:
      - name: redis
        image: redis:6.0.9
      - name: nginx
        image: nginx:1.19.3
`,
			want:   "Sync progressively because of updating image nginx:1.19.3 to redis:6.0.9, image redis:6.0.9 to nginx:1.19.3",
			wantOk: true,
		},

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. I added it on this commit.
1112cd9

{
name: "change the order cause multi-image update",
old: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-deployment
spec:
template:
spec:
containers:
- name: nginx
image: nginx:1.19.3
- name: redis
image: redis:6.0.9
`,
new: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-deployment
spec:
template:
spec:
containers:
- name: redis
image: redis:6.0.9
- name: nginx
image: nginx:1.19.3
`,
want: "Sync progressively because of updating image nginx:1.19.3 to redis:6.0.9, image redis:6.0.9 to nginx:1.19.3",
wantOk: true,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
oldManifests := mustParseManifests(t, tt.old)
newManifests := mustParseManifests(t, tt.new)
logger := zap.NewNop() // or use a real logger if available
diffs, err := provider.Diff(oldManifests[0], newManifests[0], logger)
require.NoError(t, err)

got, ok := checkImageChange(diffs.Nodes())
assert.Equal(t, tt.wantOk, ok)
assert.Equal(t, tt.want, got)
})
}
}
Loading