Merge pull request #560 from karlkfi/karl-fix-empty-set

fix: Allow empty set of apply objects
This commit is contained in:
Kubernetes Prow Robot 2022-03-02 11:05:15 -08:00 committed by GitHub
commit 16847b444b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 247 additions and 6 deletions

View File

@ -640,6 +640,22 @@ func TestApplier(t *testing.T) {
},
},
expectedStatusEvents: []testutil.ExpEvent{
{
EventType: event.ActionGroupType,
ActionGroupEvent: &testutil.ExpActionGroupEvent{
GroupName: "inventory-add-0",
Action: event.InventoryAction,
Type: event.Started,
},
},
{
EventType: event.ActionGroupType,
ActionGroupEvent: &testutil.ExpActionGroupEvent{
GroupName: "inventory-add-0",
Action: event.InventoryAction,
Type: event.Finished,
},
},
{
EventType: event.StatusType,
StatusEvent: &testutil.ExpStatusEvent{
@ -937,6 +953,22 @@ func TestApplier(t *testing.T) {
EventType: event.InitType,
InitEvent: &testutil.ExpInitEvent{},
},
{
EventType: event.ActionGroupType,
ActionGroupEvent: &testutil.ExpActionGroupEvent{
GroupName: "inventory-add-0",
Action: event.InventoryAction,
Type: event.Started,
},
},
{
EventType: event.ActionGroupType,
ActionGroupEvent: &testutil.ExpActionGroupEvent{
GroupName: "inventory-add-0",
Action: event.InventoryAction,
Type: event.Finished,
},
},
{
EventType: event.ActionGroupType,
ActionGroupEvent: &testutil.ExpActionGroupEvent{
@ -1060,6 +1092,22 @@ func TestApplier(t *testing.T) {
EventType: event.InitType,
InitEvent: &testutil.ExpInitEvent{},
},
{
EventType: event.ActionGroupType,
ActionGroupEvent: &testutil.ExpActionGroupEvent{
GroupName: "inventory-add-0",
Action: event.InventoryAction,
Type: event.Started,
},
},
{
EventType: event.ActionGroupType,
ActionGroupEvent: &testutil.ExpActionGroupEvent{
GroupName: "inventory-add-0",
Action: event.InventoryAction,
Type: event.Finished,
},
},
{
EventType: event.ActionGroupType,
ActionGroupEvent: &testutil.ExpActionGroupEvent{

View File

@ -154,12 +154,8 @@ func (t *TaskQueueBuilder) Build(taskContext *taskrunner.TaskContext, o Options)
applyObjs = t.Collector.FilterInvalidObjects(applyObjs)
pruneObjs = t.Collector.FilterInvalidObjects(pruneObjs)
if len(applyObjs) > 0 {
// Register actuation plan in the inventory
for _, id := range object.UnstructuredSetToObjMetadataSet(applyObjs) {
taskContext.InventoryManager().AddPendingApply(id)
}
if !o.Destroy {
// InvAddTask creates the inventory and adds any objects being applied
klog.V(2).Infof("adding inventory add task (%d objects)", len(applyObjs))
tasks = append(tasks, &task.InvAddTask{
TaskName: "inventory-add-0",
@ -168,6 +164,13 @@ func (t *TaskQueueBuilder) Build(taskContext *taskrunner.TaskContext, o Options)
Objects: applyObjs,
DryRun: o.DryRunStrategy,
})
}
if len(applyObjs) > 0 {
// Register actuation plan in the inventory
for _, id := range object.UnstructuredSetToObjMetadataSet(applyObjs) {
taskContext.InventoryManager().AddPendingApply(id)
}
// Filter idSetList down to just apply objects
applySets := graph.HydrateSetList(idSetList, applyObjs)

View File

@ -143,6 +143,12 @@ func TestTaskQueueBuilder_ApplyBuild(t *testing.T) {
"no resources, no apply or wait tasks": {
applyObjs: []*unstructured.Unstructured{},
expectedTasks: []taskrunner.Task{
&task.InvAddTask{
TaskName: "inventory-add-0",
InvClient: &inventory.FakeClient{},
InvInfo: invInfo,
Objects: object.UnstructuredSet{},
},
&task.InvSetTask{
TaskName: "inventory-set-0",
InvClient: &inventory.FakeClient{},
@ -850,6 +856,12 @@ func TestTaskQueueBuilder_PruneBuild(t *testing.T) {
pruneObjs: []*unstructured.Unstructured{},
options: Options{Prune: true},
expectedTasks: []taskrunner.Task{
&task.InvAddTask{
TaskName: "inventory-add-0",
InvClient: &inventory.FakeClient{},
InvInfo: invInfo,
Objects: object.UnstructuredSet{},
},
&task.InvSetTask{
TaskName: "inventory-set-0",
InvClient: &inventory.FakeClient{},
@ -864,6 +876,12 @@ func TestTaskQueueBuilder_PruneBuild(t *testing.T) {
},
options: Options{Prune: true},
expectedTasks: []taskrunner.Task{
&task.InvAddTask{
TaskName: "inventory-add-0",
InvClient: &inventory.FakeClient{},
InvInfo: invInfo,
Objects: object.UnstructuredSet{},
},
&task.PruneTask{
TaskName: "prune-0",
Objects: []*unstructured.Unstructured{
@ -904,6 +922,12 @@ func TestTaskQueueBuilder_PruneBuild(t *testing.T) {
},
options: Options{Prune: true},
expectedTasks: []taskrunner.Task{
&task.InvAddTask{
TaskName: "inventory-add-0",
InvClient: &inventory.FakeClient{},
InvInfo: invInfo,
Objects: object.UnstructuredSet{},
},
&task.PruneTask{
TaskName: "prune-0",
Objects: []*unstructured.Unstructured{
@ -957,6 +981,12 @@ func TestTaskQueueBuilder_PruneBuild(t *testing.T) {
options: Options{Prune: true},
// Opposite ordering when pruning/deleting
expectedTasks: []taskrunner.Task{
&task.InvAddTask{
TaskName: "inventory-add-0",
InvClient: &inventory.FakeClient{},
InvInfo: invInfo,
Objects: object.UnstructuredSet{},
},
&task.PruneTask{
TaskName: "prune-0",
Objects: []*unstructured.Unstructured{
@ -1022,6 +1052,12 @@ func TestTaskQueueBuilder_PruneBuild(t *testing.T) {
PruneTimeout: 3 * time.Minute,
},
expectedTasks: []taskrunner.Task{
&task.InvAddTask{
TaskName: "inventory-add-0",
InvClient: &inventory.FakeClient{},
InvInfo: invInfo,
Objects: object.UnstructuredSet{},
},
&task.PruneTask{
TaskName: "prune-0",
Objects: []*unstructured.Unstructured{
@ -1068,6 +1104,13 @@ func TestTaskQueueBuilder_PruneBuild(t *testing.T) {
},
// No wait task, since it is dry run
expectedTasks: []taskrunner.Task{
&task.InvAddTask{
TaskName: "inventory-add-0",
InvClient: &inventory.FakeClient{},
InvInfo: invInfo,
Objects: object.UnstructuredSet{},
DryRun: common.DryRunServer,
},
&task.PruneTask{
TaskName: "prune-0",
Objects: []*unstructured.Unstructured{
@ -1115,6 +1158,12 @@ func TestTaskQueueBuilder_PruneBuild(t *testing.T) {
options: Options{Prune: true},
// Opposite ordering when pruning/deleting.
expectedTasks: []taskrunner.Task{
&task.InvAddTask{
TaskName: "inventory-add-0",
InvClient: &inventory.FakeClient{},
InvInfo: invInfo,
Objects: object.UnstructuredSet{},
},
&task.PruneTask{
TaskName: "prune-0",
Objects: []*unstructured.Unstructured{
@ -1193,6 +1242,13 @@ func TestTaskQueueBuilder_PruneBuild(t *testing.T) {
Prune: true,
},
expectedTasks: []taskrunner.Task{
&task.InvAddTask{
TaskName: "inventory-add-0",
InvClient: &inventory.FakeClient{},
InvInfo: invInfo,
Objects: object.UnstructuredSet{},
DryRun: common.DryRunClient,
},
&task.PruneTask{
TaskName: "prune-0",
Objects: []*unstructured.Unstructured{
@ -1255,6 +1311,12 @@ func TestTaskQueueBuilder_PruneBuild(t *testing.T) {
},
options: Options{Prune: true},
expectedTasks: []taskrunner.Task{
&task.InvAddTask{
TaskName: "inventory-add-0",
InvClient: &inventory.FakeClient{},
InvInfo: invInfo,
Objects: object.UnstructuredSet{},
},
&task.PruneTask{
TaskName: "prune-0",
Objects: []*unstructured.Unstructured{
@ -1357,6 +1419,12 @@ func TestTaskQueueBuilder_PruneBuild(t *testing.T) {
},
options: Options{Prune: true},
expectedTasks: []taskrunner.Task{
&task.InvAddTask{
TaskName: "inventory-add-0",
InvClient: &inventory.FakeClient{},
InvInfo: invInfo,
Objects: object.UnstructuredSet{},
},
&task.PruneTask{
TaskName: "prune-0",
Objects: []*unstructured.Unstructured{

View File

@ -171,6 +171,10 @@ var _ = Describe("Applier", func() {
dryRunTest(ctx, c, invConfig, inventoryName, namespace.GetName())
})
It("EmptySet", func() {
emptySetTest(ctx, c, invConfig, inventoryName, namespace.GetName())
})
It("Deletion Prevention", func() {
deletionPreventionTest(ctx, c, invConfig, inventoryName, namespace.GetName())
})

118
test/e2e/empty_set_test.go Normal file
View File

@ -0,0 +1,118 @@
// Copyright 2020 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package e2e
import (
"context"
"fmt"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"sigs.k8s.io/cli-utils/pkg/apply"
"sigs.k8s.io/cli-utils/pkg/apply/event"
"sigs.k8s.io/cli-utils/pkg/inventory"
"sigs.k8s.io/cli-utils/pkg/testutil"
"sigs.k8s.io/controller-runtime/pkg/client"
)
//nolint:dupl // expEvents similar to other tests
func emptySetTest(ctx context.Context, c client.Client, invConfig InventoryConfig, inventoryName, namespaceName string) {
By("Apply zero resources")
applier := invConfig.ApplierFactoryFunc()
inventoryID := fmt.Sprintf("%s-%s", inventoryName, namespaceName)
inventoryInfo := invConfig.InvWrapperFunc(invConfig.FactoryFunc(inventoryName, namespaceName, inventoryID))
resources := []*unstructured.Unstructured{}
applierEvents := runCollect(applier.Run(ctx, inventoryInfo, resources, apply.ApplierOptions{
EmitStatusEvents: true,
}))
expEvents := []testutil.ExpEvent{
{
// InitTask
EventType: event.InitType,
InitEvent: &testutil.ExpInitEvent{},
},
{
// InvAddTask start
EventType: event.ActionGroupType,
ActionGroupEvent: &testutil.ExpActionGroupEvent{
Action: event.InventoryAction,
GroupName: "inventory-add-0",
Type: event.Started,
},
},
{
// InvAddTask finished
EventType: event.ActionGroupType,
ActionGroupEvent: &testutil.ExpActionGroupEvent{
Action: event.InventoryAction,
GroupName: "inventory-add-0",
Type: event.Finished,
},
},
{
// InvSetTask start
EventType: event.ActionGroupType,
ActionGroupEvent: &testutil.ExpActionGroupEvent{
Action: event.InventoryAction,
GroupName: "inventory-set-0",
Type: event.Started,
},
},
{
// InvSetTask finished
EventType: event.ActionGroupType,
ActionGroupEvent: &testutil.ExpActionGroupEvent{
Action: event.InventoryAction,
GroupName: "inventory-set-0",
Type: event.Finished,
},
},
}
Expect(testutil.EventsToExpEvents(applierEvents)).To(testutil.Equal(expEvents))
By("Verify inventory created")
invConfig.InvSizeVerifyFunc(ctx, c, inventoryName, namespaceName, inventoryID, 0)
By("Destroy zero resources")
destroyer := invConfig.DestroyerFactoryFunc()
options := apply.DestroyerOptions{InventoryPolicy: inventory.PolicyAdoptIfNoInventory}
destroyerEvents := runCollect(destroyer.Run(ctx, inventoryInfo, options))
expEvents = []testutil.ExpEvent{
{
// InitTask
EventType: event.InitType,
InitEvent: &testutil.ExpInitEvent{},
},
{
// DeleteInvTask start
EventType: event.ActionGroupType,
ActionGroupEvent: &testutil.ExpActionGroupEvent{
Action: event.InventoryAction,
GroupName: "delete-inventory-0",
Type: event.Started,
},
},
{
// DeleteInvTask finished
EventType: event.ActionGroupType,
ActionGroupEvent: &testutil.ExpActionGroupEvent{
Action: event.InventoryAction,
GroupName: "delete-inventory-0",
Type: event.Finished,
},
},
}
Expect(testutil.EventsToExpEvents(destroyerEvents)).To(testutil.Equal(expEvents))
By("Verify inventory deleted")
invConfig.InvNotExistsFunc(ctx, c, inventoryName, namespaceName, inventoryID)
}